Animation move left and right - c#

I am making a windows form animation where a animation of a character is walking left and then walk right once he reached the end of the windows form.
and i have to put a play/pause button for the animation to stop and continue where he left off
I have 16 frames each of the character walking right and left
I would like to ask how to put a boundary on the picturebox and how to get the picturebox to change to the walking right animation once it reach the left edge of the windows form and change the walking left animation once it reach the right edge of the windows form
public partial class Form1 : Form
{
//Declare a new integer for frame and set it to 1
int frame = 1;
public Form1()
{
InitializeComponent();
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
//Increase the frame per tick
frame++;
//Loop : If the frame exceeds 16, set the frame back to 1
if (frame > 16)
{
frame = 1;
}
//REtrieve the image fromfile base on the value of the ineger "frame"
pictureBox1.Image = Image.FromFile(Application.StartupPath +
"\\left" + frame + ".png");
int x = pictureBox1.Location.X;
int y = pictureBox1.Location.Y;
x -= 5;
//else if (e.KeyCode == Keys.Left) x -= 1;
pictureBox1.Location = new Point(x, y);
}

PictureBox has a border property. Check if it works for you.
You can check if PictureBox Left matches Forms Left that would mean it needs to move right and change the image on this condition.

You will need 2 different images 1 directed to left and 1 directed to right...
create an extra variable stating direction
then you can turn the image direction if the folowing criteria is met
if direction = right and picture.location >= (how far you want it to go probably border)
thendirection = leftchange to the left directed image change your movement variable to negative
if direction = left and picture.location <= 0
then direction = rightchange to the rightdirected image change your movement variable to positive

To detect when the control has reached the boundaries, you may check if the Location.X property + Width is equal to or greater than the PictureBox container (in this case, Form)'s width.
if(pictureBox1.Location.X + pictureBox1.Width >= pictureBox1.parent.Width)
{
direction = "left";//reached the end so go left
Of course you can easily test if we're at the starting position by checking if pictureBox1.Location.X == 0

Related

How can I move a frame?

Inside my page, I have a frame that loads another page. I am using this to detect if they want to move the frame around the screen:
private void Frame_MouseMove(object sender, MouseEventArgs e)
{
if (Mouse.LeftButton == MouseButtonState.Pressed)
{
}
}
How do I move the frame itself though? I have been trying to look for it and I cant seem to find the variables that control its position.
Try positioning using the frame's margin:
AppFrame.Margin = new Thickness(Mouse.X, Mouse.Y, 0, 0);
Alternatively, some frames are able to be moved with their Left and Top variables.
frame.Left = Mouse.X; // or whatever
frame.Top = Mouse.Y; // or whatever
In order to move it proportionally to the mouse, record the mouse and frame's original positions when the mouse was first dragged, and referenced them when positioned:
frame.Left = originalFrameX + (Mouse.X - originalMouseX);
frame.Top = originalFrameY + (Mouse.Y - originalMouseY);

update position of circle on pictureBox

I am using a pictureBox to move 2 linear stages; when the mouseDown event triggers, the pictureBox coordinates are remapped to match the maximum travel length of the axis, and then sent to them to perform the movement.
To improve this feature i have added a tiny dot on this image to track the current position of the mouse during the mouseDown event.
the dot must update its positition everytime the mouse moves; in order to do so i have used gfx.Clear(Color.White); to delete the previous and draw the new one.
Problem is that to understand the correct positioning of the axis the pictureBox should show a photo of the axis; but calling the gfx.Clear(Color) clears the image and leaves me with a white background.
is there a way to update the dot position without calling the gfx.Clear (in order to keep the image?)
if (e.Button.Equals(MouseButtons.Left))
{
{
this.gridImage.Refresh();
convertedX = (e.X * 100) / gridImage.Size.Width;
convertedY = (e.Y * 100) / gridImage.Size.Height;
using (Graphics gfx = Graphics.FromImage(this.gridImage.Image))
{
circle_bounds.X = e.X;
circle_bounds.Y = e.Y;
gfx.Clear(Color.White);
gfx.DrawEllipse(Pens.Red, this.circle_bounds);
}
Console.WriteLine("(X,Y): " + convertedX.ToString() + " " + convertedY.ToString());
Thread.Sleep(20);
//moveAbs(port1, "1", convertedX.ToString());
//moveAbs(port2, "1", convertedY.ToString());
initialXText.Text = convertedX.ToString();
initialYText.Text = convertedY.ToString();
}
}
What i would do is using the PictureBox.Paint event to draw the point that must follow the mouse move. First I declare a Pointto store the mouse position any time it moves:
Point mousePosition;
Then, in the PictureBox.MouseMove event handler, I would store this location and invalidate the PictureBox:
private void gridImage_MouseMove(object sender, MouseEventArgs e)
{
mousePosition = e.Location;
pictureBox1.Invalidate();
}
Finally, in the PictureBox.Paint i just draw a circle using the mouse position:
private void gridImage_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawEllipse(Pens.Red, new Rectangle(mousePosition, new Size(5,5)));
}
Hope this leads you in the right direction

What should I do when I want to make my picturebox collide in c#?

I'm creating a quite simple game that helps to understand simple logic with children while playing. It is in a very early stage now.
First look at the picture below
The Maroon colored square is the player object now, it is a 40x40 picture box
The background is a 600x600 panel with a set background image, where I drew the first map (i want to make more maps later, this is going to be the first "tutorial map")
I have 4 buttons now:
One will move the player forward - now it only moves the player square up
One will move the player backward - now it only moves the player square down
One will turn the player right - not yet functioning
One will turn the player left - not yet functioning
I already made that my player never leaves the panel no matter what but:
I want to know how can I make that my player wont move when there is a wall (green square) front of it. - Now it goes through the green wall, and i want it to only move on the white field.
Should I use some kind of objects and put them there as walls?
Thanks for help!
You have the panel, which is divided by 225 40x40 squares. So your panel has 15 squares width and 15 squares height. You can create a 15x15 matrix, where every cell can be 0 or 1 (0 is a coridor and 1 is a wall):
int[,] Matrix = new int[15, 15];
This matrix will represent your world collisions. After you have pressed a button, you should check your new player location, if it collides with matrix or out of bounds:
private void Window_KeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Right:
if ((int)PlayerLocation.X + 1 != Matrix.GetLength(1) && Matrix[(int)PlayerLocation.Y, (int)PlayerLocation.X + 1] == 0)
{
PlayerLocation = new Point(PlayerLocation.X + 1, PlayerLocation.Y);
MovePlayer();
}
break;
case Key.Left:
if ((int)PlayerLocation.X != 0 && Matrix[(int)PlayerLocation.Y, (int)PlayerLocation.X - 1] == 0)
{
PlayerLocation = new Point(PlayerLocation.X - 1, PlayerLocation.Y);
MovePlayer();
}
break;
case Key.Up:
if ((int)PlayerLocation.Y != 0 && Matrix[(int)PlayerLocation.Y - 1, (int)PlayerLocation.X] == 0)
{
PlayerLocation = new Point(PlayerLocation.X, PlayerLocation.Y - 1);
MovePlayer();
}
break;
case Key.Down:
if ((int)PlayerLocation.Y + 1 != Matrix.GetLength(0) && Matrix[(int)PlayerLocation.Y + 1, (int)PlayerLocation.X] == 0)
{
PlayerLocation = new Point(PlayerLocation.X, PlayerLocation.Y + 1);
MovePlayer();
}
break;
}
}

collision edges of the component and forms in c#

I want to make a simple arcanoid. misrepresented the problem that I can not catch the moment when the left edge of the button to the left crane hits the screen.
private void button1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.A)
{
if (ActiveForm.Left - button1.Left<10)
{
button1.Left -= 10;
}
}
if (e.KeyData == Keys.D)
{
button1.Left += 10;
}
}
I think the problem is in your if for the button1.left code.
I suppose that the ActiveForm is the form showing the game itself, and you want to move your bar to the left until it hits the left side of ActiveForm.
Take a look at this picture, basically the Form.Left is the distance between the left side of your screen and the form itself:
Instead of checking the bar position with the Form.Left, check it against "0 - bar.width", the left side of your form is always 0, so you can move the bar to the left as far as it's value is bigger than the width of the bar (bigger than 10 I presume).

when I connect for example 14 points with lines and try to move them its moving very very slow what's making it to move that slow?

This is the paint event:
private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
SolidBrush brush;
Pen p=null;
Point connectionPointStart;
Point connectionPointEnd;
Graphics g = e.Graphics;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
brush = new SolidBrush(Color.Red);
p = new Pen(brush);
for (int idx = 0; idx < wireObject1._point_X.Count; ++idx)
{
Point dPoint = new Point((int)wireObject1._point_X[idx], (int)wireObject1._point_Y[idx]);
dPoint.X = dPoint.X - 5; // was - 2
dPoint.Y = dPoint.Y - 5; // was - 2
Rectangle rect = new Rectangle(dPoint, new Size(10, 10));
g.FillEllipse(brush, rect);
}
for (int i = 0; i < wireObject1._connectionstart.Count; i++)
{
int startIndex = wireObject1._connectionstart[i];
int endIndex = wireObject1._connectionend[i];
connectionPointStart = new Point((int)wireObject1._point_X[startIndex], (int)wireObject1._point_Y[startIndex]);
connectionPointEnd = new Point((int)wireObject1._point_X[endIndex], (int)wireObject1._point_Y[endIndex]);
p.Width = 4;
g.DrawLine(p, connectionPointStart, connectionPointEnd);
moveCounter++;
textBox1.Text = moveCounter.ToString();
}
}
On the loop in the bottom I'm running over the _connectionstart List which is type of int.
I added a int variable I called it moveCounter to see how many time its calling this loop and drawing the lines.
If I'm adding two points over the pictureBox1 connect them with one line then drag one of the points around its moving smooth. Same thing with 3 connected points and with 7 connected points but when I'm getting to 9-10 points connected with many lines and try to move it drag it around or any point that is not connected everything is moving very very slow and as much as I add a new connected line between two points its getting slower.
So the problem can be a bug with my loop's in the paint event or that in the move event its doing so many time pictureBox1.refresh();
So I added a timer enabled it true in the designer and set it to 30 milliseconds. In the move event I raise a flag and in the timer tick event I check if the flag is on I make a pictureBox1.refresh(); and reset back the flag. The idea is that when I move the points or the connected points it will do it each 30 milliseconds.
But it didn't solve the problem. Still when I have 9-10 points connected with many lines between them everything is getting very slow.
This is the picturebox1 mouse move event:
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (mouseMove == true)
{
mouseDrag = true;
Point NewPoint = e.Location;
wireObject1.MovePoint(selectedIndex, NewPoint, NewPoint); // when moving a point dragging the other point is vanished deleted. To check why !
label1.Text = "{X = " + NewPoint.X + "}" + " " + "{Y = " + NewPoint.Y + "}";
refreshFlag = true;
timer2.Start();
}
else
{
label19.Text = "{X = " + e.X + "}" + " " + "{Y = " + e.Y + "}";
}
}
timer2 is another timer I added just to see how many times it moved in 5 seconds. So if timer1 set to 30 milliseconds I should see after 5 seconds something about 150 moves.
So in timer1 tick event I did:
private void timer1_Tick(object sender, EventArgs e)
{
if (refreshFlag == true)
{
pictureBox1.Refresh();
refreshFlag = false;
}
}
I was sure the timer1 idea should solve the problem but it didn't. So I wonder where the problem is maybe i did something wrong with the loop's in the paint event ?
The List _connectionstart contain indexes for example if I have two points connected with one line and I clicked on one point and drag this point around which make the line the be longer or shorter then in _connectionstart for example I have one place/cell [0] which contain index 0
In the List _point_X I have for example now two cells place in [0] 120.0 and in [1] 180.0 which are the points coordinates same for the _point_Y List.
Now the question is where is the problem ? A bug in the paint event ? Something with the move event ? I can't figure out why its getting so slow when it have 9-10 points connecting with a lot of lines between them.
For example I tested now with two points connected with a line I moved one point around which stretch the line longer or shorter and after 5 seconds the result was 160 moves counted then after another 5 seconds it was 323 and so on. So it seems to be working the timer1 and the 30 milliseconds or I'm wrong?
First, a few tweaks for the application:
Did You try to run the logic separated from drawing? => For example, an "updateData()" method and a "draw()" method? Also I would recommend to use the DoubleBuffer.
Second, if the performance is bad for a larger set of data (when You add more points), than Your algorithm is not efficient enough. If drawing a polygon is what You want, first update the vertex coordinates and then call Graphics.DrawPolygon

Categories