Programmieren eines Spieles

Diskutiere Programmieren eines Spieles im Softwareentwicklung Bereich.
X

Xknight

Hallo,
ich habe hier ein Spiel programmiert und brauche eure Hilfe dabei, denn ich überhaupt nicht was ich hier falsch gemacht habe. Immer wieder tritt diese Fehler Meldung bei mir auf.




/*
import javax.swing.*;

public class Maze {
public Maze() {
JFrame f = new JFrame();
f.setTitle("The Maze Game");
f.add(new Board());
f.setSize(500, 400);
f.setLocationRelativeTo(null);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new Maze();


}
}
*/

/*
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class Board extends JPanel implements ActionListener {

private Timer timer;

private Map m;
private Player p;
private boolean win = false;
private String Message = "";

private Font font = new Font("Levent", Font.BOLD, 48);

public Board() {

m = new Map();
p = new Player();
addKeyListener(new A1());
setFocusable(true);

timer = new Timer(25, this);
timer.start();
}

public void actionPerformed(ActionEvent e) {
if(m.getMap(p.getTileX(), p.getTileY()).equals("f")) {
Message = "Winner";
win = true;
}

repaint();
}

public void paint(Graphics g) {
super.paint(g);
if(!win) {
for(int y = 0; y < 14; y++) {
for(int x = 0; x < 14; x++) {
if(m.getMap(x ,y).equals("d")) {
g.drawImage(m.getDesert(), x * 64, y* 36, null );
}
if(m.getMap(x ,y).equals("w")) {
g.drawImage(m.getWall(), x * 64, y* 36, null );
}
}
}
g.drawImage(p.getPlayer(), p.getTileX() * 64, p.getTileY() * 32, null );
}
if(win) {
g.setColor(Color.RED);

g.setFont(font);

g.drawString(Message, 150, 300);
}

}

public class A1 extends KeyAdapter{

public void keyPressed(KeyEvent e) {
int keycode = e.getKeyCode();

if(!m.getMap(p.getTileX(), p.getTileY() -1).equals("w")){
if(keycode == KeyEvent.VK_W) {
p.move(0, -1);
}
}

if(!m.getMap(p.getTileX(), p.getTileY() +1).equals("w")) {
if(keycode == KeyEvent.VK_S) {
p.move(0, 1);
}
}

if(!m.getMap(p.getTileX() - 1, p.getTileY() ).equals("w")) {
if(keycode == KeyEvent.VK_A) {
p.move( -1, 0);
}
}

if(!m.getMap(p.getTileX() + 1, p.getTileY() ).equals("w")) {
if(keycode == KeyEvent.VK_D) {
p.move(1, 0);
}

}


}
}
}
*/

import java.awt.*;
import java.io.*;
import java.util.*;

import javax.swing.ImageIcon;

public class Map {

private Scanner sc;

private String[] Map = new String[14];

private Image desert, finish, wall;

public Image getDesert() {
return desert;
}

public Image getFinish() {
return finish;
}

public Image getWall() {
return wall;
}


public Map() {

ImageIcon img = new ImageIcon("C://ptsd2020-papa//src-code//MazeGameUI//things//desert.jfif");
desert = img.getImage();
img = new ImageIcon("C://ptsd2020-papa//src-code//MazeGameUI//things//wall.jfif");
wall = img.getImage();
img = new ImageIcon("C://ptsd2020-papa//src-code//MazeGameUI//things//finish.png");
finish = img.getImage();

openFile();
readFile();
closeFile();
}

public String getMap(int x, int y) {
String index = Map[y].substring(x, x+1);
return index;
}


public void openFile() {

try {
sc = new Scanner(new File("C://ptsd2020-papa//src-code//MazeGameUI//things//Map.txt"));
}catch(Exception e) {
System.out.println("error");
}
}

public void readFile() {
while(sc.hasNext()) {
for(int i = 0; i<14; i++) {
Map = sc.next();
}
}
}

public void closeFile() {
sc.close();
}
}

*/

/*
import java.awt.*;

import javax.swing.ImageIcon;

public class Player {

private int tileX, tileY;

private Image player;

public Player() {

ImageIcon img = new ImageIcon("C://ptsd2020-papa//src-code//MazeGameUI//things//dummy.jfif");
player = img.getImage();



tileX = 1;
tileY = 1;
}

public Image getPlayer() {
return player;
}



public int getTileX() {
return tileX;
}

public int getTileY() {
return tileY;
}

public void move(int dx, int dy) {



tileX += dx;
tileY += dy;




}
}
*/

/*
Exception in thread "main" java.lang.NullPointerException
at MazeGameUI/de.uni_koblenz.ptsd.PAPA.mazegameui.Map.readFile(Map.java:60)
at MazeGameUI/de.uni_koblenz.ptsd.PAPA.mazegameui.Map.<init>(Map.java:40)
at MazeGameUI/de.uni_koblenz.ptsd.PAPA.mazegameui.Board.<init>(Board.java:21)
at MazeGameUI/de.uni_koblenz.ptsd.PAPA.mazegameui.Maze.<init>(Maze.java:9)
at MazeGameUI/de.uni_koblenz.ptsd.PAPA.mazegameui.Maze.main(Maze.java:16)
*/
 
J

JustNobody

Code bitte in Code-Tags posten (Über dem Eingabefeld auf die "..." gehen und Code auswählen. In das Popup kann man dann den Code kopieren).

Ansonsten wäre wichtig:
Was ist die Zeile 60 in Map.java? In der Zeile kommt die NPE.

Vermutlich ist Zeile 60: while(sc.hasNext()) {
Dann hat das Erstellen des Scanners nicht geklappt weil es die Datei nicht gibt und er ist da schon mit einer Exception ausgestiegen. Diese fängst Du aber und gibst nur "error" aus. Sprich: Du hattest vorher schon eine "error" Ausgabe? ==> Gib nicht nur "error" aus sondern immer die Exception und den Stacktrace!

Dann als Hinweis: Es reicht ein / als Trenner der Verzeichnisse. Das \\ kommt nur daher, dass das \ das sogenannte Escape Zeichen ist um Sonderzeichen in einem String anzugeben. Daher ist \\ schlicht für ein \ da. (Sprich: System.out.println("\\"); gibt einfach nur \ aus!)
 
X

Xknight

Danke für deine Antwort. Aber ich habe die Map.txt datei schon erstellt, wo es eigentlich ausgeben sollte.Anmerkung 2020-09-09 121133.png
 
X

Xknight

Java:
[CODE]
[CODE]import java.awt.*;
import java.io.*;
import java.util.*;

import javax.swing.ImageIcon;

public class Map {
  
    private Scanner sc;
    
    private String[] Map = new String[14];
    
    private Image desert, finish, wall;
    
    public Image getDesert() {
        return desert;
    }
    
    public Image getFinish() {
        return finish;
    }
    
    public Image getWall() {
        return wall;
    }
    
  
    public Map() {
      
        ImageIcon img = new ImageIcon("C://ptsd2020-papa//src-code//MazeGameUI//things//desert.jfif");
        desert = img.getImage();
        img = new ImageIcon("C://ptsd2020-papa//src-code//MazeGameUI//things//wall.jfif");
        wall = img.getImage();
        img = new ImageIcon("C://ptsd2020-papa//src-code//MazeGameUI//things//finish.png");
        finish = img.getImage();
        
        openFile();
        readFile();
        closeFile();
    }
    
    public String getMap(int x, int y) {
        String index = Map[y].substring(x, x+1);
        return index;
    }
    
    
    public void openFile() {
        
        try {
          sc = new Scanner(new File("C://ptsd2020-papa//src-code//MazeGameUI//things//Map.txt")); 
        }catch(Exception e) {
            System.out.println("error");
        }
    }
    
    public void readFile() {
        while(sc.hasNext()) {
            for(int i = 0; i<14; i++) {
                Map[i] = sc.next();
            }
        }
    }
    
    public void closeFile() {
        sc.close();
    }
}
Code:
import java.awt.*;

import javax.swing.ImageIcon;

public class Player {
    
   private int tileX, tileY;
  
   private Image player;
    
    public Player() {
      
        ImageIcon img = new ImageIcon("C://ptsd2020-papa//src-code//MazeGameUI//things//dummy.jfif");
        player = img.getImage();
        

        
        tileX = 1;
        tileY = 1;
    }
    
    public Image getPlayer() {
        return player;
    }
    

    
    public int getTileX() {
        return tileX;
    }
    
    public int getTileY() {
        return tileY;
    }
    
    public void move(int dx, int dy) {
        

        
        tileX += dx;
        tileY += dy;
        
        
        
        
    }
}
Hier sind noch mal die Klassen.
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class Board extends JPanel implements ActionListener {

private Timer timer;

private Map m;
private Player p;
private boolean win = false;
private String Message = "";

private Font font = new Font("Levent", Font.BOLD, 48);

public Board() {

m = new Map();
p = new Player();
addKeyListener(new A1());
setFocusable(true);

timer = new Timer(25, this);
timer.start();
}

public void actionPerformed(ActionEvent e) {
if(m.getMap(p.getTileX(), p.getTileY()).equals("f")) {
Message = "Winner";
win = true;
}

repaint();
}

public void paint(Graphics g) {
super.paint(g);
if(!win) {
for(int y = 0; y < 14; y++) {
for(int x = 0; x < 14; x++) {
if(m.getMap(x ,y).equals("d")) {
g.drawImage(m.getDesert(), x * 64, y* 36, null );
}
if(m.getMap(x ,y).equals("w")) {
g.drawImage(m.getWall(), x * 64, y* 36, null );
}
}
}
g.drawImage(p.getPlayer(), p.getTileX() * 64, p.getTileY() * 32, null );
}
if(win) {
g.setColor(Color.RED);

g.setFont(font);

g.drawString(Message, 150, 300);
}

}

public class A1 extends KeyAdapter{

public void keyPressed(KeyEvent e) {
int keycode = e.getKeyCode();

if(!m.getMap(p.getTileX(), p.getTileY() -1).equals("w")){
if(keycode == KeyEvent.VK_W) {
p.move(0, -1);
}
}

if(!m.getMap(p.getTileX(), p.getTileY() +1).equals("w")) {
if(keycode == KeyEvent.VK_S) {
p.move(0, 1);
}
}

if(!m.getMap(p.getTileX() - 1, p.getTileY() ).equals("w")) {
if(keycode == KeyEvent.VK_A) {
p.move( -1, 0);
}
}

if(!m.getMap(p.getTileX() + 1, p.getTileY() ).equals("w")) {
if(keycode == KeyEvent.VK_D) {
p.move(1, 0);
}

}


}
}
}
[/CODE]
import javax.swing.*;

public class Maze {
public Maze() {
JFrame f = new JFrame();
f.setTitle("The Maze Game");
f.add(new Board());
f.setSize(500, 400);
f.setLocationRelativeTo(null);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new Maze();


}
}
[/CODE]
 
B

BestGoalkeeper

Hm mal Java-Code-Tags verwendet, mal nur Code-Tags, mal gar keine Tags und dann die Vorschau nicht genutzt. Zudem die Fehlermeldungen nicht ausreichend geschildert. Diese Frage genügt den Anforderungen nicht.
Lies dir mal "Vor dem ersten Posten bitte lesen" durch...
 
J

JustNobody

Ok, jetzt konnte man abzählen: Zeile 60 scheint tatsächlich die beschriebene Zeile zu sein. sc ist also wohl null. Das OpenFile() wird somit beim Öffnen eine Exception geworfen haben die Du nur in Form einer "error" Ausgabe zu sehen bekommen hast.

==> Vermutlich stimmt somit der Pfad nicht.

Der Explorer zeigt keine Dateiendungen an -> Mein Tipp wäre, auch bekannte Endungen anzeigen zu lassen! Oder in einer Eingabeaufforderung das einmal entsprechend zu prüfen.

Hm mal Java-Code-Tags verwendet, mal nur Code-Tags, mal gar keine Tags und dann die Vorschau nicht genutzt.
Er hat die nur leider versehentlich verschachtelt beim Einfügen. Der erste Code hat noch paar [CODE], die dann unten leider fehlen ...
 
X

Xknight

Java:
import javax.swing.*;

public class Maze {
    public Maze() {
        JFrame f = new JFrame();
        f.setTitle("The Maze Game");
        f.add(new Board());
        f.setSize(500, 400);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public static void main(String[] args) {
        new Maze();
        
        
    }
}
 
X

Xknight

Java:
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class Board extends JPanel implements ActionListener {
    
    private Timer timer;
    
    private Map m;
    private Player p;
    private boolean win = false;
    private String Message = "";
    
    private Font font = new Font("Levent", Font.BOLD, 48);
    
    public Board() {
      
        m = new Map();
        p = new Player();
        addKeyListener(new A1());
        setFocusable(true);
        
        timer = new Timer(25, this);
        timer.start();
    }
    
    public void actionPerformed(ActionEvent e) {
       if(m.getMap(p.getTileX(), p.getTileY()).equals("f")) {
           Message = "Winner";
           win = true;
       }
        
        repaint();
    }
    
    public void paint(Graphics g) {
        super.paint(g);
        if(!win) {
        for(int y = 0; y < 14; y++) {
            for(int x = 0; x < 14; x++) {
                if(m.getMap(x ,y).equals("d")) {
                    g.drawImage(m.getDesert(), x * 64, y* 36, null );
                }
                if(m.getMap(x ,y).equals("w")) {
                    g.drawImage(m.getWall(), x * 64, y* 36, null );
            }
        }
    }
        g.drawImage(p.getPlayer(), p.getTileX() * 64, p.getTileY() * 32, null );
}
        if(win) {
            g.setColor(Color.RED);
            
            g.setFont(font);
            
            g.drawString(Message, 150, 300);
        }       
      
}
    
    public class A1 extends KeyAdapter{
        
        public void keyPressed(KeyEvent e) {
           int keycode = e.getKeyCode();
          
           if(!m.getMap(p.getTileX(), p.getTileY() -1).equals("w")){
           if(keycode == KeyEvent.VK_W) {
               p.move(0, -1);
               }
           }
          
           if(!m.getMap(p.getTileX(), p.getTileY() +1).equals("w")) {
             if(keycode == KeyEvent.VK_S) {
                p.move(0, 1);
                       }
           }
            
           if(!m.getMap(p.getTileX() - 1, p.getTileY() ).equals("w")) {
             if(keycode == KeyEvent.VK_A) {
               p.move( -1, 0); 
             }
           }
          
           if(!m.getMap(p.getTileX() + 1, p.getTileY() ).equals("w")) {
             if(keycode == KeyEvent.VK_D) {
                 p.move(1, 0);
             }
            
        }
        
    
        }
    }
}
 
X

Xknight

Code:
Exception in thread "main" java.lang.NullPointerException
    at MazeGameUI/de.uni_koblenz.ptsd.PAPA.mazegameui.Map.readFile(Map.java:60)
    at MazeGameUI/de.uni_koblenz.ptsd.PAPA.mazegameui.Map.<init>(Map.java:40)
    at MazeGameUI/de.uni_koblenz.ptsd.PAPA.mazegameui.Board.<init>(Board.java:21)
    at MazeGameUI/de.uni_koblenz.ptsd.PAPA.mazegameui.Maze.<init>(Maze.java:9)
    at MazeGameUI/de.uni_koblenz.ptsd.PAPA.mazegameui.Maze.main(Maze.java:16)

Bei Map in Zeile 60 wollte ich die txt Datei Map auslesen in dem Ordner things welches Im Ordner ptsd2020-papa//src-code//MazeGameUI//things befindet und habe es so angegeben. Sollte ich noch ganz am Anfang Desktop auch als Dateipfad angegebn, weil der Ordner ptsd2020-papa auf meinem Desktop befindet. Bei Map Zeile 40 wollte ich die Methode readFile ausführen. Bei Board zeile 21 habe ich eine new Map erzeugen wollen. Bei Maze Zeile 9 sollte die ganzen Methoden aus der Klasse Board ausgfeführt werden. Bei Maze Zeile 16 sollte das Spiel gestartet werden.
 
J

JustNobody

Dann ist das doch die Bestätigung: Wenn der Ordner nicht auf c:\ liegt sondern auf dem Desktop, dann musst Du den Pfad auch entsprechend angeben.

Wobei Du Dich auch evtl. mit Ressourcen beschäftigen solltest. Dann liegen die Dateien in einem Order. Je nach IDE / Build Tool kann es unterschiedlich sein. Und dann gibst Du die Dateien nicht mehr als kompletten Pfad an sondern lädst die Ressourcen über den ClassLoader bzw. die Class. getResourceAsStream(...) wäre z.B. der Aufruf für einen InputStream.

Dann wäre das z.B. ein
sc = new Scanner(Map.class.getResourceAsStream("/Map.txt"));
(So die Map.txt direkt im resource Ordner liegen sollte.)
 
X

Xknight

Das heißt, dass durch die Methode get.ResourceAsStream ein InputStream erzeugt wird, welches die Datei dann ausliest. Aber die Map.txt Datei liegt in dem Ordner things welches im Ordner MazeGameUI befindet. Und der MazeGameUI Ordner ist im Ordner src-code drin, welches im Ordner ptsd2020-papa ist. Müsste ich dann diesen Pfad am Ende des Aufrufes getResourceAsStream nicht noch angeben?
 
J

JustNobody

Das ist ein Thema, das Du dir erarbeiten musst. Ich habe keine Ahnung, mit welchen Tools Du arbeitest oder nicht. Die Ressourcen liegen dann in einem klar definierten Ordner des Projekts und nicht einfach auf dem Desktop oder so.

Bei Gradle und Maven ist es üblich, eine Verzeichnisstruktur zu haben mit src/main/java und src/main/resources bzw src/test/java und src/test/resources für DInge, die zu den Unit-Tests gehören.
Eclipse 08/15 Projekte unterscheiden da nicht. Da gibt es in der Regel einen Ordner src, in das man einfach alles rein schmeisst.
...

Der wichtige Punkt dabei ist aber immer: Man hat eine Ordnerstruktur für das Projekt und da spielt es dann auch keine Rolle, wo der Projektordner liegt. Das Projekt kann unter Documents, auf dem Desktop in c:\projects oder sonst wo liegen...

Das Thema kannst Du angehen und ich würde es Dir empfehlen. Aber natürlich kannst Du auch erst einmal mit kompletten, festen Pfaden arbeiten.
Da wäre aber dann mein Tipp: Prüfe die Pfade! Du kannst z.B. mit der Maus einen Ordner oder eine Datei aus dem Explorer in die Eingabeaufforderung ziehen und schon hast Du den genauen Pfad. Damit vermeidest Du so Probleme bei der Pfadangabe.
 
X

Xknight

Danke für deine Tips. Dann muss ich mir das noch erarbeiten. Aber wie kann ich eine Datei aus meinem Explorer in die Eingabeaufforderung ziehen?
 
J

JustNobody

Per drag and drop. Öffne beide Fenster, dann click eine Datei oder Ordner an und zieh sie auf das Eingabeaufforderung-Fenster.

Dann erscheint der Pfad der Datei sozusagen als Eingabe.
 
MoxxiManagarm

MoxxiManagarm

Aus meiner Sicht ist das Problem dieses Stück Code

Java:
   public void readFile() {
        while(sc.hasNext()) {
            for(int i = 0; i<14; i++) {
                Map[i] = sc.next();
            }
        }
    }
1. Du fragst den Scanner erst ob 1 ein next hat, verwendest aber 14 mal next. Der Scanner rutscht mit jedem next um ein token weiter. Nach der. 0. Iteration innerhalb der for-Schleife ist nicht mehr sichergestellt, dass der Scanner ein next hat
2. Dein String-Array "Map" heißt genauso wie deine Klasse "Map". Bitte benenne Attribute immer im lowerCamelCase.
3. Es ist hier nicht sichergestellt, dass "sc" überhaupt initialisiert ist.
 
X

Xknight

Du meinst, ich soll den scanner initialisieren und den String Array neu bennen, wenn ich es richtig verstanden habe. Aber am Anfang der Klasse habe ich doch den Scanner definiert.
 
mihe7

mihe7

Es geht einfach darum, dass Du in der Methode nicht sicher weißt, ob sc wirklich nicht null ist. In Java gibt es übrigens Benennungskonventionen, an die man sich halten sollte: Variablen schreibt man in lowerCamelCase, Typnamen in UpperCamelCase.

Ich würde die Klasse auch nicht Map benennen, aus dem einfachen Grund, dass Java bereits eine Klasse mit diesem Namen kennt (java.util.Map) -> MazeMap oder ähnliches.

Dann könnte man noch über das Design sprechen. Was ist die Aufgabe von (Maze)Map? Macht die Klasse evtl. zu viel? Warum sind dort Bilder enthalten? Warum ist das Einlesen enthalten?
 
X

Xknight

Die Aufgabe von der Klasse (Maze)Map ist es durch das Einlesen der Bilder ein Labyrinth in die Textdatei Map abzubilden. Und auf die Frage, ob die Klasse eventuell zu viel macht, dass weiß ich von meiner Seite aus nicht.
 
mihe7

mihe7

Die Aufgabe von der Klasse (Maze)Map ist es durch das Einlesen der Bilder ein Labyrinth in die Textdatei Map abzubilden.
OK, dann zwei weitere Fragen:

1. Wozu hast Du dann eine Methode getMap, die einen String zurückgibt, wenn Du Bilder haben willst?
2. Muss das Einlesen denn in dieser Klasse erledigt werden?

Zu 2.: Du beschreibst zwei Aufgaben. Einmal das Einlesen und einmal das Abbilden.
 
Thema: 

Programmieren eines Spieles

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben