Ich muss eine 2-ovale Kollision in einem java
swing
Minispiel berechnen.Oval Kollisionsverfahren nie aufgerufen - Java Swing
Ich habe eine JPanel
die zieht meine ArrayList
Bälle Thread
's und mein Spieler Ball. In der run()
Methode meiner Nichtspielerbälle überprüfe ich für eine Kollision zwischen dem Spielerball und den Bällen Thread
ArrayList
.
Das Problem ist, dass meine Kollisions-Methode nie ausgeführt wird. Es kommt nicht einmal zu meiner Kollision if
Aussage. Ruft die Methode nie an.
Ball.java:
public class Ball extends Thread
{
int x;
int y;
int velocity = 1;
public int radius = 20;
public boolean directionX = true; // True - right, false - left
public boolean directionY = false; // True - up, false - down
public static final int Y_STARTING_POSITION = 0;
public static final int X_STARTING_POSITION = 0;
public Ball()
{
switch (this.getStartingSide())
{
case 0: // Left
{
this.directionX = true;
this.directionY = true;
this.x = this.getRandomHeight();
this.y = this.getRandomWidth();
break;
}
case 1: // Right
{
this.directionX = false;
this.directionY = false;
this.x = this.getRandomHeight();
this.y = this.getRandomWidth();
break;
}
case 2: // Top
{
this.directionX = true;
this.directionY = false;
this.x = this.getRandomWidth();
this.y = this.getRandomHeight();
break;
}
case 3: // Bottom
{
this.directionX = false;
this.directionY = true;
this.x = this.getRandomWidth();
this.y = this.getRandomHeight();
break;
}
}
}
public int getX()
{
return this.x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return this.y;
}
public void setY(int y)
{
this.y = y;
}
public void move()
{
if (this.directionX) // Right
{
this.x += this.velocity;
}
else // Left
{
this.x -= this.velocity;
}
if (this.directionY) // Up
{
this.y -= this.velocity;
}
else // Down
{
this.y += this.velocity;
}
}
@Override
public void run()
{
try
{
this.isCollision(); // Never called
Thread.sleep(20);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
/**
* Get a random number varies from 0 to the screen width.
*
* @return The random number.
*
*/
public int getRandomWidth()
{
Random random = new Random();
return random.nextInt((Program.getPanelWidth() - 0) + 1) + 0; // Minimum = 0,maximum = Program.panelWidth
}
/**
* Get a random number varies from 0 to the screen height.
*
* @return The random number.
*
*/
public int getRandomHeight()
{
Random random = new Random();
return random.nextInt((Program.getPanelHeight() - 0) + 1) + 0; // Minimum = 0,maximum = Program.panelHeight
}
/**
* Get the starting side of a ball.
*
* Left - 0.
* Right - 1.
* Top - 2.
* Bottom - 3.
*
* @return
*
*/
public int getStartingSide()
{
Random random = new Random();
return random.nextInt((4 - 0) + 1) + 0; // Minimum = 0,maximum = 3
}
public void isCollision()
{
System.out.println("SSSSSSSSSSSSSSSS");
if (Math.sqrt(Math.pow(MyPanel.playerX + MyPanel.playerRadius - this.getX() + this.radius,2)
+ Math.pow(MyPanel.playerY + MyPanel.playerRadius - this.getY() + this.radius,2))
<= MyPanel.playerRadius + this.radius) // A collision
{
System.exit(0);
}
}
} // End of Ball class
MyPanel.java:
public class MyPanel extends JPanel implements KeyListener
{
private static final long serialVersionUID = 1L;
private static final Color BACKGROUND_COLOR = Color.WHITE;
private static final Color NPC_BALLS_COLOR = Color.RED;
// The player is an oval
public static int playerRadius = 35;
public static int playerX;
public static int playerY;
// True - first player position, false - otherwise
private boolean playerPosition = true;
// Array of all the balls threads
public static ArrayList<Ball> balls = new ArrayList<Ball>();
public MyPanel()
{
this.setBackground(MyPanel.BACKGROUND_COLOR);
this.setFocusable(true);
this.addKeyListener(this);
new Timer(10,new UpdateUI());
}
// Drawing
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
final double PANEL_WIDTH = this.getWidth();
final double PANEL_HEIGHT = this.getHeight();
if (this.playerPosition)
{
MyPanel.playerX = (int)(PANEL_WIDTH/2 - MyPanel.playerRadius);
MyPanel.playerY = (int)(PANEL_HEIGHT/2 - MyPanel.playerRadius);
this.playerPosition = false;
}
// Drawing the player
g.setColor(Color.BLACK);
g.fillOval(playerX,playerY, MyPanel.playerRadius * 2, MyPanel.playerRadius * 2);
// Drawing npc's balls
g.setColor(MyPanel.NPC_BALLS_COLOR);
for (Ball ball: MyPanel.balls) // ConcurrentModificationException
{
if (ball.isAlive())
{
ball.start();
}
ball.move();
repaint();
g.fillOval(ball.getX(), ball.getY(),
ball.radius * 2, ball.radius * 2);
}
}
// Keyboard listeners
@Override
public void keyPressed(KeyEvent e)
{
switch (e.getKeyCode())
{
case KeyEvent.VK_W: // Up
{
MyPanel.playerY -= 10;
repaint();
break;
}
case KeyEvent.VK_S: // Down
{
MyPanel.playerY += 10;
repaint();
break;
}
case KeyEvent.VK_D: // Right
{
MyPanel.playerX += 10;
repaint();
break;
}
case KeyEvent.VK_A: // Left
{
MyPanel.playerX -= 10;
repaint();
break;
}
}
}
@Override
public void keyReleased(KeyEvent e)
{
}
@Override
public void keyTyped(KeyEvent e)
{
}
public class UpdateUI implements ActionListener
{
@Override
public void actionPerformed(ActionEvent e)
{
repaint();
}
}
} // End of MyPanel class
Program.java:
public class Program
{
private static int panelWidth;
private static int panelHeight;
public static void main(String[] args)
{
MyFrame frame = new MyFrame();
Program.panelWidth = frame.getWidth();
Program.panelHeight = frame.getHeight();
// Generate a ball each 2 seconds
while (true)
{
try
{
MyPanel.balls.add(new Ball());
Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
} // End of main method
public static int getPanelWidth()
{
return Program.panelWidth;
}
public static int getPanelHeight()
{
return Program.panelHeight;
}
}
Der 012.ist nichts besonderes und fügt nur die JPanel
hinzu und so.
Also meine isCollision()
Methode wird nie aufgerufen, auch wenn es auf meiner run()
Methode meiner Thread
ist. Woher?
Welche 'Thread' sichere Datenstrukturen gibt es? Und wie synchronisiere ich eine 'ArrayList'? – God
Ich habe die Antwort aktualisiert. – Timmos