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 }
时间: 2024-10-11 00:48:33