我正在制作一个瓷砖地图游戏而且我已经完成了简单的碰撞。然而,要使游戏工作,我必须知道矩形的哪一侧撞到墙/砖。只需在主冲突中放入一个简单的碰撞代码:
if(spriteX < brickX + brickwidth) {}
不起作用。目前的主要碰撞代码是:
for(int counter = 0; counter < 31; counter++) {
if(spriteX + 40 >= collisionX[counter] && collisionX[counter] + 100 >= spriteX
&& spriteY + 40 >= collisionY[counter] && collisionY[counter] + 100 >= spriteY) {
velX = 0;
velY = 0;
collisions = counter;
} else {
if(counter == collisions && jumping == false) {
fall();
}
}
}
如果你想要整个班级:
package Main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
public class Panel extends JPanel implements Runnable, KeyListener {
// dimensions
public static final int width = 800;
public static final int height = 800;
public static final int scale = 1;
// main loop
private Thread thread;
private boolean running = false;
private int FPS = 60;
private int targetTime = 1000 / FPS;
// drawing
private Graphics2D g;
private BufferedImage image;
int x;
int y;
boolean makeCollision = false;
// sprite
int spriteX = 210;
int spriteY = 200;
int velX = 0;
int velY = 10;
public boolean notOnGround = true;
int counter;
int collisionsCounter;
int jumps = 0;
public int row;
public int column;
public boolean collision;
public boolean jumping = false;
public String side = null;
// tilemap
int[][] map = {
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 1, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 1, 1, 1},
{1, 0, 0, 0, 1, 1, 0, 1},
{1, 0, 0, 1, 1, 0, 0, 1},
{1, 0, 0, 1, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1}
};
int[] collisionX = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
int[] collisionY = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
int[] jump = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
int collisions;
public Panel() {
setPreferredSize(new Dimension(width * scale, height * scale));
setFocusable(true);
requestFocus();
}
public void addNotify() {
super.addNotify();
if(thread == null) {
running = true;
addKeyListener(this);
thread = new Thread(this);
thread.start();
}
}
public void init() {
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
g = (Graphics2D) image.getGraphics();
}
public void update() {
if(spriteY < jump[0]) {
System.out.println(jump[0]);
jumping = false;
fall();
}
}
public void draw() {
g.clearRect(0, 0, WIDTH, HEIGHT);
x = 0;
y = 0;
for(column = 0; column <= 7; column++) {
x = 0;
for(row = 0; row <= 7; row++) {
changeColor(row, column, g);
g.fillRect(x, y, 100, 100);
x = x + 100;
}
y = y + 100;
}
g.setColor(Color.YELLOW);
g.fillRect(spriteX, spriteY, 40, 40);
spriteX += velX;
spriteY += velY;
for(int counter = 0; counter < 31; counter++) {
if(spriteX + 40 >= collisionX[counter] && collisionX[counter] + 100 >= spriteX
&& spriteY + 40 >= collisionY[counter] && collisionY[counter] + 100 >= spriteY){
velX = 0;
velY = 0;
collisions = counter;
} else {
if(counter == collisions && jumping == false) {
fall();
}
}
}
}
public void changeColor(int rowGive, int columnGive, Graphics g) {
if(map[rowGive][columnGive] == 1) {
g.setColor(Color.BLACK);
if(counter < 30) {
collisionX[counter] = x;
collisionY[counter] = y;
}
counter++;
} else {
g.setColor(Color.WHITE);
}
}
public void fall() {
velY = 5;
}
public void drawToScreen() {
Graphics g2 = getGraphics();
g2.drawImage(image, 0, 0, width * scale, height * scale, null);
g2.dispose();
}
public void run() {
init();
long wait;
long elapsed;
long start;
while(running) {
start = System.nanoTime();
update();
draw();
drawToScreen();
elapsed = System.nanoTime() - start;
wait = targetTime - elapsed / 1000000;
if(wait < 0) wait = 5;
try {
thread.sleep(wait);
} catch(Exception e) {
e.printStackTrace();
}
}
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if(code == KeyEvent.VK_RIGHT) {
velX = 5;
}
if(code == KeyEvent.VK_LEFT) {
velX = -5;
}
if(code == KeyEvent.VK_SPACE && jumping == false) {
jumping = true;
velY = -5;
jump[0] = spriteY - 100;
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}}
答案 0 :(得分:1)
让我们尝试将问题分开一点。你不需要知道矩形何时碰到墙壁:你需要找到矩形左侧何时击中墙壁的右侧并且当矩形的右侧点击墙的左侧。
更确切地说:不测试对象。将您的对象划分为碰撞表面(在您的情况下为左侧和右侧),找到一种模型化方法(通常x和x +宽度是矩形的左侧和右侧,如果x是您的前角的x坐标) 。并以“或”条件同时测试两者。
if(spriteX < brickX + brickwidth || spriteX + spritewidth > brickX) {}
编辑更仔细地阅读完整的课程,看起来你做了类似的事情,但你使用“&amp;&amp;”条件,意味着你永远不会是真的,因为双方的碰撞不可能同时发生。但我可能错了,你能告诉我吗?
答案 1 :(得分:0)
虽然不是严格意义上的碰撞问题,但我注意到了一个&#34;错误&#34;在draw()
中导致您的map
数组显示在-45角度左右翻转。
当行递增时,您应该递增y,而当列递增时,您应该递增x。执行此操作,您的显示将与map
初始化代码相同。
换句话说:
public void draw() {
g.clearRect(0, 0, WIDTH, HEIGHT);
x = 0;
y = 0;
for(column = 0; column <= 7; column++) {
y = 0;
for(row = 0; row <= 7; row++) {
changeColor(row, column, g);
g.fillRect(x, y, 100, 100);
y = y + 100;
}
x = x + 100;
}
...
将成为
int[][] map = {
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 1, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 1, 1, 1},
{1, 0, 0, 0, 1, 1, 0, 1},
{1, 0, 0, 1, 1, 0, 0, 1},
{1, 0, 0, 1, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1}
};
看起来像这样
而不是