Ortwin1st
Mitglied
Hallo,
habe vor einiger Zeit ein kleines Jump'n'Run bzw. Think'n'Run Spiel geschrieben. Ein Eichhörnchen läuft durch den Wald, kann auf Bäume klettern und wie ein Maulwurf in Tunneln laufen. Über meine Map aus tiles habe ich eine durchsichtige Kollisionsmap aus unterschiedlichen Farben gelegt. Vor jeder Bewegung prüfe ich, auf welches Farbfeld das Eichhörnchen tritt und je nach Ergebnis entscheidet sich was passiert.
Die Kodierung:
- schwarz: Bewegung vertikal nach unten (Schwerkraft)
- weiß: Massiv, kann nicht auf weiße Felder laufen
- grün: Kann horizontal und vertikal nach oben und unten laufen
- rot: Tot, beendet level
- pink: Nur passierbar mit Schlüssel (verschlossene Tür)
Dabei messe ich insgesamt 6 Kollionspunkte: links und rechts, je oben, mitte, unten
Meine Kollisionsmethode:
Finde die Kollisionskontrolle insgesamt sehr hackelig. Meine Betatester hatten schon bemängelt, das es schwierig ist in horizontale Tunnels zu gehen. Deshalb habe ich nachträglich ein Funktionalität eingebaut, wenn der Kopf oben anstößt, das Eichhörnchen nach unten zu versetzen.
Aber wie kann ich die Funktion insgesamt optimieren?
habe vor einiger Zeit ein kleines Jump'n'Run bzw. Think'n'Run Spiel geschrieben. Ein Eichhörnchen läuft durch den Wald, kann auf Bäume klettern und wie ein Maulwurf in Tunneln laufen. Über meine Map aus tiles habe ich eine durchsichtige Kollisionsmap aus unterschiedlichen Farben gelegt. Vor jeder Bewegung prüfe ich, auf welches Farbfeld das Eichhörnchen tritt und je nach Ergebnis entscheidet sich was passiert.
Die Kodierung:
- schwarz: Bewegung vertikal nach unten (Schwerkraft)
- weiß: Massiv, kann nicht auf weiße Felder laufen
- grün: Kann horizontal und vertikal nach oben und unten laufen
- rot: Tot, beendet level
- pink: Nur passierbar mit Schlüssel (verschlossene Tür)
Dabei messe ich insgesamt 6 Kollionspunkte: links und rechts, je oben, mitte, unten
Meine Kollisionsmethode:
Code:
public void move(long delta) {
// Berücksichtigung der Durchlaufzeit (Framerate) garantiert gleichmäßige Bewegung
int newX = (int) (x + dx*(delta/1e9));
int newY = (int) (y + dy*(delta/1e9));
int offsetX = (int) (getWidth() * 0.3);
int offsetY = 20;
// Wenn Koordinaten außerhalb der Map, nimm alten Wert
if(newX<0 || newX+getWidth()>parent.getWidth() ||
newY<0 || newY+getHeight()>parent.getHeight())
return;
Color colLT = parent.getMap().getColorForPoint(new Point(newX+offsetX,newY+offsetY));
Color colRT = parent.getMap().getColorForPoint(new Point((int)(newX+getWidth()-offsetX),newY+offsetY));
Color colLM = parent.getMap().getColorForPoint(new Point(newX+offsetX,(int) (newY+(getHeight()/2))));
Color colRM = parent.getMap().getColorForPoint(new Point((int)(newX+getWidth()-offsetX),(int) (newY+(getHeight()/2))));
Color colLB = parent.getMap().getColorForPoint(new Point(newX+offsetX,(int)(newY+getHeight()-10)));
Color colRB = parent.getMap().getColorForPoint(new Point((int)(newX+getWidth()-offsetX),(int)(newY+getHeight()-10)));
Color colLB2 = parent.getMap().getColorForPoint(new Point(newX+offsetX,(int)(newY+getHeight()-5)));
Color colRB2 = parent.getMap().getColorForPoint(new Point((int)(newX+getWidth()-offsetX),(int)(newY+getHeight()-5)));
// Wenn Luft unter den Füßen und kein Boden unter den Füßen und oben nichts zum festhalten (hängen bleiben)
if(colLB.equals(Color.black) && colRB.equals(Color.black)
&& !(colLB2.equals(Color.white) || colRB2.equals(Color.white))
/*&& !(colLT.equals(Color.green) && colRT.equals(Color.green))*/) {
controlable = false;
setPics(bImgNorm);
} else {
controlable = true;
}
// Wenn Player sich nicht bewegt
if(dx==0 && dy ==0) {
setPics(bImgNorm);
}
if(dy>0) { // Kollisionskontrolle vertikal nach unten
// Wenn neue Koordinate über unterem Rand und nicht über weißen Pixeln
if(newY+getHeight()<parent.getHeight() && !(colLB.equals(Color.white) || colRB.equals(Color.white))) {
y = newY;
if(bImgUpDown!=null) setPics(bImgUpDown);
}
} else if (dy<0) { // Kollisionskontrolle vertikal nach oben // TODO: Bug, Player springt nach oben
if(newY>0 && !(colLT.equals(Color.white) || colRT.equals(Color.white))
&& !(colLB.equals(Color.black) || colRB.equals(Color.black))
&& (colLB.equals(Color.green) && colRB.equals(Color.green)
|| colLT.equals(Color.blue) || colRT.equals(Color.blue))) {
y = newY;
if(bImgUpDown!=null) setPics(bImgUpDown);
}
}
// Wenn X nicht über horizontale Ränder geht
if(dx>0 && !(colRB.equals(Color.white) || colRM.equals(Color.white))
&& (key || !colRB.equals(Color.magenta))) {
x = newX;
if(bImgRight!=null) setPics(bImgRight);
// Geschlossene Tür öffenen
if(colLB.equals(Color.magenta)&&key)
parent.changeTile(new Point((int) x, (int)y+offsetY), TILE_OPEN_WOODDOOR);
// Wenn Kopf rechts oben anstößt, setze automatisch nach unten
if(colRT.equals(Color.white)) y += offsetY*0.3;
} else if (dx<0 && !(colLB.equals(Color.white) || colLM.equals(Color.white))
&& (key || !colLB.equals(Color.magenta))) {
x = newX;
if (bImgLeft!=null) setPics(bImgLeft);
// Geschlossene Tür öffenen
if(colLB.equals(Color.magenta)&&key)
parent.changeTile(new Point((int) x, (int)y+offsetY), TILE_OPEN_WOODDOOR);
// Wenn Kopf links oben anstößt, setze automatisch nach unten
if(colLT.equals(Color.white)) y += offsetY*0.3;
}
// Wenn Player auf Rot tritt, GameOver
if(colLB.equals(Color.red) || colRB.equals(Color.red)) { // && !colLT.equals(Color.green) && !colRT.equals(Color.green)) {
parent.endGame(false, "Aua******");
}
}
Finde die Kollisionskontrolle insgesamt sehr hackelig. Meine Betatester hatten schon bemängelt, das es schwierig ist in horizontale Tunnels zu gehen. Deshalb habe ich nachträglich ein Funktionalität eingebaut, wenn der Kopf oben anstößt, das Eichhörnchen nach unten zu versetzen.
Aber wie kann ich die Funktion insgesamt optimieren?