主要的蛇的类

  1. import java.awt.Color;
  2. import java.awt.Graphics;
  3. import java.awt.HeadlessException;
  4. import java.awt.Rectangle;
  5. import java.awt.event.KeyEvent;
  6. import java.util.Random;
  7.  
  8. public class Snake {
  9.  
  10. private Node head = null;
  11. private Node tail = null;
  12. int size = 0;
  13. private boolean live = true;
  14.  
  15. /**
  16. * 判断蛇是否活着
  17. * @return true则活着 false则死亡
  18. */
  19. public boolean isLive() {
  20. return live;
  21. }
  22. /**
  23. * 设置蛇的生死
  24. * @param live true则活着 false则死亡
  25. */
  26. void setLive(boolean live){
  27. this.live = live;
  28. }
  29.  
  30. private Yard y;
  31.  
  32. Node n = new Node(15, 15, Dir.L);
  33. /**
  34. * 构造方法
  35. * @param y
  36. */
  37. public Snake(Yard y){
  38. this.y = y;
  39. head = n;
  40. tail = n;
  41. size++;
  42. }
  43.  
  44. /**
  45. * 将一个结点添加到蛇的链表中
  46. */
  47. void addToTail(){
  48. Node node = null;
  49. switch (tail.dir) {
  50. case L:
  51. node = new Node(tail.row, tail.col+1, tail.dir);
  52. break;
  53. case U:
  54. node = new Node(tail.row+1, tail.col, tail.dir);
  55. break;
  56. case R:
  57. node = new Node(tail.row, tail.col-1, tail.dir);
  58. break;
  59. case D:
  60. node = new Node(tail.row-1, tail.col, tail.dir);
  61. break;
  62. }
  63. tail.next = node;
  64. node.prev = tail;
  65. tail = node;
  66. size++;
  67. }
  68.  
  69. /**
  70. * 将一个结点从蛇的尾巴处删除
  71. */
  72. void deleteFromTail(){
  73. if(size == 0) return;
  74. tail = tail.prev;
  75. tail.next = null;
  76. size--;
  77. }
  78.  
  79. /**
  80. * 设置使蛇的位置向前移动一步
  81. */
  82. void move(){
  83. addToHead();
  84. deleteFromTail();
  85. checkDead();
  86. }
  87. /**
  88. * 蛇的重画方法
  89. * @param g
  90. */
  91. void draw(Graphics g){
  92. if(!isLive() || size == 0) {
  93. return;
  94. }
  95. move();
  96. for(Node node = head ; node != null ; node = node.next){
  97. node.draw(g);
  98. }
  99.  
  100. }
  101. /**
  102. * 将一个结点加到蛇链表的头部
  103. */
  104. void addToHead(){
  105. Node node = null;
  106. switch (head.dir) {
  107. case L:
  108. node = new Node(head.row, head.col-1, head.dir);
  109. break;
  110. case U:
  111. node = new Node(head.row-1, head.col, head.dir);
  112. break;
  113. case R:
  114. node = new Node(head.row, head.col+1, head.dir);
  115. break;
  116. case D:
  117. node = new Node(head.row+1, head.col, head.dir);
  118. break;
  119. }
  120. node.next = head;
  121. head.prev = node ;
  122. head = node ;
  123. size++;
  124. }
  125.  
  126. /**
  127. * 保存蛇单个结点信息的类
  128. */
  129. private class Node{
  130. int w = Yard.BLOCK_SIZE;
  131. int h = Yard.BLOCK_SIZE;
  132. Dir dir = Dir.L;
  133. int row,col;
  134.  
  135. Node next = null;
  136. Node prev = null;
  137.  
  138. public Node(int row,int col,Dir dir){
  139. this.row = row;
  140. this.col = col;
  141. this.dir = dir;
  142. }
  143. //蛇单个节点的画法
  144. public void draw(Graphics g){
  145. Color c = g.getColor();
  146. g.setColor(Color.BLACK);
  147. g.fillRect(col*Yard.BLOCK_SIZE, row*Yard.BLOCK_SIZE, w, h);
  148. g.setColor(c);
  149. }
  150.  
  151. }
  152. /**
  153. * 键盘监听
  154. * @param e
  155. */
  156. public void keyPressed(KeyEvent e) {
  157. int key = e.getKeyCode();
  158. switch(key){
  159. case KeyEvent.VK_LEFT:
  160. if(head.dir != Dir.R) head.dir = Dir.L;
  161. break;
  162. case KeyEvent.VK_UP:
  163. if(head.dir != Dir.D) head.dir = Dir.U;
  164. break;
  165. case KeyEvent.VK_RIGHT:
  166. if(head.dir != Dir.L) head.dir = Dir.R;
  167. break;
  168. case KeyEvent.VK_DOWN:
  169. if(head.dir != Dir.U) head.dir = Dir.D;
  170. break;
  171. case KeyEvent.VK_F2:
  172. if(!this.isLive()){
  173. y.snake = new Snake(y);
  174. }
  175. break;
  176. }
  177. }
  178.  
  179. /**
  180. * 吃食物
  181. * @param f
  182. */
  183. public void eatFood(Food f){
  184. if(this.getRect().intersects(f.getRect())){
  185. f.setPos();
  186. y.setScore();
  187. this.addToTail();
  188. }
  189. }
  190.  
  191. /**
  192. * 通过检测来设置蛇的生死
  193. */
  194. public void checkDead(){
  195. if(head.col < 0 || head.col > Yard.COLS || head.row < 3 || head.row > Yard.ROWS-1){
  196. setLive(false);
  197. }
  198. if(size >= 4){
  199. for(Node node = head.next;node != null ; node = node.next){
  200. if(head.row == node.row && head.col == node.col){
  201. setLive(false);
  202. }
  203. }
  204. }
  205. }
  206.  
  207. public Rectangle getRect(){
  208. return new Rectangle(head.col*Yard.BLOCK_SIZE,head.row*Yard.BLOCK_SIZE,Yard.BLOCK_SIZE,Yard.BLOCK_SIZE);
  209. }
  210. }

吃的食物的类

  1. import java.awt.Color;
  2. import java.awt.Graphics;
  3. import java.awt.Rectangle;
  4. import java.util.Random;
  5.  
  6. public class Food {
  7. int row,col;
  8. int h = Yard.BLOCK_SIZE;
  9. int w = Yard.BLOCK_SIZE;
  10. private static Random rd = new Random();
  11. int step = 0;
  12.  
  13. public Food(int row ,int col) {
  14. this.row = row;
  15. this.col = col;
  16. }
  17.  
  18. public void draw(Graphics g){
  19. Color c = g.getColor();
  20. if(step == 0){
  21. g.setColor(Color.RED);
  22. step++;
  23. }else if(step == 1){
  24. g.setColor(Color.green);
  25. step++;
  26. }else {
  27. g.setColor(Color.WHITE);
  28. step = 0;
  29. }
  30.  
  31. g.fillOval(col*Yard.BLOCK_SIZE, row*Yard.BLOCK_SIZE, w, h);
  32. g.setColor(c);
  33. }
  34.  
  35. public Rectangle getRect(){
  36. return new Rectangle(col*Yard.BLOCK_SIZE, row*Yard.BLOCK_SIZE, w, h);
  37. }
  38.  
  39. void setPos(){
  40. this.row = rd.nextInt(Yard.ROWS-3)+3;
  41. this.col = rd.nextInt(Yard.COLS);
  42. }
  43. }

方向的枚举

  1. public enum Dir {
  2. L,U,R,D
  3. }

主界面的类

  1. import java.awt.Color;
  2. import java.awt.Font;
  3. import java.awt.Frame;
  4. import java.awt.Graphics;
  5. import java.awt.Image;
  6. import java.awt.event.KeyAdapter;
  7. import java.awt.event.KeyEvent;
  8. import java.awt.event.WindowAdapter;
  9. import java.awt.event.WindowEvent;
  10.  
  11. class Yard extends Frame{
  12.  
  13. PaintThread pt = null;
  14. /**
  15. * 速度 设置数字越大 越慢
  16. */
  17. public static final int SPEED = 4;
  18. /**
  19. * 行数
  20. */
  21. public static final int ROWS = 30;
  22. /**
  23. * 列数
  24. */
  25. public static final int COLS = 30;
  26. /**
  27. * 行列的宽度
  28. */
  29. public static final int BLOCK_SIZE = 15;
  30.  
  31. /**
  32. * 在游戏窗口中加入一条蛇
  33. */
  34. public Snake snake = new Snake(this);
  35.  
  36. /**
  37. * 在游戏窗口中加入一个食物
  38. */
  39. public Food food = new Food(10,10);
  40.  
  41. private Font font = new Font("宋体", Font.BOLD,30 );
  42.  
  43. private Image offScreenImage = null;
  44.  
  45. //分数
  46. private int score = 0;
  47.  
  48. public int getScore() {
  49. return score;
  50. }
  51.  
  52. public void setScore() {
  53. this.score += 5;
  54. }
  55.  
  56. /**
  57. * 窗口构建函数
  58. */
  59. public void launch(){
  60.  
  61. pt = new PaintThread();
  62. this.setLocation(200, 200);
  63. this.setSize(COLS * BLOCK_SIZE, ROWS * BLOCK_SIZE);
  64. this.addWindowListener(new WindowAdapter() {
  65.  
  66. public void windowClosing(WindowEvent e) {
  67. System.exit(0);
  68. }
  69.  
  70. });
  71.  
  72. this.setVisible(true);
  73. this.addKeyListener(new KeyMonitor());
  74. this.setResizable(false);
  75. //开始重画线程
  76. new Thread(pt).start();
  77.  
  78. }
  79.  
  80. /**
  81. * 主方法
  82. * @param args
  83. */
  84. public static void main(String[] args){
  85. new Yard().launch();
  86. }
  87.  
  88. /**
  89. * 重写的paint方法 用来画出各个元素
  90. */
  91. @Override
  92. public void paint(Graphics g) {
  93.  
  94. Color c = g.getColor();
  95. g.setColor(Color.GRAY);
  96. g.fillRect(0, 0, COLS * BLOCK_SIZE, ROWS * BLOCK_SIZE);
  97. g.setColor(Color.DARK_GRAY);
  98.  
  99. //画出横线
  100. for(int i=1; i<ROWS; i++) {
  101. g.drawLine(0, BLOCK_SIZE * i, COLS * BLOCK_SIZE, BLOCK_SIZE * i);
  102. }
  103. for(int i=1; i<COLS; i++) {
  104. g.drawLine(BLOCK_SIZE * i, 0, BLOCK_SIZE * i, BLOCK_SIZE * ROWS);
  105. }
  106.  
  107. snake.eatFood(food);
  108. g.setColor(Color.YELLOW);
  109. g.drawString("score :" + score, 10, 50);
  110. food.draw(g);
  111.  
  112. if(snake.isLive()) {
  113. snake.draw(g);
  114. }else{
  115. g.setColor(Color.YELLOW);
  116. g.setFont(font);
  117. g.drawString("Game Over!", 125, 225);
  118. }
  119. g.setColor(c);
  120.  
  121. }
  122.  
  123. /**
  124. * 重写的update用来防止屏幕闪烁
  125. */
  126. @Override
  127. public void update(Graphics g) {
  128.  
  129. if(offScreenImage == null){
  130. offScreenImage = this.createImage(COLS*BLOCK_SIZE, ROWS*BLOCK_SIZE);
  131. }
  132. Graphics graphics = offScreenImage.getGraphics();
  133. paint(graphics);
  134.  
  135. g.drawImage(offScreenImage, 0, 0, null);
  136. }
  137.  
  138. /**
  139. * 重画线程
  140. */
  141. private class PaintThread implements Runnable{
  142. private boolean flag = true;
  143.  
  144. private boolean pause = false;
  145. @Override
  146. public void run() {
  147. while(flag){
  148. if(!pause)
  149. repaint();
  150. try {
  151. Thread.sleep(25*SPEED);
  152. } catch (InterruptedException e) {
  153. e.printStackTrace();
  154. }
  155. }
  156. }
  157.  
  158. public void stopPaintThread(){
  159. flag = !flag;
  160. }
  161.  
  162. public void pausePaintThread(){
  163. pause = !pause;
  164. }
  165. }
  166.  
  167. /**
  168. * 键盘监听类
  169. */
  170. private class KeyMonitor extends KeyAdapter{
  171.  
  172. @Override
  173. public void keyPressed(KeyEvent e) {
  174. int key = e.getKeyCode();
  175. if(key == KeyEvent.VK_SPACE){
  176. pt.pausePaintThread();
  177. }
  178. snake.keyPressed(e);
  179. }
  180.  
  181. }
  182. }

贪吃蛇java版的更多相关文章

  1. 原生js写的贪吃蛇网页版游戏特效

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <bo ...

  2. c/c++ 贪吃蛇控制台版

    贪吃蛇控制台版(操作系统win7 64位:编译环境gcc, vs2017通过,其它环境未测试 不保证一定通过) 运行效果: #include <iomanip> #include < ...

  3. 贪吃蛇 Java实现(一)

    贪吃蛇  Java实现 1.面向对象思想 1.创建antition包它是包含sanke  Ground Food类 2.创建Controller包controller类 3.创建Game包有game类 ...

  4. js贪吃蛇-简单版

    分享个用原生js写的贪吃蛇,最近在学java,按照当年写的 js的思路,转换成java,换汤不换药 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1 ...

  5. 如何用python制作贪吃蛇以及AI版贪吃蛇

    用python制作普通贪吃蛇 哈喽,大家不知道是上午好还是中午好还是下午好还是晚上好! 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很 ...

  6. C语言 贪吃蛇

    贪吃蛇(单人版): 本人先来介绍一个函数 -- bioskey函数: int bioskey (int cmd) 参数 (cmd) 基本功能 0 返回下一个从键盘键入的值(若不键入任何值,则将等下一个 ...

  7. 原生JavaScript贪吃蛇

    在实例开发过程中还是能认识到很多不足的,并且加强了一些基础. 简单写一下制作过程: 1.创建画布 2.创建蛇和老鼠 坐标不能重叠 3.让蛇移动起来 4.添加死亡方法 5.添加转点坐标和方向 6.添加吃 ...

  8. 原生Js贪吃蛇游戏实战开发笔记

    前言 本课程是通过JavaScript结合WebAPI DOM实现的一版网页游戏---贪吃蛇的开发全过程,采用面向以象的思想设计开发.通过这个小游戏的开发, 不仅可以掌握JS的语法的应用,还可以学会D ...

  9. 用GUI实现java版贪吃蛇小游戏

    项目结构 新建一个JFrame窗口,作为程序入口 public class GameStart{ public static void main(String[] args) { JFrame jFr ...

随机推荐

  1. [JS] ECMAScript 6 - Async : compare with c#

    一段引言: Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大. 它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对 ...

  2. Zoomit的用法总结

    今天才发现Zoomit,相见恨晚.总结一下zoomit的使用方法,备用. Zoomit是一款超赞的演示辅助工具.具有屏幕缩放.屏幕画笔.倒计时功能.且无需安装,点开即用. 1. 屏幕缩放 Ctrl + ...

  3. MySQL 无法连接

    Host 'localhost' is not allowed to connect to this MySQL server 错误 解决办法: C:\Program Files\MySQL\MySQ ...

  4. php MongoDB driver 查询实例

    //是否只查mx $mx_on_switch = I("post.mx_on_switch"); //mx模糊查询 $mx_vague_check = I("post.m ...

  5. Spark RDD Transformation 简单用例(二)

    aggregateByKey(zeroValue)(seqOp, combOp, [numTasks]) aggregateByKey(zeroValue)(seqOp, combOp, [numTa ...

  6. ADT下载地址(申明:来源于网络)

    ADT下载地址(含各版本),最新ADT-23.0.6(申明:来源于网络) 地址:http://write.blog.csdn.net/mdeditor

  7. Men and women can't be 'just friends

    Men and women can't be 'just friends' Can heterosexual men and women ever be "just friends" ...

  8. IAR 跳转路径错误

    拷贝的代码 右键跳转的时候提示路径错误,是因为别人编译的中间文件 .ojb文件在你的电脑上不一样,拷贝代码后第一件事就是清楚obj中间连接文件,然后重新在你的电脑上编译.

  9. [No0000179]改善C#程序的建议2:C#中dynamic的正确用法

    dynamic是FrameWork4.0的新特性.dynamic的出现让C#具有了弱语言类型的特性.编译器在编译的时候不再对类型进行检查,编译期默认dynamic对象支持你想要的任何特性.比如,即使你 ...

  10. [No0000132]正确使用密码加盐散列[译]

    如果你是一个 web 开发工程师,可能你已经建立了一个用户账户系统.一个用户账户系统最重要的部分是如何保护密码.用户账户数据库经常被黑,如果你的网站曾经被攻击过,你绝对必须做点什么来保护你的用户的密码 ...