У меня есть задание для создания 2D-игры, эта игра должна использовать абстрактный класс Shape, который используется для рисования фигур.Я решил сделать 2D-платформер, но я впервые делаю что-то подобное.Я пытаюсь реализовать обнаружение столкновений и решил создать смещение моего объекта игрока, чтобы увидеть, сталкивается ли он с моим прямоугольным объектом, и остановить движение, если это произойдет.Это работает только для верхней стороны, однако справа, слева и снизу игрок будет двигаться через прямоугольник, и я не понимаю, почему.Я ожидал, что обнаружение столкновения сработает для всех сторон.Я хотел бы знать, как я могу изменить обнаружение столкновений для работы со всеми сторонами прямоугольника.
Вот рисунок, показывающий, что происходит:
МойКласс приложения:
package A2;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import java.util.TreeSet;
import static java.awt.event.KeyEvent.*;
public class App extends JFrame {
private static final int GRAVITY = 10;
private static final int MAX_FALL_SPEED = 30;
public App() {
final Player player = new Player(200, 300);
final Rectangle rectangle = new Rectangle(100, 400);
JPanel mainPanel = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
player.draw(g);
rectangle.draw(g);
}
};
mainPanel.addKeyListener(new controlHandler(this, player, rectangle));
mainPanel.setFocusable(true);
add(mainPanel);
setLayout(new GridLayout());
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(600, 600);
}
class controlHandler implements ActionListener, KeyListener {
int keyCode;
App app;
Player player;
Rectangle rectangle;
TreeSet<Integer> keys = new TreeSet<>();
Timer time = new Timer(5, this);
boolean collision = false;
public controlHandler(App app, Player player, Rectangle rectangle) {
this.app = app;
this.player = player;
this.rectangle = rectangle;
time.start();
}
public void actionPerformed(ActionEvent e) {
player.x += player.xVelocity;
player.y += player.yVelocity;
Rectangle2D offset = player.getOffsetBounds();
if(offset.intersects(this.rectangle.wallObj.getBounds2D())){
collision = true;
player.xVelocity = 0;
player.yVelocity = 0;
}
else collision = false;
repaint();
}
public void keyPressed(KeyEvent e) {
keyCode = e.getKeyCode();
keys.add(keyCode);
switch (keyCode) {
case VK_UP:
moveUp();
break;
case VK_DOWN:
moveDown();
break;
case VK_LEFT:
moveLeft();
break;
case VK_RIGHT:
moveRight();
break;
}
}
public void keyReleased(KeyEvent e) {
released();
}
public void keyTyped(KeyEvent e) { }
public void moveUp() {
player.xVelocity = 0;
player.yVelocity = -2;
}
public void moveDown() {
if(!collision) {
player.xVelocity = 0;
player.yVelocity = 2;
}
}
public void moveLeft() {
player.xVelocity = -2;
player.yVelocity = 0;
}
public void moveRight() {
player.xVelocity = 2;
player.yVelocity = 0;
}
public void released() {
player.xVelocity = 0;
player.yVelocity = 0;
}
}
public static void main(String[] args) {
App app = new App();
app.setVisible(true);
}
}
abstract class Shape {
public double x;
public double y;
public void draw(Graphics g) { }
}
Класс игрока:
package A2;
import java.awt.*;
import java.awt.geom.Rectangle2D;
public class Player extends Shape {
public double xVelocity;
public double yVelocity;
public double length = 60;
public double top;
public double right;
public double left;
public double bottom;
public Rectangle2D playerObj;
public Player(double x, double y) {
this.x = x;
this.y = y;
playerObj = new Rectangle2D.Double(x, y, length, length);
}
public Rectangle2D getOffsetBounds(){
return new Rectangle2D.Double(x + xVelocity , y + yVelocity , length, length);
}
public void draw(Graphics g) {
playerObj = new Rectangle2D.Double(x, y, length, length);
g.setColor(Color.BLACK);
Graphics2D g2 = (Graphics2D)g;
g2.fill(playerObj);
}
}
Класс прямоугольника (будет платформой):
package A2;
import java.awt.*;
import java.awt.geom.Rectangle2D;
public class Rectangle extends Shape {
public double width = 400;
public double height = 30;
public double top;
public double right;
public double left;
public double bottom;
public Rectangle2D wallObj;
public Rectangle(double x, double y) {
this.x = x;
this.y = y;
wallObj = new Rectangle2D.Double(x, y, width, height);
}
public void draw(Graphics g) {
g.setColor(Color.ORANGE);
Graphics2D g2 = (Graphics2D)g;
g2.fill(wallObj);
}
}