2D Schwerkraft bei mehreren Platformen

Status
Nicht offen für weitere Antworten.

raven

Bekanntes Mitglied
Hallo...
Ich kniffle seit einer Weile schon ein meinem Problem herum, bekomm aber keinen akzeptablen Lösungsansatz. Anfangs dachte ich nur... Ah teste ich einfach mal ob X < platform.x || x > platform.x+platform.w, dann fallen lassen, ansonsten halt stehen bleiben.
Dies Funktioniert bei mir, wenn ich nur ein Platform habe. Jedoch nicht wenn ich 2 oder mehrere habe. Nämlich da tritt das Problem auf, das zwei Plattformen untereinander liegen können. Und somit auch der x wert innerhalb der beiden Plattformen liegen kann. Ja nun ist mein Problem wie entscheide cih bis zu welcher Plattform meine Figur fallen soll.
Ich speichere meine Plattform in einen Array. Jedes Plattform-Objekt repräsentiert ein Rechteck. Sprich also x, y, w, h. Mit denen ich es auch zeichne...
Ich hoffe ich habe mein Problem gut genug beschrieben. Weiß ncith ob cih versteht was mein Problem ist.

mfg raven
 

0x7F800000

Top Contributor
Code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class JumpNRunCollisionDetection extends JApplet implements MouseMotionListener{
	private class Plattform{
		double left,right,height;
		public Plattform(double l,double r,double h){
			left=l; right=r; height=h;
		}
		public boolean isUnderPoint(double x, double y){
			return left<=x && x<=right && y>=height;
		}
	}
	
	Plattform[] plattforms;
	final Plattform nirvana=new Plattform(Double.NEGATIVE_INFINITY,Double.POSITIVE_INFINITY,Double.NEGATIVE_INFINITY);
	final double[] playerCoords=new double[2];
	
	private Plattform getSubjacentPlattform(double[] point){
		Plattform result=nirvana;	//das große nichts faengt alles auf
		for(Plattform p:plattforms){
			if(p.isUnderPoint(point[0],point[1]) && p.height>result.height){
				result=p;
			}
		}
		return result;
	}
	
	public void init(){
		plattforms=new Plattform[100];
		for(int i=0; i<plattforms.length; i++){
			double x;
			plattforms[i]=new Plattform(x=Math.random()-0.01,x+Math.random()*0.05,Math.random());
		}
		addMouseMotionListener(this);
	}

	@Override
	public void paint(Graphics g){
		g.setColor(Color.BLACK);
		g.fillRect(0,0,getWidth(),getHeight());
		
		g.setColor(Color.GREEN);
		for(Plattform p:plattforms){
			g.drawLine(	(int)(p.left*getWidth()),	(int)(p.height*getHeight()),
						(int)(p.right*getWidth()),	(int)(p.height*getHeight()));
		}
		
		g.setColor(Color.RED);
		Plattform p=getSubjacentPlattform(playerCoords);
		g.drawLine(	(int)(playerCoords[0]*getWidth()),	(int)(playerCoords[1]*getHeight()),
					(int)(playerCoords[0]*getWidth()),	(int)(p.height*getHeight()));
	}
	
	@Override
	public void mouseDragged(MouseEvent _) {}
	@Override
	public void mouseMoved(MouseEvent e) {
		playerCoords[0]=e.getX()/(double)getWidth();
		playerCoords[1]=e.getY()/(double)getHeight();
		repaint();
	}
	
	
}
kA was daran jetzt sooo problematisch sein soll, du willst deine code ja nich posten... :roll:
ist doch eine recht öde fingerübung, solang's man nicht zu gut machen will. Man kann die dinger natürlich irgendwie toll sortieren und in Bäume unterteilen, aber bei wenigen plattformen läuft's doch auch mit den trivialen < > operatoren... ???:L
 

raven

Bekanntes Mitglied
ja dank erstmal für deine Mühe. aba ganz blicke ich bei dein Code nicht durch. warum machst du was mit ousListener?
udn was bedeutet das left udn right.?
 

Developer_X

Top Contributor
alles durchlesen, dann wirst dus ´verstehen, glaub mir vincent
und bitte leg diesen Dienstag eine Super Show in Uri Geller auf Prosieben hin ok?
Kannst du mir mit meinen Problemen aus der Anderswelt helfen?

Lol

der macht das mit ouslistener wahrscheinlich aus einem bestimmten grund
 

0x7F800000

Top Contributor
ääähm... Hast du dir denn angeguggt was es tut? ???:L

EDIT @DeveloperX: geht's noch? -.-
der hat's doch tatsächlich mit dem 17x19 meter gemälde umgesetzt, ich glaub's nich^^

EDIT2: @DeveloperX: okay, schnell reagiert... Danke^^
Okay, dann wäre das problem mit dem bild behoben. Könntest du evtl noch in einem zusammenhängenden Satz erklären, was du hier eigentlich loswerden wolltest?
 

raven

Bekanntes Mitglied
Code:
if(stand == false) {
			for(int i = 0; i < game.objects.length; i++) {
				if(x+w > game.objects[i].x && x < game.objects[i].x+game.objects[i].w) {
					if(y+h < game.objects[i].y) {
						y++;
					} else {
						stand = true;
						y = game.objects[i].y-h;
					}
				}

				if(x+w < game.objects[i].x && x < game.objects[i].x+game.objects[i].w) {
					y++;
				}
			}
		}

das ist mein ansatz... also die abfrage im Player object...natürlich funktioniert meins nicht...
so in entwa hatte ich mir das vorgestellt um zu testen, wann der figur(in mein fall 25x25 rechteck) fallen soll...
 

Steev

Bekanntes Mitglied
Ich überprüfe bei so etwas immer nur einen Pixel darauf, ob er innerhalb einer Platform liegt oder nicht. Diesen Pixel "befestige" ich mittig unter der Spielfigur.

In etwa kann man das so umsetzen:

1. Position der Spielfigur ermitteln
2. Position des Pixels berechnen (Figur.x + (Figur.W / 2.), Figur.y + Figur.H)
3. Überprüfen ob der Pixel innerhalb einer Platform liegt (isInside oder ähnlich, schreibe dir hierfür eine Klasse für deine Platform und gebe der Platform dann entsprechende Daten wie x, y, W, H usw. mit. Auserdem braucht die Klasse eine Methode mit der du überprüfen kannst, ob ein Pixel innerhalb oder auserhalb des Rechtecks liegt. Alternativ kannst du dafür auch die Klasse Rectangle verwenden.)

Jetzt muss du nur noch pro Rendervorgang überprüfen, ob eine Kollision vorliegt. Liegt eine Kollision vor, so wird der Spieler so lange nach oben geschoben, bis keine Kollision mehr vorliegt. Damit verhinderst du, dass der Spieler in einer Platform rumlaufen kann. Liegt keine Kollision vor, so verschiebst du deinen Spieler nach unten.

Der Vorteil von dieser Pixelüberprüfung ist, dass der Spieler zum Beispiel mit dem Kopf in eine Andere Platform springen kann, ohne dass dann mit dieser Platform eine Kollision hervorgerufen wird.
 

raven

Bekanntes Mitglied
danke! dein ansatz aht mir schon sehr viel weiter geholfen...Meine PlayerObject fällt nun auch. Nur mein bsiheriges Problem besteht trotzdem noch. wenn sich zwei Platformen genau untereinander befinden. fällt mein PlayerObject doppelt so schnell weil er ja beide Platformen behandelt udn er fällt durch die erste durch. udn bleibt dann auch der zweiten stehn. Ich hab verscuh dies irgendwie zu umgehen, aber hab bis jetzt noch keine lösung gefunden die dies behebt.

// PlayerObject
Code:
for(int i = 0; i < game.objects.length; i++) {
				int containsTest = game.objects[i].isContain(x+w/2, y+h);
				if(containsTest == 1) {
					y--;
				} else {
					if(containsTest != 0)
						y++;
				}
}

// PlatformObject
Code:
public int isContain(int xTest, int yTest) {
		Rectangle containsTest = new Rectangle(x, y, w,h);
		if(containsTest.contains(xTest, yTest)) {
			if(yTest == y) {
				return 0;
			} else {
				return 1;
			}
		} else {
			return 2;
		}
	}
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben