This is my first question on stackoverflow, sorry if I made stupid mistakes,
I hope you can help me out!
So my game looks kinda laggy when i Run it, my player studders and if I add gifs instead of image's then everything is very slow :/
I used pictureboxes as Image's
Here is my code (I just used one class):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ProjectBlok1Remake
{
public partial class myGame : Form
{
bool jump = false;
bool right = false;
bool left = false;
int score = 0;
int jumpspeed = 10;
int force = 8;
System.Media.SoundPlayer sp = new System.Media.SoundPlayer("muziek.wav");
public myGame()
{
InitializeComponent();
sp.Play(); // play music :)
}
private void myGame_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Right)
{
right = true;
}
if (e.KeyCode == Keys.Left)
{
left = true;
}
if (e.KeyCode == Keys.Escape)
{
this.Close(); //exist the game
}
if (jump != true)
{
if (e.KeyCode == Keys.Space)
{
jump = true;
}
}
}
private void myGame_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Right)
{
right = false;
}
if (e.KeyCode == Keys.Left)
{
left = false;
}
if (jump)
{
jump = false;
}
}
private void AddPoints(int valueCoin)
{
score = valueCoin + score;
}
private void GameTimer(object sender, EventArgs e)
{
player.Top += jumpspeed;
if (jump && force < 0)
{
jump = false;
}
if (left)
{
player.Left -= 5;
}
if (right)
{
player.Left += 5;
}
if (jump)
{
jumpspeed = -12;
force -= 1;
}
else
{
jumpspeed = 12;
}
foreach (Control x in this.Controls)
{
if (x is PictureBox && x.Tag == "platform")
{
if (player.Bounds.IntersectsWith(x.Bounds) && !jump)
{
force = 8;
player.Top = x.Top - player.Height;
}
}
if (x is PictureBox && x.Tag == "coin")
{
if (player.Bounds.IntersectsWith(x.Bounds) && !jump)
{
this.Controls.Remove(x); //will remove current touched coin :)
AddPoints(5); // each coin taken, will increase the score with 5 points!
}
}
if (x is PictureBox && x.Tag == "bigCoin")
{
if (player.Bounds.IntersectsWith(x.Bounds) && !jump)
{
this.Controls.Remove(x); //will remove current touched coin :)
AddPoints(15); ; // each coin taken, will increase the score with 15 points!
}
}
this.scoreLabel.Text = "score: " + score;
}
if (player.Bounds.IntersectsWith(door.Bounds))
{
timer1.Stop();
sp.Stop();
MessageBox.Show("Congratulations! YOU WON THE GAME! + \n With a total score of: " + score + "\n Exit the game with escape (2x)");
}
if (player.Bounds.IntersectsWith(panel1.Bounds))
{
timer1.Stop();
sp.Stop();
MessageBox.Show("YOU DIED, GAME OVER! :c");
}
}
}
}
Here is an Image of how the game looks like, All the Image's you see are uploaded from a file.
https://i.stack.imgur.com/8QiIc.png
...but if i delete that, there is no gravity and he can't jump.... I didn't say to delete it. I just pointed the problem of changing the position of the player prior the intersect checking. The way you do it is to chech if the new position is ok then change it:
CODE:
private void GameTimer(object sender, EventArgs e)
{
//Don't change the position of the player but a copy one, playerClone!
Rectangle playerClone = player.Bounds;
playerClone.Y += jumpspeed;
if (jump && force < 0)
{
jump = false;
}
if (left)
{
playerClone.X -= 5;
}
if (right)
{
playerClone.X += 5;
}
if (jump)
{
jumpspeed = -12;
force -= 1;
}
else
{
jumpspeed = 12;
}
foreach (Control x in this.Controls)
{
if (x is PictureBox && x.Tag == "platform")
{
if (playerClone.IntersectsWith(x.Bounds) && !jump)
{
force = 8;
playerClone.Y = x.Top - playerClone.Height;
}
}
if (x is PictureBox && x.Tag == "coin")
{
if (playerClone.IntersectsWith(x.Bounds) && !jump)
{
this.Controls.Remove(x); //will remove current touched coin :)
AddPoints(5); // each coin taken, will increase the score with 5 points!
}
}
if (x is PictureBox && x.Tag == "bigCoin")
{
if (playerClone.IntersectsWith(x.Bounds) && !jump)
{
this.Controls.Remove(x); //will remove current touched coin :)
AddPoints(15); ; // each coin taken, will increase the score with 15 points!
}
}
this.scoreLabel.Text = "score: " + score;
}
if (playerClone.IntersectsWith(door.Bounds))
{
timer1.Stop();
sp.Stop();
MessageBox.Show("Congratulations! YOU WON THE GAME! + \n With a total score of: " + score + "\n Exit the game with escape (2x)");
return;
}
if (playerClone.IntersectsWith(panel1.Bounds))
{
timer1.Stop();
sp.Stop();
MessageBox.Show("YOU DIED, GAME OVER! :c");
return;
}
//And now set the player position
player.Bounds = playerClone;
}
Related
I'm making a platformer for my A Level programming project where the player automatically jumps on a platform upon touching it. However, I'm having trouble with the collision detection because it only bounces on one platform and falls right through the rest. they all have the same tags so i know that's not the issue.
the way that it's coded is that it will detect collision with any rectangle with the tag 'platform' however it only detects collision with 1 rectangle
Code sample below:
public partial class MainWindow : Window
{
private DispatcherTimer GameTimer = new DispatcherTimer();
private bool LeftKeyPressed, RightKeyPressed, gravity;
double score;
//this value will increase to be 5x the highest Y value so the score increases the higher Meke gets
private float SpeedX, SpeedY, FrictionX = 0.88f, Speed = 1, FrictionY = 0.80f;
//SpeedX controls horizontal movement, SpeedY controls vertical movement
private void Collide(string Dir)
{
foreach (var x in GameScreen.Children.OfType<Rectangle>())
{
if (x.Tag != null)
{
var platformID = (string)x.Tag;
if (platformID == "platform")
{
x.Stroke = Brushes.Black;
Rect MeekHB = new Rect(Canvas.GetLeft(Meek), Canvas.GetTop(Meek), Meek.Width, Meek.Height);
Rect PlatformHB = new Rect(Canvas.GetLeft(x), Canvas.GetTop(x), x.Width, x.Height);
int Jumpcount = 1;
if (MeekHB.IntersectsWith(PlatformHB))
{
if (Dir == "y")
{
while (Jumpcount != 700)
{
gravity = false;
Jumpcount = Jumpcount + 1;
}
}
}
else
{
gravity = true;
}
}
}
}
}
private void KeyboardUp(object sender, KeyEventArgs e)
{
//this is what detects when the 'A' key is being pressed
if (e.Key == Key.A)
{
LeftKeyPressed = false;
}
if (e.Key == Key.D)
{
RightKeyPressed = false;
}
}
private void KeyboardDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.A)
{
LeftKeyPressed = true;
}
if (e.Key == Key.D)
{
RightKeyPressed = true;
}
}
public MainWindow()
{
InitializeComponent();
GameScreen.Focus();
GameTimer.Interval = TimeSpan.FromMilliseconds(16);
GameTimer.Tick += GameTick;
GameTimer.Start();
}
private void GameTick(Object Sender, EventArgs e)
{
txtScore.Content = "Score: " + score;
if (LeftKeyPressed)
{
SpeedX -= Speed;
}
if (RightKeyPressed)
{
SpeedX += Speed;
}
if (gravity == true)
{
SpeedY += Speed;
}
else if (gravity == false)
{
SpeedY -= Speed+50;
}
SpeedX = SpeedX * FrictionX;
SpeedY = SpeedY * FrictionY;
Canvas.SetLeft(Meek, Canvas.GetLeft(Meek) + SpeedX);
Collide("x");
Canvas.SetTop(Meek, Canvas.GetTop(Meek) + SpeedY);
Collide("y");
double maxY = 0;
if (Canvas.GetBottom(Meek) > maxY)
{
maxY = Canvas.GetBottom(Meek);
}
score = maxY;
}
}
}
I think there is an error in your gravity = true logic. You make check for intersections in loop for all platforms, so even if first platform in loop sets gravity to false, next platform in loop will set gravity to true again and logic won't work. As far as I understand, your logic works only to detect last platform in GameScreen.Children.OfType(). Maybe try to break; you loop after you found an intersection.
And for future - add some logs to your app to be able to debug such issues. Most likely your game library provide some ways to print debug messages - add them to your code so you can see, what's going on.
And also your while (Jumpcount != 700) loop looks useless
For a school project I need to develop a platform style game purely in C# Windows forms and cannot use any other languages. I have a gravity and movement system sorted already but my character is still able to jump off the map or jump through picture boxes. How would I go about making these objects solid so that the character cannot run through them. Here is my code
What my game looks like:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
bool left;
bool right;
int gravity = 20;
int force;
bool jump;
private void Timer(object sender, EventArgs e)
{
if (left == true)
{
Character.Left -= 15;
if (Character.Image != Properties.Resources.LeftChar)
{
Character.Image = Properties.Resources.LeftChar;
}
}
if (right == true)
{
Character.Left += 15;
if (Character.Image != Properties.Resources.RightChar)
{
Character.Image = Properties.Resources.RightChar;
}
}
if (jump == true)
{
Character.Top -= force;
force -= 1;
}
if (Character.Top + Character.Height >= GameBoundary.Height)
{
Character.Top = GameBoundary.Height - Character.Height;
jump = false;
}
else
{
Character.Top += 10;
}
}
private void keydown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.A)
left = true;
if (e.KeyCode == Keys.D)
right = true;
if (jump != true)
{
if (e.KeyCode == Keys.W)
{
jump = true;
force = gravity;
}
}
}
private void keyup(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.A)
left = false;
if (e.KeyCode == Keys.D)
right = false;
}
}
I created an invisible panel that was the same size of the game called "Gameboundary", this made it possible for the player to walk on the bottom of the window, but I am not sure how I would apply this to the rest of the code. If anybody has any suggestions it will be greatly welcome. Not too good at C# just yet!
Here is a basic Collision Detection system:
public class CollisionDetection
{
public static bool ObjectTouchingOthers(Control Object, int SpaceBetweenObjects)
{
for (int i = 0; i < Object.Parent.Controls.Count; i++)
{
if (Object.Parent.Controls[i].Name != Object.Name)
{
if (Object.Left + Object.Width + SpaceBetweenObjects > Object.Parent.Controls[i].Left && Object.Top + Object.Height + SpaceBetweenObjects > Object.Parent.Controls[i].Top && Object.Left < Object.Parent.Controls[i].Left + Object.Parent.Controls[i].Width + SpaceBetweenObjects && Object.Top < Object.Parent.Controls[i].Top + Object.Parent.Controls[i].Height + SpaceBetweenObjects)
{
return true;
}
}
}
return false;
}
public static bool ObjectTouchingOthers(Control Object, int SpaceBetweenObjects, Control[] ControlsToExclude )
{
for (int i = 0; i < Object.Parent.Controls.Count; i++)
{
if (ControlsToExclude.Contains(Object.Parent.Controls[i]) == false && Object.Parent.Controls[i].Name != Object.Name)
{
if (Object.Left + Object.Width + SpaceBetweenObjects > Object.Parent.Controls[i].Left && Object.Top + Object.Height + SpaceBetweenObjects > Object.Parent.Controls[i].Top && Object.Left < Object.Parent.Controls[i].Left + Object.Parent.Controls[i].Width + SpaceBetweenObjects && Object.Top < Object.Parent.Controls[i].Top + Object.Parent.Controls[i].Height + SpaceBetweenObjects)
{
return true;
}
}
}
return false;
}
}
The first argument Object is the control you want collision detection for, and it will only detect other controls in the same container, so if you used it for a control in a panel, for example, it would only work with other controls in the panel, likewise with a Form or any other control. The second argument simply specifies how much distance you want between the controls when they are touching. If you're using the second overload, the third argument is an array of controls that you do not want collision detection for. This is how you would use the second overload:
private void btnMoveLeft_Click(object sender, EventArgs e)
{
btnPlayer.Left -= 1;
if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1, new Control[] {button1, button2}) == true)
{
btnPlayer.Left += 1;
}
}
With this overload, it will continue right through the controls you specified in the array.
And just to wrap it up, here's a basic example of how to set up collision detection:
private void btnMoveLeft_Click(object sender, EventArgs e)
{
btnPlayer.Left -= 1;
if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1) == true)
{
btnPlayer.Left += 1;
}
}
private void btnMoveRight_Click(object sender, EventArgs e)
{
btnPlayer.Left += 1;
if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1) == true)
{
btnPlayer.Left -= 1;
}
}
private void btnMoveUp_Click(object sender, EventArgs e)
{
btnPlayer.Top -= 1;
if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1) == true)
{
btnPlayer.Top += 1;
}
}
private void btnMoveDown_Click(object sender, EventArgs e)
{
btnPlayer.Top += 1;
if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1) == true)
{
btnPlayer.Top -= 1;
}
}
Just remember that you're going to have to change the names of the controls in the code I have here. And for reference, here is my test form:
You need to implement collision detection. Draw an imaginary box around your person and any objects you don't want him to pass through. Check if any of the boxes overlap. If they do, move one or both of the objects back until the boxes no longer overlap.
Picture boxes has a .Bounds with a .IntersectWith and this will take an object of type Rectangle.
In a game, you will typically have an ongoing timer, checking all sorts of stuff and progressing time.
In this timer i would make a:
if (pictureBox1.Bounds.IntersectsWith(pictureBox2.Bounds))
{
//They have collided
}
You might have a lot of objects, so you could make a List<PictureBox> and add those objects, then the list will have refferences to those PictureBoxes, that means that they will automatically be updated with the right bounds, when you go through the List.
Be sure to make the List a public property of your form class. Then before rolling through the List, instead set another List = to the public object List. This ensures that you can do a foreach() loop without getting exceptions.
I am trying to make a 2D game in winforms. i want my character to be able to double jump and if i hold the space key (jump) for a long time i will jump higher or if i hold the space key (jump) less i will jump lower (Note that although holding longer will jump higher, but only up to a fixed level, not to infinity). but I can only double jump and only jump 1 fixed distance, not hold the space longer to jump higher or hold it shorter to jump lower, someone help me, below is my code.
public partial class GamePlay_Page : Form
{
bool goRight, goLeft;
int gravity = 16;
int force;
bool jump;
int jumpTimes = 2;
public GamePlay_Page()
{
InitializeComponent();
}
private void GamePlay_Page_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.D)
{
goRight = true;
Trex.Image = Properties.Resources.running;
}
if (e.KeyCode == Keys.A)
{
goLeft = true;
Trex.Image = Properties.Resources.running2;
}
if (e.KeyCode == Keys.W && jumpTimes > 0)
{
jump = true;
force = gravity;
jumpTimes -= 1;
}
private void gameT(object sender, EventArgs e)
{
if (goRight == true && Trex.Right < 600)
{
Trex.Left += 5;
}
if (goLeft == true && Trex.Left > 10)
{
Trex.Left -= 5;
}
if (jump == true)
{
Trex.Top -= force;
force -= 1;
}
if (Trex.Top + Trex.Height >= backgroundAbove.Height)
{
Trex.Top = backgroundAbove.Height - Trex.Height;
}
else
{
Trex.Top += 3;
}
if (Trex.Top + Trex.Height == backgroundAbove.Height)
{
jumpTimes = 2;
}
private void GamePlay_Page_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.D) { goRight = false; }
if (e.KeyCode == Keys.A) { goLeft = false; }
}
I am not sure if this is what you mean, and change it according to your needs.
Please see my example:
Add a stopwatch to judge the length of the pressing time, in order to prevent the intensity from bursting.
What I set is to give a fixed force for pressing more than 3s, otherwise give an initial force for gravity.
Change it according to your needs.
You can completely change it to a force multiplied by time.
Stopwatch watch =new Stopwatch();
watch.Start();//start the timer
watch.Stop(); //stop the timer
watch.ElapsedMilliseconds// Show duration in milliseconds(Type is long)
watch.Reset();//reset the timer
Put the timing start into the KeyDown event:
if (e.KeyCode == Keys.W && jumpTimes > 0)
{
//jump = true;
//force = gravity;
//jumpTimes -= 1;
watch.Start();
}
Put the timing end and trigger the jump into the KeyUp event:
if (e.KeyCode == Keys.W && jumpTimes > 0)
{
watch.Stop();
jump = true;
jumpTimes -= 1;
if (watch.ElapsedMilliseconds > 300)//>3s
{
force = 30;
}
else
{
force = gravity;
}
}
watch.Reset();
All the codes:
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace GamePlay_Page {
public partial class GamePlay_Page : Form {
public GamePlay_Page () {
InitializeComponent();
}
bool goRight, goLeft;
int gravity = 16;
int force;
bool jump;
int jumpTimes = 2;
Stopwatch watch =new Stopwatch();
private void GamePlay_Page_Load (object sender, EventArgs e) {
}
private void GamePlay_Page_KeyDown (object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.D)
{
goRight = true;
Trex.Image = Properties.Resources.ch;
}
if (e.KeyCode == Keys.A)
{
goLeft = true;
Trex.Image = Properties.Resources.ca;
}
if (e.KeyCode == Keys.W && jumpTimes > 0)
{
//jump = true;
//force = gravity;
//jumpTimes -= 1;
watch.Start();
}
}
private void GamePlay_Page_KeyUp (object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.W && jumpTimes > 0)
{
watch.Stop();
if (e.KeyCode == Keys.W && jumpTimes > 0)
{
watch.Stop();
jump = true;
jumpTimes -= 1;
if (watch.ElapsedMilliseconds > 300)//>3s
{
force = 30;
}
else
{
force = gravity;
}
}
}
watch.Reset();
if (e.KeyCode == Keys.D)
{
goRight = false;
}
if (e.KeyCode == Keys.A)
{
goLeft = false;
}
}
private void Timer1_Tick (object sender, EventArgs e) {
if (goRight == true && Trex.Right < 600)
{
Trex.Left += 5;
}
if (goLeft == true && Trex.Left > 10)
{
Trex.Left -= 5;
}
if (jump == true)
{
Trex.Top -= force;
force -= 1;
}
if (Trex.Top + Trex.Height >= backgroundAbove.Height)
{
Trex.Top = backgroundAbove.Height - Trex.Height;
}
else
{
Trex.Top += 3;
}
if (Trex.Top + Trex.Height == backgroundAbove.Height)
{
jumpTimes = 2;
}
G.Text = gravity.ToString();
F.Text = force.ToString();
T.Text = Trex.Top.ToString();
L.Text = Trex.Left.ToString();
J.Text = jumpTimes.ToString();
W.Text = watch.ElapsedMilliseconds.ToString();
}
}
}
main page:
Output:
If you have questions about my code, please comment below and I will follow up as soon as possible.
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;
}
}
I'm doing a Pac-Man game on c# , and pac man cross every obstacles that I pass.
This is the entire code of my Pac-Man game:
using System;
using System.Media;
using System.Windows.Forms;
namespace Pac_Man {
public partial class Form1 : Form
{
Variables:
bool goLeft;
bool goRight;
bool goUp;
bool goDown;
int score = 0;
int totalCoins = 160;
int playerSpeed = 4;
int ghost1 = 4;
int ghost2 = 4;
Initializing:
public Form1()
{
InitializeComponent();
lblGame.Visible = false;
playSound();
}
Play sound:
private void playSound()
{
SoundPlayer simpleSound = new SoundPlayer(#"C:\Users\rsss-\OneDrive\Documentos\Visual Studio 2019\Projects\Pac_Man\Pac_Man\Sound\pacman_beginning.wav");
simpleSound.PlayLooping();
}
Key is down:
private void keyisdown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Up)
{
goUp = true;
}
if (e.KeyCode == Keys.Down)
{
goDown = true;
}
if (e.KeyCode == Keys.Left)
{
goLeft = true;
}
if (e.KeyCode == Keys.Right)
{
goRight = true;
}
}
Key is up:
private void keyisup(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Up)
{
goUp = false;
}
if (e.KeyCode == Keys.Down)
{
goDown = false;
}
if (e.KeyCode == Keys.Left)
{
goLeft = false;
}
if (e.KeyCode == Keys.Right)
{
goRight = false;
}
}
Timer:
private void timer1_Tick(object sender, EventArgs e)
{
int movement = playerSpeed;
if (goLeft)
{
foreach (Control x in this.Controls)
{
if (x is PictureBox && x.Tag == "obstacle" && x.Left == player.Left - playerSpeed && x.Top == player.Top)
{
movement = 0;
break;
}
}
player.Left -= movement;
movement = playerSpeed;
}
else if (goRight)
{
foreach (Control x in this.Controls)
{
if (x is PictureBox && x.Tag == "obstacle" && x.Left == player.Left + playerSpeed && x.Top == player.Top)
{
movement = 0;
break;
}
}
player.Left += movement;
movement = playerSpeed;
}
else if (goUp)
{
foreach (Control x in this.Controls)
{
if (x is PictureBox && x.Tag == "obstacle" && x.Top == player.Top - playerSpeed && x.Left == player.Left)
{
movement = 0;
break;
}
}
player.Top -= movement;
movement = playerSpeed;
}
else if (goDown)
{
foreach (Control x in this.Controls)
{
if (x is PictureBox && x.Tag == "obstacle" && x.Top == player.Top + playerSpeed && x.Left== player.Left)
{
movement = 0;
break;
}
}
player.Top += movement;
movement = playerSpeed;
}
if (player.Left > 641)
{
player.Left = 82;
}
else if (player.Left < 82)
{
player.Left = 641;
}
foreach (Control x in this.Controls)
{
if (x is PictureBox && x.Tag == "ghost")
{
if (((PictureBox)x).Bounds.IntersectsWith(player.Bounds))
{
gameOver();
MessageBox.Show("You Lost!" + "\n" + "Your score is " + score);
this.Close();
}
}
}
Ghosts Movement:
redGhost.Left += ghost1;
orangeGhost.Left += ghost2;
blueGhost.Left -= ghost1;
pinkGhost.Left -= ghost2;
foreach (Control c in this.Controls)
{
if (c is PictureBox && c.Tag == "coin")
{
if (player.Bounds.IntersectsWith(c.Bounds))
{
this.Controls.Remove(c);
score++;
}
}
}
lblScore.Text = "Score: " + score;
if (score == totalCoins)
{
gameOver();
MessageBox.Show("You Win!" + "\n" + "You reach the maximum score: " + score);
this.Close();
}
}
Game Over:
private void gameOver()
{
timer1.Stop();
lblGame.Visible = true;
lblGame.Text = "Game Over!";
}
} }
Basically, I want that the character don't move in that direction if he hits an obstacle.
Anyone can help me?
Thank you.
This is a different and hopefully simpler way to test for obstacle hit, I dont know if it can compile but i hope you get the general idea
First calculate x and y movement, then apply that movement to a copy of the players bounds and check if it intersects with any obstacle, if it does break out of the loop, if not test next obstacle
If no intersections found then move the player
Need to ensure that System.Drawing.Rectangle originalBounds = player.Bounds actually creates a copy of the players bounds, otherwise the player will move back and forward while the loop is running
private void timer1_Tick(object sender, EventArgs e)
{
int moveX = 0;
int moveY = 0;
bool hitObstacle = false;
System.Drawing.Rectangle originalBounds = player.Bounds; // make sure this is a copy of players bounds rectangle.
if(goLeft)
moveX = -playerSpeed;
else if(goRight)
moveX = playerSpeed;
else if (goUp)
moveY = -playerSpeed;
else if (goDown)
moveY = playerSpeed;
originalBounds.Offset(moveX,moveY);
foreach (Control x in this.Controls)
{
if (x is PictureBox && x.Tag == "obstacle") {
if (originalBounds.IntersectsWith(x.Bounds)) {
hitObstacle = true;
break;
}
}
if(hitObstacle==false) {
player.Bounds=originalBounds;
}
if (player.Left > 641)
.....