import static java.awt.Toolkit.getDefaultToolkit;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class Box2000 extends JFrame
{
private static final long serialVersionUID = 1L;
public boolean zulassen = true;
public int lvl = 1;
private static final int STEP_SIZE = 5;
private static final int TILDE_POW_SIZE = 25;
private static final Dimension FRAME_SIZE = new Dimension(456, 407);
private static final Dimension TILDE_SIZE = new Dimension(TILDE_POW_SIZE, TILDE_POW_SIZE);
private final Map<Integer, TildeInfo> TILDE_INFOS = new HashMap<Integer, TildeInfo>() {
private static final long serialVersionUID = 1L;
{
put(1, new TildeInfo("bild[1].png", true, "Boden", null));
put(2, new TildeInfo("bild[2].png", true, "Kiste", new KistenLogic()));
put(3, new TildeInfo("bild[3].png", false, "Wand", null));
put(4, new TildeInfo("bild[4].png", false, "Wand mit roten Rohr unten", null));
put(5, new TildeInfo("bild[5].png", false, "Wand mit roten Rohr link", null));
put(6, new TildeInfo("bild[6].png", false, "Wand mit roten Rohr oben", null));
put(7, new TildeInfo("bild[7].png", false, "Wand mit roten Rohr rechts", null));
put(8, new TildeInfo("bild[8].png", false, "Wand mit roten Rohr rechts", null));
put(9, new TildeInfo("bild[9].png", false, "Wand mit roten Rohr rechts", null));
put(10, new TildeInfo("bild[10].png", false, "Wand mit roten Rohr rechts", null));
put(11, new TildeInfo("bild[11].png", false, "Wand mit roten Rohr rechts", null));
put(12, new TildeInfo("bild[12].png", false, "Wand mit roten Rohr rechts", null));
put(13, new TildeInfo("bild[13].png", false, "Wand mit roten Rohr rechts", null));
put(14, new TildeInfo("bild[14].png", false, "Wand mit roten Rohr rechts", null));
put(15, new TildeInfo("bild[15].png", false, "Wand mit roten Rohr außer unten", null));
put(16, new TildeInfo("bild[16].png", false, "Wand mit roten Rohr rechts", null));
put(17, new TildeInfo("bild[17].png", false, "Wand mit roten Rohr rechts unten", null));
put(18, new TildeInfo("bild[18].png", false, "Wand mit roten Rohr rechts oben", null));
put(19, new TildeInfo("bild[19].png", false, "Wand mit roten Rohr links oben", null));
put(20, new TildeInfo("bild[20].png", false, "Wand mit roten Rohr links unten", null));
put(21, new TildeInfo("bild[21].png", false, "Wand mit roten Rohr r+l oben", null));
}
};
private static Tilde feld[][] = new Tilde[18][15];
private Figur figur;
public Box2000(String title) throws IOException
{
super(title);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(FRAME_SIZE);
setLocationRelativeTo(null);
setLayout(null);
figur = new Figur();
add(figur);
felderstellen();
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent evt) {
if(evt.getKeyCode() == KeyEvent.VK_UP)
figur.controllMoving(new Point(0, -1));
else if(evt.getKeyCode() == KeyEvent.VK_RIGHT)
figur.controllMoving(new Point(1, 0));
else if(evt.getKeyCode() == KeyEvent.VK_DOWN)
figur.controllMoving(new Point(0, 1));
else if(evt.getKeyCode() == KeyEvent.VK_LEFT)
figur.controllMoving(new Point(-1, 0));
}
});
setResizable(false);
setVisible(true);
}
public void felderstellen() throws IOException
{
Scanner scanner = new Scanner(new File("lvl"+lvl+".txt"));
int lineCounter = 0;
do
{
String line = scanner.nextLine();
String[] parts = line.split(",");
for(int partCounter = 0; partCounter < parts.length; partCounter++)
{
int id = Integer.parseInt(parts[partCounter]);
TildeInfo tildeInfo = TILDE_INFOS.get(id);
if(tildeInfo == null)
continue;
Tilde nextField = tildeInfo.newTilde();
nextField.setLocation(partCounter * TILDE_SIZE.width, lineCounter * TILDE_SIZE.height);
nextField.setSize(TILDE_SIZE);
add(nextField);
feld[partCounter][lineCounter] = nextField;
}
lineCounter++;
}
while (scanner.hasNextLine());
}
public static void main(String[] args) throws IOException
{
new Box2000("Box2000");
}
private final class Figur extends JLabel implements Runnable
{
private static final long serialVersionUID = 1L;
private static final byte STATE_WAIT = 0;
private static final byte STATE_MOVE = 1;
private static final byte STATE_DIE = 2;
private static final byte STATE_DEAD = 3;
private byte state;
private Thread runThread;
private Point moveDir;
private Figur()
{
setIcon(new ImageIcon(getDefaultToolkit().getImage("bild[0].png")));
setBounds(8 * TILDE_SIZE.width, 7 * TILDE_SIZE.height, TILDE_SIZE.width, TILDE_SIZE.height);
moveDir = new Point(0, 0);
state = STATE_MOVE;
runThread = new Thread(this, "Figur");
runThread.start();
}
public void run()
{
if(moveDir == null)
return;
do
{
switch(state)
{
case(STATE_WAIT):
synchronized (this)
{
try
{
wait();
}
catch (InterruptedException e) {}
}
break;
case(STATE_MOVE):
move();
break;
}
}
while(state != STATE_DIE);
state = STATE_DEAD;
}
private void move()
{
final int moveDirX = moveDir.x;
final int moveDirY = moveDir.y;
int steps = TILDE_POW_SIZE / STEP_SIZE;
int moveX = moveDirX * steps;
int moveY = moveDirY * steps;
final Tilde nextTilde = getNextTilde(moveDirX, moveDirY);
if(!checkNextTilde(moveDirX, moveDirY, nextTilde))
{
zulassen = true;
return;
}
final Point loc = new Point(getX(), getY());
for(int i = 0; i < steps; i++)
{
loc.x = loc.x + moveX;
loc.y = loc.y + moveY;
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
setLocation(loc);
}
});
try
{
TimeUnit.MILLISECONDS.sleep(10L);
}
catch (InterruptedException e) {}
}
try
{
SwingUtilities.invokeAndWait(new Runnable() {
public void run()
{
setLocation(loc);
if(nextTilde != null)
nextTilde.moveOn(new Point(moveDirX * -1, moveDirY * -1));
}
});
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch (InvocationTargetException e)
{
e.printStackTrace();
}
}
private Tilde getNextTilde(int moveDirX, int moveDirY)
{
int x = getX();
int y = getY();
int tildeX = x / TILDE_SIZE.width;
int tildeY = y / TILDE_SIZE.height;
final int nextTildeX = tildeX + moveDirX;
final int nextTildeY = tildeY + moveDirY;
return(feld[nextTildeX][nextTildeY]);
}
private boolean checkNextTilde(int moveDirX, int moveDirY, Tilde nextTilde)
{
if(nextTilde != null && !nextTilde.isPassable())
{
controllMoving(new Point(moveDir.x*-1, moveDir.y*-1));
try
{
TimeUnit.MILLISECONDS.sleep(10L);
}
catch (InterruptedException e) {}
return(false);
}
return(true);
}
public void controllMoving(Point dir)
{
if (zulassen!=true) return;
zulassen = false;
if(Math.abs(moveDir.x + dir.x) < 2)
moveDir.x+= dir.x;
if(Math.abs(moveDir.y + dir.y) < 2)
moveDir.y+= dir.y;
synchronized (this)
{
notify();
}
}
}
private static class TildeInfo
{
private boolean passable;
private Icon icon;
private String note;
private GameItem itemLogic;
public TildeInfo(String imagePath, boolean passable, String note, GameItem itemLogic)
{
super();
this.passable = passable;
icon = new ImageIcon(getDefaultToolkit().getImage(imagePath));
this.note = note;
this.itemLogic = itemLogic;
}
public int hashCode()
{
return(icon.hashCode() + note.hashCode());
}
public boolean equals(Object obj)
{
if(!(obj instanceof TildeInfo))
return(false);
TildeInfo cast = (TildeInfo)obj;
return(icon.equals(cast.icon) && note.equals(cast.note) && passable == cast.passable);
}
public Tilde newTilde()
{
Tilde t = new Tilde(passable, itemLogic);
t.setIcon(icon);
return(t);
}
}
private static class Tilde extends JLabel
{
private static final long serialVersionUID = 1L;
private boolean passable;
private GameItem itemLogic;
public Tilde(boolean passable, GameItem itemLogic)
{
super();
this.passable = passable;
this.itemLogic = itemLogic;
}
public void moveOn(Point point)
{
if(itemLogic != null)
itemLogic.moveOn(point, this);
}
public boolean isPassable()
{
return passable;
}
}
private static interface GameItem
{
public void moveOn(Point dir, Tilde t);
}
private class KistenLogic implements GameItem
{
public void moveOn(Point dir, Tilde t)
{
Tilde ground = TILDE_INFOS.get(1).newTilde();
ground.setBounds(t.getBounds());
remove(t);
add(ground);
int fieldX = t.getX() / TILDE_SIZE.width;
int fieldY = t.getY() / TILDE_SIZE.height;
feld[fieldX][fieldY] = ground;
for (int i = 0;i<18 ;i++ )
{
for (int j = 0;j<15 ;j++ )
{
if (feld[i][j] == TILDE_INFOS.get(2).newTilde()) return;
}
}
lvl++;
try {
felderstellen();
} catch(Exception e) {}
}
}
}