相机走出地图的界限。我如何解决它?

时间:2015-05-15 19:19:24

标签: java camera

的所有人。我正在制作我的java游戏问题。我已经做到了以玩家为中心,然而,我想要它做的是当相机的xPos和yPos超过Map的宽度和高度时,它会捕捉到地图上最后一排的瓷砖。 /强>

这是我的相机类:

public class GameCamera {
private CoreEngine coreEngine; 
private int xOffset; 
private int yOffset;

public GameCamera(CoreEngine coreEngine, int xOffset, int yOffset) { 
    this.coreEngine = coreEngine;
    this.xOffset = xOffset; 
    this.yOffset = yOffset; 
}

public void centerOnEntity(Entity e) { 
    xOffset = e.getX() - coreEngine.getWidth() / 2 + e.getWidth() / 2;
    yOffset = e.getY() - coreEngine.getHeight() / 2 + e.getHeight() / 2;
}

public void setCameraBounds() {
    //Code here to snap/clamp the screen when xPos or yPos exceed Map's width and height. 
}

public void move(float xAmt, float yAmt) {
    xOffset += xAmt;
    yOffset += yAmt;
}

public int getxOffset() {
    return xOffset;
}
public void setxOffset(int xOffset) {
    this.xOffset = xOffset;
}
public int getyOffset() {
    return yOffset;
}
public void setyOffset(int yOffset) {
    this.yOffset = yOffset;
} 

}

这是我的世界级:

public class World {
@SuppressWarnings("unused")
private CoreEngine coreEngine;
private int[][] tileMap; 
private int width; 
private int height;
@SuppressWarnings("unused")
private int xSpawn;
@SuppressWarnings("unused")
private int ySpawn;

private EntityManager entityManager;

public World(CoreEngine coreEngine, String filePath) {
    this.coreEngine = coreEngine;
    entityManager = new EntityManager(this, coreEngine);
    loadWorld(filePath);
}

public void update() {
    entityManager.update();
}

public void render(Graphics g) {
    int xStart = Math.max(0, coreEngine.getGameCamera().getxOffset() / Tile.TILEWIDTH);
    int xEnd = Math.min(width, (coreEngine.getGameCamera().getxOffset() + coreEngine.getWidth()) / Tile.TILEWIDTH + 1);
    int yStart = Math.max(0, coreEngine.getGameCamera().getyOffset() / Tile.TILEHEIGHT);
    int yEnd = Math.min(height, (coreEngine.getGameCamera().getyOffset() + coreEngine.getHeight()) / Tile.TILEHEIGHT + 1);

    for(int yPos = yStart; yPos < yEnd; yPos++) {
        for(int xPos = xStart; xPos < xEnd; xPos++) {
            getTile(xPos, yPos).render(g,  xPos * Tile.TILEWIDTH - coreEngine.getGameCamera().getxOffset(), yPos * Tile.TILEHEIGHT - coreEngine.getGameCamera().getyOffset());
        }
    }

    entityManager.render(g);
}

public Tile getTile(int xPos, int yPos) { 
    Tile tile = Tile.tilesArray[tileMap[xPos][yPos]];
    if (tile == null) return Tile.dirtTile; 
    return tile;
}

private void loadWorld(String filePath) { 
    String file = FileLoader.loadFile(filePath);
    String[] tokens = file.split("\\s+");
    width  = FileLoader.parseInt(tokens[0]);
    height = FileLoader.parseInt(tokens[1]);
    xSpawn = FileLoader.parseInt(tokens[2]);
    ySpawn = FileLoader.parseInt(tokens[3]);

    tileMap = new int[width][height];
    for(int yPos = 0; yPos < height; yPos++) {
        for(int xPos = 0; xPos < width; xPos++) {
            tileMap[xPos][yPos] = FileLoader.parseInt(tokens[(xPos + yPos * width) + 4]);
        }
    }
}

这是我的Player类:

public class Player extends Creature {
public static String playerKey = "Player";
private String playerName = "Player One";
public static Inventory inventory;
private Rectangle playerBox;

private Direction currentDirection;
private Bar healthBar;
private Bar energyBar;

private World worldOne;

public Player(CoreEngine coreEngine, World worldOne, int xPos, int yPos) {
    super(coreEngine, worldOne, xPos, yPos, Creature.DEFAULT_CREATURE_WIDTH, Creature.DEFAULT_CREATURE_HEIGHT);
    GameObject.addObject(coreEngine, playerKey, xPos, yPos, width, height);
    this.worldOne = worldOne;
    inventory = new Inventory(this);
    currentDirection = Direction.DOWN;
    init();
}

private void init() {
    healthBar = new Bar((CoreEngine.getWidth() / 2) - 175, (CoreEngine.getHeight() / 2) + 150, 350, 15, Color.lightGray, Color.red,Color.white, this);
    energyBar = new Bar((CoreEngine.getWidth() / 2) - 175, (CoreEngine.getHeight() / 2) + 130, 350, 15, Color.lightGray, Color.yellow, Color.white, this);
    healthBar.fillHealth();
    energyBar.fillEnergy();
}

private void setCollision(int xPos, int yPos, int width, int height) { 
     playerBox = new Rectangle(xPos, yPos, width, height); 
}

//Player Logic Goes Here
public void update() { 
    getInput();
    move(xChange, yChange);
    coreEngine.getGameCamera().centerOnEntity(this);

    healthBar.update();
    energyBar.update();
    inventory.update();
}

public void getInput() { 
    xChange = 0;
    yChange = 0;

    if(coreEngine.getKeyManager().up) {
        currentDirection = Direction.UP;
        yChange = -speed;
    }
    if(coreEngine.getKeyManager().down) {
        currentDirection = Direction.DOWN;
        yChange = speed;
    }
    if(coreEngine.getKeyManager().left) {
        currentDirection = Direction.LEFT;
        xChange = -speed;
    }
    if(coreEngine.getKeyManager().right) {
        currentDirection = Direction.RIGHT;
        xChange = speed;
    }
}

public void render(Graphics g) {
    //g.setColor(new Color(133, 20, 133));
    //g.setFont(new Font("Freaky Paper Cutouts", Font.BOLD, 14));
    //g.drawString(playerName, (xPos - coreEngine.getGameCamera().getxOffset()) - 15, (yPos - coreEngine.getGameCamera().getyOffset()) - 25);
    //g.drawString("(" + xPos + ", " + yPos + ") ", (xPos - coreEngine.getGameCamera().getxOffset()) - 15, (yPos - coreEngine.getGameCamera().getyOffset()) - 10);

    //Basic Purple Player Image
    g.drawImage(CELibrary.playerOne,  xPos - coreEngine.getGameCamera().getxOffset(), yPos - coreEngine.getGameCamera().getyOffset(), width, height, null);

    //For Use w/ Player Animation:
    switch(currentDirection) {
    case UP:
        //g.drawImage(ResourceLoader.playerUp,  xPos - coreEngine.getGameCamera().getxOffset(), yPos - coreEngine.getGameCamera().getyOffset(), width, height, null);
        break;
    case DOWN:
        //g.drawImage(ResourceLoader.playerDown,  xPos - coreEngine.getGameCamera().getxOffset(), yPos - coreEngine.getGameCamera().getyOffset(), width, height, null);
        break;
    case LEFT:
        //g.drawImage(ResourceLoader.playerLeft,  xPos - coreEngine.getGameCamera().getxOffset(), yPos - coreEngine.getGameCamera().getyOffset(), width, height, null);
        break;
    case RIGHT:
        //g.drawImage(ResourceLoader.playerRight,  xPos - coreEngine.getGameCamera().getxOffset(), yPos - coreEngine.getGameCamera().getyOffset(), width, height, null);
        break;
    default: //Default Direction = Idle
        //g.drawImage(ResourceLoader.playerIdle,  xPos - coreEngine.getGameCamera().getxOffset(), yPos - coreEngine.getGameCamera().getyOffset(), width, height, null);
        break;
    }

    inventory.render(g);

    g.setColor(Color.red); //Currently showing playerBox for debug purposes only - g.setColor(new Color(133, 20, 133));
    setCollision(xPos - coreEngine.getGameCamera().getxOffset(), yPos - coreEngine.getGameCamera().getyOffset(), Creature.DEFAULT_CREATURE_WIDTH, Creature.DEFAULT_CREATURE_HEIGHT);
    g.drawRect(playerBox.x, playerBox.y, playerBox.width, playerBox.height);

    g.setFont(new Font("Freaky Paper Cutouts", Font.BOLD, 25));
    g.setColor(Color.white);
    g.drawString("Score:", 10, 25);
    g.drawString("" + worldOne.getEntityManager().getWaveManager().score, 580, 25);

    g.setFont(new Font("Freaky Paper Cutouts", Font.BOLD, 14));
    g.setColor(new Color(133, 20, 133));
    g.drawString(playerName, (CoreEngine.getWidth() / 2) - 173, (CoreEngine.getHeight() / 2) + 123);
    g.drawString("(" + xPos + ", " + yPos + ") ", (CoreEngine.getWidth() / 2) + 110, (CoreEngine.getHeight() / 2) + 123);

    energyBar.renderEnergy(g);

    if (getEnergy() == 0) g.drawString("0", (CoreEngine.getWidth() / 2) + 148, (CoreEngine.getHeight() / 2) + 143);
    g.setColor(Color.black);
    g.drawString("Energy: ", (CoreEngine.getWidth() / 2) - 173, (CoreEngine.getHeight() / 2) + 142);
    g.drawString("" + getEnergy(), (CoreEngine.getWidth() / 2) + 148, (CoreEngine.getHeight() / 2) + 143);

    healthBar.renderHealth(g);

    if (getHealth() == 0) g.drawString("0", (CoreEngine.getWidth() / 2) + 148, (CoreEngine.getHeight() / 2) + 162);
    g.setColor(Color.white);
    g.drawString("Health: ", (CoreEngine.getWidth() / 2) - 173, (CoreEngine.getHeight() / 2) + 163);
    g.drawString("" + getHealth(), (CoreEngine.getWidth() / 2) + 148, (CoreEngine.getHeight() / 2) + 162);
}

这是我的GameState类:

public class PlayState extends GameState {

private World worldOne;

public PlayState(CoreEngine coreEngine) {
    super(coreEngine);
    init();
}

private void init() {
    worldOne = new World(coreEngine, CELibrary.WorldPath + "WorldOne.txt");
    //CEMusic.getMusic(CELibrary.Eight_Bit_Trip).play();
}

public void update() {
    worldOne.update();

    /* //Debugging Health / Energy Bar
    if (worldOne.getEntityManager().getPlayer().getHealth() == 0) worldOne.getEntityManager().getPlayer().hurt(0);
    else worldOne.getEntityManager().getPlayer().hurt(Creature.DEFAULT_DAMAGE_TAKEN);

    if (worldOne.getEntityManager().getPlayer().getEnergy() == 0) worldOne.getEntityManager().getPlayer().useEnergy(0);
    else worldOne.getEntityManager().getPlayer().useEnergy(Creature.DEFAULT_ENERGY_COST);
    */
}

@SuppressWarnings("static-access")
public void render(Graphics g) {
    //Render the Background
    g.setColor(Color.black);
    g.fillRect(0, 0, coreEngine.getWidth(), coreEngine.getHeight());

    //Render the World
    worldOne.render(g);
}

}

这是我要删除的图片: http://tinypic.com/r/8z4nkz/8

关于如何实现上述功能的任何想法?

2 个答案:

答案 0 :(得分:0)

目前,我们从未看到游戏如何以您的玩家为中心。我假设它在某个地方调用你的方法camera.centerOnEntity(mainPlayer),但我不知道。

假设您是如何使相机居中,您所要做的就是确保您的播放器本身不会脱离地图。也就是说,不要绑定相机 - 每次移动时绑定播放器(实体)本身。

答案 1 :(得分:0)

所以我不确定你如何引用整个世界,但假设你这样做(你必须格式化它才能使用你的代码):

public void setCameraBounds() {
    if(xOffset >= world.getWidth()/2 + (Half of the player)){
    moveRight = false;
    } else if(xOffset <= 0){
    moveLeft = false;
    }
    if(yOffset >= world.getHeight()/2 + (Half of the player)){
    moveDown = false;
    } else if(yOffset <= 0){
    moveUp = false;
    } 
}

在你监听移动的方法中,在你向各个方向移动之前,只需检查相应的布尔值。当你到达世界的边缘时,你的玩家就无法靠近那个边缘。