I'm trying to make a single game, but I got a little problem here...
I'm moving a picturebox with the arrow keys, to avoid other pictureboxes... The problem is, that my picturebox moves out of the form when I press the left key too many times... I succeeded in solving this problem with the right side(by blocking the picturebox with an another), but the left side version still doesn't works, and I don't know why...
Here is the code:
if (pictureBox7.Bounds.IntersectsWith(pictureBox1.Bounds))
switch (e.KeyCode)
{
case Keys.Escape: Application.Exit(); break;
case Keys.P: timerkunai1.Enabled = false;
timerkunai2.Enabled = false; timerkunai3.Enabled = false;
timerkunai4.Enabled = false; timerninja.Enabled = false;
timerlife.Enabled = false;
button3.Show(); break;
case Keys.Right: i = 6; dx = 25; press = true; break;
}
if (pictureBox8.Bounds.IntersectsWith(pictureBox1.Bounds))
switch (e.KeyCode)
{
case Keys.Escape: Application.Exit(); break;
case Keys.P: timerkunai1.Enabled = false;
timerkunai2.Enabled = false; timerkunai3.Enabled = false;
timerkunai4.Enabled = false; timerninja.Enabled = false;
timerlife.Enabled = false;
button3.Show(); break;
case Keys.Left: i = 0; dx = -25; press = true; break;
}
else
switch (e.KeyCode)
{
case Keys.Escape: Application.Exit(); break;
case Keys.P: timerkunai1.Enabled = false;
timerkunai2.Enabled = false; timerkunai3.Enabled = false;
timerkunai4.Enabled = false; timerninja.Enabled = false;
timerlife.Enabled = false;
button3.Show(); break;
case Keys.Left: i = 0; dx = -25; press = true; break;
case Keys.Right: i = 6; dx = 25; press = true; break;
}
You need code to check if the picturebox's bounds are outside of the form. If the picturebox movement will cause it to be outside the bounds then prevent the motion.
Something like this pseudocode:
if (pictureBoxZ + dx < 0 || pictureBoxZ + dx > pictureBoxZ.Parent.Width) { //Deny Motion }
Is your dx variable an offset to the new Location of the PictureBox?
Then limit the Location.x to 0:
if (pictureBox1.Location.x + dx > 0)
pictureBox1.Location += dx;
If you want to limit to left and right size, to the width of the Form use this code:
if ((pictureBox1.Location.x + dx > 0) && (pictureBox1.Location.x + dx < this.Size.Width - pictureBox1.Size.Width))
pictureBox1.Location += dx;
Related
What I'm trying to do is this:
I want the 4 pictureBoxes I got in the form to get the faces of card - turn them over I mean. a random card from the 4 will be chosen, turned over and show the face of the card being chosen also randomley.
Once a card is turned over, it cant be turend over again in the next timer interval, and once all cards had been turned over, a messageBox appears and once the user presses ok, it all restarts.
Problem is: the messageBox keeps appearing over and over again, because of the flag positive value. I don't know which variable should I use to prevent that from happening.
Relevant code:
//This function is the timer's function, it starts every time interval:
private void cardsChangingTimer_Tick(object sender, EventArgs e)
{
int chosenImage = rnd.Next(1, 17);
int chosenCard = rnd.Next(0, 4);
if (bucketArr[chosenCard] == 0)
{
bucketArr[chosenCard]++;
switch (chosenCard)
{
case 0:
card1Pic.Image = Image.FromFile("cards\\" + chosenImage + ".png");
break;
case 1:
card2Pic.Image = Image.FromFile("cards\\" + chosenImage + ".png");
break;
case 2:
card3Pic.Image = Image.FromFile("cards\\" + chosenImage + ".png");
break;
case 3:
card4Pic.Image = Image.FromFile("cards\\" + chosenImage + ".png");
break;
}
}
gameEnded = true;
for (int i = 0; i < bucketArr.Length; i++)
{
if (bucketArr[i] == 0)
{
gameEnded = false;
break;
}
}
if (gameEnded)
{
DialogResult dialog = MessageBox.Show("All 4 cards were turned over...");
if (dialog == DialogResult.OK)
{
card1Pic.Image = Image.FromFile("..\\..\\17.png");
card2Pic.Image = Image.FromFile("..\\..\\17.png");
card3Pic.Image = Image.FromFile("..\\..\\17.png");
card4Pic.Image = Image.FromFile("..\\..\\17.png");
}
gameEnded = false;
for(int i = 0; i < bucketArr.Length; i++)
bucketArr[i] = 0;
}
}
Thanks alot for any help...
The problem you are having is the timer is continuing to run while the dialog box is shown. Simply stop the timer before the MessageBox is shown then restart the timer after the box returns.
private void cardsChangingTimer_Tick(object sender, EventArgs e)
{
int chosenImage = rnd.Next(1, 17);
int chosenCard = rnd.Next(0, 4);
/// ... Rest of the code goes here
break;
}
}
if (gameEnded)
{
//Get a reference to the timer and stop it.
var timer = (Timer)sender;
timer.Stop();
DialogResult dialog = MessageBox.Show("All 4 cards were turned over...");
if (dialog == DialogResult.OK)
{
card1Pic.Image = Image.FromFile("..\\..\\17.png");
card2Pic.Image = Image.FromFile("..\\..\\17.png");
card3Pic.Image = Image.FromFile("..\\..\\17.png");
card4Pic.Image = Image.FromFile("..\\..\\17.png");
}
gameEnded = false;
for(int i = 0; i < bucketArr.Length; i++)
bucketArr[i] = 0;
//start the timer here after everything has been re-initialized.
timer.Start();
}
}
I am new to c# and I'm wanting to create a game that it has three button with different colors , I want to turn on and off each of them in random state for 1000 milisecond .. what should I do ? can anyone help me ? :)
there are three buttons including Red , Blue and Green colors , after click the "start" button they begin to blink randomly ... I want set 1000 millisecond for this blink !
switch (colorNum)
{
case 1:
btnRed.BackColor = Color.Red;
Thread.Sleep(milisecond);
//if (btn == btnRed)
//{
count++;
break;
//}
case 2:
btnBlue.BackColor = Color.Blue;
//{
count++;
break;
//}
case 3:
btnYellow.BackColor = Color.Yellow;
//{
count++;
break;
//}
}
private void Blink_Button()
{
Random rnd = new Random();
int colorNum = rnd.Next(1, 4);
switch (colorNum)
{
case 1:
btnRed.BackColor = Color.Red;
btnBlue.BackColor = Color.LightGray;
btnYellow.BackColor = Color.LightGray;
break;
case 2:
btnBlue.BackColor = Color.Blue;
btnRed.BackColor = Color.LightGray;
btnYellow.BackColor = Color.LightGray;
break;
case 3:
btnYellow.BackColor = Color.Yellow;
btnRed.BackColor = Color.LightGray;
btnBlue.BackColor = Color.LightGray;
break;
}
}
Call this method in the Timer tick event
So I have a Unity program, where it switches screens if the user presses ENTER.
However, whenever the user presses enter, instead of just going one screen forward, it skips all the way to the last screen.
Here is my OnGUI():
if (showScreen == true)
{
//this allows the screens to toggle
switch (pageNum)
{
case 1:
rectangle = GUI.Window(1,rectangle, Page1, "Computer");
break;
case 2:
rectangle = GUI.Window(1,rectangle, Page2, "Computer");
break;
case 3:
rectangle = GUI.Window(1,rectangle, Page3, "Computer");
break;
case 4:
rectangle = GUI.Window(1,rectangle, Page4, "Computer");
break;
case 5:
rectangle = GUI.Window(1,rectangle, Page5, "Computer");
GUILayout.Window (2,rect2, popUp, "Warning!");
break;
case 6:
rectangle = GUI.Window(1,rectangle, Page6, "Computer");
break;
case 7:
rectangle = GUILayout.Window(1,rectangle, Page7, "Computer");
break;
default:
break;
}
}
And here is where the GUIs are actually set up, and made to change:
void Page1(int windowID)
{ if (Input.GetKeyDown(KeyCode.Return))
{
GUI.FocusControl(null);
pageNum = 2;
}
}
void Page2(int windowID)
{
if (Input.GetKeyDown(KeyCode.Return))
{
pageNum = 3;
GUI.FocusControl(null);
}
}
//continue like this for 5 more Page#(int windowID)
So what can I insert into these classes to make my program stop skipping? should I put a pause into these if statements too?
So it looks like the easiest way to solve this problem is by changing how the program changes the stages. All you need to do is a boolean that changes to true once the return key has been pressed.
so just declare the boolean:
public class ClassName : MonoBehaviour
{
bool wasClicked = false;
Then to change the states just do this:
if (Input.GetKey(KeyCode.Return))
{
wasClicked = true;
}
if (wasClicked)
{
if (!Input.GetKey(KeyCode.Return))
{
GUI.FocusControl(null);
pageNum = next page number;
wasClicked = false;
}
}
I'm kinda new to both Keys event and timers in my code but for some reason there is this weird bug. (read the last edit)
public partial class Form1 : Form
{
bool start = false;
Snake ormen = new Snake(10);
short direction = 3;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
button1.Hide();
timer1.Enabled = true;
start = true;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
if (start)
{
ormen.rita(g);
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Up:
direction = 3;
break;
case Keys.Down:
direction = 1;
break;
case Keys.Left:
direction = 2;
break;
case Keys.Right:
direction = 0;
break;
default:
break;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
ormen.flytta(direction);
Invalidate();
}
}
}
I also tried to use debug at the key event but it does not even activate until after the time period. Can anyone please tell me why? Also if there are any obvious mistakes i would appreciate it if you could mention them. I have also tried to make the timer interval higher to check if the program can't keep up but it can. (read the last edit)
[EDIT] I don't think it will help but here is the code for the class "Snake". I doubt it's a problem in there but anyways.
private short diameter = 0;
//0 = Right, 1 = Down, 2 = Left, 3 = Up
public Snake(short diameter)
{
this.diameter = diameter;
ormensPlatser.Enqueue(new Point(0, 0));
ormensPlatser.Enqueue(new Point(0 + diameter, 0));
ormensPlatser.Enqueue(new Point(0 + diameter + diameter, 0));
}
Queue<Point> ormensPlatser = new Queue<Point>();
public void rita(Graphics g)
{
Point temp;
for (int i = 0; i < ormensPlatser.Count; i++)
{
temp = ormensPlatser.Dequeue();
g.FillEllipse(new SolidBrush(Color.Red), temp.X, temp.Y, diameter, diameter);
ormensPlatser.Enqueue(temp);
}
}
private void ormNäraKant(short direction,ref Point ormBit)
{
switch (direction)
{
case 0:
ormBit.X = ormBit.X + diameter >= 380 ? 0 : ormBit.X + diameter;
break;
case 1:
ormBit.Y = ormBit.Y + diameter >= 360 ? 0 : ormBit.Y + diameter;
break;
case 2:
ormBit.X = ormBit.X - diameter < 0 ? 370 : ormBit.X - diameter;
break;
case 3:
ormBit.Y = ormBit.Y - diameter < 0 ? 350 : ormBit.Y - diameter;
break;
}
}
public void flytta(short direction)
{
Point temp;
int temp1 = ormensPlatser.Count - 1;
for (int i = 0; i < ormensPlatser.Count; i++)
{
if (i == temp1)
{
switch(direction)
{
case 0:
temp = ormensPlatser.Dequeue();
ormNäraKant(0, ref temp);
ormensPlatser.Enqueue(temp);
break;
case 1:
temp = ormensPlatser.Dequeue();
ormNäraKant(1, ref temp);
ormensPlatser.Enqueue(temp);
break;
case 2:
temp = ormensPlatser.Dequeue();
ormNäraKant(2, ref temp);
ormensPlatser.Enqueue(temp);
break;
case 3:
temp = ormensPlatser.Dequeue();
ormNäraKant(3, ref temp);
ormensPlatser.Enqueue(temp);
break;
}
}
else
{
ormensPlatser.Dequeue();
temp = ormensPlatser.Peek();
ormensPlatser.Enqueue(temp);
}
}
}
}
}
[EDIT2] Okey, apparently it wasn't about the time or anything like that, the code worked but i think it has something to do with what slawekwin said in the comments about the focus when the program starts. So the problem is still the same but if I ALT+tab to a another program then back to the snake program it works.
SO i finally figure it out, i thought that the problem was with the timer event and the key input event when they worked together but my assumption was wrong. So what i did is that i went through all the properties that the form has and i found a setting called "KeyPrevied" and it was false so i tried to set it to true and it worked :).
I wanna write an application to do below job:
We have 15 different location (that we present them with point (x1,y1) for first location, point (x1,y2) for second location and so on point (x1,y15) for last location).
100 image must to be shown at this locations (with specific order) with pictureBox.
Each image that shown, must start to move horizontally to reach new point (e.g. point (Xc, Yc) ) and then move vertically and so on…
When the image reach to specific point (e.g. point (Xm,Ym) ), we decide that it must continue moving or it must destroy (with probability 20%) (which means that we can create next image at that initial location).
For example, an image create at location (Xi,Yi) with pictureBox1. Then it’s not allowed to create any more image at location (Xi,Yi) until pictureBox1 destroy or return to its initial location.
What I have written so far is:
create 15 location.
move one image to reach point (Xc,Yc).
I’ve some problems:
I use one timer to move an image. But I want to move 100 images. (from each 15 location, we create images and move them until we destroy them and then create next image).
So what I must to do? Use 15 timer for each location?!but How?
at specific point (e.g. point (Xk,Yk) ), the image must stop moving for random seconds and then continue moving. How I should do this? With another timer?!But how?
when image reach point (Xc,Yc) and with we decide to destroy it or not, nothing happen in my code…I don’t know why!
I’ve add an picture of what I want HERE
Here is my code so far:
public partial class Form1 : Form
{
Random r = new Random();
// falg to prevent create just one image at each location
private Boolean[] createNext = {true,true,true,true,true,true,true,
true,true,true,true,true,true,true,true};
private void setImage()
{
int i = 1 + r.Next() % 15;
while (createNext[i] != true)
i = 1 + r.Next() % 15;
switch (i)
{
case 1: pictureBox1.ImageLocation = "grin.png";
break;
case 2: pictureBox2.ImageLocation = "grin.png";
break;
case 3: pictureBox3.ImageLocation = "grin.png";
break;
case 4: pictureBox4.ImageLocation = "grin.png";
break;
case 5: pictureBox5.ImageLocation = "grin.png";
break;
case 6: pictureBox6.ImageLocation = "grin.png";
break;
case 7: pictureBox7.ImageLocation = "grin.png";
break;
case 8: pictureBox8.ImageLocation = "grin.png";
break;
case 9: pictureBox9.ImageLocation = "grin.png";
break;
case 10: pictureBox10.ImageLocation = "grin.png";
break;
case 11: pictureBox11.ImageLocation = "grin.png";
break;
case 12: pictureBox12.ImageLocation = "grin.png";
break;
case 13: pictureBox13.ImageLocation = "grin.png";
break;
case 14: pictureBox14.ImageLocation = "grin.png";
break;
case 15: pictureBox15.ImageLocation = "grin.png";
break;
}
}
private int k = 0;
private Boolean destroy = true;
// timer that move pictureBox1
void timer_Tick(object sender, EventArgs e)
{
k++;
int x = pictureBox1.Location.X;
int y = pictureBox1.Location.Y;
if (k <= 150)//go right 300 in 150 ticks
pictureBox1.Location = new Point(x + 2, y);
else if (k <= 300)
{
if (y < 200)
pictureBox1.Location = new Point(x, y + 1);
if (y > 200)
pictureBox1.Location = new Point(x, y - 1);
}
else if (k <= 400)
pictureBox1.Location = new Point(x + 2, y);
else if (k <= 550)
{
if (destroy == false)
pictureBox1.Location = new Point(x + 2, y);
if (destroy == true)
pictureBox1.Location = new Point(x, y - 3);
}
else if (k <= 650)
pictureBox1.Location = new Point(x, y - 1);
else if (k <= 850)
pictureBox1.Location = new Point(x - 2, y);
else if (k <= 950)
pictureBox1.Location = new Point(x, y + 1);
else
timer1.Stop();
}
public Form1()
{
InitializeComponent();
for (int i = 0; i < 15; i++)
{
setImage();
timer1.Start();
timer1.Interval = 15;
timer1.Tick += new EventHandler(timer_Tick);
}
}
Please help me to complete this application.
Thanks in advance.
You should probably just use one timer, and make a number of instances of a class that represents your moving picturebox. (This class would contain the points it will go to, ordered to the first point is always your next destination. Also it will contain the picturebox.. etc).
enum Action
{
None,
Stop,
CheckDestroy
}
class InterestingPoint
{
Point m_Point;
Action m_Action;
}
class MovingImage
{
public bool DestroyMe {get; private set; }
PictureBox m_PictureBox;
List<InterestingPoint> m_PointsToVisit;
int m_StoppedUntil = 0;
MovingImage(...)
{
// Constructor
}
void Update(int k)
{
if(m_StoppedUntil > k) return;
//Move m_PictureBox towards m_PointsToVisit.First
//when m_PictureBox.Location == m_PointToVisit.First, check if the InterestingPoint
//has a action you need to handle,
//like if the action is stop, you set m_StoppedUntil to k+ the number of frames you
//want the picturebox to stay still. (m_StoppedUntil = k+10 => doesnt update for 10 frames)
//if the action is checkdestroy, see if it shall be destroyed and set DestroyMe to true
}
So, you initialize your MovingImage objects with a picturebox and list of point it should move to, these points contain a action for the object to execute when it arrives there.
Keep your MovingImages in a list of some kind and iterate over them to update them.
In your Timer_Tick you do something like
void timer_Tick(object sender, EventArgs e)
{
k++
foreach(MovingImage m in m_MyMovingImages)
{
m.Update(k);
if(m.DestroyMe)
{
//Destroy it.
}
}
}