Pong game use enum for direction player in C# - 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;
}
}

Related

Detecting multiple platforms- c# wpf

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

Set an object as "Solid" in C# windows Form when developing a stickman platform game

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.

c# Platform game optimization issue + player studdering

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;
}

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
}

How to access a variable defined in designer code from other classes?

I'm trying to make a game that is round-based, and I want to make it so that the user is able to define the amount of rounds from the beginning. I've made it so that the user will input a number into a text box, and then a button will put that number into a variable called length by using "length = Convert.ToInt32(textBox1.Text)". Unfortunately, I'm not sure how to access this length variable from the Form1 class so that I can set the number of rounds. Can someone please point me in the right direction? I've tried doing SpeedDialog.length (SpeedDialog is a windows form designer class that I'm getting the info from), but it did not seem to work, saying that I cannot reference a non-static class. Could I fix this problem by making SpeedDialog static (I'm thinking not but I could be wrong)? Thank you so much! I really appreciate it!
Here's my Form1 class:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
namespace BrickO1
{
public partial class Form1 : Form
{
private const int kNumberOfTries = 3;
public int rounds;
private Ball TheBall = new Ball();
private Paddle ThePaddle = new Paddle();
private Paddle TheOtherPaddle = new Paddle();
// private System.Windows.Forms.Timer timer1;
private Score TheScore = null;
private Score TheOtherScore = null;
private Thread oThread = null; //thread is used to run sounds independently
[DllImport("winmm.dll")]
public static extern long PlaySound(String lpszName, long hModule, long dwFlags);
//method PlaySound must be imported from the .dll file winmm
public Form1()
{
InitializeComponent();
ThePaddle.Position.X = 5;
ThePaddle.Position.Y = this.ClientRectangle.Bottom - ThePaddle.Height;
TheOtherPaddle.Position.X = 5;
TheOtherPaddle.Position.Y = 0;
// this.ClientRectangle refers to the current container (the instance of Form1)
TheBall.Position.Y = this.ClientRectangle.Bottom - 200;
TheScore = new Score(ClientRectangle.Right - 30, ClientRectangle.Bottom - 40);
TheOtherScore = new Score(ClientRectangle.Right - 30, ClientRectangle.Bottom - 370);
//positions the score - 0 at this moment
// choose Level
SpeedDialog dlg = new SpeedDialog();
/* makes sure that, if the DialogResult property of the button "OK" is on,
the SpeedDialog form appears and stays on the screen, and timer's Interval
gets an appropriate value */
if (dlg.ShowDialog() == DialogResult.OK)
{
timer1.Interval = dlg.Speed;
}
}
private string m_strCurrentSoundFile = "BallOut.wav"; //sound file is initialized
public void PlayASound() //method to play a sound; to be called by a thread
{
if (m_strCurrentSoundFile.Length > 0)
{
PlaySound(Application.StartupPath + "\\" + m_strCurrentSoundFile, 0, 0);
/* the above gives full path to the location of the sound file from the startup path
of the executable file: Application.StartupPath */
}
m_strCurrentSoundFile = "";
oThread.Abort(); //aborts the tread playing sound
}
public void PlaySoundInThread(string wavefile) //creates and starts a new thread to play a sound
{
m_strCurrentSoundFile = wavefile;
oThread = new Thread(new ThreadStart(PlayASound)); //calls the method PlayASound
oThread.Start();
}
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e) //method to draw Form1
{
Graphics g = e.Graphics;
g.FillRectangle(Brushes.White, 0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height);
TheScore.Draw(g);
TheOtherScore.Draw(g);
ThePaddle.Draw(g);
TheOtherPaddle.Draw(g);
TheBall.Draw(g);
}
private void CheckForCollision()
{
if (TheBall.Position.X < 0) // hit the left side, switch polarity
{
TheBall.XStep *= -1;
TheBall.Position.X += TheBall.XStep;
PlaySoundInThread("WallHit.wav");
}
if (TheBall.Position.Y < 0) // hit the top of the form
{
//Lost the ball for 2nd paddle
TheScore.Increment();
if(TheScore.Count == SpeedDialog.length)
{
MessageBox.Show("Congrats! Player 1 wins!");
Application.Exit();
}
Reset();
PlaySoundInThread("BallOut.wav");
}
if (TheBall.Position.X > this.ClientRectangle.Right - TheBall.Width) // hit the right side, switch polarity
{
TheBall.XStep *= -1;
TheBall.Position.X += TheBall.XStep;
PlaySoundInThread("WallHit.wav");
}
if (TheBall.Position.Y > this.ClientRectangle.Bottom - TheBall.YStep) // lost the ball!
{
TheOtherScore.Increment();
if (TheScore.Count == SpeedDialog.length)
{
MessageBox.Show("Congrats! Player 2 wins!");
Application.Exit();
}
Reset();
PlaySoundInThread("BallOut.wav");
}
int hp = HitsPaddle(TheBall.Position); //check if the ball hit the paddle
if (hp > -1)// checks if the ball is not lost
{
PlaySoundInThread("PaddleHit.wav");
switch (hp) //new direction of the ball depends on which quarter of the paddle is hit
{
case 1:
TheBall.XStep = -7;
TheBall.YStep = -3;
break;
case 2:
TheBall.XStep = -5;
TheBall.YStep = -5;
break;
case 3:
TheBall.XStep = 5;
TheBall.YStep = -5;
break;
default:
TheBall.XStep = 7;
TheBall.YStep = -3;
break;
}
}
int hp2 = HitsPaddle2(TheBall.Position); //check if the ball hit the paddle
if (hp2 > -1)// checks if the ball is not lost
{
PlaySoundInThread("PaddleHit.wav");
switch (hp2) //new direction of the ball depends on which quarter of the paddle is hit
{
case 1:
TheBall.XStep = -7;
TheBall.YStep = 3;
break;
case 2:
TheBall.XStep = -5;
TheBall.YStep = 5;
break;
case 3:
TheBall.XStep = 5;
TheBall.YStep = 5;
break;
default:
TheBall.XStep = 7;
TheBall.YStep = 3;
break;
}
}
}
private int HitsPaddle(Point p)
{
Rectangle PaddleRect = ThePaddle.GetBounds(); //current position of the paddle
if (p.Y >= this.ClientRectangle.Bottom - (PaddleRect.Height + TheBall.Height))//If the ball has hit the paddle according to its y value
{
if ((p.X > PaddleRect.Left) && (p.X < PaddleRect.Right)) //ball hits the paddle (horizontally)!
{
if ((p.X > PaddleRect.Left) && (p.X <= PaddleRect.Left + PaddleRect.Width / 4))
return 1; //hits leftmost quarter of the paddle
else if ((p.X > PaddleRect.Left + PaddleRect.Width / 4) && (p.X <= PaddleRect.Left + PaddleRect.Width / 2))
return 2; //hits the second quarter of the paddle
else if ((p.X > PaddleRect.Left + PaddleRect.Width / 2) && (p.X <= PaddleRect.Right - PaddleRect.Width / 2))
return 3; //hits the third quarter of the paddle
else
return 4; //hits the rightmost quarter of the paddle
}
}
return -1;
}
private int HitsPaddle2(Point q)
{
Rectangle Paddle2Rect = TheOtherPaddle.GetBounds(); //current position of the paddle
if (q.Y <= this.ClientRectangle.Top + Paddle2Rect.Height)
{
if ((q.X > Paddle2Rect.Left) && (q.X < Paddle2Rect.Right)) //ball hits the paddle!
{
if ((q.X > Paddle2Rect.Left) && (q.X <= Paddle2Rect.Left + Paddle2Rect.Width / 4))
return 1; //hits leftmost quarter of the paddle
else if ((q.X > Paddle2Rect.Left + Paddle2Rect.Width / 4) && (q.X <= Paddle2Rect.Left + Paddle2Rect.Width / 2))
return 2; //hits the second quarter of the paddle
else if ((q.X > Paddle2Rect.Left + Paddle2Rect.Width / 2) && (q.X <= Paddle2Rect.Right - Paddle2Rect.Width / 2))
return 3; //hits the third quarter of the paddle
else
return 4; //hits the rightmost quarter of the paddle
}
}
return -1;
}
private void Reset() //resets the ball, stops timer, and redraws the main form
{
TheBall.XStep = 5;
TheBall.YStep = 5;
TheBall.Position.Y = this.ClientRectangle.Bottom - 190;
TheBall.Position.X = 5;
timer1.Stop();
TheBall.UpdateBounds();
Invalidate(TheBall.GetBounds());
}
private void timer1_Tick(object sender, System.EventArgs e) //runs one round of the game, when started
{
TheBall.UpdateBounds(); //gets the ball position
Invalidate(TheBall.GetBounds()); //redraws the ball
TheBall.Move(); //moves the ball
TheBall.UpdateBounds(); //updates position of the ball
Invalidate(TheBall.GetBounds()); //redraws the boll
CheckForCollision(); //checks for collision
Invalidate(TheScore.GetFrame()); //redraws the score
Invalidate(TheOtherScore.GetFrame());
}
private void Form1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
string result = e.KeyData.ToString();
Invalidate(ThePaddle.GetBounds());
switch (result)
{
case "Left":
ThePaddle.MoveLeft();
Invalidate(ThePaddle.GetBounds());
if (timer1.Enabled == false) //starts the game if it does not run yet
timer1.Start();
break;
case "Right":
ThePaddle.MoveRight(ClientRectangle.Right);
Invalidate(ThePaddle.GetBounds());
if (timer1.Enabled == false) //starts the game if it does not run yet
timer1.Start();
break;
case "Z":
TheOtherPaddle.MoveLeft();
Invalidate(TheOtherPaddle.GetBounds());
if (timer1.Enabled == false) //starts the game if it does not run yet
timer1.Start();
break;
case "C":
TheOtherPaddle.MoveRight(ClientRectangle.Right);
Invalidate(TheOtherPaddle.GetBounds());
if (timer1.Enabled == false) //starts the game if it does not run yet
timer1.Start();
break;
default:
break;
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
And here's the SpeedDialog class:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace BrickO1
{
public partial class SpeedDialog : Form
{
public int Speed = 250;
private static int length = 0;
public SpeedDialog()
{
InitializeComponent();
}
private void SlowRadio_CheckedChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, System.EventArgs e)
{
if (SlowRadio.Checked)
Speed = 100;
else if (MediumRadio.Checked)
Speed = 100;
else
Speed = 50;
length = Convert.ToInt32(textBox1.Text);
if(length == 0)
{
length = 5;
}
}
public int SelectedLength { get{ return length; }}
private void groupBox1_Enter(object sender, EventArgs e)
{
}
private void SpeedDialog_Load(object sender, EventArgs e)
{
}
private void groupBox2_Enter(object sender, EventArgs e)
{
}
private void maskedTextBox1_MaskInputRejected(object sender, MaskInputRejectedEventArgs e)
{
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
Thanks again!!!

Categories