Netzwerk

Anfängerfragen zum Programmieren mit PureBasic.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

@ZeHa
is richtig... mach ihm n beispiel... ;)
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag 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: )
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

[OT]

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

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

:lol:

[/OT]
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Pandorra
Beiträge: 124
Registriert: 10.02.2007 12:15

Beitrag 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)

.
Benutze PB v 4.40 Beta 3
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Pandorra
Beiträge: 124
Registriert: 10.02.2007 12:15

Beitrag 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)
Benutze PB v 4.40 Beta 3
Benutzeravatar
#NULL
Beiträge: 2238
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

@Pandorra
>> Benutze PB v 4.2
(signatur)
glaub ich nich' :wink:
my pb stuff..
Bild..jedenfalls war das mal so.
Pandorra
Beiträge: 124
Registriert: 10.02.2007 12:15

Beitrag 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.
Benutze PB v 4.40 Beta 3
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag 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
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Antworten