Seite 3 von 7

Verfasst: 14.02.2007 23:22
von Kaeru Gaman
@ZeHa
is richtig... mach ihm n beispiel... ;)

Verfasst: 14.02.2007 23:54
von ZeHa
Okay ich versuch's ;)

(ach ja, ich mach mir derzeit sogar schon konkrete Gedanken um mein "wie schreibe ich gescheiten Code"-Tutorial, ich hoffe daß ich das noch im Februar schreiben kann)

Also eine Struktur für einen Spieler könnte beispielsweise folgendermaßen aussehen:

Code: Alles auswählen

Structure player
  xPos.f
  yPos.f
  energy.b
  lives.b
  gold.l
EndStructure
Um davon nun ein "Objekt" zu erzeugen und ein paar Werte zu initialisieren, kann man folgendes machen:

Code: Alles auswählen

*player1.player = AllocateMemory(SizeOf(player))
*player1\xPos = 50
*player1\yPos = 80
...
Eine bessere Alternative wäre es, einen "Konstruktor" zu schreiben, z.B. so:

Code: Alles auswählen

Procedure.l newPlayer(x, y)
  *new.player = AllocateMemory(SizeOf(player))
  *new\xPos = x
  *new\yPos = y
  *new\energy = 100
  *new\lives = 3
  *new\gold = 0

  ProcedureReturn *new
EndProcedure
Nun kannst Du davon so viele Player erzeugen, wie Du willst. Bei einem reinen 2-Spieler-Spiel ist es sogar noch vertretbar, einen player1 und einen player2 zu machen, aber ich würde Dir jetzt schon dazu raten, ein Array hierfür zu nehmen:

Code: Alles auswählen

Global Dim *players.player(#NUMBER_OF_PLAYERS)

*players(0) = newPlayer(50, 80)
*players(1) = newPlayer(100, 10)
Um nun die Daten übers Netzwerk zu verschicken, genügt folgendes:

Code: Alles auswählen

SendNetworkData(connection, *players(0), SizeOf(player))
(das einzige, was Du auf diese Art nicht verschickt kriegst, sind Strings, die sich in der Struktur befinden, da diese ja nicht komplett sondern nur per Adresse gespeichert werden - aber die schickst Du dann eben extra (während dem Spielablauf wirst Du auch bestenfalls überhaupt keine Strings verschicken!).

EDIT: Natürlich muß ich auch noch das Empfangen erwähnen. Das funktioniert dann z.B. so:

Code: Alles auswählen

ReceiveNetworkData(connection, *players(0), SizeOf(player))
Du brauchst Dich hier also nicht mit Zerpflücken beschäftigen, sondern Du empfängst einfach den kompletten Haufen und schreibst ihn in den Buffer (die Struktur ist ja letztendlich ein zusammenhängender Speicherbereich, mit der genialen Tatsache, daß Du auf jeden Unterbereich über einen netten Namen zugreifen kansnt). Danach kannst Du ganz bequem damit arbeiten, so als sei nix gewesen.

----

Kommen wir jetzt aber nochmal zu einem ganz anderen Thema: Du solltest auf keinen Fall auf die Idee kommen und in jedem Frame alle Spieler-Daten zu verschicken. Wenn Du das 60x pro Sekunde machst, wird sich Dein Netzwerk bei Dir bedanken :mrgreen:
Eine viel effizientere Lösung ist es, immer nur dann Daten zu verschicken, wenn es notwendig ist. Beispielsweise reicht es (bei einem sauber geplanten Programm) völlig aus, wenn Du alle Tastatur-Eingaben des Clients weiterschickst. Drückt der Client-Spieler nach links, so schickst Du dem Server, daß gerade nach links gedrückt wurde. Wenn dann 3 Sekunden später was anderes gedrückt wurde, wird auch das an den Server geschickt. Dieser muß allerdings so programmiert sein, daß er sich alles komplett anhand dieser Tastatureingaben errechnen kann. Hierzu ist es gut, wenn Du die Bewegung der Spieler KOMPLETT zeitabhängig programmierst und somit die Position eines Spielers zu (weitgehend) jedem beliebigen Zeitpunkt errechnen kannst, also auch ein paar Millisekunden in die Vergangenheit wie auch in die Zukunft (!), um das Spiel ordentlich zu synchronisieren.

Bei einem rundenbasierten Spiel sieht's natürlich anders aus, aber alles was mit Echtzeit funktioniert, sollte immer komplett zeitabhängig programmiert sein (also kein Aufaddieren eines kleinen Wertes zur momentanen Position, sondern Merken der letzten Position und Zeit, und dann Multiplikation der Geschwindigkeit mit der Zeitdifferenz, und dies dann auf die letzte Position addieren - ist blöd zu beschreiben, ich weiß, aber wenn Du Fragen hast, frag :mrgreen: )

Verfasst: 15.02.2007 00:15
von Kaeru Gaman
[OT]

> Kommen wir jetzt aber nochmal zu einem ganz anderen Thema:

....now for something totally different... *BOOOOOM*

:lol:

[/OT]

Verfasst: 15.02.2007 00:20
von ts-soft
Kaeru Gaman hat geschrieben:[OT]

> Kommen wir jetzt aber nochmal zu einem ganz anderen Thema:

....now for something totally different... *BOOOOOM*

:lol:

[/OT]
Hab hier nicht gelesen, weil irgendwie hat der Thread wirklich keinen Titel.

Wäre vielleicht sinnvoll, wenn der Verfasser den mal Aussagekräftiger
gestalten könnte.

Warum ich Kaeru zitiert habe weiß ich auch nicht so genau, evtl. weil das
ganze so Themenlos ist :mrgreen:

Verfasst: 15.02.2007 18:41
von Pandorra
thx für die Tipps von dir ZeHa.
@ts_soft wäre vielleicht gut einen anderen Titel zu nehmen aber welchen?

@ZeHa
Könnte ich es dann so Programmieren das sobald ein Spieler (Client) mit dem Server in Verbindung steht für ihn ein Sprite erstellt wird?
Erstmal danke für die Tipps.
Ich hab jetzt gerade kein PB zur Hand.
Ich will mal fragen ob es ginge wenn ich Auf rechts drücke das nicht so aussehen muss( und das für jeden Client anders(also 6 Clienten Programmieren in einem Code!)) ginge es so:

Code: Alles auswählen

If KeyboardPushed(#PB_Key_Left)
Spieler2x = Spieler2x + Cos(2*#PI*(rot/360))*0.1
Spieler2z = Spieler2z - Sin(2*#PI*(rot/360))*0.1
EndIf
; hab ich mir jetzt von einem Example abgeguckt(war für 3D Meshes( :könnte sein das ich einiges falsch geschrieben hat, aber aus dem Kopf :weiß ich das alles nicht 100%tig)
:So machen und das nur einmal:

If KeyboardPushed(#PB_Key_Left)
player\xPos = player\xPos + Cos(2*#PI*(rot/360))*0.1
player\zPos = player\zPos - Sin(2*#PI*(rot/360))*0.1
EndIf

;oder muss ich player1/... schreiben und dann für jeden Clienten eine :eigene Procedur?

Schonmal danke für die Antworten.
Außerdem hat sich schonmal jemand mit Collisionsabfragen auseinandergestzt und kann mir einen Tipps geben welche am besten für Kämpfe ist? (bsp. Fliegender Speer trifft Ritter)

.

Verfasst: 15.02.2007 18:46
von Kaeru Gaman
> Außerdem hat sich schonmal jemand mit Collisionsabfragen auseinandergestzt und kann mir einen Tipps geben welche am besten für Kämpfe ist?

ähm für was für ne oberfläche denn? 2D oder 3D?

für 2D: keine.

ob ein speer deinen kämpfer trifft oder nicht wird nicht per kollisionen ermittelt,
sondern bevor der speer fliegt wird ausgerechnet, ob und wie stark er treffen soll,
und dementsprechend wird das sprite bewegt.

bei nem ballergame kann man das mit kollisionen lösen, aber auch dort ist es besser,
angepasste koordinaten-checks zu verwenden anstatt die standard sprite-kollisionen.

Verfasst: 15.02.2007 18:54
von Pandorra
gut und was wäre die beste für ein 3D Spiel( würde ich gerne mal programmieren, hab nur leider keine Grafiken zum testen geschweige denn genug erfahrung)

Verfasst: 15.02.2007 18:57
von #NULL
@Pandorra
>> Benutze PB v 4.2
(signatur)
glaub ich nich' :wink:

Verfasst: 15.02.2007 19:11
von Pandorra
ups.
Ändere ich eben schnell.

Ich hab jetzt das Problem:

Code: Alles auswählen

 DisplayTransparentSprite(0 , ...)
; was soll ich das hinschreiben zweimal *newplayer???
Bin in einer halben Stunde an meinem PC.
Dort werde ich mal herumtüfteln.

Verfasst: 15.02.2007 21:30
von PMV
:allright: ZeHa ... sehr schönes Tut ... muss ich das ganze nicht
schreiben, ich hätte es eh nie mals so ausführlich gemacht :lol:

Naja gut ... weiter:

Code: Alles auswählen

For i = 0 To ... ;hier muss die Variable hin, in der du die Anzahl der Spieler gespeichert hast (-1 nicht vergessen!) 
   DispayTransparentSprite(0, *player\xPos, *player\yPos)
Next
Desweiteren hat dieses * die bedeutung eines Zeigers (Pointer). In PB
kann man ihn zwar für einfache Variablen (noch) weg lassen, aber es ist
sauberer, wenn du ihn nutzt. Das * gehört zudem zum Variablennamen.

Code: Alles auswählen

*pointer <> pointer.l
Das sind oben zwei komplet unterschiedliche Variablen!

Zu deinem Bewegenproblem, wenn du den Tipp von ZeHa nutzen willst,
und nur die Tastendrücke sendest, kannst du eine Prozedur schreiben,
die du für jeden Player aufrufen kannst. Dieser Prozedur übergibst du
einfach die Strukture mit *player(X), wobei X für die Playernummer
steht, oder du übergibst der Prozedur einfach nur die Playernummer.

Fürs zweite wäre das hier deine Prozedur

Code: Alles auswählen

Procedure MovePlayer(PlayerNr.l) 
*player(PlayerNr)\xPos + Cos(2*#PI*(rot/360))*0.1 
*player(PlayerNr\zPos - Sin(2*#PI*(rot/360))*0.1 
EndIf
MFG PMV