I am currently making a maze solving game in Java, and I am currently running into a snag. All of the random maze generation algorithms that I could find output in a way that I couldn't figure out how to implement into my current code. I was considering using the Depth First Search, Recursive Backtracker, or Prim's Algorithm, since I thought they would be the easiest to implement while still generating good mazes. What would be a working use of one of those algorithms that works with my current program? This is my Game Class: (Feel free to point out any bad practices as well, I am pretty new to Java)
package game;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Game extends JPanel implements ActionListener, KeyListener {
private boolean upPressed = false;
private boolean downPressed = false;
private boolean rightPressed = false;
private boolean leftPressed = false;
private final int playerDiam = 100;
private final int playerSpeed = 15;
private final int tileSize = 400;
private int[][] maze = {{1, 1, 1, 1, 1, 1},
{1, 2, 1, 1, 3, 1},
{1, 0, 1, 0, 0, 1},
{1, 0, 1, 0, 1, 1},
{1, 0, 0, 0, 1, 1},
{1, 1, 1, 1, 1, 1},
};
private int[][] initX = new int[maze.length][maze.length];
private int[][] initY = new int[maze.length][maze.length];
private int deltaX = -210;
private int deltaY = -210;
private String screen = "menu";
public Game() {
setFocusable(true);
addKeyListener(this);
setUpInitialCoordinates();
Timer timer = new Timer(1000 / 60, this);
timer.start();
}
#Override
public void actionPerformed(ActionEvent e) {
tick();
}
private void setUpInitialCoordinates() {
int x = 0;
int y;
for (int[] rowData : maze) {
y = 0;
for (int ignored : rowData) {
initX[x][y] = x * tileSize;
initY[x][y] = y * tileSize;
y++;
}
x++;
}
}
private void generateMaze() {
}
private void tick() {
if (screen.equals("playing")) {
if (upPressed) {
deltaY += playerSpeed;
} else if (downPressed) {
deltaY -= playerSpeed;
}
if (rightPressed) {
deltaX -= playerSpeed;
} else if (leftPressed) {
deltaX += playerSpeed;
}
}
repaint();
}
#Override
public void keyTyped(KeyEvent e) {}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_W) {
upPressed = true;
} else if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_S) {
downPressed = true;
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyCode() == KeyEvent.VK_D) {
rightPressed = true;
} else if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_A) {
leftPressed = true;
}
}
#Override
public void keyReleased(KeyEvent e) {
if (screen.equals("menu") && e.getKeyCode() == KeyEvent.VK_ENTER) {
upPressed = false;
downPressed = false;
rightPressed = false;
leftPressed = false;
screen = "playing";
} else if (screen.equals("playing")) {
if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_W) {
upPressed = false;
} else if (e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_S) {
downPressed = false;
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyCode() == KeyEvent.VK_D) {
rightPressed = false;
} else if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_A) {
leftPressed = false;
} else if (e.getKeyCode() == KeyEvent.VK_P) {
screen = "paused";
}
} else if (screen.equals("paused" ) && e.getKeyCode() == KeyEvent.VK_P) {
upPressed = false;
downPressed = false;
rightPressed = false;
leftPressed = false;
screen = "playing";
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(new Font("Aharoni", Font.PLAIN, 36));
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
switch (screen) {
case "menu":
g.setColor(Color.BLACK);
g.drawString("Labyrinth", 300, 200);
g.drawString("Press Enter to Play!", getWidth() / 3, 500);
break;
case "playing":
int x = 0;
int y = 0;
for (int[] rowData : maze) {
for (int cellData : rowData) {
if (cellData == 1) {
g.setColor(Color.DARK_GRAY);
g.fillRect(x + deltaX, y + deltaY, tileSize, tileSize);
} else if (cellData == 2) {
g.setColor(Color.GREEN);
g.fillRect(x + deltaX, y + deltaY, tileSize, tileSize);
} else if (cellData == 3) {
g.setColor(Color.YELLOW);
g.fillRect(x + deltaX, y + deltaY, tileSize, tileSize);
}
x += tileSize;
if (x == maze.length * tileSize) {
x = 0;
y += tileSize;
}
}
} g.setColor(Color.RED);
g.fillOval(getWidth() / 2, getHeight() / 2, playerDiam, playerDiam);
break;
case "gameOver":
g.setColor(Color.BLACK);
g.drawString("Game Over",getWidth() / 3 ,50 );
break;
case "paused":
g.setColor(Color.BLACK);
g.drawString("Paused", getWidth() / 3, 50);
break;
}
}
}
as start I would
clear maze
randomly add walls
create random path for all entry/exit points pairs present
clear the maze cells along them.
If you just need maze solver (some algos for maze generation needs them)
then look here How to speed up A* algorithm at large spatial scales?
with use of solver you can change algorithm to
clear maze
add random wall
if adding it still provides solution
loop bullet(2) N times
You need to be careful about how to add the walls
for example if you add just simple lines then the maze will look like this:
This is the code for it (uses the class from linked answer)
// generate random maze with path from x0,y0 to x1,y1 present, n walls
void A_star::generate(int x0,int y0,int x1,int y1,int n)
{
int x,y,i,j,dx,dy,l,*p;
// [clear map]
for (y=0;y<ys;y++)
for (x=0;x<xs;x++)
map[y][x]=A_star_space;
// temp space
p=new int [xs>>1]; if (p==NULL) return;
// generate n walls
for (i=0;i<n;i++)
{
// random start pos,dir,length
x =Random(xs);
y =Random(ys);
dx=Random(4);
l =Random(xs>>2)+2;
if (dx==0) { dx=+1; dy= 0; }
else if (dx==1) { dx=-1; dy= 0; }
else if (dx==2) { dx= 0; dy=+1; }
else if (dx==3) { dx= 0; dy=-1; }
// add wall to maze remember set cells (for remowal if needed)
for (j=0;l;l--,x+=dx,y+=dy)
if ((x>=0)&&(x<xs))
if ((y>=0)&&(y<ys))
if (map[y][x]!=A_star_wall)
{
p[j]=x; j++;
p[j]=y; j++;
map[y][x]=A_star_wall;
}
// is there solution?
compute(x0,y0,x1,y1);
// if not remowe last added wall
if (ps==0) for (;j;)
{
j--; y=p[j];
j--; x=p[j];
map[y][x]=A_star_space;
}
}
delete[] p;
}
generated by this code:
A_star map;
map.resize(256,256);
map.generate(5,5,250,250,500);
Related
I want the ball.move(); function in the code below to continue running after pressing space once. It only works if I continue pressing the space key.
void draw() {
if (start == true) {ball.move();}
}
void keyPressed() {
if (key == ' '){start = true;}
}
void keyReleased() {
if (key == ' ') {start = false;}
}
It's for a Pong game I am making and each time the ball hits the edge it is teleported to the center of the canvas. That´s when I want to be able to start the ball movement manually again.
Here is the whole code:
Ball ball;
Player player1;
Player player2;
int scorePlayer1 = 0;
int scorePlayer2 = 0;
PFont font;
boolean start;
void setup() {
size(1368,768);
frameRate(144);
noStroke();
ball = new Ball(width/2, height/2, 30);
player1 = new Player(15, height/2, 30, 150);
player2 = new Player(width-15, height/2, 30, 150);
ball.speedX = 10;
}
void draw() {
background(0);
textSize(40);
textAlign(CENTER);
font = loadFont("Arial-Black-48.vlw");
textFont(font);
ball.display();
if (start == true) {ball.move();}
player1.run();
player2.run();
//Score
if (ball.left() < 0) {
scorePlayer2 = scorePlayer2 + 1;
ball.x = width/2;
ball.y = height/2;
}
if (ball.right() > width) {
scorePlayer1 = scorePlayer1 +1;
ball.x = width/2;
ball.y = height/2;
}
text(scorePlayer1, width/2-75, 50);
text(scorePlayer2, width/2+75, 50);
//Collision
if (ball.top() < 0) {
ball.speedY = -ball.speedY;
}
if (ball.bottom() > height) {
ball.speedY = -ball.speedY;
}
if (ball.left() < player1.right() && ball.y > player1.top()-10 && ball.y < player1.bottom()+10) {
ball.speedX = -ball.speedX;
ball.speedY = map(ball.y - player1.y, -player1.h/2, player1.h/2, -5, 5);
}
if (ball.right() > player2.left() && ball.y > player2.top()-10 && ball.y < player2.bottom()+10) {
ball.speedX = -ball.speedX;
ball.speedY = map(ball.y - player2.y, -player2.h/2, player2.h/2, -5, 5);
}
if (player1.bottom() > height) {
player1.y = height-player1.h/2;
}
if (player1.top() < 0) {
player1.y = player1.h/2;
}
if (player2.bottom() > height) {
player2.y = height-player1.h/2;
}
if (player2.top() < 0) {
player2.y = player1.h/2;
}
}
//Movement
void keyPressed() {
player1.pressed((key == 'w' || key == 'W'), (key == 's' || key == 'S'));
player2.pressed((keyCode == UP), (keyCode == DOWN));
if (key == ' '){start = true;}
}
void keyReleased() {
player1.released((key == 'w' || key == 'W'), (key == 's' || key == 'S'));
player2.released((keyCode == UP), (keyCode == DOWN));
if (key == ' ') {start = false;}
}
class Ball {
float x;
float y;
float d;
float speedX;
float speedY;
color c;
//Constructor
Ball(float tempX, float tempY, float tempD){
x = tempX;
y = tempY;
d = tempD;
speedX = 0;
speedY = 0;
c = (255);
}
void display() {
fill(c);
ellipse(x,y,d,d);
}
void move() {
x = x + speedX;
y = y + speedY;
}
//Collision help
float top() {
return y-d/2;
}
float bottom() {
return y+d/2;
}
float left() {
return x-d/2;
}
float right() {
return x+d/2;
}
}
class Player {
float x, y;
float w, h;
float speedY = 0.0;
color c;
boolean moveUp = false, moveDown = false;
//Constructor
Player(float tempX, float tempY, float tempW, float tempH){
x = tempX;
y = tempY;
w = tempW;
h = tempH;
speedY = 0;
c = (255);
}
void run() {
display();
move();
}
void display() {
fill(c);
rect(x-w/2, y-h/2, w, h);
}
//Movement
void move() {
if (!moveUp && !moveDown) {speedY = speedY * 0.85;}
if (moveUp) {speedY -= 1;}
if (moveDown) {speedY += 1;}
speedY = max(-7.0, min(7.0, speedY));
y += speedY;
}
void pressed(boolean up, boolean down) {
if (up) {moveUp = true;}
if (down) {moveDown = true;}
}
void released(boolean up, boolean down) {
if (up) {moveUp = false;}
if (down) {moveDown = false;}
}
//Collision help
float top() {
return y-h/2;
}
float bottom() {
return y+h/2;
}
float left() {
return x-w/2;
}
float right() {
return x+w/2;
}
}
In the code below, you are setting start to true when the key is pressed and false when the press is done. You can simply remove the line that sets start to false when the key press is done and the ball will always move when the space is pressed.
//Movement
void keyPressed() {
player1.pressed((key == 'w' || key == 'W'), (key == 's' || key == 'S'));
player2.pressed((keyCode == UP), (keyCode == DOWN));
if (key == ' '){start = true;}
}
void keyReleased() {
player1.released((key == 'w' || key == 'W'), (key == 's' || key == 'S'));
player2.released((keyCode == UP), (keyCode == DOWN));
//if (key == ' ') {start = false;}
}
I suppose you want the ball to stop moving when space is pressed again. This can be done in your keyPressed method as well by toggling start instead of setting it to true. Something like if (key == ' '){start = !start;}
Your problem is that when you release the space bar, it sets the start field to false. Then when the next draw() method is called, it sees that start==false and so doesn't move the ball.
If you remove that line from the keyReleased method, then it should run correctly?
So I'm just making a 2d game in my spare time and I am having a hard time understanding why my collision code breaks after my character jumps but works when my character is jumping.
Relevant Code from the main class
public void collision() {
Rectangle body = jan.getBody();
int bodyX = (int) body.getX();
int bodyY = (int) body.getY();
if (bodyX < 0) {
body.setLocation(0, bodyY);
jan.setBody(body);
}
if (bodyX > 780) {
body.setLocation(780, bodyY);
jan.setBody(body);
}
if (bodyY > 360) {
body.setLocation(bodyX, 360);
jan.setBody(body);
}
}
public void actionPerformed(ActionEvent e) {
jan.update();
collision();
repaint();
}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_LEFT) {
jan.setDirection(-1);
} else if (keyCode == KeyEvent.VK_RIGHT) {
jan.setDirection(1);
} else if (keyCode == KeyEvent.VK_SPACE) {
jan.jump();
}
}
Relevant code from the Player Class
public void jump() {
int y = (int) body.getY();
if (y == 360) {
body.translate(0, -15);
yVelocity = 15;
}
}
public void update() {
int x = getDirection();
if (x == 1) {
if (xVelocity < terminalVelocity) {
xVelocity++;
}
}
if (x == -1) {
if (xVelocity > -terminalVelocity) {
xVelocity--;
}
}
if (x == 0) {
if (xVelocity < 0) {
xVelocity++;
} else if (xVelocity > 0) {
xVelocity--;
}
}
if (body.y < 360) {
yVelocity--;
}
body.translate(xVelocity, -yVelocity);
}
Any reasons for why my code breaks down after my character jumps?
The logic of collision undoes the clamping in X if Y is also out of bounds. Try clamping in both x and y and then update the body if there's a change:
public void collision() {
Rectangle body = jan.getBody();
int bodyX = (int) body.getX();
int bodyY = (int) body.getY();
int clampedBodyX = Math.min(Math.max(0, bodyX), 780);
int clampedBodyY = Math.min(Math.max(0, bodyY), 360);
if (bodyX != clampedBodyX || bodyY != clampedBodyY) {
body.setLocation(clampedBodyX, clampedBodyY);
jan.setBody(body);
}
}
I can draw lines, but the thickness is constant. I need to change the thickness when I press a button. In this example pressing 'w' will increase the thickness and pressing 'q' will decrease the thickness.
import java.awt.*;
import java.applet.*;
import sun.swing.SwingUtilities2;
public class draw extends Applet {
boolean isBlack = true;
Point startPoint;
Point points[];
int numPoints;
boolean drawing;
int n = 0;
#Override
public void init() {
startPoint = new Point(0, 0);
points = new Point[10000];
drawing = false;
resize(300, 400);
}
#Override
public void paint(Graphics g) {
if (n == 0) {
g.setColor(Color.red);
}
if (n == 1) {
g.setColor(Color.green);
}
if (n == 2) {
g.setColor(Color.blue);
}
if (n == 3) {
g.setColor(Color.black);
}
int oldX = startPoint.x;
int oldY = startPoint.y;
for (int i = 0; i < numPoints; ++i) {
g.drawLine(oldX, oldY, points[i].x, points[i].y);
oldX = points[i].x;
oldY = points[i].y;
}
}
#Override
public boolean keyDown(Event evt, int key) {
char keyChar = (char) key;
if (keyChar == 'w') {
n++;
if (n > 3) {
n = 0;
}
}
if (keyChar == 'q') {
n--;
if (n < 0) {
n = 3;
}
}
return true;
}
#Override
public boolean mouseDown(Event evt, int x, int y) {
if (!drawing) {
startPoint.x = x;
startPoint.y = y;
}
drawing = !drawing;
return true;
}
#Override
public boolean mouseMove(Event evt, int x, int y) {
if ((drawing) && (numPoints < 10000)) {
points[numPoints] = new Point(x, y);
++numPoints;
repaint();
}
return true;
}
}
But I can't calculate the thickness of the line, how would I do that?
You need to use the Graphics2D package:
Graphics2D g2 = SwingUtilities2.getGraphics2D(g);
g2.setStroke(new BasicStroke(n));
g2.drawLine(oldX, oldY, points[i].x, points[i].y);
I think that's is all you need. It's been awhile since I've worked with it.
I have a set of sprites that I am calling in a Java game, and when I had 3 sprites it worked fine, but when I add a fourth sprite, the repaint method is only called every other time.
Here is my minimal example,
Main class:
public class Maze extends JPanel implements ActionListener{
/**
* #param args
*/
int stage;
int dir;
int x = 32;
int y = 32;
Rectangle r = new Rectangle(x,y,10,10);
Draw D = new Draw();
public static ArrayList<Rectangle> walls = new ArrayList<Rectangle>();
public ArrayList<Image> spritesl = new ArrayList<Image>();
public ArrayList<Image> spritesd = new ArrayList<Image>();
public ArrayList<Image> spritesr = new ArrayList<Image>();
public ArrayList<Image> spritesu = new ArrayList<Image>();
BufferedImage image;
public Maze() throws IOException{
setBackground(Color.black);
setSize(672,672);
Timer timer = new Timer(2000,this);
timer.addActionListener(this);
timer.start();
//add sprites
for(int i = 1; i<5; i += 1){
spritesl.add(image = ImageIO.read(new File("C:/Users/Dave/Desktop/Sprites/left" + i + ".png")));
}
for(int i = 1; i<5; i += 1){
spritesd.add(image = ImageIO.read(new File("C:/Users/Dave/Desktop/Sprites/down" + i + ".png")));
}
for(int i = 1; i<5; i += 1){
spritesr.add(image = ImageIO.read(new File("C:/Users/Dave/Desktop/Sprites/right" + i + ".png")));
}
for(int i = 1; i<5; i += 1){
spritesu.add(image = ImageIO.read(new File("C:/Users/Dave/Desktop/Sprites/up" + i + ".png")));
}
}
public static void main(String[] args) throws IOException {
JFrame frame = new JFrame();
Maze ate = new Maze();
frame.addKeyListener(new Input());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(ate);
frame.setPreferredSize(new Dimension(688, 709));//16, 37
frame.setVisible(true);
frame.pack();
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
//call wall drawer
g.setColor(Color.gray);
D.draw(g);
g.setColor(Color.red);
//set animation
if(dir == 1){
g.drawImage(spritesu.get(stage-1),x,y, this);
}else if(dir == 2){
g.drawImage(spritesr.get(stage-1),x,y, this);
}else if(dir == 3){
g.drawImage(spritesd.get(stage-1),x,y, this);
}else if(dir == 4){
g.drawImage(spritesl.get(stage-1),x,y, this);
}
System.out.println("set");
}
#Override
public void actionPerformed(ActionEvent e) {
boolean up =false;
boolean right =false;
boolean down =false;
boolean left =false;
//next part tests each direction for collisions
if(Input.right){
right = true;
x += 4;
if(x>672-32){
x -= 4;
right = false;
}else{
for(int i = 0; i < walls.size(); i += 1){
if(new Rectangle(x, y, 30, 30).intersects(walls.get(i))){
x -= 4;
right = false;
}
}
}
}
if(Input.left){
left = true;
dir=4;
x-=4;
if(x<0){
x += 4;
left = false;
}else{
for(int i = 0; i < walls.size(); i += 1){
if(new Rectangle(x, y, 32, 32).intersects(walls.get(i))){
x += 4;
left = false;
}
}
}
}
if(Input.down){
down = true;
dir=3;
y+=4;
if(y>672-32){
y -= 4;
down = false;
}else{
for(int i = 0; i < walls.size(); i += 1){
if(new Rectangle(x, y, 32, 32).intersects(walls.get(i))){
y -= 4;
down = false;
}
}
}
}
if(Input.up){
up = true;
dir=1;
y-=4;
if(y<0){
y += 4;
up = false;
}else{
for(int i = 0; i < walls.size(); i += 1){
if(new Rectangle(x, y, 32, 32).intersects(walls.get(i))){
y += 4;
up = false;
}
}
}
}
//sets direction of animation
if(left||down||right||up){
if(left){
dir = 4;
}
if(down){
dir = 3;
}
if(right){
dir = 2;
}
if(up){
dir = 1;
}
stage += 1;
if(stage >= 4 || stage <= 0){
stage = 1;
}
System.out.println(stage);
}
repaint();
}
}
My input tester(probably not necessary, but its needed for the game to run):
public class Input implements KeyListener {
public static boolean left = false;
public static boolean right = false;
public static boolean up = false;
public static boolean down = false;
public static boolean space = false;
//test for keys
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT)
left = true;
if (key == KeyEvent.VK_RIGHT)
right = true;
if (key == KeyEvent.VK_UP)
up = true;
if (key == KeyEvent.VK_DOWN)
down = true;
if (key == KeyEvent.VK_SPACE)
space = true;
}
#Override
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT)
left = false;
if (key == KeyEvent.VK_RIGHT)
right = false;
if (key == KeyEvent.VK_UP)
up = false;
if (key == KeyEvent.VK_DOWN)
down = false;
if (key == KeyEvent.VK_SPACE)
space = false;
}
#Override
public void keyTyped(KeyEvent e) {}
}
and my Draw class:
public class Draw {
public void draw(Graphics g){
//draw everything
Maze.walls.clear();
g.fillRect(0, 0, 672, 32);
g.fillRect(0, 0, 32, 672);
g.fillRect(0, 640, 320, 32);
g.fillRect(352, 640, 320, 32);
g.fillRect(640, 0, 32, 320);
g.fillRect(640, 352, 32, 320);
Maze.walls.add(new Rectangle(0, 0, 672, 32));
Maze.walls.add(new Rectangle(0, 0, 32, 672));
Maze.walls.add(new Rectangle(0, 640, 320, 32));
Maze.walls.add(new Rectangle(352, 640, 320, 32));
Maze.walls.add(new Rectangle(640, 0, 32, 320));
Maze.walls.add(new Rectangle(640, 352, 32, 320));
}
}
now, this works and cycles three stages, but as soon as I change the stage max to 5, it only paints on stages 2 and 4, which are exactly the same. Can anyone tell me what I am doing wrong?
Swing "Timers coalesce events by default." As noted by #HOFE, re-reading your sprite images is likely slowing things down enough to trigger the effect. Instead, read the images into a List<Image> when the program starts.
Hey guys i'm making a maze game and I'm trying to figure out how to make a 2D collision smooth. Currently I have some really bad collision code that I thought up since I haven't done this part yet and it is glitchy and sometimes goes inside the wall then you can't get out.
My code:
public void checkCollision() {
Rectangle player_rectangle = new Rectangle(player.getX(),player.getY(),32,32);
for(Wall wall : walls) {
Rectangle wall_rectangle = new Rectangle(wall.getX(), wall.getY(), 32,32);
if(player_rectangle.intersects(wall_rectangle)) {
if(player.xspeed == 1) {
player.xspeed = 0;
player.x -= 1.2;
} else {
if(player.xspeed == -1) {
player.xspeed = 0;
player.x += 1.2;
}
else
if(player.yspeed == 1) {
player.yspeed = 0;
player.y -= 1;
} else {
if(player.yspeed == -1) {
player.yspeed = 0;
player.y += 1;
}
}
}
}
}
}
What is a better way to do the collision? here is a picture of the types of maps I will have:
EDIT:
New Collision code:
if (player_rectangle.intersects(wall_rectangle)) {
Rectangle intersection = (Rectangle) player_rectangle.createIntersection(wall_rectangle);
if (player.xspeed > 0) {
player.x -= intersection.getWidth();
}
if (player.yspeed > 0) {
player.y -= intersection.getHeight();
}
if (player.xspeed < 0) {
player.x += intersection.getWidth();
}
if (player.yspeed < 0) {
player.y += intersection.getHeight();
}
Print(Integer.toString(intersection.width) + ", " + Integer.toString(intersection.height));
}
Movement Code:
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_LEFT) {
xspeed = -1;
} else {
if(key == KeyEvent.VK_RIGHT) {
xspeed = 1;
} else {
if(key == KeyEvent.VK_UP) {
yspeed = -1;
} else {
if(key == KeyEvent.VK_DOWN) {
yspeed = 1;
}
}
}
}
}
Thanks for any help you can give me.
You can use Rectangle.createIntersection(Rectangle).
If the player moves to a positive direction, just subtract the width and height of the resulting Rectangle from his position, if he moves to a negative, add them.
Don't set the speed to zero, this could cause the player to hang.
EDIT
if (playerRectangle.intersects(wallRectangle) {
Rectangle intersection = (Rectangle) playerRectangle.createIntersection(wallRectangle);
if (player.xspeed > 0) {
player.x -= intersection.getWidth();
}
if (player.yspeed > 0) {
player.y -= intersection.getHeight();
}
if (player.xspeed < 0) {
player.x += intersection.getWidth();
}
if (player.yspeed < 0) {
player.y += intersection.getHeight();
}
}
EDIT2
As far as I know, keyPressed is only triggered when you press a key, and not when you release it. Try it like this:
private boolean up, down, left, right;
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KEyEvent.VK_UP) {
up = true;
}
...
}
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KEyEvent.VK_UP) {
up = false;
}
...
}
// Call this in the mainthread
public void updateMovement() {
if (up) {
player.xspeed = 1;
}
...
}
So in every frame, you update the movement, move the player and then check the collision.