玩家和街区碰撞(Terraria)

时间:2016-02-27 14:05:07

标签: java

我正在制作像Terraria这样的游戏。我已经有了一个播放器,我可以放置块并通过单击现有块来删除它们。但我无法弄清楚如何制造玩家和阻止碰撞。我想创造像terraria一样的物理学。你能以某种方式帮助我吗? 这是我的3个类(我有4个但是4.类只是JFrame类):

这是我的主类(游戏循环):

package Package;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.Timer;


public class Game extends JPanel implements ActionListener, MouseListener, KeyListener {

    Timer gameLoop = new Timer(5, this);
    private static final long serialVersionUID = 1L;
    public static final int WIDTH = 1500;
    public static final int HEIGHT = 900;
    public static final Dimension windowSize = new Dimension(WIDTH, HEIGHT);

    Player player = new Player();

    public static ArrayList<Block> blocks = new ArrayList<Block>();

    private int xDistance;
    private int yDistance;

    public Game() {
        setPreferredSize(windowSize);
        setFocusable(true);
        addMouseListener(this);
        addKeyListener(this);
        setBackground(Color.WHITE);
        for (int i = 0; i < Game.WIDTH; i += 50) {
            for (int j = Game.HEIGHT - 150; j < Game.HEIGHT; j += 50) {
                blocks.add(new Block(i, j));
            }
        }
        start();
    }

    public void start() {
        gameLoop.start();
    }

    public void stop() {
        gameLoop.stop();
    }

    public void paint(Graphics g) {

        for (Block b : blocks) {
            b.render(g);
        }

        player.render(g);
    }

    public void actionPerformed(ActionEvent e) {
        player.move();
        player.offScreen();

        repaint();
    }

    public void mouseClicked(MouseEvent e) {}

    public void mousePressed(MouseEvent e) {
        int mouseX = e.getX();
        int mouseY = e.getY();
        boolean foundBlock = false;

        xDistance = mouseX % 50;
        yDistance = mouseY % 50;

        for (Block b : blocks) {
            if (b.x == mouseX - xDistance && b.y == mouseY - yDistance) {
                if (mouseX >= player.x - 150 && mouseX <= player.x + 200 && mouseY >= player.y - 150 && mouseY <= player.y + 250) {
                    blocks.remove(b);
                    foundBlock = true;
                    break;
                }
            }
        }

        if (foundBlock == false) {
            if (mouseX >= player.x - 150 && mouseX <= player.x + 200 && mouseY >= player.y - 150 && mouseY <= player.y + 250) {
                blocks.add(new Block(mouseX - xDistance, mouseY - yDistance));
            }
        }
    }

    public void mouseReleased(MouseEvent e) {}

    public void mouseEntered(MouseEvent e) {}

    public void mouseExited(MouseEvent e) {}



    public void keyTyped(KeyEvent e) {}

    public void keyPressed(KeyEvent e) {
        int arrows = e.getKeyCode();

        if (arrows == KeyEvent.VK_D) {
            player.xSpeed = 2;
        }
        if (arrows == KeyEvent.VK_A) {
            player.xSpeed = -2;
        }
    }

    public void keyReleased(KeyEvent e) {
        int arrows = e.getKeyCode();

        if (arrows == KeyEvent.VK_D) {
            player.xSpeed = 0;
        }
        if (arrows == KeyEvent.VK_A) {
            player.xSpeed = 0;
        }
    }
}

这是我的Player类:

package Package;

import java.awt.Color;
import java.awt.Graphics;

public class Player {

    public int x = 14 * 50;
    public int y = Game.HEIGHT - (5 * 50);
    public int xSpeed = 0;
    public int ySpeed = 0;
    public boolean jump = false;
    public int ticks = 6;

    public void render(Graphics g) {
        g.setColor(Color.BLACK);
        g.fillRect(x, y, 50, 100);
    }

    public void move() {
        x += xSpeed;
        y += ySpeed;
    }

    public void offScreen() {
        if (x <= 0) {
            xSpeed = 0;
    } else if (x + 50 >= Game.WIDTH) {
            xSpeed = 0;
        }
    }
}

这是我的Block Class:

package Package;

import java.awt.Color;
import java.awt.Graphics;

public class Block {

    public int x;
    public int y;

    public Block(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void render(Graphics g) {
        g.setColor(Color.GRAY);
        g.fillRect(x, y, 50, 50);
        g.setColor(Color.BLACK);
        g.drawRect(x, y, 50, 50);
    }
}

1 个答案:

答案 0 :(得分:1)

您不希望以这种方式存储块:

public static ArrayList<Block> blocks = new ArrayList<Block>();

相反,创建一个允许您通过坐标访问块的结构。也许:

public static HashMap<Integer, HashMap<Integer, Block>>()

...其中第一个整数是X坐标而第二个是Y.这样,您可以快速找到任何碰撞机会的块,而不是检查每次迭代都会在世界上的每个街区。

另外,为什么这是static?我认为不应该这样。

要检查碰撞(我假设是为了防止玩家穿过障碍物),只需弄清楚玩家在建议的移动后会在哪里找到坐标,看看玩家是否有矩形(左上角的矩形)玩家的精灵到右下角)与任何一个区块的边界矩形重叠。

但这非常重要:安排积木所以你不必全部检查!只有非常窄的坐标范围内的块可能是冲突,因此请确保您可以按范围快速访问块