Ok, so my problem is as follows, I have a timer that draws a frame every 2 seconds (testing purposes) when I press D (by press I mean the D key is continuously held down), anyways when I first press D, the form will wait 2 seconds then draws the images as it should, but the problem is it does this only once. Hence after the 2 seconds,the remanding frames will be drawn at the fastest speed in which the form can draw it at. So, how do I make sure the frame will be drawn only every 2 seconds continuously, while keeping the interval of 2 seconds no matter how long I press the D key... here is my code
public partial class Form1 : Form
{
Keys moveRight;
Keys moveLeft;
public static bool isMovingR = false;
public static bool isMovingL = false;
public static bool canMoveR = false;
Bitmap stnd = new Bitmap(Properties.Resources.Standing);
static Bitmap wlk_1_RL = new Bitmap(Properties.Resources.Walk_1_RL);
static Bitmap wlk_3_RL = new Bitmap(Properties.Resources.Walk_3_RL);
static Bitmap wlk_4_LL = new Bitmap(Properties.Resources.Walk_4_LL);
static Bitmap wlk_6_LL = new Bitmap(Properties.Resources.Walk_6_LL);
Animation animate = new Animation(new Bitmap[] { wlk_1_RL, wlk_3_RL,
wlk_4_LL, wlk_6_LL });
Timer timer = new Timer();
int imageX = 5;
int imageY = 234;
public Form1()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e)
{
if (isMovingR == false)
{
e.Graphics.DrawImage(stnd, imageX, imageY);
//Refresh();
}
if (canMoveR == true)
{
e.Graphics.DrawImage(animate.Frame2Draw(), imageX, imageY);
timer.Stop();// this simply stops the animation from continuing once I have stopped press D
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
moveRight = Keys.D;
moveLeft = Keys.A;
if (e.KeyCode == moveRight)
{
isMovingR = true;
timer.Enabled = true;
timer.Interval = 2000;
timer.Tick += Timer1_Tick;
//imageX += 5;
Refresh();
} else if (e.KeyCode == moveLeft)
{
isMovingL = true;
imageX -= 5;
Refresh();
}
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.D)
{
isMovingR = false;
canMoveR = false;
Animation.slctdImg = 0;
this.Refresh();
}
}
private void Timer1_Tick(object sender, EventArgs e)
{
canMoveR = true;
this.Invalidate(); // calls the OnPaint event
timer.Stop(); // testing purposes and also to let you know timer.stop() doesn't really fix my problem in this case
}
}
}
UPDATED CODE, based on Kirak solution
public Form1()
{
InitializeComponent();
timer.Enabled = true;
timer.Interval = 1000;
timer.Tick += Timer1_Tick;
}
protected override void OnPaint(PaintEventArgs e)
{
if (canMoveR == true)
{
e.Graphics.DrawImage(animate.Frame2Draw(), imageX, imageY);
timer.Stop();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
moveRight = Keys.D;
moveLeft = Keys.A;
if (e.KeyCode == moveRight)
{
isMovingR = true;
//imageX += 5;
Refresh();
} else if (e.KeyCode == moveLeft)
{
isMovingL = true;
imageX -= 5;
Refresh();
}
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.D)
{
isMovingR = false;
canMoveR = false;
Animation.slctdImg = 0;
this.Refresh();
}
}
private void Timer1_Tick(object sender, EventArgs e)
{
if (isMovingR == true)
{
canMoveR = true;
this.Invalidate(); // calls the OnPaint event, hence all things that the OnPaint
//event draws, will be redrawn, you make ask your self why i would need
//the canMoveR to be set to true then, this is because i plan on adding more things
// so for future purpose, all things to be drawn in the game will
// will only be drawn when i want them to be drawn or under specific circumstances
}
}
}
}
Don't set the timer on button press - have a timer ticking every 2 seconds that checks if the button is pressed and takes action if it is. eg (pseudocode):
public Form1()
{
timer.Enabled = true;
timer.Interval = 2000;
}
KeyCode keyPressed;
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
keyPressed = e.KeyCode;
}
private void Timer1_Tick(object sender, EventArgs e)
{
if (keyPressed == Keys.D)
{
// do something
}
}
Update to address new code: If you want to unset the "canMoveR" you may want to set a timeout variable - something like this:
int timeout = 0;
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
keyPressed = e.KeyCode;
timeout = 2; // 2 seconds assuming your timer ticks every 1000ms
}
then on timer tick:
private void Timer1_Tick(object sender, EventArgs e)
{
--timeout; //will go down to 1 the first tick, then down to 0 on the second
if (timeout == 0)
{
canMoveR = false;
}
}
Every time press D, the event Timer1_Tick is added, so, on second time press D, the event run 2 times. Set event on constructor.
public Form1()
{
InitializeComponent();
timer.Enabled = false;
timer.Interval = 2000;
timer.Tick += Timer1_Tick;
}
protected override void OnPaint(PaintEventArgs e)
{
if (isMovingR == false)
{
e.Graphics.DrawImage(stnd, imageX, imageY);
//Refresh();
}
if (canMoveR == true)
{
e.Graphics.DrawImage(animate.Frame2Draw(), imageX, imageY);
timer.Stop();// this simply stops the animation from continuing once I have stopped press D
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
moveRight = Keys.D;
moveLeft = Keys.A;
if (e.KeyCode == moveRight)
{
isMovingR = true;
//imageX += 5;
timer.Enabled = true;
Refresh();
} else if (e.KeyCode == moveLeft)
{
isMovingL = true;
imageX -= 5;
Refresh();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.