CryoEnix Posted April 5, 2006 Posted April 5, 2006 (edited) Hey guys - included here is the source code for a game I'm creating called 'Nukerz', a bomberman clone that I'm sure you're all familiar with. Anyhoo, the problem is with the timers I use to move the player around - they only seem to last for about a second before cutting out by themselves. Simply run the program and click the 'test' label, and wait a few seconds to initialize it. The controls use WASD. Please get back to me as to why the movement is staggered - I haven't even implemented collision detection yet, so I'm at a loss. Oh, the movement code resides in the 'Player' class! ThanksNukerz.zip Edited April 5, 2006 by PlausiblyDamp Quote Chaos is merely logic beyond human comprehension
Cags Posted April 5, 2006 Posted April 5, 2006 Just incase anyone else is considering looking at this, it's worth noting that the project was created with VS 2005 and thus cannot be opened in VS 2003. Quote Anybody looking for a graduate programmer (Midlands, England)?
CryoEnix Posted April 5, 2006 Author Posted April 5, 2006 Hmm, that's a good point, Cags. Guess I shot myself in the foot with that one... Quote Chaos is merely logic beyond human comprehension
CryoEnix Posted April 5, 2006 Author Posted April 5, 2006 (edited) Here's the exact same project in VS 2003 - note that the same problem still occurs... Edited April 5, 2006 by PlausiblyDamp Quote Chaos is merely logic beyond human comprehension
Cags Posted April 5, 2006 Posted April 5, 2006 Sub KeyDown If key is upArrow Then If char.CanMoveUp() Then char.Y = char.Y - movementSpeed End If ElseIf key is downArrow Then If char.CanMoveDown() Then char.Y = char.Y + movementSpeed End If ElseIf key is leftArrow Then If char.CanMoveLeft() Then char.X = char.X - movementSpeed End If ElseIf key is rightArrow Then If char.CanMoveRight() Then char.X = char.X + movementSpeed End If End If Paint() End Sub Sub Paint e.Graphics.DrawImage(char.Image, char.X, char.Y) End Sub There is no need for timers or such like becuase the KeyDown event is repeatedly called whilst the key is held down. Quote Anybody looking for a graduate programmer (Midlands, England)?
CryoEnix Posted April 5, 2006 Author Posted April 5, 2006 Interesting - but is the keydown event is triggered at different speed intervals depending on the PC, or is it consistent? I don't want faster computers getting an advantage... Quote Chaos is merely logic beyond human comprehension
Cags Posted April 5, 2006 Posted April 5, 2006 To be honest I'm not sure if the repeat speed of keys varies dependent on the PC, but I would suggest it does. Well the best way forward is to have a fixed speed gameloop which checks the state of the key. It sounds like your building a multiplayer game in which case most of the processing could be done server side. Basically you'd end up with something like the following. - Clients KeyDown event sends a message to the server telling it that players pressed the button. - On each game loop the server moves the clients character. - Server then sends player positions to each client. - Clients KeyUp event sends a message to the server telling it the player has stoped pressing the button. - On each game loop the server doesn't move the clients character. The servers game loop would look something like this. while(gameAlive) { // calulates any game logic like moving players, bomb explosions etc. UpdateGameStates() // sends information back to clients UpdateClients() // waits for next permited game loop while(currentTime <= nextFrameTime) { } nextFrameTime = currentTime + frameLength } If I'm honest I'm not entirely sure how all of this would be programmed, but from the articles I've read about game development, this is the approach I would take. Quote Anybody looking for a graduate programmer (Midlands, England)?
mskeel Posted April 5, 2006 Posted April 5, 2006 For all intents and purposes the events should fire at the same rate. I wouldn't worry about leveling the playing field too much. Quote
Cags Posted April 5, 2006 Posted April 5, 2006 In Windows XP the character repeat rate is alterable. Which I'm assuming is the repeat rate of the key. Quote Anybody looking for a graduate programmer (Midlands, England)?
Administrators PlausiblyDamp Posted April 5, 2006 Administrators Posted April 5, 2006 If you are looking at implementing a fixed rate loop (as Cags suggested) you will probably want to use the GetAsyncKeyState function. Also DirectInput offers it's own means of getting at this information - however that is overkill for your needs. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
CryoEnix Posted April 5, 2006 Author Posted April 5, 2006 Cheers guys, I'll look into all of that right away! Quote Chaos is merely logic beyond human comprehension
mskeel Posted April 5, 2006 Posted April 5, 2006 Good catch. I have a couple of counter points, though. 1. Variable character repeat is intended to aid users with "mobility impairments", not gain an advantage in gaming. The default is the fastest rate. This would imply (at least to me) that the rate is determined by the OS, not the CPU. reference 2. Graphics rendering and network performance will have a greater impact on gameplay than the rate at which key events are fired. These are factors that are very hardware dependent. You should spend more time optimizing these factors than worrying about event fire rates in my opinion. Another possible solution: What about catching the key down event, setting a flag, moving while the flag is true, and catching the key up event, unsetting the flag, and stop moving while the flag is false? There's a lot of details to take care of in there, but it might work. With this method the rate of event fire won't matter. Now, it is possible that I am horribly incorrect since I am making assumptions about the OS having control of the character repeat rate. ;) Maybe we could find a benchmarking program (or someone could quickly right one up) and we can actually put some hard evidence behind this one way or another? This is really just curiousity for me at this point. Quote
CryoEnix Posted April 5, 2006 Author Posted April 5, 2006 By the look of it I think the keydown fire event id governed by the BIOS - as setting called 'Typematic somethingorother', If I remember correctly. Holding the direction-key and firing it with keydown will move the sprite a pixel, pause, then move it constantly - not unlike holding down a key in any text editor. I think the problem with my app is the timers I've been using - being generated instead of being drawn on a form might have missed something in the creation. I'll let you know when I have the results of my newly written timer class. Also, thanks for the game design tips with the one big loop - It'd probably be the best way to implement the game! Quote Chaos is merely logic beyond human comprehension
Leaders snarfblam Posted April 5, 2006 Leaders Posted April 5, 2006 The operating system overrides the BIOS's key repeat rate settings, and I, for one, would not depend on the keyboard repeat rate. Yes, most users probably will remain at the default, but that one out of twenty (could be more, could be less, not the point) people who went on an expedition exploring vast depths of the control panel could have altered the repeat rate, and will be very frustrated when the game doesn't work right not matter how he changes the settings. And if you're of the opinion that it serves him right, well, I'm offended because I'm one of the people who likes to explore things like the Control Panel. Also consider, for example, the poor little kid who is playing on Grandma's computer, which has the repeat rate set at something lower than what she considers insane. And the fact that some utility programs might change settings like this without asking the user (it's happened to me). The biggest problem of all, I would think, is that there is a pause between the initial key press and the automatic repeat. A very simple solution I have used in the past with programs that run on timers is to simply keep track of which keys are pressed by setting boolean variables in the KeyDown and KeyUp events, for example: Dim UpKey As Boolean Private Sub Form_KeyDown(sender As Object, e As EventArgs) Handles MyBase.KeyDown If e.KeyCode = Keys.Up Then UpKey = True End Sub Private Sub Form_KeyUp(sender As Object, e As EventArgs) Handles MyBase.KeyDown If e.KeyCode = Keys.Up Then UpKey = False End Sub The only problem with that is that it may be vulnerable to keyboard confusion when the player mashes the keyboard (a keyboard can only transmit three or so keys, depending on which keys, to the PC at a time and things get erratic when lots of keys are pressed). I'm not sure if this is the case, and it could be tested, but I'm lazy. I'd say that PlausiblyDamp's solution would probably be the best though. Quote [sIGPIC]e[/sIGPIC]
CryoEnix Posted April 6, 2006 Author Posted April 6, 2006 Thanks marble_eater, that was quite in-depth. However, I've solved the keydown/keyup problem by using directinput to detect the keys during the game loop. I'd advise anyone else to use this method to avoid the problem that I had. Quote Chaos is merely logic beyond human comprehension
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.