【JAVA】贪吃蛇

举报
游坦之 发表于 2022/10/12 08:34:47 2022/10/12
【摘要】 @TOC 前言GUI学习时模仿狂神写的一款贪吃蛇游戏,虽然简单,但也如潮水一般敲打了当时初学的心,让我对Java的学习,有了更深的渴望,让我从一年黑框框编程第一次转向GUI编程。 一、效果图在狂神原有的基础上,增加了一定的长度,速度会加快。编程的思想:其实很简单,不过是二维方格的移动,如果把速度放慢,这就是一帧帧的图片,那么如何把一帧帧的图片"动起来"呢?这就用到了定时器。初次之外,本程序还...

@TOC


前言

GUI学习时模仿狂神写的一款贪吃蛇游戏,虽然简单,但也如潮水一般敲打了当时初学的心,让我对Java的学习,有了更深的渴望,让我从一年黑框框编程第一次转向GUI编程。


一、效果图

在狂神原有的基础上,增加了一定的长度,速度会加快。
编程的思想:其实很简单,不过是二维方格的移动,如果把速度放慢,这就是一帧帧的图片,那么如何把一帧帧的图片"动起来"呢?这就用到了定时器。
初次之外,本程序还用到了键盘事件,即上下左右可以控制方向,空格可以控制开始,如何实现这一功能,如何让程序知道我按下了这些键,这就需要键盘事件的监听。
有了键盘事件的监听,如何让小蛇动起来呢??这就用到了简单是数学计算,因为蛇头蛇身,是有固定大小的方块组成的,我只需要更改图片的位置,既可以实现蛇的移动,而且对于整个蛇而言,蛇身是根据蛇头的移动而移动,所以只需要控制蛇头。对于蛇头而言,上下左右的蛇头的方向也是不一样的,所以按下键盘同时也要更换蛇头。
当蛇身出去边界的时候,会从另一端在进入,这里可以用到取余操作。当然也可以手动赋值。
这个程序,基本上难点重点都在这里了。
贪吃的小蛇

二、源代码

Data.java

package TCS;

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

public class Data {
    public static URL headerURl = Data.class.getResource("/TCS/header.png");
    public static ImageIcon headerImg = new ImageIcon(headerURl);
    public static URL upURl = Data.class.getResource("/TCS/up.png");
    public static ImageIcon upImg = new ImageIcon(upURl);
    public static URL downURl = Data.class.getResource("/TCS/down.png");
    public static ImageIcon downImg = new ImageIcon(downURl);
    public static URL leftURl = Data.class.getResource("/TCS/left.png");
    public static ImageIcon leftImg = new ImageIcon(leftURl);
    public static URL rightURl = Data.class.getResource("/TCS/right.png");
    public static ImageIcon rightImg = new ImageIcon(rightURl);
    public static URL bodyURl = Data.class.getResource("/TCS/body.png");
    public static ImageIcon bodyImg = new ImageIcon(bodyURl);
    public static URL foodURl = Data.class.getResource("/TCS/food.png");
    public static ImageIcon foodImg = new ImageIcon(foodURl);
}

GameRun.java

package TCS;

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

public class GameRun extends JPanel implements KeyListener, ActionListener {//继承了面板
    //对蛇初始化,有蛇头,还要有身子,身子又蛇头更新的
    int lenth;
    Boolean Isover;
    int[] x = new int[600];
    int[] y = new int[600];

    int Foodx[] = new int[20];
    int Foody[] = new int[20];
    String fx;
    int score;
    Boolean Isstart = false;
    Timer timer = new Timer(100, this);
    Timer timer1 = new Timer(70, this);
    Timer timer2 = new Timer(50, this);
    Random random = new Random();

    public GameRun() {//构造器
        Init();
        //监听键盘
        this.setFocusable(true);//获得焦点事件
        this.addKeyListener(this);
        //获得
        if (lenth < 10) {

            timer.start();

        } else {
            timer.stop();
            timer1.start();

        }

    }

    public void Init() {
        x[0] = 100;
        y[0] = 100;
        x[1] = 75;
        x[2] = 50;
        y[1] = 100;
        y[2] = 100;
        score = 0;
        lenth = 3;
        fx = "R";

        for (int i = 0; i < 10; i++) {
            Foodx[i] = 25 + 25 * random.nextInt(30);
            Foody[i] = 75 + 25 * random.nextInt(20);
        }
        Isover = false;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);//清屏
        this.setBackground(Color.WHITE);
        Data.headerImg.paintIcon(this, g, 25, 11);


        g.setFont(new Font("微软雅黑", Font.BOLD, 18));
        g.drawString("长度" + lenth, 750, 30);
        g.drawString("分数" + score, 750, 53);
        g.fillRect(25, 75, 850, 600);//画颜色
        if (Isstart == false && Isover != true) {
            g.setColor(Color.WHITE);
            g.setFont(new Font("微软雅黑", Font.BOLD, 40));
            g.drawString("请按空格键开始", 320, 250);
        }
        if (Isover) {
            g.setColor(Color.red);
            g.setFont(new Font("微软雅黑", Font.BOLD, 40));
            g.drawString("任务失败,请重新开始", 320, 250);
        }
        if (fx == "R") {
            Data.rightImg.paintIcon(this, g, x[0], y[0]);
        }
        if (fx == "D") {
            Data.downImg.paintIcon(this, g, x[0], y[0]);
        }
        if (fx == "L") {
            Data.leftImg.paintIcon(this, g, x[0], y[0]);
        }
        if (fx == "U") {
            Data.upImg.paintIcon(this, g, x[0], y[0]);
        }
        for (int i = 1; i < lenth; i++) {
            Data.bodyImg.paintIcon(this, g, x[i], y[i]);
        }
        if (Isstart)//游戏开始后在画
        {
            for (int i = 0; i < 10; i++) {
                Data.foodImg.paintIcon(this, g, Foodx[i], Foody[i]);
            }
        }

        for (int i = 0; i < 10; i++) {
            if (x[0] == Foodx[i] && y[0] == Foody[i]) {
                Foodx[i] = 100 + 25 * random.nextInt(30);
                Foody[i] = 100 + 25 * random.nextInt(20);
                score += 25;
                lenth++;
                
            }
        }


    }


    @Override
    public void actionPerformed(ActionEvent e) {
        if (lenth > 10&&lenth<20) {
            timer.stop();
            timer1.start();
            timer2.stop();
        } else if(lenth<10){
            timer1.stop();
            timer.start();
            timer2.stop();
        }else{
            timer1.stop();
            timer.stop();
            timer2.start();
        }
        if (Isstart) {
            for (int i = lenth - 1; i > 0; i--) {
                x[i] = x[i - 1];
                y[i] = y[i - 1];
            }
            if (fx == "R") {
                x[0] += 25;
                if (x[0] > 850) {
                    x[0] = 25;
                }

            } else if (fx == "D") {
                y[0] += 25;
                if (y[0] > 650) {
                    y[0] = 75;
                }

            } else if (fx == "L") {
                x[0] -= 25;
                if (x[0] < 25) {
                    x[0] = 850;
                }

            } else {
                y[0] -= 25;
                if (y[0] < 75) {
                    y[0] = 650;
                }

            }
            for (int i = 1; i < lenth; i++) {
                if (x[0] == x[i] && y[0] == y[i]) {
                    Isover = true;
                    Isstart = !Isstart;
                    repaint();
                }
            }
            repaint();

        }

    }


    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        if (keyCode == KeyEvent.VK_SPACE) {

            Isstart = !Isstart;
            if (Isover) {
                Isover = !Isover;
                Init();

            }
            repaint();
        }
        if (keyCode == KeyEvent.VK_UP) {

            fx = "U";
        } else if (keyCode == KeyEvent.VK_RIGHT) {

            fx = "R";
        } else if (keyCode == KeyEvent.VK_DOWN) {

            fx = "D";
        } else if (keyCode == KeyEvent.VK_LEFT) {

            fx = "L";
        }
//        if(!Isstart)
//        {
//            Init();
//        }
//        timer.start();
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyReleased(KeyEvent e) {

    }
}

GameStart.java

package TCS;

import javax.swing.*;

public class GameStart {
    public static void main(String[] args) {
        JFrame frame = new JFrame();//创建一个组件
        frame.setBounds(10,10,925,745);//设置大小
        frame.setResizable(false);//设置为固定大小
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//可以关闭
        frame.add(new GameRun());//添加
        frame.setVisible(true);
    }
}

总结

贪吃蛇是一款经典且开发起来特别简单的游戏项目之一,他的原理不过是将静态的图动态的展示出来,方向改变是速度改变,已经头部图片的改变,仅此而已。但是对于初学者来说,跟着作者的脚步,讲这样一款烙进骨髓的游戏开发出来,其成就感不言而喻。有兴趣开发此游戏可以去B站搜索遇见狂神说,当初我也是跟着他把这个游戏做出来的。为了增加难度,大家也可以发挥自己的想象力,增加一些骚操作。即致敬童年,又毁童年,在技术的加持下,完成童年想做但是没有办法做的事情。冲冲冲~~~~
在这里插入图片描述

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。