• 0

[C#] Counter not working


Question

Edit: fix'd, sorry. Just had to only run the action if the Enter key had been released between loops.

I've been learning C# for a week or so (in combination with XNA) just to play with the basics of game development.

Anyway, I'm trying to allow a certain action to be performed up to 5 times in the course of the game (Enter key to 'warp' around the screen).

The following snippets are where I try to do this and increment a counter up to 5, and past 5 not allow the action to run.

However, currently it seems I can only warp via the Enter key once, sometimes twice if I hit it a second time very quickly? That may just be my imagination though.

public class Game1 : Microsoft.Xna.Framework.Game
	{
		int warpCount = 0;
		int warpMax = 5;

protected override void Update(GameTime gameTime)
	{
	  winMove();

protected void winMove()
	{
	  if (curState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Enter))
				{
					if (warpCount < warpMax)
					{
						winWarp();
						warpCount += 1;
					}
				}

protected void winWarp()
		{
			Random randr = new Random(); //One Random to randomize them all.
										 //I did not just write that.
			warping = true;
			if (randr.NextDouble() > 0.5)
				winLocation.X += (randr.Next(200, 300));
			else
				winLocation.X -= (randr.Next(200, 300));

			if (randr.NextDouble() > 0.5)
				winLocation.Y += (randr.Next(200, 300));
			else
				winLocation.Y -= (randr.Next(200, 300));
		}

Any help is appreciated. The above snippets mostly don't close etc because I've only shown the key parts to the warping method.

Thanks very much.

Edited by Callum M-R
Link to comment
Share on other sites

3 answers to this question

Recommended Posts

  • 0

Update is called 60 times per second. Unless you can time your pressing of the enter key so that it lasts less than 1/60th of a second, you end up calling winMove() several times each time you press Enter.

The trick is to save the keyboard state at the end of Update(), and on the next update, disregard the keys that were already pressed. Something like

class Game1 {
	KeyboardState lastKeyboardState;
	protected override void Update() {
		var newKeyboardState = Keyboard.GetState();
		var newPressedKeys = newKeyboardState.GetPressedKeys().Where(
												k => ! lastKeyboardState.GetPressedKeys().Contains(k));
		// Now newPressedKeys contains only the keys pressed this update
		// Update your game logic accordingly...

		// Once done:
		lastKeyboardState = Keyboard.GetState();
	}
}

You might find this code a bit difficult to read due to the use of C# 3.0 features, but it's never too early to learn them IMO.

On a side note, I doubt you plan on subclassing Game1, so there's no reason for winMove() and winWarp() to be anything else than private. Since C# class members are private by default, you can just write:

void winMove() {
	//blablabla
}

void winWarp() {
	//blablabla
}

etc

Edited by Dr_Asik
Link to comment
Share on other sites

  • 0

That's perfect, thank you.

After I figured Update must be running much more than once per second I made my own poorly implemented version of what you suggested, but yours is a lot cleaner and more efficient.

I also wasn't aware that members defaulted to private - that should save a fair few keystrokes as well.

I thought I'd fixed it myself, but your solution is much better. Thank you very much!

Link to comment
Share on other sites

  • 0

No problem. Just to fix a minor screw up in my example code above:

instead of

lastKeyboardState = Keyboard.GetState();

more efficient and logical is

lastKeyboardState = newKeyboardState;

Since there's no point polling the keyboard more than once per update.

Nice choice on C# and XNA. My favorite programming language and my favorite game programming framework. :p

Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.