so we are tasked to do a bomberman game using C# but we are not allowed to use other ide except for Visual studio using windows form. We are not allowed to use unity too. so my problem is how can i set boundaries? so that the player wont pass through the tiles... Please take time to check the image:
And 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;
namespace Layout
{
public partial class FormView : Form
{
enum Position
{
Left, Right, Up, Down
}
private int _x;
private int _y;
private Position _objPosition;
public FormView()
{
_x = 50;
_y = 50;
_objPosition = Position.Down;
InitializeComponent();
}
private void FormView_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(new Bitmap("Character.png"), _x, _y, 50, 50);
}
private void tmrMoving_Tick(object sender, EventArgs e)
{
Invalidate();
}
private void FormView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.D)
{
_x += 50;
_objPosition = Position.Right;
}
else if (e.KeyCode == Keys.A)
{
_x -= 50;
_objPosition = Position.Left;
}
else if (e.KeyCode == Keys.W)
{
_y -= 50;
_objPosition = Position.Up;
}
else if (e.KeyCode == Keys.S)
{
_y += 50;
_objPosition = Position.Down;
}
}
}
}
If _objPosition as I understand it contains the location (x,y) of your person then just check that against the size of the PictureBox with an If statement. I'm not sure what the _objPosition contains, you could just use your x and y directly as well.
var _x = 0;
var _y = 0;
if (_x == pictureBox1.Width)
{
// Dont Move
}
else
{
switch (e.KeyCode)
{
case Keys.D:
_x += 50;
_objPosition = Position.Right;
break;
case Keys.A:
_x -= 50;
_objPosition = Position.Left;
break;
}
}
if (_y == pictureBox1.Length)
{
//Don't Move
}
else
{
switch (e.KeyCode)
{
case Keys.W:
_y -= 50;
_objPosition = Position.Up;
break;
case Keys.S:
_y += 50;
_objPosition = Position.Down;
break;
}
}
Edited to push you more in the right direction.
Related
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 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;
}
I need help by moving a object on a Panel in two different direction. In example in the right and down direction by pressing the right and left buttons. Java have a a key release method do c# have such a similiar method?
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 runningRectangle
{
enum Position {Left, Right, Down, Up, LeftUp, LeftDown, RightUp, RightDown }
public partial class Form1 : Form
{
private int x;
private int y;
private Position objPos;
private int speed = 10;
private bool stopPressed = false;
public Form1()
{
InitializeComponent();
x = 50;
y = 50;
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.Red, x, y, 50, 50);
}
private void timer1_Tick(object sender, EventArgs e)
{
if(objPos == Position.Right)
{
x += speed;
}else if(objPos == Position.Left)
{
x -= speed;
}
else if (objPos == Position.Down)
{
y += speed;
}
else if (objPos == Position.Up)
{
y -= speed;
} else if (objPos == Position.RightUp)
{
x += speed;
y -= speed;
}
else if (objPos == Position.RightDown)
{
x += speed;
y += speed;
}
else if (objPos == Position.LeftUp)
{
x -= speed;
y += speed;
}
else if (objPos == Position.LeftDown)
{
x -= speed;
y -= speed;
}
Invalidate();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Right)
{
objPos = Position.Right;
}
else if (e.KeyCode == Keys.Left)
{
objPos = Position.Left;
}
else if (e.KeyCode == Keys.Down)
{
objPos = Position.Down;
}
else if (e.KeyCode == Keys.Up)
{
objPos = Position.Up;
}
else if(e.KeyCode == Keys.Right && e.KeyCode == Keys.Down)
{
objPos = Position.RightDown;
}
else if (e.KeyCode == Keys.Right && e.KeyCode == Keys.Up)
{
objPos = Position.RightUp;
}
else if (e.KeyCode == Keys.Left && e.KeyCode == Keys.Down)
{
objPos = Position.LeftDown;
}
else if (e.KeyCode == Keys.Left && e.KeyCode == Keys.Up)
{
objPos = Position.LeftUp;
}
else if(e.KeyCode == Keys.Space)
{
if (!stopPressed)
{
speed = 0;
stopPressed = true;
}
else if(stopPressed)
{
speed += 10;
stopPressed = false;
}
}
}
}
}
Form1_KeyDown and Form1_KeyUp exist in pair.
enum Position { None = -1, Left, Right, Down, Up, LeftUp, LeftDown, RightUp, RightDown }
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
objPos = (Position)(-1);
}
This question already has answers here:
Controling the Moving PictureBox
(2 answers)
Closed 7 years ago.
So I'm messing around, getting a hang of things and I'm making a picture box move, which I have done. However could someone show me how to make the movement more fluent but not slow it down so much?
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 meh
{
public partial class Form1 : Form
{
PictureBox Test = new PictureBox();
public Form1()
{
InitializeComponent();
FormBorderStyle = FormBorderStyle.None;
WindowState = FormWindowState.Maximized;
Test.Image = Properties.Resources.PlatinumGrass;
Test.Location = new Point(0, 0);
Test.Width = 32;
Test.Height = 32;
this.Controls.Add(Test);
KeyDown += new KeyEventHandler(Form1_KeyDown);
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
int x = Test.Location.X;
int y = Test.Location.Y;
int xmax = Screen.PrimaryScreen.Bounds.Width - 32;
int ymax = Screen.PrimaryScreen.Bounds.Height - 32;
if (e.KeyCode == Keys.Right && x < xmax ) x += 20;
if (e.KeyCode == Keys.Left && x > 0) x -= 20;
if (e.KeyCode == Keys.Up && y > 0) y -= 20;
if (e.KeyCode == Keys.Down && y < ymax) y += 20;
Test.Location = new Point(x, y);
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
I suggest not using winforms for game development
but you can add these lines to form constructor to make some improvements.
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
also you can add a for loop for movement part to improve it a little bit
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
int xmax = Screen.PrimaryScreen.Bounds.Width - 32;
int ymax = Screen.PrimaryScreen.Bounds.Height - 32;
for (int i = 0; i < 10; i++)
{
int x = Test.Location.X;
int y = Test.Location.Y;
if (e.KeyCode == Keys.Right && x < xmax) x += 2;
if (e.KeyCode == Keys.Left && x > 0) x -= 2;
if (e.KeyCode == Keys.Up && y > 0) y -= 2;
if (e.KeyCode == Keys.Down && y < ymax) y += 2;
Test.Location = new Point(x, y);
Application.DoEvents();
}
}
I'm currently working on a Snake game that can solve itself, but when I activate it, usually after 30~ successful hits, my application crashes with the aforementioned exception either in System.drawing.dll or in System.Windows.Forms.dll.
The problem usually occurs in the command "Application.DoEvents()", but it has occured in several other places too.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Threading;
using System.IO;
namespace Snake
{
enum Directions
{
Right = 1,
Left = -1,
Up = 2,
Down = -2,
NoDirection = 0
}
public partial class GameForm : Form
{
#region Data Members
SnakeGame gmGame;
Point pCurrFood;
Directions dirFirstDirection;
Directions dirSecondDirection;
Directions dirHelpDirection;
Color DEFAULT_COLOUR = Color.White;
const int SEGMENT_HEIGHT = 10;
const int SEGMENT_WIDTH = 10;
#endregion
#region Ctor
public GameForm()
{
InitializeComponent();
this.gmGame = new SnakeGame();
this.dirFirstDirection = Directions.NoDirection;
this.dirSecondDirection = Directions.NoDirection;
}
#endregion
#region Other Methods
private void PaintSegment(Graphics gGraphics, Point pnPoint, Color cColour)
{
Pen Pen = new Pen(cColour);
Rectangle Rectangle = new Rectangle(pnPoint.X,
pnPoint.Y,
SEGMENT_HEIGHT,
SEGMENT_WIDTH);
gGraphics.DrawRectangle(Pen, Rectangle);
Brush Brush = new SolidBrush(cColour);
gGraphics.FillRectangle(Brush, Rectangle);
}
private void PlaceNewFood()
{
Random rRand = new Random();
int nHeight = rRand.Next(this.panel1.Size.Height);
int nWidth = rRand.Next(this.panel1.Size.Width);
while ((nHeight % 10 != 0) || (nWidth % 10 != 0))
{
nHeight = rRand.Next(this.panel1.Size.Height - 10);
nWidth = rRand.Next(this.panel1.Size.Width - 10);
while (this.gmGame.SnakeQueue.Contains(new Point(nWidth, nHeight)))
{
nHeight = rRand.Next(this.panel1.Size.Height);
nWidth = rRand.Next(this.panel1.Size.Width);
}
}
this.pCurrFood = new Point(nWidth, nHeight);
this.PaintSegment(this.panel1.CreateGraphics(), this.pCurrFood, Color.Red);
}
private void SelfSolve()
{
this.dirFirstDirection = (Directions)(Math.Sign(this.gmGame.SnakeHead.Y -
this.pCurrFood.Y) * 2);
this.dirSecondDirection = (Directions)Math.Sign(this.pCurrFood.X -
this.gmGame.SnakeHead.X);
this.ManageSnake(this.dirFirstDirection, this.dirSecondDirection);
}
private bool WillCollide(Point pnPointToCheck)
{
return ((pnPointToCheck.X > this.panel1.Size.Width) ||
(pnPointToCheck.Y > this.panel1.Size.Height) ||
(pnPointToCheck.X * pnPointToCheck.Y < 0) ||
(this.gmGame.SnakeQueue.Contains(pnPointToCheck)));
}
private void ManageSnake(Directions dirFirstSnakeDirection,
Directions dirSecondSnakeDirection)
{
Point pnNewHead = this.gmGame.SnakeHead;
switch (dirFirstSnakeDirection)
{
case (Directions.Down):
{
if (this.WillCollide(new Point(pnNewHead.X, pnNewHead.Y + SEGMENT_HEIGHT)))
{
this.ManageSnake(Directions.NoDirection, dirSecondSnakeDirection);
}
else
{
pnNewHead.Y += SEGMENT_HEIGHT;
dirHelpDirection = Directions.Down;
}
break;
}
case (Directions.Up):
{
if (this.WillCollide(new Point(pnNewHead.X, pnNewHead.Y - SEGMENT_HEIGHT)))
{
this.ManageSnake(Directions.NoDirection, dirSecondSnakeDirection);
}
else
{
pnNewHead.Y -= SEGMENT_HEIGHT;
dirHelpDirection = Directions.Up;
}
break;
}
case (Directions.NoDirection):
{
switch (dirSecondSnakeDirection)
{
case (Directions.Right):
{
if (this.WillCollide(new Point(pnNewHead.X + SEGMENT_WIDTH, pnNewHead.Y)))
{
this.ManageSnake(this.dirHelpDirection, dirSecondSnakeDirection);
}
else
{
pnNewHead.X += SEGMENT_WIDTH;
}
break;
}
case (Directions.Left):
{
if (this.WillCollide(new Point(pnNewHead.X - SEGMENT_WIDTH, pnNewHead.Y)))
{
this.ManageSnake(this.dirHelpDirection, dirSecondSnakeDirection);
}
else
{
pnNewHead.X -= SEGMENT_WIDTH;
}
break;
}
}
break;
}
}
this.gmGame.AddSegment(pnNewHead);
if (this.gmGame.SnakeHead.Equals(this.pCurrFood))
{
this.lblScoreNum.Text = (int.Parse(this.lblScoreNum.Text) + 1).ToString();
this.PlaceNewFood();
}
else
{
this.PaintSegment(this.panel1.CreateGraphics(),
(Point)this.gmGame.SnakeQueue.Peek(),
DEFAULT_COLOUR);
this.gmGame.RemoveSegment();
}
this.PaintSegment(this.panel1.CreateGraphics(),
this.gmGame.SnakeHead,
Color.Green);
Thread.Sleep(5);
Application.DoEvents();
this.SelfSolve();
}
#endregion
#region Events
private void GameForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
this.PlaceNewFood();
this.SelfSolve();
}
else if (e.KeyCode == Keys.Escape)
{
this.Close();
}
else if (e.KeyCode == Keys.Space)
{
MessageBox.Show("Frozen, press OK to continue");
}
}
private void GameForm_ClientSizeChanged(object sender, EventArgs e)
{
this.PaintSegment(this.panel1.CreateGraphics(), new Point(210, 250), Color.Green);
this.PaintSegment(this.panel1.CreateGraphics(), new Point(220, 250), Color.Green);
this.PaintSegment(this.panel1.CreateGraphics(), new Point(230, 250), Color.Green);
this.PaintSegment(this.panel1.CreateGraphics(), new Point(240, 250), Color.Green);
this.PaintSegment(this.panel1.CreateGraphics(), new Point(250, 250), Color.Green);
}
#endregion
}
}
I know it's a lot of code, but since I'm not sure where's the root of the problem, I had to copy all of it.
I'd greatly appreciate it if you could point me in the right direction.
Thanks in advance :)
P.S. I know that the algorithm has flaws, I'll get to that later. Right now my main concern is solving the crash.
This is because you keep on going recursive in your method. e.g.:
Thread.Sleep(5);
Application.DoEvents();
this.SelfSolve();
Your method will basically never end.
You should use a timer and within that timer, call SelfSolve() This should solve your problem.
When using a timer you dont have to call DoEvents yourself since a winforms timer anyways posts a call to your method as a message and the message loop will handle the invocation and other messages.
SelfSolve should not call ManageSnake directly, but rather schedule its run for some later moment. Otherwise you get infinite recursion SelfSolve -> ManageSnake -> SelfSolve etc.