贪吃蛇单机版

  1 package greedySnaker;
  2 
  3 import java.awt.Graphics;
  4 import java.util.LinkedList;
  5 
  6 /**
  7  * 蛇类
  8  * @author 俊霖
  9  *
 10  */
 11 public class Snake {
 12     private Direction dir = Direction.LEFT;
 13     private LinkedList<SnakeNode> list = new LinkedList<SnakeNode>();
 14     private boolean isAlive = true;
 15     public Snake(){
 16         for (int i = 0; i < GameContext.SNAKE_LENGTH; i++) {
 17             list.add(new SnakeNode(270 + i * GameContext.SNAKE_SIZE, 290,i == 0));
 18         }
 19     }
 20     /**
 21      * 改变蛇的方向
 22      * @param dir 新的方向
 23      */
 24     public void changeDir(Direction newDir) {
 25         if (!((dir == Direction.LEFT && newDir == Direction.RIGHT) ||
 26             (dir == Direction.RIGHT && newDir == Direction.LEFT) ||
 27             (dir == Direction.UP && newDir == Direction.DOWN) ||
 28             (dir == Direction.DOWN && newDir == Direction.UP))) {
 29             dir = newDir;
 30         }
 31     }
 32     public SnakeNode getHead() {
 33         return list.get(0);
 34     }
 35     public SnakeNode getTail() {
 36         return list.get(list.size() - 1);
 37     }
 38     /**
 39      * 移动
 40      */
 41     public void move(){
 42         SnakeNode headNode = getHead();
 43         int x = headNode.getX();
 44         int y = headNode.getY();
 45         int size = GameContext.SNAKE_SIZE;
 46         switch (dir) {
 47         case UP:
 48             y -= size;
 49             break;
 50         case DOWN:
 51             y += size;
 52             break;
 53         case LEFT:
 54             x -= size;
 55             break;
 56         case RIGHT:
 57             x += size;
 58             break;
 59         }
 60         SnakeNode newNode = new SnakeNode(x, y,true);
 61         for (SnakeNode snakeNode : list) {
 62             snakeNode.setHead(false);
 63         }
 64         list.addFirst(newNode);
 65     }
 66     public void remove() {
 67         list.removeLast();
 68     }
 69     /**
 70      * 返回到上一步
 71      */
 72     public void returnBack() {
 73         SnakeNode headNode = getTail();
 74         int x = headNode.getX();
 75         int y = headNode.getY();
 76         int size = GameContext.SNAKE_SIZE;
 77         switch (dir) {
 78         case UP:
 79             y += size;
 80             break;
 81         case DOWN:
 82             y -= size;
 83             break;
 84         case LEFT:
 85             x += size;
 86             break;
 87         case RIGHT:
 88             x -= size;
 89             break;
 90         }
 91         SnakeNode newNode = new SnakeNode(x, y);
 92         list.addLast(newNode);
 93         list.removeFirst();
 94         getHead().setHead(true);
 95     }
 96     /**
 97      * 蛇撞到
 98      */
 99     public void callideSnakeNode() {
100         SnakeNode head = getHead();
101         int headX = head.getX();
102         int headY = head.getY();
103         for (int i = 1; i < list.size(); i++) {
104             if (headX == list.get(i).getX() && headY == list.get(i).getY()) {
105                 isAlive = false;
106             }
107         }
108     }
109     /**
110      * 绘制
111      * @param g 画笔工具
112      */
113     public void draw(Graphics g) {
114         for (SnakeNode snakeNode : list) {
115             snakeNode.draw(g);
116         }
117     }
118     /**
119      * 蛇吃蛋
120      * @param egg
121      * @return
122      */
123     public boolean eat(Egg egg) {
124         SnakeNode headNode = getHead();
125         return headNode.getX() == egg.getX() && headNode.getY() == egg.getY();
126     }
127     public Direction getDir() {
128         return dir;
129     }
130     public boolean isAlive() {
131         return isAlive;
132     }
133     public void setAlive(boolean isAlive) {
134         this.isAlive = isAlive;
135     }
136     
137     
138 }

 1 package greedySnaker;
 2 
 3 import java.awt.Color;
 4 import java.awt.Graphics;
 5 
 6 public class Egg {
 7     private int x,y;
 8     private int size = GameContext.EGG_SIZE;
 9     public Egg(){
10         int maxX = (GameContext.SQUARER_WIDTH - GameContext.EGG_SIZE) / 20;
11         x = (int) ((int)(Math.random() * maxX) * 20 + GameContext.WALL_X);
12         int maxY = (GameContext.SQUARER_HEIGHT - GameContext.EGG_SIZE) / 20;
13         y = (int) ((int)(Math.random() * maxY) * 20 + GameContext.WALL_Y);
14     }
15     public void draw(Graphics g) {
16         g.setColor(Color.ORANGE);
17         g.fillOval(x, y, size, size);
18     }
19     public int getX() {
20         return x;
21     }
22     public int getY() {
23         return y;
24     }
25     
26 }
 1 package greedySnaker;
 2 /**
 3  * 游戏的上下文
 4  * @author 俊霖
 5  *
 6  */
 7 public class GameContext {
 8     public static final int EGG_SIZE = 20;
 9     /**
10      * 蛇的初始长度
11      */
12     public static final int SNAKE_LENGTH = 5;
13     /**
14      * 蛇的速度
15      */
16     public static final int SNAKE_SPEED = 5;
17     /**
18      * 蛇头初始坐标
19      */
20     public static final int SNAKE_X = 270;
21     public static final int SNAKE_Y = 290;
22     /**
23      * 蛇大小
24      */
25     public static final int SNAKE_SIZE = 20;
26     /**
27      * 游戏宽度
28      */
29     public static final int GAME_WIDTH = 600;
30     /**
31      * 游戏高度
32      */
33     public static final int GAME_HEIGHT = 600;
34     /**
35      * 围墙宽度
36      */
37     public static final int SQUARER_WIDTH = 500;
38     /**
39      * 围墙高度
40      */
41     public static final int SQUARER_HEIGHT = 500;
42     /**
43      * 围墙坐标
44      */
45     public static final int WALL_X = 50;
46     public static final int WALL_Y = 50;
47     /**
48      * 刷新间隔时间
49      */
50     public static final int INTERVAL = 200;
51 }
 1 package greedySnaker;
 2 
 3 import java.awt.Color;
 4 import java.awt.Graphics;
 5 /**
 6  * 蛇节点类
 7  * @author 俊霖
 8  *
 9  */
10 public class SnakeNode {
11     private int x,y;
12     private int size = GameContext.SNAKE_SIZE;
13     private boolean isHead = false;
14     
15     public SnakeNode(int x, int y) {
16         this.x = x;
17         this.y = y;
18     }
19     
20     public SnakeNode(int x, int y, boolean isHead) {
21         this.x = x;
22         this.y = y;
23         this.isHead = isHead;
24     }
25 
26     public int getX() {
27         return x;
28     }
29     public int getY() {
30         return y;
31     }
32     /**
33      * 绘制蛇节点
34      * @param g 画笔工具
35      */
36     public void draw(Graphics g) {
37         if (!isHead) {
38             g.setColor(Color.GREEN);
39         }else {
40             g.setColor(Color.RED);
41         }
42         g.fillRect(x, y, size, size);
43         g.setColor(Color.BLACK);
44         g.drawRect(x, y, size, size);
45     }
46 
47     public void setHead(boolean isHead) {
48         this.isHead = isHead;
49     }
50     
51 }
1 package greedySnaker;
2 /**
3  * 方向枚举
4  * @author 俊霖
5  *
6  */
7 public enum Direction {
8     UP,DOWN,LEFT,RIGHT
9 }
  1 package greedySnaker;
  2 
  3 import java.awt.BasicStroke;
  4 import java.awt.Color;
  5 import java.awt.Graphics;
  6 import java.awt.Graphics2D;
  7 import java.awt.Image;
  8 import java.awt.Stroke;
  9 import java.awt.event.ActionEvent;
 10 import java.awt.event.ActionListener;
 11 import java.awt.event.KeyAdapter;
 12 import java.awt.event.KeyEvent;
 13 import java.awt.image.BufferedImage;
 14 
 15 import javax.swing.JFrame;
 16 import javax.swing.Timer;
 17 
 18 
 19 @SuppressWarnings("serial")
 20 public class GameFrame extends JFrame{
 21     private Timer timer;
 22     private int score;
 23     private int interval = GameContext.INTERVAL;
 24     private Egg egg = new Egg();
 25     private Snake snake = new Snake();
 26     private Image image = new BufferedImage(GameContext.GAME_WIDTH, GameContext.GAME_HEIGHT, BufferedImage.TYPE_INT_RGB);
 27     public GameFrame(){
 28         this.setTitle("贪吃蛇");
 29         this.setSize(GameContext.GAME_WIDTH,GameContext.GAME_HEIGHT);
 30         this.setResizable(false);
 31         this.setLocationRelativeTo(null);
 32         this.setDefaultCloseOperation(EXIT_ON_CLOSE);
 33         initComponents();
 34     }
 35 
 36     private void initComponents() {
 37         this.setLayout(null);
 38         timer = new Timer(interval, new ActionListener() {
 39             
 40             @Override
 41             public void actionPerformed(ActionEvent e) {
 42                 snake.move();
 43                 snake.callideSnakeNode();
 44                 if (snake.isAlive()) {
 45                     if (snake.eat(egg)) {
 46                         egg = new Egg();
 47                         score += 10;
 48                         if (score == 100) {
 49                             interval -= 30;
 50                         } else if (score == 200) {
 51                             interval -= 50;
 52                         } else if (score == 300) {
 53                             interval -= 50;
 54                         }
 55                     } else {
 56                         snake.remove();
 57                     }
 58                     SnakeNode head = snake.getHead();
 59                     int x = head.getX();
 60                     int y = head.getY();
 61                     if (x < GameContext.WALL_X
 62                             || x > GameContext.WALL_X
 63                                     + GameContext.SQUARER_WIDTH
 64                                     - GameContext.SNAKE_SIZE
 65                             || y < GameContext.WALL_Y
 66                             || y > GameContext.WALL_Y
 67                                     + GameContext.SQUARER_HEIGHT
 68                                     - GameContext.SNAKE_SIZE) {
 69                         timer.stop();
 70                         snake.setAlive(false);
 71                     }
 72                     repaint();
 73                 }
 74             }
 75         });
 76         timer.start();
 77         this.addKeyListener(new KeyAdapter() {
 78             @Override
 79             public void keyPressed(KeyEvent e) {
 80                 Direction newDir = snake.getDir();
 81                 switch (e.getKeyCode()) {
 82                 case KeyEvent.VK_A:
 83                     newDir = Direction.LEFT;
 84                     break;
 85                 case KeyEvent.VK_D:
 86                     newDir = Direction.RIGHT;
 87                     break;
 88                 case KeyEvent.VK_W:
 89                     newDir = Direction.UP;
 90                     break;
 91                 case KeyEvent.VK_S:
 92                     newDir = Direction.DOWN;
 93                     break;
 94                 case KeyEvent.VK_F2:
 95                     snake = new Snake();    //重置蛇
 96                     newDir = Direction.LEFT;//重置方向
 97                     egg = new Egg();        //重置蛋
 98                     timer.start();
 99                     break;
100                 }
101                 if (snake.getDir() != newDir && snake.isAlive()) {
102                     snake.changeDir(newDir);
103                 }
104             }
105         });
106     }
107     @Override
108     public void paint(Graphics g) {
109         Graphics2D imageG = (Graphics2D)image.getGraphics();
110         super.paint(imageG);
111         imageG.setColor(Color.BLACK);//内存图片的画笔默认为白色,所以要设置一下画笔颜色
112         Stroke stroke = imageG.getStroke();
113         imageG.setStroke(new BasicStroke(4));
114         imageG.drawRect(GameContext.WALL_X, GameContext.WALL_Y, GameContext.SQUARER_WIDTH, GameContext.SQUARER_HEIGHT);
115         imageG.setStroke(stroke);
116         imageG.setColor(Color.RED);
117         imageG.drawString("得分:" + String.valueOf(score), 50, 40);
118         if (!snake.isAlive()) {
119             snake.returnBack();
120             imageG.setColor(Color.BLACK);
121             imageG.drawString("按F2重置游戏", 280, 40);
122         }
123         snake.draw(imageG);    
124         egg.draw(imageG);
125         g.drawImage(image, 0, 0, null);
126     }
127     public static void main(String[] args) {
128         new GameFrame().setVisible(true);
129     }
130 }

 

posted @ 2014-11-17 20:33  FJ凉风  阅读(193)  评论(0编辑  收藏  举报