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();
}
}
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.
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.
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 tried searching all over the site but couldn't really find an answer to this question, I'm trying to make my Ellipse move by using the arrowkeys, but I keep getting the same error whatever I try.
Also, I get this error when I put this in my Canvas code in the XAML
KeyDown="movement"
Error:
No overload for 'movement' matches delegate 'System.Windows.Input.KeyEventHandler'
Code:
public MainWindow()
{
InitializeComponent();
x = 10;
y = 10;
diameter = 10;
DrawBall(x, y, diameter);
}
private void movement(object sender, System.Windows.Forms.KeyEventArgs key)
{
if (key.KeyCode == Keys.Up)
{
x -= 20;
}
else if (key.KeyCode == Keys.Down)
{
x += 20;
}
else if (key.KeyCode == Keys.Left)
{
y -= 20;
}
else if (key.KeyCode == Keys.Right)
{
y += 20;
}
DrawBall(x, y, diameter);
}
private void DrawBall(double x, double y, double diameter)
{
ballCanvas.Children.Clear();
Ellipse ellipse = new Ellipse();
ellipse.Stroke = new SolidColorBrush(Colors.Black);
ellipse.Fill = new SolidColorBrush(Colors.Red);
ellipse.Width = diameter;
ellipse.Height = diameter;
ellipse.Margin = new Thickness(x, y, 0, 0);
ballCanvas.Children.Add(ellipse);
}
}
}
You are using KeyEventArgs from Windows Forms. Instead use:
..., System.Windows.Input.KeyEventArgs key)...
will someone help me in this moving of my token, which is found in the diceroll() method,
if the user clicks the dice roll button, the token will round the board. the problem is the token is going outside the board
i already set a the first value of x as 15 and y as 12
(if you want to see the whole game file: http://www.mediafire.com/?1rz1689di15o8sq)
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 GAME
{
public partial class GameInterface : Form
{
int curx, cury, tempx, tempy;
private int x, y;
public int Seconds;
public int minutes = 5;
Int32 dice;
public GameInterface()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
token.Location = new Point(15, 12);
x = 15;
y = 12;
button1.Enabled = false;
}
private void Quit_Click(object sender, EventArgs e)
{
quitting quit = new quitting();
quit.ShowDialog();
}
private void Dice_Click(object sender, EventArgs e)
{
diceroll();
timer1.Enabled = true;
}
public void coorx(int x)
{
curx = x;
}
public void coory(int y)
{
cury = y;
}
public int getx()
{
return curx;
}
public int gety()
{
return cury;
}
public void diceroll()
{
System.Random diceroll = new Random();
dice = diceroll.Next(6) + 1;
DiceBox.Text = Convert.ToString(dice);
if (x >= 15 && y <= 102)
{
x = getx();
tempx = x + (105 * dice);
token.Location = new Point(tempx, y);
coorx(tempx);
}
if (x >= 608 && y <= 12)
{
y = gety();
int tempy = y + (95 * dice);
token.Location = new Point(x, tempy);
coory(tempy);
}
if (x >= 707 && y <= 552)
{
x = getx();
tempx = x - (105 * dice);
token.Location = new Point(tempx, y);
coorx(tempx);
}
if (x >= 113 && y <= 642)
{
y = gety();
int tempy = y - (95 * dice);
token.Location = new Point(x, tempy);
coory(tempy);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if ((minutes == 0) && (Seconds == 0))
{
timer1.Enabled = false;
MessageBox.Show("Game Over!");
label3.Text = "05";
label5.Text = "00";
}
else
{
if (Seconds < 1)
{
Seconds = 60;
timer1.Interval = 1000;
if (minutes != 0)
minutes -= 1;
}
else
{
Seconds -= 1;
label3.Text = minutes.ToString();
label5.Text = Seconds.ToString();
}
}
}
private void GameInterface_Load(object sender, EventArgs e)
{
}
}
}
It looks like it could fall into several of the if conditions at the same time.
say x=150, y=12 and dice=6
It would fall into this if statement:
if (x >= 15 && y <= 102) and this one: if (x >= 113 && y <= 642)
since the X and Y values don't get updated, only curx and cury, that might explain the weird token movement.