# Spielfeld erstellen



## TX (15. Nov 2009)

Hallo,

ich wollte eine Art Spieloberfläche programmieren.
Es geht, darum das ein Spielfeld erstellt wird. Dieses besteht aus vielen Sechsecken, die aneinander gepacket werden.
Ein paar Felder sind mit Spielsteinen belegt. Diese Spielsteine kann man anklicken und wenn ein anderes Spielfeld anklickt wird, liegt der Spielstein dort.


Hättet ihr Ansätze wie man das Sinnvoll aufbaut?


----------



## diggaa1984 (15. Nov 2009)

für jedes Substantiv ne Klasse bauen .. 2 Felder erzeugen, eins belegt das andere per Klick belegen .. wenn das geht, kannst dir was ausdenken bezüglich automatischer Layoutberechnung fürs Speilfeld und das ganze auf 100 Felder erhöhen


----------



## TX (15. Nov 2009)

Löst man das Erstellen des Spielfeldes eigentlich am besten mit dieser paint-methode?


----------



## diggaa1984 (16. Nov 2009)

naja du kannst auch, was ich persönlich in dem Fall weniger schön finde, pro Feld ein Label nutzen, und dem nen Bilder verpassen ^^ .. dann brauchst das nicht selbst in paintComponent regeln, aber das finde ich eher unpassend .. so hast du einerseits ne Liste von Feldobjekten, welche dein Spielfeld repräsentieren, und dazu ne Liste von Labels, welche nur als Wrapper dienen um es zu zeichnen.

Lieber selbst pinseln ^^


----------



## TX (16. Nov 2009)

Ok,
sollte man das irgendwie mit Schichten arbeiten(wenn das überhaupt geht), also untere Schicht Hintergrundbild, dann die einzelnen Spielfelder zeichnen lassen, darüber dann die Spielsteine und dann noch eine Schicht für den bewegenen Spielstein?


----------



## hdi (16. Nov 2009)

Die Schichten werden halt durch die Reihenfolge der Befehle in der paintComponent geregelt. Die n+1-te Malanweisung darin malt über dem, was die n-te Anweisung gemalt hat. Insofern musst du das dann schon berücksichtigen.


----------



## TX (17. Nov 2009)

Kann man das auch mit Tools machen wie Netbeans?


----------



## diggaa1984 (17. Nov 2009)

die komponente die ganz oben auf der form liegt wird als letztes gemalt .. so einfach ^^

oder wie hdi sagte die reihenfolge wie du was malst


```
maleWas() {
    maleHintergrund();
    maleFelder();
    maleSteine();
    maleIrgendwas();
}
```


----------



## TX (18. Nov 2009)

Ok , gut!

Wollte jetzt noch wissen ob ich diese ganzen Sechsecke oder Achtecke auch mit einen Tool zusammenklicken kann und dieses gibt mir die Koordinaten aus.
Ansonsten muss ich die alle selber festlegen...


----------



## hdi (18. Nov 2009)

Also wie ein Sechseck oder Achteck aussieht, das musst du selber implementieren. Aber wenn du dir sinnige Konstruktoren schreibst, hast du die Arbeit ja nur einmal. Ich würde jetzt zB kein Sechseck machen dessen Konstruktor 6 Punkte will, sondern zB nur den oberen linken, und den Rest errechnet er sich selber. Dann ist es recht easy neue Sechsecke zu erstellen.


----------



## Quaxli (18. Nov 2009)

TX hat gesagt.:


> Löst man das Erstellen des Spielfeldes eigentlich am besten mit dieser paint-methode?



Nein, nicht so ganz. Je nachdem was Du vorhast empfiehlt es sich das Spielfeld als eigene Klasse zu implementieren, welche die notwendig Logik kapselt. Dieser Klasse würde ich eine Methode (z. B. drawGameBoard(Graphics g) verpassen, die ein Graphics-Object übergeben bekommt und aus einer paint- bzw. paintComponnent-Methode aufgerufen werden kann.

Vom Verlauf des Threads her würde ich mal vermuten, daß dies Dein erster Versuch in die Richtung ist und das Du mehr oder weniger versuchst die ganze Logik in eine Klasse zu packen, was nicht besonders sinnvoll ist. (Korrigiere mich, wenn ich mich irre). Beschreibe doch erst mal welches Spiel Du mit welchen Logiken implementieren willst, dann kann man Dir konkrete Lösungsansätze aufzeigen. Mit dem Spielfeld anzufangen ist nicht unbedingt die beste Herangehensweise.


----------



## Gast2 (18. Nov 2009)

Schau dir doch mal in der FAQ das Malbeispiel an...
Ich würde für Zeichenobjekte Klassen erstellen die eventuell Shape implementieren dann kannst sie ganz easy zeichnen...


----------



## TX (1. Dez 2009)

So hatte das Thema etwas verdrängt! Habe jetzt aber nach etwas Informierung zur Grafikprogrammierung unter Java etwas zusammengebastelt.

Werde demnächst wohl noch ein paar Fragen dazu stellen.
Könnt euch das ja mal anschauen und eventuell Verbesserungsvorschläge geben.

Ein kleine Frage nebenbei, versuche bei der Methode stoneRun() eine Animation zu erstellen.
Also, dass jede Sekunde das nächste Feld ausgewählt wird. Geht so aber nicht !?!
Liegt es am RepaintManager oder so?


```
package Test1;

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
//import java.awt.geom.GeneralPath;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

// XXXXXXXXXXXXX GUI XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
public class WabantiGUI extends JFrame{
    
    private static final long serialVersionUID = 1L;
    
    GamePaint gamePaint = new GamePaint();
    JTextField jtsetStone;
    JTextField jtstoneRun;
    
    public WabantiGUI() {
        super("Wabanti");
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        
        getContentPane().setLayout(new BorderLayout());
        
        JPanel jpSouth = new JPanel(new FlowLayout());
        JButton jbSetStone = new JButton("Set Stone");
        jbSetStone.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setStone(); 
            }
               
            });
        jtsetStone = new JTextField(3);
        
        JButton jbStoneRun = new JButton("Stone Run");
        jbStoneRun.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                stoneRun(); 
            }
               
            });
        
        jtstoneRun = new JTextField(3);
        jtstoneRun.setEditable(false);
        
        jpSouth.add(jtsetStone);
        jpSouth.add(jbSetStone);
        
        jpSouth.add(jtstoneRun);
        jpSouth.add(jbStoneRun);
        
        getContentPane().add(gamePaint, BorderLayout.CENTER);
        getContentPane().add(jpSouth, BorderLayout.SOUTH);
        
        setSize(700, 700);
        setResizable(false);
        setVisible(true);
    }
    
    
    
    private void setStone(){
        int stoneNR = 1;
        
        try{
            stoneNR = Integer.parseInt(jtsetStone.getText());
        }catch(NumberFormatException e){
            
        }
        
        
        if(stoneNR >= 1 && stoneNR <= 169){
            gamePaint.stoneField = stoneNR;
            gamePaint.repaint();
        }
    }
    
    private void stoneRun(){
        for(int i = 1; i <= 169; i++){
            gamePaint.stoneField = i;
            jtstoneRun.setText(String.format("%d", i));
            gamePaint.repaint();
            /*
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }*/
        }
    }
    
    //XXXXXXXXXX MAIN XXXXXXXXXXXXXXXXXXX
    public static void main(String[] args) {
        new WabantiGUI();
         
     }

}


//XXXXXXXXXXXXXX Zeichnen des Spiels XXXXXXXXXXXXXXXXXXXXXXX
class GamePaint extends JComponent{

   
    private static final long serialVersionUID = 1L;
    
    public int stoneField = 1;
    
    protected void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        
        //Hintergrund zeichenen
        g2.setColor(Color.ORANGE);
        drawBackground(g2);
        
        //Spielfeld zeichnen
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setStroke(new BasicStroke(2.5f));
        g2.setColor(Color.BLACK);
        drawField(g2);
        
        //Spielsteine zeichen
        drawStones(g2);
    }
    
    //Methode zum Zeichnen der Speilsteine
    private void drawBackground(Graphics2D g2){
        g2.fillRect(0, 0, 700, 700);
    }
    
    //Methode zum Zeichnen des Spielfeldes
    private void drawField(Graphics2D g2){
        //GeneralPath polyline;
        
        int xPoints[] = new int[6];
        int yPoints[] = new int[6];
        
        
        
        for(int i = 0; i < Hexagons.hexagons.length; i++){
            xPoints = Hexagons.hexagons[i].getXPoints();
            yPoints = Hexagons.hexagons[i].getYPoints();
            
            /*polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 6);
            polyline.moveTo (xPoints[0], yPoints[0]);
            
            
            for ( int index = 1; index < 6; index++ ) {
                polyline.lineTo(xPoints[index], yPoints[index]);
            };
            
            polyline.lineTo(xPoints[0], yPoints[0]);
            g2.draw(polyline);
            */
            g2.drawPolygon(xPoints, yPoints, 6);
        } 
        
    }
    
    //Methode zum Zeichnen der Speilsteine
    private void drawStones(Graphics2D g2){
        int xPoints[] = new int[6];
        int yPoints[] = new int[6];
        
        xPoints = Hexagons.hexagons[stoneField - 1].getXPoints();
        yPoints = Hexagons.hexagons[stoneField - 1].getYPoints();
        
        g2.fillPolygon(xPoints, yPoints, 6);
    }
}
```


```
package Test1;



public class Hexagons {
    
    static Hexagon hexagons[];
    
    private static final int QUANTITY = 169;
    
    private static final int XSTART = 350;
    private static final int YSTART = 50;
    
    private static final int XPLUS = 30;
    private static final int YPLUS = 18;
    
    private static final int RADIUS = 20;
    private static final int hexagonCount[] = {1, 2, 3, 4, 5, 6, 7, 8, 7, 8, 7, 8, 7, 
      8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 6, 5, 4, 3, 2, 1};
    
    
    static{
        int x = XSTART;
        int y = YSTART;
        
        hexagons = new Hexagon[QUANTITY];
        
        int hexagonPos = 0;
        
        for(int i = 0; i < hexagonCount.length; i++){
            
            x = XSTART;
            
            for(int j = 1; j < hexagonCount[i]; j++){
                x -= XPLUS;
                
            }
            
            for(int j = 0; j < hexagonCount[i]; j++){
                hexagons[hexagonPos] = new Hexagon(x, y, RADIUS);
                hexagonPos++;
                x += XPLUS*2;
            }
            
            y += YPLUS;
            
        }
        
    }
    
}

class Hexagon{
    int xmiddle;
    int ymiddle;
    int radius;
    int xPoints[];
    int yPoints[];
    //int koorSE[];
    
    Hexagon(int x, int y, int radius){
        xPoints = new int [6];
        yPoints = new int [6];
        //koorSE = new int[4];
        
        xmiddle = x;
        ymiddle = y;
        this.radius = radius;
        
        calcPoints();
    }
    
    private  void calcPoints(){
        for (int i = 0; i < 6; i++) {
            xPoints[i] = (int)(xmiddle + radius * Math.cos(i * 2 * Math.PI / 6));
            yPoints[i] = (int)(ymiddle + radius * Math.sin(i * 2 * Math.PI / 6));   
        }  
    }
    
    
    public int[] getXPoints(){
        return xPoints;
    }
    
    public int[] getYPoints(){
        return yPoints;
    }
    
}
```


----------



## TX (2. Dez 2009)

Macht es Sinn mit diesem statischen Koordinaten? Oder sollte man die jedesmal neuberechnen lassen in der Zeichenmethode selber?

Habe schon einen kleinen Vergleichstest gemacht und irgendwie Verbrauch die Neuberechnung weniger Leistung als das statische, warum auch immer !?!


----------



## Timo Frenzel (12. Nov 2012)

TX hat gesagt.:


> [/code]
> private static final int hexagonCount[] = {1, 2, 3, 4, 5, 6, 7, 8, 7, 8, 7, 8, 7,
> 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 6, 5, 4, 3, 2, 1};
> [/code]




Ja, schon etwas her aber kann mir einer sagen wozu diese Angaben sind?
Versuche das Beispiel grad zu durchschauen und das Raster doppeltsograoß zu machen.


----------



## bERt0r (12. Nov 2012)

Und da schändest du dieses Threadgrab? Den Stil mit alles static machen solltest du dir besser nicht abschauen. Da schau her: https://dl.dropbox.com/u/13226411/HexagonTest.jar


----------

