ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021-04-24

2021-04-24 16:32:14  阅读:153  来源: 互联网

标签:24 04 int snakeX snakeY static 2021 new public


用java实现贪吃蛇游戏(源码+详细注释)

(素材图片在文末)

一、文件结构

文件结构

二、实现代码

  1. StartGame
在这里插入代package com.nanguadeng.eatsnakes;

import javax.swing.*;
import java.awt.*;

public class StartGame {
    public static void main(String[] args) {



        //创建一个窗体:
        JFrame jf = new JFrame();
        //给窗体设计标题:
        jf.setTitle("贪吃蛇小游戏");
        //获得屏幕宽和高
        int width = Toolkit.getDefaultToolkit().getScreenSize().width;
        int height = Toolkit.getDefaultToolkit().getScreenSize().height;
        //设置窗体弹出对应坐标及对应窗体宽和高
        jf.setBounds((width-800)/2,(height-800)/2,800,800);
        //设置窗体大小不可调节
        jf.setResizable(false);
        //关闭窗口时程序就关闭:
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        //创建面版:
        GamePanel gp = new GamePanel();
        //将面板放入窗体中:
        jf.add(gp);
        //默认情况下窗体是隐藏的,所以必须将窗体进行显现:
        jf.setVisible(true);//显现方法最好放最后,因为中间有一些设置
    }
}码片
  1. Images
在这里插入代package com.nanguadeng.eatsnakes;

import javax.swing.*;
import java.awt.*;

public class StartGame {
    public static void main(String[] args) {



        //创建一个窗体:
        JFrame jf = new JFrame();
        //给窗体设计标题:
        jf.setTitle("贪吃蛇小游戏");
        //获得屏幕宽和高
        int width = Toolkit.getDefaultToolkit().getScreenSize().width;
        int height = Toolkit.getDefaultToolkit().getScreenSize().height;
        //设置窗体弹出对应坐标及对应窗体宽和高
        jf.setBounds((width-800)/2,(height-800)/2,800,800);
        //设置窗体大小不可调节
        jf.setResizable(false);
        //关闭窗口时程序就关闭:
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        //创建面版:
        GamePanel gp = new GamePanpackage com.nanguadeng.eatsnakes;

import java.net.URL;
import javax.swing.*;

//Image类专门用来获取游戏中所涉及的图片
public class Images {
    /*因为是面向对象的语言
      所以要将图片封装为一个对象
      这样在程序中才可以通过操纵这个对象来操纵图片 */

    //将图片路径封装为一个对象:
    public static URL bodyURL = Images.class.getResource("/images/body.png");
    //那一个斜杠表示的是相对路径,比如现在的路径file:/D:/java成品/组件及事件处理/eatsnakes/out/production/eatsnakes/
    //将图片封装为一个对象:
    public static ImageIcon bodyImg = new ImageIcon(bodyURL);

    public static URL downURL = Images.class.getResource("/images/down.png");
    public static ImageIcon downImg = new ImageIcon(downURL);

    public static URL foodURL = Images.class.getResource("/images/food.png");
    public static ImageIcon foodImg = new ImageIcon(foodURL);

    public static URL headerURL = Images.class.getResource("/images/header.png");
    public static ImageIcon headerImg = new ImageIcon(headerURL);

    public static URL leftURL = Images.class.getResource("/images/left.png");
    public static ImageIcon leftImg = new ImageIcon(leftURL);

    public static URL upURL = Images.class.getResource("/images/up.png");
    public static ImageIcon upImg = new ImageIcon(upURL);

    public static URL rightURL = Images.class.getResource("/images/right.png");
    public static ImageIcon rightImg = new ImageIcon(rightURL);



}


  1. GamePanel
在这里插入代码片package com.nanguadeng.eatsnakes;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;

//继承了JPanel就是面板了
public class GamePanel extends JPanel {
    //蛇的长度:
    int length;
    //定义两个数组
    //一个专门存储X轴坐标
    int[] snakeX = new int[200];
    //一个专门存储Y轴坐标
    int [] snakeY = new int[200];
    //游戏只有两个状态,开始,暂停:
    boolean isStart = false;//默认暂停
    //加入一个定时器:
    Timer timer;
    //定义蛇的行走方向:
    String direction;
    //定义食物XY坐标
    int foodX;
    int foodY;
    //定义一个积分:
    int score;
    //加入一个变量,判断小蛇死亡状态:
    boolean isDie = false;
    public void init(){
        //初始化蛇的长度:
        length = 3;
        //初始化蛇头坐标:
        snakeX[0] = 175;
        snakeY[0] = 275;
        //初始化第一节身子坐标:
        snakeX[1] = 150;
        snakeY[1] = 275;
        //初始化第二节身子坐标:
        snakeX[2] = 125;
        snakeY[2] = 275;
        //初始化蛇头方向
        direction = "R";//之后将用U D R L表示方向
        //初始化食物坐标:
        foodX = 300;
        foodY = 200;
    }
    public GamePanel(){
        init ();
        //将焦点定位在当前操做面板上:
        this.setFocusable(true);
        //加入监听:
        this.addKeyListener(new KeyAdapter() {//监听按下操做
            public void keyPressed(KeyEvent e) {//监听键盘按键的按下操作
                super.keyPressed(e);
                int keyCode = e.getKeyCode();
                if(keyCode == KeyEvent.VK_SPACE){//监听格键
                    if(isDie){
                        //全部恢复到初始态
                        init();
                        isDie = false;
                    }else {
                        isStart = !isStart;//监听到按下空格后,开始状态变暂停状态,暂停状态变开始状态
                        repaint();//重绘动作
                    }
                }
                //监听向上箭头:
                if(keyCode == KeyEvent.VK_UP){
                    direction = "U";//改变方向
                }
                //监听向下箭头:
                if(keyCode == KeyEvent.VK_DOWN){
                    direction = "D";//改变方向
                }
                //监听向左箭头:
                if(keyCode == KeyEvent.VK_LEFT){
                    direction = "L";//改变方向
                }
                //监听向右箭头:
                if(keyCode == KeyEvent.VK_RIGHT){
                    direction = "R";//改变方向
                }
            }
        });
        //对定时器进行初始化动作:
        timer = new Timer(100, new ActionListener() {
            /*
            ActionListener是 事件监听
            相当于每100毫秒监听一下是否发生了一个动作
            具体动作放入ActionPerforemed
             */
            public void actionPerformed(ActionEvent e) {
                if(isStart && isDie == false){//游戏是开始状态并且不是死亡状态才会动
                    //后一节身子到前一节身子的位置上
                    for(int i = length - 1;i > 0;i--){
                        snakeX[i] = snakeX[i - 1];
                        snakeY[i] = snakeY[i - 1];
                    }
                    //动头:
                    if("R".equals(direction)){
                        snakeX[0] += 25;
                    }
                    if("L".equals(direction)){
                        snakeX[0] -= 25;
                    }
                    if("U".equals(direction)){
                        snakeY[0] -= 25;
                    }
                    if("D".equals(direction)){
                        snakeY[0] += 25;
                    }
                    //防止蛇飞出边界:
                    //向右边界:
                    if(snakeX[0] > 750){
                        snakeX[0] = 25;
                    }
                    //向上边界:
                    if(snakeY[0] < 75 ){
                        snakeY[0] = 725;
                    }
                    //向左边界:
                    if(snakeX[0] < 25){
                        snakeX[0] = 750;
                    }
                    //向下边界:
                    if(snakeY[0] > 725){
                        snakeY[0] = 75;
                    }
                    //检测碰撞的动作:(食物和蛇头坐标相同)
                    if (snakeX[0] == foodX && snakeY[0] ==foodY) {
                        //蛇长加一
                        length++;
                        //食物坐标改变:(随机生成坐标,且必须是25的倍数,不能超过矩形):
                        /*要一个[1,30]的随机数用来乘25
                        Math.random() --> [0.0,1.0)
                        Math.random() * 30 --> [0.0,30.0)
                        (int)(Math.random() * 30) --> [0,29]
                        (int)(Math.random() * 30) + 1 --> [1,30]
                         */
                        foodX = ((int)(Math.random() * 30) + 1) * 25;//[25,750]
                        /*要一个[3,29]的随机数乘25
                        [3,29] --> [0,26] + 3
                        要[0,26]的随机数
                        new Random().nextInt(27) --> [0,27) --> [0,26]
                         */
                        foodY = (new Random().nextInt(27) + 3) * 25;//[75,725]
                        //吃上食物后加10分:
                        score += 10;
                    }
                    //死亡判定:
                    for (int i = 1;i < length;i++){
                        if(snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]){
                            //将死亡状态改为true
                            isDie = true;
                        }
                    }
                    repaint();//刷新,重绘
                }
            }
        });
        //定时器要启动
        timer.start();
    }




    //paintComponent这个方法比较特殊,这个方法属于图形版的main方法,虚拟机自己调用
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        //填充背景颜色
        this.setBackground(new Color(2, 76, 76, 67));
        //画头部图片(当前窗口,G画笔工具,在-60,0处画)
        Images.headerImg.paintIcon(this,g,-60,0);
        //调节画笔颜色:
        g.setColor(new Color(205, 205, 205));
        //画一个矩形:
        g.fillRect(9,70,770,685);

        //画小蛇:
        //画蛇头
        if("R".equals(direction)){
            Images.rightImg.paintIcon(this,g,snakeX[0],snakeY[0]);
        }
        if("L".equals(direction)){
            Images.leftImg.paintIcon(this,g,snakeX[0],snakeY[0]);
        }
        if("U".equals(direction)){
            Images.upImg.paintIcon(this,g,snakeX[0],snakeY[0]);
        }
        if("D".equals(direction)){
            Images.downImg.paintIcon(this,g,snakeX[0],snakeY[0]);
        }

        //循环画蛇身:
        for(int i = 1;i<length;i++){
            Images.bodyImg.paintIcon(this,g,snakeX[i],snakeY[i]);
        }

        //如果游戏暂停,界面中间就应该有提示语:
        if(isStart == false){
            //调颜色
            g.setColor(new Color(172, 113, 222));
            //三个参数:字体,加粗,字号
            g.setFont(new Font("楷体",Font.BOLD,40));
            //画一文字:内容,X轴坐标,Y轴坐标
            g.drawString("点击空格开始游戏",250,330);
        }
        //画食物:
        Images.foodImg.paintIcon(this,g,foodX,foodY);
        //画积分:
        g.setColor(new Color(0, 47, 78));
        g.setFont(new Font("微软雅黑",Font.BOLD,20));
        g.drawString("积分:" + score,620,40);

        //画入死亡状态:
        if(isDie){
            g.setColor(new Color(199, 64, 80));
            g.setFont(new Font("微软雅黑",Font.BOLD,40));
            g.drawString("你的蛇死了,按下空格重生",175,330);
        }
    }
}

三、效果实现

开始状态
运行中
暂停状态
死亡状态

四、素材获得

https://pan.baidu.com/s/1YdUlQ2TFsx_Xwb_OEbcZkA
提取码:y5td

标签:24,04,int,snakeX,snakeY,static,2021,new,public
来源: https://blog.csdn.net/weixin_57604284/article/details/116094021

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

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

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

ICode9版权所有