首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在我的2d游戏中,当玩家在屏幕的左边或右边时,相机会移动一个额外的像素。

在我的2d游戏中,当玩家在屏幕的左边或右边时,相机会移动一个额外的像素。
EN

Stack Overflow用户
提问于 2014-12-15 23:37:56
回答 3查看 434关注 0票数 0

请原谅我英语不好。我在实现2d相机时遇到了问题。我让相机跟随玩家,直到它接近游戏级别的边缘,在那里只有玩家移动,摄像机停止。我做这个很容易,但我的问题是相机不合适。相机继续移动一个额外的像素,每次你到达边缘的游戏水平的极限,在所有四个方向(代码我张贴只显示水平移动。我这样做是为了简单)。这意味着,如果您移动40次在游戏的左边边缘附近来回移动,相机将移动额外的40像素右!我不知道怎么解决这个问题。我发布了一个非常简单的版本,从我的原始代码下面,并使它尽可能小,以显示程序如何工作。下面只需将播放器和摄像机水平地移动到屏幕上。

这是'theGamePanel‘类(它是主类) :-

代码语言:javascript
复制
public class TheGamePanel extends JPanel implements Runnable, KeyListener 
{
    private boolean left, right;
    private float cameraX, cameraY;
    private World world = new World();
    private Player player = new Player();

    public TheGamePanel() 
    {   
        //setting the size of panel
    }

    public static void main(String[] args) 
    {
        //setting the window
    }

    public void paint(Graphics g) 
    {
        super.paint(g);
        // drawing the game-level and player
        g.translate((int)cameraX, (int)cameraY);
        world.paint(g);
        player.paint(g);
        g.translate(-(int)cameraX, -(int)cameraY);
    }

    public void upd() 
    {
        player.update(left, right, this);
    }

    @Override
    public void run() 
    {
        // game-loop
    }

    @Override
    public void keyPressed(KeyEvent e) 
    {
        int code = e.getKeyCode();
        if(code == KeyEvent.VK_LEFT) 
        {
            left = true;
        }
        if(code == KeyEvent.VK_RIGHT) 
        {
            right = true;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) 
    {
        if(e.getKeyCode() == KeyEvent.VK_LEFT) 
        {
            left = false;
        }
        if(e.getKeyCode() == KeyEvent.VK_RIGHT) 
        {
            right = false;
        }
    }

    @Override
    public void keyTyped(KeyEvent e) 
    {

    }

    //to set camera position
    public void setCameraX(float cameraDx) 
    {
        cameraX += cameraDx;
    }
}

这是“玩家”班。这门课是玩家和摄像机运动发生的地方。然后相机的x和值返回到“TheGamePanel”:-

代码语言:javascript
复制
public class Player 
{
    private float x, y;
    private float dx = 1;
    private int width = 32, height = 32;
    private float leftLimit, rightLimit;

    public Player() 
    {
        //player's initial x and y coordinates
        x = 320;
        y = 240;
        //camera's limit (where the camera needs to stop following player)
        leftLimit = x;
        rightLimit = 960;
    }

    public void paint(Graphics g) 
    {
        //for painting the player
        g.setColor(Color.GREEN);
        g.fillRect((int)x, (int)y, width, height);
    }

    //to move player and camera
    public void update(boolean left, boolean right, TheGamePanel panel) 
    {
        if(left == true) 
        {
            x -= dx;
            if(x > leftLimit && x < rightLimit) 
            {
                panel.setCameraX(dx);
            }
        }
        if(right == true) 
        {
            x += dx;
            if(x > leftLimit && x < rightLimit) 
            {
                panel.setCameraX(-dx);
            }
        }
    }

}

最后是“世界”班。这个类用于简单地在背景中绘制一个大的地图(级别) :-

代码语言:javascript
复制
public class World 
{   
    private BufferedImage map;
    private int tileWd = 32, tileHi = 32;

    public World() 
    {
        try 
        {
            map = ImageIO.read(new File("map1.png"));
        }
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }

    public void paint(Graphics g) 
    {
        //simply paints a game-level in the background
    }
}

如果有什么不能理解的,请告诉我。我会增加更多细节。

EN

回答 3

Stack Overflow用户

发布于 2014-12-15 23:59:56

考虑一下玩家站在地图右边边缘的情况。只要点击一下“右”键,他就会离开摄像机--跟踪区域,这样相机就不会移动。一个快速点击“左”键将他移回摄像机-跟踪区域。相机将向左移动"dx“单位。如果我是对的,这将使玩家慢慢地靠近比赛的右边边缘。

(为了找到这样的bug,我通常会在代码中乱扔System.out.println消息。如果有很多消息,我会把它们写到一个文件中,然后对关键字进行文本搜索)

票数 0
EN

Stack Overflow用户

发布于 2014-12-16 00:14:44

你有你的相机的位置(cameraX,cameraY),但是播放器没有位置?

只需为播放器创建一个位置(playerX,playerY)

改变油漆如下:

代码语言:javascript
复制
public void paint(Graphics g) 
{
    super.paint(g);
    // drawing the game-level and player
    g.translate((int)cameraX, (int)cameraY);
    world.paint(g);
    g.translate((int)playerX, (int)playerY);
    player.paint(g);
    g.translate(-(int)(playerX+cameraX), -(int)(playerY+cameraY));
}

当玩家靠近边界时,不要移动摄像机,而只能移动玩家。

票数 0
EN

Stack Overflow用户

发布于 2014-12-16 03:06:55

我相信以下的改变解决了问题:

球员班:

代码语言:javascript
复制
//to move player and camera
public void update(boolean left, boolean right, TheGamePanel panel) 
{
    if(left == true) 
    {
        x -= dx;
        if(x > leftLimit && x < rightLimit) 
        {
            panel.setCameraX(dx);
        }
    }
    if(right == true) 
    {
        if(x > leftLimit && x < rightLimit) 
        {
            panel.setCameraX(-dx);
        }
        x += dx;     // Only change: moved this line AFTER the if block
    }
}

通过测试x,在向左移动时更改x,在向右移动时更改x之前,您可以补偿每次到达其中一个边界时积累的错误。

无论如何,我建议您改变解决问题的方法,以便使代码更易于维护和更灵活。一种方法是根据当前玩家在每一帧上的位置来计算摄像机的位置。

注意:如果方法translate(int, int)不是增量的,则TheGamePanel类的paint()方法中的行g.translate(-(int)cameraX, -(int)cameraY);是不必要的。

问候

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27495153

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档