LayoutManager RPG Programmieren, eigenes Spielfeld grafisch generieren aus Tileset

Hag2bard

Bekanntes Mitglied
Hallo,
ich möchte für ein Spiel ein Raster haben, dass pro Zelle immer 16x16 Pixel haben soll. In den einzelnen Zellen möchte ich ebenso große Bilder einfügen, so dass sich ein Gesamtbild daraus zusammen setzt.
Das ist zumindest meine Idee, wie ich in einem RPG Spiel variable Maps generieren kann.

POKEMON_ROT_IMG_06.jpg

Dieses Spiel setzt sich (ist in Assembler geschrieben) aus verschiedenen Tiles aus einem Tileset zusammen. Ich habe ein TileSet und möchte das Spielfeld zusammensetzen.
Meine erste Idee war es eine Art Layout zu erstellen, welches ein Raster erstellt. Meinetwegen erstmal in einer Größe von 10x10 Zellen. (In Pokemon wird es Blöcke genannt) oder in Pixel 160x160.

Wie mach ich sowas?
 

Anhänge

  • tileset-advance.png
    tileset-advance.png
    207,3 KB · Aufrufe: 2
K

kneitzel

Gast
Ich würde die Frage einfach umgedreht zurück geben und fragen: Wo ist denn im Augenblick dein Problem?

Hast Du Dich schon etwas damit auseinander gesetzt, wie Du Bilder laden, erzeugen, ändern kannst? Da gibt es sehr viel online zu, daher würde ich da nicht tief drauf eingehen. Eine mögliche Basis ist BufferedImage.

Um ein solches Image zu verändern, kann man sich ein Graphics2D Objekt erstellen:

Mit der Methode drawImage lässt sich dann ein Bild in ein anderes einfügen. Wenn Du alle Tiles in einem Bild hast, dann wäre diese Methode vermutlich die, die Du brauchst:
Es wird dann sowohl ein Zielbereich als auch ein Source Bereich angegeben. (Sprich: Du musst wissen, in welchem Bereich Deine Tile ist, aber das ist ja klar denke ich mal.)

Bleibt nur noch die Funktionalität: Laden eines Bildes. Das kann z.B. mittels ImageIO erfolgen:
 

Hag2bard

Bekanntes Mitglied
Mit den Links kann ich leider nichts anfangen. Ich weiß noch garnicht wie ich mein Problem aufteilen soll.
Ich glaube ich hab mich da auch sehr ungünstig ausgedrückt.

Nochmal zur Wiederholung. Ich möchte in JavaFX ein Bild auf dem Bildschirm generieren, dass aus anderen kleinen Bildchen zusammengesetzt wird.
Dafür habe ich ein Tileset von einem Pokemon Spiel.

Ich habe hier im Prinzip 2 Hauptprobleme:

- Definierte Bereiche aus einem Bild nutzen und
- Ein Bild aus mehreren kleinen Bildern zusammen setzen (am besten diese Bereiche)

Um mal ganz klein anzufangen möchte ich:

Ein Bild mit der Größe 32x32 Pixel erstellen.
Auf dieses Bild soll an Stelle 0,0 ein Bild mit 16x16 Pixel
An Stelle 0,16 ein Bild mit 16 Pixel
An Stelle 16,0 ein Bild mit 16 Pixel
An Stelle 16,16 ein Bild mit 16 Pixel

So habe ich ein Bild mit 4 Zellen.

Das wäre erstmal das erste Problem was ich klären wollen würde.

Also habe ich als erstes die Stage.
Dieser übergebe ich eine Scene.
Dieser übergebe ich ein Layout (z.b. HBox)

Und zum Layout müsste ich dann 4 Bilder hinzufügen und diese auf der Scene positionieren.
Ein Bild bekomme ich hinzugefügt

Java:
        Image image = new Image("test.png");   // Hier erstelle ich ein Image-Objekt und übergebe dem Konstruktor ein Bild
        height = image.getHeight();               //
        width = image.getWidth();                 //Hier hole ich die Größe des Bildes
        System.out.println("Höhe: " + height);    // Und gebe Sie hier aus
        System.out.println("Breite: " + width);
        ImageView imgView = new ImageView();      //Hier erstelle ich ein ImageView-Objekt
        imgView.setImage(image);                  //Hier setze ich das Image-Objekt in das ImageView-Objekt

        Rectangle2D viewportRect = new Rectangle2D(0, 0, width, height/2); //v=x v1=y v2=Breite v3=Höhe  Hier erstelle ich ein Viereck mit den Maßen
                                                                                //des Bildes und der Position 0,0
                                                                                //v = Bild nach links verschieben mit +
                                                                                //v1 = Bild nach oben verschieben mit +

        imgView.setViewport(viewportRect);                                      //Keine Ahnung was hier gemacht wird

  HBox box = new HBox();                                                  //Hier nutze ich das HBox Layout
        box.setPrefSize(400,100);                                        //und setze die Größe auf 400x100
        box.getChildren().add(imgView);                                         //Das Imageview-Objekt wird dem Layout hinzugefügt

Bei mir hapert es schon dabei die Bilder zu positionieren
Wenn ich ein zweites ImageView erstelle, also so hier:

Java:
        ImageView imgView2 = new ImageView();
        imgView2.setImage(image);
        Rectangle2D viewportRect2 = new Rectangle2D(0,-height/2,width,height/2);
        imgView2.setViewport(viewportRect2);
        box.getChildren().add(imgView2);

Dann bekomme ich nur das erste Bild angezeigt
 

mihe7

Top Contributor
Vergiss mal JavaFX.

Ich habe hier im Prinzip 2 Hauptprobleme:

- Definierte Bereiche aus einem Bild nutzen und
- Ein Bild aus mehreren kleinen Bildern zusammen setzen (am besten diese Bereiche)

Du kannst aus einem BufferedImage via getSubimage(...) rechteckige Teilbilder erhalten.

Nehmen wir mal an, Du hast ein Tileset, das aus 6 x 4 Tiles der Größe 16x16 besteht. Dann hat jedes Tile eine Koordinate (tx,ty) wobei tx zwischen 0 und 5, ty zwischen 0 und 3 verläuft. Durch Multiplikation mit 16 erhältst Du die Pixelkoordinate.

Zum Zusammensetzen: Du holst Dir vom BufferedImage (Zielbild) den Graphics-Context und malst das Tile an die betreffende Koordinate mit drawImage.

Nachtrag:
Meine erste Idee war es eine Art Layout zu erstellen, welches ein Raster erstellt. Meinetwegen erstmal in einer Größe von 10x10 Zellen. (In Pokemon wird es Blöcke genannt) oder in Pixel 160x160.

Wie mach ich sowas?
Genau das wird im o. g. Link gemacht...
 

Hag2bard

Bekanntes Mitglied
Zum Testen habe ich erstmal folgendes gebaut:

Java:
        BufferedImage bufferedImage = new BufferedImage(300,450,BufferedImage.TYPE_INT_RGB);
        try {
            bufferedImage = ImageIO.read(new File("test.png"));
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }

Mit dem vorherigen Code konnte er auch auf die test.png zugreifen.
Nun sagt er allerdings

Code:
javax.imageio.IIOException: Can't read input file!
    at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1308)
    at pokemon.MainView.<init>(MainView.java:61)
    at pokemon.Main.start(Main.java:17)

Irgendwas stimmt hier nicht, kann das sein, dass das verbugt ist?
 

Hag2bard

Bekanntes Mitglied
Java:
package pokemon;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;

public class MainView2 {
    BufferedImage bufferedImage = null;


    public MainView2() {
        bufferedImage = new BufferedImage(300, 450, BufferedImage.TYPE_INT_RGB);
        try {
            bufferedImage = ImageIO.read(getClass().getResource("test.png"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

Ich habe versucht mit diesem Code ein Bild in ein BufferedImage zu laden.
Aber ich bekomme folgende Fehlermeldung:

Code:
Exception in thread "main" java.lang.IllegalArgumentException: input == null!
    at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1400)
    at pokemon.MainView2.<init>(MainView2.java:16)
    at pokemon.Main2.main(Main2.java:5)


Ist das BufferedImage wirklich sinnvoll? Das scheint Ausmaße anzunehmen, bevor man überhaupt mal ein Bild geladen bekommt, dass ich so langsam glaube, dass es evtl deprecated ist oder sonstiges.
Irgendwas stimmt damit nicht, wo liegt hier das Problem?
 
K

kneitzel

Gast
Das klingt danach, dass der Aufruf getClass().getResource("test.png") die Ressource nicht gefunden hat.

Wo liegt die Datei test.png? Sie muss in dem Ordner der Ressourcen sein (In eclipse ist das der src Ordner, bei Gradle/Maven wäre es src/main/resources) und dort innerhalb des Ordners pokemon.

(Wobei Code und Stacktrace nicht ganz passen - das ist ja nicht Zeile 16 sondern Zeile 14 - Du hast da also ggf. schon etwas geändert!)
 

Hag2bard

Bekanntes Mitglied
Das stimmt, ich hab den Code formatiert.
Meine test.png liegt hier:
C:\Users\dch\IdeaProjects\Pokemon\src\test.png

Der Sourcecode liegt hier
C:\Users\dch\IdeaProjects\Pokemon\src\pokemon\MainView2.java

OK verstehe, meine test.png muss ich

C:\Users\dch\IdeaProjects\Pokemon\src\pokemon\
 

Anhänge

  • 1633702166001.png
    1633702166001.png
    155,3 KB · Aufrufe: 1
K

kneitzel

Gast
Ja, du kannst das Bild verschieben. Oder Du passt die Angabe im Code an. wenn Du ein / voran stellst, dann würde es auch geladen.
 

Hag2bard

Bekanntes Mitglied
Ok ich habe jetzt hinbekommen das Bild zu laden und die Methode getSubimage() funktioniert auch.
Da ich heute leider krank bin, schaffe ich es nicht klar zu denken, aber der Rest sollte reine Logik sein.

Als nächstes werde ich mich damit beschäftigen, wie man ein Bild neu zusammen setzt.
 

Hag2bard

Bekanntes Mitglied
Hallo nochmal, ich bin schon für meinen Geschmack sehr erfolgreich gewesen.
Ich kann ein BufferedImage laden und es so zerstückeln, wie ich es gerne hätte. (Also ein Teil davon holen)
Nun habe ich also ein BufferedImage, mit einem Maß von 32x32 Pixel und möchte es in ein BufferedImage der Größe 64x64 zeichnen.
Die Methode paint() habe ich allerdings nicht gefunden.

Wie beschreibe ich mein "leeres" BufferedImage der Größe 64x64 mit dem kleinen?
 
K

kneitzel

Gast
Das Malen geht über eine Graphics / Graphics2D instanz. Und die bekommst Du per createGraphics() Aufruf.

Edit: Ist auch schon in meiner Antwort in #2 mit Links und so erläutert ...
 

mihe7

Top Contributor
Und noch ein Snippet:
Java:
Graphics2D g = img.createGraphics();
g.drawImage(upperLeftTile, 0, 0, null);
g.drawImage(upperRightTile, 32, 0, null);
g.drawImage(lowerLeftTile, 0, 32, null);
g.drawImage(lowerRightTile, 32, 32, null);
g.dispose();
sobei es sich bei den xxxTile-Variablen um BufferedImages der Größe 32 x 32 handeln sollte, img ist das Zielbild.
 
K

kneitzel

Gast
Man muss übrigens nicht die einzelnen Bildchen erst ausschneiden - Wenn man das Bild, das alle Bilder enthält, hat, reicht das auch.

Der drawImage Aufruf bekommt dann einfach ein paar mehr Parameter:
Java:
g.drawImage(sourceImage,
           0, 0, 31, 31, // Destination Area
           sourceX1, sourceY1, sourceX2, sourceY1, // Area des source Images
            null); // möglicher Observer

die source Werte muss man für jedes Bild dann natürlich haben - zum Ausschneiden hattest Du die ja bereits.
 

Hag2bard

Bekanntes Mitglied
Danke nochmal für die sehr gute Hilfe, ich bin ziemlich weit gekommen.

1634565062293.png
Das tileset welches ich verwende ist ein PNG.

Wie ihr seht, ist die untere Zeile meines Buffered Images nicht fertig bisher, deshalb ist es auch klar, dass der Rest da noch schwarz ist.
Allerdings ist dieses eine Stück vom Dach also der Block mit dem Dach mit schwarzem Hintergrund.
Ich dachte mir dann also, dann muss ich zuerst so einen Rasenblock zeichnen, wie der block links daneben auch und dann das Stück vom Dach darüber zeichnen.
Das funktioniert allerdings nicht, er ersetzt diesem Bereich des Source Images. Das schwarze Stück von dem Tile ist aber transparent.
Gibt es eine Möglichkeit in 2 Layern zu zeichnen?
Java:
g.drawImage(sourceImage,
           0, 0, 31, 31, // Destination Area
           sourceX1, sourceY1, sourceX2, sourceY1, // Area des source Images
            null); // möglicher Observer


edit: Ich habs hinbekommen, hab da ein Fehler mit meinem Array gehabt
Aber so habt ihr zumindest schonmal einen Zwischenstand
 
Zuletzt bearbeitet:

Hag2bard

Bekanntes Mitglied
Eine Frage hätte ich noch, ich hab nicht viel Zeit meine Map zu erstellen, ist auch ein ziemlich großer Aufwand, aber sobald ich damit fertig bin, würde ich gerne eine Spielfigur über das Feld bewegen.
Ich habe überlegt dafür 2 BufferedImages zu haben. Eins mit dem Spielfeld und eine Kopie davon auf der ich mit der drawImage Methode die Spielfigur zeichne. Wenn die Spielfigur sich bewegt lade ich das originale BufferedImage in die Kopie und zeichne die Spielfigur dann auf eine neue Position.

Ist die Idee gut oder kann ich ein BufferedImage mit einer Spielfigur erstellen, welches ich dann über das andere BufferedImage bewege?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
3 Eigenes Frame/Window programmieren AWT, Swing, JavaFX & SWT 2
N Swing Kugel/Sphäre programmieren AWT, Swing, JavaFX & SWT 12
H RPG Programmieren, label.setLocation funktioniert nicht AWT, Swing, JavaFX & SWT 7
T Button für GUI programmieren AWT, Swing, JavaFX & SWT 1
T Wie kann man in java aufwendige grafiken programmieren AWT, Swing, JavaFX & SWT 1
A 2D-Grafik Sprung programmieren AWT, Swing, JavaFX & SWT 35
M Nutzer interface Programmieren AWT, Swing, JavaFX & SWT 2
J Kleines Helikopterspiel programmieren AWT, Swing, JavaFX & SWT 2
R kleinen JPanelEditor programmieren AWT, Swing, JavaFX & SWT 3
C Gesucht: Hilfe beim programmieren. AWT, Swing, JavaFX & SWT 1
C Hilfe beim programmieren mit studiumgebundenes Projekt AWT, Swing, JavaFX & SWT 1
2 Senso bzw SimonSays programmieren AWT, Swing, JavaFX & SWT 8
T Möchte Android-ähnlich programmieren AWT, Swing, JavaFX & SWT 7
R Eclipse GUI Programmieren AWT, Swing, JavaFX & SWT 8
I LookAndFeel HTML Auflösung - Online Editor programmieren AWT, Swing, JavaFX & SWT 2
J 2D-Grafik Menü programmieren AWT, Swing, JavaFX & SWT 2
J Swing Landkarte mithilfe von Swing programmieren AWT, Swing, JavaFX & SWT 4
T Kleinen "Gui Builder" programmieren AWT, Swing, JavaFX & SWT 12
SexyPenny90 Wie Ball programmieren, der im 4 Eck rum fliegt AWT, Swing, JavaFX & SWT 7
I Rechner programmieren AWT, Swing, JavaFX & SWT 6
F UI Toolkit programmieren AWT, Swing, JavaFX & SWT 9
S Desktop Programmieren AWT, Swing, JavaFX & SWT 2
A Programmieren einer Agenda mit einer Liste (als Applet und .txt zum Speichern) AWT, Swing, JavaFX & SWT 7
C Swing Orderbook programmieren AWT, Swing, JavaFX & SWT 6
B Editor programmieren AWT, Swing, JavaFX & SWT 26
LittleJavaCup Suchmaschine programmieren (wie bei Windows) AWT, Swing, JavaFX & SWT 2
T AWT verschiedene Oberflächen programmieren AWT, Swing, JavaFX & SWT 5
vandread Swing Probleme mit "Game of Life" programmieren AWT, Swing, JavaFX & SWT 8
J Modelleisenbahn - Kontroll-Tafel programmieren AWT, Swing, JavaFX & SWT 3
L Regler in Java Programmieren AWT, Swing, JavaFX & SWT 12
I Preisvergleich programmieren AWT, Swing, JavaFX & SWT 4
P Swing Roter Faden beim Applet GUI Programmieren AWT, Swing, JavaFX & SWT 2
J FAQ programmieren, welche Swing-Elemente AWT, Swing, JavaFX & SWT 7
G GUI - Inhalte wechseln (Eingabe-Assistenten programmieren) AWT, Swing, JavaFX & SWT 2
C Zeitplaner: Terminblock programmieren AWT, Swing, JavaFX & SWT 7
O Swing "Eigenes" JPanel wird dem JScrollPane nicht hinzugefügt AWT, Swing, JavaFX & SWT 5
M Swing JComboBox eigenes Design AWT, Swing, JavaFX & SWT 3
L LookAndFeel Eigenes Design für die Applikation AWT, Swing, JavaFX & SWT 4
L JavaFX als eigenes Objekt AWT, Swing, JavaFX & SWT 3
M Plugin oder eigenes Tool mit zB SWING AWT, Swing, JavaFX & SWT 2
E Eigenes TableModel für ArrayList<String[]> AWT, Swing, JavaFX & SWT 5
N LookAndFeel Wie kann ich mein eigenes LookAndFeel machen? AWT, Swing, JavaFX & SWT 6
1 Eigenes Layout schreiben AWT, Swing, JavaFX & SWT 4
J Eigenes Gui/ Look and Feel AWT, Swing, JavaFX & SWT 14
D Eigenes Textfeld AWT, Swing, JavaFX & SWT 8
A Minimalestopuhr: JLabel.setText() durch eigenes Event ändern AWT, Swing, JavaFX & SWT 6
C Eigenes Hintergrundbild einfügen AWT, Swing, JavaFX & SWT 6
M Eigenes Panel aus Component? AWT, Swing, JavaFX & SWT 5
F LayoutManager Eigenes Layout die Lösung?! AWT, Swing, JavaFX & SWT 4
P Eigenes Textverarbeitungsprogramm AWT, Swing, JavaFX & SWT 4
R [JTree/DefaultTreeCellRenderer] eigenes Renderer-Panel, so breit wie der JTree AWT, Swing, JavaFX & SWT 2
Developer_X LookAndFeel Eigenes Look And Feel erstellen AWT, Swing, JavaFX & SWT 33
B SWT Eigenes Icon für CheckboxTreeViewer AWT, Swing, JavaFX & SWT 3
KrokoDiehl Swing Design-Frage: eigenes Line-Wrapping AWT, Swing, JavaFX & SWT 5
M Swing eigenes StyledDocument AWT, Swing, JavaFX & SWT 2
D eigenes Tablemodel, Zeile löschen ArrayindexOOB excp AWT, Swing, JavaFX & SWT 4
S JTree mit Daten aus Model füllen, eigenes TreeModel (gute Dokumentation des Problems) AWT, Swing, JavaFX & SWT 2
P Eigenes TableModel abgeleitet von AbstractTableModel (neue rows nicht sichtbar) AWT, Swing, JavaFX & SWT 6
M Eigenes ActionEvent / Eigener Listener AWT, Swing, JavaFX & SWT 2
A JTable, eigenes TableModel und dessen Objekte AWT, Swing, JavaFX & SWT 4
G JToolbar gleich als eigenes Fenster öffnen AWT, Swing, JavaFX & SWT 2
G Eigenes ComboBoxModel AWT, Swing, JavaFX & SWT 2
M eigenes DialogFenster AWT, Swing, JavaFX & SWT 4
L Button ändert eigenes Bild und Progressbar-Value nicht AWT, Swing, JavaFX & SWT 6
J eigenes JOptionPane ? AWT, Swing, JavaFX & SWT 2
D Eigenes Tooltip AWT, Swing, JavaFX & SWT 5
G eigenes option pane AWT, Swing, JavaFX & SWT 5
C Eigenes Event AWT, Swing, JavaFX & SWT 8
S Eigenes Package für die GUI? AWT, Swing, JavaFX & SWT 6
P Eigenes Look&Feel schreiben (Tutorials?) AWT, Swing, JavaFX & SWT 6
B Eigenes Events AWT, Swing, JavaFX & SWT 3
G für showInputDialog kein eigenes Icon auswählen AWT, Swing, JavaFX & SWT 6
M JDialog und eigenes Icon AWT, Swing, JavaFX & SWT 10
P Bewegung eines Balkens in eineum JPanel welches als Spielfeld fungiert AWT, Swing, JavaFX & SWT 2
Viktim Array Spielfeld wird in GUI gedreht AWT, Swing, JavaFX & SWT 5
D Swing Spielfeld drehen von Pentago endet in einer Katastrophe AWT, Swing, JavaFX & SWT 2
P Spielfeld AWT, Swing, JavaFX & SWT 2
C Swing Info-Ebene überdeckt Spielfeld-Ebene komplett AWT, Swing, JavaFX & SWT 5
S Spielfeld mit unförmigen Objekten anklickbar machen? AWT, Swing, JavaFX & SWT 4
C Spielfeld Gitter - Einzelne Zellen verändern AWT, Swing, JavaFX & SWT 18
T Spielfeld erstellen AWT, Swing, JavaFX & SWT 15
J Ansicht wechseln zw. Spielfeld und Optionen AWT, Swing, JavaFX & SWT 3
C Spielfeld Editor AWT, Swing, JavaFX & SWT 4
B Ein Spielfeld zeichnen AWT, Swing, JavaFX & SWT 7
Y Spielfeld mit paintComponent oder doch lieber anders? AWT, Swing, JavaFX & SWT 8
G Spielfeld für ein Spiel erstellen, wie am besten? AWT, Swing, JavaFX & SWT 4

Ähnliche Java Themen

Neue Themen


Oben