|
You last visited: Today at 05:37
Advertisement
Probleme beim Schleifen basteln
Discussion on Probleme beim Schleifen basteln within the AutoIt forum part of the Coders Den category.
06/08/2012, 00:27
|
#1
|
elite*gold: 0
Join Date: Jun 2012
Posts: 5
Received Thanks: 0
|
Probleme beim Schleifen basteln
Hallo zusammen,
als blutige AutoIT Anfängerin habe ich einige Infos aus dem "Netz" zusammen getragen und daraus wollte ich mir ein mini bot für mein Lieblingsspiel schreiben, nur leider klappt das nicht so wie ich es mir denke.
Der bot sollte wenn es klappt Tastatur und Maus simulieren in form von:
Beispiel:
alle 1 sec. die Taste 1 drücken
alle 6 sec. die Taste 2 drücken
alle 17 sec. Taste 3 drücken + MausKlick
sowie die Taste B drücken 30 sec. warten dann wieder B, dann 60 sec. warten und wieder B.
Das ganze soll endlos wiederholt werden bis nen HotKey gedrückt wird.
hier mein bisheriger code:
Code:
HotKeySet("{NUMPADDIV}","_start")
HotKeySet("{NUMPADMULT}","_pause")
HotKeySet("{NUMPADSUB}","_exit")
While 1
Sleep(2000)
WEnd
Func _start()
While 1
WinWaitActive("Fenster - Titel")
Send("{1}")
Sleep(1000)
WinWaitActive("Fenster - Titel")
Send("{2}")
Sleep(6000)
WinWaitActive("Fenster - Titel")
Send("{3}")
Sleep(500)
MouseClick( "left", 725, 450, 1)
Sleep(17000)
WinWaitActive("Fenster - Titel")
Send("{b}")
Sleep(30000)
WinWaitActive("Fenster - Titel")
Send("{b}")
Sleep(60000)
Send("{b}")
WEnd
EndFunc
Func _pause()
While 1
Sleep(10000)
WEnd
EndFunc
Func _exit()
Exit
EndFunc
Problem ist das jetzt die Taste 1 nicht alle 1 sec. gedrückt wird sondern alle 114,5 sec. wenn es wieder von vorn beginnt.
Selbst beim ersten druchlauf passt die schleife schon nicht wirklich.
Ein kürzeres Sleep würde zwar bedeuten das die Zeit sich verringert aber dann kommt der Rythmus der anderen Tasten auch durcheinander.
Ich habe ein Beispiel für eine problemlösung als vbs code entdeckt, aber ich wüsste nicht wie ich das auf AutoIT Übertragen sollte.
Hier der vbs code(lediglich als bsp):
Code:
Dim oShell, StartTime, Elapsed, i, b
Set oShell = WScript.CreateObject("WScript.Shell")
StartTime = Timer
i = Int(StartTime + 10)
b = True
Do
Elapsed = Timer - StartTime
If Elapsed Mod 1 = 0 Then oShell.SendKeys("1")
If Elapsed Mod 6 = 0 Then oShell.SendKeys("2")
If Int(Timer) = i Then
oShell.SendKeys("b")
If b = True Then
i = i + 30
b = False
Else
i = i + 60
b = True
End If
End If
WScript.Sleep 1000
Loop
Hier wird ein Timer runtergezählt und wenn null erreicht ist dann wird die Taste gedrückt.
Ich bitte um Hilfe,Vorschläge,Tipps.
LG Vaioria
|
|
|
06/08/2012, 00:58
|
#2
|
elite*gold: 95
Join Date: May 2011
Posts: 982
Received Thanks: 189
|
guck dir mal  und  an. starte einfach für jede taste einen timer
|
|
|
06/10/2012, 22:58
|
#3
|
elite*gold: 556
Join Date: Aug 2006
Posts: 502
Received Thanks: 404
|
butter hat recht, da musste mit timern arbeiten
Quote:
Local $timer1 = TimerInit()
Local $timer2 = TimerInit()
Local $timer3 = TimerInit()
while 1
if TimerDiff($$timer1) > 1000 Then ...
if TimerDiff($$timer2) > 6000 Then ...
if TimerDiff($$timer3) > 17000 Then ...
Wend
|
wichtig ist dann, dass du die timer immer zurücksetzen nicht vergisst, sonst haste ein problem, dass die immer wieder ausgeführt werden
|
|
|
06/11/2012, 22:55
|
#4
|
elite*gold: 95
Join Date: May 2011
Posts: 982
Received Thanks: 189
|
Quote:
Originally Posted by uragan
wichtig ist dann, dass du die timer immer zurücksetzen nicht vergisst, sonst haste ein problem, dass die immer wieder ausgeführt werden
|
oder mit modulo arbeiten geht auch. läuft aber aufs gleiche hinaus^^
|
|
|
06/15/2012, 20:47
|
#5
|
elite*gold: 0
Join Date: Jun 2012
Posts: 5
Received Thanks: 0
|
So endlich wieder Zeit gefunden was zu basteln.
Aus einem Anfall von geistigem "durchfall" ist folgendes entstanden:
Code:
HotKeySet("{NUMPAD1}","_start")
HotKeySet("{NUMPADMULT}","_pause")
HotKeySet("{NUMPADSUB}","_exit")
While 1
Sleep(2000)
WEnd ;damit das Script nicht gleich abbrechen soll ?!?!
Dim $StartTime, $Elapsed, $i, $b ;deklarierte Variablen hoffe richtig...
$StartTime = TimerInit()
$i = Int($StartTime + 10000) ;Startzeit + 10 Sekunden
$b = True
Func _start()
While 1 ;Endloschleifen begin
$Elapsed = TimerInit() - $StartTime
If $Elapsed 1000 = 0 Then ;erste fehlermeldung ==> Variable used without being declared!
ControlSend( "TitelVomSpiel", "", "", "{1}" ) ;alle 1 Sekunde Taste 1 drücken
If $Elapsed 2000 = 0 Then
ControlSend( "TitelVomSpiel", "", "", "{2}" ) ;alle 2 Sekunde Taste 2 drücken
If $Elapsed 3000 = 0 Then ;alle 3 Sekunde Taste 3 drücken
ControlSend( "TitelVomSpiel", "", "", "{3}" )
If Int(TimerInt()) = $i Then ;Soll nach 30 Sekunden
ControlSend( "TitelVomSpiel", "", "", "{b}" ) ;Taste B drücken nach weiteren
If $b = True Then ;30 Sekunden wieder B
$i = $i+30000 ;dann nach 90 Sekunden Taste
$b = False ;B drücken und nach weiteren
Else ;90 Sekunden Taste B
$i = $i+90000 ;und da Endlosschleife im Takt von
$b = True ;30 B 90 B 30 B 90 B etc.
EndIf
EndIf
EndIf
EndIf
EndIf
$StartTime = $Elapsed ;Timer zurücksetzen
WEnd
EndFunc
Func _pause() ;Pause
While 1
Sleep(10000)
WEnd
EndFunc
Func _exit() ;ohne Taskmanager die exe killen :)
Exit
EndFunc
funktioniert natürlich nicht 
hoffe man versteht wenigstens worauf ich hinaus möchte...
könnte das vielicht so klappen oder ist das ein gar ganz falscher ansatz?
hab mich bei den Variablen für Dim entschieden mein Vorredner nutzte Local und ein Beispiel hab ich ge"google"t da wars global...
Würde für mein vorhaben Dim genügen, da mein script so vollständig wäre wenn das tastendrücken mal so funktioniert wie ich möchte ?
LG
|
|
|
06/15/2012, 21:25
|
#6
|
elite*gold: 0
Join Date: Nov 2009
Posts: 221
Received Thanks: 71
|
so wird das nicht klappen vorallem die Zeile
Code:
[COLOR=#660066]If[/COLOR] $Elapsed [COLOR=#006666]1000[/COLOR] [COLOR=#666600]=[/COLOR] [COLOR=#006666]0[/COLOR] [COLOR=#660066]Then[/COLOR]
ist Falsch, um von einem Timer die Zeit zu bekommen Benötigst du die funktion TimerDiff($Timer). Außerdem kannst du nicht $Elapsed 1000=0 schreiben
ich habe dein Code so abgeändert das er funktioniert
Code:
[/HotKeySet("{NUMPAD1}", "_start")
HotKeySet("{NUMPADMULT}", "_pause")
HotKeySet("{NUMPADSUB}", "_exit")
Global $Elapsed = 0, $i = 30000, $1=0, $2=0, $3=0, $4=0
While 1
Sleep(200)
WEnd
Func _start()
$Elapsed = TimerInit();timer starten + zurücksetzen
While 1 ;Endloschleifen begin
If TimerDiff($Elapsed) - $1 >= 1000 Then
ToolTip($1)
$1=TimerDiff($Elapsed)
ControlSend("TitelVomSpiel", "", "", "{1}") ;alle 1 Sekunden Taste 1 drücken
EndIf
If TimerDiff($Elapsed) - $2 >= 2000 Then
$2=TimerDiff($Elapsed)
ControlSend("TitelVomSpiel", "", "", "{2}") ;alle 2 Sekunden Taste 2 drücken
EndIf
If TimerDiff($Elapsed) - $3 >= 3000 Then
$3=TimerDiff($Elapsed)
ControlSend("TitelVomSpiel", "", "", "{3}");alle 3 Sekunden Taste 3 drücken
EndIf
If TimerDiff($Elapsed) - $4 >= $i Then
$4=TimerDiff($Elapsed)
ControlSend("TitelVomSpiel", "", "", "{b}")
If $i = 30000 Then
$i = 90000
Else
$i = 30000
EndIf
EndIf
WEnd
EndFunc ;==>_start
Func _exit()
Exit
EndFunc ;==>_exit
Func _pause() ;Pause
While 1
Sleep(100)
WEnd
EndFunc ;==>_pause
|
|
|
06/15/2012, 22:47
|
#7
|
elite*gold: 0
Join Date: Jun 2012
Posts: 5
Received Thanks: 0
|
Oh vielen dank, (Thanks vergeben)
erspart mir Arbeit...*freu*
Habs noch bissel modifiziert aber das Prinzip ist sehr gut zu erkennen.
Gibt es noch eine möglichkeit ganze Sekunden zu machen? Weil wenn man das Theoretisch bissel laufen lässt und Autoit immer +1002,4 ms schreibt ist ja rein rechnerisch nach gewisser Zeit eine unregelmäßigkeit drin...oder macht das der timer reset wieder wett?
|
|
|
06/16/2012, 09:48
|
#8
|
elite*gold: 280
Join Date: May 2007
Posts: 2,818
Received Thanks: 3,483
|
Quote:
Originally Posted by Vaioria
Gibt es noch eine möglichkeit ganze Sekunden zu machen? Weil wenn man das Theoretisch bissel laufen lässt und Autoit immer +1002,4 ms schreibt ist ja rein rechnerisch nach gewisser Zeit eine unregelmäßigkeit drin...oder macht das der timer reset wieder wett?
|
durch den timerreset entsteht eine unregelmäßigkeit....
deine 2ms abweichung, würden nach erst nach ca 500durchläufen eine abweichung von einer sekunde ergeben. das sollte soweit hinnehmbar sein, kann aber umgangen werden, wenn du den timer nicht resettest, sondern mit dem startpunkt weiter arbeitest. hierfür bieten sich ein externer counter, oder die modulo funktion an.
beispiel mit externem counter:
Code:
Dim $timer=TimerInit(), $counter=1, $zeit=1000, $diff[2]
While True
$diff[0] = TimerDiff($timer)
$diff[1] = $counter*$zeit
If $diff[0] >= $diff[1] Then
$counter+=1
ConsoleWrite($counter-1&" Sekunden sind vergangen seit Timerstart (aktuelle Abweichung = "&$diff[0]-$diff[1]&")"&@CRLF)
EndIf
WEnd
|
|
|
06/16/2012, 14:01
|
#9
|
elite*gold: 0
Join Date: Jun 2012
Posts: 5
Received Thanks: 0
|
Habs mal eingebaut(hoffe richtig)
Code:
HotKeySet("{NUMPAD1}", "_start")
HotKeySet("{NUMPADMULT}", "_pause")
HotKeySet("{NUMPADSUB}", "_exit")
Global $i = 20000, $1=0, $2=0, $3=0, $4=0, $timer=TimerInit(), $counter=1, $zeit=1000, $diff[2]
While 1
Sleep(2000)
WEnd
Func _start()
While 1
$diff[0] = TimerDiff($timer)
$diff[1] = $counter*$zeit
If $diff[0] >= $diff[1] Then
$counter+=1
EndIf
If TimerDiff($timer) - $1 >= 1000 Then
$1=TimerDiff($timer)
ToolTip($1)
WinWaitActive("")
Send("{1}")
EndIf
If TimerDiff($timer) - $2 >= 6000 Then
$2=TimerDiff($timer)
WinWaitActive("")
Send("{2}")
EndIf
If TimerDiff($timer) - $3 >= 16000 Then
$3=TimerDiff($timer)
WinWaitActive("")
Send("{3}")
EndIf
If TimerDiff($timer) - $4 >= $i Then
$4=TimerDiff($timer)
WinWaitActive("")
Send("{b}")
If $i = 20000 Then
$i = 40000
Else
$i = 60000
EndIf
EndIf
WEnd
EndFunc
Func _pause()
While 1
Sleep(1000)
WEnd
EndFunc
Func _exit()
Exit
EndFunc
Hab den ToolTip nochmal rein genommen zur genaueren Kontrolle aber es entstehen immer noch abweichungen. Hab ich was falsch eingebaut?
Da ich mich mit Modulo noch nicht wirklich befasst habe und es hier öffter als "oder" angepriesen wird, ist diese varriante genauer?
LG
|
|
|
06/16/2012, 18:20
|
#10
|
elite*gold: 280
Join Date: May 2007
Posts: 2,818
Received Thanks: 3,483
|
sobald du sleeps oder wait funktionen in dein script aufnimmst, zerstörst du automatisch sämtliche getimten funktionen...
WinWaitActive, deine Pause funktion und auch deine hauptschleife, haben in der form nichts in einem script zu suchen. dinge wie pausen bzw waits sollten immer über zustände geregelt werden, da ansonsten der counter wärend dieser zeit nicht hochgezählt werden kann, und somit extreme ungenauigkeiten entstehen können.
von der modulo variante würde ich dir in diesem falle abraten, da sie sehr schwer implemntierbar, und somit für anfänger eher ungeeignet wäre.
|
|
|
06/16/2012, 20:15
|
#11
|
elite*gold: 0
Join Date: Jun 2012
Posts: 5
Received Thanks: 0
|
Könntest du mir eine Hilfestellung geben wie ich meine Hauptschleife besser gestalten könnte ohne extreme ungenauigkeiten?
WinWaitAktive + Send kann man ja durch ControlSend ersetzen sowie die Pause Funktion rausnehmen für das gleiche Ergebnis.
Wie sieht eigentlich ein ContolSend für die MouseClick Aktion aus wenn die getimed sein soll?
Wird die Schleife durch Modulo nun besser oder ergibt das keinen unterschied?
Da ich den gedanken hege mich mal damit zu befassen.
LG
|
|
|
06/16/2012, 21:50
|
#12
|
elite*gold: 2
Join Date: Jul 2009
Posts: 14,456
Received Thanks: 4,685
|
ControlClick gibts glaub ich auch
|
|
|
06/16/2012, 22:04
|
#13
|
elite*gold: 280
Join Date: May 2007
Posts: 2,818
Received Thanks: 3,483
|
Quote:
Originally Posted by Vaioria
Wird die Schleife durch Modulo nun besser oder ergibt das keinen unterschied?
Da ich den gedanken hege mich mal damit zu befassen.
|
noch besser als ohne steigende verzögerung geht es nicht...
mit zuständen meinte ich ausserdem nicht das zurückgreifen auf andere funktionen für die aktionen.
anstatt WinWaitActive zu nutzen, kannst du ja auch einfach abfragen, ob das fenster gerade aktive ist, bevor du mit send weiter machst. auf diese weise wird im e-fall der send befehl einfach übersprungen, der counter aber trotzdem weiter hochgezählt.
in diesem beispiel wäre active dein status. diesen kannst du per WinActive prüfen. hierbei handelt es sich um einen status, der dir vom system vorgegeben wird. das fenster kann active sein, oder nicht. im falle von active = true, führe deine aktion aus, also:
Code:
If WinActive(...) Then Send(...)
du kannst dir auch selbst zustände erstellen, zb einen pause zustand. zustände können wir einfach in variablen definieren. zb
nun setzen wir in unser script einfach eine abfrage, welche checkt, welchen zustand $pause gerade hat. ist $pause = True, so werden einige aktionen einfach übersprungen (in diesem falle die sends), während andere sachen trotzdem weiterhin ausgeführt werden (zb das hochzählen des counters).
deine pausefunktion braucht nun nurnoch den zustand von $pause in den jeweils andere ändern:
Code:
$pause = not $pause
schon kannst du das senden wieder per hotkey pausieren, ohne hierbei dein gesamtes script zu blockieren.
Edit:
hier mal ein beispiel für deine ersten 4 sachen, welche du gerne erledigen wolltest, mit einem kleinen gui, welches zeigt, wie im hintergrund die counter gezählt werden, selbst während der pausemodus aktiv ist:
Code:
HotKeySet("{F1}", "Pause")
AutoItSetOption("WinTitleMatchMode", 4)
Dim $fenster="Unbenannt - Editor", $pause=True, $timers[4]=[TimerInit(),TimerInit(),TimerInit(),TimerInit()]
Dim $counters[4]=[1,1,1,1], $actions[4]=[0,0,0,1], $sleeps[4]=[1000,6000,17000,17000], $text[2]=["Weiter", "Pause"]
Dim $label[UBound($counters)], $taskPos = WinGetPos("classname=Shell_TrayWnd")
GUICreate('Info', 100, UBound($counters)*40+50, @DesktopWidth-100, @DesktopHeight-UBound($counters)*40-50-$taskPos[3], 0x90000000, 0x88)
For $i=0 To 3
GUICtrlCreateGroup('Counter '&$i+1, 10, 10+$i*40, 80, 40)
$label[$i] = GUICtrlCreateLabel('', 15, 25+$i*40, 60, 20)
Next
$btn = GUICtrlCreateButton('Start', 10, 173, 80, 30)
While True
If GUIGetMsg()=$btn Then Pause()
For $i=0 To 3
TimedAction($timers[$i], $sleeps[$i], $i+1, $i, $actions[$i])
Next
SetGui()
WEnd
Func Pause()
GUICtrlSetData($btn, $text[$pause])
$pause = Not $pause
EndFunc
Func TimedAction($timer, $waitTime, $key, $counter, $aktion)
If TimerDiff($timer) >= $waitTime * $counters[$counter] then
If WinActive($fenster) And Not $pause Then
If $aktion = 0 Then
Send($key)
ElseIf $aktion = 1 Then
MouseClick( "left", 725, 450, 1)
EndIf
EndIf
$counters[$counter]+=1
EndIf
EndFunc
Func SetGui()
For $i=0 To UBound($counters)-1
If GUICtrlRead($label[$i]) <> $counters[$i] Then GUICtrlSetData($label[$i], $counters[$i])
Next
EndFunc
|
|
|
 |
Similar Threads
|
Probleme mit if schleifen
06/10/2012 - C/C++ - 20 Replies
hey,
muss bei meinem Buch grad folgende aufgabe lösen:
nun habe ich folgenden code:
int main()
{
int n1;
|
Probleme beim Conectem beim eigenen Server
10/31/2011 - Minecraft - 11 Replies
Hallo
Ich hab mir ein Server erstellt nur für mich und paar Freunde.
Jetzt ist das Problem das es ganze Zeit: Loggin in ...
Was tut da nicht??
Ich will mich mit der Version 1.7.3 einloggen und die Datei zum Server machen hab ich von der Minecraft HP.
Bekomt auch THX für Antworten!
|
Probleme mit den Schleifen x.x
07/23/2010 - AutoIt - 18 Replies
Ja, hallo. :D
Mein Problem ist das ich gerne einen Bot bauen würde der einnen Tastendruck ausführt wenn sich ein bestimmer Pixel auf dem Bildschirm verändert.
Nur ist das Problem das AutoIt zu lahm ist da der Pixel sich schnell beweget und somit auch seine Farbe ändert und der Bot dann es nichtmehr schafft zuzuschlagen. :P
Was ich nun versucht hab ist das man vll. sozusagen eine Tolleranz einbaut wie z.b. bei dem Pixelsearch Befehl nur ich hab ka. wie ich das anstellen soll.
Ich...
|
Brauche Dringend Hilfe Beim Pserver basteln
05/29/2005 - Private Server Advertising - 1 Replies
Hi Leute,
also ich würde gern Ragnarok im Netzwerk mit n paar kumpels zocken. ich hab den Koreanischen Client (mit Sakray und Translation Pack) im moment benutze ich den Vidar Beta 6 als Server Emu. habe mittlerweile einen normalen account und einen gm account erstellt. die Login, Character und Map Server laufen stabil und in der clientinfo.xml hab ich die ip und so weiter bereits eingetragen hab auch ne gehexte ragexe und das Data Verzeichnis, aber sobald ich starte passiert überhaupt...
|
All times are GMT +1. The time now is 05:38.
|
|