kostenloser Webspace werbefrei: lima-city


Kollisions Abfrage?

lima-cityForumDie eigene HomepageHTML, CSS & Javascript

  1. Autor dieses Themas

    krisi12345

    Kostenloser Webspace von krisi12345

    krisi12345 hat kostenlosen Webspace.

    Folgendes:
    Ich hab ein paar blöcke/quadrate die eine art level darstellen. Der Gegener muss später über die Blöcke springen bzw. vor ihnen stehenbleiben wenn er zu tief ist oder halt nicht springt. Das ganze kann man sich wie in Mario vorstellen (-;

    Wie kann ich diese Kollisionsabfrage effezient realisieren?
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. hab zwar keine ahnung von JS, aber du kannst doch die Koordinaten abfrage und wenn die gleich sind ist es eine Kollision, so mache ich es in Delphi.
  4. Hi,

    ich würde ein zwei-dimensionales Integer-Array erstellen. Das Array enthält die Informationen, wie dein Spielfeld aufgebaut ist.
    Dein Spielfeld besteht ja aus Blöcken. Jeder Block ist ein Eintrag im Array. Mit dem Wert "0" sagst du, dass "Mario" nicht durch diesen Block gehen darf. Mit "1" sagst du, dass Mario diesen Block betreten darf. Damit könntest du auch dynamische Spielfelder erzeugen, die du z.B. in einer Datei hinterlegst und einfach lädst.

    Was du nur machen musst ist folgendes: du musst immer wissen, wo "Mario" sich gerade befindet (in Pixel) und diese Position auf die Blöcke umrechnen. Wenn du weißt welcher Block das ist, dann kannst du in dein Array schauen, ob der Block betretbar ist oder nicht. Dementsprechend fängst du das per If-Abfrage ab und handelst dann (sprich: Mario durch diesen Block laufen lassen oder nicht).
  5. Kompliziertes Thema - vor allem bei komplexen Figuren. Solange du "nur" Rechteckige Blöcke hast, ist das ganze noch recht einfach. Für einen Block brauchst du zwei Koordinaten - (x1, y1) und (x2, y2). Die Kollisionskontrolle läuft dann so ab, dass du immer überprüfst, ob die Position des Spieler(x) > x1 && < x2, sowie Spieler(y) > y1 && < y2 ist. Wenn dem der Fall ist, findet eine Kollision statt.

    tangolals Idee mit dem Array finde ich zweckmäßig, auch wenn das Hinterlegen in einer Datei nun nicht zwingend die beste Variante ist. Wenn du die Welten per AJAX nachlädst, könntest du das ganze als SQL-Tabelle speicher, und ggf. als JSon-Objekt übergeben.

    Komplizierter wird es bei komplexeren Formen. Dort definierst du am besten Kreise, welche du in die Objekte legst und überprüfst dann, ob die Entfernung zum Kreismittelpunkt < als der Radius des jeweiligen Kreises ist.

    Also letztendlich würde ich die "Blöcke" immer als Objekte instanzieren und dann ein Objekt-Array erstellen. Jedes Objekt braucht da je nach Kollisions-Kontrolle (das "Block"-Verfahren oder das "Kreis"-Verfahren) immer die jeweiligen Werte, um das ganze zu überprüfen. Am einfachsten wäre das ganze, indem du dem Objekt einfach die Spieler-Position übergibst und dieses dann zurück liefert, ob eine Kollision stattfindet oder nicht. Dann brauchst du nur noch eine schleife zur Kollisionsprüfung, in der du allen Objekten die Spieler-Position übermittelst.
  6. Also letztendlich würde ich die "Blöcke" immer als Objekte instanzieren und dann ein Objekt-Array erstellen. Jedes Objekt braucht da je nach Kollisions-Kontrolle (das "Block"-Verfahren oder das "Kreis"-Verfahren) immer die jeweiligen Werte, um das ganze zu überprüfen. Am einfachsten wäre das ganze, indem du dem Objekt einfach die Spieler-Position übergibst und dieses dann zurück liefert, ob eine Kollision stattfindet oder nicht. Dann brauchst du nur noch eine schleife zur Kollisionsprüfung, in der du allen Objekten die Spieler-Position übermittelst.


    Ja, mach es am besten so wie nerdinator es beschrieben hat. Ist am einfachsten und auch flexibel, da du nicht an einem Raster gebunden bist.
    Habe ganz ausser Acht gelassen, dass JS auch objektorientierte Programmierung möglich ist. Mein Lösungsvorschlag verzichtet gänzlich auf die Objektorientierung und habe ich so irgendwann mal in C und QBasic realisiert (mit 16 Farben und VGA-Modus mit 640x480 Pixeln, das geht ab sage ich euch^^).
  7. Autor dieses Themas

    krisi12345

    Kostenloser Webspace von krisi12345

    krisi12345 hat kostenlosen Webspace.

    tangoal schrieb:
    Hi,

    ich würde ein zwei-dimensionales Integer-Array erstellen. Das Array enthält die Informationen, wie dein Spielfeld aufgebaut ist.
    Dein Spielfeld besteht ja aus Blöcken. Jeder Block ist ein Eintrag im Array. Mit dem Wert "0" sagst du, dass "Mario" nicht durch diesen Block gehen darf. Mit "1" sagst du, dass Mario diesen Block betreten darf. Damit könntest du auch dynamische Spielfelder erzeugen, die du z.B. in einer Datei hinterlegst und einfach lädst.

    Was du nur machen musst ist folgendes: du musst immer wissen, wo "Mario" sich gerade befindet (in Pixel) und diese Position auf die Blöcke umrechnen. Wenn du weißt welcher Block das ist, dann kannst du in dein Array schauen, ob der Block betretbar ist oder nicht. Dementsprechend fängst du das per If-Abfrage ab und handelst dann (sprich: Mario durch diesen Block laufen lassen oder nicht).

    OK, ich hab jetzt ne andere Methode probiert, die geht aber nicht richtig.
    Deswegen versuch ich mal deine, aber:
    Mein "Block-Level" besteht nicht aus einem art 1 oder 0 Raster sondern aus den Position der Blöcke die dann mit ihrer "Bildgröße" multipliziert werden. Praktisch ist diese Methode aber nur beim Rendern der Blöcke.

    Wenn ich deine Methode jetzt richtig verstanden soll ich eine Array machen der eine Art raster enthält also z.B. (0,0,0,0,1,1,1,0,0) in diesem Fall dann eine 3 Blöcke große Fläche darstellt. Dazu kommt dann noch ein Array für die Z bzw. Y Position (ist ja 2D). Und nach jeder Bewegung von dem Player wird abgefragt welche Punkte der Spieler in diesem Raster füllt und ob ein Hinderniss in seiner Bahn ist.

    Ist das so Richtig???

    Und was Nerdinator schreibt ist schon richtig aber wir reden hier von Javascript! Das jeder Block das in jedem "Frame" selber macht würde manche Browser wohl überlasten

    Edit: ich würd sagen das ich meine alte Methode mit den Positionen Array einfach in eine Art Kollisions Array umrechnen lasse sobald das Script gestartet wird.

    Beitrag zuletzt geändert: 6.6.2010 20:52:06 von krisi12345
  8. function worldObject(x, y, width, height){
    	this.x1 = x;
    	this.y1 = y;
    	this.x2 = x + width;
    	this.y2 = y + height;
    	this.getCollision = function(x,y){
    		var result = false;
    		if((x >= this.x1)&&(x <= this.x2)&&(y >= this.y1)&&(y <= this.y2)) result = true;
    		return result;
    		}
    	}
    var Block = new Array();
    var Block[0] = new worldObject(100,100,100,100);
    
    function main(){
    	alert Block[0].getCollision(105,105);
    	}
    So sollte das ganze im groben und ganzen funktionieren. Über Block[x] = new worldObject(x,y, breite,höhe); instanzierst du ein neues "Objekt" im Raum. Dies kannst du praktisch gleichzeitig machen, wo du es "lädst". Block[x].getCollision(PlayerX, PlayerY) sollte dir dann true zurück geben, wenn eine Kollision vorliegt. Dies funktioniert vorerst nur bei Rechteckigen Objekten.

    tangoal schrieb:
    und habe ich so irgendwann mal in C und QBasic realisiert (mit 16 Farben und VGA-Modus mit 640x480 Pixeln, das geht ab sage ich euch^^).
    Also bei Qbasic kannst du das ganz einfach machen, indem du benutzerdefinierte Typen nimmst und ein Array als solchen definierst. ;-)
  9. Autor dieses Themas

    krisi12345

    Kostenloser Webspace von krisi12345

    krisi12345 hat kostenlosen Webspace.

    nerdinator schrieb:
    function worldObject(x, y, width, height){
    	this.x1 = x;
    	this.y1 = y;
    	this.x2 = x + width;
    	this.y2 = y + height;
    	this.getCollision = function(x,y){
    		var result = false;
    		if((x >= this.x1)&&(x <= this.x2)&&(y >= this.y1)&&(y <= this.y2)) result = true;
    		return result;
    		}
    	}
    var Block = new Array();
    var Block[0] = new worldObject(100,100,100,100);
    
    function main(){
    	alert Block[0].getCollision(105,105);
    	}
    So sollte das ganze im groben und ganzen funktionieren. Über Block[x] = new worldObject(x,y, breite,höhe); instanzierst du ein neues "Objekt" im Raum. Dies kannst du praktisch gleichzeitig machen, wo du es "lädst". Block[x].getCollision(PlayerX, PlayerY) sollte dir dann true zurück geben, wenn eine Kollision vorliegt. Dies funktioniert vorerst nur bei Rechteckigen Objekten.

    tangoal schrieb:
    und habe ich so irgendwann mal in C und QBasic realisiert (mit 16 Farben und VGA-Modus mit 640x480 Pixeln, das geht ab sage ich euch^^).
    Also bei Qbasic kannst du das ganz einfach machen, indem du benutzerdefinierte Typen nimmst und ein Array als solchen definierst. ;-)

    das Problem ist das das ganze ja eine Art Game werden soll. Der gepostete Code wird also mehrmals in der Sekunde ausgeführt.
  10. krisi12345 schrieb: das Problem ist das das ganze ja eine Art Game werden soll. Der gepostete Code wird also mehrmals in der Sekunde ausgeführt.

    Der Code muss eigentlich nur aufgerufen werden, wenn sich die Spielfigur bewegt oder das Spielfeld ändert. Auch wenn dies öfter geschehen sollte, würde ich vorschlagen es erstmal auszuprobieren.
    Wenn die Berechnungen den Spielfluss stören, dann könntest du noch überlegen die Berechnungen in einem eigenem Thread laufen zu lassen. Hab z.B. hier was gefunden dazu.
  11. krisi12345 schrieb:
    das Problem ist das das ganze ja eine Art Game werden soll. Der gepostete Code wird also mehrmals in der Sekunde ausgeführt.
    Genau deshalb bietet sich Objekt-Orientierung an. Alle anderen Verfahren wären wahrscheinlich langsamer. Am zügigsten ließe sich das wahrscheinlich aufbauen, wenn du das ganze Spiel OOP aufbaust.

    Nun werden pro Sekunde nur für jeden Block die aktuellen Koordinaten abgefragt - also bei einer abfrage wird der code
    var result = false;
    if((x >= this.x1)&&(x <= this.x2)&&(y >= this.y1)&&(y <= this.y2)) result = true;
    return result;
    ausgeführt. Sehr viel einfacher wirste das nicht hinbekommen. Du kannst das ganze ja mal testweise ausprobieren - 100 Arrays dimensionieren, die Block-Positionen eintragen und dann losrechnen. Der arbeitet dir locker die 100 Arrays in wenigen mikrosekunden durch.

    Ich weiss nicht, wie du es bisher aufgebaut hast. Am Ende kannst du das ganze noch beschleunigen, indem du ein Width-of-view-Array machst - soll heissen, dass nur die "nahegelegensten Arrays" verglichen werden. Aber alles was du sonst anstellen kannst, wird wahrscheinlich mehr Rechenzeit verbrauchen, wäre also langsamer. Praktisch jede Kollisionskontrolle in den ganzen "großen" Spielen arbeitet genau so.
  12. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!