Bewegung zum Client senden

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
INFACT
User
Beiträge: 385
Registriert: Freitag 5. Dezember 2008, 16:08

Hi,

Ich programmiere gerade ein einem online role play game und wollte mir mal hier Programmier empfehlungen holen.
Bei meinem Spiel gibt es einen Spieler, den man selbst kontrolliert, und andere Spieler oder NPCs ( Not playable Chars ), die sich bewegen können.
Ich möchte, dass, wenn ich ein NPC oder so bewegt, die neue Position an den Client ( mich ) gesendet wird. Weil die NPCs nicht zu einer Position "springen" sonder sich langsam bewegen, gibt es ganz viele Positionen, die der NPC erreichen wird.
Ich möchte aber auch nicht, dass die neue Position gesendet wird, wenn der NPC am Ziel angekommen ist. Das währe dann zu spät.
Wie würdet ihr das machen, dass die Position gesendet wird?
Ich hatte auch noch die Idee, dass man das Ziel senden könnte und dann Client und Server parralel die aktuelle position ausrechnen könnten. Dabei gibt es aber das "problem", dass ich die genaue geschwindigkeit nicht kenne. Die müsste ich dann ausrechnen lassen.

Freue mich auf Ideen
[b][i]ein kleines game für die die lust haben http://konaminut.mybrute.com[/i][/b]
;-)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Halo.

Ich gehe mal davon aus, dass es sich um Übertragung in Netzwerken handelt, obwohl es dafür ein eigenes Unterforum gibt ;-)

Am einfachsten ist es, wenn du dir die Position, die Geschwindigkeit und ggf. noch die Beschleunigung k-mal in der Sekunde zugeschickt bekommst und dazwischen einfach Extrapolierst. Dann kann auch mal die ein oder andere Position verloren gehen.

Sebastian
Das Leben ist wie ein Tennisball.
INFACT
User
Beiträge: 385
Registriert: Freitag 5. Dezember 2008, 16:08

Danke.

Es geht um übertragungen im Internet. Hätte ich vielleicht dazu schreiben solllen :roll:

Bei mir geht aber nichts verloren. Ich benutze TCP. Soll ich lieber UDP verwenden?

Edit: Oh, aber jetzt kann ich es nicht mehr verschieben. Wenn das bitte ein Mod übernehmen würde
[b][i]ein kleines game für die die lust haben http://konaminut.mybrute.com[/i][/b]
;-)
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Einfach nur "online role play game" ist total unterspezifiziert für das Problem. Da ist es schwer, etwas zu raten (in beiden Wortsinnen).

Dein größtes Problem ist wahrscheinlich der "lag", also die Verzögerung, die entsteht, wenn jede Aktion des Spielers eine Kommunikation mit dem Server erfordert. Doch nur ein Roundtrip über den Server kann sicherstellen, dass niemand schummelt.

Ich hatte mal gelesen, dass bei Age of Empire oder Warcraft (ich weiß nicht mehr genau) der Client nach einem Klick auf eine Position auf der Karte, wo sich dann eine Einheit hinbewegen soll, nicht sofort mit der Bewegung beginnt, sondern einen Moment wartet, der wahrscheinlich groß genug ist, dass die anderen Clients die Information, dass sich Spielfigur X auf Position Y bewegen soll, ebenfalls erhalten haben, und sie scheinbar alle gleichzeitig bewegt werden. Außerdem überschlägt der Server, wann die Figur am Ziel sein müsste und teilt dies allen Clients mit. Diese können dann die Figur schneller oder langsamer bewegen, je nachdem wann sie erfahren, dass sie sie bewegen sollen.

Ansonsten entspricht die Client-Server-Kommunikation im Prinzip einem Chat. Und ich würde auch erst mal davon ausgehen, das es reicht, hier einfach per TCP/IP und Textnachrichten zu kommunizieren. Erst wenn du Hunderte oder Tausende von Spielern parallel in einer Spielwelt verwalten willst, wirst du Probleme bekommen. Dafür würde ich aber ehrlich gesagt auch nicht Python benutzen -- Java (bzw. die JVM und dann vielleicht auch Scala oder Clojure) wäre für mich hier der Kompromiss aus Performance und Programmierkomfort.

Sollte es webbasiert sein, wird auch Python reichen. Ein Comet-artiges auf long-polling basiertes Chat-System per HTTP ist hier bestimmt das größte Bottleneck. Möglicherweise sollte man dann gleich auf Websockets setzen, auch wenn das IE-Benutzer (zu recht) ausschließt und nur mit Chrome und Firefox 4 (ehemals 3.7) funktioniert. Für Ruby hatte ich neulich eine vielleicht 150 Zeilen lange Implementierung eines Websocket-Servers (basierend auf EventMachine) gesehen, die auch noch eine Anbindung an Redis enthielt, das müsste man eigentlich auch in Python (vielleicht mit Tornado?) realisieren können.

Stefan
INFACT
User
Beiträge: 385
Registriert: Freitag 5. Dezember 2008, 16:08

Also man hat einen Spieler, den man mit mausklicks oder den pfeiltasten bewegen kann. Bei mausklicks würde das ja wie be warcraft gehen, aber bei den Pfeiltasten weiß man ja nicht wo der spieler aufhört diese zu drücken, also wo der spieler landen wird.

Webbasiert heißt ein Browser game oder?
Ne, das hatte ich nicht vor. Eher so was ähnliches wie WoW, oder RoM.
[b][i]ein kleines game für die die lust haben http://konaminut.mybrute.com[/i][/b]
;-)
INFACT
User
Beiträge: 385
Registriert: Freitag 5. Dezember 2008, 16:08

Ich glaube ich mache das so, dass ich immer die Position ( zur ev. Fehlerkorrektur ) Richtung und die Geschwindigkeit sende, wenn die sich ändert oder der Char aufhört zu laufen.

Irgentwelche Einwände / Verbesserungsvorschläge
[b][i]ein kleines game für die die lust haben http://konaminut.mybrute.com[/i][/b]
;-)
INFACT
User
Beiträge: 385
Registriert: Freitag 5. Dezember 2008, 16:08

Ich hab einfach mal angefangen sowas zu programmieren.

Code: Alles auswählen

import math

def getPositionOnHypotenuse(posNow, directionPos, near):
    """
        Ermittelt mit Hilfe von Pythagoras
        die genaue Position von posNow in Richtung
        directionPos. Near ist wie weit die Position
        von posNow ( in Richtung directionPos ) weg ist.
    """
    absx = abs(posNow[0] - directionPos[0])
    absy = abs(posNow[1] - directionPos[1])
    abstand = math.sqrt(absx**2 + absy**2)
    verh = float(near) / abstand
    rmx = absx * verh
    rmy = absy * verh

    x, y = directionPos

    if (posNow[0] - x) > 0:
        rx = posNow[0] - rmx
    else:
        rx = posNow[0] + rmx

    if (posNow[1] - y) > 0:
        ry = posNow[1] - rmy
    else:
        ry = posNow[1] + rmy
    return [rx, ry]


def generateNextPos(startPos, t, steigung, richtung="or"):
    """
        Generiert die Nachste Position,
        die neue position ist t von startPos
        entfernt und hat die verhaltnissteigung
        von steigung ( lineare Funktion )
        richtung kann:
            ol : Oben Links
            ul : Unten Links
            or : Oben Rechts
            ur : Unten Rechts
        sein.
    """
    if not richtung in ("ol", "ul",
                        "or", "ur"):
        raise ValueError, ("richtung "+ richtung)
    x, y = startPos

    e1 = t * steigung
    if richtung[1] == "r":
        e1 = x + t
    else:
        e1 = x - t

    if richtung[0] == "o":
        e2 = y + t*steigung
    else:
        e2 = y - t*steigung
    """if steigung > 0:
        e1 += t
        e2 = t + y
    else:
        e1 -= t
        print t, y
        e2 = y - t
        print e2"""
    #e2 = t + y
    #if steigung < 0:
    #    e2 = -e2
    print e1, e2
    pos = getPositionOnHypotenuse((x,y), (e1, e2), t)
    return pos
Damit kann man mit der steigung, der aktuellen Position, und der schnelligkeit (wie weit der gehen soll) die nächste position ausrechnen

Edit: Oh ich glaube da ist noch ein Fehler drin
Edit2: Ich weiß nicht ob das anders geht mit dem ob, ul usw. aber ich hab das einfach so gemacht.
Fertig
Zuletzt geändert von INFACT am Donnerstag 13. Mai 2010, 14:41, insgesamt 1-mal geändert.
[b][i]ein kleines game für die die lust haben http://konaminut.mybrute.com[/i][/b]
;-)
rads
User
Beiträge: 153
Registriert: Freitag 26. März 2010, 15:51

Hi, ich bin zwar aus der Java/C Ecke, aber sowas schreit nach meiner Meinung nach einem Observer-Pattern.
Wenn du das hier in der Forum suche eingibst solltest du schnell fündig werden, ich dachte gestern hier sowas gesehen zu haben.

Kurzprinziep.

Die Clients/Views registrieren sich bei einem Observer. Der Observer überwacht die Daten typischerweise Modell (Ja ein MVC Pattern ist hier natürlich sehr praktisch, wie quasi immer) .
Ändert jetzt die Control etwas am Modell bekommt das der Observer mit und teilt dies seinem
Schäfchen also den listenern mit.
Sowas kann man selber implementieren, was man nicht zwangsläufig machen sollte, oder die
oft schon vorhandenen Api Klassen verwenden (kenne hier allerdings nur die Java Variante)

Grüße
INFACT
User
Beiträge: 385
Registriert: Freitag 5. Dezember 2008, 16:08

so wie ich das jetzt verstehe habe ich das selber schon programmiert.
Ich habe das aber etwas erweitert, damit mach auch sachen nur an einen einzigen client senden kann.
[b][i]ein kleines game für die die lust haben http://konaminut.mybrute.com[/i][/b]
;-)
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

INFACT hat geschrieben:Also man hat einen Spieler, den man mit mausklicks oder den pfeiltasten bewegen kann.
Damit hast du immer noch nicht genauer definiert, was du dir unter einem RPG vorstellst und wie Client und Server zusammenarbeiten sollen. Wenn der Client eine Karte anzeigt und der Spieler dort eine Zielposition anklicken kann, dann kann diese zum Server übermittelt werden und von dort zu anderen Clients verteilt werden -- oder auch nicht. Denkbar wäre, dass Clients direkt miteinander sprechen oder das der Client selbst entscheidet, ob und wie eine Spielfigur die Zielposition erreicht.
INFACT hat geschrieben:Webbasiert heißt ein Browser game oder?
Ja, ich meinte, das ganze könnte in einem Browser ablaufen. Wenn es nicht gerade 3D sein soll, ist IMHO ein moderner Browser eine gute Basis, um einfach und bequem ein 2D oder 2½D Spiel zu bauen. Zudem läuft es dann gleich überall, wo auch Firefox oder Chrome laufen und man hat keine Probleme, irgendwelche EXE-Dinger bauen zu müssen und dabei Quelltext zu verstecken. Wenn es unbedingt ohne Browser laufen muss, gibt es noch AIR oder Titanium oder man bindet selbst in Wx oder Qt ein Webkit-Widget ein.

Aber vielleicht denke ich auch bei Rollenspiel an meine Jugend und nicht an das, was heute aktuell ist ;)

Stefan
Antworten