rendered paste bodyimport java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class Snake extends Frame implements Runnable,WindowListener,KeyListener {
private static final long serialVersionUID = -3029394778317566533L;
public static final int FPS = 30;
public static final int GAMEAREAWIDTH = 20;
public static final int GAMEAREAHEIGHT = 20;
public static final int GAMEAREABGCOLOR = 0xFFFFFF;
public static final int GAMEAREABORDERCOLOR = 0xFFFFFF;
public static final int BLOCKSIZE = 16;
public static final int NUMOFFOODS = 80;
public static final int STATE_NORMAL = 0;
public static final int STATE_STOPPED = 1;
public static boolean cont;
public static Snake inst;
public boolean inProgress;
public int score;
public static final Random randGen = new Random(System.currentTimeMillis());
Thread drawThread;
Graphics bbGraphics;
Image bbImage;
long lastUpdate;
long lastMove;
Boolean[] keys;
int state;
Follower snake;
Food[] foods;
Point direction;
public static void main(String[] args) {
cont = true;
while(cont) {
inst = new Snake();
while(inst.inProgress) {
try {
Thread.sleep(1000);
} catch(Exception e) {}
}
}
System.exit(0);
}
public Snake() {
inProgress = true;
// SET UP WINDOW
this.setTitle("Snake : 1");
this.setResizable(false);
this.setBackground(Color.white);
this.setForeground(Color.black);
this.addWindowListener(this);
this.addKeyListener(this);
this.setVisible(true);
this.setSize(getInsets().left+getInsets().right+GAMEAREAWIDTH*BLOCKSIZE, getInsets().top+getInsets().bottom+GAMEAREAHEIGHT*BLOCKSIZE);
Dimension dim = getToolkit().getScreenSize();
Rectangle abounds = getBounds();
this.setLocation((dim.width - abounds.width) / 2, (dim.height - abounds.height) / 2);
// SET UP KEYS
keys = new Boolean[256];
synchronized(keys) {
for(int i=0;i<keys.length;i++) {
keys[i] = Boolean.FALSE;
}
}
score = 1;
// SNAKE
snake = new Follower(0,0,true);
direction = new Point(1,0);
// FOOD
foods = new Food[NUMOFFOODS];
for(int i=0;i<foods.length;i++) {
foods[i] = new Food(0,0);
foods[i].shuffle(snake);
}
// STATE
state = STATE_NORMAL;
// SET UP BACKBUFFER
bbImage = this.createImage(this.getWidth(), this.getHeight());
bbGraphics = bbImage.getGraphics();
drawThread = new Thread(this);
// START DRAWING
drawThread.start();
}
public void dispose() {
inProgress = false;
super.dispose();
}
public void paint(Graphics g) {
if(bbImage!=null && bbGraphics!=null)
draw(g);
}
public void update(Graphics g) {
if(bbImage!=null && bbGraphics!=null)
draw(g);
}
public void run() {
while(true) {
lastUpdate = System.currentTimeMillis();
checkKeys();
processEvents();
repaint();
try {Thread.sleep(Math.max(1,lastUpdate+1000/FPS-System.currentTimeMillis()));}
catch(Exception e) {}
}
}
public void checkKeys() {
// check for key presses...
// remember - TRUE means pressed, null means acknowledged, FALSE means released
synchronized(keys) {
//if(state==STATE_STOPPED) return;
if(keys[KeyEvent.VK_UP]==Boolean.TRUE && direction.y!=1) {
direction = new Point(0,-1);
keys[KeyEvent.VK_UP] = null;
}
else if(keys[KeyEvent.VK_LEFT]==Boolean.TRUE && direction.x!=1) {
direction = new Point(-1,0);
keys[KeyEvent.VK_LEFT] = null;
}
else if(keys[KeyEvent.VK_RIGHT]==Boolean.TRUE && direction.x!=-1) {
direction = new Point(1,0);
keys[KeyEvent.VK_RIGHT] = null;
}
else if(keys[KeyEvent.VK_DOWN]==Boolean.TRUE && direction.y!=-1) {
direction = new Point(0,1);
keys[KeyEvent.VK_DOWN] = null;
}
else if(keys[KeyEvent.VK_F2]==Boolean.TRUE) {
this.dispose();
}
}
}
public void processEvents() {
// move snake, generate new snake tail if necessary, whatever.
if(state==STATE_NORMAL && lastUpdate>lastMove+150) {
snake.moveBy(direction.x, direction.y);
if(snake.collidesWithSelf()) gameOver();
else {
for(int i=0;i<foods.length;i++) {
if(foods[i].intersects(snake)) {
snake.eat();
foods[i].shuffle(snake);
}
}
}
lastMove = lastUpdate;
}
}
public void gameOver() {
state = STATE_STOPPED;
this.setTitle("Snake : "+score+((state==STATE_STOPPED)?" [game over]":""));
}
public void incrementScore() {
score++;
this.setTitle("Snake : "+score+((state==STATE_STOPPED)?" [game over]":""));
}
public void draw(Graphics g) {
bbGraphics.clearRect(0,0,getWidth(),getHeight());
//----------------------------------
snake.draw(bbGraphics);
for(int i=0;i<foods.length;i++)
foods[i].draw(bbGraphics);
//----------------------------------
g.drawImage(bbImage,0,0,null);
}
public void windowActivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowClosing(WindowEvent e) {cont = false; this.dispose();}
public void windowDeactivated(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
public void keyTyped(KeyEvent e) {}
public void keyPressed(KeyEvent e) {
synchronized(keys) {
if(keys[e.getKeyCode()]==Boolean.FALSE) keys[e.getKeyCode()] = Boolean.TRUE;
}
}
public void keyReleased(KeyEvent e) {
synchronized(keys) {
keys[e.getKeyCode()] = Boolean.FALSE;
}
}
protected class Follower {
Point pos;
Follower next;
boolean head;
public Follower(int x, int y, boolean head) {
pos = new Point(x,y);
this.head = head;
}
public Follower(int x, int y) {
this(x,y,false);
}
public void draw(Graphics g) {
g.setColor(Color.blue);
g.fillOval(getInsets().left+pos.x*BLOCKSIZE,getInsets().top+pos.y*BLOCKSIZE,BLOCKSIZE,BLOCKSIZE);
if(head) {
g.setColor(Color.black);
g.fillOval(getInsets().left+pos.x*BLOCKSIZE+BLOCKSIZE/4,getInsets().top+pos.y*BLOCKSIZE+BLOCKSIZE/4,BLOCKSIZE/2,BLOCKSIZE/2);
}
if(next!=null) next.draw(g);
}
public void moveTo(int x, int y) {
if(pos.x==x&&pos.y==y) return;
if(next!=null) next.moveTo(pos.x,pos.y);
pos.x=x;
pos.y=y;
if(x<0||y<0||x>GAMEAREAWIDTH-1||y>GAMEAREAHEIGHT-1) gameOver();
}
public void moveBy(int x, int y) {
this.moveTo(pos.x+x,pos.y+y);
}
public void eat() {
if(next==null) {
next = new Follower(pos.x,pos.y);
incrementScore();
} else {
next.eat();
}
}
public boolean collidesWithSelf() {
return (next==null)? false : next.intersects(pos.x,pos.y);
}
public boolean intersects(int x, int y) {
if(pos.x==x && pos.y==y) return true;
else return (next==null)?false:next.intersects(x, y);
}
}
protected class Food {
Point pos;
public Food(int x, int y) {
pos = new Point(x,y);
}
public boolean intersects(Follower f) {
return f.intersects(pos.x,pos.y);
}
public void shuffle(Follower f) {
this.shuffle(new Follower[]{f});
}
public void shuffle(Follower[] fs) {
if(fs.length<1) return;
LABEL1:
while(true) {
pos.x = randGen.nextInt(GAMEAREAWIDTH);
pos.y = randGen.nextInt(GAMEAREAHEIGHT);
for(int i=0;i<fs.length;i++)
if(fs[i].intersects(pos.x, pos.y)) continue LABEL1;
break;
}
}
public void draw(Graphics g) {
g.setColor(Color.green);
g.fillOval(getInsets().left+pos.x*BLOCKSIZE,getInsets().top+pos.y*BLOCKSIZE,BLOCKSIZE,BLOCKSIZE);
}
}
}