How do I get the image number of frame X of a view?

Started by bx83, Thu 05/03/2020 21:07:29

Previous topic - Next topic

bx83

I'm trying to manually animate something. This means counting up the delay in room_RepExec, then going through each animation frame of the view/loop I'm using, then looping back to 0 when I reach the end of the view.

However, I'm finding it impossible to go and get the image number of the next (or Xth also) frame of an animation. I can check which frame I'm on, but not set the frame, or find out the image number.

How do I do any of these things?

TheManInBoots

#1
You can actually simply write
Code: ags
Character.Frame=Character.Frame +1;


Very easy 🙂

Also, to reset the animation you write:
(if you have 18 frames in the loop)

Code: ags
if(Character. Frame==17)
{Character.Frame=0;}

(Because the frames are counted from 0 on if you check in the view tab  ;))

Can you give more details on what exactly you're trying to do?
Maybe I can tell you something else useful depending on what you're looking for...

Crimson Wizard

#2
I do not know what exactly are you animating and why manually, so idk if this is the most optimal way to do this, but answering literally to your question, this is how you get the frame's image:

Code: ags
ViewFrame* frame = Game.GetViewFrame(view, loop, frame);
int image_id = frame.Graphic;

bx83

Okay, thanks :)

How will I stop ViewFrame* getting an error because I'm defining it over and over in room_RepExec()? Delete after - how?

Crimson Wizard

Quote from: bx83 on Thu 05/03/2020 21:33:36
How will I stop ViewFrame* getting an error because I'm defining it over and over in room_RepExec()?

What error do you get? Can you show your script?

bx83

Actually surprisingly there isn't one :/ Oh well. Mostly defining variables in RepExec gives an error.

fernewelten

#6
To circumvent the standard mechanisms and do my own animation, this is how I would do it:

1. In the Editor, make a view, say VwSpec, that contains just one loop with one frame.

2. In code, when you want to start pushing your own character pixels,

  • lock the player character view to VwSpec.
  • Set some global variable, say Room17PlayerLocked, to true as soon as this has happened.
  • At this point, also create a dynamic sprite that you will use for your hand-written pixel pushing, and assign it to loop 0 of frame 0 of VwSpec.
This all should happen outside of the function room_RepExec() since it only needs to happen once, when you start the hand-written animation.
Something like this:
Code: ags
player.LockView(VWSPEC); 
Room17PlayerDS = DynamicSprite.Create(50, 50);
ViewFrame *frame = Game.GetViewFrame(VWSPEC, 0, 0);
frame.Graphic = Room17PlayerDS.Graphic;
Room17PlayerLocked = true;


(Room17PlayerLocked could be a global bool variable, perhaps defined at the start of your room file since it will only be read within this file. Room17PlayerDS is a global variable of type DynamicSprite *; we'll need to refer to it later on when we free the sprite.)

So after this has run, the player character is forced to show the graphic of frame 0 in loop 0 of view VwSpec all the time, and all automatic processing that the Engine does has been shortcut. This frame contains your dynamic sprite, ready for pixel pushing.

3. In room_RepExec(), just do the pixel pushing
Something like
Code: ags
function room_RepeatExec()
{
    if (!Room17PlayerLocked)
        return; // character hasn't been set up yet
    
    DrawingSurface *dsu = Room17PlayerDS.GetDrawingSurface();
    // torture the pixels of dsu to your liking
    dsu.Release();   
}


You don't need to do anything special additionally for the variable "dsu" within the function room_RepeatExe(); the variable will be automatically destroyed when the code leaves the function.

4. However when you are done animating, your character should be released and the dynamic sprite should probably be released, too. So code something like the following and call that function whenever you are done animating.
Code: ags
function ReleasePlayer()
{
    Room17PlayerLocked = false;
    player.UnlockView();
    ViewFrame *frame = Game.GetViewFrame(VWSPEC, 0, 0);
    frame.Graphic = 0;
    Room17PlayerDS.Destroy();
}

Crimson Wizard

#7
Quote from: bx83 on Thu 05/03/2020 23:01:04
Actually surprisingly there isn't one :/ Oh well. Mostly defining variables in RepExec gives an error.

Could you please show the example of how do you define the variable, and tell what error does it give? Otherwise, I won't know what to suggest.

bx83

If I write:

Code: ags
function room_RepExec ()
{
    int x;
}


It will fail the next loop with error 'x already defined'.

Crimson Wizard

#9
Quote from: bx83 on Thu 05/03/2020 23:30:40
If I write:

Code: ags
function room_RepExec ()
{
    int x;
}


It will fail the next loop with error 'x already defined'.

Can you elaborate, what do you mean by "next loop"? Next time you have a while or for loop in script, or next time RepExec is called? Is this a compiler error, or it happens at runtime?

Thing is, the above is a perfectly fine code on it's own. Are you sure there's no other variables called "x" there?

EDIT:
Okay, probably you mean that you are reusing same variable again lower in script, but just not posted that, at least I'll assume that, because that's the only explanation I have.
In such case you simply not redeclare it with a type.
Code: ags

ViewFrame* frame = Game.GetViewFrame(...)
do something

frame = Game.GetViewFrame(...)
do something else

fernewelten

Quote from: fernewelten on Thu 05/03/2020 23:06:37
To circumvent the standard mechanisms and do my own animation, this is how I would do it:

If you don't want to push pixels in room_RepeatExec() but only want to choose pre-made sprites, you can use a similar, simpler approach:

2. becomes:
Code: ags
player.LockView(VWSPEC); 
Room17PlayerLocked = true;


3. becomes:
Code: ags
function room_RepeatExec()
{
    ViewFrame *frame = Game.GetViewFrame(VWSPEC, 0, 0);
    frame.Graphic = MySpecialWayOfSelectingASpriteNumber();
}

(You don't need to do anything special with the variable frame, it will be automatically taken care of when the function ends.)

4. becomes:
Code: ags
function ReleasePlayer()
{
    player.UnlockView();
}

ManicMatt

Quote
Thing is, the above is a perfectly fine code on it's own. Are you sure there's no other variables called "x" there?

I've never tried it but but wouldn't defining a variable in repeatedly execute mean that its trying to define the variable repeatedly, but it can only do this the once?

Crimson Wizard

#12
Quote from: ManicMatt on Thu 05/03/2020 23:43:47
Quote
Thing is, the above is a perfectly fine code on it's own. Are you sure there's no other variables called "x" there?

I've never tried it but but wouldn't defining a variable in repeatedly execute mean that its trying to define the variable repeatedly, but it can only do this the once?

A local variable is created every time a function is run and removed from memory every time it ends. During every run it's the new variable.
It does not matter what the function is, rep exec or not, this is one rule for a function in a programming language.

But I suspect, that is not relevant to the issue.

ManicMatt

Oh, my bad, but I learned something today. :)

I tend to stick to global variables, I didn't realise this declares a local variable.

SMF spam blocked by CleanTalk