Java Slick2D: камера прокручивается, персонаж движется слишком быстро

Я играл с Slick2D для Java, и мне удалось заставить его отображать карты и перемещать спрайт моего персонажа.

Я попытался реализовать камеру, которая следует за игроком, чтобы карта прокручивалась. Во время прокрутки карты скорость перемещения этих персонажей выше, чем должна быть (возможно, из-за того, что камера прокручивает их, а также они двигаются с помощью клавиш)

Я в тупике, как это решить, хотя

Код камеры - это то, что я нашел на гладких форумах и немного изменил, чтобы рисовать каждый слой отдельно, изменив оба метода рисования, чтобы добавить слой. Я бы спросил на форумах, но они кажутся мертвыми.

это код камеры

/*
 * 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);
    }

person Ceri Turner    schedule 23.04.2014    source источник
comment
Как вы манипулируете положением персонажа?   -  person Samich    schedule 23.04.2014
comment
Это делается в классе Player. Он имеет обновление метода, которое вызывается из основного обновления. Добавил код в первый пост   -  person Ceri Turner    schedule 23.04.2014


Ответы (1)


Починил это. Отрисовка карты перемещена из класса камеры в класс карты. использовал камеру x/y, созданную в классе камеры в классе карты и игрока

person Ceri Turner    schedule 24.04.2014