Tetris Timer is not working - c#

I am trying to write Tetris in c#. The speed of the first block is normal, but the second block falling two times quicker than the first one, then the third block is three times quicker. I think there must be something wrong with the timer.
Here is part of my code:
Timer timer = new Timer();
private void Form1_Load(object sender, EventArgs e)
{
/* ... Some code ... */
Watch().Start();
}
public Timer Watch()
{
timer.Stop();
timer.Interval = 1000;
timer.Enabled = true;
/* ... Some code ... */
// Check if the block can fall down
if (CheckDown() == true)
{
timer.Tick += (sender, e) => timer_Tick(sender, e, Current_sharp.sharp);
}
return timer;
}
void timer_Tick(object sender, EventArgs e, Sharp sharp)
{
if (CheckDown())
{
/* ... Some code ... */
}
else
{
Watch().Start();
}
}
Can anybody tell me why this happens?

The problem is your function Watch().
Event's can have multiple functions called every time they are fired, that is why it uses the += sign and not the = sign. Every time you call timer.Tick += (sender, e) => timer_Tick(sender, e, Current_sharp.sharp); you are adding an additional call to timer_Tick to the queue.
So the first time timer_Tick gets called one time, it then re-registers the handler then the 2nd time around timer_Tick gets called twice, and it adds 2 more firings to the queue (making it 4)... and so on.
Without seeing the entire code here is the best I can think of to fix the problem. All I did was move the timer.Tick registration from Watch() to Form1_Load()
Timer timer = new Timer();
private void Form1_Load(object sender, EventArgs e)
{
/* ... Some code ... */
//regester the event handler here, and only do it once.
timer.Tick += (sender, e) => timer_Tick(sender, e, Current_sharp.sharp);
Watch().Start();
}
public Timer Watch()
{
timer.Stop();
timer.Interval = 1000;
timer.Enabled = true;
/* ... Some code ... */
return timer;
}
void timer_Tick(object sender, EventArgs e, Sharp sharp)
{
if (CheckDown())
{
/* ... Some code ... */
}
else
{
Watch().Start();
}
}

Maybe you're executing this:
timer.Tick += ...
many times for each block?
It seems that that should be in the constructor. And where it's now: just have:
if(...)
timer.Enabled = true;
else
timer.Enabled = false;

Your problem (might be) here:
void timer_Tick(object sender, EventArgs e, Sharp sharp)
{
if (CheckDown())
{
Some code.....
}
else
{
Watch().Start();
}
//throw new NotImplementedException();
}
I don't know exactly the logic behind your CheckDown() but I assume it returns false* when the block touches down? In which case every time a block falls it creates a new timer, while you already have a timer running from Form1_Load()...hence why you see the progressive increase in speeds.

Related

System.Windows.Forms.Timer keeps on running

I need to show a message after 10 seconds of form load.
I am using the below code
private void Form1_Load(object sender, EventArgs e)
{
SetTimeInterval();
}
System.Windows.Forms.Timer MyTimer = new System.Windows.Forms.Timer();
public void SetTimeInterval()
{
MyTimer.Interval = ( 10 * 1000);
MyTimer.Tick += new EventHandler(TimerEventProcessor);
MyTimer.Start();
}
void TimerEventProcessor(Object myObject,EventArgs myEventArgs)
{
MessageBox.Show("TIME UP");
MyTimer.Stop();
MyTimer.Enabled = false;
}
Tried using MyTimer.Stop() and MyTimer.Enabled = false, but messagebox keeps displaying every 10 seconds. How do I stop it after the first instance?
Your problem is that MessageBox.Show() is a blocking call. So MyTimer.Stop() is only called after you close the MessageBox.
So until you closed the MessageBox there will pop up new ones every 10s. The simple solution is to change the order of calls:
void TimerEventProcessor(Object myObject,EventArgs myEventArgs)
{
MyTimer.Stop();
MyTimer.Enabled = false;
MessageBox.Show("TIME UP");
}
So the timer is stopped as soon as you enter the event handler, before displaying the message box.
i would suggest this method
go to theform.designer.cs
writhe this code
this.timer1.Enabled = true;
this.timer1.Interval = 10000;
and do this in ur .cs file
private void timer1_Tick(object sender, EventArgs e)
{
MessageBox.Show("msg");
}
that work perfectly for me.

How to add delay inside a for-loop using timers

By following code(the interval of timer2 is 1000)
private void timer1_Tick(object sender, EventArgs e) {
timer7.Enabled=false;
timer8.Enabled=false;
lblTimer_Value_InBuildings.Text="0";
}
private void timer2_Tick(object sender, EventArgs e) {
lblTimer_Value_InBuildings.Text=(int.Parse(lblTimer_Value_InBuildings.Text)+1).ToString();
}
we can not create a delay in a for-loop
for(int i=1; i<=Max_Step; i++) {
// my code...
// I want delay here:
timer1.Interval=60000;
timer1.Enabled=true;
timer2.Enabled=true;
// Thread.Sleep(60000); // makes no change even if uncommenting
}
Whether I uncomment the line Thread.Sleep(60000); or not, we see nothing changed with lblTimer_Value_InBuildings in timer2_Tick.
Would you please give me a solution(with or without timers)?
Your timer is your loop, you don't need a for loop. You just keep track of your loop variables outside of the function calls. I would recommend wrapping all of this functionality into a class, to keep it separate from your GUI code.
private int loopVar = 0;
public void Form_Load()
{
// Start 100ms after form load.
timer1.Interval = 100;
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
// My Code Here
loopVar++;
if (loopVar < Max_Step)
{
// Come back to the _tick after 60 seconds.
timer1.Interval = 60000;
timer1.Enabled = true;
}
}
When you do Thread.Sleep(60000), you are telling the UI thread to sleep for 60 seconds. What this also does is prevent the execution of the timer, because the UI thread is hung up sleeping instead of processing events such as the timer sleep.
The code totally made me feel boring
methods:
private void timer1_Tick(object sender, EventArgs e) {
timer2.Enabled=false;
timer1.Enabled=false;
lblTimer_Value_InBuildings.Text="0";
}
private void timer2_Tick(object sender, EventArgs e) {
lblTimer_Value_InBuildings.Text=(int.Parse(lblTimer_Value_InBuildings.Text)+1).ToString();
}
private void timer3_Tick(object sender, EventArgs e) {
if(0!=(int)timer3.Tag) {
// your code goes here and peformed per step
timer1.Enabled=true;
timer2.Enabled=true;
}
timer3.Tag=(1+(int)timer3.Tag)%Max_Step;
}
initials:
var delayedInterval=60000;
timer1.Interval=60000;
timer2.Interval=1000;
timer3.Interval=delayedInterval+timer1.Interval;
lblTimer_Value_InBuildings.Text="0";
timer3.Tag=1;
timer3.Enabled=true;
Your original code never makes timer1 and timer2 stopped, so I think you should correct timer7 and timer8 to timer1 and timer2, otherwise they don't make sense here.

Simple Timer in C#

I have this code
private void picTop_MouseEnter(object sender, EventArgs e)
{
if (timer1.Tick == 10)
{
picBottom.Visible = true;
picTop.Visible = false;
timer1.Stop();
}
else
{
MessageBox.Show("ERROR You cannot view this section at this time.\nPlease try again later.");
}
}
private void picBottom_MouseEnter(object sender, EventArgs e)
{
picBottom.Visible = false;
picTop.Visible = true;
timer1.Start();
}
My timerinterval is set at 1000ms (so 1 second)
I only want the user to go into the top panel again after 10 seconds.
Some help would be greatly appreciated.
Current error I get: timer1.Tick is red underlined, error=
"The event 'System.Windows.Forms.Timer.Tick' can only appear on the left hand side of += or -="
Timer.Tick is not property its an event.
Use it like
timer1.Tick +=
{
picBottom.Visible = true;
picTop.Visible = false;
timer1.Stop();
}
For interval use timer.Interval
timer.Interval = 10000;
Ok. I think I understand what you're trying to achieve...
You have 2 areas on your form called "Top" & "Bottom"
Once the user enters & subsequently leaves the top area, you don't want them to be able to enter again for 10 seconds. is that correct?
So you've got a few problems... first of all, Tick is an event to which you would attach a method to be fired when it is raised. it's not an integer you can check. The only integer property on a timer of relevance for timing for is called Interval
But aside from that I don't think your method is going to be particularly effective.
Perhaps a better idea would be to add a MouseExit event to the top area. and disable that area for 10 seconds. and use a timer to re-enable it.
timer1.Tick += timer1_Tick;
public void Top_MouseExit (object sender, EventArgs e)
{
PicTop.Visible = false; // or hide/disbale it some other way
Timer1.Interval = 10000; //10 seconds
Timer1.Start();
}
public void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop();
PicTop.Visible = true; //renable the top area
}

moving a button using a timer

I have four buttons that are called "ship1,ship2" etc.
I want them to move to the right side of the form (at the same speed and starting at the same time), and every time I click in one "ship", all the ships should stop.
I know that I need to use a timer (I have the code written that uses threading, but it gives me troubles when stopping the ships.) I don't know how to use timers.
I tried to read the timer info in MDSN but I didn't understand it.
So u can help me?
HERES the code using threading.
I don't want to use it. I need to use a TIMER! (I posted it here because it doesnt give me to post without any code
private bool flag = false;
Thread thr;
public Form1()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
flag = false;
thr = new Thread(Go);
thr.Start();
}
private delegate void moveBd(Button btn);
void moveButton(Button btn)
{
int x = btn.Location.X;
int y = btn.Location.Y;
btn.Location = new Point(x + 1, y);
}
private void Go()
{
while (((ship1.Location.X + ship1.Size.Width) < this.Size.Width)&&(flag==false))
{
Invoke(new moveBd(moveButton), ship1);
Thread.Sleep(10);
}
MessageBox.Show("U LOOSE");
}
private void button1_Click(object sender, EventArgs e)
{
flag = true;
}
Have you googled Windows.Forms.Timer?
You can start a timer via:
Timer timer = new Timer();
timer.Interval = 1000; //one second
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Enabled = true;
timer.Start();
You'll need an event handler to handle the Elapsed event which is where you'll put the code to handle moving the 'Button':
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
MoveButton();
}

how do I delay action on mouse enter rectangle c#

I would like to delay an action by several seconds after a mouse pointer has entered and remained for period of time in a winform graphics rectangle. What would be a way to do this?
Thanks
c#, .net 2.0, winform
private Timer timer;
private void rect_MouseEnter(object sender, EventArgs e)
{
timer = new Timer();
timer.Interval = 3000;
timer.Start();
timer.Tick += new EventHandler(t_Tick);
}
private void rect_MouseLeave(object sender, EventArgs e)
{
timer.Dispose();
}
void t_Tick(object sender, EventArgs e)
{
timer.Dispose();
MessageBox.Show(#"It has been over for 3 seconds");
}
Something such as:
static void MouseEnteredYourRectangleEvent(object sender, MouseEventArgs e)
{
Timer delayTimer = new Timer();
delayTimer.Interval = 2000; // 2000msec = 2 seconds
delayTimer.Tick += new ElapsedEventHandler(delayTimer_Elapsed);
}
static void delayTimer_Elapsed(object sender, EventArgs e)
{
if(MouseInRectangle())
DoSomething();
((Timer)sender).Dispose();
}
Probably could be done more efficiently, but should work :D
Two ways to set up MouseInRectangle -> one is to make it get the current mouse coordinates and the position of the control and see if it's in it, another way would be a variable which you would set to false on control.mouse_leave.
Try using the Timer control (System.Windows.Forms.Timer).
Please notice System.Windows.Forms.Timer is not Exact and you cannot rely it will act on exactly the interval given.
it would be prefeable to use System.Times.timer and use the Invoke action to return to the GUI thread.

Categories

Resources