|
Timing is Everything! Displaying 1-20 of 29 total.
12
next
cronoodle
|
Ok, i used grabregion to make an attack animation. I actually got it to display, and other than a few placement issues, and a problem w/ layering, it's working good. my main problem has to do with timing. if i use a wait(10) everything in the animation looks good, but the player cant move. (actually, u do move, but it doesn't show it on the screen till the wait is over) i have the same problems with entities where they start warpin all over the screen if u press the attack button a lot. also, if you press it repeatedly, you have to wait a while before you can start moving yourself again. any suggestions on what i could do to fix this would be appreciated greatly.
here's some of my code to show you what i'm doing.
void Wait(int wait_delay)
// Does nothing for set time period
// Pass: how long to wait for in 100ths of a second
// Credit to Shadow64 for ShadowClock here
{
int wait_till = timer + wait_delay + 1; // Sets when the delay will run till
wait_delay = timer; // Record current timer value (see below)
while(timer < wait_till) // Untill time is reached
{
UpdateControls(); // Check inputs
// no such thing :( -> processentities();//keep everyone moving
}
timer = wait_delay; // Reset timer to what it started as (optional)
}
// yeah, i definitely stole that from the site! go shadow!
// this part is a lil long, but hopefully you can sift thru it.
void attack()
{
int attackimg = loadimage('attackfull.pcx');
int font = loadfont('smallfont1.gif');
int displayimg;
int frame = 1;
// makes my variables and loads a font that i was using for debugging.
switch(entity.face[player])//determining which way the player is facing.
{
case 1: while(frame<4)//facing up
{
if(frame=1)
{
grabregion(1,1,64,64,
(entity.x[player]-xwin),(entity.y[player] -ywin -64),attackimg,screen);
showpage();
wait(3);
//I lowered the wait to 3 which is WAAAY too fast, but at least you can see
//all the frames, and no one really twitches.
frame++;
}
else if(frame >1)
{
render();
grabregion(1,(1+(64 * frame-64)),64,(64 * frame),
(entity.x[player]-xwin),(entity.y[player] -ywin -64),attackimg,screen);
showpage();
wait(3);
frame++;
}
}
case 2: while(frame<4)//facing down
{
if(frame=1)
{
grabregion(1,1,64,64,
(entity.x[player]-xwin),(entity.y[player] -ywin -16),attackimg,screen);
showpage();
wait(3);
frame++;
}
else if(frame >1)
{
render();
grabregion(1,(1+(64 * frame -64)),64,(64 * frame),
(entity.x[player]-xwin),(entity.y[player] -ywin -16),attackimg,screen);
showpage();
wait(3);
frame++;
}
}
//grabregion(1,1,64,64,
// (entity.x[player]-xwin),(entity.y[player] -ywin +16),attackimg,screen);
//showpage();
case 3: while(frame<4)//facing left
{
if(frame=1)
{
grabregion(1,1,64,64,
(entity.x[player]-xwin -64),(entity.y[player] -ywin ),attackimg,screen);
showpage();
wait(3);
frame++;
}
else if(frame >1)
{
render();
grabregion(1,(1+(64 * frame -64)),64,(64 * frame),
(entity.x[player]-xwin -64),(entity.y[player] -ywin ),attackimg,screen);
showpage();
wait(3);
frame++;
}
}
//grabregion(1,1,64,64,
// (entity.x[player]-xwin -64),(entity.y[player] -ywin ),attackimg,screen);
//showpage();
case 4: while(frame<4)//facing right
{
if(frame=1)
{
grabregion(1,1,64,64,
(entity.x[player]-xwin +16),(entity.y[player] -ywin),attackimg,screen);
printstring(10,10,screen,font,str(frame));
showpage();
wait(3);
frame = frame + 1;
}
else if(frame >1)
{
render();
grabregion(1,(1+(64 * frame -64)),64,(64 * frame),
(entity.x[player]-xwin +16),(entity.y[player] -ywin),attackimg,screen);
printstring(10,10,screen,font,str(frame));
printstring(10,20,screen,font,str(1+(64*frame -64)));
showpage();
wait(3);
frame++;
}
}
freeimage(attackimg);
//grabregion(1,1,64,64,
// (entity.x[player]-xwin +16),(entity.y[player] -ywin ),attackimg,screen);
//showpage();
}
}
thanks for the help guys!
[Zip: Fixored the layout... but not the code yet I'm afraid...]
Posted on 2004-12-04 00:56:40 (last edited on 2004-12-04 01:58:25)
|
cronoodle
|
Ah HA! i told you i'd be back. i can't figure out why it won't make any of the image i'm using transparent. i tried the death magenta thing, and i tried plain white. is there a specific color that's 'transparent' that i'm missing? back to the grind.
Posted on 2004-12-04 01:07:33
|
cronoodle
|
and another thing! what the hell am i doin wrong w/ the tags for code? i can get it to start, but not stop! heeeeelp!
Posted on 2004-12-04 01:12:17
|
Kildorf
|
Quote:Originally posted by cronoodle
and another thing! what the hell am i doin wrong w/ the tags for code? i can get it to start, but not stop! heeeeelp! You should use </ pre> (without the space), not <pre/> to close the code block.
Also, with the transparency thing... what are you displaying/how are you displaying it? If you're doing a straight Blit, nothing will be shown transparent... but some of the blit functions have a Tblit version, which will treat Death Magenta -- RGB(255,0,255) -- as transparent.
Hope that helps. ^_^
Posted on 2004-12-04 01:49:52
|
Zip
|
Right, it's bath time in Bethlehem, but I promise I'll be back to edit this post into usefulness in under an hour. Can see a few things already.
Zip
[Edit: Ah, I see BlueZ has responded with one option... will add another below]
Posted on 2004-12-04 02:01:24 (last edited on 2004-12-04 04:27:40)
|
blues_zodiakos
|
Looks to me like you used <pre/> instead of </ pre> (remove the space). All end tags have the slash at the beginning of the tag after the less than. :D
You'll have to go about this problem a completely different way. First, I'll tell you the command that you are looking for at the moment.
SetEntitiesPaused(1);
Will cause all entity processing (movement, etc.) to stop until you issue SetEntitiesPaused(0);
This will stop the warping you are experiencing.
Now, here's the problem. I'm assuming what you REALLY want is for the player to be able to attack at the same time enemies are running around the screen, attacking back, etc.
What you need is to run the animation via a HookRetrace. This will be a bit more complicated depending on what kind of 'collision checking' you want. Playing the animation might be the easiest part.
Here's the psuedo-code for what you want (it's not readily usable, you'll have to finish the rest). It uses a HookRetrace to play the animation and a HookTimer to time the animation so it plays the same on any computer (which using something like Wait won't accomplish)
int AttackTimer;
int AbleToAttack;
int CurrentlyAttacking;
int CurrentAnimationFrame;
int TotalAnimationFrames=5 or whatever;
int AnimationRate=100; // 1 frame a second. You'll probably want this lower.
int GlobalTempVariable; // used for animation timing.
void StartLevel()
{
HookRetrace('MyMainHookRetrace');
HookTimer('MyAnimationHelper');
AbleToAttack=1;
}
void MyMainHookRetrace()
{
CheckToSeeIfAttackButtonPressed();
If Attack button is pressed, CheckToSeeIfAbleToAttack();
{
If(AbleToAttack)
{
AbleToAttack=0;
CurrentlyAttacking=1;
Entity.Speed[0]=0; // I think that's right, but I'm not sure.
// Causes the player to be unable to move. You'll probably
// want to use HookEntityRender to show the animation instead
// of blitting over the player entity.
}
}
If(CurrentlyAttacking)
{
BlitCurrentAnimationFrame();
DoCollisionDetection();
}
}
void MyAnimationHelper()
{
If(CurrentlyAttacking)
{
GlobalTempVariable+=1;
If(GlobalTempVariable>AnimationRate)
{
GlobalTempVariable=0;
CurrentAnimationFrame+=1;
If(CurrentAnimationFrame > TotalAnimationFrames)
{
CurrentAnimationFrame=0;
CurrentlyAttacking=0;
AbleToAttack=1;
Entity.Speed[0]=50; // I think that's the default speed.
}
}
}
}
Since HookTimer is always called more or less exactly 100 times a second, regardless of your computer's speed, the animation should play at the same rate. There are other ways of timing, such as throttling the framerate, which may or may not be more useful. If you need any help actually writing the above code, feel free to ask. I'm sure it's not the most optimized way of doing this. :D Also, if you want to actually be able to hit anybody and have it register as a hit, you'll have to program some form of collision detection (if you are going to be hitting other entities, it'll be a cinch).
Hope this helped. :D
- edited to reflect reality. :D
Posted on 2004-12-04 02:09:30 (last edited on 2004-12-04 02:48:46)
|
cronoodle
|
I guess maybe i'm still confused about hookrender and what all is goin on there. (I'm sorry, i'm not a programmer by any means (please don't laugh at my pitiful code!), but i am interrested in overcoming this, and making my bad ass (super artistic) game!
so, if it's stuck in hookrender, what layer is all that being drawn on? or is it just ontop of everything else, or is that where the R in the renderstring comes in? since it's in the 'hookrender' does that mean i don't have to showpage() any thing? or is that still the same? *head melts* wow... that's what i like about this stuff, everytime i post somethin, i learn so much i practically explode!
as always, thank you for the help, guys! just you wait! i promise something the likes you have never seen in verge. all i need is some more mt dew!
Posted on 2004-12-04 02:33:38
|
blues_zodiakos
|
Argh, my fault. HookRender is actually HookRetrace.
Yeah, the 'R' in the render string is the layer that everything that is manually drawn (for lack of a better way to put it) is put.
Here's how HookRetrace and HookTimer work.
HookTimer is a special command that calls the function you specify approximately 100 times a second (You can change that, but it's NOT recommended). So, if you have a HookTimer with nothing but 'a+=1', then after 1 second, 'a' will equal 100 (assuming it's a global variable. :D). Generally, you can't do any graphical work in a HookTimer, because it will only last until the next frame - probably too fast to actually have seen anything.
That's where HookRetrace comes in. HookRetrace calls the function you specify EVERY FRAME. It's used for special effects and such that require somthing to be drawn every frame, such as animations and status bars. Of course, everything you put in a HookRetrace is going to affect your framerate, so it's best to keep it as simple as possible.
Sorry about the HookRetrace/HookRender thing. It's just HookRetrace. My bad. :D
About ShowPage... the HookRetrace is actually CALLED by Render() (so any time you use ShowPage(), you are calling the HookRetrace as well, I THINK). You aren't allowed to use Render() or ShowPage() inside a HookRetrace, because that would cause an infinite loop, and the engine prevents it (each time the hookretrace would be called, it would call itself again. :D)
Posted on 2004-12-04 02:44:11 (last edited on 2004-12-04 02:52:56)
|
cronoodle
|
*brains melting*
What's that sound? is something frying? and what on earth is that smell?
ok, that no showpage() tip will definitely save me some probs later... i don't completely understand it, but i got the idea, and i can tinker around with the code u pasted till i get it completely.
come shpants or highwaters, i will complete this game!
Posted on 2004-12-04 03:18:07
|
cronoodle
|
OH, one more question. when i'm actually obtaining the next frames information, i should still be using grabregion? and again, how will i make it transparent, or will i need to do something else? the frames for the animation are all included into one single pcx.
Posted on 2004-12-04 03:25:56
|
cronoodle
|
wow, to my surprise, i have just learned that today is, infact, a friday! so, like all the great artists, i must find strange chemicals to stimulate myself with. Enjoy your weekends, and thank you again for all the tutulage! Lock and load, happy birthday, and stay frosty! *gun sound*
Posted on 2004-12-04 03:44:05
|
blues_zodiakos
|
What I would do, in this case, is create an array with pointers to the images you've created with grabregion. The GrabRegion command is kind of like a copy/paste command - it takes information from one image and transfers it to another. With this in mind, you only need to do the actual copy/pasting once.
[Zip: This is actually untrue, BlueZ, GrabRegion is a blit, and not far off as fast. The code below will give 'uninitailised image' errors. Having one image and grabing out frames is fine, it's how chrs work. Transparency problems are likely to be fixored by using TGrabRegion]
int AttackAnimationFrame[5];
void InitAnimationFrames()
{
GrabRegion(blah,blah,blah,blah, MyImage, AttackAnimationFrame[0]);
GrabRegion(blah,blah,blah,blah, MyImage, AttackAnimationFrame[1]);
etc.
etc.
}
All you have to do is call that command once during the beginning of the game, and you can now replace all of those other GrabRegion commands with a simple AttackAnimationFrame[blah].
This is very important, because you DON'T want to be doing memory copying operations every frame, which is exactly what GrabRegion is doing if it's in a HookRetrace.
Do you understand how pointers work?
About Transparency: There is a single color (the variable name is 'transcolor', and it's Read/Write meaning you can change it if you want, it defaults to 255,0,255, magic pink) that when you use the 'T' graphics functions, will skip over pixels of that color. You probably already knew that, but the important thing is that in the image you want to make, for example, the background transparent, those pixels must EXACTLY be that color. If you are using a PCX image, and it's 8-bit (256 color), you will probably have to convert it to a true-color image first, and replace the background with magic pink (magenta) in some program like Photoshop.
Posted on 2004-12-04 05:19:47 (last edited on 2004-12-04 05:36:12)
|
Zip
|
Right... cro..noodle. My number one recommendation is you try to use the basic verge systems as far as possible, working code with limitations is better than broken code that should be better. Recommendation 2: Don't use wait. I wrote that code in the docs, because people inevatiably want a simple delay from time to time, and tend to code bad versions. Any realtime thingy though, Wait() will destroy, as you have seen.
So, my approach to the attack animation problem. Start by using the HookEntityRender() approach to displaying your player. Get this working before you do anything else.
After this you need to add your attack animations to your chr image, in some kinda sensible pattern. Eg: WD0 WD1 WD2 WD3 WD4 (Walk down frames)
WU0 WU1 WU2 WU3 WU4 (Walk up...)
WL0 WL1 WL2 WL3 WL4
WR0 WR1 WR2 WR3 WR4
AD0 AD1 AD2 AD3 ___ (Attack down frames)
AU0 AU1 AU2 AU3 ___ (Attack up...)
AL0 AL1 AL2 AL3 ___
AR0 AR1 AR2 AR3 ___ Whatever will do, as long as you can get a frame without resorting to that horrible switch statement... Note you don't need as many attack frames as you have walk frames, just have them in a good layout.
Now, next step is to create one variable (per attacker, later), that stores the systemtime of the last start of the attack. We'll use this to work out how far through the attack they are, and draw the right frame.
So, time for a little mini-code: // Some numbers in meaningful form
#define ATTACK_DURATION 100 // or whatever
#define CHR_WALK_WIDTH 5 // frames per walk direction, in the drawing above
#define CHR_ATTACK 21 // frame number of first attack
#define ATTACK_FRAMES 4// number of frames per attack direction
// Somewhere before anything happens on the map combat-wise
HookEntityRender(player_entity, 'PlayerAttackRender');
//This function is then called EVERY time the player needs to be drawn
void PlayerAttackRender()
{
int current_frame;
// Work out the x,y coord of the current entity's hotspot on the screen
int par_xh = entity.x[event.entity] - xwin;
int par_yh = entity.y[event.entity] - ywin;
if (player_last_attack + ATTACK_DURATION < systemtime)
{
// Player is walking, use current frame
current_frame = entity.frame[event.entity];
}
else
{
// Player is attacking, use attack frame
// Sorry entity.face returns different facings than are used
// everywhere else, so we get face from the current frame
current_frame = entity.frame[event.entity] / CHR_WALK_WIDTH;
// Then get the attack frame using this direction, and the time
current_frame += CHR_ATTACK + ((systemtime-player_last_attack) / ATTACK_FRAMES);
// There are more complex but prettier ways of doing similar things
// Here we add the offset to the attack frames, and a factor of time
}
// Chuck the player onto the screen!
BlitEntityFrame(par_xh, par_yh, event.entity, current_frame], screen);
} Yes, I know that's reasonably horrible, but it boils down to just drawing the chr if they are not attacking, and otherwise drawing an animation based on time. Obviously in the attack press, you'd set player_last_attack = systemtime, and maybe reduce entity.speed[] as well. Anyway, shout if you need awt.
Zip
Posted on 2004-12-04 05:21:00
|
cronoodle
|
that's cool, and i'm definitely going to need that for the characters animation, but because i'm using multiple weapons that look different (sometimes just palet swapped, and sometimes diff gfx) i need to do some stuff outside the character's frames, unless i draw a zillion frames per chr. (which would suck for me, kuz i'm soooo lazy) so, i need another attack animation basically beside the chr of a slash or a stab. so, for that part, should i just tgrabregion() to another variable like was suggested, or is there another way i should be doing that?
Posted on 2004-12-04 18:02:51
|
Zip
|
Like... get it working simple version first, kay? Yes, it's a simple swap on the code above to get TGrabRegion() on an image rather than BlitEntityFrame() from chr - BUT NO COMPLICATED THINGS YET! Just get one chatacter attacking.
When you can give me the demo of that working, I'll help you with the next bit, Lax has entity blit overriding using grabregion for instance. However, paperdolling is extortionately difficult, so don't even THINK about weapon swapping yet. Get working code first.
Zip
Posted on 2004-12-04 21:14:21
|
cronoodle
|
Word! i definitely understand the take it one step at a time philosophy. allright, i've been playing around with the stuff you wrote for me. For now, i'm just using the darin.chr file for my tests here. (the last frames in that chr aren't really attacks, but it'll display something to let me know it's working... good enough for now) only prob w/ it, is there aren't enough frames for a 4 frame attack, so i changed #define attack_frames to 2 instead of four
so... w/ 20 walking frames, and 8 attack animations gives us a total of 28 frames... which, i think the darin.chr one had 30.
i made a trigger function too
void ZipAttackTrigger()
{
if (player_last_attack + ATTACK_DURATION < systemtime)
{
player_last_attack=systemtime;
}
}
which i hookbuttoned to the spacebar.
so, this way, it'll change the playerlastattack to something so that the entity render thing will actually do something other than the norm.
ok, everything compiles, and i'm on my way. it's working fine, but when i press space, it'll exit the game w/ a log that said it was trying to open frame 58 of 30. that means it was trying to grab a character's frame that doesn't exist, right?
so, i went back to the code, and stared at it a while, but i cant figure out how it knows when to stop getting frames... or... well, i don't even know how to explain what is confusing me here. basically what i think is happening is that since it's not really counting frames, it's just runnin on a timer, that it's grabbing frames too fast or something. does that make anysense?
so, what can i do here/what is going wrong? i'm stumped. and i've noticed that it's a lot harder for me to figure out what's happening in a bit of code, when i didn't write it.
as far as demoing goes... i can send you some of what i have now, if u wanted to see it/have a laugh. but it's all messy right now, and it's more of a function test than an actual demo, altho it does have a few extremely early versions of some of the maps you'll be on. it's up to you, really.
Posted on 2004-12-06 01:04:04
|
blues_zodiakos
|
The type of game you are trying to make wouldn't happen to be similar to a certain game featuring a boy, a girl, and a sprite, would it? :D
Posted on 2004-12-06 01:37:44 (last edited on 2004-12-06 01:38:13)
|
cronoodle
|
indeed! cept, rather than hand painted backdrops from legend of magical nutz, i'm using pre rendered 3d models. if you've ever seen ghost in the shell 2, they did a spectacular job of blending 3d geometry for backgrounds and other things with 2d hand drawn artwork for most things that are animated. it's really an amazing artwork. if you haven't seen it, i'd suggest checking it out, if only for it's aesthetic value.
[changed this to a popping link, that host seems to not support direct remote-linking, -Grue]
anyway... somethin of that quality is definitely shooting for the stars, but i figure if i can entertain some ppl, and make my friends laugh, then mission accomplished.
but yeah, it's definitely a secret of <insert a word for mana in here> style game. or... it will be. soon.
Posted on 2004-12-06 02:29:41 (last edited on 2004-12-06 13:17:52)
|
blues_zodiakos
|
I've seen ghost in the shell 2. Besides being a cool CGI film, it's also why I support a constitutional amendment banning the japanese from ever producing another anime again. When 92% of a movie's dialogue consists of obscure quotes from ancient books, you KNOW something's wrong. :D Bah, I'm just a cynic.
Have you ever played Secret of Evermore? Besides the fact that everyone besides me in the entire world hates the game with a passion (I still don't know why...), everything in the game was actually 3D renderings using a Silicon Graphics workstation (back then that meant something. :/)
Posted on 2004-12-06 14:50:36
|
cronoodle
|
yeah, it's definitely a movie full of philosophy. I liked it a lot, but it's certainly more... of a grown up type movie than a cartoon.
i have played thru secret of evermore, and the reason everyone hated it was kuz u couldnt play it 2 player as the dog!
i didn't know all thier stuff was prerendered tho... hmm... digs up the ol snes... perhaps i'll find some guidance.
anyway... to forcefully slide back on topic. i still haven't figured out what the deal was w/ the frames thing, zip. last time i ran it, it failed on frame 66. so, what's goin on here?
Posted on 2004-12-06 20:53:13
|
Displaying 1-20 of 29 total.
12
next
|
|