So I've gotten back into messing around with this game I've been creating in C++. I'm stuck on coming up with a formula to calculate a value I need. There are some pretty matherrific people here, so I thought maybe they would enjoy helping me figure this out. Like a brain teaser, yeah. This is a personal project, so not homework or anything.
This is a game that uses ASCII characters, like a rogue-like. I'm currently working on animating cells. These is the current elements:
Cells have the following properties:
a character array that stores each character it would use in animation, graphic[]
an integer of the total number of characters, animationFrames
an integer of the speed it should animate, animationSpeed
There's also a global constant for the total number of frames per second, FPS (currently set at 100)
And there's a counter integer that goes from 1 to 100 every second, animationCounter
The animationSpeed currently is related to the FPS, so if a cell has an animationSpeed of 100, it would go through all of its frames each second. If it were set to 50, it would go through them all twice per second. Set to 200, it would take 2 seconds to go through all of its frames.
To recap:animationCounter - goes from 1 to 100 every second
FPS - total frames per second, currently 100
graphic[] - character array with each animation frame inside
animationFrames - total number of frames, used as a helper for graphic[] (maybe some sort of null terminator would be better?)
animationSpeed - value related to FPS on how fast cell should animate, open for suggestions on how to redo this
Here are some sample data sets:animationSpeed = 100, animationFrames = 2
animationCounter 1 <-> 50, function should return a 0
animationCounter 51 <-> 100, function should return a 1
animationSpeed = 100, animationFrames = 1
animationCounter 1 <-> 100, function should return a 0
animationSpeed = 50, animationFrames = 2
animationCounter 1 <-> 25, function should return a 0
animationCounter 26 <-> 50, function should return a 1
animationCounter 51 <-> 75, function should return a 0
animationCounter 76 <-> 100, function should return a 1
animationSpeed = 50, animationFrames = 1
animationCounter 1 <-> 100, function should return a 0
animationSpeed = 200, animationFrames = 1
animationCounter 1 <-> 100, function should return a 0
animationSpeed = 200, animationFrames = 2
animationCounter 1 <-> 100, function should return a 0
second iteration of animationCounter 1 <-> 100, function should return a 1 (this may not be possible without some other variable or redoing the counter)
Notes:
Most of the variables can be made to either start on 0 or 1, depending on what makes the math easier. So animationCounter can go from 0-99 or 1-100, for example.
Anyone know of a way to make this work? Also accepting alternate ways of doing this to make it work. If nothing else I can just have everything animate at the same speed (already have this working), but I would like to add some flexibility to it.
Thanks in advance.
Edit: I should also point out that the point of returning these values is to use as the index of the character array to know what ASCII character to print in any given frame.
Posts
Why not specify the animation speed directly in fps? That seems like it would be more scalable, and make the math a lot easier.
Proud owner of the Veggie, Constellation and Cephalothorax badges
1) A global constant for FPS is worthless. You can use a global constant to cap FPS if you like, but you can't guarantee that it won't dip below that if you're doing some heavy processing, or if the target computer is slow, or even just if VSync is turned on.
2) How are you guaranteeing that animationCounter goes from 1-100 every second? I hope it's not by incrementing it by 1 each frame, for the reasons given above. You're probably better off ditching this variable entirely and doing something like keeping track each second of how far through the second you are.
3) You obviously need to keep track, per animation that takes more than a second, of how far in you are already (I see you thought of that already). You probably also want animationSpeed to just be the number of seconds you want it to take (maybe make it a float/double if you want fractional amounts) rather than being related to FPS.
Essentially you want to be able to tell what animation frame to use in any particular screen refresh. Am I correct?
The problem arises when you are dealing with numbers above 100, that you need to store data related to the character in order to render the frame. But this can be done with a frame counter.
Pass the current frame counter to the animation function, with the animation speed, and total frames.
So if you are on frame 165 for an animation speed of 100 and frame count of 2, the function returns a 1.
psudo code to follow
framecounter( frame, anSpeed, fcount)
{
remainder = frame % anSpeed
//now you need to divide anspeed into fcount parts
parts = anSpeed / fcount
i = 0;
while (remainder = remainder - parts > 0) i++;
return i;
}
This way you can keep counting frame up and later you can seperate frame from fps and tie it into real time.
Yes, I'm incrementing the counter each frame. I probably should separate it based on actual time passed, but if the frame rate is chugging, wouldn't it just slow down the animation? I'm fine with that as it's just (currently) environmental stuff like water and fire. Not sure if it would mess up other areas as I haven't thought it through. These are the time functions available through the library if something there would work better.
Modulus. Dammit, I knew I was forgetting something to throw at this.
return floor(remainder / parts); instead of the while loop.
so for 165th frame 100 speed and 2 frames should return 1.
and 145 should return 0
165th frame 200 speed and 2 frames should return 1
With the plan you outlined, consider what would happen if you had animation speed 100, 4 frames of animation, and an actual FPS of 60 FPS. Every second you'd see frame 1 for .42 seconds, frame 2 for .42 seconds, and frame 3 for .17 seconds. Frame 4 would go missing entirely.
For example on my computer i have vsync forced on, that means my frames per second is locked into my monitors refresh rate. 75 hrz = 75 frames a second maximum (60 hrz = 60 fps, and so on). What happens when your program wants to output at 100 fps when i limited it to 75 is that it will discard every 4th frame, the information you wrote to the buffer will simply be tossed.
For ticks, a single tick can be any length of time you desire, from an entire second to 1/100th of a second to even a millisecond (tribes 2 used this). But switching to that would probably require a rewrite of you code so I didnt suggest it initially. If your in your early stages, doing this change now will save you a lot of work if you decide to change it in the future.
It is still in the fairly early stages. Currently I have a while loop at the end of my game loop that waits for a keypress while drawing the screen 100 times a second (based on the FPS constant). The actual game is turn-based, but it draws the screen in real-time for the animations.
You should be computing values based on a delta time between firing of the animation loop (which may just be the main thread)
we also talk about other random shit and clown upon each other