Schau dir doch mal diesen Thread an. Speziell den ersten Spoiler in Xeno's Beitrag.
Beiträge von name22
-
-
Du musst bei DrawStringEx das Handle zu einem Font Objekt übergeben, nicht den Namen der Schriftart.
Mach mal bitte bei jedem Aufruf von DrawStringEx aus $sFont ein $hFont... -
... Du brauchst auch 2 verschiedene DLL Structs für verschiedene Strings...
Und bennene mal deine Variablen sinnvoller. $iX und $XX.. Ernsthaft?
Ich habs jetzt mal zum funktionieren gebracht (und aufgeräumt), aber ich würde das an deiner Stelle mit Arrays machen. Ließ dir die Kommentare mal genauer durch, ich hab eigentlich alles nötige beschrieben.Spoiler anzeigen
[autoit]#include <GDIPlus.au3>
[/autoit] [autoit][/autoit] [autoit]
#include <GUIConstants.au3>
#include <WindowsConstants.au3>;- Author: name22 (http://www.autoit.de)
[/autoit] [autoit][/autoit] [autoit]$iX_AutoIt = 50
[/autoit] [autoit][/autoit] [autoit]
$iY_AutoIt = 30
$iX_Niccoo = 150
$iY_Niccoo = 30
$sString_AutoIt = "AutoIt"
$sString_Niccoo = "Niccoo"$sFont = "Arial"
[/autoit] [autoit][/autoit] [autoit]
$iFontSize = 20$hWnd = GUICreate("Beispiel", 300, 100)
[/autoit] [autoit][/autoit] [autoit]
GUISetState()_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_GraphicsSetSmoothingMode($hGraphics, 2)$hBrush_AutoIt = _GDIPlus_BrushCreateSolid(0xFFF4567F)
[/autoit] [autoit][/autoit] [autoit]
$hBrush_Niccoo = _GDIPlus_BrushCreateSolid(0xFF0000FF)$hStringFormat = _GDIPlus_StringFormatCreate()
[/autoit] [autoit][/autoit] [autoit]
$hFamily = _GDIPlus_FontFamilyCreate($sFont)
$hFont = _GDIPlus_FontCreate($hFamily, $iFontSize)
$tLayout_AutoIt = _GDIPlus_RectFCreate($iX_AutoIt, $iY_AutoIt) ;X und Y Koordinaten angeben, Breite und Höhe ist irrelevant und kann 0 bleiben
$tLayout_Niccoo = _GDIPlus_RectFCreate($iX_Niccoo, $iY_Niccoo) ;X und Y Koordinaten angeben, Breite und Höhe ist irrelevant und kann 0 bleiben$aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $sString_AutoIt, $hFont, $tLayout_AutoIt, $hStringFormat) ;Misst die Breite/Höhe des angegebenen Strings mit der Schrift in $hFont
[/autoit] [autoit][/autoit] [autoit]
;Die gewollten Daten stecken in einem DLLStruct in $aInfo[0] die anderen Array Elemente enthalten weitere Daten die hier nicht benötigt werden.
;Wie das Struct aufgebaut ist, steht in der Hilfe zu $tagGDIPRECTF
$iWidth_AutoIt = DllStructGetData($aInfo[0], "Width") ;Breite
$iHeight_AutoIt = DllStructGetData($aInfo[0], "Height") ;Höhe$aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $sString_Niccoo, $hFont, $tLayout_Niccoo, $hStringFormat)
[/autoit] [autoit][/autoit] [autoit]
$iWidth_Niccoo = DllStructGetData($aInfo[0], "Width") ;Breite
$iHeight_Niccoo = DllStructGetData($aInfo[0], "Height") ;Höhe;Hier wird das 1te DLLStruct für PtInRect erstellt
[/autoit] [autoit][/autoit] [autoit]
$tRect_AutoIt = DllStructCreate($tagRECT)
DllStructSetData($tRect_AutoIt, "Left", $iX_AutoIt) ;Linke Kante des Rechtecks
DllStructSetData($tRect_AutoIt, "Top", $iY_AutoIt) ;Obere Kante des Rechtecks
DllStructSetData($tRect_AutoIt, "Right", $iX_AutoIt + $iWidth_AutoIt) ;Rechte Kante des Rechtecks
DllStructSetData($tRect_AutoIt, "Bottom", $iY_AutoIt + $iHeight_AutoIt) ;Untere Kante des Rechtecks
;Und hier das 2te...
$tRect_Niccoo = DllStructCreate($tagRECT)
DllStructSetData($tRect_Niccoo, "Left", $iX_Niccoo) ;Linke Kante des Rechtecks
DllStructSetData($tRect_Niccoo, "Top", $iY_Niccoo) ;Obere Kante des Rechtecks
DllStructSetData($tRect_Niccoo, "Right", $iX_Niccoo + $iWidth_Niccoo) ;Rechte Kante des Rechtecks
DllStructSetData($tRect_Niccoo, "Bottom", $iY_Niccoo + $iHeight_Niccoo) ;Untere Kante des Rechtecks
;Und ja, du bauchst 2 !!!!11_Paint()
[/autoit] [autoit][/autoit] [autoit]
GUIRegisterMsg($WM_PAINT, "_Paint") ;Neuzeichnen, falls Fenster verdeckt wurde.While True
[/autoit] [autoit][/autoit] [autoit]
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ExitLoop
Case $GUI_EVENT_PRIMARYDOWN ;Sobald die linke Maustaste innerhalb der Clientarea des Fensters geklickt wird, wird diese Nachricht gesendet. Diese Case wird ausgeführt wenn ein Linksklick auf das Fenster ausgeführt wird...
$tPoint_MousePos = _WinAPI_GetMousePos(True, $hWnd);Mausposition wird in einem DLLStruct zurückgegeben. Die Parameter geben an, dass die Koordinaten rel. zum Fenster sein sollen.Switch True ;Da nur jeweils einer von beiden Fällen eintreten kann, ist hier eine Switch Abfrage sinnvoller.
[/autoit] [autoit][/autoit] [autoit]
Case _WinAPI_PtInRect($tRect_AutoIt, $tPoint_MousePos)
MsgBox(64, "Event", "Mausklick auf 'AutoIt' registriert.")
Case _WinAPI_PtInRect($tRect_Niccoo, $tPoint_MousePos)
MsgBox(64, "Event", "Mausklick auf 'Niccoo' registriert.")
EndSwitch
EndSwitch
WEndFunc _Paint()
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_GraphicsClear($hGraphics, 0xFFFFFFFF)
_GDIPlus_GraphicsDrawStringEx($hGraphics, $sString_AutoIt, $hFont, $tLayout_AutoIt, $hStringFormat, $hBrush_AutoIt) ;String zeichnen
_GDIPlus_GraphicsDrawStringEx($hGraphics, $sString_Niccoo, $hFont, $tLayout_Niccoo, $hStringFormat, $hBrush_Niccoo) ;String zeichnen
EndFunc ;==>_Paint;Aufräumen - Wichtig!
[/autoit]
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_BrushDispose($hBrush_AutoIt)
_GDIPlus_BrushDispose($hBrush_Niccoo) ;Beide Brushes entfernen... Du erstellst 2? Dann entferne beide!
_GDIPlus_StringFormatDispose($hStringFormat)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_FontDispose($hFont)
_GDIPlus_Shutdown() -
Du könntest einfach alle Variablen in Option als Global anstatt Local deklarieren. Aber ich würde dir empfehlen, alle GUIs am Anfang des Scripts zu erstellen (dann sind die Variablen sowieso alle Global) und im Verlauf des Scripts nach Bedarf mit GUISetState an- und auszuschalten. GUIs mitten im Script zu erstellen sorgt meist für Probleme..
-
Zitat
Vorher einfach nach "\" filtern mit Stringsplit und nur das letzte Element auswerten vielleicht?
Das wäre ein bisschen viel Aufwand finde ich... Mit StringRegExpReplace hätte das alles in eine Zeile gepasst und würde auch mit noch so vielen Punkten funktionieren. -
Drucken kannst du relativ einfach über die Shell32 DLL bzw. mit dem Befehl
[autoit]_FilePrint()
[/autoit]damit lässt sich, nach meinem Wissensstand aber nur eine reine Textdatei drucken (wie man es von .txt Dateien aus Notepad kennt).
Es gibt aber bestimmt noch weiter ausgearbeitetere Lösungen mit AutoIt. Such doch mal ein bisschen über Google. -
Die sauberste Methode die auch nur einen Befehl benötigt ist meiner Meinung nach StringRegExpReplace. Das funktioniert ähnlich wie das was progandy gepostet hat.
Da jetzt wirklich alle Methoden die möglich sind (fast alle) hier gepostet wurden musst du dich jetzt für eine entscheiden Fliwatt :D. -
Die Dateiendung kann theoretisch fast beliebig viele Zeichen umfassen.. Beispiel .h für die vom C++ Linker (?) verwendeten Header Dateien.
[autoit]
Auch mehr als 3 Zeichen sind möglich und werden manchmal verwendet z.B. .jpeg und .tiff.
Geht es immer nur um einen Dateinamen mit Endung, oder kommen auch noch Verzeichnis und Datenträgerbuchstabe hinzu?
Es gibt nämlich die Funktion_PathSplit
[/autoit]mit der du einen Dateipfad in all seine Bestandteile zerlegen kannst.
[autoit]
Ansonsten geht das auch mitStringRegExpReplace
[/autoit]Edit: BugFix Oder so :D.
-
Meine Binärzahl war vermutlich richtig, aber ich hab trotzdem blödsinn gerechnet.
Auf jedenfall sind die Zahlen zu groß, und die Bignum UDF muss ran.
Edit:ZitatNein. AutoIt verwendet die größten Grenzen, die Microsoft Visual C++ zulässt. Das sind 64-bit Integer und 64-bit Floats
Ah, okay das wusste ich nicht. Dann kommt bei 10000000000000000 ^ 2 eine Zahl größer als es die 64-Bit zulassen raus, und der Rest hat zufällig eine 1 als erstes Bit, wenn da wirklich was negatives rauskommt wie x0r sagt. -
Dafür gibt es das Makro
[autoit]@GUI_CtrlID
[/autoit], welches innerhalb der aufgerufenen Funktion die ControlID des geklickten Controls definiert.
Dann könntest du in einer For-Schleife alle Button IDs in $h_button nacheinander durchgehen und mit dem Makro per If-Abfrage vergleichen. -
Das liegt wohl daran. AutoIt verwendet (glaube ich) 32-bit signed integer. Dadurch ist das erste Bit für das Vorzeichen reserviert und man kann maximal Zahlen von −2.147.483.648 bis 2.147.483.648 speichern. Was bei 10000000000000000 genau passiert weiß ich nicht. Die Bignum UDF in James Post hat aber diese Probleme nicht.
-
Zitat
Das ganze ist ein C#-XNA-Spiel.
Dann ist das wohl in Hilfe & Unterstützung auch nicht so richtig aufgehoben..Zitatich muss jetzt nur berechnen bei welchem Fach die Spitze der Waffe ist...
Brauchst du dazu wirklich ein Rechteck? Würde einfach ein Punkt an der Spitze der Waffer reichen?
Dann würde ich einfach einen Vektor vom Ankerpunkt der Waffe zu ihrer Spitze konstruieren (also relativ zum Ankerpunkt, nicht zum Ursprung des KS).
Diesen Vektor kannst du dann beliebig rotieren, indem du einfach eine Rotationsmatrix wie die in meiner Funktion darauf anwendest, ohne den Rotationspunkt. Den brauchst du ja dann nicht.
Nach der Matrix Transformation addierst du den Vektor zu seinem Ankerpunkt und hast die Spitze der Waffe relativ zum KS.
Das kannst du dann noch beschleunigen, indem du optimierte Funktionen verwendest, oder statt Sinus/Cosinus vorgerechnete Tabellen verwendest. -
Dein Bild kann ich nicht angucken, aber ich bin mir ziemlich sicher, dass ich weiß was du meinst. Handelt es sich bei dem ganzen überhaupt um ein AutoIt Problem, oder machen wir hier nur dein Hausaufgaben?

Eine Möglichkeit das ganze zu machen wäre, die Punkte des Rechtecks zu berechnen die es ohne Rotation hätte.
Also:Dann einfach immer die Höhe/Breite zu den Koordinaten der Punkte dazuaddieren bis du alle Punkte hast.
Cx = Dx + Breite
Cy = Dy
Ax = Dx
Ay = Dy + Höhe
Bx = Cx (Dx + Breite)
By = Ay (Dy + Höhe)
Dann kannst du die 3 berechneten Punkte (C, A, B) durch meine Funktion jagen (mit dem ersten Punkt "D" als Rotationspunkt und dem Winkel Alpha (z.B. 30°)), und dann hättest du die Punkte.
Man könnte das ganze auch direkter lösen, aber so wäre das recht allgemein und überschaubar. Wenn dir die paar zusätzlichen Millisekunden nichts ausmachen, funktioniert das aber auch so. -
Zitat
Ah, ich sollte erwähnen, dass sich das Rechteck in einem Koordinatensystem befindet und ich die Position der Links oberen Ecke kenne. Ich kenne auch die Längen der Seiten.
Ja, das hättest du eventuell erwähnen sollen...
Das heißt, du hast den linken oberen Punkt, die Seitenlängen und einen bestimmten Winkel. Die Kanten des Rechtecks sind normalerweise parallel zu den Koordinatenachsen, und wurde in diesem bestimmten Winkel rotiert. Aber wo liegt der Rotationspunkt? Im Ursprung des Koordinatensystems? Im linken oberen Punkt des Rechtecks? In dessen Mitte?
Du musst uns schon alle relevanten Informationen geben ^^. -
Ich bin mir nicht ganz sicher wie du das meinst.. Willst du ein Rechteck um einen Punkt rotieren lassen?
Das würde mit einer Rotationsmatrix gehen.Spoiler anzeigen
[autoit]Global Const $nDegToRad = ACos(-1) / 180
[/autoit] [autoit][/autoit] [autoit]
$nDegree = 45 ; Winkel in Grad
$nX_Rot = 0 ;Rotationspunkt - X_Koordinate
$nY_Rot = 0 ;Rotationspunkt - Y_Koordinate$nAngle = $nDegree * $nDegToRad ; Umrechnung in Radiant
[/autoit] [autoit][/autoit] [autoit]$nX_Old = 10 ;Alter Punkt - X_Koordinate
[/autoit] [autoit][/autoit] [autoit]
$nY_Old = 5 ;Alter Punkt - Y_Koordinate$nX_New = Cos($nAngle) * ($nX_Old - $nX_Rot) - Sin($nAngle) * ($nY_Old - $nY_Rot) + $nX_Rot
[/autoit] [autoit][/autoit] [autoit]
$nY_New = Sin($nAngle) * ($nX_Old - $nX_Rot) + Cos($nAngle) * ($nY_Old - $nY_Rot) + $nY_RotConsoleWrite($nX_Old & " : " & $nY_Old & @CRLF & $nX_New & " : " & $nY_New & @CRLF)
[/autoit]
Oder das ganze als Funktion:Spoiler anzeigen
[autoit]Func _Rotate2DPoint($nX_Old, $nY_Old, $nAlpha, $nX_Rot = 0, $nY_Rot = 0)
[/autoit]
; -Author: name22 (http://www.autoit.de)
Local $aPointNew[2]
$aPointNew[0] = Cos($nAlpha) * ($nX_Old - $nX_Rot) - Sin($nAlpha) * ($nY_Old - $nY_Rot) + $nX_Rot
$aPointNew[1] = Sin($nAlpha) * ($nX_Old - $nX_Rot) + Cos($nAlpha) * ($nY_Old - $nY_Rot) + $nY_Rot
Return $aPointNew
EndFunc
Du müsstest dann nur noch alle Punkte des Rechtecks um dessen Mittelpunkt rotieren lassen. Die 4 Punkte des originalen Rechtecks zu berechnen sollte ja nicht allzu schwer sein (jenachdem welche Daten du von dem Rechteck hast) ;). -
Wenn die Userlist in der Konsole ausgegeben wird, kannst du mit Stdout/Stdin Streams arbeiten.
[autoit]
In der AutoIt Hilfe zu den BefehlenStdoutRead()
[/autoit]
StdinWrite()
Run()
Findest du alles was du dazu brauchst. Beispiele sind natürlich auch dabei. Du kannst per StdinWrite in die Konsole deine Befehle schreiben und per StdoutRead die Ausgabe auslesen. -
Zu dem was eukalyptus geschrieben hat, kannst du dir auch das Spiel "Arena Fight" in meiner Signatur anschauen. Dort verwende ich die "HighPrecisionSleep" Methode mit Timern um die Framerate möglichst nahe am Sollwert zu halten.
Außerdem gibt es die Möglichkeit, alle Geschwindigkeiten von Objekten Zeitbasiert und nicht Framebasiert zu verarbeiten. Dann sind FPS und Geschwindigkeit der Objekte unabhängig voneinander.
Genau das hab ich auch in Arena Fight gemacht, weil die Framerate dort frei einstellbar ist, und einen viel zu großen Einfluss auf den Spielverlauf hätte. -
Ich hoffe ich hab dich richtig verstanden... Meinst du das in etwa so?
Spoiler anzeigen
[autoit]Dim $aTest[3][3] = [[2]] ;Anzahl der Bereiche
[/autoit] [autoit][/autoit] [autoit]
$aTest[1][0] = 0.9 ;Wahrscheinlichkeit für ersten Bereich (Summe aller Wahrscheinlichkeiten muss 1 sein)
$aTest[1][1] = 1 ;Erster Bereich Minimum
$aTest[1][2] = 3 ;Erster Bereich Maximum
$aTest[2][0] = 0.1 ;Wahrscheinlichkeit für zweiten Bereich
$aTest[2][1] = 4 ;Zweiter Bereich Minimum
$aTest[2][2] = 6 ;Zweiter Bereich Maximum$iCount = 0
[/autoit] [autoit][/autoit] [autoit]
For $i = 1 To 10000
$iRandom = _RandomPropabilyty($aTest)
If $iRandom <= 3 Then $iCount += 1
Next
ConsoleWrite("Percentage of results between 1 & 3: " & $iCount / 100 & @CRLF)Func _RandomPropabilyty($aProp)
[/autoit] [autoit][/autoit] [autoit]
;- Author: name22 (http://www.autoit.de)
If Not IsArray($aProp) Then Return SetError(1, "", "")Local $nRand = Random()
[/autoit]
Local $nProp = 0
For $i = 1 To $aProp[0][0]
$nProp += $aProp[$i][0]
If $nRand <= $nProp Then Return Random($aProp[$i][1], $aProp[$i][2], 1)
Next
Return SetError(2, "", "")
EndFunc ;==>_RandomPropabilyty
Es ist noch nicht wirklich ausreichend getestet und optimiert, aber es scheint zu funktionieren. -
Hier siehst du sogar wie das evtl. geht. eukalyptus, XP-Fan und andere haben bereits einen Visualizer hier gemacht. Das ist doch in etwa, was du suchst, oder?
Edit: Ich hab in der BASS.au3 auch mal was zum Thema BPM Measure gefunden. Schau dir mal das ganze Bass Zeugs an, ich bin mir sicher, dass du da was findest. Aber soweit ich weiß ist das mit den BPM immer so eine Sache... -
Zitat
Die müsste ich dan ja auch wieder neuladen. Nur als beispiel: er hat 3 Tower. Diese sind auf dem spielfeld verteilt. Dan müsste ich ja vorher in einem Array speichern wo die ganzen Tower stehen & welche & die dan auch wieder neuladen.
Alles musst du jeden Durchgang in der Hauptschleife neuzeichnen ;). Die Koordinaten von allen beweglichen Objekten in einem Array zu speichern ist wohl das einzig sinnvolle, ja ^^. Am besten in einem 2D Array in der Art:CodeGlobal $aTowers[10][2] = [[9]] ;9 ist die Anzahl der Array Elemente in der ersten Dimension (in diesem Fall Türme) $aTowers[1][0] = 220 ;Turm 1 - X Position $aTowers[1][1] = 50 ;Turm 1 - Y Position $aTowers[2][0] = 10 ;Turm 2 - X Position $aTowers[2][1] = 165 ;Turm 2 - Y Position
Da deine Türme nachher sicherlich noch mehr Eigenschaften haben, als nur die Koordinaten, kannst du die Anzahl der Elemente in der 2ten Dimension (Eigenschaften pro Turm) entsprechend anpassen.ZitatWenn ich das bis hier jz. richtig verstanden habe & dan da ca. 20-30 (oder vieeeeel mehr) monster rum laufen sollen und dan da noch Tower stehen (auch so 15-20) und ich muss nach jedem Gekillten monster die Map wieder neu laden, sicher das es dan nicht anfängt zu hängen?
Garantieren kann ich da nichts, aber wenn du da viel Arbeit reinsteckst, ein paar Tricks benutzt (wie zum Beispiel Marsi oder auch ich mit _WinAPI_BitBlt) und effizient/sauber programmierst, dann sollten diese Zahlen locker drin sein.
Am Anfang kannst du ja versuchen mal die Basis für dein Spiel fertig zu stellen und nur ein paar Dummy Bilder für Türme etc. einzusetzen. Dann erhöhst du die Anzahl, solange bis das Limit erreicht ist und machst dir dann Gedanken, ob du da noch nachbessern musst.