Intersect a circle with a picturebox - c#

I am making a DxBaLL Game. First i tried make the ball with picturebox but when it comes to intersection, if ball interects with 2 bricks, bricks just break but i want them break in 3 shots. So then, i tried make ball with Graphics.DrawEllips but how can i detect if ball intersect with picturebox(brick) or not?
This is the ball with picturebox version. when the ball comes between 2 bricks(picturebox), bricks are disappearing.
namespace DxBall
{
public partial class Form1 : Form
{
bool goLeft, goRight, isGameOver;
bool gameStart = false;
int sideCount = 0;
int force = 3;
int x_force = 3;
int gameScore = 0;
int[] direction = { 0, 0 }; //x,y
int stickSpeed = 15;
public Form1()
{
InitializeComponent();
}
private async void MainGameTimer(object sender, EventArgs e)
{
if (gameStart == false)
{
gameStart = true;
}
txt_score.Text = "Score: " + gameScore;
if (goLeft == true && stick.Left > 0)
{
stick.Left -= stickSpeed;
}
if (goRight == true && stick.Left < 458)
{
stick.Left += stickSpeed;
}
if (direction[0] == 0)
{
if (ball.Left > 580)
{
direction[0] = 1;
}
else
{
ball.Left += x_force;
}
}
else if (direction[0] == 1)
{
if (ball.Left < 0)
{
direction[0] = 0;
}
else
{
ball.Left -= x_force;
}
}
if (direction[1] == 0)
{
if (ball.Top > 720)
{
direction[1] = 1;
}
else
{
ball.Top += force;
}
}
else if (direction[1] == 1)
{
if (ball.Top < 0)
{
direction[1] = 0;
}
else
{
ball.Top -= force;
}
}
foreach (Control x in this.Controls)
{
if (x is PictureBox)
{
if ((string)x.Tag == "stick")
{
if (ball.Bounds.IntersectsWith(x.Bounds))
{
direction[1] = 1;
}
x.BringToFront();
}
if ((string)x.Tag == "brick")
{
if (ball.Bounds.IntersectsWith(x.Bounds))
{
sideCount++;
if (x.BackColor == Color.Red && x.Visible == true&&sideCount<1)
{
if (direction[1] == 0) direction[1] = 1;
else if (direction[1] == 1) direction[1] = 0;
x.BackColor = Color.Yellow;
}
else if (x.BackColor == Color.Yellow && x.Visible == true && sideCount < 1)
{
if (direction[1] == 0) direction[1] = 1;
else if (direction[1] == 1) direction[1] = 0;
x.BackColor = Color.Blue;
}
else if (x.BackColor == Color.Blue && x.Visible == true && sideCount < 1)
{
if (direction[1] == 0) direction[1] = 1;
else if (direction[1] == 1) direction[1] = 0;
x.Visible = false;
gameScore++;
}
}
x.BringToFront();
}
if ((string)x.Tag == "gameOver")
{
if (ball.Bounds.IntersectsWith(x.Bounds))
{
GameTimer.Stop();
txtGameOver.Text = "Game Over! Your Score is: " + gameScore;
}
}
}
}
sideCount--;
}
private void KeyIsDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
goLeft = true;
}
if (e.KeyCode == Keys.Right)
{
goRight = true;
}
}
private void Form1_Load(object sender, EventArgs e)
{
Random rnd = new Random();
ball.Left = rnd.Next(0, 580);
direction[0] = rnd.Next(0, 2);
}
private void KeyIsUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
goLeft = false;
}
if (e.KeyCode == Keys.Right)
{
goRight = false;
}
}
private void RestartGame()
{
goLeft = false;
goRight = false;
isGameOver = false;
gameScore = 0;
txt_score.Text = "Score: " + gameScore;
foreach (Control x in this.Controls)
{
if (x is PictureBox && x.Visible == false)
{
x.Visible = true;
}
}
ball.Left = 390;
ball.Top = 527;
stick.Left = 310;
stick.Top = 700;
GameTimer.Start();
}
}
}

Related

Check collision and prevent overlap

I can't seem to figure out how to make this simple animation work, where i have user control over a red square, and it shouldn't overlap/intersect with a black square (e.g. a wall sprite)
My best effort is to have stack data structure of keys pressed and if there is an intersection, then we look at (peek) last key pressed and assign a speed of -1. (See line 67 of code) But this doesn't prevent an overlap. Is there a way that I can make it so the user's red rectangle can't overlap with black?
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;
using System.Collections;
namespace Movement
{
public partial class Form1 : Form
{
bool moveRight, moveLeft, moveUp, moveDown;
Keys currentInput;
Keys lastInput;
Stack pressedKeys = new Stack();
int speed = 5;
bool collision = false;
public Form1()
{
InitializeComponent();
this.CenterToScreen();
}
private void pbRed_Click(object sender, EventArgs e)
{
}
private void moveTimeEvent(object sender, EventArgs e)
{
currentInput = Keys.KeyCode;
//moving left
if (moveLeft == true && pbRed.Left > 7 )
{
pbRed.Left -= speed;
}
//moving right
if (moveRight == true && pbRed.Left < 750)
{
pbRed.Left += speed;
}
//moving up
if(moveUp == true && pbRed.Top > 7)
{
pbRed.Top -= speed;
}
//moving down
if(moveDown == true && pbRed.Top < 400)
{
pbRed.Top += speed;
}
if (moveLeft == true || moveRight == true || moveUp == true || moveDown == true)
{
pressedKeys.Push(currentInput);
}
Collision();
}
private void Collision()
{
//collision detection
if(pbRed.Bounds.IntersectsWith(pbBlack.Bounds))
{
collision = true;
if(collision)
{
lastInput = (Keys)pressedKeys.Peek();
if(currentInput == lastInput)
{
speed = -1;
}
}
}
}
private void keyisdown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Left)
{
moveLeft = true;
}
if (e.KeyCode == Keys.Right)
{
moveRight = true;
}
if (e.KeyCode == Keys.Up)
{
moveUp = true;
}
if (e.KeyCode == Keys.Down)
{
moveDown = true;
}
}
private void keyisup(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
moveLeft = false;
}
if (e.KeyCode == Keys.Right)
{
moveRight = false;
}
if (e.KeyCode == Keys.Up)
{
moveUp = false;
}
if (e.KeyCode == Keys.Down)
{
moveDown = false;
}
}
}
}
When your speed is 5, don't apply a movement of 5 pixels in one go, but apply the 5 steps separately. Before each step, so before actually moving the rectangle, decide whether that one step movement is allowed.
Also look at vertical and horizontal movement separately.
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Movement
{
public partial class Form1 : Form
{
bool moveRight, moveLeft, moveUp, moveDown;
int speed = 5;
public Form1()
{
InitializeComponent();
this.CenterToScreen();
}
private void moveTimeEvent(object sender, EventArgs e)
{
// Get movement vector
Point movement = new Point(0, 0);
if (moveLeft) movement.X -= 1;
if (moveRight) movement.X += 1;
if (moveUp) movement.Y -= 1;
if (moveDown) movement.Y += 1;
// Speed defines how many steps we move
for (int i=1; i<= speed; i++)
{
// Check vertical movement allowed
if (movement.X != 0)
{
Rectangle newPosition = pbRed.Bounds;
newPosition.X += movement.X;
if (!CheckCollision(newPosition))
{
movement.X = 0;
}
}
// Check horizontal movement allowed
if (movement.Y != 0)
{
Rectangle newPosition = pbRed.Bounds;
newPosition.X += movement.X;
newPosition.Y += movement.Y;
if (!CheckCollision(newPosition))
{
movement.Y = 0;
}
}
// Apply Actual movement
if (!movement.IsEmpty)
{
Rectangle newPosition = pbRed.Bounds;
newPosition.X += movement.X;
newPosition.Y += movement.Y;
pbRed.Bounds = newPosition;
}
}
}
// Returns true when movingRecht is allowed position
private bool CheckCollision(Rectangle movingRect)
{
bool lResult = true;
//collision detection
lResult = lResult && !pbBlack.Bounds.IntersectsWith(movingRect);
// Check we remain inside the form
lResult = lResult && movingRect.Left >= 0;
lResult = lResult && movingRect.Top >= 0;
lResult = lResult && movingRect.Right <= ClientRectangle.Right;
lResult = lResult && movingRect.Bottom <= ClientRectangle.Bottom;
return lResult;
}
private void keyisdown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
moveLeft = true;
}
if (e.KeyCode == Keys.Right)
{
moveRight = true;
}
if (e.KeyCode == Keys.Up)
{
moveUp = true;
}
if (e.KeyCode == Keys.Down)
{
moveDown = true;
}
}
private void keyisup(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
moveLeft = false;
}
if (e.KeyCode == Keys.Right)
{
moveRight = false;
}
if (e.KeyCode == Keys.Up)
{
moveUp = false;
}
if (e.KeyCode == Keys.Down)
{
moveDown = false;
}
}
}
}

I'm getting error Ambiguity between '¨Form1.score' and ¨Form1.score'

i have int score = 0; under public partial class Form1 : Form and Im getting error in txtscore.Text = "Score: " + score; and score = 0; in private void RestartHry() does someone know why is that? Or know how to fix that bsc i have no idea. ......................................................................................................................................................................................
namespace Projekt_Havlík
{
public partial class Form1 : Form
{
bool vpravo, vlevo;
int rychlost = 8;
int score = 0;
int minul = 0;
Random rndX = new Random();
Random rndY = new Random();
PictureBox minulcoin = new PictureBox();
public Form1()
{
InitializeComponent();
RestartHry();
}
private void MainGameTimerEvent(object sender, EventArgs e)
{
//naprogramovaní textboxů
txtscore.Text = "Score: " + score;
txtminul.Text = "Minul: " + minul;
//změnění postavy při jízdě do leva/prava
if (vlevo == true && player.Left > 0)
{
player.Left -= 12;
player.Image = Properties.Resources.main_left;
}
if (vpravo == true && player.Left + player.Width <this.ClientSize.Width)
{
player.Left += 12;
player.Image = Properties.Resources.main_right;
}
}
private void KeyIsUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
vlevo = false;
}
if (e.KeyCode == Keys.Right)
{
vpravo = false;
}
}
private void KeyIsDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
vlevo = true;
}
if (e.KeyCode == Keys.Right)
{
vpravo = true;
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void RestartHry()
{
foreach(Control x in this.Controls)
{
if (x is PictureBox &&(string)x.Tag == "coins")
{
x.Top = rndY.Next(80, 300) * -1;
x.Left = rndX.Next(5, this.ClientSize.Width - x.Width);
}
}
player.Left = this.ClientSize.Width / 2;
player.Image = Properties.Resources.main_right;
score = 0;
minul = 0;
rychlost = 8;
vpravo = false;
vlevo = false;
CasovacHry.Start();
}
}
}
Try changing the name of your "score" variable, try calling it like, "myScore", typically if something is ambiguous it is because there are two fields or properties with the same name in assembly references that are not directly specified in the code.

How do I move an object using a timer and the key press event (Like snake)

I want to move a button automatically using a timer and want it to change direction when another key is pressed, kinda like what happens in snake
I have used a string to set what the direction should be, but this doesn't work.
string x = "right";
public Form1()
{
InitializeComponent();
timer1.Interval = 1000;
timer1.Start();
}
private void Player_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.W)
{
string x = "up";
}
else if (e.KeyCode == Keys.S)
{
string x = "down";
}
else if (e.KeyCode == Keys.D)
{
string x = "right";
}
else if (e.KeyCode == Keys.A)
{
string x = "left";
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void Timer1_Tick(object sender, EventArgs e)
{
while (x == "up")
{
Player.Top -= 10;
}
while (x == "down")
{
Player.Top += 10;
}
while (x == "right")
{
Player.Left += 10;
}
while (x == "left")
{
Player.Left -= 10;
}
}
}
The button just disappears, but I want it to move by ten until it gets a key press like "D" then it changes direction
1: You are creating variable 'x' every time means locally in player_keyDown event so create it globally.
2: you are using while loop it, not needed as you are already using timer_tick.
3: Instead of Top, Left use Location property of button it gives you X, Y co-ordinate
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
timer1.Interval = 1000;
timer1.Start();
}
string x = "right";
private void Player_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.W)
{
x = "up";
}
else if (e.KeyCode == Keys.S)
{
x = "down";
}
else if (e.KeyCode == Keys.D)
{
x = "right";
}
else if (e.KeyCode == Keys.A)
{
x = "left";
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (x == "up")
{
Player.Location = new System.Drawing.Point(Player.Location.X, Player.Location.Y - 10);
}
if (x == "down")
{
Player.Location = new System.Drawing.Point(Player.Location.X, Player.Location.Y + 10);
}
if (x == "right")
{
Player.Location = new System.Drawing.Point(Player.Location.X + 10, Player.Location.Y);
}
if (x == "left")
{
Player.Location = new System.Drawing.Point(Player.Location.X - 10, Player.Location.Y);
}
}
}

C# - "Pong Game" - Collision with edges of paddle

I dont know how to make ball bounce when hits Paddle´s Top or Bottom, my problem is that the ball goes through the Paddle and then keep going...
So this is the code, some things are in my language so here is translator:
Mustek = Paddle
Mic = Ball
body = Points
HraciPole = Name for graphics array, something like "GameArray"
casovac = name for timer
Kolize = Collision
PohybDolu = MoveUp (bool)
PohybNahoru = MoveDown (bool)
public partial class Form_Pong : Form
{
public static Mustek p1 = new Mustek();
public static Mustek p2 = new Mustek();
public static Mic ball = new Mic();
public int body1 = 0;
public int body2 = 0;
Graphics draw;
public Form_Pong()
{
InitializeComponent();
draw = picBoxHraciPole.CreateGraphics();
}
public static void Draw(Graphics draw)
{
draw.Clear(Color.Black);
draw.FillRectangle(new SolidBrush(Color.Blue), new Rectangle(p1.location, p1.size));
draw.FillRectangle(new SolidBrush(Color.Red), new Rectangle(p2.location, p2.size));
draw.FillRectangle(new SolidBrush(Color.White), new Rectangle(ball.location, ball.size));
}
private void casovac_Tick(object sender, EventArgs e)
{
if (casovac.Interval == 10)
{
p1.location.X = 30;
p1.location.Y = (picBoxHraciPole.Height - p1.size.Height) / 2;
p2.location.X = (picBoxHraciPole.Width - p2.size.Width) - 30;
p2.location.Y = p1.location.Y;
ball.location = new Point(picBoxHraciPole.Width / 2, picBoxHraciPole.Height / 2);
casovac.Interval = 5;
}
Kolize();
Pohyb();
Draw(draw);
}
public void Kolize()
{
if (p1.location.Y < 0)
{
p1.location.Y = 0;
}
if (p1.location.Y + p1.size.Height > picBoxHraciPole.Height)
{
p1.location.Y = picBoxHraciPole.Height - p1.size.Height;
}
if (p2.location.Y < 0)
{
p2.location.Y = 0;
}
if (p2.location.Y + p2.size.Height > picBoxHraciPole.Height)
{
p2.location.Y = picBoxHraciPole.Height - p2.size.Height;
}
if (ball.location.Y < 0)
{
ball.speed.Y = -ball.speed.Y;
}
if (ball.location.Y + ball.size.Height > picBoxHraciPole.Height)
{
ball.speed.Y = -ball.speed.Y;
}
if (ball.location.X < 0)
{
body2 += 1;
labelBody2.Text = body2.ToString();
Reset();
}
if (ball.location.X + ball.size.Width > picBoxHraciPole.Width)
{
body1 +=1;
labelBody1.Text = body1.ToString();
Reset();
}
if (new Rectangle(ball.location, ball.size).IntersectsWith(new Rectangle(p1.location, p1.size)) ||
new Rectangle(ball.location, ball.size).IntersectsWith(new Rectangle(p2.location, p2.size)))
{
ball.speed.X = -ball.speed.X;
}
if (new Rectangle(ball.location, ball.size).IntersectsWith(new Rectangle(p1.location, p1.size)) ||
new Rectangle(ball.location, ball.size).IntersectsWith(new Rectangle(p2.location, p2.size)))
{
}
}
public void Reset()
{
ball.location = new Point(picBoxHraciPole.Width / 2, picBoxHraciPole.Height / 2);
ball.speed.X = -ball.speed.X;
ball.speed.Y = -ball.speed.Y;
}
public static void Pohyb()
{
if (p1.PohybNahoru == true)
{
p1.location.Y -= 8;
}
if (p1.PohybDolu == true)
{
p1.location.Y += 6;
}
if (p2.PohybNahoru == true)
{
p2.location.Y -= 6;
}
if (p2.PohybDolu == true)
{
p2.location.Y += 6;
}
ball.location.X += ball.speed.X;
ball.location.Y += ball.speed.Y;
}
private void Form_Pong_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.W)
{
p1.PohybNahoru = true;
}
if (e.KeyCode == Keys.S)
{
p1.PohybDolu = true;
}
if (e.KeyCode == Keys.Escape)
{
Application.Exit();
}
if (e.KeyCode == Keys.Up)
{
p2.PohybNahoru = true;
}
if (e.KeyCode == Keys.Down)
{
p2.PohybDolu = true;
}
if (e.KeyCode == Keys.F1)
{
casovac.Enabled = false;
}
if (e.KeyCode == Keys.F2)
{
casovac.Enabled = true;
}
}
private void EnableDoubleBuffering()
{
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
}
private void Form_Pong_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.W)
{
p1.PohybNahoru = false;
}
if (e.KeyCode == Keys.S)
{
p1.PohybDolu = false;
}
if (e.KeyCode == Keys.Up)
{
p2.PohybNahoru = false;
}
if (e.KeyCode == Keys.Down)
{
p2.PohybDolu = false;
}
}
}
public class Mustek
{
public Point location;
public Size size;
public bool PohybNahoru, PohybDolu;
public int Score;
public Mustek()
{
Score = 0;
size.Width = 25;
size.Height = 125;
}
}
public class Mic
{
public Point location;
public Size size;
public Point speed;
public Mic()
{
speed.X = -5;
speed.Y = 5;
this.size.Width = 25;
this.size.Height = 25;
}
}
The basic logic that you are looking for is
If edge of ball =edge of paddle then change direction so as if x was decreasing bow x is to ve increasing
Once you have that you can work out angles for different conditions such as if it gits the edge of the paddle ect.

Restarting while loop in C#

I am a beginner in C# and creating a small game in where the user gets to throw a ball with a certain gravity, speed and random wind. The ball is supposed to hit a goal, give the user points (when it hits) and then go back to start position for user to throw it again. I have got everything working except the matter of getting the ball back into start position. Any help would be greatly appreciated!
Here is some parts of my code:
private void goButton_Click(object sender, EventArgs e)
{
if (running == true)
{
b1.Location = new Point(0, 300);
b1.speedX = (double)upDownX.Value;
b1.speedY = (double)upDownY.Value;
running = false;
b1.Start();
return;
}
running = true;
worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(RunMe); worker.RunWorkerAsync();
}
public void RunMe(object sender, DoWorkEventArgs e)
{
while (running)
{
if (b1.speedY > 0 && b1.Location.Y > panel.Size.Height - b1.Size.Height)
{
b1.posY = panel.Size.Height - b1.Size.Height;
addPoints();
running = false;
BeginInvoke((MethodInvoker)delegate
{
b1.Location = new Point(0, 300);
});
}
if (b1.speedX > 0 && b1.Location.X > panel.Size.Width - b1.Size.Width)
{
running = false;
if (b1.Location.Y < 290 && b1.Location.Y > 150 && b1.Location.X > 430)
{
if (diffValue.Text == "Normal")
{
Ball.score += 10;
}
if (diffValue.Text == "Easy")
{
Ball.score += 7;
}
}
else if (b1.Location.Y < 390 && b1.Location.Y > 60 && b1.Location.X > 430)
{
if (diffValue.Text == "Normal")
{
Ball.score += 5;
}
if (diffValue.Text == "Easy")
{
Ball.score += 3;
}
}
addPoints();
b1.BounceX();
goto restart;
}
if (b1.speedX < 0 && b1.Location.X < 0)
{
b1.BounceX();
}
this.Invoke(new MoveBallCallback(MoveBall), b1);
Thread.Sleep(10);
}
}
public void addPoints()
{
if (Ball.tries >= 1)
{
Ball.tries -= 1;
string triesLeft = Ball.tries.ToString();
this.Invoke(new Action(() => this.shotsLeft.Text = triesLeft));
string score = Ball.score.ToString();
this.Invoke(new Action(() => this.scores.Text = score));
Normal();
BeginInvoke((MethodInvoker)delegate
{
b1.Location = new Point(0, 300);
});
}
else
{
MessageBox.Show("No shots left!");
string currentHighscore = System.IO.File.ReadAllText(#"highscore.txt");
this.highscoreValue.Text = currentHighscore;
int Highscore = Convert.ToInt32(currentHighscore);
string score = Ball.score.ToString();
this.Invoke(new Action(() => this.scores.Text = score));
int Score = Convert.ToInt32(Ball.score);
if (Score > Highscore)
{
MessageBox.Show("New highscore!");
string highScore = score;
System.IO.File.WriteAllText(#"highscore.txt", highScore);
string highscore = Highscore.ToString();
this.Invoke(new Action(() => this.highscoreValue.Text = highscore));
}
this.Invoke(new Action(() => goButton.Enabled = false));
}
}
You can use:
continue;
to skip to next repetition of a loop (where you write goto restart;).

Categories

Resources