Hey Leute
ich wollte endlich auch mal den Anfang starten, und mich bisschen mit Zeichnen in Java befassen, und da war mir der Thread pixelgenaue Kollisionsabfrage der Kreise ziemlich gelegen, weil ich das Spiel ganz lustig finde.
Ich würd mich freuen, wenn ihr zunächst mal den Code querlesen würdet, und mir evtl. Stellen nennt, an den ich an die ganze Sache falsch rangehe. Damit meine ich z.B. grundlegende Designfehler u.ä. Wie gesagt, das ist das erste Mal, dass ich mich in einer Programmiersprache mit Zeichnen beschäftige - finde es aber ziemlich interessant.
Tja, scheinbar hab ich irgendwo auch einen logischen Fehler. Das ganze ist ein (großes)KSKB startet es doch einmal und wartet einen Augenblick, dann merkt ihr, wo mein Problem ist - es wird eine Kollision entdeckt, obwohl sich um den jeweiligen Ball herum kein anderer befindet.
Ich freue mich über Hilfe
Hier der Code (nicht erschrecken, es sieht nach mehr aus, als es wirklich ist):
ich wollte endlich auch mal den Anfang starten, und mich bisschen mit Zeichnen in Java befassen, und da war mir der Thread pixelgenaue Kollisionsabfrage der Kreise ziemlich gelegen, weil ich das Spiel ganz lustig finde.
Ich würd mich freuen, wenn ihr zunächst mal den Code querlesen würdet, und mir evtl. Stellen nennt, an den ich an die ganze Sache falsch rangehe. Damit meine ich z.B. grundlegende Designfehler u.ä. Wie gesagt, das ist das erste Mal, dass ich mich in einer Programmiersprache mit Zeichnen beschäftige - finde es aber ziemlich interessant.
Tja, scheinbar hab ich irgendwo auch einen logischen Fehler. Das ganze ist ein (großes)KSKB startet es doch einmal und wartet einen Augenblick, dann merkt ihr, wo mein Problem ist - es wird eine Kollision entdeckt, obwohl sich um den jeweiligen Ball herum kein anderer befindet.
Ich freue mich über Hilfe
Hier der Code (nicht erschrecken, es sieht nach mehr aus, als es wirklich ist):
Code:
package de.mcs.test.graphics;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class Balls extends JComponent implements Runnable {
private static final long serialVersionUID = 3224830373101405104L;
private int width;
private int height;
private List<Ball> balls;
private int ballsAmount = 10;
private boolean clicked;
private int explodingSize = 40;
public Balls(int width, int height) {
super();
setPreferredSize(new Dimension(width, height));
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
if(!clicked)
{
Ball clickedBall = new Ball(0, new Point(0,0), new Point(e.getX(), e.getY()), Color.WHITE);
clickedBall.setExploding(true);
balls.add(clickedBall);
clicked = true;
}
}
});
this.width = width;
this.height = height;
initBalls(ballsAmount, 8);
startAnimation();
}
private void initBalls(int amount, int radius)
{
this.balls = new ArrayList<Ball>();
Random rand = new Random();
for(int i = 0; i < amount; i++)
{
this.balls.add( new Ball(radius,
new Point(rand.nextInt(1)+1, rand.nextInt(1)+1),
new Point(rand.nextInt(width-radius*2), rand.nextInt(height-radius*2)),
new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)))
);
}
}
private void startAnimation() {
new Thread(this).start();
}
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
repaint();
for(Ball ball : balls)
{
ball.move();
ball.checkExploding();
if(ball.isExploding())
{
for(int i = 0; i < balls.size(); i++)
{
Ball tmp = balls.get(i);
if(ball == tmp)
continue;
if(ball.checkCollision(tmp))
tmp.setExploding(true);
}
}
}
Thread.sleep(20);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(new Color(0, 51, 51));
g2d.fillRect(0, 0, width, height);
for(Ball ball : balls)
ball.paint(g2d);
}
class Ball {
private int radius;
private Point speed;
private Point position;
private Color color;
private boolean exploding;
private int explodingCounter;
public boolean isExploding() {
return exploding;
}
public void setExploding(boolean exploding) {
this.exploding = exploding;
if(exploding)
{
this.speed.x = 0;
this.speed.y = 0;
}
}
public Ball(int radius, Point speed, Point position, Color color) {
this.radius = radius;
this.speed = speed;
this.position = position;
this.color = color;
}
public void move() {
if (position.x < 0 || (position.x + radius * 2) > width)
speed.x = -speed.x;
if (position.y < 0 || (position.y + radius * 2) > height)
speed.y = -speed.y;
position.x += speed.x;
position.y += speed.y;
}
public void checkExploding()
{
if(!exploding)
return;
if(explodingCounter++ < 100)
{
if(radius < explodingSize)
radius++;
}
else if(radius-- >= 1);
}
public boolean checkCollision(Ball ball)
{
double dx = Math.abs((position.x - radius/2) - (ball.position.x - ball.radius/2));
double dy = Math.abs((position.y - radius/2) - (ball.position.y - ball.radius/2));
double d = radius + ball.radius;
return d*d >= dx*dx+dy*dy;
}
public void paint(Graphics2D g2d) {
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
g2d.setComposite(ac);
g2d.setColor(color);
g2d.fillOval(position.x-(exploding ? radius/2 : 0), position.y-(exploding ? radius/2 : 0), radius * 2, radius * 2);
}
public void setRadius(int radius) {
this.radius = radius;
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Balls");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Balls(500, 350));
frame.pack();
frame.setVisible(true);
}
}