Seite 2 von 2

Verfasst: Samstag 19. Dezember 2009, 16:34
von Dav1d
WCS für CSS?

Verfasst: Samstag 19. Dezember 2009, 21:47
von theliquidwave
Hi.
Ja, das ist eine "Spieler-in-Box" Abfrage. Das ganze funktioniert ohne min und max aber nicht :?
Eine Checkkugel ist nicht drin (was auch immer das bringen sollte?!) da die Boxen eckig sein MÜSSEN.

Wie würde denn eine kürzere Abfrage aussehen, die auch ohne min und max funktioniert? Bei mir geht das ganze nicht. Positionsangaben können (natürlich) auch negative Werte beinhalten!

Die 100ms sind nötig, da ich ein Checkpoint-Plugin realisieren möchte - alles andere ist zu ungenau (da auch die Zeit von einzelnen Checkpoints gespeichert wird, uvm.).

@ David: Nein, kein WCS - ich hasse das.

Gruß

Verfasst: Samstag 19. Dezember 2009, 21:59
von EyDu
Hallo.
Chrisber hat geschrieben:Ja, das ist eine "Spieler-in-Box" Abfrage. Das ganze funktioniert ohne min und max aber nicht :?
Wenn du es vernünftig machst, dann gilt immer position1 < position2. So einfach kommst du um min und max ;-)
Chrisber hat geschrieben:Eine Checkkugel ist nicht drin (was auch immer das bringen sollte?!) da die Boxen eckig sein MÜSSEN.

Nicht unbedingt. Wenn du die Größe der Kugel geschickt wählst, dann fällt es einem menschlichen Spieler eigentlich nicht auf, dass kein Rechteck verwendet wird. Das hängt allerdings ein wenig von der Größe des Rechtecks und der Bewegungsfreiheit des Spielers ab. Da musst du entscheiden, ob die Ungenauigkeit akzeptabel ist.

Verfasst: Samstag 19. Dezember 2009, 23:09
von theliquidwave
Ist sie nicht, da die Boxen eine genaue Höhe und Breite haben. Sie können unbegrenzt viele <Units> (Einheiten) groß sein.

Zur Überprüfung - wie darf ich das verstehen? Ich habe ja jeweils immer 3 X,Y,Z Werte:

1. Die Position des Spielers
2. Die erste Position der Box
3. Die zweite Position der Box

Folgende Abfrage funktioniert nicht (wenn ich's recht verstanden habe):

Code: Alles auswählen

if self.position1[0] <= player.position[0] <= self.position2[0] and self.position1[1] <= player.position[1] <= self.position2[1] and self.position1[2] <= player.position[2] <= self.position2[2]:
Gruß

Verfasst: Samstag 19. Dezember 2009, 23:24
von EyDu
Chrisber hat geschrieben:Folgende Abfrage funktioniert nicht (wenn ich's recht verstanden habe):

Code: Alles auswählen

if self.position1[0] <= player.position[0] <= self.position2[0] and ...
Doch, die sollte funktionieren. Es muss nur sichergestellt sein, dass alle Komponenten in position1 kleiner sind als in position2.

Verfasst: Samstag 19. Dezember 2009, 23:58
von theliquidwave
Ja das ist ja das Problem :P
Es kann ja sein, dass zum Beispiel position2[0] -200.36 hat und position1[0] 118.734. Aber einfach das negative zum positiven Wandeln geht ja auch nicht, da die Koordinate ja nicht umsonst negativ ist - denn die positive ist ja ganz wo anders. Wie lösen?

Gruß

Verfasst: Sonntag 20. Dezember 2009, 00:28
von EyDu
Du musst eben beim Erzeugen der Rechtecke dafür sorgen, dass diese Bedingung eingehalten wird. Negative Zahlen sind hier eigentlich irrelevant.

Verfasst: Sonntag 20. Dezember 2009, 00:31
von theliquidwave
Ich kann dafür nicht sorgen :?
Serveradmins sollen alles selber festlegen können und denen so etwas zu erklären ist verdammt schwer :/

Gruß

Verfasst: Sonntag 20. Dezember 2009, 00:53
von BlackJack
@Chrisber: Na dann musst Du eben dafür sorgen, dass denen entweder eine entsprechende Fehlermeldung präsentiert wird, oder eben beim Einlesen dieser Daten entsprechend umsortieren. Ich denke Dir geht's so um Geschwindigkeit, da sollte man diese Arbeit *einmal* machen und nicht bei *jedem* Test berücksichtigen müssen.

Verfasst: Sonntag 20. Dezember 2009, 00:53
von EyDu
Ok, wenn es global nicht geht, dann halt lokal:

Code: Alles auswählen

zipped = zip(position1, position2)
mins = map(min, zipped)
maxs = map(max, zipped)

if mins[0] <= position[0] <= maxs[0] and ...

#oder
if all(map(lambda (m, x, n): m <= x <= n, zip(mins, position, maxs))):

Verfasst: Sonntag 20. Dezember 2009, 03:22
von theliquidwave
@ BlackJack: Gute Idee :oops: Bin ich gar nicht drauf gekommen :lol:
@ EyDu: Danke. Werde ich morgen testen ;)

Gruß

Verfasst: Sonntag 20. Dezember 2009, 17:14
von Defnull
Das meinte ich übrigens auch mit: Du optimierst an der falschen Stelle. Du hast recht, das der Code in der Schleife schnell sein sollte, aber noch besser ist es, wenn er gar nicht in der Schleife ist. Sortiere die Ecken der Checkpoints einmal direkt im Konstruktor des Checkpoint-Objektes und du kannst dir das min() und max() in der Schleife sparen.

Zum ursprünglichen Problem: Jeder Spieler muss jeden Checkpoint nur einmal durchlaufen. Du hast also prinzipiell eine NxM Matrix für Spieler und Checkpoints mit True (für durchlaufen) und False (für nicht durchlaufen) und du möchtest verhindern, das Checkpoint-Spieler-Kombinationen geprüft werden, die bereits ein True in dieser Matrix haben.

a) Du pflegst diese Matrix und prüfst vor jedem Check, ob "checked[spieler-index][checkoint-index]" ein True enthält.
b) Du speicherst eine einfache Liste für jeden Spieler (oder eine für jeden Checkpoint) und checkst die.

Das geht deutlich schneller, als Slicing oder Listen-Manipulation.

Verfasst: Sonntag 20. Dezember 2009, 18:34
von theliquidwave
Problem ist aber, dass es auch mehrere Strecken für den "Parkour" geben kann. Es könnte also so aussehen:

Code: Alles auswählen

CP1 ------- CP2
  |
  |
  |
  |
CP3
Das ganze würde so also nicht funktionieren, da es sein kann, dass der Spieler den 1. Weg mit CP1 -> CP2 -> CP4 -> CPX nimmt.

Danke für die Tipps.

Gruß

Verfasst: Sonntag 20. Dezember 2009, 21:55
von Defnull
Versteh ich das richtig: Es gibt ein Netz von Checkpoints, die man nacheinander aktivieren muss, aber es gibt alternative Wege?

Dann würde ich für jeden Checkpoint speichern, welche Spieler ihn aktivieren können und welche Checkpoints frei geschaltet werden, sobald der aktuelle aktiviert wurde. Du beginnst das Spiel also mit einem Start-Checkpoint, auf den alle Spieler zugreifen können. Sobald jemand diesen Checkpoint erreicht, werden für diesen Spieler alle folgenden Checkpoints aktiviert und der aktuelle deaktiviert. Aktiviert jemand den Ziel-Checkpoint, passiert was tolles ;)

Code: Alles auswählen

for player in player_list:
  for checkpoint in checkpoint_list:
    if player.id in checkpoint.open_for \
    and check_collision(checkpoint, player):
      checkpoint.open_for.remove(player.id)
      print "Spieler %s erreicht Checkpoint %s" % player, checkpoint
      for nextcp in checkpoint.next_checkpoints:
        print "Nächster Checkpoint: %s" % nextcp
        nextcp.open_for.add(player.id)
      continue # Ein Spieler kann nur in einem Checkpoint gleichzeitig sein

Verfasst: Sonntag 20. Dezember 2009, 22:47
von theliquidwave
Erm - Geile Idee :)
Werde das morgen mal umsetzen und berichten :)

Danke!

Gruß