小白教程

 找回密码
 立即注册
查看: 5383|回复: 0

Java游戏:简单的贪吃蛇小游戏

[复制链接]

176

主题

185

帖子

663

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
663
发表于 2021-4-16 12:02:46 | 显示全部楼层 |阅读模式
Java——贪吃蛇小游戏的实现
1. 程序结构
  程序结构图如图:


2. 程序设计思路
2.1 Data类
作用:连接statics文件夹,将静态资源包中的图片转化为图标 方便在面板上绘制。
实现:使用class.getResource(String path)方法。
   代码如下:
  1. package com.snake;
  2. import javax.swing.*;
  3. import java.net.URL;
  4. public class Data {
  5.     //贪吃蛇头部
  6.     public static URL upUrl = Data.class.getResource("/statics/up.png");
  7.     public static ImageIcon up = new ImageIcon(upUrl);
  8.     public static URL downUrl = Data.class.getResource("/statics/down.png");
  9.     public static ImageIcon down = new ImageIcon(downUrl);
  10.     public static URL leftUrl = Data.class.getResource("/statics/left.png");
  11.     public static ImageIcon left = new ImageIcon(leftUrl);
  12.     public static URL rightUrl = Data.class.getResource("/statics/right.png");
  13.     public static ImageIcon right = new ImageIcon(rightUrl);
  14.     //贪食蛇身体
  15.     public static URL bodyUrl = Data.class.getResource("/statics/body.png");
  16.     public static ImageIcon body = new ImageIcon(bodyUrl);
  17.     //食物
  18.     public static URL foodUrl = Data.class.getResource("/statics/food.png");
  19.     public static ImageIcon food = new ImageIcon(foodUrl);
  20. }
复制代码
2.2 StartGame类
  • 作用:创建游戏窗口,在窗口中添加一个游戏面板。
  • 实现:使用JFrame类创建游戏窗口,利用其add()方法添加一个GamePanel类实例化对象。

   代码如下:

  1. package com.snake;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. public class StartGame {
  5.     public static void main(String[] args){
  6.         //建立游戏窗口
  7.         JFrame frame = new JFrame("Java-贪吃蛇小游戏");//标题
  8.         frame.setSize(900,720);//窗口大小
  9.         frame.setLocationRelativeTo(null);//窗口显示屏幕中间
  10.         frame.setResizable(false);//固定窗口大小
  11.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗体关闭事件
  12.         frame.add(new GamePanel());//添加游戏内容
  13.         frame.setVisible(true);//设置窗体可见
  14.     }
  15. }
复制代码

2.3 GamePanel类

作用:实现游戏的动态页面。

实现:(1)init()方法:初始化小蛇位置;

           (2)eat()方法:用随机种子随机食物的位置,并进行判定,食物位置不能和小蛇位置重合;

           (3)继承JPanel类,重写paintComponent(Graphics g)方法,在方法中绘制标题栏、小蛇的位置(根据direction小蛇头部方向变量绘制小蛇头部)、小蛇身体、积分栏、游戏提醒项与失败判断项;

           (4)实现KeyListener 接口中的keyPressed(KeyEvent e)方法,获取键盘输入,根据键盘输入对游戏状态或者小蛇头部方向direction变量进行更改;

           (5)实现ActionListener接口中的actionPerformed(ActionEvent e)方法,根据游戏状态和direction变量进行小蛇移动操作(注意禁用直接回头操作),进行吃食物判定和死亡判定。使用Timer计时器让游戏动态变化,用repaint()方法实时更新界面。

   代码如下:

  1. package com.snake;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import java.awt.event.KeyEvent;
  7. import java.awt.event.KeyListener;
  8. import java.util.Random;

  9. public class GamePanel extends JPanel implements KeyListener, ActionListener {
  10.     int[] snakeX = new int[500];//贪吃蛇横坐标
  11.     int[] snakeY = new int[500];//贪吃蛇纵坐标
  12.     int foodX;//食物横坐标
  13.     int foodY;//食物蛇纵坐标
  14.     int length;//贪吃蛇的长度
  15.     String  direction;//贪吃蛇头方向
  16.     int score;//积分
  17.     Random r = new Random();
  18.     Timer timer = new Timer(100,this);
  19.     boolean isStart;
  20.     boolean isFail;
  21.     //构造函数
  22.     public GamePanel(){
  23.         init();
  24.         this.setFocusable(true);
  25.         this.addKeyListener(this);
  26.         timer.start();
  27.     }
  28.     private void init(){
  29.         length=3;
  30.         snakeX[0]=100;snakeY[0]=100;
  31.         snakeX[1]=75;snakeY[1]=100;
  32.         snakeX[2]=50;snakeY[2]=100;
  33.         direction = "R";
  34.         eat(foodX,foodY);
  35.         isStart = false;
  36.         isFail = false;
  37.         score = 0;

  38.     }
  39.     private void eat(int x,int y){
  40.         x= 25 + 25*r.nextInt(34);
  41.         y= 75 + 25*r.nextInt(24);
  42.         for (int i = 0; i < length; i++) {
  43.             if(snakeX[i]==x&&snakeY[i]==y){
  44.                 x = 25 + 25*r.nextInt(34);
  45.                 y = 75 + 25*r.nextInt(24);
  46.             }
  47.         }
  48.         foodX = x;foodY = y;
  49.     }
  50.     protected void paintComponent(Graphics g) {
  51.         super.paintComponent(g);
  52.         this.setBackground(Color.white);//设置背景板为白色
  53.         //画标题
  54.         g.setColor(Color.GREEN);
  55.         g.setFont(new Font("幼圆",Font.BOLD,50));
  56.         g.drawString("贪吃蛇游戏",300,60);
  57.         //绘制游戏区域
  58.         g.setColor(Color.GRAY);
  59.         g.fillRect(25,75,850,600);
  60.         //画贪吃蛇头部
  61.         if(direction=="R"){
  62.             Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);
  63.         }
  64.         else if(direction=="L"){
  65.             Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);
  66.         }
  67.         if(direction=="U"){
  68.             Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);
  69.         }
  70.         else if(direction=="D"){
  71.             Data.down.paintIcon(this,g,snakeX[0],snakeY[0]);
  72.         }
  73.         //画身体
  74.         for (int i = 1; i < length ; i++) {
  75.             Data.body.paintIcon(this,g,snakeX[i],snakeY[i]);
  76.         }
  77.         //画食物
  78.         Data.food.paintIcon(this,g,foodX,foodY);
  79.         //绘制积分栏
  80.         g.setColor(Color.BLACK);
  81.         g.setFont(new Font("幼圆",Font.BOLD,20));
  82.         g.drawString("长度:"+length,730,30);
  83.         g.drawString("得分:"+score,730,60);
  84.         //游戏开始提醒
  85.         if(isStart==false){
  86.             g.setColor(Color.BLACK);
  87.             g.setFont(new Font("幼圆",Font.BOLD,40));
  88.             g.drawString("按空格键开始游戏",300,300);
  89.         }
  90.         //失败判断
  91.         if(isFail){
  92.             g.setColor(Color.RED);
  93.             g.setFont(new Font("幼圆",Font.BOLD,40));
  94.             g.drawString("游戏失败,按空格键重新开始",300,300);
  95.         }
  96.     }

  97.     @Override
  98.     public void keyPressed(KeyEvent e) {
  99.         int keyCode = e.getKeyCode();//获取按下的按键
  100.         //判断空格
  101.         if(keyCode==KeyEvent.VK_SPACE){
  102.             if(isFail){
  103.                 isFail = false;
  104.                 init();
  105.             }
  106.             else{
  107.                 isStart = !isStart;
  108.             }
  109.             repaint();
  110.         }
  111.         //判断方向
  112.         if(keyCode==KeyEvent.VK_LEFT&&direction!="R"){
  113.             direction = "L";
  114.         }
  115.         else if(keyCode==KeyEvent.VK_RIGHT&&direction!="L"){
  116.             direction = "R";
  117.         }
  118.         else if(keyCode==KeyEvent.VK_UP&&direction!="D"){
  119.             direction = "U";
  120.         }
  121.         else if(keyCode==KeyEvent.VK_DOWN&&direction!="U"){
  122.             direction = "D";
  123.         }
  124.     }
  125.     @Override
  126.     public void keyReleased(KeyEvent e) {

  127.     }
  128.     @Override
  129.     public void keyTyped(KeyEvent e) {
  130.     }


  131.     @Override
  132.     public void actionPerformed(ActionEvent e) {
  133.         //判断游戏状态
  134.         if(isStart&&!isFail){
  135.             //移动身体
  136.             for (int i = length-1; i > 0 ; i--) {
  137.                 snakeX[i] = snakeX[i-1];
  138.                 snakeY[i] = snakeY[i-1];
  139.             }
  140.             //移动头部
  141.             if(direction=="R"){
  142.                 snakeX[0] += 25;
  143.                 if(snakeX[0]>850){
  144.                     snakeX[0] = 25;
  145.                 }
  146.             }
  147.             else  if(direction=="L"){
  148.                 snakeX[0] -= 25;
  149.                 if(snakeX[0]<25){
  150.                     snakeX[0] = 850;
  151.                 }
  152.             }
  153.             else  if(direction=="U"){
  154.                 snakeY[0] -= 25;
  155.                 if(snakeY[0]<75){
  156.                     snakeY[0] = 650;
  157.                 }
  158.             }
  159.             else  if(direction=="D"){
  160.                 snakeY[0] += 25;
  161.                 if(snakeY[0]>650){
  162.                     snakeY[0] = 75;
  163.                 }
  164.             }
  165.             //吃食物
  166.             if(snakeX[0]==foodX&&snakeY[0]==foodY){
  167.                 length++;
  168.                 score += 10;
  169.                 eat(foodX,foodY);
  170.             }
  171.             //死亡判定
  172.             for (int i = 1; i < length; i++) {
  173.                 if(snakeX[0]==snakeX[i]&&snakeY[0]==snakeY[i]){
  174.                     isFail=true;
  175.                 }
  176.             }
  177.             repaint();
  178.         }
  179.         timer.start();
  180.     }
  181. }
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|小白教程 ( 粤ICP备20019910号 )

GMT+8, 2024-9-20 14:38 , Processed in 0.030053 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc. Template By 【未来科技】【 www.wekei.cn 】

快速回复 返回顶部 返回列表