0

slick で衝突を管理するにはどうすればよいですか?

マップを作成し、壁であるすべてのタイルにはオプションがブロックされています = true;

衝突を実装する方法、壁にぶつかった場合、それを通り抜けることができる? また、マップの端に到達すると、移動をブロックします。

package javagame;

import org.newdawn.slick.Animation;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.tiled.TiledMap;

public class Play extends BasicGameState {

    Animation movingUp, movingDown, movingLeft, movingRight;
    Animation player;
    int[] duration = {200, 200, 200};
    float playerX = 0;
    float playerY = 0;
    float cameraX;
    float cameraY;
    float screenWidth;
    float screenHeight;
    private TiledMap map = null;
    private static final float SPEED = 0.1f;

    private boolean[][] blocked;

    public Play(int state, int x, int y) {
        playerX = (float) x;
        playerY = (float) y;
    }

    private boolean blocked(float x, float y) {
        return blocked[(int) x][(int) y];
    }

    @Override
    public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {

        map = new TiledMap("map/map.tmx");

        // build a collision map based on tile properties in the TileD map 
        blocked = new boolean[map.getWidth()][map.getHeight()];
        for (int x = 0; x < map.getWidth(); x++) {
            for (int y = 0; y < map.getHeight(); y++) {
                int tileID = map.getTileId(x, y, 0);
                String value = map.getTileProperty(tileID, "blocked", "false");
                if ("true".equals(value)) {
                    blocked[x][y] = true;
                }
            }
        }

        Image[] walkUp = {
            new Image("graphics/player/up0.png"),
            new Image("graphics/player/up1.png"),
            new Image("graphics/player/up2.png")
        };

        Image[] walkDown = {
            new Image("graphics/player/down0.png"),
            new Image("graphics/player/down1.png"),
            new Image("graphics/player/down2.png")
        };
        Image[] walkLeft = {
            new Image("graphics/player/left0.png"),
            new Image("graphics/player/left1.png"),
            new Image("graphics/player/left2.png")
        };
        Image[] walkRight = {
            new Image("graphics/player/right0.png"),
            new Image("graphics/player/right1.png"),
            new Image("graphics/player/right2.png")
        };

        movingUp = new Animation(walkUp, duration, false);
        movingDown = new Animation(walkDown, duration, false);
        movingLeft = new Animation(walkLeft, duration, false);
        movingRight = new Animation(walkRight, duration, false);

        player = movingDown;

    }

    @Override
    public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {

        screenWidth = gc.getWidth();
        screenHeight = gc.getHeight();

        cameraX = (screenWidth / 2) - (playerX / 2);
        cameraY = (screenHeight / 2) - (playerY / 2);

        map.render((int) playerX, (int) playerY);

        player.draw(cameraX, cameraY);

        g.drawString("X: " + playerX + "\nY: " + playerY, 520, 20);
        g.resetTransform();

    }

    @Override
    public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
        Input input = gc.getInput();

        if (input.isKeyDown(Input.KEY_UP) || input.isKeyDown(Input.KEY_W)) {
            player = movingUp;
            playerY += delta * SPEED;
            player.update(delta);
        } else if (input.isKeyDown(Input.KEY_DOWN) || input.isKeyDown(Input.KEY_S)) {
            player = movingDown;
            playerY -= delta * SPEED;
            player.update(delta);
        } else if (input.isKeyDown(Input.KEY_LEFT) || input.isKeyDown(Input.KEY_A)) {
            player = movingLeft;
            playerX += delta * SPEED;
            player.update(delta);
        } else if (input.isKeyDown(Input.KEY_RIGHT) || input.isKeyDown(Input.KEY_D)) {
            player = movingRight;
            playerX -= delta * SPEED;
            player.update(delta);
        }

    }

}

サンプルソースコード (NetBeans プロジェクト) は次のとおりです。

https://www.box.com/s/9nicp0n067de632kcpj3

4

2 に答える 2

2

更新時に、配列を簡単に確認できます。壁の場合は更新しないでください。境界の場合は、更新しないでください。

@Override
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
    Input input = gc.getInput();
    float yChange = 0, xChange=0;
    boolean capturedInput = false;
    if (input.isKeyDown(Input.KEY_UP) || input.isKeyDown(Input.KEY_W)) {
        player = movingUp;
        yChange += delta * SPEED;
        capturedInput = true;
    } else if (input.isKeyDown(Input.KEY_DOWN) || input.isKeyDown(Input.KEY_S)) {
        player = movingDown;
        yChange -= delta * SPEED;
        capturedInput = true;
    } else if (input.isKeyDown(Input.KEY_LEFT) || input.isKeyDown(Input.KEY_A)) {
        player = movingLeft;
        xChange += delta * SPEED;
        capturedInput = true;
    } else if (input.isKeyDown(Input.KEY_RIGHT) || input.isKeyDown(Input.KEY_D)) {
        player = movingRight;
        xChange -= delta * SPEED;
        capturedInput = true;
    }
    if(capturedInput==true && !blocked(playerX+xChange,playerY+yChange)){
        playerX += xChange;
        playerY += yChange;
        player.update(delta);
    }
}

private boolean blocked(float x, float y) {
    return blocked[(int) x][(int) y];
}

ほとんどの場合、最初に値を確認し、問題がなければプレーヤーの値を変更するまで値を変更しないでください。

編集:変数capturedInputを追加しました。これにより、実際にkeyDownイベントがあることがわかります。これについては、2 つのコメントがあります。これは、コードを機能させるための「ハック」であり、最も美しいものではないと考えています。私は個人的に、キー クリックをリッスンするイベント リスナーをウィンドウに追加しようとします。キーがクリックされると、フレームが更新されて更新される間ずっと位置情報を変更するか、変更があったときにのみ更新します。 repaint() を呼び出します。

onKeyDown を聞くためのチュートリアルはたくさんあります。あなたのコードは今よりうまく機能し、あなたのようにエッジを手動でキャッチする必要はありません。ブール値のブロック配列でエッジの周りに壁を描くことができるはずです.そうでない場合は、メソッドを続行できます.

于 2012-11-22T00:19:16.117 に答える
0

wiki Slickで説明されているように、ブロックの Rectangle の作成元XY位置にタイルの寸法を掛けたものを作成してからintersects()、エンティティと衝突するかどうかをメソッドで確認してください。

お役に立てば幸いです。

于 2012-11-25T06:46:09.723 に答える