Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / I need help with an animation problem

Author
Message
I need help with my animation
14
Years of Service
User Offline
Joined: 20th Apr 2010
Location:
Posted: 21st Apr 2010 05:27
This is my first time posting and i have been looking around on the forums in hopes of an answer to my question. I have a Whack-A-Mole type game and I'm trying to animate the object coming out of the hole this is what i have.... what is happening is the object pops up and stops on a random frame and not the final frame. i have a hunch that it is getting stuck in a infinite loop so the comp is just terminating the loop and so it ends in a random frame... this is my first game so I'm still learning the libraries. any help you be most appreciated.
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 21st Apr 2010 08:38
Please post the code. It is not possible to guess what's wrong without seeing the code.
I need help with my animation
14
Years of Service
User Offline
Joined: 20th Apr 2010
Location:
Posted: 21st Apr 2010 16:23
[void Lvl1()
{
/* This is the level design the idea is that after hiting the sprite 10 times a song plays
i would like to have the sprite restart this i have not worked on though due to the fact
that the sprite will not even play through all of its frames properly.
I have this hunch it is getting stuck in a infinate loop somewhere but i dont know why*/

dbHideSprite(2);
dbHideSprite(3);
dbHideSprite(5);
dbShowSprite(6);
dbShowSprite(7);

dbPlaySprite(7,1,3,80);

if (dbSpriteFrame(7)
dbSetSpriteFrame(7,3);

if (dbSpriteCollision(7,1))
{
if (dbMouseClick())
{
score = 1;
}
}

if (score == 10)
dbPlaySound(1);
} code]
I need help with my animation
14
Years of Service
User Offline
Joined: 20th Apr 2010
Location:
Posted: 21st Apr 2010 18:26
i know the end is a little off, i have been messing with a lot of ideas and trying all kinds of things. Sorry about the absence in code for the op im still geating use to this forum layout.
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 22nd Apr 2010 19:55 Edited at: 23rd Apr 2010 08:35
First a forum advice: use the "code" button above the text editor to enclose your code between tags, which will show a nice pushbutton to open and close the code part, so people don't need to scroll through the whole code to read a post. (EDIT: the format will also be better because the code tags preserve the indentation.) (If you want to post a lot of code, it is also an option to include it as an attachment file.)

Second, it would have been good to post more of the code since this is only a part of it. For example it is not visible where the main game loop is or whether other parts of the code are doing anything else with that sprite, even accidentally.

I have only one idea what the problem can be. This statement is suspicious:



Did you copy-paste this or you retyped the code on the forum? This wouldn't even compile since one closing bracket is missing. The other thing that is missing is the check of the return value. The dbSpriteFrame command returns the index of the sprite frame that is shown at the moment. Since you are playing the sprite between frames 1 and 3, the return value is always non-zero, which is treated as true. Therefore this statement will always set the sprite frame to 3.

If you want to play the sprite animation once and then stop it at the last frame, try something like this (called from the main game loop):



The above code will stop animating the sprite when frame 3 is reached. When you need to play it again, set the sprite frame back to 1.

Whatever your problem is, it is certainly not an infinite loop. The computer will never randomly terminate an infinite loop, as you supposed in your first post. The program would simply freeze until you kill it from the task manager or from the Visual Studio debugger. If only the animation stops at a random frame but the program continues working and you can normally play with it or exit it by pressing the Escape key, then you don't have an infinite loop.

If this does not help and you still can't figure out the problem, then post again but attach your entire code file.
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 23rd Apr 2010 08:26
Another thing that can be a problem is if the Lvl1 function is not called enough times to finish the animation. That's why it would be good to see how it is called from the game loop.

You will also have a problem with your hit counter as well. The dbMouseClick function does not register a click only once, it returns true as long as the mouse button is pressed, many times per second. To avoid registering all ten hits for the same click, define a boolean variable and count a hit only when the mouse has just been released. Also, you set the score to 1 instead of increasing it by 1, so it will never reach 10. Example solution:

I need help with my animation
14
Years of Service
User Offline
Joined: 20th Apr 2010
Location:
Posted: 23rd Apr 2010 18:56
ok, it still didnt work this is all i have


I'm really sorry about not being able to use the forum right. i hope that works. Thank you for your help though i really appreciate it. P.S. all the notes are to my self mostly because I tried to learning this all on my own.
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 24th Apr 2010 20:57 Edited at: 24th Apr 2010 21:05
OK I see the problem but it's a bit difficult to explain. The design of the program structure is not good.

What's happening here: you display the menu sprites. In the main loop you check if the player clicked on the "play" menu sprite and if yes, call the Lvl1 function. But the Lvl1 function will execute only once and then returns control immediately to the game loop, which will check again if the player clicked on the menu sprite... Note that sprite collision will work even if the sprite is hidden, and I already said that dbMouseClick returns true as long as the mouse button is pressed. So, this "have I clicked on Play button?" check will result in several "yes" answers, because you cannot click fast enough to register the click only once. Therefore, the Lvl1 function will be called several times - but how many times, you cannot tell, it's random. It depends on how many milliseconds you hold down the mouse button.

Then there is the special property of dbPlaySprite: it does not play the animation from beginning to end. To make the animation continuous, you have to call this function again and again from the main loop, otherwise it only displays one frame. The speed value takes care of the animation timing (it determines when to switch from one frame to the next) but you have to take care of calling the function. So, how far your animation will play depends on how many times you manage to call the Lvl1 function (which depends on how long the mouse button was down).

I think the main problem is that your program design is mixing the linear and the loop elements. The progression of the game from displaying the menu to playing the game is a linear sequence, but this does not fit together with the endlessly running game loop. In any case, checking collision with the menu sprites again when they are not any more displayed is superfluous and takes away performance from the game.

What you should do is to implement game status (game mode) values which tell you what to do in the main loop: when the game status is "menu" then display menu, when the game status is "play" then call the game playing functions and when the game status is "exit" then return to Windows. There is a nice example of game statuses in the "Dark Invaders" tutorial which comes with the Dark GDK installation. Have a look at it. (The game switch is on page 4 and 5 of the pdf document but it's worth to read more of that text.) Try to redesign the program. I might have a go at writing a framework for you if you need further advice.
I need help with my animation
14
Years of Service
User Offline
Joined: 20th Apr 2010
Location:
Posted: 26th Apr 2010 04:59
Sweet, thank you so much i will redo this stuff on tuseday and give it a go, i will look into the Dark Invaders, and thanks again i really am thankful for your help
I need help with my animation
14
Years of Service
User Offline
Joined: 20th Apr 2010
Location:
Posted: 27th Apr 2010 20:48
ok i fixed the animation problem i think
, but im having trouble with clicking on the animation. yes i know i should learn how to use header files the codes a little cluttered, im looking into it.
I need help with my animation
14
Years of Service
User Offline
Joined: 20th Apr 2010
Location:
Posted: 30th Apr 2010 05:33
ok well i got the clicking on the animation to work but i have a problem with score keeping this is wat i have
, it enters an infinite loop, i run it and the program wont go past my main menu and freezes. Please if you could help with this i would be grateful.
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 2nd May 2010 15:59 Edited at: 2nd May 2010 17:00
Sorry for the late answer, I haven't looked at the forum in the past few days.

The program freezes because it never updates the screen and doesn't get out of the score loop. It is the dbSync() command which does the drawing, but that command is at the end of the main loop. When you enter this loop:
it is just running around without drawing anything to the display and it does not return control to the main loop for screen refresh. So, another structural change would be needed.

There are other issues as well. The level1 function keeps deleting the same sprites over and over which is not necessary. It would be better to put the sprite deletion just before you change the game mode in the gameMenu function:



Keep in mind that if you delete the sprites, you'd need to reload them when you want to display the main menu again, so maybe hiding them is a better idea than deleting.

Pay attention to the difference between = (assignment) and == (equality test). At least in two places you committed this mistake:



The correct operator would have been == and not =. These statements will always make the variables equal to the right-side value, so the test will always be true.

The way you are using the click variable doesn't make much sense because in this way it is not able to detect the release of the mouse button. Instead of this code:



you could just as well write this and it would do the same thing:



If you are using dbSpriteHit, maybe you don't need the mouse button release test, because that function triggers a "collision" only the first time when two sprites overlap and then it doesn't trigger again until the two sprites move away from each other (out of collision range) and then collide again. If, in the game, it is not allowed for the player to hit the same animated sprite in the same position several times (e.g. because the mole will immediately pop up somewhere else), then dbSpriteHit is a good choice. However, if repeated hits on the same sprite are allowed and possible, then dbSpriteCollision should be used and then you need the mouseclick test as well.

In the next post I'll try to make some changes on the code so that at least it should run without freezing.
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 2nd May 2010 16:23 Edited at: 2nd May 2010 16:24
Here is the promised change on the level1 function which allows it to run and keep track of the score and the mouse button status, without freezing the main loop. Since this function will be called many times from the main loop, the score and click variables should be made static variables to preserve their last values from one function call to the next. When the score reaches 10, my idea was that you will change the game mode. Either introduce a new game mode which signals to the main program that the game should be finished, or change the mode back to the main menu (but then you should take care of re-loading or redisplaying the menu sprites). Since the game mode is changed, the level1 function will not be called any more.

Another possible solution would be to make the level1 function a loop on its own which does not return control to the main loop until the game is finished. In that case, you need a dbSync() in the level1 function as well, to refresh the screen, and you need a while loop which encapsulates the whole function, including dbSync and dbPlaySprite - everything that you need to draw the screen.

It is a question of taste how you design the program and finding a good design is one of the most difficult tasks.

I haven't tested this since I don't have your sprites but I hope it will work.

Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 2nd May 2010 16:59
Here is yet another version, in which the level1 function has its own loop and does not return control to the main program until the game is finished. This may be better for performance reason, since the function does not need to be called in every frame. The while loop runs until the game mode is changed and the screen is refreshed with dbSync within the loop. In this case you don't need to make the variables static.

I need help with my animation
14
Years of Service
User Offline
Joined: 20th Apr 2010
Location:
Posted: 3rd May 2010 05:51
THANK YOU SO MUCH!!!! IT WORKS GREAT! i am very thankful lets see how every think else goes...
I need help with my animation
14
Years of Service
User Offline
Joined: 20th Apr 2010
Location:
Posted: 3rd May 2010 06:20
where would be a good place to look for great explanations of the randomizing process... I want to asign each hole a # and from there on tell the sprite to pop up the... thats the idea any way and wat types of fonts are available i whould like to put in a time clockand score counter like very very soon.
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 4th May 2010 21:26
For random numbers, look up the dbRandomize and dbRND functions in the Dark GDK help.

I guess any font is available that's installed in your Windows. See dbSetTextFont in the Dark GDK help. I never tried to change fonts, so I can't help you there further.

For a game timer, use the dbTimer function to count elapsed time in milliseconds. Usually in a game you are not interested in exact current time, only elapsed time. But if you want to display current system time, then look up the built-in C++ functions, that's a bit more complicated though:

http://www.cplusplus.com/reference/clibrary/ctime/localtime/

Score counter is easy. Convert your score variable into text format (I recommend sprintf) and write it to the screen with dbText.
I need help with my animation
14
Years of Service
User Offline
Joined: 20th Apr 2010
Location:
Posted: 5th May 2010 00:12
ok i dont kno if i have the randomization correct but i have run in to another issue with animations. it will animate the first time but afte i delete the sprite it shows the whole picture? i have tried to call the animate sprite function again and what not but it still will not work.
This is the only stuff i have changed and also wen its is in the level one portion if i click to exit out at all it freezes and i have to terminate the proses from the task list any ideas on these things?
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 6th May 2010 08:26
Why do you delete the sprite? It would be enough to reposition it at another hole. If you want it to disappear temporarily, then either use dbHideSprite or position its coordinates out of the visible screen area. If you delete the sprite, it does not exist any more in memory (the image is still there but the sprite isn't), so obviously the animation won't work unless you re-create the animated sprite.

I don't know why it freezes when you try to exit. Try to include a function call exit(1) and that should terminate the program. Alternatively, you can write the main loop so that it loops until a boolean flag is set to true. Or post how you implemented exiting from the main loop and then maybe I'll know what the problem is.

By the way, it's a good idea to delete the resources you used (images, sprites, sounds) before exiting the program. In my program I included a function called CleanMemory, which deletes every existing resource and this will be called every time before exiting. Such function can be useful also when you are changing game levels.
I need help with my animation
14
Years of Service
User Offline
Joined: 20th Apr 2010
Location:
Posted: 7th May 2010 00:21
yeah i fixed that i just thought thats wat you where suppose to do wen you where done with sprites and as far as the randomization its not randomizing i have no clue why. i have loook all over this forum but i cant find and actual example just ppl saying look it up in the help thing which dose nothing think you could help out with this issue?
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 7th May 2010 19:45
I think the problem is that the dbRandomize command is inside your loop. This command gives the initial value to the random number generator, so it should be called only once in the program. If you call it in every loop, and even with a constant number, then it will always begin the random number sequence from the beginning, so the next dbRND will return always the same number.

The "seed" that you give to the random number generator can actually be anything but it is usually recommended to use a timer value, so that it's really unpredictable: dbRandomize(dbTimer()). Place this into the game initialization function, or at least before the while loop in the level function.
I need help with my animation
14
Years of Service
User Offline
Joined: 20th Apr 2010
Location:
Posted: 8th May 2010 07:53
it works with dbTimer() just fine in the and out side of the loop but it moves to quickly.....it looks like 3 red translucent bars zooming up and down out of all the holes.... this isnt good i need it to pop up thats it in random positions...
JTK
14
Years of Service
User Offline
Joined: 10th Feb 2010
Location:
Posted: 8th May 2010 08:38 Edited at: 8th May 2010 08:50
Random positions may be the wrong term; random location seems more likely to me...

First off, with the code above, the


should be:



and placed *before* the call to



As such, consider this:

Assume Random Position has been identified (which hole the critter will be popping-up from):

Once a sprite begins to pop out of a hole, you want it to take "N"-seconds to carry-out its complete animation (say 2-seconds at lower levels [we'll just say 2000ms] - to pop out / disappear again). This allows 1-second to Pop-Out and 1-Second to Disappear again...

dbTimer() tells you how many m/s has elapsed since its last call:

Therfore, to make your sprite "pop-out" animation to take 1-full second (1000/ms), you need the following equations:



Where: ms_elapsed_since_last_update = dbTimer() - last_call_to_dbTimer;

And last_frame = maximum frame number you wish to use for the animation cycle...

And in the case of the "pop-up/disappear" cycle taking 2-seconds (2000/ms); it would become:



Where: popup_disappear_frame_count = the number of "sprite-images" required to illustrate the entire pop-up and disappear cycle of the animation you are trying to illustrate.

I Hope this helps,

JTK
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 8th May 2010 10:59 Edited at: 8th May 2010 11:18
This is again a program structure issue. You generate a new random value for the "hole" variable every loop, so the sprite is changing position 60 times per second. What you want to do is to assign a new value to the hole variable only when:

a) the player has successfully clicked on the sprite,
b) the sprite has completed the animation cycle (maybe with an additional little delay afterwards).

Maybe you can introduce a boolean flag which indicates whether you need to determine a new position or not.

What JTK says concerns the speed of the animation. That's a perfectly valid advice as well but it's a different problem. By the way, the animation speed can be changed by the last parameter of the dbPlaySprite function as well. With a little experimentation you can find the suitable speed value.

EDIT try this:



In this code, a new hole is selected only on the conditions I mentioned above. The animation is also reset to play from the beginning again. There is just one problem with this. When the sprite reaches animation frame 3, a new hole will be seleceted immediately, which means that frame 3 will not be shown for the specified amount of delay. Basically, frames 1 and 2 will be played but not 3. The easieast way to solve this is to change the sprite picture to include a frame 4 and then use frame 4 as the "animation end" condition.

You can also use a timer to determine how long the animation should be playing or to add more waiting time after the animation has finished, but that's a bit more complicated than adding one more frame to the sprite.

I'm not saying that the above code is the best structure but it's a start. Try thinking over step by step what the program has to do, when and in what order, and then adjust the structure to the planned sequence.
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 8th May 2010 11:34
Slightly modified version of the above code, with a boolean flag, to avoid code repetition:



Test how it works. Again, I'm not saying it's the ideal solution. To find the best structure for your program takes some effort.
I need help with my animation
14
Years of Service
User Offline
Joined: 20th Apr 2010
Location:
Posted: 8th May 2010 22:42
yeah i worked some stuff out i incorporated some of that stuff and then added some other stuff like a counters and several other forms to pop out if you could just take a peak at this
, its the whole code let me kno wat you see plz
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 9th May 2010 17:20 Edited at: 9th May 2010 17:29
Well, I don't see obvious errors but that huge if statement is very ugly. If you want to determine the sprite index based on "bro" and the position based on "hole", then the whole "if" structure can be replaced with a few simple calculations:



(In the dbSprite command, the first and last parameters can be the same because you use the same index for the sprite and the image.)

Since the "if" structure (or the lines above if you exchange it) already contains the dbPlaySprite command for every possible situation, the next dbPlaySprite, under the comment "Select a new hole ... end of animation" is not necessary. It does not reset the animation cycle anyway at that point, so the comment is misleading if you leave it in the program.

Supposing that you only want to have one mole on the screen at the same time, I don't see code to hide the other two sprites which are not playing at the moment. Also, in the collision check, you reset the animation of only sprite 7, ignoring the other two. And if the animation plays from frame 1, then it should probably be dbSetSpriteFrame(7,1) instead of zero.

One more thing: I would place the two character array declarations (str and time arrays) before the while loop, to avoid re-allocating them in every loop.
I need help with my animation
14
Years of Service
User Offline
Joined: 20th Apr 2010
Location:
Posted: 10th May 2010 05:13
Im having a problem with trying to get it to only so one per hole and i will wont multiples on screen eventually. i am working on it but if you have any ideas im open.
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 11th May 2010 08:37
To hide those two sprites which are not used at the moment, you can try dbHideSprite (and dbShowSprite when they are needed again), but it is easier to just position them off the screen. That has also the advantage that you won't acccidentally detect a collision with an invisible sprite. Set their coordinates to negative values like -100,-100 and they will effectively "disappear".

Login to post a reply

Server time is: 2024-11-19 23:36:13
Your offset time is: 2024-11-19 23:36:13