Erstes Multiplayerspiel, Positionsabfrage :/

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

 

emcapone

Betreff: Erstes Multiplayerspiel, Positionsabfrage :/

BeitragDi, Jul 22, 2008 23:53
Antworten mit Zitat
Benutzer-Profile anzeigen
nabend allerseits, bin grad dabei mein erstes multiplayerspiel zu machn. im moment versuche ich die positionsabfrage zwischen beiden spielern (Host und Client) zu programmieren. Das heisst wenn Player1 nach links läuft, soll das Player2 auf seinem Bildschirm sehen können.
Nach meiner Logik müsste das folgendermaßen aufgebaut sein, das verbinden an sich klappt auch, die Positionsabfrage ansich funktioniert jedoch nicht. Ich bedanke mich für jede helfende Antwort!

Code: [AUSKLAPPEN]

 Graphics3D 800, 600

SetBuffer BackBuffer()

;Onlinesettings

Global stream
Global empfangsport
Global sendeport

; Player 1

Global x1
Global y1
Global z1

;Player 2

Global x2
Global y2
Global z2





;Spielfigur 1 laden und positionieren

x1=-15
y1=0
z1=15

Global  mario=LoadMesh( "dateien\mario.x" )
ScaleEntity mario, 0.1,0.2,0.1
PositionEntity mario, x1, y1, z1




;Spielfigur 2 laden und positionieren

x2=-20
y2=0
z2=10
Global mario2=LoadMesh("dateien\mario.x")
ScaleEntity mario2, 0.1,0.2,0.1
PositionEntity mario2,x2,y2,z2
;Bullet laden

Global munition = 10 + munitionx

Global bullet=LoadMesh("dateien\bullet.x")

ScaleEntity bullet, 0.1, 0.1, 0.3

;Boot laden
posix = 15
posiy = -3
posiz = -70

Global auto=LoadMesh("dateien\auto.x")

ScaleEntity auto, 0.4, 0.4, 0.4

PositionEntity auto, posix, posiy, posiz

;SOUNDS LADEN



; MAP LADEN

Global Testmap=LoadMesh("dateien\Testmap.x")

ScaleEntity Testmap, 2, 2, 2

PositionEntity Testmap, 0, -5, 0

; Munition
Global munianzeige=LoadImage("dateien\testmuni.jpg")

;camera
Global camera



;Kollisionen

Const mario_TYPE=1
Const Testmap_TYPE=2
Const auto_TYPE=3
Const bullet_TYPE=4
Const mario2_TYPE=5

EntityType auto,auto_TYPE
EntityType mario,mario_TYPE
EntityType Testmap,Testmap_TYPE
EntityType bullet,bullet_TYPE
EntityType mario2,mario2_TYPE

Collisions auto_TYPE,mario_TYPE,2,1
Collisions mario_TYPE,Testmap_TYPE,2,2 
Collisions mario_TYPE,auto_TYPE,2,2
Collisions auto_TYPE,Testmap_TYPE,2,2
Collisions bullet_TYPE,testmap_TYPE,2,2
Collisions auto_TYPE,mario2_TYPE,2,1 ; Auto und Spieler2
Collisions mario2_TYPE,Testmap_TYPE,2,2
Collisions mario2_Type,auto_TYPE,2,2


While Not KeyHit(1)

; Spielerwahl
;-----------> Hauptmenu <------------
Print "Willkommen"
Print ""
Print "Wähle [1] um das Spiel als Host zu starten.";Host ist der PC wo das Spiel startet
Print "Wähle [2] um das Spiel als Client zu starten.";Client ist der PC wo sich mit einem Host verbindet
Print "Wähle [3] um das Spiel zu Verlassen."
wahl_nummer = Input("Ihre Wahl:") ;jetzte nach der Wahl des Players fragen


 

;;;;Einstellung;;;;;;; zu /////PLAYER 1///////
If wahl_nummer = 1

sendeport = 8000 ;ist der Port womit man dann Daten senden kann
  empfangsport = 8001;ist der Port womit man dann Daten empfangen kann
    stream = CreateUDPStream(empfangsport) ;den UDP-Stream erstellen um Daten zu empfangen
        Print "Spiel als Host gestartet"
        Print "Deine IP findest du unter *www.wasistmeineip.de*,"
        Print "diese braucht der Client um mit dir zu verbinden!"
        Print "Warten auf den Client..."
          Repeat ;solange warten bis der Client sich mit dem Host verbunden hat
             ip = RecvUDPMsg(stream);wenn eine nachricht empfangen wird...
              Until ip <> 0
             WriteByte stream,1;eine anwort senden
             SendUDPMsg stream,ip,sendeport


EndIf



;;;;Einstellung;;;;;;; zu /////PLAYER 2///////
If wahl_nummer=2; player ist player2 (also client)

  ip_nummer$ = Input("Die IP vom Host: ") ;nach der IP fragen...
  ip = integerip(ip_nummer$)            ;IP umwandeln...

  sendeport = 8001 ;ist der Port womit man dann Daten senden kann
  empfangsport = 8000;ist der Port womit man dann Daten empfangen kann
    stream = CreateUDPStream(empfangsport) ;den UDP-Stream erstellen um Daten zu empfangen


        WriteByte stream,1 ;1 senden damit der Host weis das ein Client da ist
        SendUDPMsg stream,ip,sendeport ;die nachricht senden
       
      Delay 1000;1sekunde lang warten und dann prüfen ob der host da ist
       
If RecvUDPMsg(stream) Then empfangen = ReadByte(stream)
         
If empfangen = 1   Print "Spiel als Client gestartet"
EndIf

Repeat
Cls
;;;;;;;;; PLAYER EEEEEEEEEEEEEEIIIIINS ;;;;;;;;;;;;;;;;;

If wahl_nummer = 1
;Steuerung zu fuß 

If KeyDown(200)  Then MoveEntity mario,0,0,1.4  bewegung=1
If KeyDown(208)  Then MoveEntity mario,0,0,-1.4 bewegung=1
If KeyDown(205)  Then MoveEntity mario,1.4,0,0  bewegung=1
If KeyDown(203)  Then MoveEntity mario,-1.4,0,0 bewegung=1

;Spielfigur 1 laden

ScaleEntity mario, 0.1, 0.2, 0.1

;Camera
camera=CreateCamera(mario)
PositionEntity camera, 0, 25, -20

.MoveCamera
mx#=-.25*MouseXSpeed()
my#=.25*MouseYSpeed()
MoveMouse GraphicsWidth()/2,GraphicsHeight()/2

TurnEntity mario,0,mx#,0,1
TurnEntity camera,my#,0,0,0




;Steuerung im Bot

If EntityCollided(mario,auto_Type) bedingung=1 ;Autofahren
If EntityCollided(mario2,auto_Type) bedingung=1

If KeyDown(17) And bedingung=1 Then MoveEntity auto,0,0,9  PositionEntity mario,EntityX(auto),EntityY(auto),EntityZ(auto)
If KeyDown(33) And bedingung=1 Then MoveEntity auto,0,0,-7 PositionEntity mario,EntityX(auto),EntityY(auto),EntityZ(auto)
If KeyDown(32) And bedingung=1 Then TurnEntity auto,0,-3,0  PositionEntity mario,EntityX(auto),EntityY(auto),EntityZ(auto)
If KeyDown(30) And bedingung=1 Then TurnEntity auto,0,3,0 PositionEntity mario,EntityX(auto),EntityY(auto),EntityZ(auto)

;Bullet

If bulletready = 0 PositionEntity bullet,EntityX(mario),EntityY(mario)+8,EntityZ(mario) 
If GetMouse() And munition >0 Then bulletready = 1 MoveEntity bullet,0,0,2000  munitionx = -1
If bulletready < 1 Then PositionEntity bullet,EntityX(mario),EntityY(mario)+8,EntityZ(mario)
RotateEntity bullet,EntityPitch(camera)-2,EntityYaw(mario),EntityRoll(mario)
If EntityCollided(bullet,Testmap_Type)  bulletready=0

; Eigene Position senden
WriteByte  stream,x1
SendUDPMsg stream,ip,sendeport

;Position des Gegners lesen
If RecvUDPMsg(stream)  Then newmsg=1
If newmsg = 1 x2=ReadByte 

EndIf

;;;;;;PLAYER ZWEIIIIII;;;;;;;;;;;;
If wahl_nummer = 2

;Laufen

If KeyDown(200)  Then MoveEntity mario2,0,0,1.4   bewegung=1
If KeyDown(208)  Then MoveEntity mario2,0,0,-1.4  bewegung=1
If KeyDown(205)  Then MoveEntity mario2,1.4,0,0   bewegung=1
If KeyDown(203)  Then MoveEntity mario2,-1.4,0,0  bewegung=1

;Camera
camera=CreateCamera(mario2)
PositionEntity camera, 0, 25, -20

.MoveCamera2
mx#=-.25*MouseXSpeed()
my#=.25*MouseYSpeed()
MoveMouse GraphicsWidth()/2,GraphicsHeight()/2

TurnEntity mario2,0,mx#,0,1
TurnEntity camera,my#,2,0,0



;Steuerung im Bot

If EntityCollided(mario2,auto_Type) bedingung=1 ;Wenn Mario das Auto berüht dann Autofahren

If KeyDown(17) And bedingung=1 Then MoveEntity auto,0,0,9  PositionEntity mario2,EntityX(auto),EntityY(auto),EntityZ(auto)
If KeyDown(33) And bedingung=1 Then MoveEntity auto,0,0,-7 PositionEntity mario2,EntityX(auto),EntityY(auto),EntityZ(auto)
If KeyDown(32) And bedingung=1 Then TurnEntity auto,0,-3,0  PositionEntity mario2,EntityX(auto),EntityY(auto),EntityZ(auto)
If KeyDown(30) And bedingung=1 Then TurnEntity auto,0,3,0 PositionEntity mario2,EntityX(auto),EntityY(auto),EntityZ(auto)

;Bullet

If bulletready = 0 PositionEntity bullet,EntityX(mario2),EntityY(mario2)+8,EntityZ(mario2) 
If GetMouse() And munition >0 Then bulletready = 1 MoveEntity bullet,0,0,2000  munitionx = -1
If bulletready < 1 Then PositionEntity bullet,EntityX(mario2),EntityY(mario2)+8,EntityZ(mario2)
RotateEntity bullet,EntityPitch(camera)-2,EntityYaw(mario2),EntityRoll(mario2)
If EntityCollided(bullet,Testmap_Type)  bulletready=0   

;Eigene Position senden
WriteByte  stream,x2
SendUDPMsg stream,ip,sendeport

;Position des Gegners lesen
If RecvUDPMsg(stream)  Then newmsg=1
If newmsg = 1 x1=ReadByte

EndIf



WireFrame(0)

UpdateWorld

RenderWorld



;Munianzeige



;FADENKREUZ
Fadenkreuz=LoadImage("Dateien\crosshair.png")

Breite = AufloesungX / 2
Hoehe = Aufloesungy / 2


;DRAWIMAGE FADENKREUZ
DrawImage Fadenkreuz,0,0,0


;Position ermitteln:
x1 = EntityX(mario)
y1 = EntityY(mario)
z1 = EntityZ(mario)

x2 = EntityX(mario2)
y2 = EntityY(mario2)
z2 = EntityZ(mario2)



Flip
Until KeyHit(1)
Wend

End

Function IntegerIP(IP$)
 A1 = Int(Left(IP$,Instr(IP$,".")-1)) : IP$ = Right(IP$,Len(IP$)-Instr(IP$,"."))
 A2 = Int(Left(IP$,Instr(IP$,".")-1)) : IP$ = Right(IP$,Len(IP$)-Instr(IP$,"."))
 A3 = Int(Left(IP$,Instr(IP$,".")-1)) : IP$ = Right(IP$,Len(IP$)-Instr(IP$,"."))
 A4 = Int(IP$)
 Return (A1 Shl 24) + (A2 Shl 16) + (A3 Shl 8 ) + A4
End Function

ZaP

BeitragMi, Jul 23, 2008 0:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Du solltest vor jede Nachricht ein Byte schreiben, damit dein Gegenüber weiß, was du von ihm willst (z.B. 1 für 'Ich habe mich grade angeschlossen' oder 2 für 'Achtung, es folgt meine aktuelle Position'). Das ganze packst du am besten in Konstanten, damit du nicht so leicht durcheinander kommst:

Code: [AUSKLAPPEN]

const NM_PLAYER_JOINED = 1
const NM_PLAYER_POSITION = 2
const NM_SERVER_SHUTDOWN = 3

....

WriteByte stream, NM_PLAYER_POSITION ;Der Empfänger liest zuerst dieses Byte, und weiß dadurch, dass er als nächstes die Position des Spielers aus dem Stream lesen kann.
WriteFloat stream, x#
...


Am besten ist es, wenn du alle Spieler in Types packst, und nicht für jeden eine neue Prozedur erstellst. An sich ist es wichtig, von jedem Spieler die Integer IP und den Port zu haben.
Starfare: Worklog, Website (download)
 

emcapone

BeitragMi, Jul 23, 2008 14:23
Antworten mit Zitat
Benutzer-Profile anzeigen
thx für die antwort, ich hoffe ich hab das jez richtig verstanden...
also praktisch so:


Code: [AUSKLAPPEN]

const NM_PLAYER_POSITION = 2
 
;Sender

WriteByte stream, NM_PLAYER_POSITION ;Sagt dem Empfänger, dass jez die Posi kommt
WriteFloat stream, x#   ;Gibt dem Empfänger die Position x#

;Empfänger

If  NM_PLAYER_POSITION = 2 Then x# =  ReadFloat(stream) 
; Wenn er bescheidbekommen hat, dass als nächstes die Posi kommt, liest er die Position

ZaP

BeitragMi, Jul 23, 2008 14:31
Antworten mit Zitat
Benutzer-Profile anzeigen
An sich richtig. Es ist aber besser, wenn du gleich alles, was nötig ist in den stream schreibst und dann sendest, sprich x,y,z, evtl. noch yaw und pitch. (sendudpmsg nich vergessen Wink)
Starfare: Worklog, Website (download)
 

emcapone

BeitragFr, Jul 25, 2008 0:27
Antworten mit Zitat
Benutzer-Profile anzeigen
ok mir wurde vorhin klar das ich den ganzen code den ich hatte in die tonne haun kann :/ ich will das ganze jez so machn, dass es ein host gibt, der nur das Hostprogramm ausführt und die Spieler das Clientprogramm ausführen. aber irgendwie hab ich grad gemerkt, dass das mit dem ganzen udp kram doch ganz schön kompliziert ist... folgendes problem hat sich jez aufgetan, ich wollte jez nicht extra nen neuen eintrag dafür machn. also gut ich hab 2 kleine test codes geschrieben, damit ich erstmal nur mit dem prinzip klarkomme.

Host:
Code: [AUSKLAPPEN]

; SERVERRRR

Global stream
Global empfangsport = 8001
Global sendeport = 8000
Global spielerid

stream = CreateUDPStream(empfangsport)


Repeat ;solange warten bis der Client sich mit dem Host verbunden hat
ipx = RecvUDPMsg(stream)
Until ipx<>0

spielerid=ReadFloat(stream); SpielerID lesen

;SPIELER 1-20

;[1]

If spielerid=1001
Print "spieler Eins hat sich angemeldet"
If RecvUDPMsg(stream) Then xy=ReadByte(stream);als nächstes soll er xy lesen
Delay 1000
Print xy
EndIf




und der Spieler/Client
Code: [AUSKLAPPEN]

; DER CLIENT


Global stream
Global empfangsport = 8000
Global sendeport = 8001
Global iphost$ ;IP vom Server






stream = CreateUDPStream(empfangsport)
iphost$=Input ("Gebe hier die Server IP ein und bestätige mit der Enter-Taste!" ) ;Server IP eingeben
  iphost = integerip(iphost$)            ;IP umwandeln...
ip=Input ("Gebe hier deine eigene IP ein.")    ;eigene IP eingeben
id=Input ("Gib nun hier deine Spieler ID ein.") ;Spieler ID eingeben
erkennungsid=id+1000 ; Id mit der der Client beim Host anfragt



Print erkennungsid ; nur ein test ob die erkennungsID richtig berechnet wurde

;Verbindungsaufbau zum Server


WriteFloat stream,erkennungsid ;Erkennungs-ID senden damit der Server weiss wer wir sind
SendUDPMsg stream,iphost,sendeport ;die nachricht senden

Delay 500
WriteFloat stream,1 ;Nur zum testen ob die 1 ankommt
SendUDPMsg stream,iphost,sendeport


Function IntegerIP(IP$)
A1 = Int(Left(IP$,Instr(IP$,".")-1)) : IP$ = Right(IP$,Len(IP$)-Instr(IP$,"."))
A2 = Int(Left(IP$,Instr(IP$,".")-1)) : IP$ = Right(IP$,Len(IP$)-Instr(IP$,"."))
A3 = Int(Left(IP$,Instr(IP$,".")-1)) : IP$ = Right(IP$,Len(IP$)-Instr(IP$,"."))
A4 = Int(IP$)
Return (A1 Shl 24) + (A2 Shl 16) + (A3 Shl 8 ) + A4
End Function


So Host startet als erstes. Client startet danach und gibt die IP des hostes ein. Die eigene IP ist überflüssig. Wichtig ist, dass er als SpielerID eine "1" eingibt...
also gut kurzgefasst: die erste nachricht kommt beim host an, die zweite jedoch nicht! Merkwürdig :/

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group