Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: wynni2 on Sun 16/12/2018 19:42:21

Title: "flicker" effect when modifying ViewFrames while walking
Post by: wynni2 on Sun 16/12/2018 19:42:21
Hi all -

I'm working on an effect where characters appear to "wade" through water.

Right now it works by (1) making a DynamicSprite* dyWade from the character's currently displayed ViewFrame*, vwCurrent, (2) drawing a transparent rectangle over the bottom of dyWade, (3) assigning vwCurrent.Graphic = dyWade.Graphic, and (4) restoring vwCurrent.Graphic to its default value when the next animation frame is displayed.

This works well at low res with one issue: there's a "flicker" effect. I assume this is from the default sprite being drawn, and then the modified sprite being drawn an instant later. It's just a little distracting.

Is this something that I can work around (ie, is it possible to modify a character's current ViewFrame before it's drawn onto the screen)?

Here's the relevant code (dyWade, vwCurrent, vwLast, and lastgraphic are arrays declared elsewhere):

Code (ags) Select

void RestoreLastViewFrame(this Character*) {
  //restores the previously displayed ViewFrame for "this" to "lastgraphic," its default sprite
  //must be called after lastgraphic is stored
 
  vwLast[this.ID].Graphic = lastgraphic[this.ID];
  vwLast[this.ID] = null;
}

void MakeWadingSprite(this Character*, int depth) {
  //makes a wading sprite out of "this"'s current viewframe
  //  and stores it to dyWade[this.ID]
  //also saves the default graphic for "this"'s current ViewFrame to lastgraphic[this.ID]
 
  //must have stored vwCurrent[this.ID] before calling
  dyWade[this.ID] = DynamicSprite.CreateFromExistingSprite(vwCurrent[this.ID].Graphic, true);
  DrawingSurface* dwWade = dyWade[this.ID].GetDrawingSurface();
  dwWade.DrawingColor = COLOR_TRANSPARENT;
  int x1 = 0;
  int x2 = dyWade[this.ID].Width;
  int y2 = dyWade[this.ID].Height;
  int y1 = y2 - depth;
  dwWade.DrawRectangle(x1, y1, x2, y2);
  dwWade.Release();
 
  lastgraphic[this.ID] = vwCurrent[this.ID].Graphic;   
}

void Wade(this Character*) { //CALLED IN REPEATEDLY_EXECUTE
 
  vwCurrent[this.ID] = this.GetCharacterFrame(); //GetCharacterFrame(this Character*) returns ViewFrame for this.View, this.Loop, this.Sprite
 
  if (vwLast[this.ID] == null) {
    vwLast[this.ID] = vwCurrent[this.ID];
    this.MakeWadingSprite(15);
    vwCurrent[this.ID].Graphic = dyWade[this.ID].Graphic;
  }
  else if (vwLast[this.ID] != vwCurrent[this.ID]) {
    this.RestoreLastViewFrame();
  }
}
Title: Re: "flicker" effect when modifying ViewFrames while walking
Post by: Snarky on Sun 16/12/2018 20:25:50
Try calling it in late_repeatedly_execute_always()
Title: Re: "flicker" effect when modifying ViewFrames while walking
Post by: wynni2 on Sun 16/12/2018 22:15:03
Yep, that did it.

That was simpler than I expected. I had completely forgotten about late_repeatedly_execute.

Thanks.