I'm thinking of having my inventory screen (Sierra style) contain simple, repeated animations for each item. So, instead of a flat "coin," I'd show a coin slowly rotating or something. Is this possible (and simple) in AGS, or should I stick to static objects?
I don't think there's any way to make the actual inventory display a rotating object.
However, I don't know of any professional games that do this either.
For instance I can think of QFGV, the inventory images are static, but when you select them you see a rotating 3d image on the side. And in a game like Hitman, you can cycle your inventory, and the selected object rotates in 3D.
Both of the above options could be done in AGS. You would need to make the object a 3D model, and render out the full rotation, make that into a loop, then on your inventory GUI make a button or something and animate that button with the proper loop that represented the selected inventory item. I might be doing this in my game too.
It's possible, using some scripting:
(Code converted from my AGS v2.7 script module, so it may still contain some syntax errors.)
// main global script
struct struct_AnimatedInventoryItem {
int normalgraphic;
int view;
int loop;
int animationdelay;
int repeat;
int currentframe;
int currentdelay;
};
#define AGS_MAX_INV_ITEMS 300
struct_AnimatedInventoryItem AnimatedInventoryItem[AGS_MAX_INV_ITEMS];
function AnimateInventoryItem(int invitemid, int view, int loop, int delay, int repeat) {
if (AnimatedInventoryItem[invitemid-1].view == 0) // if inv item does NOT have a view set (isn't animating)
AnimatedInventoryItem[invitemid-1].normalgraphic = theinvitem.Graphic; // store inv item's current (normal) graphic
// store supplied settings for animation routines (see repeatedly_execute):
AnimatedInventoryItem[invitemid-1].view = view;
AnimatedInventoryItem[invitemid-1].loop = loop;
AnimatedInventoryItem[invitemid-1].animationdelay = delay;
AnimatedInventoryItem[invitemid-1].repeat = repeat;
// reset current status so animation starts from beginning when this function is called on already animating inventory items:
AnimatedInventoryItem[invitemid-1].currentframe = 0;
AnimatedInventoryItem[invitemid-1].currentdelay = 0;
}
function StopAnimatingInventoryItem(int invitemid, int keepcurrentframe) {
if (AnimatedInventoryItem[invitemid-1].view) { // if inv item has a view set (is animating)
AnimatedInventoryItem[invitemid-1].view = 0; // reset the view so inv item will not be animated anymore
if (keepcurrentframe == 0) SetInvItemPic(invitemid, AnimatedInventoryItem[invitemid-1].normalgraphic; // if current frame should not be kept, change inv item graphic back to normal
}
}
function repeatedly_execute() {
int invitemid = 0; // start with first inventory item (array index starts at 0)
while (invitemid < AGS_MAX_INV_ITEMS) { // loop for each inventory item
if (AnimatedInventoryItem[invitemid].view) { // if inv item has a view set (is animating)
if (AnimatedInventoryItem[invitemid].currentdelay) AnimatedInventoryItem[invitemid].currentdelay--; // if delay until next frame has NOT yet elapsed, decrease it
else { // if delay until next frame has elapsed
SetInvItemPic(invitemid+1, GetGameParameter(GP_FRAMEIMAGE, AnimatedInventoryItem[invitemid].view, AnimatedInventoryItem[invitemid].loop, AnimatedInventoryItem[invitemid].currentframe);
// change inv item's graphic to new frame
AnimatedInventoryItem[invitemid].currentdelay = AnimatedInventoryItem[invitemid].animationdelay + GetGameParameter(GP_FRAMESPEED, AnimatedInventoryItem[invitemid].view, AnimatedInventoryItem[invitemid].loop, AnimatedInventoryItem[invitemid].currentframe);
// set delay until next frame to animation delay + new frame's delay
AnimatedInventoryItem[invitemid].currentframe++; // set following frame to display next
if (AnimatedInventoryItem[invitemid].currentframe >= GetGameParameter(GP_NUMFRAMES, AnimatedInventoryItem[invitemid].view, AnimatedInventoryItem[invitemid].loop, 0)) { // if no more frames in view loop
if (AnimatedInventoryItem[invitemid].repeat == 0) StopAnimatingInventoryItem(inventory[invitemid+1], 0); // if animation was set to play once, stop animation (reverting to normal graphic)
else if (AnimatedInventoryItem[invitemid].repeat == 1) AnimatedInventoryItem[invitemid].currentframe = 0; // if animation was set to repeat, set first frame to display next
else if (AnimatedInventoryItem[invitemid].repeat == 2) StopAnimatingInventoryItem(inventory[invitemid+1], 1); // if animation was set to play once and to keep last frame, stop animation keeping current frame
}
}
}
invitemid++; // loop to next inventory item
}
}
// main script header
import function AnimateInventoryItem(int invitemid, int view, int loop, int delay, int repeat);
import function StopAnimatingInventoryItem(int invitemid, int keepcurrentframe);
Edit:
It may not work if your inventory GUI is set to "Popup modal" so you might need to set it to "Normal" and turn it off in game_start first.
Whoa, did you write all that for the purposes of this example, or are you using this in a game? If so...I'd be interested to know what game that is...because I didn't think you were into 3d..
As it were I wrote this just last week. I thought it would be a neat thing to be able to do.
I'll probably use it in my game, which at the moment is nothing more than a tech demo. I love scripting so much I don't get much else done. ;)
Quote from: strazer on Fri 08/04/2005 04:39:41
As it were I wrote this just last week. I thought it would be a neat thing to be able to do.
I'll probably use it in my game, which at the moment is nothing more than a tech demo. I love scripting so much I don't get much else done. ;)
And I would like to offer my appreciation for all that you do here .
Thank you. My pleasure, honestly. :)