Bewegungs-Simulator mit Startschwierigkeiten

Fivo

Neues Mitglied
Hallo liebe Javaisten,

gerne möchte ich mich mit einem Problem an euch wenden. Ich bin Java-Neuling und versuche hier ein Programm ala Hamstersimulator zu programmieren.
In dem Programm geht es um mehrere Spielfiguren, die sich zufällig auf einem Spielfeld bewegen sollen. Diese sollen dabei Eigenschaften, wie zum Beispiel Lebenspunkte, Größe, Mana, wasauchimmer haben. In meinem bisherigen Quelltext habe ich es so weit gebracht, dass sich ein Spieler namens "X" in beispielsweise 30 Zügen zufällig bewegt :applaus: . Die zufällige Bewegung macht meiner Meinung nach keine Probleme. Was mir problematisch erscheint, ist dem "X" eine irgendwie geartete Eigenschaft zuzuordnen. Am Ende stelle ich mir sowas wie "player_xyz.move()" vor ???:L .
Habt ihr da eine Idee, wie ich das möglicherweise umsetzen könnte?

Vielen herzlichen Dank!


Fivo




Anbei der Quelltext:

Java:
package movement_0_1;

import static java.lang.Math.round;
import java.util.Timer;
import java.util.TimerTask;

public class Bewegung {
    public static Timer timer;         
    public static TimerTask timertask;
      
    static int q = 0;                     //Zählvariable für den Timer
    static int p = 0;                    //Zufallszahl für Wahrscheinlichkeit der Bewgungsrichtung
    static int x_max = 5;             //Maximale Feldgröße in x-Richtung (horizontal)
    static int y_max = 5;             //Maximale Feldgröße in y-Richtung (vertikal)
    static int x =round(x_max/2); //Anfangsposition in x-Richtung Spieler "X"
    static int y =round(y_max/2); //Anfangsposition in y-Richtung Spieler "X"
    static boolean stop = false;
    
    static String[][] felder = new String [y_max+1][x_max+1]; //Erstellen des Feldes 
    
    //Spielfeld initialisierung und setzen aller Felder auf 0
    static void playground(){           

        for (int i=0; i< felder.length; ++i)       // Zeile
        {
            for (int j=0; j<felder[0].length; ++j) // Spalte
            {
                felder[i][j]=".";
                felder[round(y_max/2)][round(x_max/2)]="X";
                System.out.print(felder[i][j]);
            }
            System.out.println();
        }
    }    
    
    static void up(){
        if (y-1 < 0)
            System.out.println("Außerhalb des Bereiches!");
            else
        {
            updateGround(y,x,"."); 
            y--;
            updateGround(y,x,"X"); // macht probleme, wenn wir mehrere (verschiedene) X's haben
            drawGround();
        }
    }
    static void down(){
        if (y+1 > y_max)
            System.out.println("Außerhalb des Bereiches!");
        else
        {
            updateGround(y,x,".");
            y++;
            updateGround(y,x,"X");
            drawGround();
        }
    }
    static void right(){
        if (x+1 > x_max)
            System.out.println("Außerhalb des Bereiches!");
        else
        {
            updateGround(y,x,".");
            x++;
            updateGround(y,x,"X");
            drawGround();
        }
    }
    static void left(){
        if (x-1 < 0)
            System.out.println("Außerhalb des Bereiches!");
        else
        {
            updateGround(y,x,".");
            x--;
            updateGround(y,x,"X");
            drawGround();   
        }   
    }
    
    public static void start() {
        System.out.println("Fuer Start = 1");
        int Richtung = new java.util.Scanner( System.in ).nextInt();
        if (Richtung == 1) timerStarten(1000);
    }
        
    public static void timerStarten(long intervall){ 
if(timer==null){
timer = new Timer();
timertask = new TimerTask()
{
  public void run() 
  {
   timerAction();
  }
};
timer.schedule(timertask, 0, intervall);
}
}     
    public static void timerStoppen(){
if(timer!=null)
{
 timertask.cancel();
 timer.cancel();
 timertask=null;
 timer=null;
}
}
    public static void timerAction() {
    if (q==30) timerStoppen();
    else
     { 
      q++;
      move();
     }
   }     
    public static void move(){
                        
            p = (int) (Math.random()* 20); 
            
            if (p <= 5) {
              up();
            //  updatePos();
            }
            if (p > 5 && p <= 10) {
              down();
            //  updatePos();
            }
            if (p > 10 && p <= 15) {
              right();
            //  updatePos();
            }
            if (p > 15 && p <= 20) {
              left();
            //  updatePos();
            }                             
    }
  
    //Ausgabe der aktuellen Koordinaten x/y
    static void updatePos(){        
        System.out.println("x: " +x + ", y: " +y);
        // System.out.println("p = " +p);
    }
    
    //Setzen des Wertes im Array "." = leer, "X" = Spieler
    static void updateGround(int y,int x, String player){
        felder[y][x] = player;   //was passiert hier bei mehreren X's ??   
    }
    
    //Zeichnung der Matrix
    static void drawGround(){
        for (int i=0; i< felder.length; ++i)     // Zeile
            {
                for (int j=0; j<felder[0].length; ++j) // Spalte
                {
                   System.out.print(felder[i][j]);
                }
                System.out.println();
            }    
        System.out.println();
         
    }
          
    public static void main(String[] args) {
        playground();
        start();
    }
    
}
 
Zuletzt bearbeitet:

Thallius

Top Contributor
Du solltest wesentlich mehr in Klassen denken.

Jede Spielfigur sollte eine eigene Klasse sein. Diese Klasse hat halt beliebig viele Eigenschaften, wie eben Name, Mana oder was auch immer

Das Spielfeld ist auch eine Klasse. Es hat ein zweidimensionales Array wie du es jetzt auch schon hast, nur nicht ein Array von char wie o und x, sondern von Spielfiguren. Steht auf einem Feld keine Figur ist der Inhalt Null ansonsten steht halt die Spielfigur selber darin.

Wenn du willst kannst du sogar noch einen Schritt weiter gehen und jedes Feld auf dem Spielfeld zu einer eigenen Klasse machen um diesem später weitere Eigenschaften wie Art (Wasser, Gebirge, wüste etc) oder Bodenschätze zu geben

Gruß

Claus
 

ChIcKiN

Mitglied
Hallo Claus,

vielen herzlichen Dank für Deine Anregung. Ich arbeite zusammen mit Fivo an dem "Projekt". Deine Anmerkungen haben wir versucht umzusetzen. Dabei ist Folgendes rausgekommen:


Zunächst haben wir da die Oberklasse, die ihre Attribute an die Unterklassen Ground und Player vererben kann. Wichtig sind hier vor allem die Koordinaten.

Java:
package Evolution_0_1;

//Spielobjekt Oberklasse zum Vererben von Eigenschaften (Name, Größe, Koordinaten, etc.)

public class GameObject {
    String groesse;   //derzeit nicht genutzt
    static int x; //X-Koordinate
    static int y; //Y-Koordinate
    
}

Hier die Klasse zur Beschreibung des Terrains
Java:
package Evolution_0_1;

//Hier werden alle Bodeneigenschaften deklariert

public class Ground extends GameObject {
    String terrain;
}

In dieser Klasse wird das Spielfeld durch Zufallszahlen generiert (drawNewGround). Dabei wird zwischen Gras, Stein und Wasser unterschieden. Im Verlauf der Simulation wird dieses Spielfeld geupdated (updateGround). Beim updaten haben wir aber so unsere Zweifel, ob das im weiteren Verlauf noch gut funktioniert.

Java:
package Evolution_0_1;


public class Playground {
    static int x_max = 10;
    static int y_max = 10;
    static String[][] field = new String [y_max][x_max]; //Erstellen des Feldes 
    static Ground grass = new Ground();  
    static Ground water = new Ground();     
    static Ground stone = new Ground();     
    static int i;
    static int j;

    static void drawNewGround(){  //Zeichnung der Matrix
             
        grass.terrain = ".";
        water.terrain = "~";
        stone.terrain = "o";
                    
        for (i=0; i< field.length; ++i) {  //Zeile
            for (j=0; j<field[0].length; ++j) {  //Spalte

                int p = (int) (Math.random()* 30); 
                
                if (p <= 3) {
                  field[i][j]=water.terrain;
                }
                if (p > 3 && p <= 27) {
                  field[i][j]=grass.terrain;
                }
                if (p > 27 && p <= 30) {
                  field[i][j]=stone.terrain;
                }
                  System.out.print(field[i][j]);
                }
                System.out.println();
            }    
        System.out.println();
}

    static void updateGround(int y, int x, String GO) {
        
      field[y][x] = GO;
                      
        for (i=0; i< field.length; ++i) {      // Zeile
          for (j=0; j<field[0].length; ++j) {  // Spalte
             System.out.print(field[i][j]);
          }
        System.out.println();
        }    
      System.out.println();
    }
    
}

Im Folgenden werden die Spielereigenschaften deklariert und die Bewegungssimulation ausgeführt. Anhang einer gewissen Wahrscheinlichkeit, die durch Zufallszahlen bestimmt wird, läuft der Spieler auf, ab, nach rechts oder nach links. Diese Funktionen werden dann aufgerufen und das Spielfeld aktualisiert. Die ehemalige Spielerposition "X" wird erstmal durch Gras "." ersetzt.

Java:
package Evolution_0_1;

import static Evolution_0_1.Playground.grass;
import static Evolution_0_1.Playground.updateGround;


public class Player extends GameObject{
    String name;
    int speed;
    int sight;
     

    //Movement
    
    static void move(){  //wählt zufällig eine Richtung aus, in die der Spieler geht

        int p = (int) (Math.random()* 20); //Zufallszahl generieren
         
        if (p <= 5) {
          up();
        }
        if (p > 5 && p <= 10) {
          down();
        }
        if (p > 10 && p <= 15) {
          right();
        }
        if (p > 15 && p <= 20) {
          left();
        }  
    }
     
    static void up(){
      if (Player.y-1 < 0){
        updateGround(Player.y, Player.x, grass.terrain);
        Player.y = Playground.y_max-1;
        updateGround(Player.y, Player.x, "X");
      }
      else {
        updateGround(Player.y, Player.x, grass.terrain);
        Player.y--;
        updateGround(Player.y, Player.x, "X");
      }
    }
        
    static void down(){
      if (Player.y+2 > Playground.y_max) {
        updateGround(Player.y, Player.x, grass.terrain);
        Player.y = 0;
        updateGround(Player.y, Player.x, "X");
      }
      else {
        updateGround(Player.y,Player.x,grass.terrain);
        Player.y++;
        updateGround(Player.y,Player.x,"X");
      }
    }
    
    static void right(){
      if (Player.x+2 > Playground.x_max){
        updateGround(Player.y, Player.x, grass.terrain);
        Player.x = 0;
        updateGround(Player.y, Player.x, "X");
      }
      else {
        updateGround(Player.y,Player.x,grass.terrain);
        Player.x++;
        updateGround(Player.y,Player.x,"X");
      }
    }
    
    static void left(){
      if (Player.x-1 < 0){
        updateGround(Player.y, Player.x, grass.terrain);
        Player.x = Playground.x_max-1;
        updateGround(Player.y, Player.x, "X");
      }
      else {
        updateGround(Player.y,Player.x,grass.terrain);
        Player.x--;
        updateGround(Player.y,Player.x,"X");
     }   
    }
    
}

Der Timer ist dafür da, dass man einzelne Schritte nachvollziehen kann, ohne dass das Programm in Millisekunden abgelaufen ist. Zunächst wird die Simulation gestartet, die den timer startet, der widerum eine Aktion ausführt, die die Bewegungsimulation beginnt (zu kompliziert?). timerStop wird derzeit nicht benötigt.

Java:
package Evolution_0_1;

import java.util.Timer;
import java.util.TimerTask;


public class Timer_ {
    
    static java.util.Timer timer;         
    static TimerTask timertask;
    
    
static void start() {   //startet den Timer mit der funktion timerstarten
    System.out.println("Fuer Start = 1");
    int Richtung = new java.util.Scanner( System.in ).nextInt();
    if (Richtung == 1) timerStart(500);              //1000 = 1sekunde
}    

    
static void timerStart (long intervall){  //führt die timerAction aus
  if(timer==null){
   timer = new Timer();
   timertask = new TimerTask() {
     public void run() {
       timerAction();
       }
     }; 
   timer.schedule(timertask, 0, intervall);
  }
}     

static void timerStop(){  //stoppt den Timer
  if(timer!=null) {
   timertask.cancel();
   timer.cancel();
   timertask=null;
   timer=null;
  }
}

static void timerAction() {  //führt die Bewegungsfunktion aus. 
  Player.move();}
}

In dieser Klasse wird das gesamte Spiel gestartet.

Java:
package Evolution_0_1;

/* Das ist die Hauptklasse (?), von der aus das Spiel gestartet und gespielt wird */

public class Play {

    public static void main(String[] args) {
       Playground.drawNewGround(); //neues Feld erstellen
       
       Timer_.start();
    
    }
}

Soweit zu unserem "Programm" das erst noch eins werden will. Jetzt aber zu den Fragen:
Wie würde das ganze ausschauen, wenn wir einen zweiten Spieler ins Leben rufen wollten? Also nicht nur generieren, sondern der soll sich auch bewegen lassen. Beide Spieler sollen aber separat voneinander laufen können. In der "Hauptklasse" public class play {} einen zweiten Spieler zu generieren hat zwar funktioniert, wir bekamen zwar ein zweites "X" ins Spiel, dies lies sich aber nicht bewegen und wurde irgendwann überschrieben :)

Weiterhin wird das Spielfeld derzeit von dem bewegenden Spieler überschrieben. Das soll später natürlich nicht mehr der Fall sein. Auch eine Kollisionsabfrage benötigen wir, damit der Spieler nicht über Stein und Wasser läuft. Unsere Idee wäre da eine separate Matrix für Spieler, Terrain und Spielfeld, um dann deren Inhalte zu vergleichen und gegebenenfalls zu ersetzen/überschreiben.

Was meint Ihr dazu?
 

ARadauer

Top Contributor
ich hab mir jetzt nicht alles durchgelesen
Was meint Ihr dazu?

Java:
public class Player extends GameObject{
    String name;
    int speed;
    int sight;
     
 
    //Movement
    
    static void move(){
...

ähmn stop... einfach mal kapitel 5 lesen
Galileo Computing :: Java ist auch eine Insel – 5 Eigene Klassen schreiben :rtfm:

weg mit dem static an dieser stelle, die methode muss ich auf das objekt beziehen und nicht die klasse


Java:
public class GameObject {
    String groesse;   //derzeit nicht genutzt
    static int x; //X-Koordinate
    static int y; //Y-Koordinate
    
}
alle deine GameObjekte haben die gleiche position... was static bewirkt muss man verstanden haben, sonst macht java programmierung keinen sinn
 

Ähnliche Java Themen

Neue Themen


Oben