Rotating large sprites

Started by AnasAbdin, Tue 19/01/2016 07:40:33

Previous topic - Next topic

AnasAbdin

Hello :-[

I am trying to make a sprite that is larger than the room to rotate. The sprite covers the entire room and tens of pixels more in each direction. I'm trying to make it rotate around the center of the room exactly at the point[320,200] forever. I tried using dynamic sprites but I couldn't make it work.

Question 1: Will it slow the game?
Question 2: How do I do that? ???


This is an illustration of what I'm trying to do:



Snarky

Quote from: AnasAbdin on Tue 19/01/2016 07:40:33I tried using dynamic sprites but I couldn't make it work.

Come on, Anas! You know the drill: Don't just say "it's not working!" Show us what you tried and explain how the results differ from what you want.

QuoteWill it slow the game?

Probably.

AnasAbdin

Hmphhh fine :-[

I used the following to test whether I'm right or wrong:

Code: ags
DynamicSprite* sp = DynamicSprite.CreateFromExistingSprite(205);
sp.Rotate(180);


The game ran normally but the sprite didn't show, I'm assuming maybe it rotated according to a corner point I'm not sure about and got drawn outside the room's view. I'm also not sure how walkbehinds will handle the sprite as well.

Crimson Wizard

Quote from: AnasAbdin on Tue 19/01/2016 09:24:48
Code: ags
DynamicSprite* sp = DynamicSprite.CreateFromExistingSprite(205);
sp.Rotate(180);


The game ran normally but the sprite didn't show

The code you posted does not display the sprite, but creates and rotates a completely new one. That sprite now exists in memory. Do you have a code that draws that new sprite on screen?

AnasAbdin

Quote from: Crimson Wizard on Tue 19/01/2016 09:32:47
Do you have a code that draws that new sprite on screen?

Nope.
I thought CreateFromExistingSprite(205) would take the sprite existing in slot number 205

Crimson Wizard

Quote from: AnasAbdin on Tue 19/01/2016 09:41:00
I thought CreateFromExistingSprite(205) would take the sprite existing in slot number 205
No, it creates a new sprite having a copy of original content.
You need to either draw sprite on room background using DrawingSurface, or assign it to some room object like
Code: ags

oMyObject.Graphic = sp.Graphic;

Note, in the latter case you would have to store Dynamic Sprite in the global variable, or it gets deleted immediately on function end.

Snarky

It doesn't overwrite the original sprite, it creates a new sprite in a new sprite slot (which you can look up in its DynamicSprite.Graphic property). But even if it did, you still need to somehow display it on screen. You can use an overlay, an object or a GUI button, for example: set their Graphic property to the sprite slot of the dynamic sprite. They'll interact with walkbehinds just the same way objects, overlays and GUI elements normally do.

(CW beat me to the punch: I'd just clarify that by "global variable" he means a variable declared outside of a function, not necessarily one of AGS's "Global Variables")

Monsieur OUXX

Quote from: Crimson Wizard on Tue 19/01/2016 09:45:14
Note, in the latter case you would have to store Dynamic Sprite in the global variable, or it gets deleted immediately on function end.

+1 for that, it's usually the trickiest part for beginners.
Also, please keep us posted on what you get, performance-wise, as well as regarding any other aspect that might be of concern to you.
 

AnasAbdin

#8
Thanks guys.
So far I managed to get the rotated sprite drawn on screen.
I just don't know where's the center of rotation ???

I managed to position the sprite so that the room is right in its center (remember the sprite is larger than the room). Still the sprite rotates outside the room's scope. Is there a way to make the sprite rotate's center a specific point?

This is the code I used so far:
Code: ags
DynamicSprite *sp;


Code: ags
sp = DynamicSprite.CreateFromExistingSprite(object[1].Graphic);
sp.Rotate(5);

object[1].Graphic = sp.Graphic;

//the following line is just for testing something...
object[1].SetPosition(-914, 780);

Snarky

When you rotate, the sprite dimensions will be set as necessary to fit the rotated sprite. In other words, the dimensions will be the bounding box of the rotated sprite, aligned so that the left and top edges are at (0,0), because sprites always start at (0,0).

Because of symmetry, the center of the original sprite will be at sp.Width/2,sp.Height/2 (the new width and height, which depend on the rotation). So you just need to align that point with the center of the room.

AnasAbdin

Thanks Snarky ;-D
I got it to work using:

Code: ags
object[1].SetPosition(320 - (sp.Width/2),  200 + (sp.Height/2));


but sad news for Monsieur OUXX and me :~( the performance is bad...
So I guess I'll either have to use a smaller sprite or find another way to achieve the effect I was looking for (nod)

Thanks CW for your help and lesson 8-)

Monsieur OUXX

Quote from: AnasAbdin on Tue 19/01/2016 12:59:47
but sad news for Monsieur OUXX and me :~( the performance is bad...

Bad how? What's your current FPS?
Also, Don't you ever use hard-coded dimensions, you evil astronaut. System.ViewportWidth all the way!
 

AnasAbdin

er... how do I know my FPS? :-D

I'm using:

AGS 3.3.3
Direct3D 9 hardware acceleration
640x400 32bit


Khris

Call Debug(4, 1); to turn on the FPS counter.

I was doing the same thing (rotating a big sprite) for the Mario Kart clone, and I ended up prerendering the rotated versions. Not only was the performance impact huge, but there's a small "bug" in the Rotate code that will make the rotated pixels jump all over the place the further you are away from the rotation's center. Some of you might remember an earlier Kart demo of mine where the track was extremely jittery while cornering.

AnasAbdin


SMF spam blocked by CleanTalk