grafik in bereiche einteilen (dartboard)

teddydeluxe

Mitglied
hallo,

ich möchte eine grafik (dartboard) in einzelne abschnitte unterteilen, auf die man klicken kann. wenn auf den jeweiligen abschnitt mit den punkten geklickt wird, soll diese punktzahl abgezogen werden.
also ein kleines programm, dass das punkte runterzählen erleichtert bei einem nicht-elektronischen dartboard.
ich weiss nur nicht wie ich es mit der grafik angehen soll, dass bestimmte bereiche zu verschiedenen listenerern gehören oder ob das überhaupt möglich ist. ich wollte es mit java swing machen.

wie könnte ich das realisieren ?

vielen dank
 
Zuletzt bearbeitet von einem Moderator:
S

SlaterB

Gast
es gibt grundsätzlich zwei Varianten:
a)
den Bildschirm mit verschiedenen GUI-Komponenten, etwa bemalten JPanel/JLabel nebeneinander befüllen
( a2) in diesem Fall vielleicht auch eine JTable mit von Haus aus Gitter-Struktur a la Excel)
darauf dann ein bis viele Listener, den Komponenten zugeordet bzw. die Zelle einer JTable feststellbar

b)
nur eine gesamte Zeichenfläche, nur einen Listener darauf, von der genauen Pixelpositon eines Mausklicks exakt zurückrechnen,
welcher Bereich gemeint war, das Zeichnen muss dazu natürlich auch pixelgenau passen
 

Marco13

Top Contributor
Wenn die einzelnen Felder des Dartboards als Shapes gespeichert sind, kann man sie erstens schön Zeichnen (auch beliebig skaliert) und zweitens mit shape.contains(mousePos) testen, ob es getroffen wurde.
 

teddydeluxe

Mitglied
vieln dank euch beiden. ich hab mir gedanken darüber gemacht einfach ein bild zu nehmen und die klickposition zurück zu rechnen und damit zu bestimmen auf welches feld geklickt wurde, aber das scheint mir bei diesen "pizzastück" artigen formen recht viel aufwand, wenn man es genau haben will.

ich werde erstmal schauen, dass ich die pizzastücke mit shapes forme und dann weiter schauen.

dankeschön erstmal
 
S

SlaterB

Gast
ach so, Pizza Dartboard, dann fällt die JTable ja aus,

hilfreich ist hier noch, zum Mittelpunkt den Radius und Winkel als Kreis betrachtet zu errechnen,
so kommst du noch mit überschaubaren Aufwand zum Ziel,
Liste aller Felder 20, 1, 18, 4 usw.
automatisch aufgeteilt Winkel 18 Grad, 36 Grad, 54 Grad usw., je nach Radius 2x, 1x, 3x usw.
mit paar Schleifen kommt man dabei recht weit

auf diese Weise kannst du natürlich auch Punkte für Shapes ausrechnen, das ist dann Jacke wie Hose,
Kreisbahn evtl. schwierig bei Shapes, aber muss ja nicht sein nur fürs Klicken, dann auch nicht zwingend besonders kleine Trefffelder,
mit den Radien spielen,

wenn erstmal das Modell/ die Berechnungen stehen, dann wird bei Anpassungen automatisch richtig neu gemalt und gleichzeitig richtig zurückgerechnet, schöne Sache,
besser als nur einmalig Shapes mit bestimmten manuell gesetzen Pixelpositionen

das Thema gabs auch schon ein paar Mal im Forum, richtige Lösung ist aber glaube ich nicht dabei,
'dart board java' in Suchmaschinen liefert auch Ergebnisse, aber zu durchsuchen
 
Zuletzt bearbeitet von einem Moderator:

Marco13

Top Contributor
Um das getroffene Feld wirklich auszurechnen braucht's auch nicht so viel. Man kann aus der Positon der Maus und dem Mittelpunkt des Malbereichs alles ausrechnen, was man braucht: den Winkel und den Abstand zum Mittelpunkt. Aus dem Winkel bekommt man raus, welches der 20 Pizzastücke getroffen wurde. Aus dem Abstand bekommt man den "Ring". Allerdings muss diese Information (speziell die Radien der Ringe) dann irgendwo gespeichert werden, und ggf. ein
int segmentIndexToNumber[] = { 20, 1, 18 ... }

Aber für die Shapes kannst du mal in http://www.java-forum.org/awt-swing-swt/108611-roulettescheibe-zeichnen.html schauen. Das ist im Prinzip das gleiche :D
 

teddydeluxe

Mitglied
ok, ich bin mal wieder dazu gekommen, daran weiter zu arbeiten. das zeichnen der 20 kreisabschnitte hab ich jetzt ohne shapes gelöst.

Code:
 boolean color = true;
        for (int i = 0; i < 20; i++) {

            if (color) {
                g.setColor(Color.red);
                color = false;
            } 
            else {
                g.setColor(Color.blue);
                color = true;
            }
            int angle = i * 18;
            g.fillArc(0, 0, 600, 600, angle, 18);
        }
    }

aber ich hab schwierigkeiten mit der mathematischen funktion, um die koordinaten jedes einzelnen feldes zu begrenzen, um das klicken darauf abzufangen.
ich habe den mittelpunkt, den radius des gesamten kreises und den winkel des feldes. wie kann ich daraus die grenzen eines feldes berechnen, um sie mit der mausposition zu vergelchen ?
 

Marco13

Top Contributor
Java:
Point mousePos = ...
Point center = ...
int dx = mousePos.x-center.x;
int dy = mousePos.y-center.y;
double angle = Math.atan2(dy, dx);
double distance = mousePos.distance(center);
sollte reichen.
 
S

SlaterB

Gast
wie schon gesagt wurde, den Winkel musst du ausrechnen, aus der x/y-Abweichung ergibt sich mit sin/cos und rechtwinkligen Dreieck ein Winkel,
evt. für die 4 Sektoren unterscheiden
Sinus und Kosinus ? Wikipedia

der Abstand zum Mittelpunkt ist hoffentlich nicht zu erklären,

je nachdem ob dann der Abstand > ist als Grenze x und je nach einer der 20 Kategorien die sich aus dem Winkel ergeben weißt du welches Feld es ist,

genauer möchte ich persönlich es vorerst nicht erklären, wäre ja Musterlösung


fang doch mal mit einem MouseListener und Berechnung des Abstands zum Mittelpunkt an,
schon 3 schnelle Klicks und Ausgaben
"Abstand 4.7"
"Abstand 3.3"
"Abstand 0.1"
wären ein Stück des Weges

(edit: ok, Berechnungen sind etwas weiter nun, wobei auch noch auf 4 Sektoren zu achten,
aber auch erst Hälfte des Wegs zum Feld)
 
Zuletzt bearbeitet von einem Moderator:

teddydeluxe

Mitglied
danke euch beiden, den listener habe ich schon, ich muss noch daraus auf das feld schliessen können. ich bastel erstmal weiter mit den informationen :) ich melde mich bestimmt nochmal wieder
 

teddydeluxe

Mitglied
so nochmal vielen dank, das hat hat super geklappt. ich bräuchte bitte noch ein wenig hilfe beim zeichnen der zahlen auf der scheibe. die zahlen sind noch nicht richtig angeordnet (siehe bild) und wahrscheinlich liegt es an meiner formel oder an der abweichung beim casten in int.

Code:
final int[] score = new int[]{6,13,4,18,1,20,5,12,9,14,11,8,16,7,19,3,17,2,15,10};  
 int middleX = 350;
        int middleY = 350;
        double pi = 3.141592654;
        int radius = 210;
        double angle = (5 * pi / 180);
        double radiant = 18 * pi / 180;
        
        
        for (int i = 0; i < score.length; i++) {
            String s = String.valueOf(score[i]);

            g.drawString(s,
                    (int) (middleX + (Math.cos(angle) * radius)),
                    (int) (middleY - (Math.sin(angle) * radius))); 
            angle += radiant;
        }
 

Anhänge

  • dartboard.png
    dartboard.png
    72,8 KB · Aufrufe: 43
S

SlaterB

Gast
ungewöhnliche Abweichungen, aber mag so sein,
fange besser mit dem Malen eines Punktes an, z.B. genau in der Mitte jeden Bereiches mit gebührenden Radius,

danach male die Zahl genau an diesem Punkt, schau dir an wie sie sich dazu verschiebt,
baue gegebenenfalls kleine Korrekturen ein, standardmäßig etwas links + höher,
vielleicht bei extremen Positionen noch stärker abweichend

wenn du noch den Code für das restliche Malen postest können andere eher auch testen
 

teddydeluxe

Mitglied
danke, das versuche ich später. hier ist der code für das zeichnen :

Java:
import java.applet.Applet;
import java.awt.*;
import javax.swing.JFrame;


public class DartBoard extends Applet {

    Point center = new Point(350, 350);
    Point mousePos;
    final int[] score = new int[]{6, 13, 4, 18, 1, 20, 5, 12, 9, 14, 11, 8, 16, 7, 19, 3, 17, 2, 15, 10};


    @Override
    public void paint(Graphics gr) {

        Graphics2D g = (Graphics2D) gr;
        g.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        Color beige = new Color(255, 211, 155);
        Color forestGreen = new Color(34, 139, 34);
        boolean color = true;

        // triple
        for (int i = 0; i < 20; i++) {
            int w = (i * 18) + 9;
            if (color) {
                g.setColor(forestGreen);
                color = false;
            } else {
                g.setColor(Color.red);
                color = true;
            }
            g.fillArc(50, 50, 600, 600, w, 18);
        }

        // double
        for (int i = 0; i < 20; i++) {
            int w = (i * 18) + 9;
            if (color) {
                g.setColor(beige);
                color = false;
            } else {
                g.setColor(Color.black);
                color = true;
            }
            g.fillArc(75, 75, 550, 550, w, 18);
        }

        // single
        for (int i = 0; i < 20; i++) {
            int w = (i * 18) + 9;
            g.setColor(Color.black);

            if (color) {
                g.setColor(Color.black);
                color = false;
            } else {
                g.setColor(beige);
                color = true;
            }
            g.fillArc(100, 100, 500, 500, w, 18);
        }

        // bull
        g.setColor(forestGreen);
        g.fillOval(319, 319, 60, 60);

        // bullseye
        g.setColor(Color.red);
        g.fillOval(337, 337, 25, 25);

        // zahlen
        int fontSize = (int) (22);
        Font font = new Font("Serif", Font.BOLD, fontSize);
        g.setFont(font);
        g.setColor(Color.WHITE);


        int middleX = 350;
        int middleY = 350;
        double pi = 3.141592654;
        int radius = 210;
        double angle = (5 * pi / 180);
        double radiant = 18 * pi / 180;

        for (int i = 0; i < score.length; i++) {
            String s = String.valueOf(score[i]);

            g.drawString(s,
                    (int) (middleX + (Math.cos(angle) * radius)),
                    (int) (middleY - (Math.sin(angle) * radius)));
            angle += radiant;
        }
    }

    public static void main(String[] args) {

        JFrame f = new JFrame("DartBoard");
        f.setSize(768, 768);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new DartBoard(), BorderLayout.CENTER);
        f.setVisible(true);
    }
}
 

Marco13

Top Contributor
Beachte dass der "Nullpunkt" eines Strings unten links liegt. Vermutlich wäre die sauberste Lösung, auch die Größe des Strings (20 vs. 1) mit einzubeziehen. Im verlinkten Roulettescheiben-Thread werden auch die Zahlen gemalt (und sogar richtig gedreht ;) )
 

teddydeluxe

Mitglied
das war das problem, die unterschiedlichen grössen der strings und, dass es nicht der mittelpunkt der zahl war. mit etwas schieben siehts gut aus. dankeschön

Java:
        int middleX = 350;
        int middleY = 340;
        double pi = 3.141592654;
        int radius = 210;
        //double angle = (2 * pi / 180);
        double angle = 0.00;
        double radiant = 18 * pi / 180;
        
        FontMetrics fontMetrics = g.getFontMetrics();
        int fontHeight = fontMetrics.getHeight();
        
               
        for (int i = 0; i < score.length; i++) {
            String s = String.valueOf(score[i]);
            
            int delta = fontMetrics.stringWidth(s)/2;

            g.drawString(s,
                    (int) (middleX + (Math.cos(angle) * radius) - delta),
                    (int) (middleY - (Math.sin(angle) * radius)) + fontHeight - fontMetrics.getDescent()); 
            angle += radiant;
        }
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Feste Blöcke mit Grafik Spiele- und Multimedia-Programmierung 9
Anfänger2011 Wichtig: Grafik und Sprites erstellen Spiele- und Multimedia-Programmierung 1
T LWJGL Grafik meines Projektes läuft nicht korrekt auf meinem iMac Spiele- und Multimedia-Programmierung 19
S Wolken Bild/Grafik vom Programm erstellen lassen Spiele- und Multimedia-Programmierung 11
Luk10 Tipps für bessere Animationen / Grafik Engine Spiele- und Multimedia-Programmierung 2
M Einen Hobby Game - / Grafik Designer zu finden (Screenshot vom Spiel) Spiele- und Multimedia-Programmierung 7
D einfache 2D Grafik in JAVA. absoluter Anfänger Spiele- und Multimedia-Programmierung 5
R 2D Grafik JOGL Spiele- und Multimedia-Programmierung 18
Developer_X 3D Grafik Formeln Spiele- und Multimedia-Programmierung 35
S Grafik erstellen für Java Spiel Spiele- und Multimedia-Programmierung 8
Developer_X Java3D Grafik Boni Spiele- und Multimedia-Programmierung 8
H Grafik verschwindet durch Größenveränderung von GridBag Spiele- und Multimedia-Programmierung 5
N Felder auf Grafik Spiele- und Multimedia-Programmierung 2
R Grafik-Engine? MemoryImageSource? Spiele- und Multimedia-Programmierung 10
E Tester mit Intels Onboard-Grafik (o.ä.) gesucht! Spiele- und Multimedia-Programmierung 28
N Grafik als Hintergrund eines Rechtecks verwenden? Spiele- und Multimedia-Programmierung 4
G Entscheidungshilfe: Grafik-API Spiele- und Multimedia-Programmierung 5
T Spiel mit schöner Grafik, bitte testen Spiele- und Multimedia-Programmierung 10
V Wie bewege ich eine eingefügte Grafik (img) ? Spiele- und Multimedia-Programmierung 2
S Wie kann ich das Zeichnen der Grafik feiner machen? Spiele- und Multimedia-Programmierung 9
8u3631984 Kamera Stream Bereiche ausgrauen Spiele- und Multimedia-Programmierung 3

Ähnliche Java Themen

Neue Themen


Oben