2010-11-24 2 views
0

Très bien, alors j'essaie de faire un moteur de plate-forme rapide et sale, et j'ai quelques problèmes avec mes plates-formes de détection de collision et de déplacement. D'une part, le «joueur» semble légèrement rebondir sur les plates-formes en mouvement, et lorsqu'il touche le côté droit, des erreurs se produisent également. Je vais télécharger une démo jnlp afin que vous puissiez essayer de trouver plus d'erreurs et de voir ce qu'il se passe, mais voici la source:Plate-forme rapide et sale avec la physique a des erreurs avec les plates-formes mobiles

import java.awt.Rectangle; 
import java.util.Vector; 

import org.newdawn.slick.AppGameContainer; 
import org.newdawn.slick.BasicGame; 
import org.newdawn.slick.Color; 
import org.newdawn.slick.GameContainer; 
import org.newdawn.slick.Graphics; 
import org.newdawn.slick.Input; 
import org.newdawn.slick.SlickException; 


public class Platformer extends BasicGame{ 

boolean keys[]; 
int ALL_KEYS = 0xFF; 
Player player; 
Vector<Vector<Thing> > things; 
int level = 0; 

public Platformer() { 
    super("You've met with a terrible fate, haven't you?"); 
} 

public void init(GameContainer gc) throws SlickException { 
    keys = new boolean[ALL_KEYS]; 
    for(int i = 0; i < ALL_KEYS; i++){ 
    keys[i] = false; 
    } 

    player = new Player(); 
    things = new Vector<Vector<Thing> >(); 
    Vector<Thing> temp = new Vector<Thing>(); 
    temp.add(new Thing(0, 440, 640, 40, 1)); 
    temp.add(new Thing(200, 300, 240, 50, 1)); 
    temp.add(new Thing(500, 200, 240, 50, 1)); 

    things.add(temp); 
} 

public void update(GameContainer gc, int delta) throws SlickException{ 
    if(keys[Input.KEY_UP]){ 
    player.velo = player.maxJump; 
    keys[Input.KEY_UP] = false; 
    } 

    if(keys[Input.KEY_DOWN]){ 
    keys[Input.KEY_DOWN] = false; 
    } 

    if(keys[Input.KEY_LEFT]){ 
    player.delta -= player.speed; 

    if(player.delta < -player.maxSpeed) 
    player.delta = -player.maxSpeed; 
    } 

    else if(keys[Input.KEY_RIGHT]){ 
    player.delta += player.speed; 

    if(player.delta > player.maxSpeed) 
    player.delta = player.maxSpeed; 
    } 

    else{ 
    if(player.delta < -0.5){ 
    player.delta += player.speed; 
    } 

    else if(player.delta > 0.5){ 
    player.delta -= player.speed; 
    } 

    else if(player.delta > -0.5 && player.delta < 0.5){ 
    player.delta = 0; 
    } 
    } 

    if(player.delta < 0) 
    player.moveLeft(things.get(level)); 

    else if(player.delta > 0) 
    player.moveRight(things.get(level)); 

    if(player.velo < 0) 
    player.moveUp(things.get(level)); 

    else 
    player.moveDown(things.get(level)); 


    things.get(level).get(1).moveRight(player, things.get(level)); 

} 

public void render(GameContainer gc, Graphics g) throws SlickException{ 
    g.setColor(new Color(0,55,55)); 
    g.fillRect(0, 0, 640, 480); 

    g.setColor(new Color(255,0,0)); 
    g.fillRect(player.x, player.y, player.width, player.height); 

    for(int i = 0; i < things.get(level).size(); i++){ 
    if(things.get(level).get(i).type == 1) 
    g.setColor(new Color(0,100,100)); 

    g.fillRect(things.get(level).get(i).x, things.get(level).get(i).y,things.get(level).get(i).width, things.get(level).get(i).height); 
    } 
} 

public void keyPressed(int key, char c) { 
    keys[key] = true; 
} 

public void keyReleased(int key, char c) { 
    keys[key] = false; 
} 

public static void main(String[] args) throws SlickException{ 
    AppGameContainer app = 
    new AppGameContainer(new Platformer()); 

    app.setShowFPS(false); 
    app.setAlwaysRender(true); 
    app.setTargetFrameRate(60); 
    app.setDisplayMode(640, 480, false); 
    app.start(); 
} 


class Player{ 
    float x = 50; 
    float y = 50; 

    float delta = 0; // x momentum 
    float velo = 0; 
    int height = 50; 
    int width = 30; 
    float speed = 0.2f; 
    int maxSpeed = 6; 
    int maxFallSpeed = 5; 
    int maxJump = -8; 

    public void moveLeft(Vector<Thing> things){ 
    x += delta; 

    if(x < 0) 
    x = 0; 

    for(int i = 0; i < things.size(); i++){ 
    if(new Rectangle((int) x, (int) y, width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){ 
    x += (things.get(i).x + things.get(i).width) - x; 
    delta = 0; 
    } 
    } 
    } 

    public void moveRight(Vector<Thing> things){ 
    x += delta; 

    if(x + width > 640) 
    x = (640 - width); 

    for(int i = 0; i < things.size(); i++){ 
    if(new Rectangle((int) x, (int) y, width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){ 
    x -= (x + width) - things.get(i).x; 
    delta = 0; 
    } 
    } 
    } 

    public void moveLeftWithThing(Vector<Thing> things, float thingSpeed){ 
    x -= thingSpeed; 

    if(x < 0) 
    x = 0; 

    for(int i = 0; i < things.size(); i++){ 
    if(new Rectangle((int) x, (int) y, width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){ 
    x += (things.get(i).x + things.get(i).width) - x; 
    delta = 0; 
    } 
    } 
    } 

    public void moveRightWithThing(Vector<Thing> things, float thingSpeed){ 
    x += thingSpeed; 

    if(x + width > 640) 
    x = (640 - width); 

    for(int i = 0; i < things.size(); i++){ 
    if(new Rectangle((int) x, (int) y, width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){ 
    x -= (x + width) - things.get(i).x; 
    delta = 0; 
    } 
    } 
    } 

    public void moveUp(Vector<Thing> things){ 
    y += velo; 

    velo += speed; 

    if(velo > maxFallSpeed) 
    velo = maxFallSpeed; 

    for(int i = 0; i < things.size(); i++){ 
    if(new Rectangle((int) x, (int) y, width, height/2).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){ 
    y += (things.get(i).y + things.get(i).height) - y; 
    velo = 0; 
    } 
    } 
    } 

    public void moveDown(Vector<Thing> things){ 
    y += velo; 

    velo += speed; 

    if(velo > maxFallSpeed) 
    velo = maxFallSpeed; 


    boolean b = false; 
    for(int i = 0; i < things.size(); i++){ 
    if(!b && new Rectangle((int) x, (int) y + (height/2), width, height).intersects(new Rectangle((int) things.get(i).x, (int) things.get(i).y, things.get(i).width, things.get(i).height))){ 
    y -= (y + height) - things.get(i).y; 
    velo = 0; 
    } 
    } 
    } 

} 

class Thing{ 
    float x = 50; 
    float y = 50; 
    int height = 50; 
    int width = 30; 
    int type = -1; 
    float speed = 0.5f; 

    public Thing(float x, float y, int width, int height, int type){ 
    this.x = x; 
    this.y = y; 
    this.width = width; 
    this.height = height; 
    this.type = type; 
    } 

    public void moveUp(Player player){ 
    y -= 0.5f; 

    if(new Rectangle((int) x,(int) y, width, height).intersects(new Rectangle((int) player.x, (int) player.y, player.width, player.height))){ 
    player.y -= (player.y + player.height) - y; 
    player.velo = 0; 
    } 
    } 

    public void moveRight(Player player, Vector<Thing> things){ 
    x += speed; 

    if(new Rectangle((int) x,(int) y - 1, width, height).intersects(new Rectangle((int) player.x, (int) player.y, player.width, player.height))){ 
    player.moveRightWithThing(things, speed); 
    } 
    } 
} 

} 

Et voici la démo: http://prime.programming-designs.com/java/platformer_demo/platdemo.jnlp

+1

Trop de code et pas assez question. – walkytalky

+0

Je ne peux pas reproduire cela; Comment obtenez-vous votre problème? –

+0

si je trouve la possibilité de sauter dans les airs d'une manière inquiétante non physique –

Répondre

7

La raison pour laquelle vous avez difficulté à trouver l'erreur est que le code est horrible.

  • De grandes quantités de duplication de code: moveLeft, moveRight, moveUp et moveDown sont très similaires.
  • La logique d'accélération due à la gravité apparaît à deux endroits.
  • La logique de collision répétée partout.
  • Mauvais choix de noms. velo pour la vitesse vers le bas, mais delta pour la vitesse vers la droite (mal étiqueté comme "impulsion"): pourquoi pas vy et vx? Aussi maxSpeed pour la vitesse horizontale maximale, mais maxFallSpeed pour la vitesse verticale maximale.
  • Accélération/décélération appelée speed.
  • Une allocation inutile, par ex. appeler new Rectangle chaque fois que vous voulez tester si quelque chose a frappé quelque chose d'autre.
  • Les positions sont à virgule flottante, mais la collision est basée sur des entiers.

Duplication de code a pour effet d'introduire des bugs, car lorsque la fonctionnalité est dupliquée il y a la possibilité de se tromper dans l'un des endroits, et aussi des insectes qui se cachent, parce que le volume du Code rend plus difficile à repérer leur.

Quoi qu'il en soit, le rebondissement sur les plates-formes peut être quelque chose à voir avec le fait que dans Player:moveDown vous utilisez un rectangle qui est compensé par la moitié de la hauteur du joueur, alors que dans Thing:moveRight vous entrer en collision avec un rectangle qui est pas compensé. (Mais c'est juste une supposition.)

Questions connexes