我正在制作像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);
}
}
答案 0 :(得分:1)
您不希望以这种方式存储块:
public static ArrayList<Block> blocks = new ArrayList<Block>();
相反,创建一个允许您通过坐标访问块的结构。也许:
public static HashMap<Integer, HashMap<Integer, Block>>()
...其中第一个整数是X坐标而第二个是Y.这样,您可以快速找到任何碰撞机会的块,而不是检查每次迭代都会在世界上的每个街区。
另外,为什么这是static
?我认为不应该这样。
要检查碰撞(我假设是为了防止玩家穿过障碍物),只需弄清楚玩家在建议的移动后会在哪里找到坐标,看看玩家是否有矩形(左上角的矩形)玩家的精灵到右下角)与任何一个区块的边界矩形重叠。
但这非常重要:安排积木所以你不必全部检查!只有非常窄的坐标范围内的块可能是冲突,因此请确保您可以按范围快速访问块。