Java/Tutorials/Entwicklung eines einfachen Karteneditors III/Kapitel 6
Aus Scientia
Version vom 24. Januar 2011, 12:21 Uhr von Alexis Hiemis (Diskussion | Beiträge)
Inhaltsverzeichnis
Karteneditor Klassen
Karte
import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import javax.imageio.ImageIO; public class Karte { int[][] karte; int[] passmap; String kartenName; String tilesetDateiname; ArrayList<BufferedImage> tileset=new ArrayList<BufferedImage>(); public Karte(int[][] karte, String dateiname, String name) { this.kartenName=name; this.karte=karte; this.tilesetDateiname=dateiname; try { BufferedImage bildTileset=ImageIO.read(new File(dateiname)); int breite=bildTileset.getWidth()/32; int höhe=bildTileset.getHeight()/32; for(int x=0;x<breite;x++) { for(int y=0;y<höhe;y++) { BufferedImage tile=bildTileset.getSubimage(x*32, y*32, 32, 32); this.tileset.add(tile); } } } catch (IOException fehler) { fehler.printStackTrace(); } this.passmap=new int[tileset.size()]; } public BufferedImage getTileImage(int x, int y) { int tile=karte[x][y]; return tileset.get(tile); } public void setTile(int x, int y, int tileID) { karte[x][y]=tileID; } }
KartenAnsicht
import java.awt.Dimension; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.image.BufferedImage; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.RepaintManager; public class KartenAnsicht extends JPanel{ KartenFenster fenster; JScrollPane scroll=new JScrollPane(); RepaintManager m; public KartenAnsicht(KartenFenster kfenster) { scroll.setViewportView(this); fenster=kfenster; //verhindert Flackern setDoubleBuffered(true); changeKarte(); m=RepaintManager.currentManager(fenster); addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { zeichneTile(e.getX(), e.getY()); } }); addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseDragged(MouseEvent e) { zeichneTile(e.getX(), e.getY()); } }); /*AdjustmentListener adjust=new AdjustmentListener() { @Override public void adjustmentValueChanged(AdjustmentEvent e) { e.getAdjustable().setUnitIncrement(32); repaint(); } }; scroll.getVerticalScrollBar().addAdjustmentListener(adjust); scroll.getHorizontalScrollBar().addAdjustmentListener(adjust);*/ } public void paintComponent(Graphics g) { Rectangle r=g.getClipBounds(); int startx=r.x; int starty=r.y; int endx=startx+r.width; int endy=starty+r.height; startx=startx/32; starty=starty/32; endx=endx/32; endy=endy/32; if(endx < fenster.aktuelleKarte.karte.length) { endx++; } if(endy < fenster.aktuelleKarte.karte[0].length) { endy++; } for(int x=startx;x < endx;x++) { for(int y=starty;y < endy;y++){ BufferedImage tile=fenster.aktuelleKarte.getTileImage(x, y); g.drawImage(tile, x*32, y*32, this); } } } public void changeKarte() { //Hier wird nun eine Feste größe des JPanel gesetzt. int dx=fenster.aktuelleKarte.karte.length; int dy=fenster.aktuelleKarte.karte[0].length; setPreferredSize(new Dimension(dx*32,dy*32)); scroll.setViewportView(this); } public void zeichneTile(int x, int y) { x=x/32; y=y/32; fenster.aktuelleKarte.karte[x][y]=fenster.palette.aktuelleTile; Rectangle r=scroll.getViewport().getViewRect(); int dx=this.scroll.getLocation().x+fenster.getInsets().left-r.x; int dy=this.scroll.getLocation().y+fenster.getInsets().top-r.y; m.addDirtyRegion(fenster , dx+x*32, dy+y*32, 32, 32); } }
KartenDialog
import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JTextField; public class KartenDialog extends JDialog{ KartenFenster fenster; JTextField kartenName=new JTextField(); JTextField kartenBreite=new JTextField(); JTextField kartenHöhe=new JTextField(); JTextField tilesetDateiname=new JTextField(); JLabel name=new JLabel("Name:"); JLabel dateiname=new JLabel("Tileset:"); JLabel breite=new JLabel("Karten Breite:"); JLabel höhe=new JLabel("Karten Höhe:"); JButton okay=new JButton("okay"); public KartenDialog(KartenFenster kfenster) { super(kfenster, "Karte erstellen"); fenster=kfenster; Dimension dim=new Dimension(100, 20); kartenBreite.setPreferredSize(dim); kartenHöhe.setPreferredSize(dim); kartenName.setPreferredSize(dim); tilesetDateiname.setPreferredSize(dim); höhe.setPreferredSize(dim); breite.setPreferredSize(dim); name.setPreferredSize(dim); dateiname.setPreferredSize(dim); okay.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { erstelleKarte(); } }); setSize(250,200); setLayout(new FlowLayout()); add(name); add(kartenName); add(breite); add(kartenBreite); add(höhe); add(kartenHöhe); add(dateiname); add(tilesetDateiname); add(okay); setVisible(true); } public void erstelleKarte() { int breite=Integer.parseInt(kartenBreite.getText()); int höhe=Integer.parseInt(kartenHöhe.getText()); int[][] karte= new int[breite][höhe]; String name=kartenName.getText(); String tileset=tilesetDateiname.getText(); fenster.aktuelleKarte=new Karte(karte, tileset, name); fenster.ansicht.changeKarte(); fenster.palette.repaint(); fenster.ansicht.repaint(); fenster.ansicht.scroll.repaint(); fenster.repaint(); dispose(); } }
KartenFenster
import java.awt.BorderLayout; import javax.swing.JFrame; public class KartenFenster extends JFrame{ Karte aktuelleKarte; TilePalette palette; KartenAnsicht ansicht; KartenMenü kartenMenü; public KartenFenster() { this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.requestFocus(); int karte[][]=new int[100][100]; String name="Unser erste Karte"; String tilesetDateiname="Tileset.png"; aktuelleKarte=new Karte(karte, tilesetDateiname, name); palette=new TilePalette(this); //Initialisere KartenAnsicht ansicht=new KartenAnsicht(this); //Initialisere KartenMenü kartenMenü=new KartenMenü(this); setLayout(new BorderLayout()); add(kartenMenü, BorderLayout.NORTH); add(palette, BorderLayout.WEST); add(ansicht.scroll , BorderLayout.CENTER); //größe des Fensters setzen setSize(1024, 768); //Setzen eines Fenstertitels setTitle("Karteneditor"); } }
KartenMenü
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; public class KartenMenü extends JMenuBar{ KartenFenster fenster; JMenu datei=new JMenu("Datei"); JMenuItem neu=new JMenuItem("Neue Karte"); JMenuItem speichern=new JMenuItem("Karte Speichern"); JMenuItem laden=new JMenuItem("Karte Laden"); JMenu karte=new JMenu("Karte"); JMenuItem passierbarkeit=new JMenuItem("Passierbarkeit Einstellen"); public KartenMenü(KartenFenster kfenster) { fenster=kfenster; neu.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { neu(); } }); laden.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { laden(); } }); speichern.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { speichern(); } }); datei.add(neu); datei.add(speichern); datei.add(laden); add(datei); passierbarkeit.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { passiserbarkeit(); } }); karte.add(passierbarkeit); add(karte); } public void passiserbarkeit() { JFrame frame=new JFrame("Passierbarkeit"); frame.add(new PassmapPalette(fenster)); frame.pack(); frame.setVisible(true); } public void neu() { new KartenDialog(fenster); } public void laden() { try { JFileChooser speicherDialog=new JFileChooser(); speicherDialog.showOpenDialog(fenster); FileInputStream datei=new FileInputStream(speicherDialog.getSelectedFile()); BufferedInputStream buf=new BufferedInputStream(datei); ObjectInputStream lese = new ObjectInputStream(buf); int[][]karte=(int[][]) lese.readObject(); String name=(String) lese.readObject(); String dateiname=(String) lese.readObject(); int passmap[]=(int[]) lese.readObject();//Neu fenster.aktuelleKarte=new Karte(karte,dateiname, name); fenster.aktuelleKarte.passmap=passmap;//Neu lese.close(); fenster.ansicht.changeKarte(); fenster.palette.repaint(); fenster.ansicht.repaint(); fenster.ansicht.scroll.repaint(); fenster.repaint(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void speichern() { try { JFileChooser speicherDialog=new JFileChooser(); speicherDialog.showSaveDialog(fenster); FileOutputStream datei=new FileOutputStream(speicherDialog.getSelectedFile()); BufferedOutputStream buf=new BufferedOutputStream(datei); ObjectOutputStream schreibe = new ObjectOutputStream(buf); schreibe.writeObject(fenster.aktuelleKarte.karte); schreibe.writeObject(fenster.aktuelleKarte.kartenName); schreibe.writeObject(fenster.aktuelleKarte.tilesetDateiname); schreibe.writeObject(fenster.aktuelleKarte.passmap); schreibe.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
Main
public class Main { public static void main(String[] args) { //Starten des Karteneditors KartenFenster karteneditor=new KartenFenster(); //Den Karteneditor sichtbar machen karteneditor.setVisible(true); } }
PassmapPalette
import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; public class PassmapPalette extends TilePalette{ public PassmapPalette(KartenFenster kartenfenster) { super(kartenfenster); } public void paintComponent(Graphics g) { int tileAnzahl=fenster.aktuelleKarte.tileset.size(); int zeile=0; int spalte=0; for(int i=0;i<tileAnzahl;i++) { BufferedImage tile=fenster.aktuelleKarte.tileset.get(i); g.drawImage(tile,spalte*32, zeile*32, this); if(fenster.aktuelleKarte.passmap[i] == 1) { g.setColor(Color.green); g.drawOval(spalte*32, zeile*32, 32, 32); } else { g.setColor(Color.red); g.drawRect(spalte*32, zeile*32, 32, 32); } if(i%4 == 3) { zeile++; spalte=0; } else spalte++; } } @Override public void setTileID(int x, int y) { super.setTileID(x, y); if(fenster.aktuelleKarte.passmap[aktuelleTile] == 1) { fenster.aktuelleKarte.passmap[aktuelleTile] = 0; } else { fenster.aktuelleKarte.passmap[aktuelleTile] = 1; } repaint(); } }
TilePalette
import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import javax.swing.JPanel; public class TilePalette extends JPanel { KartenFenster fenster; int aktuelleTile=0; public TilePalette(KartenFenster kartenfenster) { fenster=kartenfenster; setPreferredSize(new Dimension(4*32, (fenster.aktuelleKarte.tileset.size()/4)*32)); setDoubleBuffered(true); this.addMouseListener(new MouseAdapter(){ @Override public void mouseClicked(MouseEvent e) { setTileID(e.getX(), e.getY()); } }); } public void paintComponent(Graphics g) { int tileAnzahl=fenster.aktuelleKarte.tileset.size(); int zeile=0; int spalte=0; for(int i=0;i<tileAnzahl;i++) { BufferedImage tile=fenster.aktuelleKarte.tileset.get(i); g.drawImage(tile,spalte*32, zeile*32, this); if(i%4 == 3) { zeile++; spalte=0; } else spalte++; } } public void setTileID(int x, int y) { int spalte=x/32; int zeile=y/32; int tileID=zeile*4+spalte; if(tileID < fenster.aktuelleKarte.tileset.size()) { aktuelleTile=tileID; } } }
Engine Klassen
Karte
import java.awt.image.BufferedImage; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.ObjectInputStream; import java.util.ArrayList; import javax.imageio.ImageIO; public class Karte { int[] passmap; int[][] karte; int breite; int höhe; String kartenName; String tilesetDateiname; ArrayList<BufferedImage> tileset=new ArrayList<BufferedImage>(); public Karte(int[][] karte, String dateiname, String name) { this.kartenName=name; this.karte=karte; this.tilesetDateiname=dateiname; breite=karte.length; höhe=karte[0].length; try { BufferedImage bildTileset=ImageIO.read(new File(dateiname)); int breite=bildTileset.getWidth()/32; int höhe=bildTileset.getHeight()/32; for(int x=0;x<breite;x++) { for(int y=0;y<höhe;y++) { BufferedImage tile=bildTileset.getSubimage(x*32, y*32, 32, 32); this.tileset.add(tile); } } } catch (IOException fehler) { fehler.printStackTrace(); } this.passmap=new int[tileset.size()]; } public BufferedImage getTileImage(int x, int y) { int tile=karte[x][y]; return tileset.get(tile); } public void setTile(int x, int y, int tileID) { karte[x][y]=tileID; } public static Karte ladeKarte(String kartendateiname) { try { FileInputStream datei = new FileInputStream(new File(kartendateiname)); BufferedInputStream buf=new BufferedInputStream(datei); ObjectInputStream lese = new ObjectInputStream(buf); int[][]karte=(int[][]) lese.readObject(); String name=(String) lese.readObject(); String dateiname=(String) lese.readObject(); int[] passmap=(int[]) lese.readObject(); Karte geladeneKarte=new Karte(karte,dateiname, name); geladeneKarte.passmap=passmap; lese.close(); return geladeneKarte; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } }
Main
public class Main { public static void main(String[] args) { SpielFenster spiel=new SpielFenster(); } }
SpielAnsicht
import java.awt.Dimension; import java.awt.Graphics; import javax.swing.JPanel; public class SpielAnsicht extends JPanel implements Runnable{ SpielerSprite spieler; SpielFenster fenster; Karte karte; final int MAX_GAME_SPEED=33; public SpielAnsicht(SpielFenster f) { fenster=f; karte=fenster.karte; spieler=fenster.spieler; setPreferredSize(new Dimension(640,480)); setDoubleBuffered(true); } public void paintComponent(Graphics g) { zeichneKarte(g); zeichneSpieler(g); } public void zeichneSpieler(Graphics g) { g.drawImage(spieler.getImage(), spieler.position.x*32, spieler.position.y*32-16, this); } public void zeichneKarte(Graphics g) { int startx=fenster.ansichtsPunkt.x; int starty=fenster.ansichtsPunkt.y; int endx=startx+20; int endy=starty+15; for(int x=startx, rx=0;x<endx;x++, rx++) { for(int y=starty,ry=0;y<endy;y++,ry++) { g.drawImage(karte.getTileImage(x, y), rx*32, ry*32,this); } } } @Override public void run() { while(true) { float START = System.currentTimeMillis(); repaint(); float AUSFUEHR = System.currentTimeMillis()-START; if(MAX_GAME_SPEED>AUSFUEHR) { try { Thread.sleep(MAX_GAME_SPEED-(int)AUSFUEHR); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
== SpielerSprite
import java.awt.Point; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class SpielerSprite extends Sprite{ BufferedImage charset; Point position=new Point(9,8); SpielFenster fenster; Steuerung steuerung; float animation=0.0f; public SpielerSprite(String dateiname, SpielFenster f) { fenster=f; steuerung=fenster.steuerung; try { charset=ImageIO.read(new File(dateiname)); } catch (IOException fehler) { fehler.printStackTrace(); } } @Override public BufferedImage getImage() { if(steuerung.bewegung)animation+=0.33; else animation=0.0f; if((int)animation ==4 ) animation=0.0f; return charset.getSubimage(((int)animation)*32, steuerung.letzterichtung*48, 32, 48); } }
SpieleFenster
import java.awt.Dimension; import java.awt.Point; import javax.swing.JFrame; public class SpielFenster extends JFrame{ Point ansichtsPunkt=new Point(0,0); SpielAnsicht ansicht; Steuerung steuerung; SpielerSprite spieler; SpielSchleife schleife; Karte karte; Thread zeichenThread; Thread schleifenThread; public SpielFenster() { steuerung=new Steuerung(); addKeyListener(steuerung); spieler=new SpielerSprite("Char.png",this); karte=Karte.ladeKarte("1.karte"); ansicht=new SpielAnsicht(this); schleife=new SpielSchleife(this); add(ansicht); zeichenThread=new Thread(ansicht); schleifenThread=new Thread(schleife); zeichenThread.start(); schleifenThread.start(); setSize(new Dimension(640,480)); setTitle("Spiel"); setVisible(true); } }
SpieleSchleife
import java.awt.Point; public class SpielSchleife implements Runnable{ SpielFenster fenster; Karte karte; Steuerung steuerung; Point punkt; int MAX_GAME_SPEED=33; public SpielSchleife(SpielFenster f) { fenster=f; karte=fenster.karte; steuerung=fenster.steuerung; punkt=fenster.ansichtsPunkt; } public void run() { while(true) { float START = System.currentTimeMillis(); Point alterPunkt = new Point(punkt.x,punkt.y); if(steuerung.hoch == true) { punkt.y--; } else if(steuerung.runter == true) { punkt.y++; } else if(steuerung.links == true) { punkt.x--; } else if(steuerung.rechts == true) { punkt.x++; } if(punkt.x > karte.breite-20) { punkt.x--; } else if(punkt.y > karte.höhe-15) { punkt.y--; } else if(punkt.x < 0) { punkt.x++; } else if(punkt.y < 0) { punkt.y++; } int spielerX=fenster.spieler.position.x; int spielerY=fenster.spieler.position.y; int tileID=karte.karte[punkt.x+spielerX][punkt.y+spielerY]; if(karte.passmap[tileID] == 0) { punkt.x=alterPunkt.x; punkt.y=alterPunkt.y; } float AUSFUEHR = System.currentTimeMillis()-START; if(MAX_GAME_SPEED>AUSFUEHR) { try { Thread.sleep(MAX_GAME_SPEED-(int)AUSFUEHR); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
Sprite
import java.awt.image.BufferedImage; public abstract class Sprite { public abstract BufferedImage getImage(); }
Steuerung
import java.awt.event.KeyEvent; import java.awt.event.KeyListener; public class Steuerung implements KeyListener{ public int letzterichtung=0;// 3=hoch, 0=runter,1=links,2=rechts boolean bewegung=false; public boolean hoch=false; public boolean runter=false; public boolean links=false; public boolean rechts=false; @Override public void keyPressed(KeyEvent e) { switch(e.getKeyCode()) { case KeyEvent.VK_UP: letzterichtung=3; hoch=true; bewegung=true; break; case KeyEvent.VK_DOWN: letzterichtung=0; runter=true; bewegung=true; break; case KeyEvent.VK_LEFT: letzterichtung=1; links=true; bewegung=true; break; case KeyEvent.VK_RIGHT: letzterichtung=2; rechts=true; bewegung=true; break; } } @Override public void keyReleased(KeyEvent e) { switch(e.getKeyCode()) { case KeyEvent.VK_UP: hoch=false; bewegung=false; break; case KeyEvent.VK_DOWN: runter=false; bewegung=false; break; case KeyEvent.VK_LEFT: links=false; bewegung=false; break; case KeyEvent.VK_RIGHT: rechts=false; bewegung=false; break; } } @Override public void keyTyped(KeyEvent e) { } }