Hey,
Habe zwei Fragen zu denen ich dringend eine Antwort suche.
Ich will aktuell ein Game im Stil von Streetfighter oder Tekken erstellen.
1. Frage, gibt es eine Möglichkeit .gif Animationen mit GDI+ direkt einzubinden, oder muss ich das im AutoIt-Script "animieren"?
2. Frage, gibt es eine Möglichkeit Multiplayer 1vs1 einzubauen?
Da hatte ich mir vorgestellt das die Spielerdaten auf einen FTP Server die ganze Zeit hochgeladen werden und vom anderen Spieler ausgelesen werden. Allerdings bin ich mir sicher das dass nicht wirklich effektiv ist oder überhaupt funktioniert, hoffe jemand kann mir da helfen
Mfg
GDI+ Animationen und AutoIt Multiplayer
-
- [ offen ]
-
Nakroma -
9. Februar 2013 um 21:45 -
Geschlossen -
Erledigt
-
-
Zu 2)
Das funktioniert wahrscheinlich schon, ist aber wie du schon selbst angemerkt hast nicht sehr effektiv. Ein in AutoIt geschriebener TCP- oder UDP-Server (einfach mal die Funktionen in der Hilfe anschauen) wäre besser und auch einfacher zu verwenden. -
1) Ne, Animationen kannst du so direkt nicht einfügen. Musst du wohl oder übel im Script animieren. Kannst aber den aufbau einer *.gif lernen und dann die einzelnen Bilder selber auslesen. Könnte man sicherlich immer wieder gebrauchen.
-
Was man auch machen könnte wäre folgendes: Jede Animation besteht aus einigen (immer gleich vielen) "Phasen" oder eben Einzelbildern, die alle zum Beispiel praktisch in einem Array abgespeichert werden. In der Zeichnen-Methode kann man dann statt dem Index für das Bild, eine Globale Variable "$Phase" einsetzen, welche vom Script in einem vorgegebenen Zeitabstand verändert/hochgezählt wird... Somit hat man bei geschickter Bilderwahl für die einzelnen Phasen, eine schöne 'Animation'.
-
Hmm okey, die erste Frage wäre beantwortet.
[autoit]
Hab aber grade ein kleines Problem mit den TCP Servern.
Man schickt ja ein Paket so:$socket = TCPConnect("xxxxxxxx", 5001)
[/autoit]
If $socket = -1 Then
MsgBox(16, "Error", "Die Verbindung zum Server konnte nicht hergestellt werden!")
EndIf
$sendedBytes = TCPSend($socket, "Hi")
If $sendedBytes = 0 Then
MsgBox(16, "Error", "Das Paket konnte nicht gesendet werden.")
EndIf
[autoit]
Und empfangen tut man es so:
[/autoit]
$mainsocket = TCPListen("xxxxxxxx", 5000)
$acceptedSocket = TCPAccept($mainsocket)
If $acceptedSocket <> -1 Then
$receivedData = TCPRecv($acceptedSocket, 1024)
MsgBox(64, "Client hat was empfangen!", "Server hat eine Nachricht gesendet: " & $receivedData)
TCPCloseSocket($acceptedSocket)
EndIf
Das Problem ist, egal was ich sende, also z.B. eine Bewegungsvariable oder eine Verändernung des Mana etc., alles wird in $receivedData gespeichert.
Gibt es eine Möglichkeit quasi $sendedBytes = TCPSend($socket, $x) Auch mit $x ? TCPRECV(..) auffangen zu lassen, ohne einen neuen Port aufzumachen?
Mfg -
Dann musst du dem Server eben noch die Information senden, was für Daten er überhaupt gerade empfängt und diese dann auswerten. Zum Beispiel TCPSend($Server, "PosX|" & $x)
-
Hmm habs mir schon gedacht, wollts aber eigentlich vermeiden^^ Okey danke.
Noch ein Problem. Bei den beiden Scripten sollte eigentlich jeweils eines der roten Quadrate bewegbar sein und dies auf die andere GUI übertragen. Ich such jetzt schon 2 Stunden nach dem Fehler, finde ihn aber einfach nicht. Die beiden Quadrate bewegen sich jeweils, allerdings überträgt es die Daten nicht, obwohl es eigentlich funktionieren sollte.
client.au3:Spoiler anzeigen
[autoit]
[/autoit] [autoit][/autoit] [autoit]
#include <GuiConstants.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
OnAutoItExitRegister("_exit")
_GDIPlus_Startup()TCPStartup()
[/autoit] [autoit][/autoit] [autoit]
$mainsocket = TCPListen("127.0.0.1", 5000)HotKeySet("s", "_move")
[/autoit] [autoit][/autoit] [autoit]$gui = GUICreate("Client", 1000, 600)
[/autoit] [autoit][/autoit] [autoit]Global $iWidth = 400, $iHeight = 400
[/autoit] [autoit][/autoit] [autoit]
Global $aPos_Rect[4] = [0, 100, 200, 200]
Global $aPos_Rect2[4] = [300, 100, 200, 200]$hGraphic = _GDIPlus_GraphicsCreateFromHWND($gui) ;Grafikobjekt
[/autoit] [autoit][/autoit] [autoit]
$hGraphic2 = _GDIPlus_GraphicsCreateFromHWND($gui)
$hBrush = _GDIPlus_BrushCreateSolid(0xFFFF0000) ;PinselGUISetOnEvent(-3, "_exit")
[/autoit] [autoit][/autoit] [autoit]
GUIRegisterMsg(0x000F, "WM_PAINT")
GUISetState(@SW_SHOW)While 1
[/autoit] [autoit][/autoit] [autoit]
$acceptedSocket = TCPAccept($mainsocket)
If $acceptedSocket <> -1 Then
$receivedData = TCPRecv($acceptedSocket, 1024)
$aPos_Rect[0] = $receivedData
_WinAPI_RedrawWindow($gui, 0, 0, $RDW_INTERNALPAINT)
TCPCloseSocket($acceptedSocket)
EndIf
WEndFunc _senden()
[/autoit] [autoit][/autoit] [autoit]
$socket = TCPConnect("127.0.0.1", 5001)
If $socket = -1 Then
MsgBox(16, "Error", "Die Verbindung zum Server konnte nicht hergestellt werden!")
EndIf
$sendedBytes = TCPSend($socket, $aPos_Rect2[0])
If $sendedBytes = 0 Then
MsgBox(16, "Error", "Das Paket konnte nicht gesendet werden.")
EndIf
TCPCloseSocket($socket)
EndFuncFunc _exit()
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_GraphicsDispose($hGraphic2)
_GDIPlus_Shutdown()
Exit
EndFuncFunc _move()
[/autoit] [autoit][/autoit] [autoit]
$aPos_Rect2[0] += 2
_WinAPI_RedrawWindow($gui, 0, 0, $RDW_INTERNALPAINT)
EndFuncFunc WM_PAINT()
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_GraphicsClear($hGraphic,0xFFF0F0F0)
_GDIPlus_GraphicsClear($hGraphic2,0xFFF0F0F0)
_GDIPlus_GraphicsFillRect($hGraphic, $aPos_Rect[0], $aPos_Rect[1], $aPos_Rect[2], $aPos_Rect[3], $hBrush)
_GDIPlus_GraphicsFillRect($hGraphic2, $aPos_Rect2[0], $aPos_Rect2[1], $aPos_Rect2[2], $aPos_Rect2[3], $hBrush)
EndFuncTCPShutdown()
[/autoit]
server.au3:Spoiler anzeigen
[autoit]
[/autoit] [autoit][/autoit] [autoit]
#include <GuiConstants.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
OnAutoItExitRegister("_exit")
_GDIPlus_Startup()TCPStartup()
[/autoit] [autoit][/autoit] [autoit]
$mainsocket = TCPListen("127.0.0.1", 5001)HotKeySet("w", "_move")
[/autoit] [autoit][/autoit] [autoit]$gui = GUICreate("Server", 1000, 600)
[/autoit] [autoit][/autoit] [autoit]Global $iWidth = 400, $iHeight = 400
[/autoit] [autoit][/autoit] [autoit]
Global $aPos_Rect[4] = [0, 100, 200, 200]
Global $aPos_Rect2[4] = [300, 100, 200, 200]$hGraphic = _GDIPlus_GraphicsCreateFromHWND($gui) ;Grafikobjekt
[/autoit] [autoit][/autoit] [autoit]
$hGraphic2 = _GDIPlus_GraphicsCreateFromHWND($gui)
$hBrush = _GDIPlus_BrushCreateSolid(0xFFFF0000) ;PinselGUISetOnEvent(-3, "_exit")
[/autoit] [autoit][/autoit] [autoit]
GUIRegisterMsg(0x000F, "WM_PAINT")
GUISetState(@SW_SHOW)While 1
[/autoit] [autoit][/autoit] [autoit]
$acceptedSocket = TCPAccept($mainsocket)
If $acceptedSocket <> -1 Then
$receivedData = TCPRecv($acceptedSocket, 1024)
$aPos_Rect2[0] = $receivedData
_WinAPI_RedrawWindow($gui, 0, 0, $RDW_INTERNALPAINT)
TCPCloseSocket($acceptedSocket)
EndIf
WEndFunc _senden()
[/autoit] [autoit][/autoit] [autoit]
$socket = TCPConnect("127.0.0.1", 5000)
If $socket = -1 Then
MsgBox(16, "Error", "Die Verbindung zum Server konnte nicht hergestellt werden!")
EndIf
$sendedBytes = TCPSend($socket, $aPos_Rect[0])
If $sendedBytes = 0 Then
MsgBox(16, "Error", "Das Paket konnte nicht gesendet werden.")
EndIf
TCPCloseSocket($socket)
EndFuncFunc _exit()
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_GraphicsDispose($hGraphic2)
_GDIPlus_Shutdown()
Exit
EndFuncFunc _move()
[/autoit] [autoit][/autoit] [autoit]
$aPos_Rect[0] += 2
_WinAPI_RedrawWindow($gui, 0, 0, $RDW_INTERNALPAINT)
EndFuncFunc WM_PAINT()
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_GraphicsClear($hGraphic,0xFFF0F0F0)
_GDIPlus_GraphicsClear($hGraphic2,0xFFF0F0F0)
_GDIPlus_GraphicsFillRect($hGraphic, $aPos_Rect[0], $aPos_Rect[1], $aPos_Rect[2], $aPos_Rect[3], $hBrush)
_GDIPlus_GraphicsFillRect($hGraphic2, $aPos_Rect2[0], $aPos_Rect2[1], $aPos_Rect2[2], $aPos_Rect2[3], $hBrush)
EndFuncTCPShutdown()
[/autoit] -
Ich habe gerade zwar keine Zeit um den Fehler in deinen Scripts zu suchen, aber bitte missbrauche TCP nicht so! Wenn du 2 Spieler hast, die über die Position des Anderen bescheid wissen sollen, dann ist immer einer der Server und einer der Client. Dann baut der Client eine Verbindung zum Server auf und über diese Eine Verbindung werden dann alle Pakete verschickt. Hier hatte ich schon mal ein Beispiel dazu gepostet... Und Ja dieses Thema haben wir hier wirklich schon hunderte Male durchgekaut.
Edit: Ich glaub ich setz mich jetzt wirklich mal an ein gescheites TCP-Tutorial... -
Hab mal wieder ein kleines Problem mit mehreren Clients
Ich habe jetzt einfach mal die UDF von hier genommen: https://autoit.de/index.php?page…2087#post262087
Damit
klappt auch alles wunderbar, aber der Client verarbeitet irgendwie die
Returns nicht. Sleep funktioniert nicht und ich weiß nicht was Christoph mit
"Normalerweise macht man das so, dass der Client/Server die Pakete
'unvorbereitet' empfängt." meint.
Bevor man mein Script liest,
solltest man vlt wissen worum es geht, ich will wie gesagt ein
Multiplayerfähiges StreetFighter Game bauen. Aber, weil man sonst die
Ports freigeben muss, will ich das nicht über einen Host & einen
Client laufen lassen wie in etwas älteren Spielen, WarCraft III z.B.
sondern ich will einen großen Server auf dem dann immer zwei Clients
zusammen spielen können. Aktuell löse ich das so, indem ich bei Login
einer freien $player[$i] diesen Client zuteile. In der späteren Match
Funktion soll der Server dann einfach zwei Clients die eingeloggt sind
zusammenwerfen.
Server.au3Spoiler anzeigen
[autoit]
[/autoit] [autoit][/autoit] [autoit]
#include "TCPServer.au3" ;http://pastebin.com/Ht8vqAXN
$Server_IP = "25.57.169.7"
$Server_Port = 32976
Global $player[99]
For $i=0 To 98
$player[$i] = False
Next
Global $login = False
_TCPServer_RegisterEvent($TCPSERVER_RECEIVEDDATA, "ReceivedData")
_TCPServer_Startup($Server_IP, $Server_Port)
ConsoleWrite("Server ist nun hochgefahren." & @CRLF)While Sleep(100)
[/autoit] [autoit][/autoit] [autoit]
WEndFunc ReceivedData($socket, $data)
[/autoit]
$data = StringSplit($data, "|")
Switch $data[1]
Case "SHUTDOWN"
ConsoleWrite("Server wird runtergefahren." & @CRLF)
_TCPServer_Shutdown()
Exit
Case "CONNECT"
If ($data[0] = 2) Then
For $i=0 To 98
If $player[$i] = False Then
$player[$i] = True
ConsoleWrite("Ein Client hat sich als Player " & $i & " eingeloggt." & @CRLF)
Return $i
$login = True
ExitLoop
EndIf
Next
If $login <> True Then
Return "Der Server ist aktuell ausgelastet. Versuch es später nochmal."
ConsoleWrite("Der Server ist ausgelastet." & @CRLF)
EndIf
$login = False
EndIf
Case "LOGOUT"
If ($data[0] = 2) Then
$player[$data[2]] = False
ConsoleWrite("Client " & $data[2] & " hat sich ausgeloggt." & @CRLF)
EndIf
Case Else
ConsoleWrite("Unbekanntes Kommando: " & $data[1] & @CRLF)
EndSwitch
EndFunc
Client.au3Spoiler anzeigen
[autoit]
[/autoit] [autoit][/autoit] [autoit]
#include
#include
Opt("GUIOnEventMode", 1)
TCPStartup()
$Server_IP = "25.57.169.7"
$Server_Port = 32976
$hGUI = GUICreate("GDI-TCP-Client", 400, 400)
$button1 = GUICtrlCreateButton("Einlogen", 10, 10)
$button2 = GUICtrlCreateButton("Ausloggen", 10, 60)
GUISetOnEvent(-3, "_exit")
GUICtrlSetOnEvent($button1, "_einloggen")
GUICtrlSetOnEvent($button2, "_ausloggen")
GUISetState(@SW_SHOW)$MainSocket = TCPConnect($Server_IP, $Server_Port)
[/autoit] [autoit][/autoit] [autoit]
If @error Then
MsgBox(16, 'Fehler beim Verbinden', 'Entweder stimmen IP-Adresse/Port
nicht, oder es ist bereits ein anderer Client mit dem Server
verbunden.', 10)
_exit()
EndIfWhile 1
[/autoit] [autoit][/autoit] [autoit]
$Recv = TCPRecv($MainSocket, 1024)
If @error Then _exit()
If $Recv <> '' Then
If StringIsDigit($Recv) Then
MsgBox(0, "", "Du bist nun Player " & $Recv)
Global $baum = $Recv
Else
MsgBox(0, "", $Recv)
EndIf
EndIf
WEndFunc _einloggen()
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
TCPSend($MainSocket, "CONNECT|")
EndFunc
Func _ausloggen()
TCPSend($MainSocket, "LOGOUT|" & $baum)
EndFuncFunc _exit()
[/autoit]
TCPCloseSocket($MainSocket)
TCPShutdown()
Exit
EndFuncNoch anzumerken ist, das dies meine Hamachi IP ist, also nicht wundern das ich sie nicht zensiere^^
Wäre nett wenn mir jemand helfen könnte,
Mfg Nakro -
Auf den ersten Blick finde ich in den Skripten jetzt keinen Fehler...
Was mich allerdings wundert ist die im Server angegebene IP-Adresse. Sollte da nicht eigentlich sowas wie "127.0.0.1" oder @IPAddress1 stehen? Hast du mal den Rückgabewert von _TCPServer_Startup überprüft? Es könnte ja sein, dass der Server gar nicht startet und der Client somit gar nicht die Möglichkeit hat, irgendwelche Daten zu verarbeiten. -
Gut, dann poste ich mal wieder hier damit ich keinen neuen Thread aufmachen muss.
Ich hab grade massive Probleme mit GDI+ und Backbuffern. Klappt alles super bis auf die Imagegröße.
Die wird irgendwie durch die Bitmap verkleinert, die Werte bleiben aber die gleichen(die ich ja später brauche zum Hitbox berechnen).
Wenn ich die Bitmap auf die selbe Größe wie die Figur mache, wird sie irgendwann abgeschnitten.Mit gleicher Bitmap, Bild ist in der richtigen Größe wie die Variablen aber wird abgeschnitten wenn man zu weit läuft:
Spoiler anzeigen
[autoit]
[/autoit] [autoit][/autoit] [autoit]
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <GuiConstants.au3>
Opt("GUIOnEventMode", 1)
_GDIPlus_Startup()
Global $aPos_RectX[2] = [0, 400]
Global $aPos_RectY[2] = [0, 400]
Global $aPos_RectW[2] = [100, 100]
Global $aPos_RectH[2] = [142, 142]
HotKeySet("w", "_move")$hGUI = GUICreate("GUI", 700, 700)
[/autoit] [autoit][/autoit] [autoit]$hPlayer = _GDIPlus_ImageLoadFromFile("./data/char1.gif")
[/autoit] [autoit][/autoit] [autoit]
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($aPos_RectW[0], $aPos_RectH[0], $hGraphic)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
GUISetOnEvent(-3, "_exit")
GUIRegisterMsg(0x000F, "WM_PAINT")
GUISetState(@SW_SHOW)While 1
[/autoit] [autoit][/autoit] [autoit]
WEndFunc _exit() ; Beenden des Clients
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_ImageDispose($hPlayer)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_Shutdown()
Exit
EndFunc
Func WM_PAINT() ; Redraw Funktion
_GDIPlus_GraphicsClear($hBackbuffer, 0xFF000000 + 0xF0F0F0)
_GDIPlus_GraphicsDrawImageRect($hBackbuffer,$hPlayer, $aPos_RectX[0], $aPos_RectY[0], $aPos_RectW[0], $aPos_RectH[0])_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, $aPos_RectX[0], $aPos_RectY[0], $aPos_RectW[0], $aPos_RectH[0])
[/autoit]
EndFunc
Func _move()
$speed = 1
$aPos_RectX[0] += $speed
_WinAPI_RedrawWindow($hGUI, 0, 0, $RDW_INTERNALPAINT)
EndFuncMit Bitmap die so groß ist wie die GUI, Bild wird verkleinert Height und Width Werte bleiben aber normal groß:
Spoiler anzeigen
[autoit]
[/autoit] [autoit][/autoit] [autoit]
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <GuiConstants.au3>
Opt("GUIOnEventMode", 1)
_GDIPlus_Startup()
Global $aPos_RectX[2] = [0, 400]
Global $aPos_RectY[2] = [0, 400]
Global $aPos_RectW[2] = [100, 100]
Global $aPos_RectH[2] = [142, 142]
HotKeySet("w", "_move")$hGUI = GUICreate("GUI", 700, 700)
[/autoit] [autoit][/autoit] [autoit]$hPlayer = _GDIPlus_ImageLoadFromFile("./data/char1.gif")
[/autoit] [autoit][/autoit] [autoit]
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics(700, 700, $hGraphic)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
GUISetOnEvent(-3, "_exit")
GUIRegisterMsg(0x000F, "WM_PAINT")
GUISetState(@SW_SHOW)While 1
[/autoit] [autoit][/autoit] [autoit]
WEndFunc _exit() ; Beenden des Clients
[/autoit] [autoit][/autoit] [autoit]
_GDIPlus_ImageDispose($hPlayer)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_Shutdown()
Exit
EndFunc
Func WM_PAINT() ; Redraw Funktion
_GDIPlus_GraphicsClear($hBackbuffer, 0xFF000000 + 0xF0F0F0)
_GDIPlus_GraphicsDrawImageRect($hBackbuffer,$hPlayer, $aPos_RectX[0], $aPos_RectY[0], $aPos_RectW[0], $aPos_RectH[0])_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, $aPos_RectX[0], $aPos_RectY[0], $aPos_RectW[0], $aPos_RectH[0])
[/autoit]
EndFunc
Func _move()
$speed = 1
$aPos_RectX[0] += $speed
_WinAPI_RedrawWindow($hGUI, 0, 0, $RDW_INTERNALPAINT)
EndFunc