i am creating a minigame where when the use clicks a button, it "attacks" the monster causing it to lose 5 hp, displayed using a progressbar. then at the same time the monster also attacks making the player lose hp. but the problem is these events happen at the exact same time, and i would like a 2 second interval between the events. ive been trying to get a timer event to work since this morning, but it just wouldnt work here is my code
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If Tick = 0 Then
Timer1.Stop()
Timer1.Enabled = False
Else
Tick -= 1
End If
End Sub
and here is the attack button event
Private Sub btnAttack_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAttack.Click
PlayerAttacks(mhealth, attack)
textShiftUp(numlines)
HPBarsAlter(mhealth, health)
Tick = 2
Timer1.Start()
MonsterAttacks(health, mattack, CritRate)
HPBarsAlter(mhealth, health)
MobDeath(mhealth, MobNumber)
Timer1.Stop()
End Sub
please tell me if you need any more information thank you :)
Basically, move your monster attack to the timer
Private Sub btnAttack_Click(...)
btnAttack.Enabled = False ' disable more attacks
PlayerAttacks(mhealth, attack)
textShiftUp(numlines)
HPBarsAlter(mhealth, health)
MonsterTimer.Interval = 2000
MonsterTimer.Start()
End Sub
Private Sub MonsterTimer_Tick(...
' not sure what the old code was doing
MonsterTimer.Stop ' stop the attacks
MonsterAttacks(health, mattack, CritRate)
HPBarsAlter(mhealth, health)
MobDeath(mhealth, MobNumber)
btnAttack.Enabled = True ' allow more attacks
End Sub
EDIT
Added 2 lines to toggle the ability to attack while waiting.
Related
I am trying to make an idle game something like cookie clicker, and I am having problems with making a simple line of code that repeats every second and adds 5 to a number every second. Could anyone help me? I want this to start the loop if someone clicks the button.
you could use a timer. Enable/start the timer when the button is clicked.
See example at MSDN: Windows Form Timer
add a timer and in the button code type :
TimerName.start
and add this in the timer code :
TimerName.interval = 1000
'replace TimerName with the name of timer you just added
'this will add 5 to number you want every second , interval of timer = 1000 that means it does the code every second
NumberThatYouWant += 5
'Replace NameThatYouWant with the number name that you want to add 5 to it every second
Yeah create a timer, then set the timer.interval to 1000 to tick each second, then create a sub for timer.tick and put the number you want to be increased in there and that should work.
EG.
Private Sub Timer1_Tick() Handles Timer1.Tick
variable += 5
End Sub
You have to change the interval in the properties window (bottom right)
Hope this helps!
Edit: I didn't include Timer1.start because the other answers said that. Don't forget to use it.
Setting the Timer
First, add a timer control to your form. Set the timer's interval value to '1000' (the timer's interval is measured in milliseconds). You should also enable your timer at run-time:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Timer1.Enabled = True
End Sub
So your code should look similar to this:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Timer1.Interval = 1000
End Sub
Adding the value with the Timer
Now say the button's name is 'button1', we will now finish the code to add 5 to the button's text property every 1 second, like so:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Timer1.Interval = 1000
Button1.Text += 5
End Sub
This code can also be written as "Button1.Text = Button1.Text + 5" I hope this helps clear up the ambiguity.
Public Class Form1
Dim Iclick, submit
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Iclick.InvokeMember("click")
With WebBrowser1.Document
For l_index As Integer = 0 To ListBox1.Items.Count - 1
Dim l_text As String = CStr(ListBox1.Items(l_index))
.All("input").InnerText = l_text
System.Threading.Thread.Sleep(5000)
Next
'.All("input").InnerText = "http://wordpress.com"
End With
submit.InvokeMember("click")
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
WebBrowser1.Navigate("http://whatwpthemeisthat.com")
End Sub
Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
Iclick = WebBrowser1.Document.GetElementById("input")
submit = WebBrowser1.Document.GetElementById("check")
End Sub
End Class
This is my code so far I have a ListBox with URLs I want to check using web browser which theme are they running (if they are wordpress) but the program seems to be bugged when I click START it is NOT responding, until the last element. It has to do something with the system.threading.thread.sleep line but I don't know what am I doing wrong? Thanks.
That's excactly what the Thread.Sleep() method is for. It freezes for 5 seconds.
Also you are replacing the input each time the For loop repeats. So it replaces, waits 5 seconds, replaces, waits 5 sec... and so on.
I guess you are trying to click the submit button for each of the elements, but that's not what you are doing. You have to hit the submit button each time the text has changed. However you really can't be sure about the loading time of the page.
I'd suggest you to place the submit-part inside the loop, then wait, then go into the next iteration. Maybe you could even try to run the website multiple times, one for each listbox item and then apply the right text to the controls in the webpage, hit the button and receive your result.
EDIT: Your best bet for the Thread.Sleep() would be creating a new thread in which you place the loop. This thread can be paused for 5 seconds, and your application will still respond. This is how you create one:
Imports System.Threading.Thread
Dim myThread as Thread
'//..........
'//Button1 is clicked ->
myThread = new Thread (AddressOf myLoop)
myThread.start()
'//..........
Private Sub myLoop ()
'// Loop goes here...
'Sleeping here will only affect the thread that runs this sub. Your form will still be available
End Sub
In my current project I have a self-made audioplayer which is operated trough my musictimer() function. Below is a sub which orders the audioplayer to go to the next song when someone has clicked on a picture. This works perfectly.
Private Sub PictureBox4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox4.Click
If (ListBox1.Items.Count - 1 > songBeingPlayed) Then
musictimer("next")
Else
musictimer("stop")
End If
End Sub
Below there is a sub which orders the player to play the next song when a song is finished playing. This sub also works but only when I have the MessageBox.Show("blabla") line in there. Otherwise it simply ignores the musictimer("next"). Obviously its quite annoying to have popup messages the entire times so I want it gone. Does anyone know whats going on? Im clueless.
Private Sub AxWindowsMediaPlayer1_PlayStateChange(ByVal sender As System.Object, ByVal e As AxWMPLib._WMPOCXEvents_PlayStateChangeEvent) Handles AxWindowsMediaPlayer1.PlayStateChange
If AxWindowsMediaPlayer1.playState = WMPLib.WMPPlayState.wmppsStopped Then
musictimer("next")
MessageBox.Show("blabla")
End If
End Sub
My very messy musictimer function.
Function musictimer(ByVal action)
If action Is "initial" Then
TextBox1.Text = "0:00"
Timer1.Stop()
secondsCounter = 1
doubledigitsecondCounter = 0
minuteCounter = 0
End If
If action Is "reset" Then
TextBox1.Text = "0:00"
Timer1.Stop()
secondsCounter = 1
doubledigitsecondCounter = 0
minuteCounter = 0
Me.AxWindowsMediaPlayer1.URL = ""
changePlayButton("play")
End If
If action Is "start" Then
If (ListBox1.Items.Count > 0) Then
Me.AxWindowsMediaPlayer1.URL = directoryPath + listboxpl(songBeingPlayed)
AxWindowsMediaPlayer1.Ctlcontrols.play()
Timer1.Start()
changePlayButton("pause")
End If
End If
If action Is "pause" Then
Timer1.Stop()
AxWindowsMediaPlayer1.Ctlcontrols.pause()
changePlayButton("play")
End If
If action Is "next" Then
If (ListBox1.Items.Count - 1 > songBeingPlayed) Then
songBeingPlayed += 1
musictimer("reset")
musictimer("start")
changePlayButton("pause")
Else
musictimer("pause")
End If
End If
If action Is "previous" Then
If (songBeingPlayed > 0) Then
songBeingPlayed -= 1
musictimer("reset")
musictimer("start")
End If
End If
End Function
The PlayStateChanged event is quite notorious. It was really meant to just update a UI element that shows the state. Doing anything with the player in that event is very troublesome. A call to MessagBox can have an affect because it pumps a message loop, always a big deal for ActiveX controls.
The best way to stay out of trouble is by delaying your code, making it run after the event was fired and the player is back into a quiescent state. Elegantly done by using the Control.BeginInvoke() method. Like this:
Private Sub AxWindowsMediaPlayer1_PlayStateChange(ByVal sender As System.Object, ByVal e As AxWMPLib._WMPOCXEvents_PlayStateChangeEvent) Handles AxWindowsMediaPlayer1.PlayStateChange
If e.newState = WMPLib.WMPPlayState.wmppsStopped Then
Me.BeginInvoke(New Action(AddressOf NextSong))
End If
End Sub
Private Sub NextSong()
musictimer("next")
End Sub
I've made it so I have a progress bar which is the players health starting at 100 and going down over time via a timer. When the player health progress bar gets to 0, I want a message to come up saying "You died! Game over."
Instead of doing that, it just does that when I click it as soon as the progress bar has reached 0, due to the 'Handles PlayerHealth.Click' bit. But what do I change the PlayerHealth.Click to to make it so the message box comes up when the progress bar just hits 0, without having to click it?
I can't find the right thing in the intellisense list. Or is there a better method?
Here's the piece of code in question :
Private Sub AttackButton_Click(sender As System.Object, e As System.EventArgs) Handles AttackButton.Click
PlayerHealthTimer.Start()
EnemyHealth.Increment(-2)
End Sub
Private Sub PlayerHealthTimer_Tick(sender As System.Object, e As System.EventArgs) Handles PlayerHealthTimer.Tick
PlayerHealth.Increment(-2)
End Sub
Private Sub PlayerHealth_Value(sender As System.Object, e As System.EventArgs) Handles PlayerHealth.Click
If PlayerHealth.Value = 0 Then
MsgBox("You died! Game over.")
End If
End Sub
Ignore the middle sub.
Thank you!
It fires on click because you have the MessageBox in the Sub that is handling the click method.
You may actually want to use the middle sub you said to ignore :). That one handles the logic on each tick.
Private Sub PlayerHealthTimer_Tick(sender As System.Object, e As System.EventArgs) Handles PlayerHealthTimer.Tick
PlayerHealth.Increment(-2)
if PlayerHealth.Value = 0 Then
MsgBox("You died! Game Over.")
''Then make sure to stop the timer
PlayerHealthTimer.Stop()
End If
End Sub
you can just use condition like
if PlayerHealth.value<=0 then
'place a message box or other way to show info message
end if
I would like to stop the timer whenever a mouse stops moving inside a groupbox
As of now, I start the timer when the mouse hover at the groupbox and stops it when it leaves the group box.
Private Sub gbxMouseMap_MouseHover(sender As Object, e As System.EventArgs) Handles gbxMouseMap.MouseHover
Timer.Start()
End Sub
Private Sub gbxMouseMap_MouseLeave(sender As Object, e As System.EventArgs) Handles gbxMouseMap.MouseLeave
Timer.Stop()
End Sub
In the MouseMove event set a class varible named LastMoveTime to the current timer elapsed time. In the MouseHover event check to see if LastMoveTime has reached the timeout period, if so stop the timer.
I will get you started...
Private LastMoveTime As DateTime
Private MouseTimeoutMilliseconds as Integer = 500
'put inside hover
If LastMoveTime.AddMilliseconds(MouseTimeoutMilliseconds) < Now Then
Timer.Stop()
Else
Timer.Start()
End if
To prevent having to handle this for many controls you can rearrange things a bit and cache the information needed to know if cursor has moved and how long the idle time is, to do this you need a Point variable and a Date variable. The Timer needs to tick all the time. In addition, to balance the cursor Show/Hide calls you need a variable to keep track of its visibility state. Here is the complete code sample:
Private loc As Point, idle As Date, hidden As Boolean,
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If loc <> Cursor.Position Then
If hidden Then
Cursor.Show()
hidden = False
End If
loc = Cursor.Position
idle = Date.Now
ElseIf Not hidden AndAlso (Date.Now - idle).TotalSeconds > 3 Then
Cursor.Hide()
hidden = True
End If
End Sub
This Timer can tick each 1/2-1 seconds depending on how responsive you want it, the idle time is set to 3 seconds. The code should be easy to understand when you read it and give it some thought, if not ask