I am making a brick break game in c# windows form in which I need to remove a picture box when the ball(picture box) collide with it........
I have tried hide, dispose remove control and even making it equal to null but all of them just hide it and doesn't make it vanished completely means that there is still collision.....
here is my code:
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 WindowsFormsApplication20
{
public partial class Form1 : Form
{
public int spx =10;
public int spy = 10;
public Form1()
{
InitializeComponent();
timer1.Enabled = true;
Cursor.Hide();
this.FormBorderStyle = FormBorderStyle.None;
this.TopMost = true;
this.Bounds = Screen.PrimaryScreen.Bounds;
paddle.Top = background.Bottom - (background.Bottom / 10);
if(paddle.Left > background.Left)
{
paddle.Left += 0;
}
}
private void Form1_ControlRemoved(object sender, ControlEventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
ball.Left += spx;
ball.Top += spy;
paddle.Left = Cursor.Position.X - (paddle.Left / Width);
if(ball.Left <= background.Left)
{
spx = -spx;
}
if (ball.Right >= background.Right)
{
spx = -spx;
}
if (ball.Top <= background.Top)
{
spy = -spy;
}
if (ball.Bottom >= background.Bottom)
{
spy = -spy;
}
if (paddle.Top <= ball.Bottom && paddle.Top >= ball.Top && ball.Left >= paddle.Left && ball.Right <= paddle.Right)
{
spy = -spy;
}
if (pictureBox.Top <= ball.Bottom && pictureBox.Bottom >= ball.Top && ball.Left <= pictureBox.Right && ball.Right >= pictureBox.Left)
{
spy = -spy;
background.Controls.Remove(pictureBox);
pictureBox = null;
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
this.Close();
}
}
}
}
Your code that checks for collisions is hard-coded to look at pictureBox. Making it invisible doesn't change that.
If you want to use the Visible property of pictureBox to hide it, then you should change those if conditions to ignore it if it isn't visible:
if (pictureBox.Visible && (pictureBox.Top <= ball.Bottom && pictureBox.Bottom >= ball.Top && ball.Left <= pictureBox.Right && ball.Right >= pictureBox.Left))
{
spy = -spy;
pictureBox.Visible = false;
}
Related
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;
}
}
}
}
Could someone help me?
I really don't know what to do. I don't want to restart my project even if there is little code inside it don't ask me why. Maybe because Im lazy. I think it is probably problems with the varibels I guess. As I said I don't know.
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 Project_Zomboid
{
public partial class Form1 : Form
{
int positiony = 0;
int positionx = 0;
public Form1()
{
InitializeComponent();
player.Controls.Add(ak47gun);
ak47gun.Location = new Point(0, 0);
ak47gun.BackColor = Color.Transparent;
Startup();
player.Location = new Point(positionx, positiony);
}
void Startup()
{
if (true == true)
{
}
}
private void keypress(object sender, System.Windows.Forms.KeyEventArgs e)
{
if(e.KeyCode == Keys.W)
{
positiony += 1;
}
else if(e.KeyCode == Keys.S)
{
positiony -= 1;
}
else if (e.KeyCode == Keys.D)
{
positionx += 1;
}
else if( e.KeyCode == Keys.A)
{
positionx -= 1;
}
}
}
}
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 Project_Zomboid
{
public partial class Form1 : Form
{
int positiony = 0;
int positionx = 0;
Thread gameLoop;
public Form1()
{
InitializeComponent();
player.Controls.Add(ak47gun);
ak47gun.Location = new Point(0, 0);
ak47gun.BackColor = Color.Transparent;
gameLoop = new Thread(new ThreadStart(Startup));
gameLoop.Start();
}
public void Startup()
{
while(true)
{
player.Location = new Point(positionx, positiony);
Thread.Sleep(128);
}
}
private void keypress(object sender, System.Windows.Forms.KeyEventArgs e)
{
if(e.KeyCode == Keys.W)
{
positiony += 1;
}
else if(e.KeyCode == Keys.S)
{
positiony -= 1;
}
else if (e.KeyCode == Keys.D)
{
positionx += 1;
}
else if( e.KeyCode == Keys.A)
{
positionx -= 1;
}
}
}
}
I think that will get your image moving around the screen but, I would seriously suggest if you're interested in making games you should consider watching a lot of tutorials online on youtube. This movement isn't time sensitive so your picture will move as fast as the cpu can add to the x or y position. Which should be really fast. The sleep in the thread is to make sure your picture isn't always updating. I would first suggest a tutorial that explains delta time and velocity.
There are also a TON of free example games online that can give you a great example of how a lot of this is done.
Something else to note is if you don't want a game loop/thread update the player.Location = new Point(positionx, positiony) inside the keypress method after updating the integer.
I'm using Visual Studio 2019 my question is closely aligned with the use of this Tutorial. I've done all the steps such as:
Creation of a Window Form in C#
Adding existing file Joystick.cs
Adding Reference item
Added Application Configuration File and pasted the code provided
Pasted example code into Form1.cs
My question: What am I missing? I can't access the library for joystick Screenshot of Error
Here is the whole Form1.cs code:
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 RunJoyStickOnLocalMachine{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void joystickTimer_Tick_1(object sender, EventArgs e)
{
try
{
joystick.UpdateStatus();
joystickButtons = joystick.buttons;
if (joystick.Xaxis == 0)
output.Text += "Left\n";
if (joystick.Xaxis == 65535)
output.Text += "Right\n";
if (joystick.Yaxis == 0)
output.Text += "Up\n";
if (joystick.Yaxis == 65535)
output.Text += "Down\n";
for (int i = 0; i < joystickButtons.Length; i++)
{
if (joystickButtons[i] == true)
output.Text += "Button " + i + " Pressed\n";
}
}
catch
{
joystickTimer.Enabled = false;
connectToJoystick(joystick);
}
}
}
}
If there is anything else that I need to provide please notify me.
Thank You!
Edit: I've solved this problem by comparing both the tutorial file and the step by step tutorial file that the blog has.
You can download the project from the article you mentioned to check the code.
Based on my test, you can use the following code in the form1.cs code after you add theJoystick.cs to your project.
public partial class Form1 : Form
{
private Joystick joystick; // define the type Joystick
private bool[] joystickButtons; // here define the bool array
public Form1()
{
InitializeComponent();
joystick = new Joystick(this.Handle);
connectToJoystick(joystick);
}
private void joystickTimer_Tick(object sender, EventArgs e)
{
try
{
joystick.UpdateStatus();
joystickButtons = joystick.buttons;
if (joystick.Xaxis == 0)
output.Text += "Left\n"; // output is the name of richtextbox
if (joystick.Xaxis == 65535)
output.Text += "Right\n";
if (joystick.Yaxis == 0)
output.Text += "Up\n";
if (joystick.Yaxis == 65535)
output.Text += "Down\n";
for (int i = 0; i < joystickButtons.Length; i++)
{
if (joystickButtons[i] == true)
output.Text += "Button " + i + " Pressed\n";
}
}
catch
{
joystickTimer.Enabled = false;
connectToJoystick(joystick);
}
}
private void enableTimer()
{
if (this.InvokeRequired)
{
BeginInvoke(new ThreadStart(delegate ()
{
joystickTimer.Enabled = true;
}));
}
else
joystickTimer.Enabled = true;
}
private void connectToJoystick(Joystick joystick)
{
while (true)
{
string sticks = joystick.FindJoysticks();
if (sticks != null)
{
if (joystick.AcquireJoystick(sticks))
{
enableTimer();
break;
}
}
}
}
}
I have been working on a little game and I encountered with this problem and I can't figure out how to solve it. Everything worked fine until I put a checkBox on the form. How can I reach that to use the checkBox and the control at the same time and not to break the control loop with the checkBox.
Here is my code:
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.Threading;
namespace Mozgás_Gyakorlás
{
public partial class Form1 : Form
{
enum Position
{
Left, Right, Up, Down
}
public int x = 262;
public int y = 318;
private Position pozíció;
public Form1()
{
InitializeComponent();
pozíció = Position.Left;
}
public void pictureBox4_Paint(object sender, PaintEventArgs e)
{
timer2.Start();
e.Graphics.FillRectangle((Brushes.Blue), x, y, 20, 20);
checkBox1.PerformLayout();
}
private void timer2_Tick(object sender, EventArgs e)
{
if(pozíció == Position.Right)
{
x += 3;
}
if(pozíció == Position.Left)
{
x -= 3;
}
if(pozíció == Position.Up)
{
y -= 3;
}
if(pozíció == Position.Down)
{
y += 3;
}
pictureBox4.Invalidate();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Up)
{
pozíció = Position.Up;
}
if(e.KeyCode == Keys.Down)
{
pozíció = Position.Down;
}
if(e.KeyCode == Keys.Left)
{
pozíció = Position.Left;
}
if(e.KeyCode == Keys.Right)
{
pozíció = Position.Right;
}
}
private void checkBox1_Click(object sender, EventArgs e)
{
if (checkBox1.Checked == true)
{
pictureBox4.Image = Image.FromFile(#"D:\Táblázat2.JPG");
}
else
{
pictureBox4.Image = null;
}
}
}
}
Here's some points that might help.
The Timer should be started/stopped in the Form's constructor/Load event or on a Button click and not in the Paint event.
public Form1()
{
InitializeComponent();
pozíció = Position.Left;
timer2.Start();
}
The Timer.Tick event:
private void timer2_Tick(object sender, EventArgs e)
{
//Hint: You might want to keep the rectangle within the canvas.
pozíció = x < 0 ? Position.Right : x + 21 > pictureBox4.ClientRectangle.Right ? Position.Left : pozíció;
pozíció = y < 0 ? Position.Down : y + 21 > pictureBox4.ClientRectangle.Bottom ? Position.Up : pozíció;
switch (pozíció)
{
case Position.Right:
x += 3;
break;
case Position.Left:
x -= 3;
break;
case Position.Up:
y -= 3;
break;
case Position.Down:
y += 3;
break;
default:
x = 0;
y = 0;
break;
}
pictureBox4.Invalidate();
}
You can write the enum block as follows:
enum Position
{
Left = 37,
Up,
Right,
Down,
}
Where 37 is the KeyCode of the Left key, and consequently Up = 38, Right = 39, and Down = 40. So you can shrink the KeyDown event as follows:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Left ||
e.KeyCode == Keys.Up ||
e.KeyCode == Keys.Right ||
e.KeyCode == Keys.Down)
{
pozíció = (Position)e.KeyCode;
pictureBox4.Invalidate();
}
}
To show/hide the image, handle the CheckedChanged instead:
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
pictureBox4.Image = checkBox1.Checked ? Táblázat2 : null;
}
Presuming that the Táblázat2 is a class level variable = Image.FromFile(#"D:\Táblázat2.JPG"); assigned in the Form's constructor.
The Paint event:
private void pictureBox4_Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.Blue, x, y, 20, 20);
}
Alternatively, and as you are handling the Paint event, you can get rid of the CheckedChanged event of the CheckBox control and draw the image yourself:
private void pictureBox4_Paint(object sender, PaintEventArgs e)
{
var g = e.Graphics;
if (checkBox1.Checked)
{
var sz = Táblázat2.Size;
var r = e.ClipRectangle;
g.SmoothingMode = SmoothingMode.HighQuality;
g.DrawImage(Táblázat2,
new Rectangle((r.Width - sz.Width) / 2, (r.Height - sz.Height) /2, sz.Width, sz.Height),
new Rectangle(0, 0, sz.Width, sz.Height),
GraphicsUnit.Pixel);
}
g.FillRectangle(Brushes.Blue, x, y, 20, 20);
}
and just in case the timer is not enabled:
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
pictureBox4.Invalidate();
}
Good luck.
I'm programming an calendar with C# right now.
If i call my calendar, it creates as much panels as the current month has days. But if I want to increase the current month by one, the panels from the current month are stilt there.
So i have to delete all my panels as soon as I change the month.
But how can i do it in this case ?
Thanks for the help.
Code eplain:
First I call the createPanel method, to create panels for the current month.
Next if I click the MonthAdd method, I want to delete all my created panels.
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.Globalization;
namespace Einteilungs_Plan
{
public partial class Kalender : Form
{
public DateTime TodayDate { get; set; }
int counting = 0;
public Kalender()
{
InitializeComponent();
//Kalenderwochen initialisieren
monat(counting);
createPanel(true);
}
public string monat(int adding)
{
string monat = DateTime.Now.AddMonths(adding).ToString("MMMM");
tbMonat.Text = monat;
return monat;
}
private void btnAddMonth_Click(object sender, EventArgs e)
{
counting++;
if(counting < 12)
{
monat(counting);
switch (counting)
{
case 0:
int number = 10;
break;
case 1:
break;
default:
break;
}
}
else
{
counting--;
}
}
private void btnRemoveMonth_Click(object sender, EventArgs e)
{
counting--;
if (counting > -1)
{
monat(counting);
}
else
{
counting++;
}
}
public void createPanel(bool remove)
{
var numDays = DateTime.DaysInMonth(DateTime.Today.Year, DateTime.Today.Month);
int locationX = 12;
int locationY = 74;
for (int i = 0; i <= numDays; i++)
{
//Create Panel
Panel test = new Panel();
//Fill Panel
test.Name = "panel" + i;
test.Width = 200;
test.Height = 100;
test.BackColor = Color.White;
test.Location = new System.Drawing.Point(locationX, locationY);
this.Controls.Add(test);
test.Show();
if(i == 6 || i == 13 || i == 20 || i == 28)
{
locationY += 106;
locationX = -194;
}
locationX += 206;
}
}
public void Kalender_Shown(object sender, EventArgs e)
{
}
private void Kalender_Load(object sender, EventArgs e)
{
}
private void btnNeuerEintrag_Click(object sender, EventArgs e)
{
Formular formular = new Formular();
formular.Show();
formular.Focus();
}
private void btnHinzufügen_Click(object sender, EventArgs e)
{
Formular formular = new Formular();
formular.Show();
formular.Focus();
}
}
}
...
for (int i = 0; i <= numDays; i++)
{
//Create Panel
test[i] = new Panel();
}
...
and then
this.Control.Remove(test[i]);
I'm not sure if I undestood you well but first simple solutiona that comes into my mind is that while creating panels you can keep them in some List for example and before generating new month you can call
foreach (var p in panels)
this.Controls.Remove(p);