Animating the inv item cursor hotspot marker sprite

Started by markbilly, Tue 08/06/2010 16:02:50

Previous topic - Next topic

markbilly

So, I'd like to be able to have an animated inventory item cursor hotspot marker sprite. At the moment, the ordinary cursor will animate when over a hotspot/object. I want to have the inventory cursors to do the same.

Any ideas?

Have I missed this somewhere in the help file/manual?

Thanks,
Mark
 

Khris

The item is the actual cursor; the little crosshair or custom icon is just added to that, so no, this isn't supported directly.

You can emulate what you want though by using an array of DynamicSprites. Make them copies of the inv item graphic, draw the marker animation frames on them, then cycle through them using Mouse.ChangeModeGraphic.
Takes a bit of scripting though.

tzachs

Another option (I think) would be to use Mouse.ChangeModeView.

Create the views beforehand like you do for all other objects.
Set "Handle inventory clicks in script" to true,
set "Use selected inventory graphic for cursor" to false,
and then when an inventory item is clicked change use Mouse.ChangeModeView where the view is the matching view for the clicked inventory item.

Some scripting required here as well, but at least no need to involve dynamic sprites and switching the frames yourself...

Wyz

When I tried something similar I ended up this solution:
You could create a DynamicSprite and draw the original cursor sprite on it. That also means you need to program the animations your self (keep track of the view and frame somewhere and draw the next frame periodically using repeatedly_execute). I don't know if that helps you though. :)
Life is like an adventure without the pixel hunts.

markbilly

#4
tzachs's idea sounds like the simplest solution. I'll have a go at it tomorrow. Thanks everyone :)

Actually, would putting a:

Code: ags

if (active inv = key)
{
Mouse.ChangeModeView(key cursor animation view);
}


in repeatedly_execute_always for all inventory items work?
 

Khris

It might be easier but is much more work. Assuming the marker animation had five frames and there were 30 inv items, that's 30 views and 150 sprites. Now imagine you want to change the animation...

Plus, putting it in rep_ex(_always) like that won't work. Code in there is called 40 (by default) times per second. The animation wouldn't have a chance to start.

To refine my suggested solution:

-Create a view called INVCURVIEW with one loop and as many frames as the animation requires.

-In General Settings / Inventory, set the last option to false.

-In the properties of the Use inv cursor, set Animate to true, the following two are optional.

-Import the sprites that make up the marker animation and make sure they occupy consecutive slots.

-Paste the code to your Global.asc (merge rep_ex_always / delete the existing one).

-Alter the three #define lines to suit your requirements. MARKER_OFFSET allows you to move the marker outside the item; in the example, a transparent border six pixels wide is added to the top and left of the cursor graphic.

Code: ags
#define INV_CUR_FRAMES 4
#define INV_CUR_FIRST_SLOT 7
#define MARKER_OFFSET 6

DynamicSprite*inv_cur[INV_CUR_FRAMES];

void UpdateInvCurView() {

  if (player.ActiveInventory == null) return;

  int i, w, h;
  DrawingSurface*ds;
  ViewFrame*vf;
  mouse.ChangeModeView(eModeUseinv, -1);
  while (i < INV_CUR_FRAMES) {
    // if (inv_cur[i] != null) inv_cur[i].Delete();
    inv_cur[i] = DynamicSprite.CreateFromExistingSprite(player.ActiveInventory.Graphic, true);
    w = inv_cur[i].Width;
    h = inv_cur[i].Height;
    // add transparent border to left and top
    inv_cur[i].ChangeCanvasSize(w+MARKER_OFFSET, h+MARKER_OFFSET, MARKER_OFFSET, MARKER_OFFSET);
    ds = inv_cur[i].GetDrawingSurface();
    ds.DrawImage(0, 0, i + INV_CUR_FIRST_SLOT);
    ds.Release();
    vf = Game.GetViewFrame(INVCURVIEW, 0, i);
    vf.Graphic = inv_cur[i].Graphic;
    i++;
  }
  mouse.ChangeModeGraphic(eModeUseinv, inv_cur[0].Graphic);
  mouse.ChangeModeView(eModeUseinv, INVCURVIEW);
}

InventoryItem*oldai;

void repeatedly_execute_always() {
  if (player.ActiveInventory != oldai) {
    UpdateInvCurView();
    oldai = player.ActiveInventory;
  }
}


Tested, working. May contain bugs.

markbilly

#6
My God, you're kind! :)

I'll get this tested in the next few hours and get back to you.

Thanks so much.

EDIT: Works a dream!
 

SMF spam blocked by CleanTalk