How to constrain sprite movement within isometric boundaries in libgdx? - java

I am currently generating an isometric map which should allow some sprites to move randomly within its bounds. My sprites, or 'humans' do move within a specified constraint however it is not the correct boundaries I wish to set it to. Below is my code.
public class Human implements Entity {
private int[][] map;
public static final int TILE_WIDTH = 34;
public static final int TILE_HEIGHT = 34;
private int min = 100;
private int max = 200;
private Texture img;
// position variable
private Vector2 pos;
private float time;
public Human() {
img = new Texture(Gdx.files.internal("humanFF.png"));
// coordinates of human initial position
pos = new Vector2(9, 220);
// for locking movement if need be.
time = 2;
map = randomGenerator();
}
#Override
public void render(SpriteBatch batch) {
batch.draw(img, pos.x, pos.y);
}
#Override
public void update(float delta) {
time += delta;
Random rand = new Random();
int upperbound = 2;
double double_random = rand.nextDouble(upperbound);
// lock human, can only move once every 2 secs.
if (time > 0) {
move();
time = 0;
}
}
private void move() {
/** Calculation **/
for (int row = map.length - 1; row >= 0; row--) {
for (int col = map.length - 1; col >= 0; col--) {
float x = (col - row) * (TILE_WIDTH / 2f - 2);
float y = (col + row) * (TILE_HEIGHT / 4f);
}
}
// after calculation, mapWidth is 525 pixels.
int mapWidth = map.length * (TILE_WIDTH / 2 - 2);
// after calculation, mapHeight is 280 pixels.
int mapHeight = map.length * (TILE_HEIGHT / 4);
// Calculate the minimum and maximum x-coordinates.
float minX = 0;
float maxX = mapWidth - TILE_WIDTH;
if (maxX < 0) {
maxX = 0;
}
// max-x coordinate is 491.0. min-x coordinate is 0.0.
// Calculate the minimum and maximum y-coordinates.
float minY = 0;
float maxY = mapHeight - TILE_HEIGHT;
if (maxY < 0) {
maxY = 0;
}
// check the position of human against map boundaries
if (pos.x < minX) {
pos.x = minX;
} else if (pos.x > maxX) {
pos.x = maxX;
}
if (pos.y < minY) {
pos.y = minY;
} else if (pos.y > maxY) {
pos.y = maxY;
}
// min-y coordinate is 0.0, max-y coordinate is 246.0.
// a variable to store a random generated value between 100 and 200.
int a = (int) (Math.random() * (max - min + 1) + min);
float newX = pos.x;
float newY = pos.y;
// move up
if (a <= 125) {
newX -= 15;
newY += 8.5;
}
// move down
else if (a <= 150 && a > 125) {
newX += 15;
newY -= 8.5;
}
// move left
else if (a <= 175 && a > 150) {
newX -= 15;
newY -= 8.5;
}
// move right
else if (a <= 200 && a > 175) {
newX += 15;
newY += 8.5;
}
if (newX >= minX && newX <= maxX && newY >= minY && newY <= maxY) {
pos.x = newX;
pos.y = newY;
}
}
public int[][] randomGenerator() {
Random r = new Random();
int Size = r.nextInt(35, 36);
int[][] map = new int[Size][Size];
for(int row = 0; row < map.length; row++) {
for(int col = 0; col < map.length; col++) {
int Number = r.nextInt(10);
if(Number == 0) {
map[row][col] = 0;
} else if (Number == 1) {
map[row][col] = 1;
}
else if (Number == 2) {
map[row][col] = 2;
}
else if (Number == 3) {
map[row][col] = 3;
}
else if (Number == 4) {
map[row][col] = 4;
}
else if (Number == 5) {
map[row][col] = 5;
}
else if (Number < 8) {
map[row][col] = 6;
}
else {
map[row][col] = 7;
}
}
}
map[0][0] = 1;
return map;
}
}
Based on the above, I am generating a random value which defines the movement of my 'humans' thus adding or subtracting from their x and y positions. In my attempt to tackle the problem of these sprites moving outside of my isometric map, I tried to calculate my mapWidth, mapHeight, min-x, max-x, min-y and max-x and then checking the position of my human against these boundaries to determine their movement.
Although these sprites now move within a constraint, it is not same dimension as my isometric map, but are now constrained to a rectangular-shaped boundary. How do I modify my code so that the sprites only move within the isometric map I have generated?
Below is a photo for visualisation.

The coordinate system you use for Human enties is ordinary orthogonal, you don't map these coordinates to an isometric view but you -have to- map them onto the isometric background. Screen coordinate system is basically different from the isometric one. When you render you need to map coordinates so that
(0,0)-> left corner
(0,maxY)->top corner
(maxX,maxY)->right corner
(maxX,0)->bottom corner
See here for to and back(map screen touch events to the map etc) conversion LibGdx render a sprite on top of a isometric tile

Related

How to convert the mouse position in pixels into the row and column on the grid?

I am basically making a battleship guessing game where you have to the position of a ship by the click of your mouse. When a position of the ship is guessed correctly it deletes that ship cell from the array and when every cell is guessed correctly, the game is over.
What I am now struggling on is to
keep the ship cells within the canvas
convert the mouse position in pixels into the row and column on the grid
if the guess is correct, add the guess to the hit array and if missed adding it to the miss array.
when a guess is made, in addition to colouring the cell, print either “Hit!” or “Miss!” on the cell
sinking the ship when all cells have been hit
In your code you've mixed rows and columns. The x coordinate goes from the left to the right, this are the columns. The y axis goes from the top to the bottom and corresponds to the rows.
Don't store column, row, hit and miss in arrays. But use 2-dimensional arrays to store the position of the ship and the positions of mouse clicks:
boolean [][] ship;
boolean [][] click;
keep the ship cells within the canvas
If the direction is horizontal, then the x start position of the ship has to be less than NUM_COLS - shipLength:
randomX = (int)random(NUM_COLS - shipLength);
randomY = (int)random(NUM_ROWS);
If the direction is horizontal, then the y start position of the ship has to be less than NUM_ROWS - shipLength:
randomX = (int)random(NUM_COLS);
randomY = (int)random(NUM_ROWS - shipLength);
Call randomShip in setup rather than draw:
void setup() {
size(600, 500);
randomShip();
println(store);
}
void draw() {
// randomShip(); <---- delete
drawCells (row, column, shipLength, (255) );
}
Generate the random position and size of the ship in randomShip;
void randomShip () {
ship = new boolean[NUM_COLS][NUM_ROWS];
click = new boolean[NUM_COLS][NUM_ROWS];
shipLength = (int)random (3, 8);
int store = (int)random(vert, horz);
if (store >= 0) {
int randomX = (int)random(NUM_COLS - shipLength);
int randomY = (int)random(NUM_ROWS);
for (int i = 0; i < shipLength; i++ ) {
ship[randomX + i][randomY] = true;
}
} else {
int randomX = (int)random(NUM_COLS);
int randomY = (int)random(NUM_ROWS - shipLength);
for (int i = 0; i < shipLength; i++ ) {
ship[randomX][randomY+1] = true;
}
}
println(shipLength);
}
convert the mouse position in pixels into the row and column on the grid
if the guess is correct, add the guess to the hit array and if missed adding it to the miss array.
The cell which was clicked can be get by the dividing the mouse coordinates mouseX and mouseY by CELLSIZE
int cell_x = mouseX / CELLSIZE;
int cell_y = mouseY / CELLSIZE;
Store mark the clicked cells and count the hits and miss in mouseClicked:
void mouseClicked () {
int cell_x = mouseX / CELLSIZE;
int cell_y = mouseY / CELLSIZE;
if (!click[cell_x][cell_y]) {
click[cell_x][cell_y] = true;
if ( ship[cell_x][cell_y] ) {
hitCount ++;
} else {
missCount ++;
}
}
}
when a guess is made, in addition to colouring the cell, print either “Hit!” or “Miss!” on the cell
Evaluate the ship position (ship[][]) and clicked positions (click[][]) in drawCells. Draw the cells and the text dependent on the states in 2 nested loops:
void drawCells(int colour) {
for (int i = 0; i < NUM_COLS; i++) {
for (int j = 0; j < NUM_ROWS; j++) {
float x = i * CELLSIZE;
float y = j * CELLSIZE;
if (ship[i][j]) {
fill (colour);
rect(x, y, CELLSIZE, CELLSIZE);
}
if (click[i][j]) {
fill(255, 0, 0);
textSize(15);
text(ship[i][j] ? "hit" : "miss", x+10, y+30);
}
}
}
}
sinking the ship when all cells have been hit
Handle the end of the game in draw:
e.g.
void draw() {
drawCells(255);
if (hitCount == shipLength ) {
// [...]
}
}
Full code listing:
final int CELLSIZE = 50;
final int NUM_ROWS = 10;
final int NUM_COLS = 12;
int horz = (int)random(50);
int vert = (int)random(-50);
int store;
int shipLength;
boolean [][] ship;
boolean [][] click;
int hitCount = 0;
int missCount = 0;
void setup() {
size(600, 500);
randomShip();
println(store);
}
void draw() {
drawCells(255);
if (hitCount == shipLength ) {
// [...]
}
}
void drawCells(int colour) {
for (int i = 0; i < NUM_COLS; i++) {
for (int j = 0; j < NUM_ROWS; j++) {
float x = i * CELLSIZE;
float y = j * CELLSIZE;
if (ship[i][j]) {
fill (colour);
rect(x, y, CELLSIZE, CELLSIZE);
}
if (click[i][j]) {
fill(255, 0, 0);
textSize(15);
text(ship[i][j] ? "hit" : "miss", x+10, y+30);
}
}
}
}
void randomShip () {
ship = new boolean[NUM_COLS][NUM_ROWS];
click = new boolean[NUM_COLS][NUM_ROWS];
hitCount = 0;
missCount = 0;
shipLength = (int)random (3, 8);
int store = (int)random(vert, horz);
if (store >= 0) {
int randomX = (int)random(NUM_COLS - shipLength);
int randomY = (int)random(NUM_ROWS);
for (int i = 0; i < shipLength; i++ ) {
ship[randomX + i][randomY] = true;
}
} else {
int randomX = (int)random(NUM_COLS);
int randomY = (int)random(NUM_ROWS - shipLength);
for (int i = 0; i < shipLength; i++ ) {
ship[randomX][randomY+1] = true;
}
}
println(shipLength);
}
void mouseClicked () {
int cell_x = mouseX / CELLSIZE;
int cell_y = mouseY / CELLSIZE;
if (!click[cell_x][cell_y]) {
click[cell_x][cell_y] = true;
if ( ship[cell_x][cell_y] ) {
hitCount ++;
} else {
missCount ++;
}
}
}

Image edge detection algorithm: creating a 2D mesh

Let's first start off with what I am trying to do. I would like to be able to take PNG file with a transparent background and find anywhere from 90 to 360 points along the edge of the subject of the image. Here is a rough example of what I mean. Given this image of Mario and Yoshi:
I want to make a circle that is centered at the center of the image with a diameter slightly larger than the largest side of the image to serve as a reference. Then, I want to go around the circle at set intervals, and trace a line towards the center until it hits a non-transparent pixel. Here is what that would look like:
I have attempted to implement this a few different times, all of which failed, and I was hoping to get some guidance or insight as to what I am doing wrong. Here is an image of the math I am using behind the code (sorry if the quality is not great, I don't have a scanner):
The Line 1 is either the top, bottom, left or right edge of the image, and Line 2 goes through the center of the circle at the given angle. The point where lines 1 and 2 intersect should be on the edge of the image, and is where we should start looking for the edge of the image's subject.
Here is the code that I came up with from this idea. I did it in Java because BufferedImage is really easy to use, but I am going to translate this over to C# (XNA) for the final product.
public class Mesh {
private int angleA, angleB, angleC, angleD;
private BufferedImage image;
private Point center;
public ArrayList<Point> points = new ArrayList<>();
public Mesh(BufferedImage image) {
center = new Point(image.getWidth() / 2, image.getHeight() / 2);
angleA = (int) (Math.atan(center.y / center.x) * (180 / Math.PI));
angleB = 180 - angleA;
angleC = 180 + angleA;
angleD = 360 - angleA;
this.image = image;
for(int angle = 0; angle <= 360; angle+=4){
Point point = getNext(angle);
if(point != null) points.add(point);
}
}
private Point getNext(int angle) {
double radians = angle * Math.PI / 180;
double xStep = Math.cos(radians);
double yStep = Math.sin(radians);
int addX = angle >= 90 && angle <= 270 ? 1 : -1;
int addY = angle >= 0 && angle <= 180 ? 1 : -1;
double x, y;
if (xStep != 0) {
double slope = yStep / xStep;
double intercept = center.y - (slope * center.x);
if (angle >= angleA && angle <= angleB) {
y = 0;
x = -intercept / slope;
} else if (angle > angleB && angle < angleC) {
x = 0;
y = intercept;
} else if (angle >= angleC && angle <= angleD) {
y = image.getHeight() - 1;
x = (y - intercept) / slope;
} else {
x = image.getWidth() - 1;
y = slope * x + intercept;
}
} else {
x = center.x;
y = angle <= angleB ? 0 : image.getHeight();
}
if (x < 0) x = 0;
if (x > image.getWidth() - 1) x = image.getWidth() - 1;
if (y < 0) y = 0;
if (y > image.getHeight() - 1) y = image.getHeight() - 1;
double distance = Math.sqrt(Math.pow(x - center.x, 2) + Math.pow(y - center.y, 2));
double stepSize = Math.sqrt(Math.pow(xStep, 2) + Math.pow(yStep, 2));
int totalSteps = (int) Math.floor(distance / stepSize);
for (int step = 0; step < totalSteps; step++) {
int xVal = (int) x;
int yVal = (int) y;
if(xVal < 0) xVal = 0;
if(xVal > image.getWidth() -1) xVal = image.getWidth() -1;
if(yVal < 0) yVal = 0;
if(yVal > image.getHeight()-1) yVal = image.getHeight() -1;
int pixel = image.getRGB(xVal, yVal);
if ((pixel >> 24) == 0x00) {
x += (Math.abs(xStep) * addX);
y += (Math.abs(yStep) * addY);
} else {
return new Point(xVal, yVal);
}
}
return null;
}
}
The algorithm should be returning all positive points that are all ordered in counterclockwise rotation (and non-overlapping) but I have failed to get the desired output (this being my most recent attempt) so just to restate the question, is there a formalized way of doing this, or can someone find the mistake I made in my logic. For visual reference, the Mario and Yoshi Traced image is sort of what the final output should look like, but with many more points (which would give more detail to the mesh).

Balls collision detection - radius calculation - nearly done

Hello :) I'm totally lost. I have two balls on the screen, floating. Also I have a method that checks is there is a collision and a method name 'collide' that collides :)
When both balls goes in a straight line on each other it collides well. The problem is shown on the picture:
So, the methods are:
public final float ball_radius = 2.4f; // ball image has 48 width
public boolean isColliding(Ball ball)
{
distance = Math.sqrt((ball.image_center_x - this.image_center_x)*(ball.image_center_x - this.image_center_x)+(ball.image_center_y - this.image_center_y)*(ball.image_center_y - this.image_center_y));
if(distance <= 2*ball_radius)
return true;
/*
float sumRadius = 9.6f;
float sqrRadius = sumRadius * sumRadius;
float distSqr = (xd * xd) + (yd * yd);
if (distSqr <= sqrRadius)
{
return true;
}*/
return false;
}
void Collide(Ball ball1, Ball ball2)
{
double dx = (ball1.x - ball2.x) + dt * (ball1.vx - ball2.vx);
double dy = (ball1.y - ball2.y) + dt * (ball1.vy - ball2.vy);
// if collision swap velocities
if (Math.sqrt(dx * dx + dy * dy) <= 2*ball_radius) {
double tempx = ball1.vx;
double tempy = ball1.vy;
ball1.vx = ball2.vx;
ball1.vy = ball2.vy;
ball2.vx = tempx;
ball2.vy = tempy;
}
}
private void moveBalls(){
for (int i = 0; i < balls.size(); i++) {
Ball ball1 = balls.get(i);
for (int a = i + 1; a < balls.size(); a++) {
Ball ball2 = balls.get(a);
if(ball1.isColliding(ball2)) {
ball1.Collide(ball1, ball2);
checkHealthAndChangeColor(ball1, ball2);
}
//catchMP.start();
}
}
for (int i = 0; i < balls.size(); i++) {
balls.get(i).step();
}
}

Transition 2D player Position A to B on JAVA

Am having issues trying to figure out how to translate or 'animate' my player's position to a new tile, this is what am doing :
if (input.right){
x += 1;
Right now am listening for key.inputs and then x++/x-- or y++/y-- on my players position that makes him move pixel by pixel, but i want my player to move exactly to the next tile(32 pixels) with one hit of the key with like a linear transition from the player's tile position to the next tile over time?
Something like (pseudo code i think..)
if input && walking false
walking = true
increment 1 by 1 32 ints to X over time?
after completed walking = false
I still cant even figure out the logic behind something like that.
An example is the movement in a game called Tibia.
Now Some bits of my code (player related)..
GAMECLASS >
public Game()
player = new Player(playerSpawn.x(), playerSpawn.y(), key);
player.init(level);
public void run()
....
render();
frames++;
....
public void update()
key.update();
player.update();
level.update();
public void render()
.....
int xScroll = ( player.x + 32) - screen.width / 2;
int yScroll = ( player.y + 32) - screen.height / 2;
level.render(xScroll, yScroll, screen);
player.render(screen);
for (int i =0; i < pixels.length; i++){
pixels[i] = screen.pixels[i];
}
SCREENCLASS >
......
public int[] pixels;
public int[] tiles = new int[VIEW_SIZE * VIEW_SIZE];
.....
public void renderTile(int xp, int yp, Tile tile){
xp -= xOffset;
yp -= yOffset;
for (int y = 0; y < tile.sprite.SIZE; y++){
int ya = y + yp;
for (int x = 0; x < tile.sprite.SIZE; x++){
int xa = x + xp;
if (xa < -tile.sprite.SIZE || xa >= width || ya < 0 || ya >= height) break;
if (xa < 0) xa = 0;
pixels[xa + ya * width] = tile.sprite.pixels[x + y * tile.sprite.SIZE];
}
}
}
//THIS IS THE METHOD CALLED TO RENDER THE PLAYER > SEE BELLOW AT THE PLAYER CLASS FOR THE CALL
public void renderMob(int xp, int yp, Mob mob){
xp -= xOffset;
yp -= yOffset;
for (int y = 0; y < 64; y++){
int ya = y + yp;
int ys = y;
for (int x = 0; x < 64; x++){
int xa = x + xp;
int xs = x;
if (xa < -64 || xa >= width || ya < 0 || ya >= height) break;
if (xa < 0) xa = 0;
int col = mob.getSprite().pixels[xs + ys * 64];
if (mob instanceof Chazer && col == 0xFF9b0000) col = 0xff54ff00;
if (col != 0xFFFF00FF) pixels[xa + ya * width] = col;
}
}
}
PLAYERCLASS >
public Player(int x , int y, Keyboard input){
this.x = x;
this.y = y;
this.input = input;
}
//PLAYER UPDATE
public void update(){
if (anim < 7500) anim++;
else anim = 0;
if (input.down) ya = 1;
if (input.up) ya = -1;
if (input.left) xa = -1;
if (input.right) xa = 1;
//CHECK BELLOW TO THIS MOVE METHOD
if (xa != 0){
move(xa, 0);
} else if(ya != 0){
move(0, ya);
}
}
clear();
}
//HERE ANIMATION AND CHOOSE WHAT SPRITE = WHERE PLAYER IS LOOKING AT
public void render(Screen screen){
if (dir == 0) {
sprite = Sprite.player_n;
if (walking) {
if (anim % 20 > 10){
sprite = sprite.player_n1;
} else {
sprite = sprite.player_n2;
}
}
}
if (dir == 1) {
sprite = Sprite.player_e;
if (walking) {
if (anim % 20 > 10){
sprite = sprite.player_e1;
} else {
sprite = sprite.player_e2;
}
}
}
if (dir == 2) {
sprite = Sprite.player_s;
if (walking) {
if (anim % 20 > 10){
sprite = sprite.player_s1;
} else {
sprite = sprite.player_s2;
}
}
}
if (dir == 3) {
sprite = Sprite.player_w;
if (walking) {
if (anim % 20 > 10){
sprite = sprite.player_w1;
} else {
sprite = sprite.player_w2;
}
}
}
// ADDING OFFSET CUZ THE PLAYER IS DOUBLE THE SIZE OF THE TILE
int xx = x - 42;
int yy = y - 42;
screen.renderMob(xx, yy, sprite);
}
//THIS IS HOW I MOVE THE PLAYER
public void move(int xa, int ya){
if (xa != 0 && ya != 0){
move(xa, 0);
move(0, ya);
return;
}
if (xa > 0) dir = 1;
if (xa < 0) dir = 3;
if (ya > 0) dir = 2;
if (ya < 0) dir = 0;
if(!collision(xa, 0)){
x += xa;
}
if(!collision(0, ya)){
y += ya;
}
}
Thanks alooot!
**Run method!
public void run() {
long xlastTime = System.nanoTime();
long timer = System.currentTimeMillis();
final double xns = 1000000000.0 / 60.0;
double delta = 0;
int frames = 0;
requestFocus();
while(running){
long xnow = System.nanoTime();
delta += (xnow-xlastTime) / xns;
xlastTime = xnow;
while (delta >= 1) {
update();
delta--;
}
render();
frames++;
if (System.currentTimeMillis() - timer > 1000){
timer += 1000;
frame.setTitle(title + " | " + frames + " fps");
frames = 0;
}
}
stop();
}
What I would do is declare two int fields in the player class:
private float xToMove = 0;
private float yToMove = 0;
Then, under your input event:
if (input.down && yToMove == 0)
yToMove = -32;
if (input.up && yToMove == 0)
yToMove = 32;
if (input.left && xToMove == 0)
xToMove = -32;
if (input.right && xToMove == 0)
xToMove = 32;
And finally, in your Player class's update method:
public void update()
{
if (xToMove > 0)
{
xToMove--;
x++;
}
if (xToMove < 0)
{
xToMove++;
x--;
}
if (yToMove > 0)
{
yToMove--;
y++;
}
if (yToMove < 0)
{
yToMove++;
y--;
}
}
Of course this is simplified a bit but the concept is there
EDIT: to change the speed. Note that xToMove and yToMove have been changed to floats.
You can use a float to represent the amount of time 1 move takes
float period = 1000; //The time one move takes in milliseconds
Somewhere you should calculate the number of pixels to be moved each frame. You could make a calculateSpeed() method or just throw it into the constructor or something. Depends on if you want speed to change during the game.
float speed = 32f / (fps * (period / 1000f)); //fps should be obtained dynamically and should be a float
Then when you update you should do this:
if (xToMove > 0)
{
xToMove -= speed;
x += speed;
if (xToMove <= 0)
{
//Set these guys to nice even numbers to prevent problems
xToMove = 0;
x = (float) Math.round(x);
}
}
Also make sure that x and y are floats.
EDIT 2: fps
int frames = 0;
int fps = 60;
requestFocus();
while(running){
long xnow = System.nanoTime();
delta += (xnow-xlastTime) / xns;
xlastTime = xnow;
while (delta >= 1) {
update();
delta--;
}
render();
frames++;
if (System.currentTimeMillis() - timer > 1000){
timer += 1000;
fps = frames;
frame.setTitle(title + " | " + fps + " fps");
frames = 0;
}
}
stop();

Java Rect.intersects() not working sometimes

I currently loop through all my sprites checking if they intersect with each other like this:
for (Sprite s : sprites) {
if (s.dead) {
dead.add(s);
}
for (Sprite sprite : sprites) {
if (!sprite.equals(s)) {
s.collide(sprite, maxX, maxY);
}
}
s.run();
}
and the sprite checks using the Rect.intersects() method like so:
if (getRect().intersects(s.getRect()))
But sometimes it just completely ignores a collision, and the objects just pass through each other.
Any ideas?
You should try changing the code to
if(getRect().intersects(s.getRect()) || s.getRect().intersects(getRect()))
{
// They have intersected
}
The reason for this being, the intersection method check is unique for each rectangle. Performing an intersection check to see if rectangle a intersects rectangle b, is different than performing an intersection check to see if rectangle b intersects rectangle a.
Other than this, can you give me more information on your rectangles? Are they rotating? How fast are they moving? How large are they? Other information would be use full as well, I can try to think of other reasons for why they are not colliding.
I fixed it by making it create a rectangle for the area that it covers between frames like so:
private void checkForNextCollision() {
double boundsWidth = width + dX ;
if(dX < 0){
boundsWidth= width - dX ;
}
double boundsHeight = height + dY ;
if(dY < 0){
boundsHeight = height - dY ;
}
double boundx = xWorld + dX ;
double boundy = yWorld + dY ;
betweenRect = new Rectangle((int)(boundx),(int)(boundy),(int)(boundsWidth), (int)(boundsHeight));
}
This rectangle is then checked against the rectangle created in the other sprites to check if there should be a collision in the next frame:
public void collide(Sprite s, int maxX, int maxY) {
maxWX = maxX;
maxWY = maxY;
//check for collision with borders
if (xWorld <= 0) {
dX = -dX;
xWorld += 2;
if(xWorld < -1000){
dX = 0;
xWorld += 10;
}
}
if (yWorld <= 0) {
dY = -dY;
yWorld += 2;
if(yWorld < -1000){
dX = 0;
yWorld += 10;
}
}
if (xWorld + width >= maxX) {
dX = -dX;
xWorld -= 2;
if(xWorld+width > maxX + 1000){
dX = 0;
xWorld -= 10;
}
}
if (yWorld + height >= maxY) {
dY = -dY;
yWorld -= 2;
if(yWorld+height > maxY + 1000){
dY = 0;
yWorld -= 10;
}
}
//check for collision with borders
if(betweenRect.intersects(s.betweenRect)){
willIntersect = true;
}else{
willIntersect = false;
}
// Use all checks to see if they should collide
if (getRect().intersects(s.getRect()) || s.getRect().intersects(getRect()) || willIntersect || (xWorld + width > s.xWorld && xWorld < s.xWorld + s.width && yWorld < s.yWorld+s.height && yWorld + height > s.yWorld) ) {
double lastDy = dY;
double lastsDy = s.dY;
double lastDx = dX;
double lastsDx = s.dX;
dY = (((weight - s.weight) / (weight + s.weight)) * lastDy)
+ (((2.0 * s.weight) / (weight + s.weight)) * lastsDy);
s.dY = (((s.weight - weight) / (weight + s.weight)) * lastsDy)
+ (((2.0 * weight) / (weight + s.weight)) * lastDy);
dX = (((weight - s.weight) / (weight + s.weight)) * lastDx)
+ (((2.0 * s.weight) / (weight + s.weight)) * lastsDx);
s.dX = (((s.weight - weight) / (weight + s.weight)) * lastsDx)
+ (((2.0 * weight) / (weight + s.weight)) * lastDx);
if(willIntersect){
willIntersect = false;
//s.willIntersect = false;
}
}
}

Categories

Resources