贪吃蛇小游戏_图形化界面设计之容器(JFrame)

ゝ一世哀愁。 2023-09-24 14:37 147阅读 0赞

图片信息:

  1. public class Images {
  2. //首先将图片的路径进行封装为对象:
  3. public static URL bodyURL = Images.class.getResource("/images/body.png");
  4. //封装图片:
  5. public static ImageIcon bodyImg = new ImageIcon(bodyURL);
  6. //首先将图片的路径进行封装为对象:
  7. public static URL downURL = Images.class.getResource("/images/down.png");
  8. //封装图片:
  9. public static ImageIcon downImg = new ImageIcon(downURL);
  10. //首先将图片的路径进行封装为对象:
  11. public static URL foodURL = Images.class.getResource("/images/food.png");
  12. //封装图片:
  13. public static ImageIcon foodImg = new ImageIcon(foodURL);
  14. //首先将图片的路径进行封装为对象:
  15. public static URL headerURL = Images.class.getResource("/images/header.png");
  16. //封装图片:
  17. public static ImageIcon headerImg = new ImageIcon(headerURL);
  18. //首先将图片的路径进行封装为对象:
  19. public static URL leftURL = Images.class.getResource("/images/left.png");
  20. //封装图片:
  21. public static ImageIcon leftImg = new ImageIcon(leftURL);
  22. //首先将图片的路径进行封装为对象:
  23. public static URL rightURL = Images.class.getResource("/images/right.png");
  24. //封装图片:
  25. public static ImageIcon rightImg = new ImageIcon(rightURL);
  26. //首先将图片的路径进行封装为对象:
  27. public static URL upURL = Images.class.getResource("/images/up.png");
  28. //封装图片:
  29. public static ImageIcon upImg = new ImageIcon(upURL);
  30. }

创建窗体(同时也正作为程序入口,在本类启动程序)

  1. public class MyFrame {
  2. //程序入口
  3. public static void main(String[] args) {
  4. //创建一个窗体
  5. JFrame jf = new JFrame();
  6. //给窗体加一个标题
  7. jf.setTitle("贪吃蛇小游戏by杜杜");
  8. //获取屏幕的宽
  9. int width = Toolkit.getDefaultToolkit().getScreenSize().width;
  10. //获取屏幕的高:
  11. int height = Toolkit.getDefaultToolkit().getScreenSize().height;
  12. //设置窗体的位置:
  13. jf.setBounds((width-800)/2,(height-800)/2,800,800);
  14. //在关闭窗体的时候 程序也要停止:
  15. jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
  16. //进行设置,让窗体的大小不可变:
  17. jf.setResizable(false);
  18. //创建一个面板:
  19. MyGamePanel gp = new MyGamePanel();
  20. //将面板放入窗体中:
  21. jf.add(gp);
  22. //将窗体展现出来:--->必须放在最后
  23. jf.setVisible(true);
  24. }
  25. }

创建面板

  1. /**
  2. * @Description: GamePanel本身不是一个面板
  3. * 但是需要继承一个类:JPanel
  4. * 那么GamePanel就具备面板的能力了
  5. * @Author: 杜杜
  6. * @Date: 2022/11/23 13:55
  7. */
  8. public class MyGamePanel extends JPanel {
  9. //定义蛇的长度:
  10. private int length;
  11. //定义一个数组,专门存储蛇的x轴坐标:
  12. int[] snakeX = new int[600];
  13. //定义一个数组,专门存储蛇的y轴坐标:
  14. int[] snakeY = new int[600];
  15. //设置食物的xy轴坐标:
  16. int foodX ;
  17. int foodY ;
  18. //设置一个变量,定义小蛇的方向:
  19. String direction = "R"; //方向: L R U D
  20. //定义一个变量,控制游戏是否开始:
  21. boolean flag = false;
  22. //创建一个定时器:
  23. Timer timer;
  24. //定义一个变量,专门用来接收积分:
  25. int score ;
  26. //加入一个变量,判断蛇的生死:
  27. boolean isDie = false;//默认蛇不是死的
  28. //初始化方法:
  29. public void init(){
  30. length = 3;//蛇的初始化长度为3
  31. //初始化蛇头的坐标:
  32. snakeX[0] = 150;
  33. snakeY[0] = 300;
  34. //初始化第一节蛇身子坐标:
  35. snakeX[1] = 125;
  36. snakeY[1] = 300;
  37. //初始化第二节蛇身子坐标:
  38. snakeX[2] = 100;
  39. snakeY[2] = 300;
  40. //初始化食物的位置:
  41. foodX = 325;
  42. foodY = 225;
  43. }
  44. //画面板
  45. public MyGamePanel(){
  46. init();
  47. //将焦点放在面板上:
  48. this.setFocusable(true);
  49. //加入一个键盘监听:
  50. this.addKeyListener(new KeyAdapter() {
  51. @Override
  52. public void keyPressed(KeyEvent e) {
  53. super.keyPressed(e);
  54. int key = e.getKeyCode();
  55. System.out.println(key);
  56. if(key == KeyEvent.VK_SPACE){//监听到空格了
  57. if(isDie){
  58. //蛇如果死了,点击空格后 恢复最开始的状态:
  59. init();
  60. isDie = false;//由死变生
  61. }else{
  62. /* System.out.println("你已经点击空格了");*/
  63. flag = !flag;
  64. //游戏如果是开始的,就变为暂停的
  65. //游戏如果是暂停的,就变为开始的
  66. repaint();//重新绘制
  67. }
  68. }
  69. //上
  70. if(key == KeyEvent.VK_UP){
  71. direction = "U";
  72. }
  73. //下
  74. if(key == KeyEvent.VK_DOWN){
  75. direction = "D";
  76. }
  77. //左
  78. if(key == KeyEvent.VK_LEFT){
  79. direction = "L";
  80. }
  81. //右
  82. if(key == KeyEvent.VK_RIGHT){
  83. direction = "R";
  84. }
  85. }
  86. });
  87. //初始化定时器:创建定时器的对象
  88. //参数两个:第一个参数设置:蛇多久动一次
  89. //第二个参数:就是设置蛇具体怎么动-->重写了一个actionPerformed方法
  90. //具体蛇头的逻辑要写在actionPerformed方法中
  91. timer = new Timer(100, new ActionListener() {
  92. @Override
  93. public void actionPerformed(ActionEvent e) {
  94. if(flag&&isDie==false){//如果游戏是开始的,蛇才会动
  95. //蛇的后一节 到 前一节位置上去:
  96. //实际就是改变蛇的坐标 -->改变的蛇身子
  97. for (int i = length-1;i>0;i--){
  98. snakeX[i] = snakeX[i-1];
  99. snakeY[i] = snakeY[i-1];
  100. }
  101. //改变蛇头:
  102. //往右动的话 蛇头 x坐标+25
  103. if(direction.equals("R")){
  104. snakeX[0] = snakeX[0] + 25;
  105. }
  106. if(direction.equals("L")){
  107. snakeX[0] = snakeX[0] - 25;
  108. }
  109. if(direction.equals("U")){
  110. snakeY[0] = snakeY[0] - 25;
  111. }
  112. if(direction.equals("D")){
  113. snakeY[0] = snakeY[0] + 25;
  114. }
  115. //防止蛇飞出边界:
  116. //向右边界:
  117. if(snakeX[0] > 750){
  118. snakeX[0] = 25;
  119. }
  120. //向上边界:
  121. if(snakeY[0] < 100 ){
  122. snakeY[0] = 725;
  123. }
  124. //向左边界:
  125. if(snakeX[0] <25){
  126. snakeX[0] = 750;
  127. }
  128. //向下边界:
  129. if(snakeY[0] > 725){
  130. snakeY[0] = 100;
  131. }
  132. //当蛇头和食物的坐标重合的时候就是吃到食物了:
  133. if(snakeX[0] == foodX&&snakeY[0] == foodY){
  134. //蛇长度加1:
  135. length++;
  136. //改变食物的位置;-->重点:食物的坐标 无论是x 还是y必须是25的倍数
  137. foodX = 25 + 25*(new Random().nextInt(28));
  138. foodY = 100 + 25*(new Random().nextInt(25));
  139. //积分增长:
  140. score = (length-3)*10;
  141. }
  142. /*
  143. [25,725] --> [0,700]+25
  144. Math.random -- > [0.0,1.0)
  145. Math.random*701 --> [0.0,700.0)
  146. (int)(Math.random*701) -->[0,700]
  147. (int)(Math.random*701)+ 25
  148. [100,750] -->[0,650]+100
  149. */
  150. //加入一个死亡判定:蛇头跟身子的任意一节重合,都失败
  151. for (int i=1;i<length;i++){
  152. if(snakeX[0]==snakeX[i]&&snakeY[0]==snakeY[i]){
  153. isDie = true;
  154. }
  155. }
  156. //蛇的坐标改完以后,重绘这个画面
  157. repaint();
  158. }
  159. }
  160. });
  161. //定时器开启:
  162. timer.start();
  163. }
  164. /*
  165. paintComponent这个方法 就类似 我们平时写的main方法
  166. 它能做的事就是 :底层也会直接调用,只要你写了这个方法,当需要画图的时候
  167. 底层就去自动调用这个方法
  168. 所以你想要画的东西,都要写在这个方法中
  169. */
  170. @Override
  171. protected void paintComponent(Graphics g) {
  172. super.paintComponent(g);
  173. //先将面板的背景颜色画上:
  174. this.setBackground(new Color(174, 207, 174));
  175. //画一个图片:
  176. /*
  177. 四个参数:this指代当前面板 g利用画笔 x,y指的就是举例 面板左上角的坐标
  178. */
  179. Images.headerImg.paintIcon(this,g,10,10);
  180. //调节画笔的颜色:
  181. g.setColor(new Color(190, 179, 201));
  182. //画一个矩形:
  183. /*
  184. 四个参数:x,y 设置坐标 后面两个参数:设置矩形的宽和高
  185. */
  186. g.fillRect(10,70,770,685);
  187. //画蛇头:
  188. if(direction.equals("R")){
  189. Images.rightImg.paintIcon(this,g,snakeX[0],snakeY[0]);
  190. }
  191. if(direction.equals("L")){
  192. Images.leftImg.paintIcon(this,g,snakeX[0],snakeY[0]);
  193. }
  194. if(direction.equals("U")){
  195. Images.upImg.paintIcon(this,g,snakeX[0],snakeY[0]);
  196. }
  197. if(direction.equals("D")){
  198. Images.downImg.paintIcon(this,g,snakeX[0],snakeY[0]);
  199. }
  200. /*//画第一节身子:
  201. Images.bodyImg.paintIcon(this,g,snakeX[1],snakeY[1]);
  202. //画第二节身子:
  203. Images.bodyImg.paintIcon(this,g,snakeX[2],snakeY[2]);*/
  204. //将画身子的方法优化:
  205. for (int i = 1;i<length;i++){
  206. Images.bodyImg.paintIcon(this,g,snakeX[i],snakeY[i]);
  207. }
  208. //画食物:
  209. Images.foodImg.paintIcon(this,g,foodX,foodY);
  210. //判断游戏到底是开始还是暂停:
  211. if(flag == false ){//游戏暂停:
  212. //在面板上写文字:写游戏暂停的文字:
  213. g.setColor(new Color(114, 98, 255));
  214. //三个参数:字体样式,加粗效果,字号
  215. g.setFont(new Font("微软雅黑",Font.BOLD,40));
  216. //写文字
  217. g.drawString("点击空格开始游戏!",250,330);
  218. }/*else{//游戏开始
  219. //什么都不用动。。不用管
  220. }*/
  221. //画积分:
  222. g.setColor(new Color(4, 2, 2, 246));
  223. //三个参数:字体样式,加粗效果,字号
  224. g.setFont(new Font("微软雅黑",Font.BOLD,20));
  225. //写文字
  226. g.drawString("积分:"+score,620,40);
  227. //根据蛇的死亡状态来在画布上画内容:
  228. if(isDie){
  229. g.setColor(new Color(255, 90, 210));
  230. //三个参数:字体样式,加粗效果,字号
  231. g.setFont(new Font("微软雅黑",Font.BOLD,20));
  232. //写文字
  233. g.drawString("小蛇死亡,游戏停止\n按下空格重新开始游戏!",250,330);
  234. }
  235. }
  236. }

发表评论

表情:
评论列表 (有 0 条评论,147人围观)

还没有评论,来说两句吧...

相关阅读

    相关 贪吃游戏

    贪吃蛇游戏是一款比较经典的休闲游戏,文章包括项目的部分源码以及运行界面的一些图片,项目也参考学习了许多大佬的文章,会在文章最后面贴出参考文章,有什么问题也请大家指正。 一、

    相关 js游戏贪吃

    介绍一个由本人制作的贪吃蛇小游戏。这个游戏采用了前端BootStrap框架和jQuery框架,因此移动端和电脑端都能兼容。虽然界面比较简陋,但是基本功能比较齐全,如果有bug欢

    相关 贪吃游戏总论

    引言:一个月前完成了贪吃蛇小游戏,作为一个用来练手的项目,自己的确成长了不少,打算就这个项目写点东西,后来工作太忙,再加上一些原因,一直到现在才有空写下来,贪吃蛇小游戏分为总论