# Bewegte Zeichnungen anklicken



## TheChemist (24. Mai 2008)

Hallo

ich habe angefangen, mich mit Spieleprogrammierung in Java zu befassen und auch gleich mein erstes Spiel programmiert. Zuvor hab ich das Tutorial von Quaxli durchgearbeitet.

Nun aber zu meinem Problem. In meinem Spiel geht es darum bewegte Bälle abzuschissen. Die Bälle sind Zeichnungen.
Immoment mache ich es, dass ich bei jedem Mauklick eine Methode aufrufe, die die Länge des Verbindungsvektors zwischen Mausklick und Mittelpunkt des Balles berechnet. Ist die Länge kleiner als der Radius, gilt der Ball als getroffen. In der Theorie hört sich das zwar relativ sicher an, aber im Spiel selbst stellst es sich als extrem ungenau heraus  :? 

Meine Frage ist jetzt: Gibt es eine andere Möglichkeit zur Überprüfung? Ich habe schon ein bisschen drüber nachgedacht, aber mir kamen bisher noch keine Ansätze.

Ich hoffe das Problem is klar, Code kann ich bei Bedarf anhängen 

~Max


----------



## Illuvatar (24. Mai 2008)

Das ist nicht nur relativ sicher, das ist sogar theoretisch 100% sicher. Zeig mal deinen Code wo du das überprüfst


----------



## TheChemist (24. Mai 2008)

Also einmal die Überprüfung im Game Panel


```
public void mouseClicked(MouseEvent e)
    {
        if(!paused) {   
            for(Sprite b: actors) {
                b.checkHit(e.getX(), e.getY());
            }
        } else {
            setPaused(false);
            doInitalizations();
        }
    }
```

Damit wird im Ball folgende Methode aufgerufen:

```
public void checkHit(int xMaus, int yMaus)
    {
        //Verbindungvektor zwischen Maus und Ball
        double xV = xMaus - x;
        double yV = yMaus - y;
        //Laenge des Vektors
        double distance = Math.sqrt((xV * xV) + (yV * yV));
        
        if(distance < radius) {
            hit();
        } 
    }
```

Im Spiel passiert wenn ich auf den Ball selbst klicke meist garnix.
Wenn ich irgendwo in die Umgebung klicke klappt es meistens. Ich vermute das hängt mit der Geschwindigkeit des Balles  zusammen, aber ich wei nicht so recht wie ich die mit einbeziehen soll


----------



## André Uhres (24. Mai 2008)

Während der Spieler klickt, bewegt sich der Ball ja weiter.
Imho muss der Spieler das berücksichtigen und immer ein wenig davor klicken.
Das gilt wohl um so mehr, je schneller der Ball ist.


----------



## TheChemist (24. Mai 2008)

Ja das hab ich auch schon gedacht, aber es passiert auch mal, dass ich den Ball treffe obwohl ich hinten dran klicke, bzw eben nicht in seine Flugbahn


----------



## pyr0t0n (25. Mai 2008)

theoretisch

sqrt(((mouse_x - ballx)*(mouse_x - ball_x)) + ((mouse_y - ball_y)*(mouse_y - ball_y))) < Radius

dann getroffen ^^

also wenn du bei jedem klick eine Liste mit allen fliegenden bällen durchgehst und den abstand vergleichst sollte das gehen.

So funktionierts bei mir auf jedenfall


----------



## Quaxli (25. Mai 2008)

TheChemist hat gesagt.:
			
		

> ```
> public void mouseClicked(MouseEvent e)
> {
> if(!paused) {
> ...




Du loopst bei jedem Klick über alle Sprites, daß finde ich prinzipiell nicht schön. Probier doch mal Folgendes:

- definiere eine Instanzvariable vom Typ Point oder Point2D - nennen wir sie mal click 
- in mouseClicked instanziierst Du sie dann (click = new Point(...))
- wenn Du wie in meinem Tutorial z. B. in der doLogic-Methode sowieso über alle Sprites loopst, prüfst Du:
-- ob der Punkt ungleich null ist und mit einem der Sprites kollidiert
-- wenn das der Fall ist , führst Du die notwendigen Aktionen aus und setzt click anschließend wieder auf null

Damit sparst Du Dir einen Loop und kannst sicher sein, daß die Objekte nicht bewegt werden, während Du in mouseClicked die Aktionen ausführst.


----------



## TheChemist (26. Mai 2008)

Danke, das werd ich mal probieren


----------

