Animating leaves (heavy gif warning)

Started by eri0o, Mon 25/06/2018 05:28:51

Previous topic - Next topic

eri0o

was anyone ever able to recreate leaves animating in low resolution games (320x240 // 320x180) through code in success?

I am looking for an effect similar to the one in Owlboy.

Spoiler


[close]

I looked over the Underwater module, because it's the most similar I could remember, but I don't understand yet how to modify until a flailing effect can be made.

Spoiler

LeavesAnimation.asc
Code: ags

// new module script
#define MAX_FRAMES 10

#define MAX_BLOCKS 128


int block_w;
int block_h;
int block_x[MAX_BLOCKS];
int block_y[MAX_BLOCKS];

bool Leaves_enabled = false;
int original_graphic;

float tt = 0.0;
float t = 0.0;
float a[MAX_FRAMES], b[MAX_FRAMES], c[MAX_FRAMES];

DynamicSprite * dyn_spr;

static void LeavesAnimation::SetBaseGaphic(int leavesGraphic){
  if(dyn_spr!=null){
    dyn_spr.Delete();  
  }
  original_graphic = leavesGraphic;
  dyn_spr = DynamicSprite.CreateFromExistingSprite(original_graphic, true);
}

static int LeavesAnimation::GetGaphic(){
  if(dyn_spr!=null){
    return dyn_spr.Graphic;  
  }
  return 0;
}

static void LeavesAnimation::Enable() {
  float scalar = 8000.0;
  int i = 0;
  
  int delta1 = Random(MAX_FRAMES-1);
  int delta2 = Random(MAX_FRAMES-1);
  int delta3 = Random(MAX_FRAMES-1);
  
  while (i < MAX_FRAMES) {
    a[i] = Maths.Cos(Maths.Pi*IntToFloat((delta1+i)%MAX_FRAMES)/IntToFloat(MAX_FRAMES));  //IntToFloat( Random(2000)*(Random(1)-1) )/scalar;
    b[i] = Maths.Sin(Maths.Pi*IntToFloat((delta2+i)%MAX_FRAMES)/IntToFloat(MAX_FRAMES));  //IntToFloat( Random(2000)*(Random(1)-1) )/scalar;
    c[i] = Maths.Cos(Maths.Pi*IntToFloat((delta3+i)%MAX_FRAMES)/IntToFloat(MAX_FRAMES));  //IntToFloat( Random(2000)*(Random(1)-1) )/scalar;
    i++;
  }
  
  block_w = Game.SpriteWidth[original_graphic]/48;
  block_h = Game.SpriteHeight[original_graphic]/24;
  
  i = 0;
  while (i < MAX_BLOCKS) {
    block_x[i] = Random(Game.SpriteWidth[original_graphic]- 1 - block_w);
    block_y[i] = Random(Game.SpriteHeight[original_graphic] - 1 - block_h);
    i++;
  }
  Leaves_enabled = true;
}

static void LeavesAnimation::Disable() {
  Leaves_enabled = false;
}

float get_gradient_x(int xi, int yi) {
  float x = IntToFloat(xi)/160.0 - 1.0;
  float y = IntToFloat(yi)/160.0 - 1.0;

  float dx = 0.0;
  
  int i = 0;
  while (i < MAX_FRAMES) {
    dx += a[i]*t*Maths.Cos(a[i]*t*x + b[i]*t*y + c[i]);
    i++;
  }
  return dx;
}

float get_gradient_y(int xi, int yi) {
  float x = IntToFloat(xi)/160.0 - 1.0;
  float y = IntToFloat(yi)/160.0 - 1.0;

  float dy = 0.0;

  int i = 0;
  while (i < MAX_FRAMES) {
    dy += b[i]*t*Maths.Cos(a[i]*t*x + b[i]*t*y + c[i]);
    i++;
  }
  return dy;
}

function offset_a_block(DrawingSurface *surf, int x, int y, int w, int h) {
  int xoff = FloatToInt(1.0*get_gradient_x(x + w/2, y + w/2));
  int yoff = FloatToInt(1.0*get_gradient_y(x + h/2, y + h/2));
  
  xoff = Utils.clampInt(xoff, 1, -1);
  yoff = Utils.clampInt(yoff, 1, 0);
  
  //w = Utils.clampInt(w, Game.SpriteWidth[original_graphic]-x, 1);
  //w = Utils.clampInt(w, Game.SpriteHeight[original_graphic]-y, 1);
  
  DynamicSprite *ds = DynamicSprite.CreateFromDrawingSurface(surf, x, y, w, h);
  //surf.DrawingColor = COLOR_TRANSPARENT;
  //surf.DrawRectangle(x, y, x+w, y+w);
  surf.DrawImage(x - xoff, y - yoff, ds.Graphic);
}

function repeatedly_execute_always() {
  if (Leaves_enabled) {
    if(dyn_spr==null){
      return;
    }
    
   if(getCurrentFrame()%4!=0){
      return;  
    }
    
    tt = tt + 0.01;
    float k = Utils.clampFloat((2.0*Maths.Pi*Maths.Sin(tt)), 8.0, 0.0) ; ///8.0;

    t=1.0;

    if(dyn_spr!=null){
      dyn_spr.Delete();  
    }
    dyn_spr = DynamicSprite.CreateFromExistingSprite(original_graphic, true);

    //SetBackgroundFrame(0);
    // repeatedly grab a random chunk from bg 1 and paste it to bg 0, slightly offset
    DrawingSurface *surf = dyn_spr.GetDrawingSurface();  //Room.GetDrawingSurfaceForBackground(0);

    int i = 0;
    while (i < MAX_BLOCKS) {
      if(Random(FloatToInt(k))==0){
        block_x[i] = Random(Game.SpriteWidth[original_graphic]- 1 - block_w);
        block_y[i] = Random(Game.SpriteHeight[original_graphic] - 1 - block_h);
      }
      //int x = Random(Game.SpriteWidth[original_graphic]- 1 - block_w);
      //int y = Random(Game.SpriteHeight[original_graphic] - 1 - block_h);
      offset_a_block(surf, block_x[i], block_y[i], block_w, block_h);
      i++;
    }

    surf.Release();
  }
}


    // draw some more around the player
    // ViewFrame *frame = Game.GetViewFrame(player.View, player.Loop, player.Frame);
    // int graphic = frame.Graphic;
    // int height = FloatToInt(IntToFloat(Game.SpriteHeight[graphic]*player.Scaling)/100.0);
    // int width  = FloatToInt(IntToFloat( Game.SpriteWidth[graphic]*player.Scaling)/100.0);
    // int left = player.x - width/2;
    // int top = player.y - height - player.z;

    // i = 0;
    // while (i < 32) {
    //   i++;
    //   int w = Room.Width/64;
    //   int x = left - w/2 + Random(width - 1);
    //   int y = top - w/2 + Random(height - 1);
    //   if (x < 0) x = 0;
    //   else if (x >= Room.Width - w) x = Room.Width - 1 - w;

    //   if (y < 0) y = 0;
    //   else if (y >= Room.Height - w) y = Room.Height - 1 - w;   

    //   offset_a_block(surf, x, y, w);
    // }


LeavesAnimation.ash
Code: ags

// new module header

struct LeavesAnimation {
  
import static void Enable();
import static void Disable();
import static void SetBaseGaphic(int leavesGraphic);
import static int GetGaphic();

};

[close]

Here is a different gif idea (but I still can't understand how to implement leaf animation on the bg...)
Spoiler


[close]

SMF spam blocked by CleanTalk