Java Slick2D:相机正在滚动,角色移动得太快

时间:2014-04-23 12:10:06

标签: java slick2d

我一直在玩Slick2D for Java,我设法让它显示地图并让我的角色精灵四处移动。

我试图在玩家后面实现一个摄像头,以便地图滚动。当地图滚动时,角色的移动速度比它应该的速度快(可能是由于相机滚动它以及随着键移动)

我很难理解如何解决它

相机代码是我在光滑的论坛上找到的,并稍微修改以分别绘制每个图层,修改两个drawmap方法以添加图层。我会在论坛上问,但它们似乎已经死了。

这是相机代码

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package engine;

/**
 *
 * @author Ceri
 */
import java.awt.geom.Point2D;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.tiled.TiledMap;

public class Camera {

    /**
     * the map used for our scene
     */
    protected TiledMap map;

    /**
     * the number of tiles in x-direction (width)
     */
    protected int numTilesX;

    /**
     * the number of tiles in y-direction (height)
     */
    protected int numTilesY;

    /**
     * the height of the map in pixel
     */
    protected int mapHeight;

    /**
     * the width of the map in pixel
     */
    protected int mapWidth;

    /**
     * the width of one tile of the map in pixel
     */
    protected int tileWidth;

    /**
     * the height of one tile of the map in pixel
     */
    protected int tileHeight;

    /**
     * the GameContainer, used for getting the size of the GameCanvas
     */
    protected GameContainer gc;

    /**
     * the x-position of our "camera" in pixel
     */
    protected float cameraX;

    /**
     * the y-position of our "camera" in pixel
     */
    protected float cameraY;

    protected Point2D.Float currentCenterPoint = new Point2D.Float(0, 0);

    /**
     * Create a new camera
     *
     * @param gc the GameContainer, used for getting the size of the GameCanvas
     * @param map the TiledMap used for the current scene
     */
    public Camera(GameContainer gc, TiledMap map) {
        this.map = map;

        this.numTilesX = map.getWidth();
        this.numTilesY = map.getHeight();

        this.tileWidth = map.getTileWidth();
        this.tileHeight = map.getTileHeight();

        this.mapWidth = this.numTilesX * this.tileWidth;
        this.mapHeight = this.numTilesY * this.tileHeight;

        this.gc = gc;
    }

    /**
     * "locks" the camera on the given coordinates. The camera tries to keep the
     * location in it's center.
     *
     * @param x the real x-coordinate (in pixel) which should be centered on the
     * screen
     * @param y the real y-coordinate (in pixel) which should be centered on the
     * screen
     * @return
     */
    public Point2D.Float centerOn(float x, float y) {
        //try to set the given position as center of the camera by default
        cameraX = x - gc.getWidth() / 2;
        cameraY = y - gc.getHeight() / 2;

        //if the camera is at the right or left edge lock it to prevent a black bar
        if (cameraX < 0) {
            cameraX = 0;
        }
        if (cameraX + gc.getWidth() > mapWidth) {
            cameraX = mapWidth - gc.getWidth();
        }

        //if the camera is at the top or bottom edge lock it to prevent a black bar
        if (cameraY < 0) {
            cameraY = 0;
        }
        if (cameraY + gc.getHeight() > mapHeight) {
            cameraY = mapHeight - gc.getHeight();
        }

        currentCenterPoint.setLocation(cameraX, cameraY);
        return currentCenterPoint;
    }

    /**
     * "locks" the camera on the center of the given Rectangle. The camera tries
     * to keep the location in it's center.
     *
     * @param x the x-coordinate (in pixel) of the top-left corner of the
     * rectangle
     * @param y the y-coordinate (in pixel) of the top-left corner of the
     * rectangle
     * @param height the height (in pixel) of the rectangle
     * @param width the width (in pixel) of the rectangle
     */
    public void centerOn(float x, float y, float height, float width) {
        this.centerOn(x + width / 2, y + height / 2);
    }

    /**
     * "locks the camera on the center of the given Shape. The camera tries to
     * keep the location in it's center.
     *
     * @param shape the Shape which should be centered on the screen
     */
    public void centerOn(Shape shape) {
        this.centerOn(shape.getCenterX(), shape.getCenterY());
    }

    /**
     * draws the part of the map which is currently focussed by the camera on
     * the screen
     */
    public void drawMap(int layer) {
        this.drawMap(0, 0, layer);
    }

    /**
     * draws the part of the map which is currently focussed by the camera on
     * the screen.<br>
     * You need to draw something over the offset, to prevent the edge of the
     * map to be displayed below it<br>
     * Has to be called before Camera.translateGraphics() !
     *
     * @param offsetX the x-coordinate (in pixel) where the camera should start
     * drawing the map at
     * @param offsetY the y-coordinate (in pixel) where the camera should start
     * drawing the map at
     */
    public void drawMap(int offsetX, int offsetY, int layer) {
        //calculate the offset to the next tile (needed by TiledMap.render())
        int tileOffsetX = (int) -(cameraX % tileWidth);
        int tileOffsetY = (int) -(cameraY % tileHeight);

        //calculate the index of the leftmost tile that is being displayed
        int tileIndexX = (int) (cameraX / tileWidth);
        int tileIndexY = (int) (cameraY / tileHeight);

        //finally draw the section of the map on the screen
        map.render(
                tileOffsetX + offsetX,
                tileOffsetY + offsetY,
                tileIndexX,
                tileIndexY,
                (gc.getWidth() - tileOffsetX) / tileWidth + 1,
                (gc.getHeight() - tileOffsetY) / tileHeight + 1, layer, false);
    }

    /**
     * Translates the Graphics-context to the coordinates of the map - now
     * everything can be drawn with it's NATURAL coordinates.
     */
    public void translateGraphics() {
        gc.getGraphics().translate(-cameraX, -cameraY);
    }

    /**
     * Reverses the Graphics-translation of Camera.translatesGraphics(). Call
     * this before drawing HUD-elements or the like
     */
    public void untranslateGraphics() {
        gc.getGraphics().translate(cameraX, cameraY);
    }

}

这就是它被调用的方式 在引擎类

    public void render(GameContainer gc, Graphics g) throws SlickException {

            camera = new Camera(gc, world.map);
            camera.centerOn(player.getX(), player.getY());
            camera.drawMap(0);
            camera.drawMap(1);
            player.draw();
            camera.drawMap(2);
        }

这就是玩家类

的方式
public Player(MapClass m) throws SlickException {
        map = m;

        Image[] movementUp = {new Image("Images/Player/u1.png"), new Image("Images/Player/u2.png"), new Image("Images/Player/u3.png"), new Image("Images/Player/u4.png")};
        Image[] movementDown = {new Image("Images/Player/d1.png"), new Image("Images/Player/d2.png"), new Image("Images/Player/d3.png"), new Image("Images/Player/d4.png")};
        Image[] movementLeft = {new Image("Images/Player/l1.png"), new Image("Images/Player/l2.png"), new Image("Images/Player/l3.png"), new Image("Images/Player/l4.png")};
        Image[] movementRight = {new Image("Images/Player/r1.png"), new Image("Images/Player/r2.png"), new Image("Images/Player/r3.png"), new Image("Images/Player/r4.png")};
        int[] duration = {100, 100, 100, 100};

        up = new Animation(movementUp, duration, false);
        down = new Animation(movementDown, duration, false);
        left = new Animation(movementLeft, duration, false);
        right = new Animation(movementRight, duration, false);

        // Original orientation of the sprite. It will look right.
        sprite = right;
    }

public void update(GameContainer container, int delta) throws SlickException {
        Input input = container.getInput();
        if (input.isKeyDown(Input.KEY_UP)) {
            sprite = up;
            sprite.update(delta);
            // The lower the delta the slowest the sprite will animate.
            if (!map.isBlocked(x, y - delta * 0.1f))
                y -= delta * 0.1f;
        } else if (input.isKeyDown(Input.KEY_DOWN)) {
            sprite = down;
            sprite.update(delta);
            if (!map.isBlocked(x, y + 16 + delta * 0.1f))
                y += delta * 0.1f;
        } else if (input.isKeyDown(Input.KEY_LEFT)) {
            sprite = left;
            sprite.update(delta);
            if (!map.isBlocked(x - delta * 0.1f, y))
                x -= delta * 0.1f;
        } else if (input.isKeyDown(Input.KEY_RIGHT)) {
            sprite = right;
            sprite.update(delta);
            if (!map.isBlocked(x + 16 + delta * 0.1f, y))
                x += delta * 0.1f;
        }
    }

    public void draw() {
        sprite.draw(x, y);
    }

1 个答案:

答案 0 :(得分:0)

修正了它。将地图绘制从相机类移动到地图类中。使用了地图和玩家类中相机类中创建的相机x / y