Rectangle intersects not working while jumping - java

I am making a game with android. The player is a rectangle that has to jump over obstacles. When i jump i decrease the height and the y coordinates. When i run the game the rectangle is jumping but when i try to jump over an obstacle its still hitting it. So i think i forget to change a value but i have no idea what value. Sorry for my bad english and i am a beginner at coding.
This is my Player class:
package com.example.niek.speelveld;
import android.graphics.Canvas;
import android.graphics.Paint;
/**
* Created by Niek on 15-8-2017.
*/
public class Player extends GameObject {
private int score;
private boolean up;
private boolean playing;
private long startTime;
private int h = 0;
private boolean jump;
public Player(int x , int y){
super.x = x;
super.y = y;
width = 100;
height = GamePanel.HEIGHT;
score = 0;
startTime = System.nanoTime();
}
public void setUp(boolean b){up = b;}
public void update(){
long elapsed = (System.nanoTime()-startTime)/1000000;
if(elapsed>100){
score++;
startTime = System.nanoTime();
}
if(up && h == 0){
jump = true;
up = false;
}
if (jump) {
if (h < 120) {
h = h + 7;
height = height - 7;
y = y - 7;
} else {
jump = false;
}
} else {
if (h > 0) {
h = h - 7;
height = height + 7;
y = y + 7;
}
}
}
public void draw(Canvas canvas){
Paint myPaint = new Paint();
myPaint.setStyle(Paint.Style.STROKE);
myPaint.setStrokeWidth(7);
canvas.drawRect(x, y, width + x, height, myPaint );
myPaint.setStrokeWidth(1);
canvas.drawText("HIGHSCORE " + score, GamePanel.WIDTH - 100 , 0+myPaint.getTextSize(), myPaint);
}
public int getScore(){return score;}
public boolean getPlaying(){return playing;}
public void setPlaying(boolean b){playing = b;}
//public void resetScore(){score = 0;}
public boolean getJump() {
return jump;
}
}
And in my Gamepanel class i use these 2 methods. When i call the class obstacle.get(i).update(); its only updating the x value so its moving towards the player.
public void update(){
if(player.getPlaying()) {
bg.update();
player.update();
//Add obstacles with timer
long obstacleElapsed = (System.nanoTime()-obstacleStartTime)/1000000;
if(obstacleElapsed >(2000 - player.getScore()/4)){
obstacles.add(new Obstacle(BitmapFactory.decodeResource(getResources(), R.drawable.rsz_spike1), WIDTH + 10, HEIGHT - 51, 14, 51, player.getScore()));
//reset timer
obstacleStartTime = System.nanoTime();
}
}
//Loop through every obstacle and check collision
for(int i = 0; i<obstacles.size(); i++){
obstacles.get(i).update();
if (collision(obstacles.get(i), player)) {
obstacles.remove(i);
player.setPlaying(false);
Intent intent = new Intent(c, Result.class);
intent.putExtra("SCORE", player.getScore());
c.startActivity(intent);
break;
}
//Remove obstacles that are out of the screen
if (obstacles.get(i).getX() < -100) {
obstacles.remove(i);
break;
}
}
}
public boolean collision(GameObject o, GameObject p){
if(Rect.intersects(o.getRectangle(), p.getRectangle())){
return true;
}
return false;
}
#Override
public void draw(Canvas canvas){
//Get Width and Height from screen
final float scaleFactorX = (float)getWidth()/WIDTH;
final float scaleFactorY = (float)getHeight()/HEIGHT;
if(canvas!=null) {
final int savedState = canvas.save();
canvas.scale(scaleFactorX, scaleFactorY);
bg.draw(canvas);
player.draw(canvas);
//Draw obstacles
for(Obstacle o : obstacles ){
o.draw(canvas);
}
canvas.restoreToCount(savedState);
}
}
And finally the Player and the Obstacle class extends Gameobject where i have the getRectangle method.
public Rect getRectangle(){
return new Rect(x, y, x+width, y+height);
}

Related

Detecting interactions between Canvas objects

In my current prototype I have a fixed grid of rectangles I draw on the canvas in a loop, and a red square "gamePiece" which can be dragged around the screen by a player's finger (screenshot below). My goal is to make it so that the player square can interact with the grey squares, but I'm not sure how to detect interactions between canvas objects. How can this be accomplished?
The relevant chunks of my code are below, but please let me know if there is anything else I can provide to help. I don't expect anyone to make this for me, but if someone could point me towards good resources I would appreciate it a lot!!
Code
GamePiece (Red Square)
public class GamePiece implements GameObject {
private Rect rectangle;
private int color;
public GamePiece(Rect rectangle, int color) {
this.rectangle = rectangle;
this.color = color;
}
#Override
public void draw(Canvas canvas) {
Paint paint = new Paint();
paint.setColor(color);
canvas.drawRect(rectangle, paint);
}
#Override
public void update() {
}
public void update(Point point) {
//ltrb
rectangle.set(point.x - rectangle.width()/2, point.y - rectangle.height()/2, point.x + rectangle.width()/2, point.y + rectangle.height()/2);
}
}
GameTile (Individual Gray Squares)
public class GameTile implements GameObject{
private RectF rectangle;
private int color;
public static int tilesPerRow = 10;
final public static int TILE_SIZE = (PolyGoneUtils.getScreenWidth() - (40 + 20 * tilesPerRow)) / tilesPerRow;
public GameTile(RectF rectangle, int color) {
this.rectangle = rectangle;
this.color = color;
}
#Override
public void draw(Canvas canvas) {
Paint paint = new Paint();
paint.setColor(color);
canvas.drawRoundRect(rectangle, 10, 10, paint);
}
#Override
public void update() {
}
#Override
public void update(Point point) {
rectangle.set(point.x - rectangle.width()/2, point.y - rectangle.height()/2, point.x + rectangle.width()/2, point.y + rectangle.height()/2);
}
}
GameBoard (makes the grid of GameTiles)
public class GameBoard extends View {
private static final int originX = 30;
private static final int originY = 400;
private static final int tileSize = GameTile.TILE_SIZE;
public GameBoard(Context context) {
super(context);
}
public static void makeGameBoard(Canvas canvas) {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
GameTile gameTile = new GameTile(new RectF(originX + i * tileSize + (20 * i),
originY + j * tileSize + (20 * j),
originX + (i + 1) * tileSize + (20 * i),
originY + (j + 1) * tileSize + (20 * j)), Color.DKGRAY);
gameTile.draw(canvas);
}
//System.out.println("Squared Dimensions of the tiles are: " + tileSize);
}
}
}
And Finally here is my GameView
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
private MainThread thread;
Context context;
private GamePiece gamePiece;
private Point piecePoint;
public GameView(Context context) {
super(context);
this.context = context;
getHolder().addCallback(this);
thread = new MainThread(getHolder(), this);
setFocusable(true);
gamePiece = new GamePiece(new Rect(300, 300, 384, 384), Color.rgb(255, 0, 0));
piecePoint = new Point(342, 342);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceCreated(#NonNull SurfaceHolder holder) {
thread = new MainThread(getHolder(), this);
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceDestroyed(#NonNull SurfaceHolder holder) {
boolean retry;
retry = true;
while(retry) {
try {
thread.setRunning(false);
thread.join();
} catch (Exception e) {e.printStackTrace();}
retry = false;
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: //player pressing down
case MotionEvent.ACTION_MOVE: //player moving their finger
piecePoint.set((int)event.getX(), (int)event.getY() - 100);
}
return true;
//return super.onTouchEvent(event);
}
public void update() {
gamePiece.update(piecePoint);
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
canvas.drawColor(Color.parseColor("#201E36"));
GameBoard.makeGameBoard(canvas); // Drawing GameBoard Grid
gamePiece.draw(canvas);
}
}
Following #Mike M.'s suggestions I have implemented the following solution. Instead of creating my tiles and drawing them every loop, I have changed it to where I define my GameBoard tiles initially in GameView and store them to an ArrayList...
//Within GameBoard class
public static void makeGameBoard() {
tiles = new ArrayList<>();
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
GameTile gameTile = new GameTile(new RectF(originX + i * tileSize + (20 * i),
originY + j * tileSize + (20 * j),
originX + (i + 1) * tileSize + (20 * i),
originY + (j + 1) * tileSize + (20 * j)), Color.DKGRAY);
tiles.add(gameTile);
}
}
}
I then use a separate method to draw them from this ArrayList in draw...
//Within GameBoard class
public static void drawGameBoard(Canvas canvas) {
for (int i = 0; i < tiles.size(); i++) {
tiles.get(i).draw(canvas);
}
}
Finally, to handle the interactions between the board's gameTiles and the player's gamePiece I simply check if the Point at the center of the gamePiece is within any of the gameBoard's gameTiles in the tiles ArrayList with RectF's built in .contains method.
//Within GameBoard class
public static void doesTileInteract(Point gamePiecePoint) {
for (int i = 0; i < tiles.size(); i++) {
if (tiles.get(i).getRectangle().contains(gamePiecePoint.x, gamePiecePoint.y)) {
System.out.println("The tiles are interacting!");
}
}
}
Which is called in the onTouchEvent method.
//Within GameView class
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: //player pressing down
wasClicked = gamePiece.getRectangle().contains((int) event.getX(), (int) event.getY());
case MotionEvent.ACTION_MOVE: //player moving their finger
if (wasClicked) {
gamePiecePoint.set((int) event.getX(), (int) event.getY() - 100);
}
GameBoard.doesTileInteract(gamePiecePoint);
}
return true;
//return super.onTouchEvent(event);
}
Thanks so much to #Mike M. for all his suggestions!! I really appreciate the help.

Collision for an Array of bricks and making a grid of bricks without using a 2D array for Processing

I'm very new to processing and for a project in college we need to make an animation or game of some sort. I have chosen to make breakout for my animation but I am having problems with 2 parts of my code. The first one is that I am trying to get the bricks to line up across the top of the screen in a 5 by 6 grid. I got a little help from my lecturer but it only makes 2 rows and I think the rest of them go off screen. The second problem I'm having is trying to get hit detection to work for my ball and bricks. I think it's because the bricks are in an array and not a single object and I have no clue how to go about it. Any help or advice would be much appreciated. Below is what I have done so far.
Main Code
PImage bg;
PlayerName pl;
Ball bl;
Paddle pad;
Brick[] bricks;
int numOfCols = 30; // Number of bricks I want in total
int distRows = 1; // The distance between each of the bricks below each other
void setup() {
size(1280, 720);
noCursor();
bg = loadImage("space.jpg");
pl = new PlayerName(JOptionPane.showInputDialog("Please enter your name (max of 12 char): "));
bl = new Ball(51);
pad = new Paddle(300,15);
// Below is my attempt to try make the bricks spawn across the screen but it only does 2 rows
bricks = new Brick[numOfCols];
int xForBrick = 0;
for(int col = 0; col < numOfCols; col++){
if(col == 5)
{
distRows = 15;
xForBrick = 0;
}
bricks[col] = new Brick(xForBrick*256,distRows);
xForBrick++;
}
}
void draw() {
background(bg);
// Ignore these values below. This was just to help me visual stuff for hit detection.
//text(pl.getName(),500,500);
text(pad.getYPos(), 500,500);
text(pad.getXPos(), 525,525);
text(bl.getXCoord(), 500, 550);
text(bl.getYCoord(), 525, 575);
bl.display(); //Dsiplays the ball
bl.gameOver(); // Controls the balls movement and ends game if ball goes off screen
pad.display(); // Displays the paddle
pad.movement(); //Controls the movement of the paddle with the mouse
for(int col = 0; col < numOfCols; col++){
bricks[col].display();
}
boolean collision = onHit(pad,bl);
if (collision == true){
bl.bounce();
}
boolean collision2 = onHit2(bl,bricks);
if(collision2 == true){
bl.bounce();
}
}
boolean onHit(Paddle pad, Ball bl){
float ballDistanceX = abs(bl.getXCoord() - pad.getXPos() - pad.getPaddleW()/2);
float ballDistanceY = abs(bl.getYCoord() - pad.getYPos());
if(ballDistanceX > (pad.getPaddleW()/2 + bl.getSize()/2)){
return false;
}
if (ballDistanceY > (pad.getPaddleH()/2)){
return false;
}
return true;
}
boolean onHit2(Ball bl, Brick bricks){
float ballDistanceX2 = abs(bl.getXCoord() - bricks.getXPos() - bricks.getSizeW()/2);
float ballDistanceY2 = abs(bl.getYCoord() - bricks.getSizeH());
if(ballDistanceX2 > (bricks.getSizeW() + bl.getSize()/2)){
return false;
}
if(ballDistanceY2 > (bricks.getSizeH()/2)){
return false;
}
return true;
}
Ball class
public class Ball {
private float xCoord, yCoord, size, veloX, veloY;
Ball(float size) {
setSize(size);
death();
}
public boolean gameOver() {
boolean lose = false;
xCoord = xCoord + veloX;
yCoord = yCoord + veloY;
//When ball leaves screen, ball resets
if (yCoord > height + size/2) {
death();
lose = true;
}
// Makes ball bounce off of right edge
if (xCoord > width - size/2) {
xCoord = width - size/2;
veloX = veloX * -1;
}
//Makes ball bounce off of left edge
if (xCoord < size/2) {
xCoord = size/2;
veloX = veloX * -1;
}
// Makes it so the ball bounces off the top edge
if (yCoord < size/2) {
yCoord = size/2;
veloY = veloY * -1;
}
return lose;
}
public void display() {
fill(120, 70, 200);
noStroke();
ellipse(xCoord, yCoord, size, size);
}
//Makes ball bounce off of paddle
public void bounce() {
veloY = veloY * -1;
yCoord = yCoord + veloY;
}
//When ball goes off the bottom of the screen, it resets back to the center with a different velocity
private void death() {
xCoord = width/2;
yCoord = height/2;
veloX = 3;
veloY = -3;
}
public float getXCoord() {
return xCoord;
}
public float getYCoord() {
return yCoord;
}
public float getSize() {
return size;
}
public float getVeloX() {
return veloX;
}
public float getVeloY() {
return veloY;
}
public void setXCoord(float xCoord) {
this.xCoord = xCoord;
}
public void setYCoord(float yCoord) {
this.yCoord = yCoord;
}
public void setSize(float size) {
if ((size >= 30) && (size <= 50)) {
this.size = size;
} else {
this.size = 30;
}
}
public void setVeloX(float veloX) {
this.veloX = veloX;
}
public void setVeloY(float veloY) {
this.veloY = veloY;
}
}
Brick class
public class Brick{
private float xPos,yPos,sizeW,sizeH;
boolean isShown;
Brick(float xPos, float yPos){
this.xPos = xPos;
this.yPos = yPos;
sizeW = 256;
sizeH = 15;
}
public void display(){
fill(#8F52EC);
stroke(0);
strokeWeight(2);
rect(xPos, yPos, sizeW, sizeH);
}
public float getXPos(){
return xPos;
}
public float getYPos(){
return yPos;
}
public float getSizeW(){
return sizeW;
}
public float getSizeH(){
return sizeH;
}
public boolean getIsShown(){
return isShown;
}
public void setXPos(float xPos){
this.xPos = xPos;
}
public void setYPos(float yPos){
this.yPos = yPos;
}
public void setSizeW(float sizeW){
this.sizeW = sizeW;
}
public void setSizeH(float sizeH){
this.sizeH = sizeH;
}
}
Paddle class
public class Paddle{
private float xPos, yPos, paddleH, paddleW;
public Paddle(float paddleW, float paddleH){
setPaddleW(paddleW);
setPaddleH(paddleH);
xPos = width/2;
yPos = height - this.paddleH;
}
public void movement(){
xPos = mouseX - paddleW/2;
if (xPos < 0){
xPos = 0;
}
if (xPos > (width - paddleW)){
xPos = width - paddleW;
}
}
public void display(){
fill(#320048);
noStroke();
rect(xPos,yPos,paddleW,paddleH);
}
public float getXPos(){
return xPos;
}
public float getYPos(){
return yPos;
}
public float getPaddleW(){
return paddleW;
}
public float getPaddleH(){
return paddleH;
}
public void setXPos(float xPos){
this.xPos = xPos;
}
public void setYPos(float yPos){
this.yPos = yPos;
}
public void setPaddleW(float paddleW){
if ((paddleW >= 30) && (paddleW <= width/2)){
this.paddleW = paddleW;
}
else {
this.paddleW = 300;
}
}
public void setPaddleH(float paddleH){
if ((paddleH >= 10) && (paddleH <= 20)){
this.paddleH = paddleH;
}
else {
this.paddleH = 15;
}
}
}
PlayerName class
public class PlayerName{
private String name;
public PlayerName(String name){
if(name.length() < 12){
this.name = name;
}
else{
this.name = name.substring(0,12);
}
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name.substring(0,12);
}
}
I can't see everything, but try this change in main:
int xForBrick = 0;
for(int col = 0; col < numOfCols; col++)
{
if(col % 5 == 0) //change here
{
distRows = distRows + 1; //change here
xForBrick = 0;
}
bricks[col] = new Brick(xForBrick*256,distRows);
xForBrick++;
}

Unfreezing colliding rectangles?

I need help with a project. For this project we have created moving rectangles that "freeze" when clicked on. We are also supposed to make frozen rectangles unfrozen if they collide with another. I have gotten the first step done but I can't seem to get the rectangles to unfreeze if they collide. I apologize if this doesn't make sense. I am new to Java and stack overflow. Here is my class code.
import edu.princeton.cs.introcs.StdDraw;
import java.util.Random;
import java.awt.Color;
public class MovingRectangle {
//canvas = canvasSize;
public int width; //width of rectangle
public int height; //height of rectangle
public double xVelocity; //x velocity
public double yVelocity; //y velocity
public int xPosition; //x starting position
public int yPosition; //y starting position
private boolean isFrozen; //the rectangle is still moving
// private int R, G, B;
Random rng = new Random();
public int R = rng.nextInt(256);
public int G = rng.nextInt(256);
public int B = rng.nextInt(256); //RGB variables
public int canvas;
public Color c;//canvas size
public MovingRectangle(int x, int y, int w, int h, double xv, double yv, int canvasSize) {
xPosition = x;
yPosition = y;
width = w;
height = h;
xVelocity = xv;
yVelocity = yv;
canvas = canvasSize;
isFrozen = false;
c =new Color(R,G,B);
}
//draws rectangle
public void draw() {
// Random rng = new Random();
// R = rng.nextInt(256);
// G = rng.nextInt(256);
// B = rng.nextInt(256);
// c = new Color(R,G,B);
StdDraw.setPenColor(c);
StdDraw.filledRectangle(xPosition, yPosition, width/2, height/2);
}
//pick a new random color
// public void color() {
// Random rng = new Random();
//
// R = rng.nextInt(256);
// G = rng.nextInt(256);
// B = rng.nextInt(256);
// c = new Color(R,G,B);
// }
//updates position every frame
public void move() {
if (isFrozen == false) {
xPosition += xVelocity;
yPosition += yVelocity;
// xPosition += 0;
// yPosition += 0;
//Check for hitting sides of canvas
if (xPosition > canvas) {
xVelocity *= -1;
//color();
}
if( xPosition < 0) {
xVelocity *= -1;
//color();
}
if (yPosition > canvas ) {
yVelocity *= -1;
//color();
}
if(yPosition <= 0) {
yVelocity*=-1;
//color();
}
}
}
public boolean ifColliding(MovingRectangle rectangle) {
int rightedge = rectangle.xPosition + rectangle.width/2;
int leftedge = rectangle.xPosition - rectangle.width/2;
int topedge = rectangle.yPosition + rectangle.height/2;
int bottomedge = rectangle.yPosition - height/2;
int rightedge2 = this.xPosition + this.width/2;
int leftedge2 = this.xPosition - this.width/2;
int topedge2 = this.yPosition + this.height/2;
int bottomedge2 = this.yPosition - this.height/2;
if(leftedge<rightedge2 && leftedge2<rightedge && topedge>bottomedge2 && bottomedge<topedge2) {
return true;
}
else {
return false;
}
}
public void freeze() {
if(StdDraw.mousePressed() && StdDraw.mouseX() <= xPosition+width && StdDraw.mouseX() >= xPosition-width && StdDraw.mouseY() <=yPosition+height &&StdDraw.mouseY() >= yPosition-height) {
xVelocity=0;
yVelocity=0;
c= new Color(100,0,0);
isFrozen= true;
}
}
public boolean isFrozen() {
return isFrozen;
}
public void winState() {
StdDraw.clear();
}
public void setFrozen(boolean val) {
isFrozen = false;
if (isFrozen == false) {
xPosition += xVelocity;
yPosition += yVelocity;
}
}
// public void stop() {
// isMoving = false;
// }
}
And my driver.
import edu.princeton.cs.introcs.StdDraw;
import java.util.Random;
import java.util.Scanner;
import java.awt.Color.*;
import edu.princeton.cs.introcs.StdDraw;
public class RectangleDriver {
public static final int canvas = 500;
public static void main(String[] args) {
//set canvas size
StdDraw.setCanvasSize(canvas,canvas);
StdDraw.setXscale(canvas, 0);
StdDraw.setYscale(0, canvas);
//assign variables
Random rng = new Random();
//make a rectangle
MovingRectangle[] rectangles = new MovingRectangle[5]; //(x, y, w, h, xv, yv, canvas);
for(int i =0;i<rectangles.length;i++) {
int x = rng.nextInt(canvas); //xPosition
int y = rng.nextInt(canvas); //yPosition
int w = rng.nextInt(100)+20; //width
int h = rng.nextInt(100)+20; //height
double xv = rng.nextInt(5)+2; //xVelocity
double yv = rng.nextInt(5)+2; //yVelocity
rectangles[i]= new MovingRectangle(x,y,w,h,xv,yv,canvas);
}
//while isMoving, the rectangles move
while (true) {
StdDraw.clear();
for(int i =0; i<rectangles.length;i++) {
rectangles[i].move();
rectangles[i].draw();
rectangles[i].freeze();
System.out.println(rectangles[i].isFrozen());
//for 0
if(rectangles[i].ifColliding(rectangles[1])){
if(rectangles[0].isFrozen()) {
rectangles[0].setFrozen(false);
}
}
if(rectangles[i].ifColliding(rectangles[2])){
if(rectangles[0].isFrozen()) {
rectangles[0].setFrozen(false);
}
}
if(rectangles[i].ifColliding(rectangles[3])){
if(rectangles[0].isFrozen()) {
rectangles[0].setFrozen(false);
}
}
if(rectangles[i].ifColliding(rectangles[4])){
if(rectangles[0].isFrozen()) {
rectangles[0].setFrozen(false);
}
}
//for 1
if(rectangles[1].ifColliding(rectangles[0])){
if(rectangles[1].isFrozen()) {
rectangles[1].setFrozen(false);
}
}
if(rectangles[1].ifColliding(rectangles[2])){
if(rectangles[1].isFrozen()) {
rectangles[1].setFrozen(false);
}
}
if(rectangles[1].ifColliding(rectangles[3])){
if(rectangles[1].isFrozen()) {
rectangles[1].setFrozen(false);
}
}
if(rectangles[1].ifColliding(rectangles[4])){
if(rectangles[1].isFrozen()) {
rectangles[1].setFrozen(false);
}
}
// for 2
if(rectangles[2].ifColliding(rectangles[0])){
if(rectangles[2].isFrozen()) {
rectangles[2].setFrozen(false);
}
}
if(rectangles[2].ifColliding(rectangles[1])){
if(rectangles[2].isFrozen()) {
rectangles[2].setFrozen(false);
}
}
if(rectangles[2].ifColliding(rectangles[3])){
if(rectangles[2].isFrozen()) {
rectangles[2].setFrozen(false);
}
}
if(rectangles[2].ifColliding(rectangles[4])){
if(rectangles[2].isFrozen()) {
rectangles[2].setFrozen(false);
}
}
//for 3
if(rectangles[3].ifColliding(rectangles[1])){
if(rectangles[3].isFrozen()) {
rectangles[3].setFrozen(false);
}
}
if(rectangles[3].ifColliding(rectangles[2])){
if(rectangles[3].isFrozen()) {
rectangles[3].setFrozen(false);
}
}
if(rectangles[3].ifColliding(rectangles[0])){
if(rectangles[3].isFrozen()) {
rectangles[3].setFrozen(false);
}
}
if(rectangles[3].ifColliding(rectangles[4])){
if(rectangles[3].isFrozen()) {
rectangles[3].setFrozen(false);
}
}
//for 4
if(rectangles[4].ifColliding(rectangles[1])){
if(rectangles[4].isFrozen()) {
rectangles[4].setFrozen(false);
}
}
if(rectangles[4].ifColliding(rectangles[2])){
if(rectangles[4].isFrozen()) {
rectangles[4].setFrozen(false);
}
}
if(rectangles[4].ifColliding(rectangles[3])){
if(rectangles[4].isFrozen()) {
rectangles[4].setFrozen(false);
}
}
if(rectangles[4].ifColliding(rectangles[0])){
if(rectangles[4].isFrozen()) {
rectangles[4].setFrozen(false);
}
}
}
if(rectangles[0].isFrozen()==true && rectangles[1].isFrozen()==true && rectangles[2].isFrozen()==true && rectangles[3].isFrozen()==true && rectangles[4].isFrozen()==true) {
StdDraw.clear();
StdDraw.text(250, 250, "You win!");
}
StdDraw.show(100);
}
}
}

How to spawn collectibles at random positions in Java

I making a game in Android Studio with Java. I am having an issue where my collectible keeps re-spawning in the same position after the player has collected it. I would like for it to re-spawn at random positions on the screen. How can I do this?
The collectible is a fuel can.
Here is the fuel can collectible class
Fuel.java
public class Fuel extends GameObject {
public Fuel(Bitmap res, int w, int h, int numFrames) {
x = GamePanel.WIDTH + 5000;
y = GamePanel.HEIGHT / 2;
dy =(random.nextInt()*(GamePanel.HEIGHT - (maxBorderHeight* 2)+maxBorderHeight));
dx = +GamePanel.MOVESPEED;
height = h;
width = w;
Bitmap[] image = new Bitmap[numFrames];
spritesheet = res;
for (int i = 0; i < image.length; i++)
{
image[i] = Bitmap.createBitmap(spritesheet, 0, i*height, width, height);
}
animation.setFrames(image);
animation.setDelay(100-dx);
animation.update();
}
public void update()
{
if (x < 0) {
reset();
}
x += dx;
dx = dx- 1;
if (dx <= -15) {
dx = -15;
}
animation.update();
}
public void draw(Canvas canvas)
{
try {
canvas.drawBitmap(animation.getImage(),x,y,null);
}catch (Exception e){}
}
public void reset(){
x = GamePanel.WIDTH + 5000;
y = GamePanel.HEIGHT/2 ;
dy = (random.nextInt()*(GamePanel.HEIGHT - (maxBorderHeight* 2)+maxBorderHeight));
dx = +GamePanel.MOVESPEED;
}
public void fuelCollected(){
reset();
}
}
GamePanel.java
public class GamePanel extends SurfaceView implements SurfaceHolder.Callback
{
private Fuel fuel;
#Override
public void surfaceCreated(SurfaceHolder holder){
fuel = new Fuel(BitmapFactory.decodeResource(getResources(), R.drawable.fuel),40,40,1);
}
public void update()
{
fuel.update();
if(collectFuel(player,fuel)){
distance +=100;
}
public boolean collectFuel(GameObject player, GameObject fuel){
if(Rect.intersects(player.getRectangle(),fuel.getRectangle()))
{
fuelCollected();
return true;
}
return false;
}
public void fuelCollected(){fuel.fuelCollected();}
}
#Override
public void draw(Canvas canvas){
// draw fuel can
fuel.draw(canvas);
}
}
Change Fuel reset() method to something like this:
public void reset() {
x = random.nextInt(GamePanel.WIDTH);
y = random.nextInt(GamePanel.HEIGHT);
dy = (random.nextInt()*(GamePanel.HEIGHT - (maxBorderHeight* 2)+maxBorderHeight));
dx = +GamePanel.MOVESPEED;
}
Assuming that x, y are integer variables x will be a random integer between 0 and GamePanel.WIDTH and y a random integer between 0 and GamePanel.HEIGHT.
Why do you add 5000 to the GamePanel.WIDTH ?

How do I paint multiple objetcs that move at different speeds in Java?

I am working on homework for class, and its late because I can't seem to understand the material despite all the research that I am doing. I am a beginner and do not know much in the way of java. Also, this is my first post so please be forgiving when you are reading this.
I am building on source code from my textbook, which I updated recently for past homework, but now I am trying to generate a class that draws multiple squares and moves those objects independently and at different speeds. They will all need to rebound off the walls as well. I followed the instructions and created two arrays that will hold the random x and y values between 1 and 10. However, I struggle with arrays and I am sure that I am not doing it correctly. So, I would love some feedback to see if I have it set up correctly.
I have a the jpanel pulling up and drawing, and as long as there is 1 square it is working fine bouncing off the walls, but things change when I draw more than one. The do not move independently and they also share the same speed. Some even disappear from time to time. This has really thrown me off. I appreciate any help!
In short, I am trying to paint new squares that all travel in different directions and at different speeds. Per the instructions we are suppose create and use a two arrays that handle the x and y values.
Here is what I have so far:
public class DotsPanel extends JPanel
{
private int delay = 15;
private final int SIZE = 7, IMAGE_SIZE = 3; // radius of each dot
private Timer timer;
private int x, y, i;
private ArrayList<Point> pointList;
static int [] xarray = new int [1000];
static int [] yarray = new int [1000];
Random rand = new Random();
//-----------------------------------------------------------------
// Constructor: Sets up this panel to listen for mouse events.
//-----------------------------------------------------------------
public DotsPanel()
{
pointList = new ArrayList<Point>();
int [] xarray = new int [1000];
int [] yarray = new int [1000];
timer = new Timer(delay, new ReboundListener());
addMouseListener (new DotsListener());
addMouseMotionListener (new DotsListener());
setBackground(Color.gray);
setPreferredSize(new Dimension(700, 500));
for(int i = 0; i < xarray.length; i++)
{
xarray[i] = rand.nextInt(7);
yarray[i] = rand.nextInt(7);
}
timer.start();
}
//-----------------------------------------------------------------
// Draws all of the dots stored in the list.
//-----------------------------------------------------------------
public void paintComponent(Graphics page)
{
super.paintComponent(page);
page.setColor(Color.BLUE);
for (Point spot : pointList)
{
page.fillRect(spot.x-SIZE, spot.y-SIZE, 25, 25);
page.drawString("Count: " + pointList.size(), 5, 15);
}
}
//*****************************************************************
// Represents the listener for mouse events.
//*****************************************************************
private class DotsListener implements MouseListener, MouseMotionListener
{
//--------------------------------------------------------------
// Adds the current point to the list of points and redraws
// the panel whenever the mouse button is pressed.
//--------------------------------------------------------------
public void mousePressed(MouseEvent event)
{
pointList.add(event.getPoint());
repaint();
}
public void mouseDragged(MouseEvent event)
{
// initially I had two xarray and yarray in here just like in
// mouseClicked
// but it did not change anything when removed
}
//--------------------------------------------------------------
// Provide empty definitions for unused event methods.
//--------------------------------------------------------------
public void mouseClicked(MouseEvent event)
{
xarray[i] = rand.nextInt(7);
yarray[i] = rand.nextInt(7);
}
public void mouseReleased(MouseEvent event) {}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
public void mouseMoved(MouseEvent e) {}
}
private class ReboundListener implements ActionListener
{
//--------------------------------------------------------------
// Updates the position of the image and possibly the direction
// of movement whenever the timer fires an action event.
//--------------------------------------------------------------
public void actionPerformed(ActionEvent event)
{
for (Point spot : pointList)
{
spot.x += xarray[i];
spot.y += yarray[i];
if (spot.x <= 0 || spot.x >= 700)
xarray[i] = xarray[i] * -1;
if (spot.y <= 0 || spot.y >= 500)
yarray[i] = yarray[i] * -1;
repaint();
}
}
}
}
However, I struggle with arrays and I am sure that I am not doing it correctly.
I wouldn't use Arrays.
Instead, have a Ball object manage its own state. Then you can have different color, speed, size etc for each Ball. Then when the Timer fires you just calculate the new position and repaint the Ball.
Here is an example to get you started:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class BallAnimation4
{
private static void createAndShowUI()
{
BallPanel panel = new BallPanel();
JFrame frame = new JFrame("BallAnimation4");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( panel );
frame.setSize(800, 600);
frame.setLocationRelativeTo( null );
//frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible( true );
panel.addBalls(5);
panel.startAnimation();
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
class BallPanel extends JPanel implements ActionListener
{
private ArrayList<Ball> balls = new ArrayList<Ball>();
public BallPanel()
{
setLayout( null );
setBackground( Color.BLACK );
}
public void addBalls(int ballCount)
{
Random random = new Random();
for (int i = 0; i < ballCount; i++)
{
Ball ball = new Ball();
ball.setRandomColor(true);
ball.setLocation(random.nextInt(getWidth()), random.nextInt(getHeight()));
ball.setMoveRate(32, 32, 1, 1, true);
// ball.setMoveRate(16, 16, 1, 1, true);
ball.setSize(32, 32);
balls.add( ball );
}
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
for (Ball ball: balls)
{
ball.draw(g);
}
}
public void startAnimation()
{
Timer timer = new Timer(75, this);
timer.start();
}
public void actionPerformed(ActionEvent e)
{
move();
repaint();
}
private void move()
{
for (Ball ball : balls)
{
ball.move(this);
}
}
class Ball
{
public Color color = Color.BLACK;
public int x = 0;
public int y = 0;
public int width = 1;
public int height = 1;
private int moveX = 1;
private int moveY = 1;
private int directionX = 1;
private int directionY = 1;
private int xScale = moveX;
private int yScale = moveY;
private boolean randomMove = false;
private boolean randomColor = false;
private Random myRand = null;
public Ball()
{
myRand = new Random();
setRandomColor(randomColor);
}
public void move(JPanel parent)
{
int iRight = parent.getSize().width;
int iBottom = parent.getSize().height;
x += 5 + (xScale * directionX);
y += 5 + (yScale * directionY);
if (x <= 0)
{
x = 0;
directionX *= (-1);
xScale = randomMove ? myRand.nextInt(moveX) : moveX;
if (randomColor) setRandomColor(randomColor);
}
if (x >= iRight - width)
{
x = iRight - width;
directionX *= (-1);
xScale = randomMove ? myRand.nextInt(moveX) : moveX;
if (randomColor) setRandomColor(randomColor);
}
if (y <= 0)
{
y = 0;
directionY *= (-1);
yScale = randomMove ? myRand.nextInt(moveY) : moveY;
if (randomColor) setRandomColor(randomColor);
}
if (y >= iBottom - height)
{
y = iBottom - height;
directionY *= (-1);
yScale = randomMove ? myRand.nextInt(moveY) : moveY;
if (randomColor) setRandomColor(randomColor);
}
}
public void draw(Graphics g)
{
g.setColor(color);
g.fillOval(x, y, width, height);
}
public void setColor(Color c)
{
color = c;
}
public void setLocation(int x, int y)
{
this.x = x;
this.y = y;
}
public void setMoveRate(int xMove, int yMove, int xDir, int yDir, boolean randMove)
{
this.moveX = xMove;
this.moveY = yMove;
directionX = xDir;
directionY = yDir;
randomMove = randMove;
}
public void setRandomColor(boolean randomColor)
{
this.randomColor = randomColor;
switch (myRand.nextInt(3))
{
case 0: color = Color.BLUE;
break;
case 1: color = Color.GREEN;
break;
case 2: color = Color.RED;
break;
default: color = Color.BLACK;
break;
}
}
public void setSize(int width, int height)
{
this.width = width;
this.height = height;
}
}
}
Since your Arrays only contain the Point you want to paint you don't have any information about the speed each point should be moved at. The best you could do is create a random amount each point should be moved each time its location is changed. This would give erratic movement as each time you move a point the distance would be random.
If you want more constant speed then you would need to create a second Array to contain the distance each point should move every time.
This starts to get messy creating a new Array every time you want a new property to be unique for the object you want to paint. That is why the approach to create a custom Object with multiple properties is easier to manage.

Categories