[Java] 贪吃蛇代码 →→→→→进入此内容的聊天室

来自 , 2020-06-03, 写在 Java, 查看 102 次.
URL http://www.code666.cn/view/490640b4
  1. import java.awt.*;
  2. import java.awt.event.*;
  3. import javax.swing.*;
  4. import java.util.*;
  5. //=============================================
  6. //Main Class
  7. //=============================================
  8. public class GreedSnake implements KeyListener
  9. {
  10. JFrame mainFrame;
  11. Canvas paintCanvas;
  12. JLabel label得分;//计分牌
  13. SnakeModel snakeModel=null;// 蛇
  14. public static final int canvasWidth=200;
  15. public static final int canvasHeight=300;
  16. public static final int nodeWidth=10;
  17. public static final int nodeHeight=10;
  18. //----------------------------------------------------------------------
  19. //GreedSnake():初始化游戏界面
  20. //----------------------------------------------------------------------
  21. public GreedSnake()
  22. {
  23. //设置界面元素
  24. mainFrame=new JFrame("贪吃蛇");
  25. Container cp=mainFrame.getContentPane();
  26. label得分=new JLabel("得分:");
  27. cp.add(label得分,BorderLayout.NORTH);
  28. paintCanvas=new Canvas();
  29. paintCanvas.setSize(canvasWidth+1,canvasHeight+1);
  30. paintCanvas.addKeyListener(this);
  31. cp.add(paintCanvas,BorderLayout.CENTER);
  32. JPanel panelButtom=new JPanel();
  33. panelButtom.setLayout(new BorderLayout());
  34. JLabel labelHelp;// 帮助信息
  35. labelHelp=new JLabel("上下加速;",JLabel.CENTER);
  36. panelButtom.add(labelHelp,BorderLayout.NORTH);
  37. labelHelp=new JLabel("确认,R,S开始;",JLabel.CENTER);
  38. panelButtom.add(labelHelp,BorderLayout.CENTER);
  39. labelHelp=new JLabel("空格或者P暂停,卢奇",JLabel.CENTER);
  40. panelButtom.add(labelHelp,BorderLayout.SOUTH);
  41. cp.add(panelButtom,BorderLayout.SOUTH);
  42. mainFrame.addKeyListener(this);
  43. mainFrame.pack();
  44. mainFrame.setResizable(false);
  45. mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  46. mainFrame.setVisible(true);
  47. begin();
  48. }
  49. //----------------------------------------------------------------------
  50. //keyPressed():按键检测
  51. //----------------------------------------------------------------------
  52. public void keyPressed(KeyEvent e)
  53. {
  54. int keyCode=e.getKeyCode();
  55. if(snakeModel.running) switch(keyCode)
  56. {
  57. case KeyEvent.VK_UP:
  58. snakeModel.changeDirection(SnakeModel.UP);
  59. break;
  60. case KeyEvent.VK_DOWN:
  61. snakeModel.changeDirection(SnakeModel.DOWN);
  62. break;
  63. case KeyEvent.VK_LEFT:
  64. snakeModel.changeDirection(SnakeModel.LEFT);
  65. break;
  66. case KeyEvent.VK_RIGHT:
  67. snakeModel.changeDirection(SnakeModel.RIGHT);
  68. break;
  69. case KeyEvent.VK_ADD:
  70. case KeyEvent.VK_PAGE_UP:
  71. snakeModel.speedUp();// 加速
  72. break;
  73. case KeyEvent.VK_SUBTRACT:
  74. case KeyEvent.VK_PAGE_DOWN:
  75. snakeModel.speedDown();// 减速
  76. break;
  77. case KeyEvent.VK_SPACE:
  78. case KeyEvent.VK_P:
  79. snakeModel.changePauseState();// 暂停或继续
  80. break;
  81. default:
  82. }
  83. //重新开始
  84. if(keyCode==KeyEvent.VK_R || keyCode==KeyEvent.VK_S
  85. || keyCode==KeyEvent.VK_ENTER)
  86. {
  87. snakeModel.running=false;
  88. begin();
  89. }
  90. }
  91. //----------------------------------------------------------------------
  92. //keyReleased():空函数
  93. //----------------------------------------------------------------------
  94. public void keyReleased(KeyEvent e)
  95. {
  96. }
  97. //----------------------------------------------------------------------
  98. //keyTyped():空函数
  99. //----------------------------------------------------------------------
  100. public void keyTyped(KeyEvent e)
  101. {
  102. }
  103. //----------------------------------------------------------------------
  104. //repaint():绘制游戏界面(包括蛇和食物)
  105. //----------------------------------------------------------------------
  106. void repaint()
  107. {
  108. Graphics g=paintCanvas.getGraphics();
  109. //draw background
  110. g.setColor(Color.YELLOW);
  111. g.fillRect(0,0,canvasWidth,canvasHeight);
  112. //draw the snake
  113. g.setColor(Color.BLUE);
  114. LinkedList na=snakeModel.nodeArray;
  115. Iterator it=na.iterator();
  116. while(it.hasNext())
  117. {
  118. Node n=(Node)it.next();
  119. drawNode(g,n);
  120. }
  121. // draw the food
  122. g.setColor(Color.RED);
  123. Node n=snakeModel.food;
  124. drawNode(g,n);
  125. update得分();
  126. }
  127. //----------------------------------------------------------------------
  128. //drawNode():绘画某一结点(蛇身或食物)
  129. //----------------------------------------------------------------------
  130. private void drawNode(Graphics g,Node n)
  131. {
  132. g.fillRect(n.x*nodeWidth,n.y*nodeHeight,nodeWidth-1,nodeHeight-1);
  133. }
  134. //----------------------------------------------------------------------
  135. //update得分():改变计分牌
  136. //----------------------------------------------------------------------
  137. public void update得分()
  138. {
  139. String s="得分: "+snakeModel.得分;
  140. label得分.setText(s);
  141. }
  142. //----------------------------------------------------------------------
  143. //begin():游戏开始,放置贪吃蛇
  144. //----------------------------------------------------------------------
  145. void begin()
  146. {
  147. if(snakeModel==null||!snakeModel.running)
  148. {
  149. snakeModel=new SnakeModel(this,canvasWidth/nodeWidth,
  150. this.canvasHeight/nodeHeight);
  151. (new Thread(snakeModel)).start();
  152. }
  153. }
  154. //----------------------------------------------------------------------
  155. //main():主函数
  156. //----------------------------------------------------------------------
  157. public static void main(String[] args)
  158. {
  159. GreedSnake gs=new GreedSnake();
  160. }
  161. }
  162. /**************************************************************************
  163. *要点分析:
  164. *1)数据结构:matrix[][]用来存储地图上面的信息,如果什么也没有设置为false,
  165. * 如果有食物或蛇,设置为true;nodeArray,一个LinkedList,用来保存蛇的每
  166. * 一节;food用来保存食物的位置;而Node类是保存每个位置的信息。
  167. *2)重要函数:
  168. * changeDirection(int newDirection) ,用来改变蛇前进的方向,而且只是
  169. * 保存头部的前进方向,因为其他的前进方向已经用位置来指明了。 其中newDirection
  170. * 必须和原来的direction不是相反方向,所以相反方向的值用了同样的奇偶性。在测试
  171. * 的时候使用了direction%2!=newDirection%2 进行判断。
  172. * moveOn(),用来更新蛇的位置,对于当前方向,把头部位置进行相应改变。如果越界,
  173. * 结束;否则,检测是否遇到食物(加头部)或身体(结束);如果什么都没有,加上头部,
  174. * 去掉尾部。由于用了LinkedList数据结构,省去了相当多的麻烦。
  175. *************************************************************************/
  176.  
  177. //----------------------------------------------------------------------
  178. //Node:结点类
  179. //----------------------------------------------------------------------
  180. class Node
  181. {
  182. int x;
  183. int y;
  184. Node(int x,int y)
  185. {
  186. this.x=x;
  187. this.y=y;
  188. }
  189. }
  190. //----------------------------------------------------------------------
  191. //SnakeModel:贪吃蛇模型
  192. //----------------------------------------------------------------------
  193. class SnakeModel implements Runnable
  194. {
  195. GreedSnake gs;
  196. boolean[][] matrix;// 界面数据保存在数组里
  197. LinkedList nodeArray=new LinkedList();
  198. Node food;
  199. int maxX;//最大宽度
  200. int maxY;//最大长度
  201. int direction=2;//方向
  202. boolean running=false;
  203. int timeInterval=200;// 间隔时间(速度)
  204. double speedChangeRate=0.75;// 速度改变程度
  205. boolean paused=false;// 游戏状态
  206. int 得分=0;
  207. int countMove=0;
  208. // UP和DOWN是偶数,RIGHT和LEFT是奇数
  209. public static final int UP=2;
  210. public static final int DOWN=4;
  211. public static final int LEFT=1;
  212. public static final int RIGHT=3;
  213. //----------------------------------------------------------------------
  214. //GreedModel():初始化界面
  215. //----------------------------------------------------------------------
  216. public SnakeModel(GreedSnake gs,int maxX,int maxY)
  217. {
  218. this.gs=gs;
  219. this.maxX=maxX;
  220. this.maxY=maxY;
  221. matrix=new boolean[maxX][];
  222. for(int i=0;i<maxX;++i)
  223. {
  224. matrix[i]=new boolean[maxY];
  225. Arrays.fill(matrix[i],false);// 没有蛇和食物的地区置false
  226. }
  227. //初始化贪吃蛇
  228. int initArrayLength=maxX>20 ? 10 : maxX/2;
  229. for(int i=0;i<initArrayLength;++i)
  230. {
  231. int x=maxX/2+i;
  232. int y=maxY/2;
  233. nodeArray.addLast(new Node(x,y));
  234. matrix[x][y]=true;// 蛇身处置true
  235. }
  236. food=createFood();
  237. matrix[food.x][food.y]=true;// 食物处置true
  238. }
  239. //----------------------------------------------------------------------
  240. //changeDirection():改变运动方向
  241. //----------------------------------------------------------------------
  242. public void changeDirection(int newDirection)
  243. {
  244. if(direction%2!=newDirection%2)// 避免冲突
  245. {
  246. direction=newDirection;
  247. }
  248. }
  249. //----------------------------------------------------------------------
  250. //moveOn():贪吃蛇运动函数
  251. //----------------------------------------------------------------------
  252. public boolean moveOn()
  253. {
  254. Node n=(Node)nodeArray.getFirst();
  255. int x=n.x;
  256. int y=n.y;
  257. switch(direction)
  258. {
  259. case UP:
  260. y--;
  261. break;
  262. case DOWN:
  263. y++;
  264. break;
  265. case LEFT:
  266. x--;
  267. break;
  268. case RIGHT:
  269. x++;
  270. break;
  271. }
  272. if((0<=x&&x<maxX)&&(0<=y&&y<maxY))
  273. {
  274. if(matrix[x][y])// 吃到食物或者撞到身体
  275. {
  276. if(x==food.x&&y==food.y)// 吃到食物
  277. {
  278. nodeArray.addFirst(food);// 在头部加上一结点
  279. //计分规则与移动长度和速度有关
  280. int 得分Get=(10000-200*countMove)/timeInterval;
  281. 得分+=得分Get>0 ? 得分Get : 10;
  282. countMove=0;
  283. food=createFood();
  284. matrix[food.x][food.y]=true;
  285. return true;
  286. }
  287. else return false;// 撞到身体
  288. }
  289. else//什么都没有碰到
  290. {
  291. nodeArray.addFirst(new Node(x,y));// 加上头部
  292. matrix[x][y]=true;
  293. n=(Node)nodeArray.removeLast();// 去掉尾部
  294. matrix[n.x][n.y]=false;
  295. countMove++;
  296. return true;
  297. }
  298. }
  299. return false;//越界(撞到墙壁)
  300. }
  301. //----------------------------------------------------------------------
  302. //run():贪吃蛇运动线程
  303. //----------------------------------------------------------------------
  304. public void run()
  305. {
  306. running=true;
  307. while(running)
  308. {
  309. try
  310. {
  311. Thread.sleep(timeInterval);
  312. }catch(Exception e)
  313. {
  314. break;
  315. }
  316. if(!paused)
  317. {
  318. if(moveOn())// 未结束
  319. {
  320. gs.repaint();
  321. }
  322. else//游戏结束
  323. {
  324. JOptionPane.showMessageDialog(null,"你傻逼啊这么简单都会死",
  325. "傻逼",JOptionPane.INFORMATION_MESSAGE);
  326. break;
  327. }
  328. }
  329. }
  330. running=false;
  331. }
  332. //----------------------------------------------------------------------
  333. //createFood():生成食物及放置地点
  334. //----------------------------------------------------------------------
  335. private Node createFood()
  336. {
  337. int x=0;
  338. int y=0;
  339. do
  340. {
  341. Random r=new Random();
  342. x=r.nextInt(maxX);
  343. y=r.nextInt(maxY);
  344. }while(matrix[x][y]);
  345. return new Node(x,y);
  346. }
  347. //----------------------------------------------------------------------
  348. //speedUp():加快蛇运动速度
  349. //----------------------------------------------------------------------
  350. public void speedUp()
  351. {
  352. timeInterval*=speedChangeRate;
  353. }
  354. //----------------------------------------------------------------------
  355. //speedDown():放慢蛇运动速度
  356. //----------------------------------------------------------------------
  357. public void speedDown()
  358. {
  359. timeInterval/=speedChangeRate;
  360. }
  361. //----------------------------------------------------------------------
  362. //changePauseState(): 改变游戏状态(暂停或继续)
  363. //----------------------------------------------------------------------
  364. public void changePauseState()
  365. {
  366. paused=!paused;
  367. }
  368. }

回复 "贪吃蛇代码"

这儿你可以回复上面这条便签

captcha