Accidentally created an infinite while loop in C# - c#

So I've recently been learning C# for my A-Level programming project where I am creating a game. I have a sprite which I can move about the screen but I would like the sprite to only be able to move 6 times before it's forced to stop moving. I thought that I could do this by having a variable that would decrement every time that the sprite was moved (using the keyboard). However, I have somehow created an infinite loop which I did not want. I discovered this with the Console.WriteLine(spaceMoved); which will not be in my final code. I've tried all sorts of things but I can't get rid of this infinite loop. I am creating this in a Windows Forms Application by the way.
private void Gameplay_KeyDown(object sender, KeyEventArgs e)
{
int spaceMoved = 6;
do
{
int x = placeholder1.Location.X;
int y = placeholder1.Location.Y;
if (e.KeyCode == Keys.Right) x += 64;
else if (e.KeyCode == Keys.Left) x -= 64;
else if (e.KeyCode == Keys.Down) y += 64;
else if (e.KeyCode == Keys.Up) y -= 64;
placeholder1.Location = new Point(x, y);
spaceMoved--;
Console.WriteLine(spaceMoved);
} while (spaceMoved > 0);

This is not an infinite loop. Your do while will execute 6 times.
However, you seem to have glossed over the fact that this will execute 6 times whenever Gameplay_KeyDown is called. Every time, the counter "resets" (using imprecise language here) so it executes another 6 times.
If you want the counter to be remembered outside of a single function call, you must declare it outside of the function.
This also means you don't need the do while inside the function. Every function will perform exactly one move (as long as the player has moves left).
Something along these lines:
private int movesLeft = 6;
private void Gameplay_KeyDown(object sender, KeyEventArgs e)
{
if(movesLeft > 0)
{
int x = placeholder1.Location.X;
int y = placeholder1.Location.Y;
if (e.KeyCode == Keys.Right) x += 64;
else if (e.KeyCode == Keys.Left) x -= 64;
else if (e.KeyCode == Keys.Down) y += 64;
else if (e.KeyCode == Keys.Up) y -= 64;
placeholder1.Location = new Point(x, y);
movesLeft--;
Console.WriteLine($"{movesLeft} moves left!");
}
}

Every time you press the key down you start from 6 moves. Try this if you want to use all 6 moves in 1 press (please note: you can avoid using a loop here):
int spaceMoved = 6;
private void Gameplay_KeyDown(object sender, KeyEventArgs e)
{
do
{
int x = placeholder1.Location.X;
int y = placeholder1.Location.Y;
if (e.KeyCode == Keys.Right) x += 64;
else if (e.KeyCode == Keys.Left) x -= 64;
else if (e.KeyCode == Keys.Down) y += 64;
else if (e.KeyCode == Keys.Up) y -= 64;
placeholder1.Location = new Point(x, y);
spaceMoved--;
Console.WriteLine(spaceMoved);
} while (spaceMoved > 0);
}
Or if you don't want to use all 6 at once, but only 1 per key press (not very clear from your question), do this:
int spaceMoved = 6;
private void Gameplay_KeyDown(object sender, KeyEventArgs e)
{
int x = placeholder1.Location.X;
int y = placeholder1.Location.Y;
if (e.KeyCode == Keys.Right) x += 64;
else if (e.KeyCode == Keys.Left) x -= 64;
else if (e.KeyCode == Keys.Down) y += 64;
else if (e.KeyCode == Keys.Up) y -= 64;
placeholder1.Location = new Point(x, y);
spaceMoved--;
Console.WriteLine(spaceMoved);
}

Your do wile condition is still valid that's why it's running over and over. Try to make with for loop it'll be fine
int spacemoved = 6;
for(int i = 0; i<= spacemoved; i++)
{
do something();
}

Related

Pong game use enum for direction player in C#

I am new to enum and my teacher said I should use it in my code, so I tried but it doesn't work, I am trying to make pong. This is my code. I tried using examples form other codes with enum but it doesnt work.
using System;
using System.Windows.Forms;
namespace pong_1._13
{
public partial class Form1 : Form
{
int MaxScore = 10; // the max score you can get
int ActivateBotCheat = 9; // makes the bot always win when the playerscore = the value of AcitvateBotCheat, To turn cheat off set value to 10
int speed = 6; // bot speed
int playerSpeed = 8; // the speed of the player
int topScreen = 0; // the top of the screen
int bottemScreen = 350; // the boytom of th screen
int middelScreen = 300; // respawnpoint of the ball
int leftSideScreen = 0; // the left side of the screen
// right side of screen = ClientSize.Width
int YIs0 = 10; // the value Y gets when it ends up at 0 so the bal keeps going up and down
int YcheatOffset = 30; // offset bot when cheat is enabled
enum Deraction {goUp, goDown}
Deraction UpDown;
int ballX = 5; // the x angle of the ball left/right
int ballY = 5; // the y angle of the ball up/down
int ballXspeedAdd = 1; // after round add ball speed X
int ballYspeedAdd = 5; // after round add ball speed Y
int score = 0; // the score of the player
int scoreAI = 0; // the score of the bot
public Form1()
{
InitializeComponent();
}
private void keyIsUp(object sender, KeyEventArgs e) // looks if the player wants to go up or down if not then makes the player stand still
{
if (e.KeyCode == Keys.Up)
{
}
else if (e.KeyCode == Keys.Down)
{
Deraction Down = Deraction.goDown;
}
}
private void keyIsDown(object sender, KeyEventArgs e) // looks if the player wants to go up or down if so makes the player go up and down
{
if (e.KeyCode == Keys.Down)
{
Deraction Down = Deraction.goDown;
}
else if (e.KeyCode == Keys.Up)
{
Deraction Up = Deraction.goUp;
}
}
private void timerTick(object sender, EventArgs e)
{
playerScore.Text = "" + score; // dispays player score
aiScore.Text = "" + scoreAI; // displays bot score
ball.Top += ballY; // makes the ball bouwns
ball.Left -= ballX; // makes the ball bouwns
bot.Top += speed; // makes bot faster
if (score < ActivateBotCheat)
{
if (bot.Top < topScreen || bot.Top > bottemScreen) // normal game play for the bot
{
speed = -speed; // makes bot slower
}
}
else // cheat code for bot
{
bot.Top = ball.Top - YcheatOffset; // set the x cordinats of the bot = to x cordinats of the ball mines the offset
}
if (ball.Left < leftSideScreen) // when bot scores
{
ball.Left = middelScreen; // respawnpoit ball
ballX = -ballX; // makes the ball go the other way
ballX -= ballXspeedAdd; // makes the bal go faster
ballY = -ballY; // makes the ball go the other way
ballY += ballYspeedAdd; // makes the bal go faster
scoreAI++;
}
if (ball.Left + ball.Width > ClientSize.Width) // when player scores
{
ball.Left = middelScreen; // respawnpoit ball
ballX = -ballX; // makes the ball go the other way
ballX += ballXspeedAdd; // makes the bal go faster
ballY = -ballY; // makes the ball go the other way
ballY += ballYspeedAdd; // makes the bal go faster
score++;
}
if (ball.Top < leftSideScreen || ball.Top + ball.Height > ClientSize.Height) // when ball hits border of the screen
{
ballY = -ballY; // makes the ball go the other way
}
if (ball.Bounds.IntersectsWith(player.Bounds) || ball.Bounds.IntersectsWith(bot.Bounds)) // when ball hits border of the screen
{
ballX = -ballX; // makes the ball go the other way
}
if(ballY == 0) // makes sure ball Y is not 0
{
ballY += YIs0;
}
if (UpDown == Deraction.goUp && player.Top > topScreen) // makes player go up
{
player.Top -= playerSpeed;
}
if (UpDown == Deraction.goDown && player.Top < bottemScreen) // makes player go down
{
player.Top += playerSpeed;
}
if (score == MaxScore) // show message when player wins
{
score++;
gameTimer.Stop();
MessageBox.Show("You win this game");
}
if (scoreAI == MaxScore) // show message when bot wins
{
scoreAI++;
gameTimer.Stop();
MessageBox.Show("The bot wins, you lose");
}
}
}
}
enum Deraction {goUp, goDown};
Deraction UpDown;
This is correct. Your problem is that you are not using UpDown later. Instead, you are writing Deraction Down = Deraction.goDown; which does not affect UpDown.
Change your code to assign to UpDown.
Example:
private void keyIsUp(object sender, KeyEventArgs e) // looks if the player wants to go up or down if not then makes the player stand still
{
if (e.KeyCode == Keys.Up)
{
}
else if (e.KeyCode == Keys.Down)
{
UpDown = Deraction.goDown;
}
}
private void keyIsDown(object sender, KeyEventArgs e) // looks if the player wants to go up or down if so makes the player go up and down
{
if (e.KeyCode == Keys.Down)
{
UpDown = Deraction.goDown;
}
else if (e.KeyCode == Keys.Up)
{
UpDown = Deraction.goUp;
}
}

C# End image movement by pressing key

I am new to C# and wanted to know how I could make it so that once the user presses the enter key, the current location of the image becomes its fixed location. I was thinking that the best way to do it would be using a while loop. Help would really be appreciated. The following is my code for moving my image:
private void pictureBox1_KeyDown(object sender, KeyEventArgs e)
{
int x = pictureBox1.Location.X;
int y = pictureBox1.Location.Y;
{
if (e.KeyCode == Keys.Right) x += 50;
else if (e.KeyCode == Keys.Left) x -= 50;
else if (e.KeyCode == Keys.Up) y -= 50;
else if (e.KeyCode == Keys.Down) y += 50;
pictureBox1.Location = new Point(x, y);
}
}
In this solution i have used a global bool object and changed flag to true once an enter key is pressed.
I have a form with Picture Box and on the form_KeyDown event i placed your code with small change.
bool bIsEnterKeyPressed = false;
private void frmSampleJson_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
bIsEnterKeyPressed = true;
}
if (!bIsEnterKeyPressed)
{
int x = pictureBox1.Location.X;
int y = pictureBox1.Location.Y;
{
if (e.KeyCode == Keys.Right) x += 50;
else if (e.KeyCode == Keys.Left) x -= 50;
else if (e.KeyCode == Keys.Up) y -= 50;
else if (e.KeyCode == Keys.Down) y += 50;
pictureBox1.Location = new Point(x, y);
}
}
}
Once enter is pressed the bIsEnterKeyPressed is changed to true and the position will not be changed after that.

c# variables reset when code is moved from keydown event into a function - can anyone explain why?

I am using a C# windows forms application in VS Express 2010. I'm playing around with some code for the purposes of learning. I have a form object, which I want to continually move in one direction with a key press - original code for this works fine.
In the process of trying to tidy it by moving the code for "movement" into a function, the code no longer works as before. Instead of my object moving from its current position in the direction selected, it now resets its position every time a key is pressed. I was wondering why this is happening, as the change I have made is absolutely minimal. Please see code:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down)
{
direction = 4;
}
if (e.KeyCode == Keys.Up)
{
direction = 2;
}
if (e.KeyCode == Keys.Right)
{
direction = 3;
}
if (e.KeyCode == Keys.Left)
{
direction = 1;
}
while (direction != 0)
{
Application.DoEvents();
if (direction == 1)
{
X = X - 1;
}
else if (direction == 2)//up
{
Y = Y - 1;
}
else if (direction == 3)
{
X = X + 1;
}
else if (direction == 4)//down
{
Y = Y + 1;
}
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
when I move the while loop into a movement function, the variables X and Y are reset to 0 upon every key press. code for this looks as follows:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down)
{
direction = 4;
}
if (e.KeyCode == Keys.Up)
{
direction = 2;
}
if (e.KeyCode == Keys.Right)
{
direction = 3;
}
if (e.KeyCode == Keys.Left)
{
direction = 1;
}
movement(X, Y, direction);
}
I feel like I'm missing something obvious here but I don't understand why it's behaving differently. Thanks for any help :)
EDIT 1: The code for the movement function:
movement(int X, int Y, int direction)
{
while (direction != 0)
{
Application.DoEvents();
if (direction == 1)
{
X = X - 1;
}
else if (direction == 2)//up
{
Y = Y - 1;
}
else if (direction == 3)
{
X = X + 1;
}
else if (direction == 4)//down
{
Y = Y + 1;
}
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
I guess your movement method changes X and Y which were supplied as parameters. However, the parameters X and Y are passed 'by value', not 'by reference'.
If you want to make this work, you either have to use class variables, and remove the parameters in the method call, or use ref, which I will demonstrate:
movement(ref X, ref Y, direction);
And:
private void movement(ref int X, ref int Y, int direction)
{ }
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down) direction = 4;
else if (e.KeyCode == Keys.Up) direction = 2;
else if (e.KeyCode == Keys.Right) direction = 3;
else if (e.KeyCode == Keys.Left) direction = 1;
while (direction != 0)
{
Application.DoEvents();
if (direction == 1) X--;
else if (direction == 2) Y--;
else if (direction == 3) X++;
else if (direction == 4) Y++;
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
Could be rewritten :
private void SetDirection(KeyEventArgs e)
{
if (e.KeyCode == Keys.Down) direction = 4;
else if (e.KeyCode == Keys.Up) direction = 2;
else if (e.KeyCode == Keys.Right) direction = 3;
else if (e.KeyCode == Keys.Left) direction = 1;
}
private void ApplyMovement()
{
while (direction != 0)
{
Application.DoEvents();
if (direction == 1) X--;
else if (direction == 2) Y--;
else if (direction == 3) X++;
else if (direction == 4) Y++;
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
SetDirection(e);
ApplyMovement();
}
You have to understand that the variables X, Y, and direction are class members, so they are accessible from anywhere in your class, and when you call movement(X, Y, direction) then movement plays with copies of those variables, so when you do X = X + 1 inside your movement method, you are not actually changing the X value of your class, but only to the copy of it.
This means that the variables X and Y (i.e. class members) are not reset to 0 upon every key press. In fact they are never set to anything else.
Note that you could also use switch statements instead of all those ifs.
switch (direction)
{
case 1: X--; break; // left
case 2: Y--; break; // up
case 3: X++; break; // right
case 4: Y++; break; // down
}

Restricting picture box movement inside panel

i am creating a game application in c#, there is panel and picturebox inside that panel. now i want to restrict that picture box within that panel boundary. i am moving picture box with keydown event.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
pictureBox1.Left -= 10;
//po = position.Left;
}
else if (e.KeyCode == Keys.Right)
{
pictureBox1.Left += 10;
// po = position.Right;
}
else if (e.KeyCode == Keys.Up)
{
pictureBox1.Top -= 10;
// po = position.Up;
}
else if (e.KeyCode == Keys.Down)
{
pictureBox1.Top +=10;
// po = position.Down;
}
}
It is preferred that you use a switch statement in your case.
The below code is tested and working. You just need to set the Max values calculated from the height/width of the PictureBox and Panel.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
int borderMargin = 5;
int stepSize = 10;
switch (e.KeyCode)
{
case Keys.Left:
{
int newLeft = Math.Max(0, pictureBox1.Left - stepSize);
pictureBox1.Left = newLeft;
break;
}
case Keys.Right:
{
int maxVal = panel1.Width - pictureBox1.Width - borderMargin;
int newLeft = Math.Min(maxVal, pictureBox1.Left + stepSize);
pictureBox1.Left = newLeft;
break;
}
case Keys.Up:
{
int newTop = Math.Max(0, pictureBox1.Top - stepSize);
pictureBox1.Top = newTop;
break;
}
case Keys.Down:
{
int maxVal = panel1.Height - pictureBox1.Height - borderMargin;
int newTop = Math.Min(maxVal, pictureBox1.Top + stepSize);
pictureBox1.Top = newTop;
break;
}
}
}
Also set the borderMargin and stepSize according to your needs based on your Form configuration.

I can't seem to move the location of a Picture box in c#

I'm trying to make it so that when I press the up arrow, it moves the picture box up, the down arrow moves down, ect. But I can't seem to get it to work. It is giving me the error:
Can't modify the return value of
'System.Windows.Forms.Control.Location' because it is not a variable
This is my code:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Up)
{
ImgGuy.Location.Y--;
}
else if (e.KeyCode == Keys.Down)
{
ImgGuy.Location.Y++;
}
else if (e.KeyCode == Keys.Left)
{
ImgGuy.Location.X--;
}
else if (e.KeyCode == Keys.Right)
{
ImgGuy.Location.X++;
}
Any help is greatly appreciated.
You have to recreate new Location:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
Point l;
if(e.KeyCode == Keys.Up)
{
l = new Point(ImgGuy.Location.X, ImgGuy.Location.Y - 1);
}
else if (e.KeyCode == Keys.Down)
{
l = new Point(ImgGuy.Location.X, ImgGuy.Location.Y + 1);
}
else if (e.KeyCode == Keys.Left)
{
l = new Point(ImgGuy.Location.X - 1, ImgGuy.Location.Y);
}
else if (e.KeyCode == Keys.Right)
{
l = new Point(ImgGuy.Location.X + 1, ImgGuy.Location.Y);
}
ImgGuy.Location = l;
}
Try this:
ImgGuy.Location = new Point(ImgGuy.Location.X+1, ImgGuy.Location.Y+1) // etc
The problem is that Location returns a copy of the location.
Alternatively, set Control.Left and Control.Top instead.
You need to produce a new point
In this case X is increased aka move left
Pic.Location = new Point(Pic.Location.X + 1, Pic.Location.Y);

Categories