I am trying to make a grid (with minimal code) that blocks can snap to. What I want is when the mouse is in the grid square, the block moves to that square. What I have written essentially says that if the X or Y are beyond the grid block times the size of the block, move to the next grid block. Currently, this code creates a 3x3 grid, though the code SHOULD generate infinite gridspaces. I cannot move the block outside of this 3x3 grid.
public class Player extends Entity {
public Player(double entSize, boolean collideA, boolean collideB, double x, double y) {
super(entSize, collideA, collideB, x, y);
}
public void init() {
Texture texFile = loadTexture("stone");
texture(false, true);
texFile.bind();
render();
}
void input() {
int gridPosX = 1;
int gridPosY = 1;
if(getX() > gridPosX*entSize) {
gridPosX += 1;
} if(getX() < gridPosX*entSize) {
gridPosX -= 1;
} if(getY() > gridPosY*entSize) {
gridPosY += 1;
} if(getY() < gridPosY*entSize) {
gridPosY -= 1;
}
this.x = gridPosX*entSize;
this.y = gridPosY*entSize;
}
}
The X and Y values are what define the blocks position and shape parameters.
Fixed by using for loops for the positive grid increments!
NEW CODE:
public class Player extends Entity {
public Player(double entSize, boolean collideA, boolean collideB, double x, double y) {
super(entSize, collideA, collideB, x, y);
}
public void init() {
Texture texFile = loadTexture("stone");
texture(false, true);
texFile.bind();
render();
}
void input() {
int gridPosX = 0;
int gridPosY = 0;
for(gridPosX = 0; getX() > gridPosX*entSize; gridPosX++) {
gridPosX += 0;
} if(getX() < gridPosX*entSize) {
gridPosX -= 1;
} for(gridPosY = 0; getY() > gridPosY*entSize; gridPosY++) {
gridPosY += 0;
} if(getY() < gridPosY*entSize) {
gridPosY -= 1;
}
this.x = gridPosX*entSize;
this.y = gridPosY*entSize;
}
}
Related
I am making a program in Java that makes a ball move on only the x-axis, but if R is pressed it reverses directions, or if P is pressed it pauses. I am not able to make it so that if I press P again, it un-pauses the movement and continues. I got the ball to be able to pause in place, but I can not continue to move it after
Code:
import java.awt.Color;
import GameTest.KeyPressExample.Player;
import hsa2.GraphicsConsole;
public class MainClass {
static final int WINW = 500;
static final int WINH = 500;
GraphicsConsole gc = new GraphicsConsole(WINW, WINH);
boolean pause = false;
private int y;
private int x;
int bx = 400;
int by = 300;
int xspeed = 1;
int size = 35;
public static void main(String[] args) {
new MainClass().runGame();
}
MainClass() {
gc.setTitle("Graphics test");
gc.setAntiAlias(true);
gc.setLocationRelativeTo(null);
gc.setBackgroundColor(Color.PINK);
gc.clear();
}
void Player(int x, int y) {
this.x = x;
this.y = y;
int width = 100;
int height = 50;
}
void runGame() {
while(true) {
if (!pause) {
moveBall();
drawGraphics();
}
gc.sleep(5);
}
}
void Keyboard() {
}
void moveBall() {
bx += xspeed;
if (bx < 0) {
bx = 0;
xspeed *= -1;
}
//this will stop the ball when moving
if (gc.isKeyDown('P')) {
pause = true;
xspeed *= 0;
}
// if R is pressed it goes the opposite way
if (gc.isKeyDown('R')) {
xspeed *= -1;
}
if (bx + size > WINW) {
bx = 0;
xspeed *= -1;
}
}
void drawGraphics() {
synchronized(gc) {
gc.setColor(Color.BLUE);
gc.clear();
gc.fillOval(bx, by, size, size);
}
}
}```
I'm working on a project where we are supposed to have rectangles of random sizes bounce off a wall and change color each time they bounce.
When you click on them, they are supposed to freeze in place and turn red. I'm just having trouble having them stop and for some reason they slow when one is clicked.
import java.util.Random;
public class Main {
public static void main(String[] args) {
MovingRectangles[] rectangles = new MovingRectangles[5];
Random rng = new Random();
for (int i = 0; i < rectangles.length; i++) {
rectangles[i] = new MovingRectangles(rng.nextDouble(), rng.nextDouble(), rng.nextDouble(), rng.nextDouble(), rng.nextDouble(), rng.nextDouble());
}
for (int g = 0; g < rectangles.length; g++) {
rectangles[g] = new MovingRectangles(
rng.nextDouble(),
rng.nextDouble(),
rng.nextDouble() / 50 - 0.01,
rng.nextDouble() / 50 - 0.01,
rng.nextDouble() * 0.04 + 0.03,
rng.nextDouble() * 0.04 + 0.03
);
}
while (true) {
StdDraw.clear();
for (int h = 0; h < rectangles.length; h++) {
rectangles[h].draw();
rectangles[h].update();
}
int count = 0;
for (int i =0; i < rectangles.length; i++) {
rectangles[i].draw();
if (StdDraw.mousePressed() && rectangles[i].containsPoint(StdDraw.mouseX(), StdDraw.mouseY())) {
rectangles[i].freeze();
}
if (rectangles[i].isFrozen()) {
count++;
StdDraw.show(25);
}
}
}
}}
This is the class for moving rectangles. Stackoverflow says I need to add context to explain what this code is.
import java.util.Random;
public class MovingRectangles {
private double x;
private double y;
private double vx;
private double vy;
private double hx;
private double hy;
private boolean isFrozen;
private int red;
private int green;
private int blue;
public MovingRectangles(double x, double y, double vx, double vy, double hx, double hy) {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
isFrozen = false;
this.hx = hx;
this.hy = hy;
randomColor();
}
public void randomColor() {
Random rng = new Random();
red = rng.nextInt(256);
blue = rng.nextInt(256);
green = rng.nextInt(256);
}
public void draw() {
if (isFrozen) {
StdDraw.setPenColor(StdDraw.RED);
} else {
StdDraw.setPenColor(red, green, blue);
}
StdDraw.filledRectangle(x, y, hx, hy);
}
public void update() {
x += vx;
y += vy;
if (x - hx < 0) {
vx *= -1;
x = 0 + hx;
randomColor();
}
if (x + hx > 1) {
vx *= -1;
x = 1 - hx;
randomColor();
}
if (y - hy < 0) {
vy *= -1;
y = 0 + hy;
randomColor();
}
if (y + hy > 1) {
vy *= -1;
y = 1 - hy;
randomColor();
}
}
public void freeze() {
isFrozen = true;
}
public boolean isFrozen() {
return isFrozen;
}
public boolean containsPoint(double a, double b) {
return
a > x - hx &&
a < x + hx &&
b > y - hy &&
b < y + hy;
}
}
The only other thing I need to add is for it to print "You Win" when all five of the boxes have been clicked. thanks for any help.
My thought is that you're not stopping the actual update of the rectangle.
In your MovingRectangles class...
public void update() {
if(!this.isFrozen) {
{...your code...}
}
}
add at the very beginning of update method line like
if(isFrozen) return;
it should stop your rectangle.
the another way (if you don't want to touch rectangle class).
after
for (int h = 0; h < rectangles.length; h++) {
rectangles[h].draw();
add
if(!rectangles[h].isFrozen()) rectangles[h].update();
This update to draw fixed the problem I was having.
public void draw() {
if (isFrozen) {
StdDraw.setPenColor(StdDraw.RED);
StdDraw.filledRectangle(x, y, hx, hy);
vx = 0;
vy = 0;
} else {
StdDraw.setPenColor(red, green, blue);
}
StdDraw.filledRectangle(x, y, hx, hy);
}
I'm trying to create a Roomba program with a ball that bounces around the screen that cleans the tiles that it passes over. The program should start with all grey tiles and when the ball passes over them then the tiles turn white. Currently I have the ball that bounces around everywhere and a grid method which creates a 5x5 grid.
I have encountered two problems:
I cannot make the grid and the ball appear in the same simulation while running the program, it's either one or the other.
I'm having trouble with finding a way to analyze if the ball has passed over certain squares in the grid, perhaps I need to create an object for the grid/ball?
My code:
import edu.princeton.cs.introcs.StdDraw;
public class Roomba {
private static int windowWidth = 200;
private static int windowHeight = 200;
private static double x = 100;
private static double y = 100;
private static double vx = 2;
private static double vy = 4;
private static int radius = 5;
private static boolean inGame = true;
public static void updateLocations() {
x += vx;
y += vy;
}
public static void drawGrid() {
StdDraw.setScale(0, 5);
int[][] grid = new int[5][5];
for (int x = 0; x < grid.length; x++) {
for (int y = 0; y < grid.length; y++) {
grid[x][y] = 255;
}
}
for (int x = 0; x < grid.length; x++) {
for (int y = 0; y < grid.length; y++) {
StdDraw.square(x, y, 1);
}
}
}
public static void updateVelocities() {
if (y + radius >= windowHeight) {
vy = -vy;
} else if (y - radius <= 0) {
vy = -vy;
}
if (x >= 194 || x <= 6) {
vx = -vx;
}
}
public static void setBackground() {
StdDraw.clear(StdDraw.GRAY);
// drawGrid();
}
public static void drawBall() {
StdDraw.setPenColor(StdDraw.BLACK);
StdDraw.filledCircle(x, y, radius);
// StdDraw.setPenColor(StdDraw.RED);
// StdDraw.filledSquare(x + 3, y + 3, 1);
StdDraw.setPenColor(StdDraw.BLACK);
StdDraw.text(100, 70, "x is: " + x + " y is: " + y);
}
public static void draw() {
setBackground();
drawBall();
}
public static void main(String[] args) {
StdDraw.setCanvasSize(800, 800);
StdDraw.setXscale(0, windowWidth);
StdDraw.setYscale(0, windowHeight);
while (true) {
if (inGame) {
draw();
updateVelocities();
updateLocations();
} else {
StdDraw.text(100, 100, "Game Over");
}
// change to if all tiles have been cleaned
// if (x + radius > windowWidth || x - radius < 0) {
// inGame = false;
// }
StdDraw.show(20);
}
}
}
Maybe the background is being drawn over the ball or vice verse? Try to draw the ball first then the background? Make sure the ball is actually being rendered at the correct size and not as the entire screen. I'm not to familiar with 2D graphics but maybe there is some z fighting?
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have been working on a Breakout game and have just about everything done except for the brick collision. The ball bounces of the wall and paddle fine, but when it comes to the brick it goes straight through them. I'm pretty sure the problem is in the checkBrick() part of the main class, but have no idea what to do about it.
Main Class:
import java.awt.*;
import java.awt.event.KeyEvent;
import java.applet.*;
import java.util.Random;
import javax.swing.JOptionPane;
public class Breakout extends Applet implements Runnable {
Ball ball = new Ball();
Paddle paddle = new Paddle(135, 375);
Brick[] brick = new Brick[50];
private int bX[] = new int[50];
private int bY[] = new int[50];
private int bW[] = new int[50];
private int bH[] = new int[50];
Thread t;
Random trajectory = new Random();
boolean lose;
Image buffer = null;
// The life cycle of the Applet
// Sets up window
public void init() {
setSize(377, 500);
buffer = createImage(377, 500);
// setBackground(Color.black);
System.out.println("init()");
}
public void start() {
if (t == null) {
t = new Thread(this);
t.start();
}
System.out.println("start()");
}
public void run() {
System.out.println("run()");
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
while (!lose) {
ball.move();
paddle.move();
checkWall();
checkPaddle();
checkBrick();
ball.move();
repaint();
try {
Thread.sleep(30);
} catch (InterruptedException ex) {
}
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
}
JOptionPane.showMessageDialog(null, "Game Over");
System.out.println("Termintated");
System.exit(0);
}
public void stop() {
System.out.println("stop()");
}
public void destroy() {
System.out.println("destroy()");
}
public void paint(Graphics g) {
Graphics screen = null;
screen = g;
g = buffer.getGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, 377, 500);
createBricks(g);
createPaddle(g);
createBall(g);
screen.drawImage(buffer, 0, 0, this);
}
public void update(Graphics g) {
paint(g);
}
private void createBricks(Graphics g) {
int brickIndex = 0;
int brickX = 15, brickY = 160;
int brickW = 30, brickH = 10;
for (int i = 0; i <= 4; i++) {
brickX = 15;
brickY -= 20;
for (int n = 0; n < 10; n++) {
brick[brickIndex] = new Brick();
brick[brickIndex].setBounds(brickX, brickY, brickW, brickH);
bX[brickIndex] = brick[brickIndex].x();
bY[brickIndex] = brick[brickIndex].y();
bW[brickIndex] = brick[brickIndex].w();
bH[brickIndex] = brick[brickIndex].h();
brick[brickIndex].setColor(i);
brick[brickIndex].paint(g);
brickIndex++;
brickX += 35;
}
}
}
private void createPaddle(Graphics g) {
paddle.paint(g);
}
private void createBall(Graphics g) {
ball.paint(g);
}
private void checkWall() {
// If ball hits right wall it will bounce
if ((ball.getX() + ball.getR()) >= 380) {
ball.setVX(trajectory.nextInt(2) + -3);
}
// If ball hits left wall it will bounce
if ((ball.getX() - ball.getR()) < -10) {
ball.setVX(trajectory.nextInt(4) + 1);
}
// If ball hits ceiling it will bounce
if ((ball.getY() + ball.getR()) < 12)
ball.setVY(trajectory.nextInt(5) + 1);
// If ball goes through floor it will subtract a life
if ((ball.getY() + ball.getR()) > 515)
lose = true;
}
private void checkBrick() {
for (int i = 0; i < 50; i++) {
int tempX, tempY, tempW, tempH;
tempX = bX[i];
tempY = bY[i];
tempW = bW[i];
tempH = bH[i];
if ((ball.getX() + ball.getR()) < (tempX + tempW)
&& (ball.getX() + ball.getR()) >= tempX) {
if ((ball.getY() + ball.getR()) > (tempY + tempH)
&& (ball.getY() + ball.getR()) <= tempY) {
System.out.println("Brick " + i + " has been hit.");
}
}
}
}
private void checkPaddle() {
// Check for paddle
if ((ball.getX() + ball.getR()) < (paddle.getX() + 100)
&& (ball.getX() + ball.getR()) >= paddle.getX() + 5) {
if ((ball.getY() + ball.getR()) > (paddle.getY() - 5)
&& (ball.getY() + ball.getR()) <= (paddle.getY() + 5)) {
ball.setVX((trajectory.nextInt(7) + -2) + 1);
ball.setVY(trajectory.nextInt(1) + -3);
}
}
}
// Key Detectors
public boolean keyDown(Event e, int key) {
if (key == Event.RIGHT) {
paddle.setVX(0);
if ((paddle.getX() + 100) < 377)
paddle.setVX(10);
}
if (key == Event.LEFT) {
paddle.setVX(0);
if (paddle.getX() > 0)
paddle.setVX(-10);
}
return true;
}
// To make sure it doesn't just keep moving one way
public boolean keyUp(Event e, int key) {
paddle.setVX(0);
return true;
}
}
Ball Class:
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
public class Ball
{
private int x, y; //Position
private int vx, vy; //Velocity
private int r; //radius
//constructor
public Ball()
{
x = 177;
y = 315;
vx = 0;
vy = 5;
r = 15;
}
public void paint(Graphics g)
{
g.setColor(Color.white);
g.fillOval(x, y, r, r);
}
//returns the x of origin
public int getX()
{
return x;
}
//returns the y of origin
public int getY()
{
return y;
}
public int getVX()
{
return vx;
}
//returns the y of origin
public int getVY()
{
return vy;
}
//returns the radius r of the ball
public int getR()
{
return r;
}
//sets the velocity of x to a different value
public void setVX(int vx)
{
this.vx = vx;
}
//sets the velocity of y to a different value
public void setVY(int vy)
{
this.vy = vy;
}
//sets the x value
public void setX(int x)
{
this.x = x;
}
//sets the y value
public void setY(int y)
{
this.y = y;
}
//starts making the ball move by changing its coords
public void move()
{
x+= vx;
y+= vy;
}
}
Paddle Class:
import java.awt.Color;
import java.awt.Graphics;
public class Paddle {
// declares variables for x and y coordinates
int x, y;
//The velocity of to move paddle
int vx;
// constructor that takes in x and y coordinates for paddle
public Paddle(int x, int y)
{
this.x = x;
this.y = y;
}
public void paint(Graphics g)
{
// paints paddle
g.setColor(Color.WHITE);
g.fillRect(x, y, 100, 15);
g.setColor(Color.GREEN);
g.drawRect(x, y, 100, 15);
}
// gets x coordinate of paddle
public int getX() {
return x;
}
// sets x coordinate of paddle
public void setX(int x) {
this.x = x;
}
// gets y coordinate of paddle
public int getY() {
return y;
}
// sets y coordinate of paddle
public void setY(int y) {
this.y = y;
}
public void setVX(int vx)
{
this.vx = vx;
}
//Moves the paddle
public void move()
{
x+=vx;
}
}
Brick Class:
import java.awt.Color;
import java.awt.Graphics;
public class Brick
{
private Color color =(Color.cyan);
private int x, y, w, h;
public Brick()
{
//Garbage values that are there just for declaration
x = 0;
y = 0;
w = 10;
h = 10;
}
//Sets color for the brick
public void setColor(int paintC)
{
switch(paintC)
{
case 0:
color = (Color.magenta);
break;
case 1:
color = (Color.blue);
break;
case 2:
color = (Color.yellow);
break;
case 3:
color = (Color.orange);
break;
default:
color = (Color.red);
break;
}
}
//Sets the location then size of the brick
public void setBounds(int x, int y, int w, int h)
{
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
//returns x value
public int x()
{
return this.x;
}
//returns y value
public int y()
{
return this.y;
}
//returns width value
public int w()
{
return this.w;
}
//returns height value
public int h()
{
return this.h;
}
//Sets x for the brick
public void setX(int x)
{
this.x = x;
}
//Sets y for the brick
public void setY(int y)
{
this.y = y;
}
public void setW(int w)
{
this.w = w;
}
public void setH(int h)
{
this.h = h;
}
public void paint(Graphics g)
{
g.setColor(color);
g.fillRect(x, y, w, h);
g.setColor(Color.green);
g.drawRect(x, y, w, h);
}
}
I've begin running over your code, quite frankly can't be bothered trying to figure out your logic, but what I believe you're trying to deduce is if the brick "contains" the ball, rather then if the ball intersects with the brick.
You don't care how much of the ball or brick are intersecting, only if the they do...for example...
private void checkBrick() {
int tx = ball.getX();
int ty = ball.getY();
int tw = ball.getR();
int th = ball.getR();
tw += tx;
th += ty;
for (int i = 0; i < 50; i++) {
int tempX, tempY, tempW, tempH;
tempX = bX[i];
tempY = bY[i];
tempW = bW[i];
tempH = bH[i];
int rw = tempW + tempX;
int rh = tempH + tempY;
// overflow || intersect
if ((rw < tempX || rw > tx) &&
(rh < tempY || rh > ty) &&
(tw < tx || tw > tempX) &&
(th < ty || th > tempY)) {
System.out.println("Hit");
}
}
}
Now, I stole this from Rectangle#intersects
Basically, if you used the geometry class from the 2D Graphics API, you could reduce this down to...
private void checkBrick() {
Rectangle b = new Rectangle(ball.getX(), ball.getY(), ball.getR(), ball.getR());
for (int i = 0; i < 50; i++) {
int tempX, tempY, tempW, tempH;
tempX = bX[i];
tempY = bY[i];
tempW = bW[i];
tempH = bH[i];
Rectangle brick = new Rectangle(tempX, tempY, tempW, tempH);
System.out.println("brick = " + brick);
if (b.intersects(brick)) {
System.out.println("Break");
}
}
}
And, yes, I did actually run your code
The problem is that the method checkBrick() is not changing anything, it is just printing if the ball has a collision with the brick.
You may want to change the Ball velocity, as you did within checkWall() and checkPaddle().
private void checkBrick() {
for (int i = 0; i < 50; i++) {
...
if (...) {
ball.setVX(...); // Add these lines setting the correct values
ball.setVY(...);
}
}
}
You may also want to check if your if-conditions are correct, and do what you expected.
Assuming tempH is positive,
((ball.getY() + ball.getR()) > (tempY + tempH)
&& (ball.getY() + ball.getR()) <= tempY)
can't ever be true. The > needs to be < and the <= needs to be >=.
Additionally, you'll need to take some kind of action if the brick is hit, rather than just printing out the fact. Sorry, I'm not sure what's supposed to happen - does the brick disappear? Or the ball bounce? Or both?
Second answer (in addition to other answer which I believe is ALSO a problem), your logic is asking if the ball is contained within a brick, but when you create the ball its radius is greater than the height of a brick, so even correcting that logic won't fix the problem.
You should refactor your code to make it read out like natural language, this would help a lot with debugging (or writing less bugs in the first place!) i.e.
in brick class:
public int bottom()
{
return y;
}
public int top()
{
return y + h;
}
in ball class:
public int bottom()
{
return y - r;
}
public int top() {
return y + r;
}
then in main class:
private boolean withinY(brick) {
return (ball.bottom => brick.bottom() && ball.top =< brick.top());
}
then the logic reads nicer (psuedo):
foreach brick in wall {
if (ball.withinY(brick) and ball.withinX(brick))
BAM!!
}
You're checking if the ball is between the left and right side of the brick, but then checking if the ball is both above AND below the brick, because you've got your greater than and less than's mixed up. Also the center of the ball needs to be subtracted from it's Y position.
if ((ball.getY() + ball.getR()) **>** (tempY + tempH) &&
(ball.getY() **+** ball.getR()) **<=** tempY)
could be
if ((ball.getY() + ball.getR()) < (tempY + tempH) &&
(ball.getY() - ball.getR()) >= tempY)
but I'd suggest finding if the top of the ball is between the top and bottom of the brick, OR if the bottom of the ball is between the top and bottom of the brick:
if (((ball.getY() + ball.getR()) < (tempY + tempH) && (ball.getY() - ball.getR()) >= tempY)) ||
((ball.getY() - ball.getR()) < (tempY + tempH) && (ball.getY() - ball.getR()) >= tempY))) {
CODE
}
And use similar logic for finding between left and right sides of the brick
I've been working on this game with LWJGL for a few weeks now. Ever since I added the ability to jump, the upward collision has been giving me a lot of problems.
The game is a 2D tile-based sidescroller. Overall, the collision is almost perfect except for when the player jumps. At first I thought "Oh, maybe I just need to change the jumping mechanics," but then I realized that it only happens when the player is passed a certain x coordinate.
Now, for the actual problem itself: if the player jumps when passed a certain x coordinate, they will pass through the tile and testing for top collision returns false.
This is the entire Player class:
package Minecraft2D;
import static Minecraft2D.World.BLOCK_SIZE;
import Minecraft2D.Tools.Tools;
import Minecraft2D.UI.Inventory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import static Minecraft2D.Boot.*;
import org.lwjgl.util.Rectangle;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
public class Player {
private float x;
private float y;
public int width = 32;
public int height = 50;
private float DX = 0;
private float DY = 0;
private Texture left = null;
private Texture right = null;
Texture texture = null;
public boolean direction[] = { false, false, false, false };
public boolean collision = false;
public boolean ground = false;
public boolean jump = false;
public boolean top = false;
public Player(float x, float y) {
this.x = x;
this.y = y;
try {
this.left = TextureLoader.getTexture("PNG", new FileInputStream(new File(path + "player_left.png")));
this.right = TextureLoader.getTexture("PNG", new FileInputStream(new File(path + "player_right.png")));
this.texture = this.right;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void draw() {
Tools.drawTexture((int)x, (int)y, width, height, texture);
}
public void checkCollision(Player player, Block block) {
if (player.getY() < block.getY() + BLOCK_SIZE && player.getX() < block.getX() + BLOCK_SIZE && player.getY() + this.height > block.getY() && player.getX() + this.width > block.getX() && block.getType() != BlockType.AIR) {
Rectangle top = new Rectangle();
top.setBounds((int) player.x + 4, (int) player.y + 1, this.width - 8, 1);
Rectangle bottom = new Rectangle();
bottom.setBounds((int) player.x + 4, (int) player.y + this.height, this.width - 8, 1);
Rectangle left = new Rectangle();
left.setBounds((int) player.x, (int) player.y + 1, 1, this.height - 5);
Rectangle right = new Rectangle();
right.setBounds((int) player.x + player.width, (int) player.y + 1, 1, this.height - 5);
Rectangle blok = new Rectangle();
blok.setBounds((int) block.getX(), (int) block.getY(), BLOCK_SIZE, BLOCK_SIZE);
if (bottom.intersects(blok)) {
player.setY((block.getY() - this.height - 1));
ground = true;
jump = false;
} else if (top.intersects(blok)) {
DY = 0;
this.top = true;
y -= (player.y) - (block.getY() + BLOCK_SIZE);
}
if (!top.intersects(blok)) {
if (left.intersects(blok)) {
player.setX(block.getX() + this.width);
} else if (right.intersects(blok)) {
player.setX(block.getX() - this.width);
}
}
} else {
collision = false;
ground = false;
}
if (!collision && !jump) {
setDY(.003f);
}
if (ground && !jump) {
DY = 0;
}
if (jump && DY < 0.003f) {
DY += 0.0001;
} else {
// jump = false;
}
if (top) {
DY = 0f;
top = false;
}
x += DX;
y += DY;
if (x > Boot.SCREEN_WIDTH) {
x = 0;
}
if (x < 0) {
x = Boot.SCREEN_WIDTH;
}
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public void setDX(float dx) {
this.DX = dx;
}
public void setDY(float dy) {
this.DY = dy;
}
public void setJump() {
if (!jump) {
jump = true;
ground = false;
DY = -0.13f;
y -= 1;
}
}
public void setTexture(int tex) {
if (tex == 0) {
this.texture = this.left;
}
if (tex == 1) {
this.texture = this.right;
}
}
}
==============
EDIT: I have no clue why, but as my character moves closer to the map's 0 x-coordinate, the character's y coordinate increases very slowly. This probably has something to do with the problem I have been getting. I am looking into it and I have a suspicion that it may have something to do when I cast the player's x and y values from doubles to integers for use in the top, bottom, left, and right Rectangles.
EDIT again:
I don't know if this matters, but I have been checking collision like this: (This is in the "Boot" class.)
private void checkCollision() {
for (int x = 0; x < BLOCKS_WIDTH - 1; x++) {
for (int y = 0; y < BLOCKS_HEIGHT - 1; y++) {
Block blk = grid.getAt(x, y);
player.checkCollision(blk);
}
}
}
Why are you passing a player into checkCollision? It seems like you should not be passing in a player, but instead using the members of the player that's calling the checkCollision method. I think that may be leading to some confusion for you. Such as:
y -= (player.y) - (block.getY() + BLOCK_SIZE);
This looks like you are trying to push the player below the block b/c they intersected it during their jump. If that's the case, it should just be
y = (block.getY() + BLOCK_SIZE);
I would remove the player from the function argument and rewrite the function and see what you get. Hope that helps.
EDIT
Your comment states that you can no longer pass the player into the function. Not sure about your exact implementation, but here's what games that I have typically seen look like:
public class Player
{
private int x, y, dx, dy;
public void checkCollision(Block block)
{
if (isTopCollision(block))
fall(block.getY() + block.getHeight());
}
private boolean isTopCollision(Block block)
{
return y > block.getY() + block.getSize() && y < block.getY();
}
private void fall(int adjustedY)
{
y = adjustedY;
top = true;
dy = 0;
// etc
}
}
public class MyGame
{
public void gameloop()
{
for (Block b : blocks)
player.checkCollision(b);
}
}