Wie man einfache Spiele programmieren kann

mihe7

mihe7

Top Contributor
Zur Abwechslung mal einen

BUG-REPORT

Beim Testen mit z. B. Test3 fällt auf, dass es beim Erreichen des Ziels eine NullPointerException gibt. Grund ist, dass in Methode movePlayer der Klasse MazeGame nicht geprüft wird, ob überhaupt ein Observer registriert wurde.

Den Fehler bitte beheben. Das Ende der Methode movePlayer in MazeGame bitte so abändern:

Java:
        if (observer != null && isWin()) {
            observer.gameOver();
        }
 
mihe7

mihe7

Top Contributor
Allmählich wird es Zeit, eine "fertige" Anwendung zu bauen.

Zuvor kümmern wir uns aber noch um das Problem, dass das Spiel unzulässige Züge ermöglicht. Das lässt sich strukturell lösen, indem wir bei der Bewegung nur noch eine Richtungsangabe zulassen. Da sich der Spieler nur in eine der vier Himmelsrichtungen bewegen können soll, führen wir für diese eine Aufzählung ein.

Java:
enum Direction { 
    NORTH(0,-1), EAST(1,0), SOUTH(0,1), WEST(-1,0);

    private int dx;
    private int dy;

    Direction(int dx, int dy) {
        this.dx = dx;
        this.dy = dy;
    }

    public Position move(Position pos) {
        return pos.move(dx, dy);
    }
}

Die movePlayer-Methoden in MazeGame und MazeWorld können nun als Parameter eine Direction statt zweier int-Werte erhalten. Direction enthält auch eine move-Methode, die eine neue in die jeweilige Richtung verschobene Position zurückgibt. Damit werden die int-Werte vollständig gekapselt, der Rest der Anwendung kann diese nicht einmal mehr sehen. Cool, oder?

In MazeWorld muss dann lediglich noch die neue Position über die Richtung bestimmt werden:
Java:
    public void movePlayer(Direction dir) {
        Position newPos = dir.move(player);
        if (isLegalMove(newPos)) {
            Position oldPos = player;
            player = newPos;
            movedFrom(oldPos);
        }
    }

Nochmal zur Verdeutlichung: wir haben eben ein logisches Problem durch die Einführung eines Datentyps gelöst. Es ist nun praktisch unmöglich, dass der Spieler eine unzulässige Bewegung durchführen kann, denn jetzt haben wir den Compiler auf unserer Seite, der bereits zur Übersetzungszeit falsche Angaben verhindert. Natürlich könnte die Methode movePlayer noch null als Richtungsangabe erhalten, was zur Laufzeit aber zu einer NullPointerException führen würde. Der Zug würde also nicht ausgeführt.

Natürlich müssen wir jetzt die Klassen, die movePlayer aufrufen, entsprechend anpassen. Details bzgl. der bestehenden "Testklassen" finden sich im Repository. Hier möchte ich nur den KeyboardController zeigen:

Java:
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Map;
import java.util.HashMap;

public class KeyboardController extends KeyAdapter {
    private static final Map<Integer, Direction> KEY_MAPPING =
            new HashMap<>();
    static {
        KEY_MAPPING.put(KeyEvent.VK_LEFT, Direction.WEST);
        KEY_MAPPING.put(KeyEvent.VK_RIGHT, Direction.EAST);
        KEY_MAPPING.put(KeyEvent.VK_UP, Direction.NORTH);
        KEY_MAPPING.put(KeyEvent.VK_DOWN, Direction.SOUTH);
    }

    private final MazeGame game;

    public KeyboardController(MazeGame game) {
        this.game = game;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        Direction dir = KEY_MAPPING.get(e.getKeyCode());
        if (dir != null) {
            game.movePlayer(dir);
        }
    }
}

Damit haben wir switch gekillt. Wer sich fragt, was das bringen soll: die Einträge einer Map sind zur Laufzeit änderbar. D. h. theoretisch ließe sich mit ein paar Änderungen eine konfigurierbare Tastaturbelegung erreichen...
 
mihe7

mihe7

Top Contributor
Was noch fehlt, ist das Laden eines Labyrinths aus einer Datei, die der Anwender wählt. Viele Beispiele sind derart gestrickt, dass einfach in einem ActionListener - in der Regel implementiert als anonyme innere Klasse - ein JFileChooser verwendet wird und dort auch alles andere zu finden ist.

Das kann man durchaus machen und der Ansatz hat den Vorteil, dass er sehr einfach zu verstehen ist: Datei auswählen, einlesen, fertig. Die bisherige Methode createWorld derart umzuschreiben ist fast trivial, so dass ich mir den Code dazu spare. Vielmehr möchte ich etwas over-engineering betreiben, um einen anspruchsvolleren Weg zu gehen, der für ähnliche aber ggf. komplexere Probleme eingeschlagen werden kann.

Egal welchen Ansatz man wählt, müssen wir uns zunächst um etwas anderes kümmern: wir haben ein Format für das Labyrinth, nicht aber für die Spielwelt definiert. Das Problem dabei ist, dass wir den Startpunkt des Spielers nicht kennen, so dass dieser in createWorld fest auf (4,4) gesetzt wurde. Das funktioniert natürlich bei beliebigen Labyrinthen nicht mehr.

Die Frage ist jetzt, ob der Startpunkt geladen oder zufällig gewählt werden soll. Für das Laden könnte man unter Zuhilfenahme von MazeTextFormat ein eigenes MazeWorldTextFormat definieren. Dabei könnte die Datei einfach mit der Spielerposition beginnen. Das ist auch nicht viel mehr Aufwand als das, was wir umsetzen wollen: den Spieler zufällig positionieren.

Nachdem das geklärt ist, fangen wir mal mit dem over-engineering an :) Dazu müssen wir uns klarmachen, dass beim Laden verschiedene Dinge zusammenkommen.
  1. Eine Aktion des Benutzers, die an verschiedenen Stellen im Programm (z. B. Menü und Toolbar) auftreten kann
  2. Die Auswahl einer Datei durch den Benutzer
  3. Das Einlesen der Datei in ein Objekt (hier: Maze)
  4. Im Erfolgsfall: das Verwenden des eingelesenen Objekts in einer von der Anwendung definierten Art und Weise
  5. Im Fehlerfall: die Behandlung des Fehlers in einer von der Anwendung definierten Art und Weise

Sehr viel Verantwortung für eine einzige Klasse. Dabei sind die einzelnen Punkte scharf voneinander abgrenzbar und müssen lediglich passend entkoppelt werden. Wie das funktioniert, haben wir schon mehrfach gesehen: eigene Klassen und Schnittstellen definieren.

Die ersten beiden Punkte betreffen ausschließlich die Oberfläche, die vom Einlesen selbst in keinster Weise berührt wird. Die letzten Punkte sind nicht ganz so einfach: die Unterscheidung nach Erfolgs- und Fehlerfall hat mit der Oberfläche nichts zu tun - die Behandlung der Fälle kann dagegen das UI betreffen. Eben diese Behanldung muss aber nicht in der Aktion selbst stattfinden.

Konkret: man könnte nach dem JFileChooser versuchen, die Datei einzulesen, und im Falle eines Fehlers ein Dialogfenster anzeigen. Was aber, wenn die Anwendung an der Stelle gar kein Dialogfenster sondern ein TransparentPanel anzeigen will? Noch schlimmer: was, wenn beim Aufruf über das Menü ein Dialogfenster, beim Aufruf über die Toolbar dagegen ein TransparentPanel angezeigt werden soll? Und für den Erfolgsfall: wer sagt denn, dass nach dem Laden eines Labyrinths immer dasselbe passieren muss?

Um noch eins draufzusetzen, muss die Datei denn immer vom Anwender mit einem JFileChooser gewählt werden? Wohl kaum.

Der langen Rede kurzer Sinn: wir erstellen uns ein "Lademodul", das nur die Aufgabe hat, beim Einlesen Erfolgs- und Fehlerfall zur Behandlung an entsprechende Objekte weiterzuleiten.

Java:
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class MazeLoader {
    private static final MazeTextFormat FORMAT = new MazeTextFormat();

    private MazeHolder holder;
    private ExceptionHandler exceptionHandler;

    public void setMazeHolder(MazeHolder holder) {
        this.holder = holder;
    }

    public void setExceptionHandler(ExceptionHandler handler) {
        exceptionHandler = handler;
    }

    public void load(File file) {
        try(FileReader reader = new FileReader(file)) {
            Maze maze = FORMAT.read(reader);
            if (holder != null) {
                holder.setMaze(maze);
            }
        } catch (IllegalArgumentException | IOException ex) {
            if (exceptionHandler != null) {
                exceptionHandler.handleException(ex);
            } else {
                ex.printStackTrace();
            }
        }
    }
}

Dabei sind MazeHolder und ExceptionHandler zwei Interfaces, die jeweils die betreffende Methode enthalten. Die Benutzeraktion lagern wir ebenfalls in eine Klasse aus, die mit einem "Lademodul" arbeiten kann:

Java:
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import java.io.File;

import javax.swing.Action;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;

public class LoadMazeAction extends AbstractAction {
    private final MazeLoader loader;
    private final JFileChooser chooser;

    public LoadMazeAction(MazeLoader loader) {
        super("Labyrinth laden...");
        this.loader = loader;

        putValue(Action.MNEMONIC_KEY, KeyEvent.VK_L);
        putValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY, 10);

        chooser = new JFileChooser();
        chooser.setAcceptAllFileFilterUsed(true);
        chooser.addChoosableFileFilter(new FileNameExtensionFilter(
                "Maze Text File", "mtf"));
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        File mazeFile = selectFile(getWindow(e));
        if (mazeFile != null) {
            return;
        }
        loader.load(mazeFile);
    }

    private File selectFile(Window parent) {
        int result = chooser.showOpenDialog(parent);
        if (result == JFileChooser.APPROVE_OPTION) {
            return chooser.getSelectedFile();
        }
        return null;
    }

    private Window getWindow(ActionEvent e) {
        Object src = e.getSource();
        if (src instanceof JComponent) {
            return SwingUtilities.getWindowAncestor((JComponent) src);
        }
        return null;
    }
}

Die Klasse implementiert nicht ActionListener sondern erweitert AbstractAction, eine Swing-Klasse, die es ermöglicht, eine Aktion anwendungsweit zu de-/aktivieren, wobei die Steuerelemente entsprechend reagieren. D. h. man kann eine Aktion für mehrere Steuerelemente verwenden und diese werden "ausgegraut", sobald man die Aktion deaktiviert. Auf diese Möglichkeit wollte ich durch die Verwendung von AbstractAction nur einmal hinweisen.

Viel interessanter ist aber, dass die Aktion nur das Lademodul kennen muss und keine Ahnung davon hat, was mit der gewählten Datei passiert. Schon gar nicht, was nach dem Einlesen mit den Daten geschieht. Auf diese Weise haben wir eine vollständige Entkopplung von Aktion, Ausgabe (UI) und Verarbeitung erreicht.

Wir könnten den Code nun in eine weitere Testklasse einbauen, jedoch würde das bereits sehr unübersichtlich werden. Wir brauchen immerhin eine Implementierung für das Exception-Handling sowie für die Verarbeitung des geladenen Labyrinths. Da muss ein wenig Struktur rein. Die folgt im nächsten Kommentar; der Code findet sich bis dahin nicht im Repository.
 
mihe7

mihe7

Top Contributor
Zunächst werden wir den bisherigen Code ein wenig verbessern. Würde man z. B. nicht nach jeder "Runde" eine neue MazeGame-Instanz erstellen sondern einfach die MazeWorld austauschen, müsste man diverse Listener nur einmal erstellen und registrieren. Der GameStateObserver könnte dann auch diese Änderung beobachten, eine mögliche Implementierung:

Java:
    private final GameStateObserver gameStateHandler = new GameStateObserver() {
        @Override
        public void gameOver() {
            winnerMessage.show();
        }
        @Override
        public void worldChanged(MazeWorld newWorld) {
            worldView.changeWorld(newWorld);
        }
    };
In App6.java muss der Observer an die geänderte Schnittstelle angepasst werden. Ebenso muss MazeGame über das betreffende Ereignis informieren, sprich die worldChanged-Methode aufrufen. Beides ist trivial, so dass ich den Code hier nicht zeige (im Repository ist der Code natürlich geändert).

Als nächstes gliedern wir das UI aus der Anwendungsklasse aus - wir erstellen eine Klasse für das "Hauptfenster". Dieses bekommt auch gleich eine Menüzeile spendiert, um ein anderes Labyrinth zu laden. In Verbindung mit LoadMazeAction und dem MazeLoader könnte der Code dann wie folgt aussehen:

Java:
import javax.swing.*;

public class MainWindow {

    private final MazeGame game;
    private final LoadMazeAction loadMazeAction;

    private JFrame frame;
    private MessageOverlay winnerMessage;
    private final WorldView worldView;

    private final GameStateObserver gameStateHandler = new GameStateObserver() {
        @Override
        public void gameOver() {
            winnerMessage.show();
        }
        @Override
        public void worldChanged(MazeWorld newWorld) {
            worldView.changeWorld(newWorld);
            frame.pack();
        }
    };

    public MainWindow(MazeGame game, MazeLoader loader) {
        this.game = game;
        game.setObserver(gameStateHandler);
        loadMazeAction = new LoadMazeAction(loader);

        worldView = new WorldView(game.getWorld(), 32, 32);
        WorldViewDefaults.configure(worldView);
        worldView.setFocusable(true);
        worldView.addKeyListener(new KeyboardController(game));
    }

    public void show() {
        frame = new JFrame("maze");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setJMenuBar(createMenuBar());
        frame.add(worldView);
        frame.pack();
        frame.setVisible(true);

        initWinnerMessage(frame);
    }

    private JMenuBar createMenuBar() {
        JMenuItem loadMazeItem = new JMenuItem(loadMazeAction);
        JMenuItem exitItem = new JMenuItem("Beenden");
        exitItem.setMnemonic('e');
        exitItem.addActionListener(e -> System.exit(0));
        JMenu gameMenu = new JMenu("Spiel");
        gameMenu.setMnemonic('S');
        gameMenu.add(loadMazeItem);
        gameMenu.addSeparator();
        gameMenu.add(exitItem);

        JMenuBar menuBar = new JMenuBar();
        menuBar.add(gameMenu);
        return menuBar;
    }

    private void initWinnerMessage(JFrame frame) {
        String message = "<html><h1 style=\"text-align: center;\">Gewonnen!</h1>" +
            "<p>Weiter mit der Leertaste.</p>";

        winnerMessage = new MessageOverlay(frame)
                .display(message);
    }
}

Das sieht doch schon wesentlich aufgeräumter aus. Man beachte, dass hier ausschließlich Themen des UIs behandelt werden. Das Spiel und das Lademodul kommen von außen, woher interessiert das UI nicht. Somit könnten wir z. B. eine von MazeGame abgeleitete Klasse mit anderen Spielregeln verwenden, ohne am UI auch nur eine Zeile ändern zu müssen. Vorstellbar wäre beispielsweise, dass es "Teleporter"-Felder gibt, die den Spieler auf ein anderes freies, zufällig gewähltes Feld "beamen".

Das Lademodul (MazeLoader) kümmert sich nur um das Labyrinth, für das Spiel müssen wir aber eine Spielwelt erstellen.

Java:
import java.io.IOException;
import java.io.StringReader;
import java.io.UncheckedIOException;

import java.util.ArrayList;
import java.util.List;

public class MazeWorldFactory {

    public MazeWorld createInitialWorld() {
        String text = "f";
             
        MazeTextFormat fmt = new MazeTextFormat();
        try {
            Maze maze = fmt.read(new StringReader(text));
            return new MazeWorld(maze, new Position(0, 0));
        } catch (IOException ex) {
            throw new UncheckedIOException(ex);
        }
    }

    public MazeWorld createWorld(Maze maze) {
        Position pos = determineStartPosition(maze);
        if (pos == null) {
            return createInitialWorld(); 
        }
        return new MazeWorld(maze, pos);
    }

    private Position determineStartPosition(Maze maze) {
        List<Position> free = new ArrayList<>();
        for (int y = 0, height = maze.getHeight(); y < height; y++) {
            for (int x = 0, width = maze.getWidth(); x < width; x++) {
                if (maze.get(x,y) == FieldType.DESERT) {
                    free.add(new Position(x,y));
                }
            }
        }

        if (free.isEmpty()) {
            return null;
        }
        return free.get((int)(Math.random() * free.size()));
    }
}

Die Anwendung hält den Spaß letztlich zusammen:
Java:
import javax.swing.SwingUtilities;

public class App {

    private final MazeGame game;
    private final MazeWorldFactory factory;

    public App() {
        factory = new MazeWorldFactory();
        game = new MazeGame(factory.createInitialWorld());
    }

    public void run() {
        MazeLoader loader = new MazeLoader();
        loader.setMazeHolder(maze -> game.setWorld(factory.createWorld(maze)));
        new MainWindow(game, loader).show();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new App().run());
    }
}

Im Repository finden sich unter maze-samples auch Beispiele für Labyrinthe.

Damit soll das Ganze an der Stelle auch im Wesentlichen ein Ende finden, auch wenn das Spiel nicht fertig ist. Es wird nicht alles 100 %-ig funktionieren, z. B. müsste die Glasspane Tastatur- und Mausereignisse abfangen. Darum ging es hier aber nie, vielmehr sollte ein Ansatz skizziert werden, welche Überlegungen angestellt werden usw. Aus dem Grund sind einige Dinge für ein so kleines Projekt auch etwas übertrieben, auf der anderen Seite fehlt z. B. die Strukturierung des Quellcodes mit Paketen. Evtl. hole ich das später einmal nach.

Kritik und Fragen einfach posten.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
K Einfache Engine für einfaches 3D gesucht Spiele- und Multimedia-Programmierung 10
Taschentuch9 Einfache fertige Schach AI gesucht Spiele- und Multimedia-Programmierung 3
D einfache 2D Grafik in JAVA. absoluter Anfänger Spiele- und Multimedia-Programmierung 5
D Einfache Physik (Beschleunigung) Spiele- und Multimedia-Programmierung 6
B Einfache Animationen darstellen Spiele- und Multimedia-Programmierung 12
N Spiele-Menü in Java Spiele- und Multimedia-Programmierung 9
T Neuronale Netze und Spiele Spiele- und Multimedia-Programmierung 4
H KI für Spiele Spiele- und Multimedia-Programmierung 1
H 3D Spiele mit Java - Diskussion Spiele- und Multimedia-Programmierung 35
D 2d Spiele Bibliothek Spiele- und Multimedia-Programmierung 9
M Spiele Tutorial.. Findet Bilddateien nicht Spiele- und Multimedia-Programmierung 6
K Casino Spiele UI Spiele- und Multimedia-Programmierung 7
J 2D Spiele - Inwiefern Vektorrechnung nötig? Spiele- und Multimedia-Programmierung 7
S Aufbau für 2D Spiele Spiele- und Multimedia-Programmierung 7
A Drawable und Moveable in Quaxli 2D Spiele Tutorial Spiele- und Multimedia-Programmierung 7
Gossi Probleme beim Laden der Images aus dem "Tutorial für Java-Spiele" Spiele- und Multimedia-Programmierung 4
X Gutes 2D Spiele Tutorial? Spiele- und Multimedia-Programmierung 9
B Spiele Tutorials Spiele- und Multimedia-Programmierung 9
F wie richtig spiele programmieren ? Spiele- und Multimedia-Programmierung 19
C Java für große Spiele geeignet ? Spiele- und Multimedia-Programmierung 101
B Spiele programmieren für ein Fenster? Spiele- und Multimedia-Programmierung 14
V Online-Spiele syncronisieren. Spiele- und Multimedia-Programmierung 5
L 2D-Spiele ruckeln auf JPanel Spiele- und Multimedia-Programmierung 7
J Suche Java Spiele Editor! Spiele- und Multimedia-Programmierung 2
Developer_X Java3D-Ungeeignet für 3D Spiele wegen Heap Space=? Spiele- und Multimedia-Programmierung 23
D Spiele Wuerfel 3D aber wie Spiele- und Multimedia-Programmierung 6
D Problem mit dem Spiele TUT Spiele- und Multimedia-Programmierung 16
H 2d- Spiele Entwicklung Spiele- und Multimedia-Programmierung 11
D sehr simple Java Spiele Platformübergreifend für Handys/PDAs Spiele- und Multimedia-Programmierung 3
Quaxli Welche Grafiksoftware nutzt Ihr für 2D-Spiele? Spiele- und Multimedia-Programmierung 6
D Welcher Image Typ am besten für 2D-Spiele geeignet? Spiele- und Multimedia-Programmierung 5
X JPCT 3d-Spiele Programmierung Tutorial Spiele- und Multimedia-Programmierung 40
X 3D Spiele Tutorial gewünscht? Spiele- und Multimedia-Programmierung 14
G Bekannte Spiele in Java programmiert Spiele- und Multimedia-Programmierung 9
R Spiele für den DVD Player Spiele- und Multimedia-Programmierung 6
F 2d Spiele Spiele- und Multimedia-Programmierung 4
J soundlösung zu langsam für spiele Spiele- und Multimedia-Programmierung 16
T Größeres Spiele Projekt - einige Fragen zur Umsetzung Spiele- und Multimedia-Programmierung 3
O soundlösung für spiele (mit lautstärke) Spiele- und Multimedia-Programmierung 4
Landei Entwicklungsumgebung für "Pseudo-3D"-Spiele? Spiele- und Multimedia-Programmierung 17
A Spiele kommentieren Spiele- und Multimedia-Programmierung 4
M Images/Sounds für Spiele Spiele- und Multimedia-Programmierung 3
A Werden "große Spiele" mal in Java programmiert? Spiele- und Multimedia-Programmierung 43
H Große Spiele in welcher Sprache Spiele- und Multimedia-Programmierung 33
R eure programmierten Spiele Spiele- und Multimedia-Programmierung 53
M Brauche Hilfe was zu Programmieren Spiele- und Multimedia-Programmierung 4
N Minecraft Spigot-Plugin | Schusswaffe programmieren Spiele- und Multimedia-Programmierung 3
A Programmieren eines Memorys mit Java (in Eclipse) Spiele- und Multimedia-Programmierung 5
A DoodleJump programmieren: Kollisionsabfrage Spiele- und Multimedia-Programmierung 6
I Vier gewinnt programmieren, Klick-Reihenfolge Spiele- und Multimedia-Programmierung 2
B Programmieren wie der Befehl /ban in Minecraft geblockt wird aber nicht /ban mit einem Argument Spiele- und Multimedia-Programmierung 1
K Android Spiel Programmieren Spiele- und Multimedia-Programmierung 6
P Tennis- Spielstand- Zähler für Schule programmieren Spiele- und Multimedia-Programmierung 6
J HDMI Ausgänge mit Java programmieren? Spiele- und Multimedia-Programmierung 18
L Hörtest programmieren und implementieren Spiele- und Multimedia-Programmierung 2
E Möchte Jump and Run programmieren Spiele- und Multimedia-Programmierung 2
E Möchte Spiel Programmieren Spiele- und Multimedia-Programmierung 7
M Gesellschaftsspiel Mühle in Java programmieren Spiele- und Multimedia-Programmierung 3
M Textbasiertes Spiel programmieren Spiele- und Multimedia-Programmierung 4
M Logitech G15/G510 Applets programmieren Spiele- und Multimedia-Programmierung 3
F Spiel ähnlich wie SimCity/o.ä programmieren Spiele- und Multimedia-Programmierung 5
O Rundenbasiertes strategiespiel programmieren Spiele- und Multimedia-Programmierung 2
K 2D Blockade Programmieren Spiele- und Multimedia-Programmierung 3
wolfgang63 Mit JavaFX einfaches Game programmieren Spiele- und Multimedia-Programmierung 5
J Mod Loader programmieren Spiele- und Multimedia-Programmierung 11
I Hitpoints/Lifepoints programmieren, wie? Spiele- und Multimedia-Programmierung 7
B Spiel Programmieren, die Anfänge Spiele- und Multimedia-Programmierung 6
wolfgang63 Einfachen Soundgenerator programmieren Spiele- und Multimedia-Programmierung 1
J UNO Programmieren Spiele- und Multimedia-Programmierung 4
F Bot Programmieren Spiele- und Multimedia-Programmierung 10
N Game GUI Programmieren Spiele- und Multimedia-Programmierung 16
T MiniCraft - selbst nach Programmieren Spiele- und Multimedia-Programmierung 25
A Klickgame ala "Harveys neue Augen" oder "Edna bricht aus" in Java programmieren... Fragen zu Kleinig Spiele- und Multimedia-Programmierung 8
S Spiel Programmieren (Kreise treffen) Spiele- und Multimedia-Programmierung 5
C Hinterteil von Snake programmieren Spiele- und Multimedia-Programmierung 11
B Kartenspiel Leben und Tod programmieren Spiele- und Multimedia-Programmierung 11
T Vier gewinnt programmieren Spiele- und Multimedia-Programmierung 9
N Stimme programmieren Spiele- und Multimedia-Programmierung 11
Sebi Mit Java Online games programmieren ? Spiele- und Multimedia-Programmierung 8
N Labyrinth programmieren/Denkhilfe Spiele- und Multimedia-Programmierung 3
data89 Spiel mit JMonkey programmieren Spiele- und Multimedia-Programmierung 6
O Programmieren von "Familienduell" Spiele- und Multimedia-Programmierung 3
A Wie JAVA Webcam Client programmieren? Spiele- und Multimedia-Programmierung 11
T vier gewinnt programmieren - aber wie Spiele- und Multimedia-Programmierung 19
N In einem Kasten springende Bälle programmieren...Hilfe Spiele- und Multimedia-Programmierung 7
B Problem beim Programmieren von 4Gewinnt Spiele- und Multimedia-Programmierung 5
A Programmieren eines Bruchrechners Spiele- und Multimedia-Programmierung 3
K Malefiz programmieren - Frage zu den einzelnen Spielfeldern Spiele- und Multimedia-Programmierung 5
G wer möchte mit mir risiko programmieren? Spiele- und Multimedia-Programmierung 7
B Problem beim Programmieren Von Mühle Spiele- und Multimedia-Programmierung 6
N Sinus Welle programmieren! Spiele- und Multimedia-Programmierung 4
J Gesellschaftsspiele programmieren Spiele- und Multimedia-Programmierung 8
P 2D Spiel mir drehbaren Bildern (Sprites) programmieren Spiele- und Multimedia-Programmierung 10
U Ball programmieren Spiele- und Multimedia-Programmierung 26
A "Wegnehm-Spiel" programmieren, Tipps + Links? Spiele- und Multimedia-Programmierung 8

Ähnliche Java Themen

Anzeige

Neue Themen


Oben