Reflections (SOLVED)

Started by Calin Leafshade, Fri 23/10/2009 16:00:03

Previous topic - Next topic

Calin Leafshade

hey guys,

I've just started working with dynamic sprites and they seem pretty cool.

However i've tried to make a puddle with the below code but in game it seems a little bit choppy. any ideas whatI'm doing wrong?

Code: ags

function Puddle_Update()
{
        
  		DynamicSprite *bg = DynamicSprite.CreateFromBackground(); //Create Background Sprite
      if (cEgo.x > 160 && cEgo.x < 200 && cEgo.y > 140) //Check if character is within bounds of puddle
      {
          DrawingSurface *bgs = bg.GetDrawingSurface();
          ViewFrame *currentview = Game.GetViewFrame(cEgo.View, cEgo.Loop, cEgo.Frame); // Get characters current frame
          DynamicSprite *MPuddle = DynamicSprite.CreateFromExistingSprite(currentview.Graphic, true); //create sprite from that frame.
          if (currentview.Flipped == true){
               MPuddle.Flip(eFlipLeftToRight);// If view is flipped then flip the character reflection sprite
          }
          bgs.DrawImage(cEgo.x - (MPuddle.Width/2), cEgo.y - MPuddle.Height, MPuddle.Graphic, 60); // draw character sprite on bg sprite
      }
      bg.Crop(160, 160, 40, 20); //Crop the sprite to a small rectangle from the puddle (i'll make it non rectangular later)
      bg.Flip(eFlipUpsideDown); // flip the reflection
		  DrawingSurface *surface = Room.GetDrawingSurfaceForBackground();
      surface.DrawImage(160, 180, bg.Graphic); //Draw reflection
      surface.Release();
      bg.Delete();

}

Crimson Wizard

Firstly, you do not Release bgs Drawing surface, and do not Delete MPuddle dynamic sprite. That may cause memory leak.

Calin Leafshade

#2
Quote from: Crimson Wizard on Fri 23/10/2009 16:10:12
Firstly, you do not Release bgs Drawing surface, and do not Delete MPuddle dynamic sprite. That may cause memory leak.

Thats true thanks,

I think the problem stems from the fact that character animations are anchored to the centre of the sprite not the corner.. so as i redraw it, it jumps all over the place during the animation.

nope thats not true since the animation stutters even on the idle animation.

Ok i think i've identified the problem as this line

Code: ags

ViewFrame *currentview = Game.GetViewFrame(cEgo.View, cEgo.Loop, cEgo.Frame); // Get characters current frame


It doesnt seem to consistently get the current frame for the character.

Various debugging methods seem to show that the .frame property isnt reliable in a game loop.

Any ideas how to find the characters current sprite easier?

GarageGothic

I've had the same problem with the ViewFrame not being accurate (or rather, the character's frame seemingly being úpdated at the end of the loop, before rendering so the DynamicSprite sometimes lag one frame behind). An easy fix is to make the actual player character invisible and use a visible dummy character whose ViewFrame is set to the current player ViewFrame and coordinates set to (player.x, player.y) every loop in the repeatedly_execute(). Of course you also need to move the dummy character to the player's room in the Enters Room Before Fade-in event.

monkey0506

Quote from: Crimson Wizard on Fri 23/10/2009 16:10:12
Firstly, you do not Release bgs Drawing surface, and do not Delete MPuddle dynamic sprite. That may cause memory leak.

Failure to release the bgs DrawingSurface would mean that the actual DynamicSprite wouldn't be getting properly updated. However AGS's memory management would prevent actual memory leaks from this.

I've never encountered any issues with the Character.Frame property not matching the actual visible frame. Sounds to me like it might have something to do with a scripting problem, but otherwise it might be a bug in AGS. What version(s) of AGS are you using when you're encountering this problem? What are the aforementioned debugging methods that have unearthed this problem? Is there anywhere in the manual that might reference such a delay in the property being updated (if there is it isn't referenced on the Character.Frame page)??

Calin Leafshade

Well I added the following line

Code: ags

      RoomSurface.DrawString(10, 10, eFontFont0, "%d %d %d",cEgo.View, cEgo.Loop, cEgo.Frame);


and the frame value seems to jump a little.

If i watch the idle animation its almost as if it plays the frames like 1, 2, 1, 3, 2, 4 etc

This is current code im using

Code: ags

function Puddle_Update()
{
      DynamicSprite *SurfaceBuffer = DynamicSprite.Create(320, 200);  
  		DynamicSprite *bg = DynamicSprite.CreateFromBackground(); //Create Background Sprite
      
      bg.Flip(eFlipUpsideDown); // flip the reflection
   
          DrawingSurface *bgs = bg.GetDrawingSurface();
          ViewFrame *currentview = Game.GetViewFrame(cEgo.View, cEgo.Loop, cEgo.Frame); // Get characters current frame
          DynamicSprite *MPuddle = DynamicSprite.CreateFromExistingSprite(currentview.Graphic, true); //create sprite from that frame.
          if (currentview.Flipped == true){
               MPuddle.Flip(eFlipLeftToRight);// If view is flipped then flip the character reflection sprite
               
          }
          MPuddle.Flip(eFlipUpsideDown); //flip character sprite
          MPuddle.Tint(255, 255, 255, 100, 85); // to match room lighting
          
          bgs.DrawImage(cEgo.x - (MPuddle.Width/2), 200 - (cEgo.y - MPuddle.Height), MPuddle.Graphic, 60); // draw character sprite on bg sprite

      
    bg.Crop(150, 40, 50, 20); //Crop the sprite to a small rectangle from the puddle (i'll make it non rectangular later)
      DrawingSurface *RoomSurface = Room.GetDrawingSurfaceForBackground();
		  DrawingSurface *surface = SurfaceBuffer.GetDrawingSurface();
      surface.DrawImage(150, 180, bg.Graphic); //Draw reflection
      surface.DrawImage(cEgo.x - (MPuddle.Width/2), cEgo.y + 2, MPuddle.Graphic); // draw character sprite on bg sprite
      surface.DrawImage(0, 0, 286); //Draw Transparency Mask for puddle.
      RoomSurface.DrawSurface(surface);
      RoomSurface.DrawingColor = 14;
      RoomSurface.DrawString(10, 10, eFontFont0, "%d %d %d",cEgo.View, cEgo.Loop, cEgo.Frame);
      surface.Release();
      RoomSurface.Release();
      bgs.Release();
      bg.Delete();  
      SurfaceBuffer.Delete();
      MPuddle.Delete();

}


and here is what it looks like (sorry for large file)

http://www.thethoughtradar.com/AGS/puddle.zip




Calin Leafshade

FIXED!

I had 2 identical backgrounds in the room. i didnt seem them animating but they were messing up my dynamic sprites.

WINNER!

monkey0506

Quote from: Calin Leafshade on Sat 24/10/2009 00:21:45and the frame value seems to jump a little.

If i watch the idle animation its almost as if it plays the frames like 1, 2, 1, 3, 2, 4 etc

What is the animation delay? Have you tried using perhaps a Display call to actually verify the order of the frames? You could do it like:

Code: ags
int prevFrame = -1;

function repeatedly_execute() {
  if (cEgo.Frame != prevFrame) Display("old frame: %d, new frame: %d", prevFrame, cEgo.Frame);
  prevFrame = cEgo.Frame;
}


It might be possible depending on the animation delay, game speed, screen refresh rate, etc. that you might just not actually be seeing the frame numbers updated at the appropriate times even if the animation is played in the right order.

Again I'm not saying you're wrong, but just trying to help generate ideas to figure out exactly what's going on here.

Calin Leafshade

After i removed the second problematic background frame, the .frame property seems to work perfectly.. im not sure if its a bug or just that the 2nd background frame was somehow affecting the drawingsurface.

Pumaman

The drawing surface commands operate on the current background, so it would have been continually switching between which background was being drawn onto, as the animated backgrounds switched.

Glad it's sorted!

SMF spam blocked by CleanTalk