rotate animated character in real 2d

Started by selmiak, Sat 01/09/2012 21:12:24

Previous topic - Next topic

selmiak

I hope this is rather easy, if not feel free to move this to advanced.

Imagine a little buggy as a character in a total 2d sideview game driving left and right (like these motocross Flash games). And then the first slope comes, say in a 30° angle. So I'd use different regions to set the angle, but how to I rotate the character? I know there is a draw function but I can't get it to work on characters. And will it rotate around the middle of the bottom line and draw the sprite according to the x/y position of the middle of the bottom line, or will it create a new reactangle around the whole rotated sprite and use the middle of the bottom line of this?

Another thing, using a view for the animation of the character and keeping loop 0 (down) with sprite image 0 and no loop 3 (up) at all will only use left and right animations, even if the caracter moves "up" and "down", right? So if the charater moves straight "up", how does AGS decide which view to use?

another idea would be to have a specific views for every angle, but I don't want to pixel all this and there is also the bottom line problem mentioned above.

Khris

You can rotate a character by rotating all its view's frames.
I'd create a second view with all the necessary frames (just assign sprite 0 to them). In-game, iterate through the loops and their frames, and assign DynamicSprites to them using Game.GetViewFrame().

That way you can create an entire view on the fly.

If you use the DynamicSprite.Rotate function, the sprite will be rotated around its center. A possible solution is to expand the canvas of all the character sprites so the pivot is always centered, then reposition the car using car.z = Game.SpriteHeight[current_sprite]/2; (in rep_exe, of course).

How I'd go about this depended on the animation of the buggy. I'd probably pre-render the chassis at various angles and animate the wheels separately.

Regarding the "only left and right loops" issue, I'm not sure AGS is that "clever", in my experience at least, having only one frame in a loop doesn't prevent AGS from showing it during walking.
The thing is, I'm not sure I'd even use built-in walking for a 2D buggy race game. Or rather, I'm sure I wouldn't use it :)
For games like this, the proper way is to raw draw the entire thing or directly change the coordinates of characters.

selmiak

uhm... thanks for the reply, but... how?

Khris

I guess you're referring to rotating the frames?
Code: ags
// global DynamicSprite array
DynamicSprite*d[20];

void CreateRotatedView(int angle) {
  int v = 1;  // view goes here
  int nv = 2;  // dummy view for rotated sprites goes here
  int l = 1, f;   // start at loop 1, frame 0
  ViewFrame*vf;
  int di = 0;      // index of dynamic sprite array
  while (l <= 2) {
    f = 0;
    while (f < Game.GetFrameCountForLoop(v, l)) {
      vf = Game.GetViewFrame(v, l, f);
      d[di] = DynamicSprite.CreateFromExistingSprite(vf.Graphic);
      d[di].Rotate(angle);
      vf = Game.GetViewFrame(nv, l, f);
      vf.Graphic = d[di].Graphic;
      di++;
      f++;
    }
    l++;
  }
}


This will put a copy of view v into view nv (at least loops 1 and 2), where each sprite is rotated by angle degrees.

selmiak

what does void do?

How do I call and manipulate the angle while ingame?

Snarky

void is a function that doesn't return a value. You call it like any other function, by writing the function name followed by the arguments in parenthesis. For example:

Code: AGS

    CreateRotatedView(10);  // Create a view rotated by 10 degrees

Khris

Btw, I haven't tested this and I have no idea how fast it is. The speed also depends on the size of the sprites, of course.

There might be a noticeable pause/FPS drop when you call this "in real-time".

selmiak

hehey, got the rotation working. Thanks a lot.
But as I thought the character is drawn above where it is supposed to be as the bottom line changed. How can I draw the character somewhere else, related to the actual current position but keep it on a rather slim walkable area? Is this even possible? I fiddled around with a dummy character in the correct position but the dummy won't animate if I put it on screen related to actual position (in room_RepExec with cDummy.x = player.x+20; and so on).

Khris

If you just need to offset the character vertically, you can use their .z property.

Positioning a dummy doesn't animate them, only calling .Walk() does.

What you can do is:
Code: ags
 // in rep_ex_always
  cDummy.Loop = player.Loop;
  cDummy.Frame = player.Frame:

selmiak


selmiak

I have no idea where my first post in this thread went, but I have another, rather cosmetic problem. When using the rotation script I get the following error message in warnings.log:
Quote(in room 2): Dynamic sprite 64 was never deleted
(in room 2): Dynamic sprite 65 was never deleted
(in room 2): Dynamic sprite 66 was never deleted
(in room 2): Dynamic sprite 67 was never deleted
(in room 2): Dynamic sprite 68 was never deleted
(in room 2): Dynamic sprite 69 was never deleted
(in room 2): Dynamic sprite 70 was never deleted
(in room 2): Dynamic sprite 71 was never deleted
(in room 2): Dynamic sprite 72 was never deleted
(in room 2): Dynamic sprite 73 was never deleted
(in room 2): Dynamic sprite 74 was never deleted
(in room 2): Dynamic sprite 75 was never deleted
(in room 2): Dynamic sprite 76 was never deleted
(in room 2): Dynamic sprite 78 was never deleted
(in room 2): Dynamic sprite 79 was never deleted
(in room 2): Dynamic sprite 80 was never deleted
(in room 2): Dynamic sprite 81 was never deleted
(in room 2): Dynamic sprite 82 was never deleted
These sprite numbers start with the first free sprite slot, so, where do I delete these in the code?

Crimson Wizard

#11
This is a quite usual thing when you use global Dynamic Sprites in AGS. Unfortunately, AGS does not have "On Quit" event that will let you to delete your stuff in time.
AGS deletes all created Dynamic sprites anyway. But it still posts those annoying warnings.
Possible solution is to delete them when player quits using available in-game option. But that won't work in case user exits by hitting Alt+X or closing the window by X button in the corner.

SMF spam blocked by CleanTalk