1

So i have these 2 ArrayLists one for balls and the other for enemies. I want when the x and y coords of a ball are equal to the x and y coords of an enemy they both to be removed. Here is the code:

Main:

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Main extends JPanel implements ActionListener, KeyListener{
Timer t = new Timer(5,this);
public JFrame f;
public Paint p;
public Ball ball;
public Enemy enemy;
public static Main main;
private boolean s1 = false, s2 = false, s3 = false;

public Main (){
    f = new JFrame();
    f.setSize(500,500);
    f.setBackground(new Color(32768));
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.add(p = new Paint());
    f.addKeyListener(this);
    f.setResizable(false);
    t.start();

}
public void actionPerformed(ActionEvent arg0) {
    p.color++;
    p.c++;
    p.move();
    p.repaint();
}

public void keyPressed(KeyEvent arg0) {
    if (arg0.getKeyCode() == KeyEvent.VK_A)
    {
        p.velx = -1;
        s1 = true;
    }
    if (arg0.getKeyCode() == KeyEvent.VK_D)
    {
        p.velx = 1;
        s2 = true;
    }
    if (arg0.getKeyCode() == KeyEvent.VK_SPACE){
        p.al.add(new Ball(p.x +30,p.y2));
        s3 = true;
    }
    if(s1==true && s3==true)
    {
        p.velx = -1;
        p.al.add(new Ball(p.x +30,p.y2));
    }
    if(s2==true && s3==true)
    {
        p.velx = 1;
        p.al.add(new Ball(p.x +30,p.y2));
    }
    if (s3 == true){
        p.al.add(new Ball(p.x +30,p.y2));
    }
}

public void keyReleased(KeyEvent arg0) {
        if (arg0.getKeyCode() == KeyEvent.VK_A)
        {
            p.velx = 0;
            s1 = false;
        }
        if (arg0.getKeyCode() == KeyEvent.VK_D)
        {
            p.velx = 0;
            s2 = false;
        }
        if (arg0.getKeyCode() == KeyEvent.VK_SPACE){
            s3 = false;
        }
}

public void keyTyped(KeyEvent arg0) {

}

public static void main(String[] args){
    main = new Main();
}
}

Paint:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;

import javax.swing.JPanel;
import javax.swing.Timer;
public class Paint extends JPanel implements ActionListener{
Timer t = new Timer(5,this);
public int x = 250, y = 450, velx = 0, color = 1,vely = -1,y2 = y, c = 32768, velz = 1;
public ArrayList<Ball> al = new ArrayList<Ball>();
public ArrayList<Enemy> al2 = new ArrayList<Enemy>();
Random rx = new Random();
Random ry = new Random();
public Enemy enemy;
public Ball ball;

public Paint(){
    createEnemys();
}

ActionListener taskPerformer = new ActionListener(){
    public void actionPerformed(ActionEvent arg0) {
        Iterator<Enemy> it = al2.iterator();
        while (it.hasNext()) {
            Enemy enemy = it.next();
            if (enemy.x == 520)
            {
                enemy.x = -120;
            }
            enemy.x +=1;
            repaint();
        }
    }
};
Timer t2 = new Timer(5,taskPerformer);

public void actionPerformed(ActionEvent arg0) {
    Iterator<Ball> it = al.iterator();
    while (it.hasNext()) {
        Ball ball = it.next();
        if (ball.y < -10) {
            it.remove();
            System.out.println(enemy.getX());
        } else {
            ball.y += vely;
            repaint();
        }
    }
}

public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.setColor(Color.gray);
    g.fillRect(0, 0, 500, 500);
    for(Ball ball : this.al) {
        g.setColor(Color.RED);
        g.fillOval(ball.x,ball.y,10,10);
        t.start();
    }
    for(Enemy enemy : this.al2) {
        g.setColor(new Color(c));
        g.fillRect(enemy.x,enemy.y,enemy.h,enemy.w);
        t2.start();
    }
    g.setColor(new Color(color));
    g.fillRect(x, y, 70, 10);
}



public void move(){
    x += velx;
    if (x <= 3)
    {
        x = 3;
    }
    if (x >= 420)
    {
        x = 420;
    }
}

public void createEnemys(){
    al2.add(new Enemy(-60,10,60,10));
    al2.add(new Enemy(20,10,60,10));
    al2.add(new Enemy(100,10,60,10));
    al2.add(new Enemy(180,10,60,10));
    al2.add(new Enemy(260,10,60,10));
    al2.add(new Enemy(340,10,60,10));
    al2.add(new Enemy(420,10,60,10));
    al2.add(new Enemy(500,10,60,10));

    al2.add(new Enemy(-60,30,60,10));
    al2.add(new Enemy(20,30,60,10));
    al2.add(new Enemy(100,30,60,10));
    al2.add(new Enemy(180,30,60,10));
    al2.add(new Enemy(260,30,60,10));
    al2.add(new Enemy(340,30,60,10));
    al2.add(new Enemy(420,30,60,10));
    al2.add(new Enemy(500,30,60,10));

    al2.add(new Enemy(-60,50,60,10));
    al2.add(new Enemy(20,50,60,10));
    al2.add(new Enemy(100,50,60,10));
    al2.add(new Enemy(180,50,60,10));
    al2.add(new Enemy(260,50,60,10));
    al2.add(new Enemy(340,50,60,10));
    al2.add(new Enemy(420,50,60,10));
    al2.add(new Enemy(500,50,60,10));

    al2.add(new Enemy(-60,70,60,10));
    al2.add(new Enemy(20,70,60,10));
    al2.add(new Enemy(100,70,60,10));
    al2.add(new Enemy(180,70,60,10));
    al2.add(new Enemy(260,70,60,10));
    al2.add(new Enemy(340,70,60,10));
    al2.add(new Enemy(420,70,60,10));
    al2.add(new Enemy(500,70,60,10));
}

}

Ball:

import javax.swing.JPanel;

public class Ball extends JPanel{
public int x,y;
public Ball(int x1, int y1) {
    x = x1;
    y = y1;
}
}

And finally Enemy:

import javax.swing.JPanel;

public class Enemy extends JPanel{
public int x,y,h,w;
public Enemy(int x, int y,int h,int w) {
    this.x = x;
    this.y = y;
    this.h = h;
    this.w = w;
}
public int getX() {
    return x;
}
public int getY() {
    return y;
}
}

The problem is in Class Paint where i can't check the collision of a ball and an enemy so they can be removed. If anyone can help me thanks

Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122

1 Answers1

1

Assuming that you use Java 8, it can be done using the Stream API and the method removeAll(Collection) to remove all matching elements with this:

al.removeAll(
    al.stream().filter(
        ball -> {
            List<Enemy> enemies = al2.stream()
                .filter(enemy -> ball.x == enemy.x && ball.y == enemy.y)
                .collect(Collectors.toList());
            al2.removeAll(enemies);
            return !enemies.isEmpty();
        }
    ).collect(Collectors.toList())
);

Otherwise, you can still use the old approach with 2 loops that iterate over an Iterator to be able to remove the current element thanks to the method remove()

main: for (Iterator<Ball> itBall = al.iterator(); itBall.hasNext();) {
    Ball ball = itBall.next();
    for (Iterator<Enemy> itEnemy = al2.iterator(); itEnemy.hasNext();) {
        Enemy enemy = itEnemy.next();
        if (ball.x == enemy.x && ball.y == enemy.y) {
            itBall.remove();
            itEnemy.remove();
            continue main;
        }
    }
}
Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
  • I dont know if i put it in the right place but in the class Paint i made an second timer, so i put these 2 codes in there but only sometimes they dissapear (i have tested the codes separately too). I dont know if its my fault but for me this dont work either way. – Kristiqn Georgiev Sep 25 '16 at 15:20
  • Probably because what you ask in your question description is not what you need. I mean you say "I want when the x and y coords of a ball are equal to the x and y coords of an enemy they both to be removed", if it is your algorithm to detect a collision it is really weak, since you have a round balls and rectangle enemies so to get a collision the center of a ball must match exactly with the top left corner of your enemy which is quite rare that's why it doesn't work. The algo is simply incorrect, you need a more accurate algo allowing to detect a collision between a round and a rectangle – Nicolas Filotto Sep 25 '16 at 17:28
  • what if i turn the balls into rectangles? – Kristiqn Georgiev Sep 25 '16 at 17:35
  • well generally speaking, for performance reason it is how it is done in practice, even if the object is a round, the area used to detect a collision is a square of 2*radius side long. But still you need to check if those shapes intersect with each other and this can be done only with tests based on inequality not equality. This should help http://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection – Nicolas Filotto Sep 25 '16 at 17:45
  • You can simply use Rectangle#intersects(Rectangle r) https://docs.oracle.com/javase/8/docs/api/java/awt/Rectangle.html#intersects-java.awt.Rectangle- instead of the test ball.x == enemy.x && ball.y == enemy.y – Nicolas Filotto Sep 25 '16 at 17:51
  • please also note that you don't cover intersection between balls or between enemies – Nicolas Filotto Sep 25 '16 at 17:52
  • Thanks a lot for the help man!! I coudnt have done it without you ! – Kristiqn Georgiev Sep 26 '16 at 12:53