#29817 - ThUg4LiFe - Thu Nov 25, 2004 1:54 pm
this is something ive always wondered about, and i dont know if im yet to read something about it - but im up to pg 350 of 600 on a book about C, also found in the misc. section of the beginners faq the link to a guide to programming for GBA and how to create graphics and with all the technical data, and now im feeling more confident that i will be able to program a game for the GBA
i just wonder how a game/program is made to constantly be checking for user input - there may be a way this is done with a command which takes affect over a whole period of time when other codes may be executing - or is it simply that you would need to keep running a code to check for input between every single frame of animation where you want to reading input...
the concept isnt something ive figured out myself yet, can someone enlighten me
cheers
#29819 - Krakken - Thu Nov 25, 2004 3:04 pm
You can actually do it either way. You can syncronise the update of the input to each frame by checking the register status or you can make the code generate an interrupt whenever a key is pressed. An interrupt will stop the execution of the code and jump to the interrupt handler where you can do whatever. Following that it will return to normal execution.
Also on a side note, the input register should always be read into a local variable before checking it.
#29820 - ThUg4LiFe - Thu Nov 25, 2004 3:22 pm
thanx thats exactly what i needed to know
#29825 - ThUg4LiFe - Thu Nov 25, 2004 5:58 pm
what about though, when you want codes to be executing at the SAME time.. a couple of examples..
you may have a scoring system, but the way the score increases takes a while to roll over or keep racking up the score because it may increase in smaller chunks (i.e. a score of 1000 during gameplay may increment the score in 100's) but you dont want the rest of the code to be frozen until all ten 100s have been added to the score! how do you get around this.........
(after a bit of wondering, i think maybe you have to make a score increment at the start of what i could only describe as the game 'cycle' loop - but the loop repeats itself very quickly and so it can still call the score increments at the start of each fairly quickly)
another example: you may have animations you want to still be active while other code is executing
(in fact, i think the same applies, because it the animation updates at the start of each game loop and a game loop is always (if possible) a matter of less than a second (preferrably fixed at that too) then you can always keep updating everything rapidly)
i dont know if im on the right kind of concept on how this sort of thing is done
#29827 - poslundc - Thu Nov 25, 2004 6:10 pm
The GBA's screen updates once every 1/60'th of a second. Your game's primary loop should cycle around this VBlank/VDraw sequence. While the screen is being displayed, take all of the time you need to update information like what score is currently being displayed (which doesn't have to be the actual score; it can be the current state of the counter as it ticks up towards the actual score) and what frame of a sprite's animation you want to display. Then during the VBlank period do whatever you need to do in order to make that display on the screen, then repeat the process for the next frame, and the next, etc.
Google up finite state machines if you are still having trouble with this concept. The game is basically a big finite state machine: every 1/60th of a second you determine the new state of the display.
Dan.
#29828 - Fatnickc - Thu Nov 25, 2004 6:25 pm
Well, I don't really know about the exact same time. My dad said in Basic there is a when() command, which will execute two things at once, but I am not sure if that kind of thing exists in C.
Seeing as no one has posted some pretty code yet (:)) I will :
Code: |
/*insert stuff here*/
while(1)
{
Input();
Pics();
Phys();
etc();
WaitForVSync();
CopyOAM();
} |
Put this at the end of the other stuff, but within the main game loop, or make it a function and call it like function();, which may well just create and endless loop, but hey, this is that, until stopped.
A few things to be aware of with this method, though.
thing 1)
If, in Input(), you reference to something made in Phys(), you need to place Phys() before Input() . While this sounds fairly easy, what happens if :
Input() needs Phys() which needs Pics() which needs Input() which needs etc()?
Umm, nothing, at least to my mind. If that is what the case is, you should do either of the two things (I'm quoting this 'cause I think it'll be a quote for years to come ;)):
Quote: |
a) Separate the parts of the function out, so that the parts can be ordered in sequence as individual parts.
b) Start again with your functions. That will just get tougher now.
|
Ends thing 1.
thing 2)
If, in Input(), you have a scoring system that will take one away from the user's bomb total every time they press A, and you are allowing them 50 bombs, you might well decide to have a loop in the structure of :
Code: |
while(bomb<50) {
if(keyPressed(KEY_A)) {
bomb++; }
} |
(where you show the opposite of what the code says, just for ease of reading now)
You will be waiting for them to press A 50 times.
This, however, will halt the while(1) {} structure, because it won't let the next function run 'at the same time' ('' used for to the human eye, with additional speed 'injected' into the game) as the GBA will still be fixated on getting those 50 presses until it can move on. Of course, after that it will run smoothly, as bomb is no longer smaller than 50 so the loop won't be triggered. However, by then, the weapons are out and the game is practically dead. Mainly, the game will have been put down a long time ago, as the zombies which are moving around in Pics() haven't had the chance to move, so you have been shooting nothing. Fun.
thing 3) If you are going to do the while(1) { } way of living, you should always make sure that you have the last two function calls (WaitForVSync(); and CopyOAM();, or whatever you have called them) should always be there, because if you left it out somewhere, it might not update ever, and be a pain. Also, it beefs out what really is the main part of your game.
Find this useful? Please Say :). Find any major errors? Please Say :).
Want to thank me? Please Do.
I don't reckon that I have been a very 'useful' member of the community so far, and hope this helps lots of people :D.
#29829 - tepples - Thu Nov 25, 2004 6:51 pm
ThUg4LiFe wrote: |
(after a bit of wondering, i think maybe you have to make a score increment at the start of what i could only describe as the game 'cycle' loop - but the loop repeats itself very quickly and so it can still call the score increments at the start of each fairly quickly) |
Have two variables called score and display_score. At the beginning of each scene, set display_score = score, and have game scoring logic modify only score. Then do this at the beginning of the game loop:
Code: |
/* score is the current score */
/* display_score is the score being displayed */
/* every game loop do this */
display_score += (score - display_score + 15) >> 4;
|
See if that effect looks any good.
Quote: |
another example: you may have animations you want to still be active while other code is executing |
Then you create a data structure for each animation, and update all the data structures every game loop or every nth game loop (using a down counter that's part of the animation's data structure).
Quote: |
i think the same applies, because it the animation updates at the start of each game loop and a game loop is always (if possible) a matter of less than a second (preferrably fixed at that too) |
Game loops on the GBA typically run at about 60 Hz, or once every vblank.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#29833 - ThUg4LiFe - Thu Nov 25, 2004 7:16 pm
thanks all, it seems i was along the right tracks :) understanding how C works and all its potential and tools to the extent i now do has made me start realising exactly how im going to be programming this game in its entirety (whereas before i just had idea about how to make some parts function) its all coming together now though in my head and ive been scrapping down notes on paper all day at work about how im gonna do this
wouldnt have got this far without this website though
#29838 - ThUg4LiFe - Thu Nov 25, 2004 7:41 pm
so ive just devised this game loop.. dont know if ive forgotten key things
game loop
{
turn on/off the interrupts for all moves available for character's current stance and frame of animation
update characters animation frames
update level animation frames
update ActualScore
update DisplayScore (for a counter racking up score while play continues)
detect interaction/collision with other characters/objects/walls
update speed & meter
update health when you have stopped moving (if this will increase when you can rest for a minute [cleared all enemies or are in a safe location])
}
can the interrupts be set up to detect what input has been entered?? (i.e. a double tap, or a tap then hold) and execute the relevant code/function?? but also be disabled when you dont want it to load a new code from the user input??
#29842 - sajiimori - Thu Nov 25, 2004 9:57 pm
There's only one reason to use interrupts for input, and that's to detect buttons presses that last less than an iteration of the main loop. This is hardly ever necessary. Just poll input once per frame.
#29880 - tepples - Fri Nov 26, 2004 7:48 am
sajiimori wrote: |
There's only one reason to use interrupts for input, and that's to detect buttons presses that last less than an iteration of the main loop. This is hardly ever necessary. Just poll input once per frame. |
Almost. There are two more reasons to use a keypress interrupt: - to detect the exact time of a button press, such as to initialize a random number seed or to exactly judge the timing of a button press in a rhythm game, or
- to wake the CPU from sleep mode.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.