import java.awt.Canvas; import java.awt.Frame; import java.awt.Graphics; import java.awt.Color; import java.awt.event.KeyListener; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.awt.image.BufferedImage; public class Snake extends Canvas implements Runnable, KeyListener { boolean playing; boolean updated; int state; int dx, dy; int dx2, dy2; int bitCount; final int height = 500; final int width = 500; long sleep; Frame frame; BufferedImage off; Graphics canvas; Coord head; Coord food; static Thread game; ArrayList bits; public static void main(String args[]) { Snake snake = new Snake(); game = new Thread(snake); game.start(); } public Snake() { sleep = 100; playing = true; off = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); canvas = off.getGraphics(); frame = new Frame("Snake - RLN"); frame.add(this); addKeyListener(this); frame.addKeyListener(this); frame.setSize(506, 532); frame.setResizable(false); frame.setVisible(true); state = 0; } public void run() { try { while(true) { process(); Thread.sleep(sleep); } } catch (Exception e) { e.printStackTrace(); } } public void paint(Graphics g) { g.drawImage(off, 0, 0, width, height, this); } public void process() { switch(state) { case 0: // init bitCount = 0; updated = false; bits = new ArrayList(20); head = new Coord(100, 100); food = new Coord((int)(Math.random() * 50) * 10, (int)(Math.random() * 50) * 10); bits.add(head); ++bitCount; dx = 1; dy = 0; dx2 = 1; dy2 = 0; state = 1; break; case 1: // game loop if(head.equals(food)) { Coord coord = new Coord(0, 0); bits.add(coord); ++bitCount; food.x = (int)(Math.random() * 50) * 10; food.y = (int)(Math.random() * 50) * 10; if((bitCount - 1) % 2 == 0 && sleep > 5) sleep -= 5; } canvas.setColor(Color.GREEN); canvas.fillRect(0, 0, height, width); canvas.setColor(Color.WHITE); for(int i = bitCount - 1; i >= 0; --i) { if(i == 0) bits.get(i).translate(head.x + dx * 10, head.y + dy * 10); else bits.get(i).translate(bits.get(i - 1).x, bits.get(i - 1).y); canvas.fillRect(bits.get(i).x, bits.get(i).y, 10, 10); } canvas.setColor(Color.RED); canvas.fillRect(food.x, food.y, 10, 10); updated = false; if(head.x < 0 || head.x > width || head.y < 0 || head.y > height) { state = 2; playing = false; sleep = 100; break; } for(int i = 1; i < bitCount; ++i) { if(bits.get(i).equals(head)) { state = 2; playing = false; sleep = 100; break; } } paint(getGraphics()); break; case 2: // game over canvas.setColor(Color.GREEN); canvas.fillRect(0, 0, width, height); canvas.setColor(Color.BLUE); canvas.drawString("Game over!", 180, 250); canvas.drawString("Score: " + (bitCount - 1) * 10, 180, 260); canvas.drawString("Press to play again", 180, 270); paint(getGraphics()); break; default: break; } } public void keyReleased(KeyEvent e) { } public void keyPressed(KeyEvent e) { int k = e.getKeyCode(); if(!updated) { if(k == e.VK_UP) { if(dy == 1 && bitCount > 1) return; dy = -1; dx = 0; updated = true; } else if(k == e.VK_DOWN) { if(dy == -1 && bitCount > 1) return; dy = 1; dx = 0; updated = true; } else if(k == e.VK_LEFT) { if(dx == 1 && bitCount > 1) return; dx = -1; dy = 0; updated = true; } else if(k == e.VK_RIGHT) { if(dx == -1 && bitCount > 1) return; dx = 1; dy = 0; updated = true; } } if(k == e.VK_ENTER && !playing) { state = 0; playing = true; } } public void keyTyped(KeyEvent e) { } } class Coord { int x; int y; public Coord(int x, int y) { this.x = x; this.y = y; } public void translate(int x, int y) { this.x = x; this.y = y; } public boolean equals(Coord c) { return c.x == x && c.y == y; } }