簡體   English   中英

在我的2D游戲中,每當玩家在屏幕的左或右邊界時,相機就會額外移動1個像素

[英]In my 2d game, the camera is moving 1 extra pixel each time the player is at the left or the right limit of the screen

請原諒我英語不好。 實施2D相機時出現問題。 我使攝像機跟隨玩家,直到到達游戲級別的邊緣,只有玩家移動並且攝像機停止。 我很容易做到這一點,但是我的問題是相機不合適。 每當您在所有四個方向上達到游戲級別限制的邊緣時,相機都會繼續移動1個像素(我發布的代碼僅顯示水平移動。為簡單起見,我這樣做了)。 這意味着,如果您在游戲的左邊緣來回移動40次,相機將向右移動40個像素! 我不知道該如何解決。 我在下面的原始代碼中發布了一個非常簡化的版本,並使其盡可能小以顯示該程序的工作方式。 接下來,只需在屏幕上水平移動播放器和攝像機即可。

這是'theGamePanel'類(它是主類):-

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':-

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

}

最后是“世界”課。 此類僅用於在背景中繪制大地圖(級別):-

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
    }
}

如果無法理解,請告訴。 我將添加更多詳細信息。

考慮玩家站在地圖右邊緣附近的情況。 快速按一下“向右”鍵可將他移出攝像機跟隨區域,以使攝像機不移動。 迅速按一下“左”鍵,將他移回攝影機跟隨區域。 攝像機將向左移動“ dx”單位。 如果我是正確的話,這將使玩家慢慢爬近游戲場的右邊緣。

(要查找類​​似的錯誤,我通常使用System.out.println消息來System.out.println代碼。如果有很多消息,則將它們寫到文件中並對關鍵字進行文本搜索)

您有相機的位置(cameraX,cameraY),但播放器沒有位置?

只需為玩家創建一個位置(playerX,playerY)

像這樣改變油漆:

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

當玩家靠近邊界時,請勿移動相機,而只能移動玩家。

我相信以下更改可以解決此問題:

玩家等級

//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,可以補償每次到達邊界之一時積累的錯誤。

無論如何,我建議您更改解決問題的方法,以使您的代碼更易於維護和更靈活。 一種方法是根據當前播放器在每一幀上的位置來計算攝像機位置。

注意:這行g.translate(-(int)cameraX, -(int)cameraY); 一旦方法translate(int, int)不是增量的translate(int, int)就不需要在TheGamePanel類的paint()方法中進行操作。

問候

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM