# TowerDefense



## zerni1 (15. Mai 2007)

Hallo !

ich hab mir mal überlegt eine TowerDefense in Java zu programmieren!

Spielprinzip: Einheiten laufen einen Pfad entlang und der Spieler baut türme, die den Creeps den Weg versperren bzw. umleiten und damit verlängern um sie abzuschießen bevor sie ankommen.

Ich habe jetzt ein paar allgemeine Fragen:

Threads:
- Ist es sinnvoll für jede Einheit/Turm einen eigenen Thread anzulegen oder besser 1 Thread = 5 Creeps/Tower

KI:
- Wie würdet ihr es realisieren, dass die Einheiten sich Wegpunkte suchen? gibt es da evtl. Algorithmen, die zu benutzen wären?

Engine:
- Ich habe eigentlich vor das ganze mit Graphics(2) zu machen, gibt es da Engines, die sich mehr anbieten oder/und schneller sind?


hier der Code:

```
/*
 * Main.java
 *
 * Created on 11. Mai 2007, 13:36
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package towerdefense;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Main extends JFrame{

  private GraphicsDevice graphicsDevice;
  private DisplayMode origDisplayMode;

  private JButton bt_close;
  private JButton bt_minimize;
  private JButton bt_credits;
  private JButton bt_introduction;
  private JButton bt_options;
  private JButton bt_play;
  private JButton bt_mainmenu;

  private JComboBox cb_depth;
  private JComboBox cb_hz;
  private JComboBox cb_res;
  private JLabel la_depth;
  private JLabel la_hz;
  private JLabel la_music;
  private JLabel la_res;
  private JLabel la_sound;
  private JSlider sl_music;
  private JSlider sl_sound;
  
  private JPanel pn_options;
  private JPanel pn_mainmenu;
  private JPanel pn_game;
  private JPanel pn_instructions;
  private JPanel pn_credits;
  private JPanel pn_small_bt;
    
    public Main(GraphicsDevice graphicsDevice){
    
    this.graphicsDevice = graphicsDevice;
    origDisplayMode = graphicsDevice.getDisplayMode();

        if (graphicsDevice.isFullScreenSupported()){
          setUndecorated(true);
          setResizable(false);
          graphicsDevice.setFullScreenWindow(this);
          validate();
        }else{
          System.out.println("Full-screen mode not supported");
        }
    initComponents();
    }

    public static void main(String[] args){
        GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] devices = graphicsEnvironment.getScreenDevices();
            for(int cnt = 0;cnt < 1;cnt++){
              System.out.println(devices[cnt]);
            }
        new Main(devices[0]);
    }

    private void initComponents() {
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(null);
        setTitle("Z's TD-0.1A");   
        mainmenu();
    }

    private void game(){
        if(pn_mainmenu != null)remove(pn_mainmenu);

        pn_game = new javax.swing.JPanel();
        
        pn_game.setLayout(null);
        getContentPane().add(pn_game);
        pn_game.setBounds(0,0,getWidth(),getHeight());   
        
        small_bt(pn_game);
    }
    
    private void options(){
        if(pn_mainmenu != null)remove(pn_mainmenu);
        
        la_res = new javax.swing.JLabel();
        la_depth = new javax.swing.JLabel();
        la_hz = new javax.swing.JLabel();
        la_sound = new javax.swing.JLabel();
        la_music = new javax.swing.JLabel();
        cb_res = new javax.swing.JComboBox();
        cb_depth = new javax.swing.JComboBox();
        cb_hz = new javax.swing.JComboBox();
        sl_sound = new javax.swing.JSlider();
        sl_music = new javax.swing.JSlider();
        pn_options = new javax.swing.JPanel();
        
        // Options-Panel
        pn_options.setLayout(null);
        getContentPane().add(pn_options);
        pn_options.setBounds(0,0,getWidth(),getHeight());

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        la_res.setFont(new java.awt.Font("Georgia", 1, 24));
        la_res.setText("Resolution");
        pn_options.add(la_res);
        la_res.setBounds((this.getWidth()/2)-140, 300, 140, 30);

        la_depth.setFont(new java.awt.Font("Georgia", 1, 24));
        la_depth.setText("Depth");
        pn_options.add(la_depth);
        la_depth.setBounds((this.getWidth()/2)-80, 360, 80, 30);

        la_hz.setFont(new java.awt.Font("Georgia", 1, 24));
        la_hz.setText("Hz");
        pn_options.add(la_hz);
        la_hz.setBounds((this.getWidth()/2)-40, 420, 40, 30);

        la_sound.setFont(new java.awt.Font("Georgia", 1, 24));
        la_sound.setText("Sound");
        pn_options.add(la_sound);
        la_sound.setBounds((this.getWidth()/2)-90, 480, 90, 30);

        la_music.setFont(new java.awt.Font("Georgia", 1, 24));
        la_music.setText("Music");
        pn_options.add(la_music);
        la_music.setBounds((this.getWidth()/2)-80, 540, 80, 30);

        cb_res.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2"}));
        pn_options.add(cb_res);
        cb_res.setBounds((this.getWidth()/2), 300, 150, 30);

        cb_depth.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2"}));
        pn_options.add(cb_depth);
        cb_depth.setBounds((this.getWidth()/2), 360, 150, 30);

        cb_hz.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2"}));
        pn_options.add(cb_hz);
        cb_hz.setBounds((this.getWidth()/2), 420, 150, 30);

        pn_options.add(sl_sound);
        sl_sound.setBounds((this.getWidth()/2), 480, 150, 24);

        pn_options.add(sl_music);
        sl_music.setBounds((this.getWidth()/2), 540, 150, 24);
        
        small_bt(pn_options);
    }
    
    private void credits(){
        if(pn_mainmenu != null)remove(pn_mainmenu);
        
        pn_credits = new javax.swing.JPanel();
        
        // Options-Panel
        pn_credits.setLayout(null);
        getContentPane().add(pn_credits);
        pn_credits.setBounds(0,0,getWidth(),getHeight());
        
        small_bt(pn_credits);
    }
    
    private void instructions(){
        if(pn_mainmenu != null)remove(pn_mainmenu);
        
        pn_instructions = new javax.swing.JPanel();
        
        // Options-Panel
        pn_instructions.setLayout(null);
        getContentPane().add(pn_instructions);
        pn_instructions.setBounds(0,0,getWidth(),getHeight());
        
        small_bt(pn_instructions);
    }
    
    private void mainmenu(){
        if(pn_options != null) remove(pn_options);
        if(pn_instructions != null) remove(pn_instructions);
        if(pn_credits != null) remove(pn_credits);
        
        bt_play = new javax.swing.JButton();
        bt_options = new javax.swing.JButton();
        bt_credits = new javax.swing.JButton();
        bt_introduction = new javax.swing.JButton();
        pn_mainmenu = new javax.swing.JPanel();
        
        pn_mainmenu.setLayout(null);
        getContentPane().add(pn_mainmenu);
        pn_mainmenu.setBounds(0,0,getWidth(),getHeight());
        
        bt_play.setText("Play");
        bt_play.setFont(new java.awt.Font("Georgia", 1, 24));
        bt_play.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                bt_playMouseClicked(evt);
            }
        });
        pn_mainmenu.add(bt_play);
        bt_play.setBounds((this.getWidth()/2)-100, 300, 200, 50);
        
        
        bt_introduction.setText("Instruction");
        bt_introduction.setFont(new java.awt.Font("Georgia", 1, 24));
        bt_introduction.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                bt_introductionMouseClicked(evt);
            }
        });
        pn_mainmenu.add(bt_introduction);
        bt_introduction.setBounds((this.getWidth()/2)-100, 540, 200, 50);
        

        bt_options.setText("Options");
        bt_options.setFont(new java.awt.Font("Georgia", 1, 24));
        bt_options.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                bt_optionsMouseClicked(evt);
            }
        });
        pn_mainmenu.add(bt_options);
        bt_options.setBounds((this.getWidth()/2)-100, 380, 200, 50);

        
        bt_credits.setText("Credits");
        bt_credits.setFont(new java.awt.Font("Georgia", 1, 24));
        bt_credits.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                bt_creditsMouseClicked(evt);
            }
        });
        pn_mainmenu.add(bt_credits);
        bt_credits.setBounds((this.getWidth()/2)-100, 460, 200, 50);
        
        small_bt(pn_mainmenu);
    }
  
    private void small_bt(javax.swing.JPanel panel){
        bt_close = new javax.swing.JButton();
        bt_minimize = new javax.swing.JButton();
        bt_mainmenu = new javax.swing.JButton();
        pn_small_bt = new javax.swing.JPanel();
        
        pn_small_bt.setLayout(null);
        panel.add(pn_small_bt);
        pn_small_bt.setBounds(getWidth()-100,0,100,40);
        
        bt_close.setFont(new java.awt.Font("Verdana", 1, 12));
        bt_close.setText("X");
        bt_close.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        bt_close.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                bt_closeMouseClicked(evt);
            }
        });

        pn_small_bt.add(bt_close);
        bt_close.setBounds(70, 10, 20, 20);

        bt_minimize.setFont(new java.awt.Font("Verdana", 1, 12));
        bt_minimize.setText("_");
        bt_minimize.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        bt_minimize.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                bt_minimizeMouseClicked(evt);
            }
        });

        pn_small_bt.add(bt_minimize);
        bt_minimize.setBounds(40, 10, 20, 20);
        
        bt_minimize.setFont(new java.awt.Font("Verdana", 1, 12));
        bt_mainmenu.setText("M");
        bt_mainmenu.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        bt_mainmenu.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                bt_mainmenuMouseClicked(evt);
            }
        });

        pn_small_bt.add(bt_mainmenu);
        bt_mainmenu.setBounds(0, 10, 20, 20);
    }
  
    private void bt_minimizeMouseClicked(java.awt.event.MouseEvent evt) {
        this.setState ( this.ICONIFIED );
    }

    private void bt_closeMouseClicked(java.awt.event.MouseEvent evt) {                                      
        graphicsDevice.setDisplayMode(origDisplayMode);
        System.exit(0);
    }   
 
    private void bt_mainmenuMouseClicked(java.awt.event.MouseEvent evt) {
        mainmenu();
    }
    
    private void bt_creditsMouseClicked(java.awt.event.MouseEvent evt) {

    }

    private void bt_optionsMouseClicked(java.awt.event.MouseEvent evt) {
        options();
    }

    private void bt_introductionMouseClicked(java.awt.event.MouseEvent evt) {

    }

    private void bt_playMouseClicked(java.awt.event.MouseEvent evt) {

    }
}
```


----------



## Evil-Devil (15. Mai 2007)

Ich würd ein Thread bzw. Gameschleife  für alles machen. Reicht eigentlich vollkommen.

Den Weg würd ich vermutlich über einen Vector realisieren der nur die Eckpunkte speichert. Und das Spielfeld jenachdem. Wenn es in Felder aufgeteilt ist als 3 dimensionales array und sonst einen vector mit allen türmen.


----------



## zerni (15. Mai 2007)

Habe zum Algo für die Wegfindung A* gefunden!

den werde ich vermutlich etwas einfacher umsetzen.

Danke schon für die Antwort!


----------



## Illuvatar (15. Mai 2007)

Hm? Du brauchst doch keine Wegfindung, jedenfalls keine so komplizierte, dass du A* bräuchtest. Die Feinde laufen doch von Straßenecke 1 zu 2 zu 3 zu 4....


----------



## zerni (15. Mai 2007)

nein, ich wollte das so implementieren: http://www.handdrawngames.com/DesktopTD/


----------



## Java_Freak (16. Mai 2007)

Schau dir doch mal den Sourcecode von ApoTowerdefence an , ist hier auch irgendwo ein Thread drüber...


----------

