ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

GUI编程---贪吃蛇小游戏开发

2021-05-31 11:52:18  阅读:151  来源: 互联网

标签:游戏 int GUI snakeX --- 小游戏 static new public


①初识理论

  • 帧:时间片足够小=》就是动画,1秒30帧。连起来是动画,拆开就是静态的图片!
  • 键盘监听
  • 定时器Timer

å¨è¿éæå¥å¾çæè¿°

②游戏开发思路

(定义数据,画上面板,监听事件(键盘/事件))

1、首先一个游戏主启动类StartGame类,里面放一个JFrame窗口及其大小位置设置,关闭设置,这里设置窗口大小不可变,以防拉伸导致游戏图标变形,相关的具体操作都在相应类中进行!

2、正常的游戏界面应在面板上!因此定义一个GamePanel类进行操作,首先是重写了painComponent(Graphics p)方法,游戏中的所有东西都是用这支画笔来画!首先是绘制静态的面板,设置面板颜色为白色。

3、接着把游戏图片素材放入static字典中,放入游戏开发包下,定义一个Data类,在其中获取存放游戏图片的地址,并把它们变为图标,接着在花瓣上画上头部广告栏、矩形(默认黑色)的游戏界面。

4、绘制静态的的小蛇,在GamePanel类中定义小蛇的数据结构!

  • int length; =>蛇的长度

  • int[] snakeX=new int[600]; => 蛇的位置的 x 坐标25*25

  • int[] snakeY=new int[500]; => 蛇的位置的 y 坐标25*25

  • String fx; => 初始方向

然后写初始化方法init()方法初始化静态小蛇的长度、位置及其初始方向,再在构造器中调用init()方法,接着把小蛇画入面板中!(要判断头的方向!),身体用for循环画。

5、游戏当前状态inStart:开始/停止,空格键控制!初始设为停止false,判断状态后将提示文字画上面板!

6、空格键控制游戏开始与停止!设置键盘监听!直接在GamePanel类中实现KeyListener接口!按下空格键–>状态取反,重画repaint(),再init()函数中设置焦点事件和添加键盘监听。

7、小蛇动起来,Timer定时器!在GamePanel类中实现ActionListener接口即可。游戏一开始就启动定时器!接着写出小蛇移动的位置坐标处理,上下左右移动,头部、身体坐标如何变化,最后repaint()重画页面。这样子小蛇可以自己动了。但我们需要通过键盘监听上下左右键来控制小蛇的移动!身体移动是一样的,我们只需要判断移动方向,把头的位置坐标找好就行!

8、小蛇吃食物长大啦~,定义食物的坐标并在init()中初始化

  • int foodX;

  • int foodY;

  • Random random=new Random();

吃食物即是头部坐标和食物坐标重合,小蛇长度+1,再次生成随机的食物,吃完食物再画身体!

9、定义失败状态,默认是不失败,如果失败面板上需要出现文字提示,在面板上画即可。空格键可能是开始/停止游戏,也可能是失败后重新开始游戏,所以按下空格键得根据游戏失败装药isFail判断时开始/停止、还是重新初始开始游戏!如果游戏开始状态且没有失败,那么需要在走向后面加上失败判定:头部坐标和自己身体的任一坐标重合即为游戏失败,isfail=true! 此时会出现游戏失败提示,按下空格键是重新初始化开始游戏,而不是普通的暂停开始。

10、积分,定义数据,画上画板,监听:吃到食物分数+10

11、实现代码:

package com.xiao.lesson07_game;import javax.swing.*;//游戏的主启动类
public class StartGame {
    public static void main(String[] args) {
        JFrame frame = new JFrame("贪吃蛇");

        //正常游戏界面应在面板上
        frame.add(new GamePanel());
        
        frame.setBounds(10,10,900,720);
        frame.setResizable(false);//大小不可变
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.
package com.xiao.lesson07_game;import javax.swing.*;import java.net.URL;//数据中心
public class Data {
    //相对路径“tx.jpg
    //绝对路径:/  相当于当前的项目
    //头+身体+食物
    public static URL headerURL=Data.class.getResource("statics/header.png");
    public static ImageIcon header=new ImageIcon(headerURL);
    public static URL bodyURL=Data.class.getResource("statics/body.png");
    public static ImageIcon body=new ImageIcon(bodyURL);
    public static URL foodURL=Data.class.getResource("statics/food.png");
    public static ImageIcon food=new ImageIcon(foodURL);

    //上下左右
    public static URL upURL=Data.class.getResource("statics/up.png");
    public static URL downURL=Data.class.getResource("statics/down.png");
    public static URL leftURL=Data.class.getResource("statics/left.png");
    public static URL rightURL=Data.class.getResource("statics/right.png");
    public static ImageIcon up=new ImageIcon(upURL);
    public static ImageIcon down=new ImageIcon(downURL);
    public static ImageIcon left=new ImageIcon(leftURL);
    public static ImageIcon right=new ImageIcon(rightURL);}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.
package com.xiao.lesson07_game;import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.Random;//游戏面板
public class GamePanel extends JPanel implements KeyListener, ActionListener {
    //定义小蛇的数据结构
    int length;  //长度
    int[] snakeX=new int[600]; //x坐标 25*25
    int[] snakeY=new int[500]; //y坐标 25*25
    String fx; //初始方向

    //食物的坐标(随机!)
    int foodX;  //正常食物
    int foodY;
    Random random=new Random();//随机

    int score;  //成绩

    boolean isStart=false;// 游戏当前状态:开始/停止,默认停止

    boolean isFail=false;  //游戏失败状态

    //定时器,以毫秒为单位
    Timer timer=new Timer(100,this); //100ms执行一次

    //构造器
    public GamePanel() {
        init();
        //获得焦点和键盘监听
        this.setFocusable(true);  //获得焦点事件
        this.addKeyListener(this);  //获得键盘监听器
        timer.start();//游戏一开始定时器就启动

        //食物坐标得在游戏界面,小蛇才能吃到!        foodX=25+25*random.nextInt(34);
        foodY=75+25*random.nextInt(24);

        score=0;
    }

    //小蛇初始化方法
    public void init(){
        length=3;
        snakeX[0]=100;  snakeY[0]=100;  //脑袋坐标
        snakeX[1]=75;  snakeY[1]=100;  //第一个身体坐标
        snakeX[2]=50;  snakeY[2]=100;  //第二个身体坐标        fx="R";  //初始方向向右    }

    //绘制面板,游戏中的所有东西,都是用这支画笔来画!
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); //清屏
        //绘制静态的面板
        this.setBackground(Color.WHITE);
        Data.header.paintIcon(this, g, 25, 11);//画上头部广告栏
        g.fillRect(25, 75, 850, 600);  //画矩形=》游戏界面

        //画积分
        g.setColor(Color.WHITE);
        g.setFont(new Font("微软雅黑",Font.BOLD,18));
        g.drawString("长度:"+length,775,30);
        g.drawString("分数:"+score,775,50);
        //画食物
        Data.food.paintIcon(this,g,foodX,foodY);
        //把小蛇画上去,得判断初始方向!        if (fx.equals("R")) {
            Data.right.paintIcon(this, g, snakeX[0], snakeY[0]);//蛇头初始化向右        } else if (fx.equals("L")) {
            Data.left.paintIcon(this, g, snakeX[0], snakeY[0]);//蛇头初始化向右        } else if (fx.equals("U")) {
            Data.up.paintIcon(this, g, snakeX[0], snakeY[0]);//蛇头初始化向右        } else if (fx.equals("D")) {
            Data.down.paintIcon(this, g, snakeX[0], snakeY[0]);//蛇头初始化向右        }
        for (int i = 1; i < length; i++) {
            Data.body.paintIcon(this,g,snakeX[i],snakeY[i]);//身体        }

        //游戏状态
        if(isStart==false){
            g.setColor(Color.WHITE);//设置画笔颜色
            g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体
            g.drawString("按下空格键开始游戏!",250,380);  //写游戏提示        }

        if(isFail){
            g.setColor(Color.WHITE);//设置画笔颜色
            g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体
            g.drawString("Score:"+score,230,330);
            score=0;
            g.setColor(Color.RED);//设置画笔颜色
            g.drawString("失败,按下空格键重新开始!",230,380);  //写游戏提示        }
    }

    //键盘监听事件:键盘按压,控制游戏开始、停止
    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();  //获得键盘按键是哪个

        if(keyCode==KeyEvent.VK_SPACE){
            if(isFail){
                //重新开始                isFail=false;
                init();
            }else{
            isStart=!isStart;  //取反            }
            repaint();
        }

        //小蛇移动,上下左右
        if(keyCode==KeyEvent.VK_UP){
            fx="U";
        }else if(keyCode==KeyEvent.VK_DOWN){
            fx="D";
        }else if(keyCode==KeyEvent.VK_LEFT){
            fx="L";
        }else if(keyCode==KeyEvent.VK_RIGHT){
            fx="R";
        }
    }
    @Override
    public void keyReleased(KeyEvent e) { }
    @Override
    public void keyTyped(KeyEvent e) { }


    //事件监听--需要通过固定事件来刷新,1s=10次,Timer
    @Override
    public void actionPerformed(ActionEvent e) {
        //如果游戏是开始状态,就让小蛇动起来
        if(isStart && isFail==false) {
            //吃食物,坐标重合            if((snakeX[0]==foodX && snakeY[0]==foodY)){
                length++;  //小蛇长长了!                score+=10;
                //食物再次随机生成!
                foodX = 25 + 25 * random.nextInt(34);
                foodY = 75 + 25 * random.nextInt(24);
                }

            //身体移动不用变!都一样的            for (int i = length - 1; i > 0; i--) {
                //向前移动一节,后一节变为前一节的位置
                snakeX[i] = snakeX[i - 1];
                snakeY[i] = snakeY[i - 1];
            }
            //走向            if (fx.equals("R")) {
                //右移
                snakeX[0] = snakeX[0] + 25;
                if (snakeX[0] > 850) {
                    snakeX[0] = 25;
                }  //边界判断            } else if (fx.equals("L")) {
                //左移
                snakeX[0] = snakeX[0] - 25;
                if (snakeX[0] < 25) {
                    snakeX[0] = 850;
                }
            } else if (fx.equals("U")) {
                //上移
                snakeY[0] = snakeY[0] - 25;
                if (snakeY[0] < 75) {
                    snakeY[0] = 650;
                }
            } else if (fx.equals("D")) {
                //下移
                snakeY[0] = snakeY[0] + 25;
                if (snakeY[0] > 650) {
                    snakeY[0] = 75;
                }
            }
            //失败判定:撞到自己            for (int i = 1; i < length; i++) {
                if(snakeX[0]==snakeX[i] && snakeY[0]==snakeY[i]){
                    isFail=true;
                }
            }
            repaint();//重画页面        }
        timer.start();
    }}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.56.57.58.59.60.61.62.63.64.65.66.67.68.69.70.71.72.73.74.75.76.77.78.79.80.81.82.83.84.85.86.87.88.89.90.91.92.93.94.95.96.97.98.99.100.101.102.103.104.105.106.107.108.109.110.111.112.113.114.115.116.117.118.119.120.121.122.123.124.125.126.127.128.129.130.131.132.133.134.135.136.137.138.139.140.141.142.143.144.145.146.147.148.149.150.151.152.153.154.155.156.157.158.159.160.161.162.163.164.165.166.167.168.169.170.171.172.173.174.175.176.177.178.179.180.181.182.183.184.185.186.187.188.189.190.191.192.193.
  • 12、效果图

å¨è¿éæå¥å¾çæè¿°

13、打包发布

点击Project Structure–>Artifaxts–>”+“号–>选择JAR–>from modules with dependencies,选择main方法函数,例如在www.cungun.com可以启动类,apply即可。

选择build–>build Artifacts–>build,等待即可在项目的out目录下看到artifacts目录,里面就是生成的jar包,可以发给朋友玩了

命令行打开:java -jar gui-study.jar,即可开始贪吃蛇游戏!

14、优化(未实现!)

level:越到后面速度越快!根据level设定定时器delay

撞墙判定

小蛇不能回头

食物形式,分数或长度增长不一样

界面优化

游戏联机(网络编程)




标签:游戏,int,GUI,snakeX,---,小游戏,static,new,public
来源: https://blog.51cto.com/u_14967986/2835022

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有