I have an assignment to create a 2D game, this game must use an abstract class Shape which is used to draw shapes. I decided to make a 2D platformer, but it's my first time doing something like this. I am trying to implement collision detection, and decided to create an offset of my player object to see if it collides with my rectangle object, and stop movement if it does. This is only working for the top side, however on the right, left and botton the player will move through the rectangle and I don't understand why. I expected the collision detection to work for all sides. I would like to know how I can change my collision detection to work for all sides of the rectangle.
Here's a gif showing what happens:
My App class:
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) { }
}
Player class:
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);
}
}
Rectangle class (will be a platform):
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);
}
}