home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet Gallery
/
INTERGAL.bin
/
intergal
/
prgs
/
idv21
/
data.z
/
Sokoban.java
< prev
next >
Wrap
Text File
|
1996-05-20
|
7KB
|
239 lines
// Sokoban written by Lars Gersmannn May'96
import java.awt.*;
import java.applet.Applet;
import java.net.*;
import java.io.*;
import ImageTracker;
public class Sokoban extends Applet implements Runnable {
Image img = null;
Thread thread = null;
volatile boolean pleasestop = false;
final int SLEEP = 100;
ImageTracker it = null;
public final int PLANE_X = 22,
PLANE_Y = 22,
LEN = 25; // Len = x,y of sprite
char PlayPlane[] = new char[PLANE_X*PLANE_Y],
OrgPlane[] = new char[PLANE_X*PLANE_Y],
LevelPlane[] = new char[PLANE_X*PLANE_Y];
int x = 0,
y = 0; // player position
boolean complete = false; // true, if game completed
int PlayerSprite = 0;
final int PLAYER_LEFT = 0,
PLAYER_UP = 1,
PLAYER_RIGHT = 2,
PLAYER_DOWN = 3,
FLOOR = 4,
WALL = 5,
GOAL = 6,
STONE = 7;
final String LEVEL_FILE = "Level/SCREEN."; // startup level = LEVEL_FILE + "1";
int Level = 1;
final int MAX_LEVEL = 10; // count of existing levels
Choice LevelChoice=null;
public Sokoban() {
super();
img = createImage( PLANE_X*LEN, PLANE_Y*LEN);
}
public void init() {
it = new ImageTracker( this, "img");
readLevel( LEVEL_FILE + Level );
resetLevel();
setLayout(new BorderLayout());
Panel p = new Panel();
p.setLayout(new FlowLayout());
p.add( new Button(" Reset ") );
LevelChoice = new Choice();
for(int i=1; i<MAX_LEVEL; i++)
LevelChoice.addItem(" Level " + i + " ");
p.add( LevelChoice);
add( "South", p );
}
public void paint(Graphics g) {
g.drawImage( img, 0, 0, this );
}
public boolean handleEvent(Event evt) {
if(evt.id == Event.KEY_ACTION) { // Cursor keys movement
switch (evt.key) {
case Event.UP: PlayerSprite=PLAYER_UP; movePlayer(0,-1);
break;
case Event.DOWN: PlayerSprite=PLAYER_DOWN; movePlayer(0,1);
break;
case Event.RIGHT: PlayerSprite=PLAYER_RIGHT; movePlayer(1,0);
break;
case Event.LEFT: PlayerSprite=PLAYER_LEFT; movePlayer(-1,0);
break;
}
return true;
}
if(evt.id == Event.ACTION_EVENT) {
if(evt.arg==" Reset ") resetLevel();
if(evt.target instanceof Choice) {
Level=LevelChoice.getSelectedIndex()+1;
readLevel(LEVEL_FILE + Level);
resetLevel();
}
return true;
}
return super.handleEvent( evt );
}
public void start() {
thread = new Thread(this);
thread.start();
}
public void run() {
while(true) {
getGraphics().drawImage( img, 0, 0, this);
try { thread.sleep(SLEEP); } catch(InterruptedException e) {};
}
}
final int pos( int px, int py)
{
return py*PLANE_X+px;
}
public void movePlayer(int relx, int rely)
{
if(PlayPlane[pos(x+relx,y+rely)]!='#') {// if there is no wall ...
Graphics g = img.getGraphics();
if(g==null) return;
if( PlayPlane[pos(x+relx,y+rely)]!='$' ) { // ... and no stone:
PlayPlane[pos(x,y)]=OrgPlane[pos(x,y)];
g.drawImage( it.getImage( OrgPlane[pos(x,y)]=='.' ? GOAL : FLOOR), x*LEN, y*LEN, this);
PlayPlane[pos(x+=relx,y+=rely)]='@'; // move player to new position
g.drawImage( it.getImage(PlayerSprite), x*LEN, y*LEN, this);
}
else // ... else if there a stone:
if( PlayPlane[pos(x+2*relx,y+2*rely)]!='#'
&& PlayPlane[pos(x+2*relx,y+2*rely)]!='$' ) // if there is no wall or other stone
{
PlayPlane[pos(x,y)]=OrgPlane[pos(x,y)]; //
g.drawImage( it.getImage( OrgPlane[pos(x,y)]=='.' ? GOAL : FLOOR), x*LEN, y*LEN, this);
PlayPlane[pos(x+=relx,y+=rely)]='@'; // move player to new position
g.drawImage( it.getImage(PlayerSprite), x*LEN, y*LEN, this);
PlayPlane[pos(x+relx,y+rely)]='$'; // move stone to new psoition
g.drawImage( it.getImage(STONE), (x+relx)*LEN, (y+rely)*LEN, this);
int i = PLANE_X*PLANE_Y; // game completed ?
complete=true;
while(--i>=0)
if( OrgPlane[i]=='.' && PlayPlane[i]!='$' ) complete=false;
if(complete) {
if(Level+1 < MAX_LEVEL) { // read next level
LevelChoice.select(Level);
readLevel(LEVEL_FILE + (++Level));
}
resetLevel();
complete=false;
}
}
}
}
/** reads level from file LevelPlane_File
to LevelPlane
*/
void readLevel( String LevelPlane_File ) {
String s = null;
int iy = 0;
showStatus("Loading next Level ...");
try {
DataInputStream in = new DataInputStream( new URL( getDocumentBase(),
LevelPlane_File ).openStream() );
while( (s=in.readLine()) != null ) {
s.getChars( 0, s.length(), LevelPlane, pos(0,iy));
LevelPlane[pos(s.length(),iy++)]='\n';
}
in.close();
} // let rest of LevelPlane start with '\n'
catch( IOException e ) {
showStatus("An IOException occured us by loading levelfile \""
+ LevelPlane_File + "\". Please reload Page."); }
showStatus("");
while(iy<PLANE_Y) LevelPlane[pos(0,iy++)]='\n';
}
/** reset current level
*/
void resetLevel() {
if(img==null) img = createImage( PLANE_Y*LEN, PLANE_Y*LEN );
Graphics g = img.getGraphics();
for( int y=0; y<PLANE_Y; y++) {
NextLine:
for( int x=0; x<PLANE_X; x++) {
int SpriteId=-1;
switch ( LevelPlane[ pos( x, y) ] ) {
case ' ': if(SpriteId==-1) SpriteId=FLOOR;
case '.': if(SpriteId==-1) SpriteId=GOAL;
case '#': if(SpriteId==-1) SpriteId=WALL;
case '$': if(SpriteId==-1) SpriteId=STONE;
case '@': if( (PlayPlane[pos(x,y)]=LevelPlane[pos(x,y)]) =='@') {
g.drawImage( it.getImage(PLAYER_DOWN), x*LEN, y*LEN, this);
this.x = x;
this.y = y;
break;
}
g.drawImage( it.getImage(SpriteId), x*LEN, y*LEN, this);
break;
case '\r': x--; break; // ignore carriage return
case '\n': while(x<PLANE_X) { // clear rest of line
PlayPlane[pos(x,y)]=' ';
g.drawImage( it.getImage(FLOOR), LEN*x++, LEN*y, this);
}
break NextLine; // goto NextLine
}
}
}
System.arraycopy( LevelPlane, 0, PlayPlane, 0, PLANE_X*PLANE_Y);
System.arraycopy( LevelPlane, 0, OrgPlane, 0, PLANE_X*PLANE_Y);
OrgPlane[pos(this.x,this.y)]=' '; // delete player from OrgPlane
int r = PLANE_X*PLANE_Y;
while(--r>=0)
if(OrgPlane[r]=='$') OrgPlane[r]=' '; // delete all stones from OrgPlane
}
public Dimension minimumSize() {
return new Dimension( PLANE_X*LEN, PLANE_Y*LEN );
}
public Dimension preferredSize() {
return minimumSize();
}
}