经典贪吃蛇---java

本文档展示了如何使用Java编程实现一个简单的贪吃蛇游戏。游戏包括创建图像资源、设置窗口、监听键盘输入以及使用定时器控制游戏逻辑。代码详细解释了游戏各个部分的实现,包括蛇的移动、食物生成、碰撞检测以及游戏状态管理。
摘要由CSDN通过智能技术生成

程序不大,收获良多

材料也上传了,在资源中。

java是面向对象的语言,所以使用每个对象时候,它必须是在一个类中,被封装起来的。(正因如此才可以导入图片,将图片编译)

package com.msb.demo1;

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

/**
 * @Auther:zhangjj
 * @Date:2021/4/1 - 04-01-8:48
 * @Description:com.msb.demo1
 * @version:1.0
 */
public class Images {
    public static URL bodyURL = Images.class.getResource("/Images/body.png");
    public static ImageIcon body = new ImageIcon(bodyURL);
    public static URL downURL = Images.class.getResource("/Images/down.png");
    public static ImageIcon down = new ImageIcon(downURL);
    public static URL foodURL = Images.class.getResource("/Images/food.png");
    public static ImageIcon food = new ImageIcon(foodURL);
    public static URL headerURL = Images.class.getResource("/Images/header.png");
    public static ImageIcon header = new ImageIcon(headerURL);
    public static URL leftURL = Images.class.getResource("/Images/left.png");
    public static ImageIcon left = new ImageIcon(leftURL);
    public static URL rightURL = Images.class.getResource("/Images/right.png");
    public static ImageIcon rihgt= new ImageIcon(rightURL);
    public static URL upURL = Images.class.getResource("/Images/up.png");
    public static ImageIcon up = new ImageIcon(upURL);
    public static URL sprURL = Images.class.getResource("/Images/sup.png");
    public static ImageIcon spr = new ImageIcon(sprURL);
}

将图片编译完成之后,就可以将他应用到程序之中

首先创建一个窗口作为游戏的“家”——游戏要在窗口内运行

此时涉及到一个类:JFrame---具体内容自行在SDK中学习查看

package com.msb.demo1;

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

/**
 * @Auther:zhangjj
 * @Date:2021/4/1 - 04-01-9:18
 * @Description:com.msb.demo1
 * @version:1.0
 */
public class StartGme {
    public static void main(String[] args) {
       //创建窗口
        JFrame jf =new JFrame();
        //设置标题
        jf.setTitle("贪吃蛇游戏");
        //调取方法直接获取
        int width = Toolkit.getDefaultToolkit().getScreenSize().width;
        int height = Toolkit.getDefaultToolkit().getScreenSize().height;
        //设置窗体的弹出坐标,对应窗体的大小
        int wandh =800;
        //jf.setBounds(570,140,800,800);//570=(1940-800)/2;140=(1080-800)/2
        jf.setBounds((width-wandh)/2,(height-wandh)/2,wandh,wandh);
        //设置窗口不可调解
        jf.setResizable(false);
        jf.setBackground(new Color(114, 2, 255));
        //关闭窗口的同时关闭程序
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE/* =3 */);
        //创建面板
        GamePaneTest gp1 = new GamePaneTest();
        //将面板添加到窗口
         jf.add(gp1);
        //让窗口显示
        jf.setVisible(true);
    }
}

窗口创建好之后,游戏在窗口中哪里运行也是个问题,所以我们再建一个类,在这类重在建立一个面板,游戏在面板中运行(面板也是一个类我们要创建新面板就得继承内部类:JPanel---》具体内容SDK中自行查找学习)

将类定义完毕之后,添加到窗口的之中---》位置自定

 

注:在定义这个新类的时候又有两个点

一丶监视器

对键盘的监视器:addKeyListener

                          将键盘上的摁键当做是参数传入的的时候,其实是传入了一个int型的数

二丶定时器

从程序开始到程序中断的一种方式:Timer

package com.msb.demo1;

import sun.security.util.Length;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;

/**
 * @Auther:zhangjj
 * @Date:2021/4/1 - 04-01-21:22
 * @Description:com.msb.demo1
 * @version:1.0
 */
public class GamePaneTest extends JPanel {
    //定义蛇的初始长度
    int Length = 3;
    //定义两个数组
    //蛇的X轴坐标
    int[] SnakeX = new int[500];
    //蛇的Y轴坐标
    int[] SnakeY = new int[500];
    //定义游戏状态--》暂停、开始
    boolean isStart = false;
    //蛇头方向
    String direction;
    //加入时间监听器
    Timer timer,timer0;
    //定义食物的X,Y坐标
    int foodX,foodY ;
    //定义积分
    int score;
    //定义一个boolean确定小蛇状态
    boolean isDie =false;
    //定义一个彩蛋出现时间
    int surTimestart,surTimeEnd;
    //彩蛋的X,Y
    int surX,surY;
    int[] sp1 = new int[4];
    int[] sp2 = new int[4];
    //定时器的时间
    int times;
    int time ;
    public void inin(){
        //蛇的初始长度
        Length = 3;
        SnakeX[0] = 175;
        SnakeY[0] = 275;
        SnakeX[1] = 150;
        SnakeY[1] = 275;
        SnakeX[2] = 125;
        SnakeY[2] = 275;
        direction = "R";//'L' 'R' 'U' 'D'
        foodX = 300;
        foodY = 200;
        surX =600;surY=15;
        score = 0;
        surTimestart = surTimeEnd =2000;
        times =0;
        time =0 ;
    }
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        //填充背景颜色
        this.setBackground(new Color(64, 219, 188, 255));
        //画头部图片
        Images.header.paintIcon(this,g,0,0);
        //改变画笔颜色
        g.setColor(new Color(63, 4, 191, 225));
        //绘制游戏界面
        g.fillRect(10,70,770,690);
       //画蛇头
        if(direction == "R"){
            Images.rihgt.paintIcon(this,g,SnakeX[0],SnakeY[0]);
        }
        if(direction == "L"){
            Images.left.paintIcon(this,g,SnakeX[0],SnakeY[0]);
        }
        if(direction == "U"){
            Images.up.paintIcon(this,g,SnakeX[0],SnakeY[0]);
        }
        if(direction == "D"){
            Images.down.paintIcon(this,g,SnakeX[0],SnakeY[0]);
        }
        //优化为循环画身子
        for (int i = 1; i < Length; i++) {
            Images.body.paintIcon(this,g,SnakeX[i],SnakeY[i]);
        }
        //画食物
        Images.food.paintIcon(this,g,foodX,foodY);
        //画积分
        g.setColor(new Color(243, 4, 4));
        g.setFont(new Font("微软雅黑",Font.BOLD,20));
        g.drawString("积分"+score,700,50);
        //画彩蛋
        Images.spr.paintIcon(this,g,surX,surY);
        //游戏暂停时显示提示
        if(isStart == false){
            g.setColor(new Color(243, 4, 4));
            g.setFont(new Font("微软雅黑",Font.BOLD,100));
            g.drawString("空格开始游戏",100,400);
        }
        //游戏结束画面
        if(isDie == true){
            g.setColor(new Color(243, 4, 4));
            g.setFont(new Font("微软雅黑",Font.BOLD,60));
            g.drawString("游戏结束"+","+"空格重新开始",100,400);
        }
    }
    //构造器
    public GamePaneTest() {
        inin();
        //将焦点定位在当前操作面板上
        this.setFocusable(true);
        //加入监听器
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                super.keyPressed(e);
                int keyCode = e.getKeyCode();
                /*System.out.println(keyCode);*/
                if(keyCode == KeyEvent.VK_SPACE){
                    if(isDie){
                        inin();
                        isDie = false;
                    }
                    else {
                        isStart = !isStart;
                        repaint();
                    }
                }
                //监听即将改变的方向输出键
                if(keyCode ==KeyEvent.VK_LEFT&&!"R".equals(direction )){
                        direction = "L";
                        repaint();
                }
                if(keyCode ==KeyEvent.VK_RIGHT && !"L".equals(direction)){
                        direction = "R";
                        repaint();
                }
                if(keyCode ==KeyEvent.VK_UP&&!"D".equals(direction)){
                    direction = "U";
                }
                if(keyCode ==KeyEvent.VK_DOWN&&!"U".equals(direction)){
                    direction = "D";
                }
            }

        });
        //对定时器初始化
        timer0 = new Timer(100, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

            }
        });
        timer = new Timer(100, new ActionListener() {
            @Override
            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]<100){
                        SnakeY[0] = 725;
                    } if(SnakeX[0]<25){
                        SnakeX[0] = 750;
                    }
                    if(SnakeY[0]>725){
                        SnakeY[0] = 100;
                    }
                    //检测碰撞动作---》吃的动作:因为每 100s画一次
                    //没有彩蛋时
                    if(SnakeX[0]==foodX&&foodY == SnakeY[0]){
                        Length++;//蛇长加一
                        /*
                        *算法解析:foodX=25*(int)(30*(Math.random()+1))
                           random = [0.0,1.0)--->[1,30]
                           * 1.30*random=[0.0,30.0)
                           * 2.int(random)=[0,29]
                           * 3.int(random+1)=[1,30]
                         * */
                        foodX = 25*(int)(15*(Math.random()+1));//x必须是25到725的25的倍数
                        foodY = 25*(new Random().nextInt(20)+4);//Y必须是100到725的25的倍数
                        /*System.out.println(foodX);
                        System.out.println(foodY);*/
                        score +=10;
                    }
                    if((SnakeX[0]==surX+25&&SnakeY[0]==surY+25)||(SnakeX[0]==surX+25&&SnakeY[0]==surY)||(SnakeX[0]==surX&&SnakeY[0]==surY+25)||(SnakeX[0]==surX&&SnakeY[0]==surY)){
                        Length+=5;
                        surX =surY =2000;
                        score +=50;
                    }
                    //死亡判断
                    for (int i = 1; i < Length; i++) {
                        if(SnakeX[0]==SnakeX[i]&&SnakeY[0]==SnakeY[i]){
                            isDie = true;
                        }
                    }
                    //彩蛋时间
                    surTimestart +=timer.getDelay();
                    if(surTimestart%8000==0){
                        surX = 25*(new Random().nextInt(20)+2);
                        surY = 25*(new Random().nextInt(20)+1);
                        time =surTimestart;
                        times =1;
                        surTimeEnd +=timer.getDelay();
                    }
                    if(times==1){
                        if ((surTimestart-time)%2000==0&&surTimestart-time!=0){
                            //System.out.println(time);
                            time = 0;times=0;
                            surX =600; surY =15;
                        }
                    }
                    repaint();//界面重绘
                }
            }
        });
        //定时器启动
        timer.start();
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值