Breakout brick collision in java - java

I have been working on a Breakout game and have just about everything done except for the brick collision. The ball bounces of the wall, paddle and the brick. However when the ball bounces of the brick, the brick does not disappear. I am really stuck on this. Any ideas are greatly appreciated.
What I have for brick, ball and main class:
Brick Class:
import java.awt.*;
import java.applet.*;
public class Brick2{
private int x;
private int y;
public Brick2(int X, int Y){
x =X;
y=Y;
}
public void update(Ball ba){
collision(ba);
}
public void collision(Ball ba){
int bX = ba.getX();
int bY = ba.getY();
int bHeight = ba.getImageHeight();
int bWidth = ba.getImageWidth();
for(int x=0; x <= 600; x+=55){
for (int y=0; y<= 100; y+=25){
if (bX-bWidth<=x && bX+bWidth>=x && bY-bHeight<=y && bY+bHeight>=y){
ba.setXVel(6);
}
}
}
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public void paint(Graphics g){
for(int x=0; x <= 800; x+=55){
for (int y=0; y<= 100; y+=25){
g.setColor(Color.RED);
g.fillRect(x,y,50,20);
}
}
}
}
Ball Class:
import java.awt.*;
import java.applet.*;
public class Ball {
private int x=355 ;
private int y=200;
private int speed = 6;
private int xVel = -speed;
private int yVel = speed;
private boolean gameOver = false;
private Image ball;
public Ball (Breakout bR){
ball = bR.getImage(bR.getDocumentBase(),"ball.png");
}
public void update(Breakout bR, Paddle p){
x += xVel;
y += yVel;
if (x < 0){
xVel = speed;
}
else if (x > bR.getWidth()){
xVel = -speed;
}
if(y > bR.getHeight()){
gameOver = true;
}
else if (y < 0){
yVel = speed;
}
collision(p);
}
public void collision(Paddle p){
int pX = p.getX();
int pY = p.getY();
int pHeight = p.getImageHeight();
int pWidth = p.getImageWidth();
if (pX<=x && pX+pWidth>=x && pY-pHeight<=y && pY+pHeight>=y){
yVel = -speed;
}
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public int getImageWidth(){
return ball.getWidth(null);
}
public int getImageHeight(){
return ball.getHeight(null);
}
public void setXVel(int xv){
yVel = xv;
}
public void paint (Graphics g, Breakout bR){
g.drawImage(ball,x,y,bR);
if (gameOver){
g.setColor(Color.WHITE);
g.drawString("Game Over", 100,300);
}
}
}
Main Class:
import java.applet.*;
import java.awt.*;
public class Breakout extends Applet implements Runnable{
Thread thread = new Thread(this);
boolean running = true;
//Brick b;
Brick2 b2;
Paddle p;
Ball ba;
Image dbImage;
Graphics dbg;
public void init(){
setSize(800,600);
//b = new Brick(this);
b2 = new Brick2(0,0);
p = new Paddle(this);
ba = new Ball(this);
}
public void start(){
thread.start();
}
public void destroy(){
running = false;
}
public void stop(){
running = false;
}
public void run(){
while(running){
//b.update(this,ba);
b2.update(ba);
p.update(this);
ba.update(this,p);
repaint();
try{
thread.sleep(20);
}
catch (InterruptedException e){
System.out.println("AN ERROR HAS OCCURED");
}
}
}
public void update(Graphics g, Brick2 b){
dbImage = createImage(getWidth(),getHeight());
dbg = dbImage.getGraphics();
paint(dbg);
g.drawImage(dbImage,0,0,this);
}
public void paint(Graphics g){
g.fillRect(0,0,800,600);
//b.paint(g,this);
b2.paint(g);
p.paint(g,this);
ba.paint(g,this);
}
}
Thanks for your help.

You could add a boolean isDestroyed = false in your Brick Class. Once the Ball touches the Brick (in your collision() method), set isDestroyed = true and stop drawing/interacting with that Brick :) Don't forget to make that brick = null so it frees up memory later :)
The best way to do this would be to create the boolean isDestroyed as a private variable and get its' value with a isDestroyed method:
public class Brick2 {
private boolean isDestroyed = false;
public boolean isDestroyed() {
return isDestroyed;
}
public void setIsDestroyed(boolean newValue) {
isDestroyed = newValue;
}
}
Then, in your Main class, before calling b2.paint(), check if b2.isDestroyed returns true:
public class Breakout...{
public void paint(...) {
if(b2 != null && !b2.isDestroyed())
b2.paint(g);
else
b2 = null;
}
BUT, if I were you, I would create an ArrayList of Bricks and add/remove them through the ArrayList. They will be easier to manage that way :) Hola if you need anything else.

Treat an array of bricks the same way you would treat any other collection of objects. You can use List<brick> = new ArrayList<brick>();
Brick should have four coordinates and shape would fit well for this purpose, int brickLife = 1 that changes to zero once the ball breaks it. You might want to increase the value to add sturdy bricks.

Related

Collision detection only working on top side of wall - Java

I have an assignment to create a 2D game, this game must use an abstract class Shape which is used to draw shapes. I decided to make a 2D platformer, but it's my first time doing something like this. I am trying to implement collision detection, and decided to create an offset of my player object to see if it collides with my rectangle object, and stop movement if it does. This is only working for the top side, however on the right, left and botton the player will move through the rectangle and I don't understand why. I expected the collision detection to work for all sides. I would like to know how I can change my collision detection to work for all sides of the rectangle.
Here's a gif showing what happens:
My App class:
package A2;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import java.util.TreeSet;
import static java.awt.event.KeyEvent.*;
public class App extends JFrame {
private static final int GRAVITY = 10;
private static final int MAX_FALL_SPEED = 30;
public App() {
final Player player = new Player(200, 300);
final Rectangle rectangle = new Rectangle(100, 400);
JPanel mainPanel = new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
player.draw(g);
rectangle.draw(g);
}
};
mainPanel.addKeyListener(new controlHandler(this, player, rectangle));
mainPanel.setFocusable(true);
add(mainPanel);
setLayout(new GridLayout());
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(600, 600);
}
class controlHandler implements ActionListener, KeyListener {
int keyCode;
App app;
Player player;
Rectangle rectangle;
TreeSet<Integer> keys = new TreeSet<>();
Timer time = new Timer(5, this);
boolean collision = false;
public controlHandler(App app, Player player, Rectangle rectangle) {
this.app = app;
this.player = player;
this.rectangle = rectangle;
time.start();
}
public void actionPerformed(ActionEvent e) {
player.x += player.xVelocity;
player.y += player.yVelocity;
Rectangle2D offset = player.getOffsetBounds();
if(offset.intersects(this.rectangle.wallObj.getBounds2D())){
collision = true;
player.xVelocity = 0;
player.yVelocity = 0;
}
else collision = false;
repaint();
}
public void keyPressed(KeyEvent e) {
keyCode = e.getKeyCode();
keys.add(keyCode);
switch (keyCode) {
case VK_UP:
moveUp();
break;
case VK_DOWN:
moveDown();
break;
case VK_LEFT:
moveLeft();
break;
case VK_RIGHT:
moveRight();
break;
}
}
public void keyReleased(KeyEvent e) {
released();
}
public void keyTyped(KeyEvent e) { }
public void moveUp() {
player.xVelocity = 0;
player.yVelocity = -2;
}
public void moveDown() {
if(!collision) {
player.xVelocity = 0;
player.yVelocity = 2;
}
}
public void moveLeft() {
player.xVelocity = -2;
player.yVelocity = 0;
}
public void moveRight() {
player.xVelocity = 2;
player.yVelocity = 0;
}
public void released() {
player.xVelocity = 0;
player.yVelocity = 0;
}
}
public static void main(String[] args) {
App app = new App();
app.setVisible(true);
}
}
abstract class Shape {
public double x;
public double y;
public void draw(Graphics g) { }
}
Player class:
package A2;
import java.awt.*;
import java.awt.geom.Rectangle2D;
public class Player extends Shape {
public double xVelocity;
public double yVelocity;
public double length = 60;
public double top;
public double right;
public double left;
public double bottom;
public Rectangle2D playerObj;
public Player(double x, double y) {
this.x = x;
this.y = y;
playerObj = new Rectangle2D.Double(x, y, length, length);
}
public Rectangle2D getOffsetBounds(){
return new Rectangle2D.Double(x + xVelocity , y + yVelocity , length, length);
}
public void draw(Graphics g) {
playerObj = new Rectangle2D.Double(x, y, length, length);
g.setColor(Color.BLACK);
Graphics2D g2 = (Graphics2D)g;
g2.fill(playerObj);
}
}
Rectangle class (will be a platform):
package A2;
import java.awt.*;
import java.awt.geom.Rectangle2D;
public class Rectangle extends Shape {
public double width = 400;
public double height = 30;
public double top;
public double right;
public double left;
public double bottom;
public Rectangle2D wallObj;
public Rectangle(double x, double y) {
this.x = x;
this.y = y;
wallObj = new Rectangle2D.Double(x, y, width, height);
}
public void draw(Graphics g) {
g.setColor(Color.ORANGE);
Graphics2D g2 = (Graphics2D)g;
g2.fill(wallObj);
}
}
So, based on my understanding, your collision detection process is basically to create a "virtual" instance of the object and determine if it will collide.
Your code is actually work, you can tell by the fact that the object "stops" moving once it collides, but what you're not doing, is reseting the objects position after it.
Let's look at the original code...
public void actionPerformed(ActionEvent e) {
player.x += player.xVelocity;
player.y += player.yVelocity;
Rectangle2D offset = player.getOffsetBounds();
if (offset.intersects(this.rectangle.wallObj.getBounds2D())) {
collision = true;
player.xVelocity = 0;
player.yVelocity = 0;
} else {
collision = false;
}
repaint();
}
Update the position of the object
Create a virtual instance of the object, which applies the velocity to the objects current position ... again?
Determine if the object collides
Stop the movement if any
... where do you reset the position of object so it's no longer colliding?!?
Instead, you shouldn't set the position of the object until AFTER you've determine if a collision has occurred or not, for example...
public void actionPerformed(ActionEvent e) {
Rectangle2D offset = player.getOffsetBounds();
if (offset.intersects(this.rectangle.wallObj.getBounds2D())) {
collision = true;
player.xVelocity = 0;
player.yVelocity = 0;
} else {
player.x += player.xVelocity;
player.y += player.yVelocity;
collision = false;
}
repaint();
}
The problem with this approach, though, is if the velocity is large enough, the object will appear not to collide, but stop a little before it, as the amount of change is larger than the remaining gap.
What you need to do, is once you've detected a collision is calculate the difference between the amount you want to move and the space available and move the object only by that amount instead

brick collision for breakout in java

I am working on a breakout game. i have almost everything done except for the collision for the bricks. so far, when the ball hits the brick the brick bounces back but the brick does not disappear. If someone could help me that would be great.
Main class:
public class Breakout extends Applet implements Runnable{
Thread thread = new Thread(this);
boolean running = true;
Brick2 b;
Paddle p;
Ball ba;
Image dbImage;
Graphics dbg;
public void init(){
setSize(800,600);
b = new Brick2();
p = new Paddle(this);
ba = new Ball(this);
}
public void start(){
thread.start();
}
public void destroy(){
running = false;
}
public void stop(){
running = false;
}
public void run(){
while(running){
b.update(ba);
p.update(this);
ba.update(this,p);
repaint();
try{
thread.sleep(20);
}
catch (InterruptedException e){
System.out.println("AN ERROR HAS OCCURED");
}
}
}
public void update(Graphics g){
dbImage = createImage(getWidth(),getHeight());
dbg = dbImage.getGraphics();
paint(dbg);
g.drawImage(dbImage,0,0,this);
}
public void paint(Graphics g){
g.fillRect(0,0,800,600);
b.paint(g);
p.paint(g,this);
ba.paint(g,this);
}
}
Brick Class:
public class Brick2{
private int x;
private int y;
public Brick2(){
}
public void update(Ball ba){
collision(ba);
}
public void collision(Ball ba){
int bX = ba.getX();
int bY = ba.getY();
int bHeight = ba.getImageHeight();
int bWidth = ba.getImageWidth();
for(int x=0; x <= 800; x+=55){
for (int y=0; y<= 100; y+=25){
if (bX-bWidth<=x && bX+bWidth>=x && bY-bHeight<=y && bY+bHeight>=y){
ba.setXVel(6);
}
}
}
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public void paint(Graphics g){
for(int x=0; x <= 800; x+=55){
for (int y=0; y<= 100; y+=25){
g.setColor(Color.RED);
g.fillRect(x,y,50,20);
}
}
}
}
Ball Class:
public class Ball {
private int x=355 ;
private int y=200;
private int speed = 6;
private int xVel = -speed;
private int yVel = speed;
private boolean gameOver = false;
private Image ball;
public Ball (Breakout bR){
ball = bR.getImage(bR.getDocumentBase(),"ball.png");
}
public void update(Breakout bR, Paddle p){
x += xVel;
y += yVel;
if (x < 0){
xVel = speed;
}
else if (x > bR.getWidth()){
xVel = -speed;
}
if(y > bR.getHeight()){
gameOver = true;
}
else if (y < 0){
yVel = speed;
}
collision(p);
}
public void collision(Paddle p){
int pX = p.getX();
int pY = p.getY();
int pHeight = p.getImageHeight();
int pWidth = p.getImageWidth();
if (pX<=x && pX+pWidth>=x && pY-pHeight<=y && pY+pHeight>=y){
yVel = -speed;
}
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public int getImageWidth(){
return ball.getWidth(null);
}
public int getImageHeight(){
return ball.getHeight(null);
}
public void setXVel(int xv){
yVel = xv;
}
public void paint (Graphics g, Breakout bR){
g.drawImage(ball,x,y,bR);
if (gameOver){
g.setColor(Color.WHITE);
g.drawString("Game Over", 100,300);
}
}
}
Thanks for your help.
Nothing seems to happen in class Ball's collision function if a collision is detected.
After
ba.setXVel(6);
You need to have some code to make the brick no longer paint. Try giving the brick a visibility attribute in the class definition:
private Boolean visible;
When in the collision function after
ba.setXVel(6);
Insert
setVisible(false);
You'll need to write a setter and getter for the visible attribute. Then in the paint function, set it only to paint if visible is true.
You'll need to have more than one Brick2 instance. Each Brick2 instance will represent one individual brick. Put them in a collection like List and step through them to draw them.
One way to create the list would be:
List<Brick2> bricks = new List<Brick2>;
for (i = 0; i > num_bricks; i++ ) {
bricks.add(new Brick2());
}
But you'll need to have a way to set the position of each brick. Perhaps based on the brick number(i) and use the brick constructor to derive it's position based on the order in which they're created.

Java Applet Timer and Jumping

Okay, I kind of need lots of help, so whatever advice anyone has would be much appreciated! I am trying to write a running/jumping game where the player/ball must avoid the blocks to reach the finish line as quickly as possible. Right now, my two main issues are the jumping action and creating a timer. When my player jumps, it goes up, and then down.
I have included the following code in my Circle class:
public void horiz(int val){
for(int c = 0; c<val+1; c++){
x++;
repaint();}
}
public void vert(int val){
y += val;
}
public void down(int val){
y += val;
}
And then It is executed through buttons:
public void actionPerformed(ActionEvent e){
if(e.getSource() instanceof Button){
if(e.getSource() == run)
player.horiz(10);
else if (e.getSource()== jump){
player.vert(-10);
}
repaint();
collision();
}
In order to get the player to go up, and then back down, I had tried this...
public void actionPerformed(ActionEvent e){
if(e.getSource() instanceof Button){
if(e.getSource() == run)
player.horiz(10);
else if (e.getSource()== jump){
player.vert(-10);
repaint();
player.down(10);
}
repaint();
collision();
}
But I think I need to have it wait a few seconds before coming back down. I have read a bunch about swing, util, and robot timers, but I do not know which/how to implement them here.
My other problem is creating a timer that displays the time elapsed since the game has started. I thing This could be execute similarly to the jumping timer, but, again, I am unsure which type of timer I should be using.
If I am right, I cannot use swing because my program is written in AWT? Please excuse the awful colors, I am still figuring out the basics. Thanks so much for any advice of help you can give me! :)
Here is the full code:
import java.awt.*;
import java.awt.Rectangle;
import java.awt.Shape;
import javafx.scene.shape.*;
import java.awt.event.*;
import java.util.Random;
import java.util.Timer;
import javax.swing.JOptionPane;
import java.awt.Toolkit;
import java.util.Timer;
import java.util.TimerTask;
import java.applet.Applet;
public class TryingAgain extends Applet
implements ActionListener{
//creates arrays of rect values
int[]xA = new int[10];
int[]yA = new int[10];
int[]widthA = new int[10];
int[]heightA = new int[10];
private Rectangle rectangle;
//creates buttons to move player
private Button run = new Button("Run");
private Button jump = new Button("Jump");
//creates player and obstacles
private Circle player = new Circle(110,110,20);
private makeRect block = new makeRect();
private finishLine line = new finishLine();
//initiates the buttons with actionListener
public void init(){
this.setSize(new Dimension(1300,500));
setBackground(Color.GREEN);
add(run);
add(jump);
run.addActionListener(this);
jump.addActionListener(this);
}
//draws the player and blocks on the screen
public void paint(Graphics g){
player.draw(g);
block.draw(g);
line.draw(g);
}
//if methods to be control movement
public void actionPerformed(ActionEvent e){
if(e.getSource() instanceof Button){
if(e.getSource() == run)
player.horiz(10);
else if (e.getSource()== jump){
player.vert(-10);
}
repaint();
collision();
}
}
public void collision(){
if(crashTest() == true){
JOptionPane.showMessageDialog(this, "Game Over", "Game Over", JOptionPane.YES_NO_OPTION);
System.exit(ABORT);
}
if(winTest() == true){
JOptionPane.showMessageDialog(this, "You Finished!", "You Finished!", JOptionPane.PLAIN_MESSAGE);
}
}
class Circle{
private int radius;
private int x,y;
public Circle(){
x = 110; y = 110;
radius = 20;
}
public Circle(int x0, int y0, int rad){
x = x0; y = y0; radius = rad;
}
public void draw(Graphics g){
g.setColor(Color.CYAN);
g.fillOval(x - radius, y-radius, 2*radius, 2*radius);
}
public void horiz(int val){
for(int c = 0; c<val+1; c++){
x++;
repaint();}
}
public void vert(int val){
y += val;
}
public void down(int val){
y += val;
}
public Rectangle getBounds(){
return new Rectangle(x-radius, y-radius, 2*radius, 2*radius);
}
}
class makeRect{
private int Xmax = 150;
private int Xmin = 50;
private int Wmax = 50;
private int Hmax = 25;
private int Wmin = 10;
private int Hmin = 5;
Random rand = new Random();
int randx = rand.nextInt((Xmax-Xmin)+1)+Xmin;
int randh = rand.nextInt((Hmax-Hmin)+1)+Hmin;
int randw = rand.nextInt((Wmax-Wmin)+1)+Wmin;
//fills arrays
{for(int i = 0; i < 10; i++){
Random rand = new Random();
int randx = rand.nextInt((Xmax-Xmin)+1)+Xmin;
int randh = rand.nextInt((Hmax-Hmin)+1)+Hmin;
int randw = rand.nextInt((Wmax-Wmin)+1)+Wmin;
if(i>0)
xA[i] = (randx+xA[i-1]);
else
xA[i] = 160;
yA[i] = randh+110;
widthA[i] = randw;
heightA[i] = randh;
}
}
private int x, y, width, height;
public makeRect(){
x = 150; y = 120; width = 30; height = 10;
}
public void makeRect(int x0, int y0, int w0, int h0){
x = x0; y = y0; width = w0; height = h0;
}
public void draw(Graphics g) {
g.setColor(Color.ORANGE);
{for(int i = 0; i < 10; i++){
g.fillRect(xA[i], yA[i], heightA[i], widthA[i]);
}}
}
public Rectangle getBounds(){
return new Rectangle(randx, 110+randh, 30, 10);
}
}
class finishLine{
private int x, y, width, height;
public void finishLine(int x0, int y0, int w0, int h0){
x = x0; y = y0; width = w0; height = h0;
}
public void draw(Graphics g){
g.setColor(Color.MAGENTA);
g.fillRect(1200, 80, 30, 30);
}
}
public boolean crashTest(){
boolean end = false;
{for(int i = 0; i<10; i++){
if(player.getBounds().intersects(new Rectangle(xA[i], yA[i], heightA[i], widthA[i])))
end = true;
}
return end;
}
}
public boolean winTest(){
boolean win = false;
if(player.getBounds().intersects(new Rectangle(1200, 80, 30, 30)))
win = true;
return win;
}
}

Java-Pong AI not moving

I am making pong in java but the enemy AI is not moving. It should move to the direction the ball goes to. Please can someone help me?
Main class:
import javax.swing.*;
public class Main extends JFrame{
final static int WW = 800;
final static int WH = 600;
public Main(){
setSize(WW,WH);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setTitle("Pong");
add(new GamePanel());
setVisible(true);
}
public static void main(String[] args){
new Main();
}
}
GamePanel class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GamePanel extends JPanel implements ActionListener,KeyListener{
Player player = new Player();
Computer computer = new Computer();
Ball ball = new Ball();
public GamePanel(){
Timer time = new Timer(20, this);
time.start();
this.addKeyListener(this);
this.setFocusable(true);
}
private void update(){
player.update();
ball.update();
ball.Collision(player);
computer.update();
ball.Collision(computer);
}
public void paintComponent(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(0, 0, Main.WW, Main.WH);
player.paint(g);
ball.paint(g);
computer.paint(g);
}
public void actionPerformed(ActionEvent e){
update();
repaint();
}
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_UP){
player.setyv(-10);
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN){
player.setyv(10);
}
}
public void keyReleased(KeyEvent e){
if(e.getKeyCode()==KeyEvent.VK_UP || e.getKeyCode()==KeyEvent.VK_DOWN)
player.setyv(0);
}
public void keyTyped(KeyEvent e){
}
}
Player class:
import java.awt.*;
public class Player {
private int y = 300;
private int w = 20;
private int h = 120;
private int yv = 0;
private int x = 700;
public Player(){
}
public void update(){
y = y + yv;
}
public void paint(Graphics g){
g.setColor(Color.WHITE);
g.fillRect(x,y,w,h);
}
public void setyv(int speed){
yv = speed;
}
public int getX(){
return this.x;
}
public int getY(){
return this.y;
}
public int getW(){
return this.w;
}
public int getH(){
return this.h;
}
}
Ball class:
import java.awt.*;
public class Ball {
private int x = 400;
private int y = 300;
private int xv = -10;
private int yv = 10;
public void update(){
x = x += xv;
y = y += yv;
if(x < 10){
xv = 10;
}
if(x > 770){
xv = -10;
}
if(y < 10){
yv = 5;
}
if(y > 550){
yv = -5;
}
}
public int getY(){
return this.y;
}
public void paint(Graphics g){
g.setColor(Color.WHITE);
g.fillOval(x, y, 20, 20);
}
public void Collision(Player player){
if(this.x > (player.getX()-10)){
if(this.y > player.getY() && (this.y < player.getY() + player.getH())){
xv = -10;
}
}
}
public void Collision(Computer cpu){
if(this.x < (cpu.getX()+10)){
if(this.y > cpu.getY() && (this.y < cpu.getY() + cpu.getH())){
xv = 10;
}
}
}
}
Computer class:
import java.awt.*;
public class Computer {
private int y = 300;
private int w = 20;
private int h = 120;
private int yv = 0;
private int x = 100;
Ball ballpos = new Ball();
public Computer(){
}
public void update(){
if(ballpos.getY() < this.y){
yv = -1;
}
else if(ballpos.getY() > this.y){
yv = 1;
}
y = y + yv;
}
public void paint(Graphics g){
g.setColor(Color.WHITE);
g.fillRect(x,y,w,h);
}
public int getX(){
return this.x;
}
public int getY(){
return this.y;
}
public int getW(){
return this.w;
}
public int getH(){
return this.h;
}
}
I am sorry if this is too much code, but if only send the AI class, you can not see where the problem is I guess. Please help me I do not know why it is not working. Sorry for my bad English.
Your Computer class creates a differrent ball (ballpos) that is never updated and therefore the AI never moves. You need to pass your Ball object from the GamePanel class to the Computers update method:
Computer:
public void update(Ball ball){
if(ball.getY() < this.y){
yv = -1;
}
else if(ball.getY() > this.y){
yv = 1;
}
y = y + yv;
}
GamePanel:
private void update(){
player.update();
ball.update();
ball.Collision(player);
computer.update(ball);
ball.Collision(computer);
}

Java awt Why can I only remove most recent addition to Linked List

I'm creating a space shooter game in Java awt for my college computer science project.
The enemies that I have spawn every 3 seconds via a timer and are added to a LinkedList, and a for loop renders them all.
In the class I have for my player's bullet object, there are if statements to check whether the laser comes into the bounds of an enemy, and if they are all true it removes the enemy from the LinkedList.
However, only the most recent addition to the LinkedList is being removed; the bullet passes through the others and nothing happens. This is my first time making a game, and the first time I've ever used a LinkedList, so excuse any misunderstandings.
The controller class controls the enemies, the Laser class is the bullet and the Enemy class is the Enemy object. There's also a player, Main and GUI class.
import java.awt.*;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;
public class Controller
{
private LinkedList<Enemy> e = new LinkedList<Enemy>();
Enemy tempEnemy, tempEnemy2
;
Main main;
int refreshSpawn = 3000; //move timer refresh rate
int xpos;
int width;
int ypos;
int height;
Timer spawnTimer = new Timer();
public Controller(Main main)
{
this.main = main;
spawn();
}
public void spawn()
{
spawnTimer.schedule(new TimerTask()
{
public void run() //run method and timer
{
addEnemy(new Enemy(main, (int)(Math.random()*4+2)));
}
}, 0, refreshSpawn);
}
public void render(Graphics g)
{
for(int i = 0; i < e.size(); i++)
{
tempEnemy = e.get(i);
xpos = tempEnemy.getX();
width = tempEnemy.getXsize();
ypos = tempEnemy.getY();
height = tempEnemy.getYsize();
tempEnemy.render(g);
}
}
public void update()
{
for(int i = 0; i < e.size(); i++)
{
tempEnemy2 = e.get(i);
tempEnemy2.move();
}
}
public void addEnemy(Enemy enemy)
{
e.add(enemy);
System.out.println(e.size());
//spawn();
}
public void removeEnemy()
{
e.remove(tempEnemy);
}
public int getX()
{
return xpos;
}
public int getY()
{
return ypos;
}
public int getXsize()
{
return width;
}
public int getYsize()
{
return height;
}
public Enemy getEnemy()
{
return tempEnemy;
}
}
import java.awt.*;
public class Enemy
{
Image ship; //image of enemy ship
int x, y; //ship position
int speed;
public Enemy(Main main, int speed) //constructing enemy
{
this.speed = speed;
ship = main.getImage(main.getDocumentBase(), "enemyShip"+(int)(Math.random()*6+1)+".png"); //picture for enemy ship
x = (int)(Math.random()*900+1); //enemy has a starting position at a random x point
y = -100; //start ship slightly off screen so it doesn't suddenly appear
}
public void move()
{
y += speed;
if(y > 600)
{
y = -100;
x = (int)(Math.random()*900);
}
}
public void render(Graphics g)
{
g.drawImage(ship, x, y, null);
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public int getXsize()
{
return ship.getWidth(null);
}
public int getYsize()
{
return ship.getHeight(null);
}
}
import java.awt.*;
public class Laser
{
Image img; //image of laser
int laserSpeed = 10; //speed of laser
int x, y; //position of laser
int xSize, ySize; //size of laser
Controller cont;
GUI gui;
public Laser(Image img, int x, int y, Controller cont, GUI gui) //constructing laser
{
this.cont = cont;
this.img = img; //setting laser image
this.gui = gui;
xSize = x; //size of laser
ySize = y; //size of laser
}
public void shoot(int x, int y, int shipSize)
{
this.x = x + (shipSize/2) - (xSize/2);
this.y = y;
}
public void move()
{
y -= laserSpeed;
if(x <= cont.getX() + cont.getXsize() && x + xSize >= cont.getX() - cont.getXsize())
{
if(y <= cont.getY() + cont.getYsize() && y > 0)
{
remove();
cont.removeEnemy();
gui.scoreUp(5);
}
}
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public int getXSize()
{
return xSize;
}
public int getYSize()
{
return ySize;
}
public Image getImage()
{
return img;
}
public void remove()
{
y = -ySize;
x = -100;
}
}
From what I can tell, tempEnemy is assigned to the last element in the LinkedList by the render method. This means that when you call removeEnemy it is removing the last rendered object (likely the last object you added).
What you should be doing is telling the Controller which Enemy it should be using, it has absolutely no idea what your intentions are when you call it...

Categories

Resources