Player sprite editing

Started by Calin Leafshade, Sun 08/08/2010 21:30:54

Previous topic - Next topic

Calin Leafshade

HI!

ok so i'm trying to write a function which replaces a colour in a sprite.

that part is easy but i get these sprites from a view frame and set the dynamic sprite back to the viewframe.

Now, when I do this it obviously changes the viewframe and the next time the function comes round the colour will no longer be there and/or it will crash when it tries to get a new sprite from viewframe because the vf points to a dynamic sprite.

So i need to set the sprite to the vf but save the spriteslot so I can reset the viewframe back once the animation has moved onto the next frame.

The code below *kinda* works but the colours flicker because i'm not resetting the viewframes properly and its alternating between a fixed sprite and the original.

can anyone see the flaw in my logic?

(If a variable is not declared explicitly in the code then its a global)

Code: ags


function DoEyes(){
  
  
  ViewFrame *vf = player.GetViewFrame();
  if (Prevf != null && (Prevf.View != vf.View || Prevf.Loop != vf.Loop || Prevf.Frame != vf.Frame)) Prevf.Graphic = PrevSprite;
  
  
  PrevSprite = vf.Graphic;
  Prevf = vf;
  
  PlayerSprite = DynamicSprite.CreateFromExistingSprite(vf.Graphic, true);
  DrawingSurface *ds = PlayerSprite.GetDrawingSurface();
  int x, y;
  while (y < PlayerSprite.Width){
    
    while (x < PlayerSprite.Height){
      int colour = ds.GetPixel(x, y);
      if (colour == 59360){
        ds.DrawingColor = EyeColor;
        ds.DrawPixel(x, y);
          
        
      }
        
      x++;
    }
    x = 0;
    y ++;
  }
  ds.Release();
  
  
  vf.Graphic = PlayerSprite.Graphic;
  
  
}


Kweepa

I haven't looked at the big picture, but in the inner loop you're looping x from 0-height and y from 0-width, rather than x from 0-width and y from 0-height.
I think SetPixel has error checking so I don't think it's a big deal...
Still waiting for Purity of the Surf II

tzachs

Well, it's a guess but maybe when you get the view frame it's already after it was rendered to the screen...

I would try to do the same logic, only instead of working with the current and previous frames, to work with the next and current frame...

Calin Leafshade

It seems AGS does some very strange things when you try to edit the current viewframe so instead I made a function which dumps all the pixels that need changing (the eyes if you hadnt guessed) to a file.

Then, on startup the game loads those values to a struct and then when I need to replace those values I iterate through every sprite in the struct changing all the pixels at once and apply those to all the viewframes.

It's one hell of a cluster-fucknction...

monkey0506

Quote from: Calin Leafshade on Sun 08/08/2010 21:30:54Now, when I do this it obviously changes the viewframe and the next time the function comes round the colour will no longer be there and/or it will crash when it tries to get a new sprite from viewframe because the vf points to a dynamic sprite.

So i need to set the sprite to the vf but save the spriteslot so I can reset the viewframe back once the animation has moved onto the next frame.

I'm a bit confused by this. What do you mean "it will crash..because the vf points to a dynamic sprite"?

A ViewFrame.Graphic property can validly be set to a DynamicSprite.Graphic property so long as the DynamicSprite remains in memory (i.e., there is a DynamicSprite* pointing to the sprite). If you remove the DynamicSprite from memory while the ViewFrame.Graphic is still set to the sprite's Graphic, then this will cause problems. Is that what you're describing? If so, the solution is simply to change the ViewFrame.Graphic before removing the DynamicSprite from memory.

Otherwise I don't know what you mean.

Calin Leafshade

no rather what i mean is that when the sprite comes round again (in an animation) the DynamicSprite.CreateFromExistingSprite() will try to create a dynamic sprite from *another* dynamic sprite because the vf currently points to the Dynamic sprite we set the first time around.

monkey0506

#6
But that's a problem..because?

Code: ags
DynamicSprite *one = DynamicSprite.CreateFromExistingSprite(42);
DynamicSprite *two = DynamicSprite.CreateFromExistingSprite(one.Graphic);


Doesn't seem to cause any issues. You said it would crash..?

If the DynamicSprites weren't being removed from memory then sure, that could potentially yield a memory leak..but they are being freed..so..?

Calin Leafshade

firstly that isnt what would happen in a loop.

this would:
Code: ags

DynamicSprite *one = DynamicSprite.CreateFromExistingSprite(one.graphic);


Having two alternating sprites does fix this.

However I really need the sprite to get the *original un-edited* sprite each time to apply the colour swap because the new sprite wouldnt contain my special colour to be replaced.

monkey0506

Well, you said "will try to create a dynamic sprite from *another* dynamic sprite".

Besides, this works perfectly fine:

Code: ags
DynamicSprite *one = DynamicSprite.CreateFromExistingSprite(42);
one = DynamicSprite.CreateFromExistingSprite(one.Graphic);


Because the new DynamicSprite gets created from the existing DynamicSprite before the original DynamicSprite gets replaced by the new one.

Anyway, if you need to use the original sprite, why not just reset ViewFrame.Graphic before running your modifications? I can't imagine that:

Code: ags
vf.Graphic = ORIGINAL_SPRITE;
// modify sprite
vf.Graphic = MODIFIED_SPRITE


Within the same function would really allow time enough to refresh the screen with the changes.

SMF spam blocked by CleanTalk