Unfreezing colliding rectangles? - java

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);
}
}
}

Related

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++;
}

Rectangle intersects not working while jumping

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);
}

Key is unregistered when other key is pressed

I'm recreating Asteroids, the spaceship can move forward and backwards and change it's rotation. When I for example move forward, the velocity keeps increasing until I release the forward key. But it also stops increasing the velocity when I for example hit the rotate left key. I don't understand why it does this, and I want to be able to increase the rotation degrees while increasing or decreasing my velocity (i.e. pressing UP or DOWN arrow). It also stops moving forward or rotating when I shoot (i.e. space bar).
Also, is my code readable and the aproach OO?
Asteroids:
import javax.swing.*;
public class Asteroids {
public static void createAndShowGui() {
GamePanel gamePanel = new GamePanel();
JFrame frame = new JFrame("Asteroids");
frame.getContentPane().add(gamePanel);
frame.pack();
frame.setVisible(true);
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocation(2000, 50);
gamePanel.requestFocusInWindow();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
GamePanel.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
public class GamePanel extends JPanel implements ActionListener {
private final int WIDTH = 1600;
private final int HEIGHT = 900;
private ArrayList<Rock> rocks;
private ArrayList<Bullet> bullets;
private SpaceShip spaceShip;
private boolean keyHeld;
private int keyCode;
public GamePanel() {
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setUp();
}
public void setUp() {
Timer animationTimer = new Timer(15, this);
spaceShip = new SpaceShip(WIDTH, HEIGHT);
bullets = new ArrayList<>();
rocks = new ArrayList<>();
addKeyListener(new KeyListener());
for (int i = 0; i < 12; i++) {
rocks.add(new Rock(WIDTH, HEIGHT));
}
animationTimer.start();
}
class KeyListener extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
keyCode = e.getKeyCode();
keyHeld = true;
}
#Override
public void keyReleased(KeyEvent e) {
keyHeld = false;
}
}
#Override
public void actionPerformed(ActionEvent e) {
checkRockCollisions();
for (int i = 0; i < bullets.size(); i++)
checkBulletOffScreen(bullets.get(i));
spaceShip.checkForCollisionWithFrame(WIDTH, HEIGHT);
moveObjects();
checkForPressedKeys();
repaint();
}
public void moveObjects() {
for (Rock rock : rocks)
rock.moveForward();
for (Bullet bullet : bullets)
bullet.moveForward();
spaceShip.moveSpaceShip();
}
public void checkRockCollisions() {
for (int i = 0; i < rocks.size(); i++) {
Rock rock = rocks.get(i);
rocks.stream().filter(rockToCheck -> !rock.equals(rockToCheck)).forEach(rock::checkRockCollision);
for (int j = 0; j < bullets.size(); j++) {
Bullet bullet = bullets.get(j);
if (rock.checkBulletCollision(bullet)) {
rocks.remove(rock);
bullets.remove(bullet);
}
}
if (rock.checkSpaceShipCollision(spaceShip))
resetSpaceShip();
rock.checkFrameCollision(WIDTH, HEIGHT);
}
}
public void checkBulletOffScreen(Bullet bullet) {
if (bullet.getxPos() + bullet.getBulletWidth() < 0 || bullet.getxPos() > WIDTH || bullet.getyPos() + bullet.getBulletHeight() < 0 || bullet.getyPos() > HEIGHT)
bullets.remove(bullet);
}
public void resetSpaceShip() {
spaceShip = new SpaceShip(WIDTH, HEIGHT);
}
public void checkForPressedKeys() {
if (keyHeld) {
switch (keyCode) {
case KeyEvent.VK_RIGHT:
spaceShip.increaseRotationDegree();
break;
case KeyEvent.VK_LEFT:
spaceShip.decreaseRotationDegree();
break;
case KeyEvent.VK_UP:
spaceShip.increaseForwardVelocity();
break;
case KeyEvent.VK_DOWN:
spaceShip.decreaseForwardVelocity();
break;
case KeyEvent.VK_SPACE:
bullets.add(new Bullet(spaceShip.getxPos() + spaceShip.getSpaceShipRadius(), spaceShip.getyPos() + spaceShip.getSpaceShipRadius(), spaceShip.getRotationDegree()));
keyHeld = false;
break;
}
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
RenderingHints mainRenderingHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHints(mainRenderingHints);
for (Rock rock : rocks)
rock.display(g2d);
for (Bullet bullet : bullets)
bullet.display(g2d);
spaceShip.display(g2d);
g2d.dispose();
}
}
SpaceShip.java
import java.awt.*;
public class SpaceShip {
private double xPos;
private double yPos;
private double xVelocity;
private double yVelocity;
private int spaceShipDiameter;
private int rotationDegree;
private int spaceShipRadius;
public SpaceShip(final int WIDTH, final int HEIGHT) {
spaceShipDiameter = 30;
spaceShipRadius = spaceShipDiameter / 2;
xPos = WIDTH / 2 - spaceShipRadius;
yPos = HEIGHT / 2 - spaceShipRadius;
rotationDegree = 0;
}
public int getSpaceShipRadius() {
return spaceShipRadius;
}
public double getxPos() {
return xPos;
}
public double getyPos() {
return yPos;
}
public int getRotationDegree() {
return rotationDegree;
}
public void increaseForwardVelocity() {
xVelocity += 0.04 * Math.sin(Math.toRadians(this.rotationDegree));
yVelocity += 0.04 * -Math.cos(Math.toRadians(this.rotationDegree));
}
public void decreaseForwardVelocity() {
xVelocity -= 0.04 * Math.sin(Math.toRadians(this.rotationDegree));
yVelocity -= 0.04 * -Math.cos(Math.toRadians(this.rotationDegree));
}
public void moveSpaceShip() {
this.xPos += xVelocity;
this.yPos += yVelocity;
}
public void increaseRotationDegree() {
if (rotationDegree >= 350)
rotationDegree = 0;
else
rotationDegree+=10;
}
public void decreaseRotationDegree() {
if (rotationDegree <= 0)
rotationDegree = 350;
else
rotationDegree-=10;
}
public void checkForCollisionWithFrame(final int WIDTH, final int HEIGHT) {
if (xPos + spaceShipDiameter < 0)
xPos = WIDTH;
else if (xPos > WIDTH)
xPos = 0 - spaceShipDiameter;
else if (yPos + spaceShipDiameter < 0)
yPos = HEIGHT;
else if (yPos > HEIGHT)
yPos = 0 - spaceShipDiameter;
}
public void display(Graphics2D g2d) {
g2d.setColor(Color.BLACK);
g2d.rotate(Math.toRadians(rotationDegree), xPos + spaceShipRadius, yPos + spaceShipRadius);
g2d.fillOval((int) xPos, (int) yPos, spaceShipDiameter, spaceShipDiameter);
g2d.setColor(Color.YELLOW);
g2d.drawLine((int) xPos + spaceShipRadius, (int) yPos , (int) xPos + spaceShipRadius, (int) yPos + spaceShipRadius);
}
}
Rock.java
import java.awt.*;
import java.util.Random;
public class Rock {
private int xPos;
private int yPos;
private int rockDiameter;
private int xVelocity;
private int yVelocity;
private int rockRadius;
private Color rockColor;
public Rock(int WIDTH, int HEIGHT) {
Random r = new Random();
rockDiameter = r.nextInt(40) + 30;
rockRadius = rockDiameter / 2;
xPos = r.nextInt(WIDTH - rockDiameter);
yPos = r.nextInt(HEIGHT - rockDiameter);
xVelocity = r.nextInt(6) - 3;
yVelocity = r.nextInt(6) - 3;
rockColor = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
}
public void moveForward() {
xPos += xVelocity;
yPos += yVelocity;
}
public void checkRockCollision(Rock rock) {
if (calculateDistances(rock.xPos, rock.yPos, rock.rockRadius))
switchVelocities(rock);
}
public void switchVelocities(Rock rock) {
int tempXVelocity = this.xVelocity;
int tempYVelocity = this.yVelocity;
this.xVelocity = rock.xVelocity;
this.yVelocity = rock.yVelocity;
rock.xVelocity = tempXVelocity;
rock.yVelocity = tempYVelocity;
moveForward();
rock.moveForward();
}
public boolean checkBulletCollision(Bullet bullet) {
return calculateDistances(bullet.getxPos(), bullet.getyPos(), bullet.getBulletRadius());
}
public boolean checkSpaceShipCollision(SpaceShip spaceShip) {
return calculateDistances(spaceShip.getxPos(), spaceShip.getyPos(), spaceShip.getSpaceShipRadius());
}
public boolean calculateDistances(double objectxPos, double objectyPos, int objectRadius) {
int radiusOfBoth = objectRadius + rockRadius;
double horDistance = Math.abs((objectxPos + objectRadius) - (xPos + rockRadius));
double verDistance = Math.abs((objectyPos + objectRadius) - (yPos + rockRadius));
double diagDistance = Math.sqrt(Math.pow(horDistance, 2) + Math.pow(verDistance, 2));
return diagDistance <= radiusOfBoth;
}
public void checkFrameCollision(final int WIDTH, final int HEIGHT) {
if (xPos < 0) {
xVelocity *= -1;
xPos = 0;
} else if (xPos + rockDiameter > WIDTH) {
xVelocity *= -1;
xPos = WIDTH - rockDiameter;
} else if (yPos < 0) {
yVelocity *= -1;
yPos = 0;
} else if (yPos + rockDiameter > HEIGHT) {
yVelocity *= -1;
yPos = HEIGHT - rockDiameter;
}
}
public void display(Graphics2D g2d) {
g2d.setColor(rockColor);
g2d.fillOval(xPos, yPos, rockDiameter, rockDiameter);
}
}
Bullet.java
import java.awt.*;
public class Bullet {
private double xPos;
private double yPos;
private int bulletWidth;
private int bulletHeight;
private double xVelocity;
private double yVelocity;
private int bulletRadius;
public Bullet(double startingXPos, double startingYPos, int rotationDegree) {
bulletHeight = 10;
bulletWidth = 10;
bulletRadius = bulletWidth / 2;
xPos = startingXPos - bulletRadius;
yPos = startingYPos - bulletRadius;
xVelocity = 5 * Math.sin(Math.toRadians(rotationDegree));
yVelocity = 5 * -Math.cos(Math.toRadians(rotationDegree));
}
public void moveForward() {
this.xPos += xVelocity;
this.yPos += yVelocity;
}
public double getxPos() {
return xPos;
}
public double getyPos() {
return yPos;
}
public int getBulletWidth() {
return bulletWidth;
}
public int getBulletHeight() {
return bulletHeight;
}
public int getBulletRadius() {
return bulletRadius;
}
public void display(Graphics2D g2d) {
g2d.setColor(Color.GREEN);
g2d.fillOval((int) xPos, (int) yPos, bulletWidth, bulletHeight);
}
}
You're only keeping track of the most recent key pressed. Instead, you need to keep track of every key being pressed. One way to do that is by using a boolean variable for each key. In your keyPressed() function, set the appropriate boolean to true, and in the keyReleased() function, set it to false. Then in your game loop, just check which booleans are true and take the appropriate action.

Collision detection using plain arrays and rectangles--java

I am almost done with my first little java game for my final project. It is a sidescroller where you have to shoot/avoid asteroids. My last problem is figuring out how to make my array of asteroids collide with the player's lasers. Here's what I have so far, there's an "AWT-EventQueue-0" java.lang.NullPointerException" on line 137, that I can't deal with. Any help is appreciated.
Edit: I added in my other classes, I realize it would be hard to judge the functionality of my code if I didn't show you where it came from.
package ShooterGame;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;
public class Board extends JPanel implements ActionListener
{
Enemy[] baddies = new Enemy[10000];
Player p;
Image img;
int y;
Timer time;
boolean lost = false;
static Font font = new Font("SanSerif", Font.BOLD, 24);
public AudioClip theme, bang, laser;
static ArrayList<Enemy> enemies;
public static int score = 0;
public static int lives = 5;
public Board()
{
p = new Player();
addKeyListener(new ActionListener());
setFocusable(true);
ImageIcon i = new ImageIcon("images/background.png");
img = i.getImage();
time = new Timer(5, this);
time.start();
for(int j = 0; j < baddies.length; j++)
{
Random ran = new Random();
y = ran.nextInt(365)+1;
baddies[j]= new Enemy((100*j + 700), y, "images/asteroid.gif");
}
theme = Applet.newAudioClip(getClass().getResource("theme.mid"));
theme.play();
bang = Applet.newAudioClip(getClass().getResource("bang.wav"));
}
public void actionPerformed(ActionEvent e)
{
checkCollisions();
ArrayList<?> bullets = Player.getBullets();
for(int i = 0; i < bullets.size(); i++)
{
Bullet b = (Bullet)bullets.get(i);
if(b.isVisible() == true)
{
b.move();
}
else
{
bullets.remove(i);
}
}
p.move();
for(int i = 0; i < baddies.length; i++)
{
if(p.x > 400)
{
baddies[i].move(p.getdx());
}
}
repaint();
}
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
if(lost)
{
g2d.drawString("You Lose!", 300, 300);
}
if((p.getX() - 590) % 2400 == 0 || (p.getX() - 590) % 2400 == 1)
{
p.nx = 0;
}
if((p.getX() - 1790) % 2400 == 0 ||(p.getX() - 1790) % 2400 == 1)
{
p.nx2 = 0;
}
g2d.drawImage(img, 685-p.nx2, 0, null);
if(p.getX() >= 590)
{
g2d.drawImage(img, 685-p.nx, 0, null);
}
g2d.drawImage(p.getImage(), p.edge, p.getY(), null);
ArrayList<?> bullets = Player.getBullets();
for(int i = 0; i < bullets.size(); i++)
{
Bullet b = (Bullet)bullets.get(i);
g2d.drawImage(b.getImg(), b.getX(), b.getY(), null);
}
for(int i = 0; i < baddies.length; i++)
{
if(baddies[i].isAlive == true)
{
g2d.drawImage(baddies[i].getImg(), baddies[i].getX(), baddies[i].getY(), null);
}
}
g2d.setColor(Color.white);
g2d.drawString("Score: " + score, 0, 320);
g2d.drawString("Lives: " + lives, 80, 320);
}
public void checkCollisions()
{
Rectangle[] rect = new Rectangle[baddies.length];
for(int i = 0; i < baddies.length; i++)
{
Enemy e = (Enemy)baddies[i];
rect[i] = e.getBounds();
}
ArrayList<?> bullets = Player.getBullets();
for (int i = 0; i < bullets.size(); i++)
{
Bullet b = (Bullet) bullets.get(i);
Rectangle b1 = b.getBounds();
if (rect[i].intersects(b1) && baddies[i].isAlive())
{
score++;
baddies[i].isAlive = false;
baddies[i].isVisible = false;
bang.play();
}
Rectangle h = p.getBounds();
if (h.intersects(rect[i]))
{
if(baddies[i].isAlive() == true)
{
lives--;
if(lives < 0)
{
lost = true;
theme.stop();
System.exit(1);
}
}
}
}
}
private class ActionListener extends KeyAdapter
{
public void keyReleased(KeyEvent e)
{
p.keyReleased(e);
}
public void keyPressed(KeyEvent e)
{
p.keyPressed(e);
}
}
}
Enemy
package ShooterGame;
import java.awt.*;
import javax.swing.ImageIcon;
public class Enemy
{
int x, y;
Image img;
boolean isAlive = true;
boolean isVisible = true;
public Enemy(int startX, int startY, String location)
{
x = startX;
y = startY;
ImageIcon l = new ImageIcon(location);
img = l.getImage();
}
public Rectangle getBounds()
{
return new Rectangle(x, y, 60, 60);
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public boolean isAlive()
{
return isAlive;
}
public boolean isVisible()
{
return isVisible;
}
public Image getImg()
{
return img;
}
public void move(int dx)
{
x = x - dx;
}
}
Bullet
package ShooterGame;
import java.applet.Applet;
import java.awt.*;
import javax.swing.ImageIcon;
import java.applet.AudioClip;
public class Bullet
{
int x, y;
Image img;
boolean visible;
public Bullet(int startX, int startY)
{
x = startX;
y = startY;
ImageIcon newBullet = new ImageIcon("images/bullet.gif");
img = newBullet.getImage();
visible = true;
}
public Rectangle getBounds()
{
return new Rectangle(x, y, 9, 5);
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public Image getImg()
{
return img;
}
public boolean isVisible()
{
return visible;
}
public void move()
{
x = x + 2;
if(x > 700)
{
visible = false;
}
}
public void setVisible(boolean isVisible)
{
visible = isVisible;
}
}
Player
package ShooterGame;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class Player
{
int x, dx, y, dy, nx2, nx, edge, ceiling;
Image player;
ImageIcon ib = new ImageIcon("images/player1back.gif");
ImageIcon i = new ImageIcon("images/playerstill.gif");
ImageIcon f = new ImageIcon("images/playerforward.gif");
ImageIcon up = new ImageIcon("images/playerup.gif");
ImageIcon down = new ImageIcon("images/playerdown.gif");
public AudioClip laser;
static ArrayList<Bullet> bullets;
public Player()
{laser = Applet.newAudioClip(getClass().getResource("laser.wav"));
player = ib.getImage();
x = 75;
nx = 0;
nx2 = 685;
y = 172;
edge = 150;
ceiling = 0;
bullets = new ArrayList<Bullet>();
}
public static ArrayList<Bullet> getBullets()
{
return bullets;
}
public void fire()
{
Bullet z = new Bullet((edge + 60), (y+17));
bullets.add(z);
}
public Rectangle getBounds()
{
return new Rectangle(edge, y, 43, 39);
}
public void move()
{
y = y + dy;
if(y < ceiling)
{
y = ceiling;
}
if(y > 290)
{
y = 290;
}
if(dx != -1)
{
if(edge + dx <= 151)
{
edge = edge + dx;
}
else
{
x = x + dx;
nx2 = nx2 + dx;
nx = nx + dx;
}
}
else
{
if(edge + dx > 0)
{
edge = edge + dx;
}
}
}
public int getX()
{
return x;
}
public int getdx()
{
return dx;
}
public int getY()
{
return y;
}
public Image getImage()
{
return player;
}
public void keyPressed(KeyEvent e)
{
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT)
{
dx = 2;
player = f.getImage();
}
if(key == KeyEvent.VK_UP)
{
dy = -1;
player = up.getImage();
}
if(key == KeyEvent.VK_DOWN)
{
dy = 1;
player = down.getImage();
}
if(key == KeyEvent.VK_SPACE)
{
fire();
laser.play();
}
}
public void keyReleased(KeyEvent e)
{
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT)
{
dx = 1;
player = ib.getImage();
}
if(key == KeyEvent.VK_UP)
{
dy = 0;
player = ib.getImage();
}
if(key == KeyEvent.VK_DOWN)
{
dy = 0;
player = ib.getImage();
}
}
}
Frame
package ShooterGame;
import javax.swing.*;
public class Frame
{
public AudioClip theme;
public Frame()
{
JFrame frame = new JFrame();
frame.add(new Board());
frame.setTitle("SideShooter");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700,365);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
public static void main(String[] args)
{
new Frame();
}
}
Ok, so the problem is the line mentioned in the other answer, but I believe it is that all the enemies may not be initialised before it checks collisions. Because you are making 10000 of them to start with, I think your action performed method may be checking collisions before they have all be created.
One thing to try could be to bring down the amount of enemies you have and see if it still keeps happening, try 100 or 1000, but this still won't fix the issue.
You really want to be change your game to run in it's own loop though, at the moment you are only checking collisions when the player performs an action. so if the player stops moving, no collision detection...
I would suggest that you find a book called 'Killer Game Programming in Java', there are free ebook version, and just read the first 2 chapters about making a game loop. The book is a bit old, but the basics of the loop are very good.
This question here also contains a very simple loop, and some suggestions in the comments about how to make it better.
The error is on the line
rect[i] = e.getBounds();
Are you not initializing the bounds of your Enemy class correctly? Alternatively, the Enemy you pulled out of the array could be null.

Three Paddle Pong Hit Detection

I am creating yet another version of pong. This one uses 3 paddles for each person. I have spent almost two hours trying to figure out why the two other paddles are not detecting when the ball strikes the paddle. The original (top) paddle does detect the hit and properly updates the hit counter. I have tried separate if statements, else if statements etc., with no success. I created three Y variables to detect the position of all three paddles still no luck.
Any suggestions?
import java.awt.Point;
public class box {
private int xTopLeft, yTopLeft, width, height;
int xBall, yBall;
private int radius = 5;
int xBallVel, yBallVel;
int VELOCITY_MAG =5;
public Point ballLoc = new Point();
private int paddleY;
private int paddleYP2;
private int paddleYP3;
private int paddleWidth = 20;
private int paddleWidth2 = 20;
private int paddleWidth3 = 20;
int hitCount = 0;
int missCount = 0;
private boolean updating=true;
public int getBallRadius()
{
return radius;
}
public Point getBallLoc()
{
ballLoc.x = xBall;
ballLoc.y = yBall;
return ballLoc;
}
public box(int x, int y, int w, int h)
{
xTopLeft =x;
yTopLeft = y;
width =w;
height = h;
createRandomBallLocation();
}
public void updatePaddle(int y)
{
paddleY = y;
}
public void updatePaddleP2(int yp2)
{
paddleYP2 = yp2;
}
public void updatePaddleP3(int yp3)
{
paddleYP3 = yp3;
}
public int getPaddleWidth()
{
return paddleWidth ;
}
public int getPaddleWidth2()
{
return paddleWidth2 ;
}
public int getPaddleWidth3()
{
return paddleWidth3 ;
}
public int getPaddleY()
{
System.out.println(paddleY);
return paddleY;
}
public int getPaddleP2()
{
System.out.println(paddleYP2);
return paddleYP2;
}
public int getPaddleP3()
{
return paddleYP3;
}
public int getHitCount()
{
return hitCount;
}
public int getMissCount()
{
return missCount;
}
public int velMag()
{
return VELOCITY_MAG;
}
public void update()
{
if (!updating) return;
xBall = xBall + xBallVel;
yBall = yBall + yBallVel;
if (xBall + radius >= xTopLeft+width && xBallVel>=0)
if ((yBall >= paddleY-paddleWidth && yBall <= paddleY + paddleWidth)
|| (yBall >= paddleYP2-paddleWidth2 && yBall <= paddleYP2 + paddleWidth2 )
|| (yBall >= paddleYP3-paddleWidth3 && yBall <= paddleYP3 + paddleWidth3 ))
{
// hit paddles
xBallVel = - xBallVel;
hitCount++;
}
else if (xBall+radius >= xTopLeft + width)
{
xBallVel = - xBallVel;
}
if (yBall+radius >= yTopLeft + height && yBallVel >= 0)
{
yBallVel = - yBallVel;
}
if (yBall-radius <= yTopLeft && yBallVel <=0)
{
yBallVel = - yBallVel;
}
if (xBall-radius <= xTopLeft && xBallVel <= 0)
{
xBallVel = - xBallVel;
}
}
public void createRandomBallLocation()
{
xBall = xTopLeft + radius +
(int)((width-2*radius)*Math.random());
yBall = yTopLeft + radius +
(int)((height-2*radius)*Math.random());
xBallVel = velMag();
yBallVel = velMag();
}
}
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.image.BufferStrategy;
public class Pong extends JFrame
implements Runnable{
box box = null;
int top, left, width, height;
final int LINE_THICKNESS = 5;
Graphics bufferGraphics;
int sleep=25;
public Pong(String name)
{
super(name);
int windowWidth = 1024;
int windowHeight =768;
this.setSize(windowWidth, windowHeight);
this.setResizable(false);
this.setLocation(400, 150);
this.setVisible(true);
this.createBufferStrategy(4);
MyMouseClick mmc = new MyMouseClick();
addMouseListener(mmc);
MyMouseMotion mmm = new MyMouseMotion();
addMouseMotionListener(mmm);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Thread thread = new Thread(this);
thread.start();
}
public void run()
{
while(true)
{
try
{
if (box != null)
{
box.update();
repaint();
}
Thread.sleep(sleep);
}
catch (InterruptedException e)
{}
}
}
public void paint(Graphics g)
{
BufferStrategy bf = this.getBufferStrategy();
g = bf.getDrawGraphics();
Dimension d = getSize();
if (box ==null)
{
Insets insets = getInsets();
left = insets.left;
top = insets.top;
width = d.width-left - insets.right;
height = d.height - top - insets.bottom;
box = new box(left, top, width, height);
}
g.fillRect(0,0, d.width, d.height);
g.setColor(Color.BLUE);
g.setFont(new Font("Arial", 20, 30));
g.drawString("Hits: "+box.getHitCount(), 20, 60);
g.setColor(Color.red);
g.setFont(new Font("Arial", 20, 30));
g.drawString("Misses: "+box.getMissCount(), 20, 380);
g.fillRect(left, top, left+width, LINE_THICKNESS); // top of box
g.setColor(Color.white);
g.fillRect(left, top+height, left+width, LINE_THICKNESS); // bottom of box
g.drawLine(left, top, left, top+height); // left of box
g.drawLine(left+width, top, left+width, top+height); // right side
Point ballLoc = box.getBallLoc();
int radius = box.getBallRadius();
g.fillOval(ballLoc.x - radius, ballLoc.y-radius, 2*radius, 2*radius);
// Draw paddles Player 1
g.setColor(Color.yellow);
int yp = box.getPaddleY();
int yp2 = box.getPaddleP2();
int yp3 = box.getPaddleP3();
int yw = box.getPaddleWidth();
int yw2 = box.getPaddleWidth2();
int yw3 = box.getPaddleWidth3();
g.fillRect(left+width-5, yp-yw, 4, 50);
g.fillRect(left+width-5, (yp2-yw2)+280, 4, 50);
g.fillRect(left+width-5, (yp3-yw3)+140, 4, 50);
bf.show();
}
// *********************** Inner classes
class MyMouseClick extends MouseAdapter
{
public void mouseClicked(MouseEvent e)
{
box = null;
repaint();
}
}
class MyMouseMotion extends MouseMotionAdapter
{
public void mouseMoved(MouseEvent e)
{
int y = e.getY();
int y2 = e.getY();
int y3 = e.getY();
if (box != null)
{
box.updatePaddle(y);
box.updatePaddleP2(y2);
box.updatePaddleP3(y3);
repaint();
}
}
}
// ************************************
public static void main(String[] args) {
Pong t = new Pong("Three Paddle Pong");
t.setVisible(true);
} // end of main
}
In the paint method you do paint your 3 paddles at different y positions, but for the actual paddle positions, paddleYP? which are used for collision detection, you just set the 3 paddles to the same y in mouseMoved.

Categories