[javase]练手小项目贪吃蛇小游戏(代码片段)

maets906 maets906     2023-01-20     149

关键词:

本文章是【狂神说Java】一小时开发贪吃蛇游戏的学习笔记。

动画帧的概念

动画帧——就是影像动画中最小单位的单幅影像画面,相当于电影胶片上的每一格镜头。 一帧就是一副静止的画面,连续的帧就形成动画,如电视图象等。
我们通常说帧数,简单地说,就是在1秒钟时间里传输的图片的帧数,也可以理解为图形处理器每秒钟能够刷新几次,通常用fps(Frames Per Second)表示。
每一帧都是静止的图象,快速连续地显示帧便形成了运动的假象。高的帧率可以得到更流畅、更逼真的动画。每秒钟帧数 (fps) 愈多,所显示的动作就会愈流畅。
——来自百度知道

绘制静态窗口

作者这里在IDEA里新建项目时就遇到问题了:.java文件的左下角有个橙色小图标,鼠标移动到上面时显示"Java file outside of source root",并且main方法前也没有执行的绿色按钮。这里以作者之前做的一个学校作业为例。


这里参考了一篇博客解决了这个问题
关于IDEA中突然出现java file outside of source root的问题解决

按步骤点击后,界面恢复如下:

运行结果也正常


看完可能出现的问题后,我们回到正题。

我们新建一个项目,并建好包,并把图片资源导入。

作者并没有学过GUI的相关知识,所以这部分直接跟着视频敲就完事了。

//StartGame.java
package snakegames;

import javax.swing.*;

public class StartGame 
    public static void main(String[] args) 
        //1.绘制一个静态窗口 JFrame
        JFrame frame=new JFrame("Snake Game");
        frame.setBounds(10,10,900,720);//设置界面大小
        frame.setResizable(false); //窗口大小则不可改变
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭界面,游戏可以关闭了
        frame.setVisible(true);//让窗口能够显示出来

    

运行效果

绘制游戏面板

接下来我们新建一个类,用来编写画板。

//GamePanel.java
package snakegames;

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

public class GamePanel extends JPanel 
    //画板:画界面,画蛇
    @Override
    //Graphics 画笔
    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);
    

我们新建一个类Data来存放外部数据。

导入图片时要寻找好路径。

//Data.java
package snakegames;

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

//存放外部数据
public class Data 
    //头部的图片 URL:定位图片地址 ImageIcon:图片
    public static URL headerURL=Data.class.getResource("/statics/header.png");
    public static ImageIcon header=new ImageIcon(headerURL);

    //把图片全部导入
    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 URL bodyURL=Data.class.getResource("/statics/body.png");
    public static URL foodURL=Data.class.getResource("/statics/food.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);
    public static ImageIcon body=new ImageIcon(bodyURL);
    public static ImageIcon food=new ImageIcon(foodURL);


然后我们在StartGame类里添加上画板

//StartGame.java
package snakegames;

import javax.swing.*;

public class StartGame 
    public static void main(String[] args) 
        //1.绘制一个静态窗口 JFrame
        JFrame frame=new JFrame("Snake Game");
        frame.setBounds(10,10,900,720);//设置界面大小
        frame.setResizable(false); //窗口大小则不可改变
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭界面,游戏可以关闭了

        //2.面板JPanel 可以加入到Frame
        frame.add(new GamePanel());


        frame.setVisible(true);//让窗口能够显示出来

    

效果图

画静态小蛇

package snakegames;

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

public class GamePanel extends JPanel 

    int length;//蛇的长度
    int[] snakeX=new int[600];//蛇的坐标X
    int[] snakeY=new int[500];//蛇的坐标Y
    String fx;//R:right L:left U:up D:down


    //初始化
    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";
    
    //构造器
    public GamePanel()
        init();
    

    //画板:画界面,画蛇
    @Override
    //Graphics 画笔
    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);

        //画一条静态的小蛇
        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]);//蛇的身体长度通过length来控制
        
    

效果图

让小蛇动起来

接收键盘的输入:监听

package snakegames;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class GamePanel extends JPanel implements KeyListener 

    int length;//蛇的长度
    int[] snakeX=new int[600];//蛇的坐标X
    int[] snakeY=new int[500];//蛇的坐标Y
    String fx;//R:right L:left U:up D:down
    boolean isStart=false;//游戏是否开始

    //初始化
    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";
    
    //构造器
    public GamePanel()
        init();
        //获取键盘的监听事件
        this.setFocusable(true);
        this.addKeyListener(this);
    

    @Override
    public void keyTyped(KeyEvent e) /*键盘按下,弹起:敲击*/
    @Override
    public void keyReleased(KeyEvent e) /*释放某个键*/

    //接收键盘的输入:监听
    @Override
    public void keyPressed(KeyEvent e) 
        //键盘按下未释放
        //接收键盘的输入,获取按下的键盘是哪个键
        int keyCode=e.getKeyCode();
        if(keyCode==KeyEvent.VK_SPACE)//如果按下的是空格键
            isStart=!isStart;//如果是启动,就暂停;如果是不启动,则启动
            repaint();//刷新界面
        
    



    //画板:画界面,画蛇
    @Override
    //Graphics 画笔
    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);

        //画一条静态的小蛇
        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]);//蛇的身体长度通过length来控制
        
        //游戏提示是否开始
        if(isStart==false)
            //画一个文字 String
            g.setColor(Color.WHITE);//设置画笔的颜色
            g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体
            g.drawString("按下空格开始游戏",300,300);
        

    

效果图

按下空格后

再次按下空格

定时器,监听时间流动

我们想让小蛇动起来,最核心的部分就在下面。

直观地看:

  • 脑袋右移一格,第一个身体跟着脑袋右移到刚才脑袋的位置,第二个身体跟着移动到刚才第一个身体的位置
  • 脑袋下移一格,第一个身体跟着脑袋移动到刚才脑袋的位置,第二个身体跟着移动到刚才第一个身体的位置,以此类推

代码实现:

  • 除了脑袋,身体从最后一个开始,每个都向前移动,覆盖前一个身体

我认为actionPerformed方法中的内容,是整个项目的核心。

package snakegames;

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.sql.Time;

public class GamePanel extends JPanel implements KeyListener, ActionListener 

    int length;//蛇的长度
    int[] snakeX=new int[600];//蛇的坐标X
    int[] snakeY=new int[500];//蛇的坐标Y
    String fx;//R:right L:left U:up D:down
    boolean isStart=false;//游戏是否开始
    Timer timer=new Timer(100,this);//定时器


    //初始化
    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";
    
    //构造器
    public GamePanel()
        init();
        //获取键盘的监听事件
        this.setFocusable(true使用前端原生js,贪吃蛇小游戏

...,因为最近有点小忙。不过即使是忙,也也还是写了两个小游戏,其中一个就是这个,贪吃蛇啦。算是一个小练手了,这个是在有点太简单了,只是第一次写这种小游戏,还是零零星星花了三五天时间,下面就是这个小游戏的gif... 查看详情

汇编语言贪吃蛇游戏(代码片段)

  最近刚学完汇编,于是准备做个小游戏练练手。就瞅准了最最最老生常谈的贪吃蛇。  首先贪吃蛇必须是用户让蛇改变方向,蛇就得改变方向,吃到东西蛇会变长。  但我们不太可能一次性就做出来这么多功... 查看详情

gui简单实战——贪吃蛇(代码片段)

...前面学到的GUI基础知识完成实战,完成一个简单的贪吃蛇项目项目功能用键盘上下左右实现贪吃蛇的自动移动贪吃蛇吃到食物后,长度加一,分数加一贪吃蛇吃到自己的身体,则游戏结束按空格键实现游戏的暂停和继续效果截图... 查看详情

c语言项目:贪吃蛇游戏(双人模式),详细思路+源码分享(代码片段)

每天一个C语言小项目,提升你的编程能力!贪吃蛇游戏大家都玩过,它的玩法也很简单:用游戏按键上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长&#x... 查看详情

c语言零基础项目:贪吃蛇!详细思路+源码分享(代码片段)

每天一个C语言小项目,提升你的编程能力!贪吃蛇游戏大家应该都不陌生了,要说没玩过的话,可能你是15后吧?贪吃蛇游戏最初为单机模式,后续又陆续推出团战模式、赏金模式、挑战模式等多种玩法。... 查看详情

html实现简单的贪吃蛇小游戏(附完整源码)(代码片段)

 基于HTML5技术的贪吃蛇小游戏的设计与实现项目简介:        贪吃蛇作为我们儿时经典的游戏之一,它是一款单机而又好玩的小游戏。今天,就让我们用html5技术实现一个简单的贪吃蛇小游戏!项目核心技术... 查看详情

react-redux自制简易贪吃蛇小游戏(代码片段)

初始化用脚手架新建一个react项目:npxcreate-react-appsnake-demo关于安装和创建、启动,可以看我的这篇文章:React入门:基本环境搭建首先画一个框,当作边界,再初始化贪吃蛇,就像这样:左上角两个小黑... 查看详情

react-redux自制简易贪吃蛇小游戏(代码片段)

初始化用脚手架新建一个react项目:npxcreate-react-appsnake-demo关于安装和创建、启动,可以看我的这篇文章:React入门:基本环境搭建首先画一个框,当作边界,再初始化贪吃蛇,就像这样:左上角两个小黑... 查看详情

react-redux自制简易贪吃蛇小游戏(代码片段)

初始化用脚手架新建一个react项目:npxcreate-react-appsnake-demo关于安装和创建、启动,可以看我的这篇文章:React入门:基本环境搭建首先画一个框,当作边界,再初始化贪吃蛇,就像这样:左上角两个小黑... 查看详情

自制贪吃蛇游戏中的几个“大坑”(代码片段)

...深刻的“挫折”做一个具体的讲解,以此来为这个贪吃蛇项目画上一个完整句号。(包括打包这个游戏时遇到的问题及解决方式。)BUG1 在运行贪吃蛇游戏时,如果同时按下两个方向键会出现贪吃蛇“莫名其妙”死亡的情况... 查看详情

2021-10-18python使用curses库贪吃蛇小游戏走过的坑

Python使用curses库贪吃蛇小游戏走过的坑介绍引入自定义模块并同级调用Windows的curses库下载Redirectionisnotsupported.conda环境下的报错介绍在Github上发现了这个贪吃蛇小项目想当做练手贪吃蛇项目,没想到光是让它跑起来就踩了无... 查看详情

自动玩贪吃蛇的小白痴机器人(代码片段)

偶然间刷到的一个非常治愈的贪吃蛇小视频 于是萌生了制作这个小白痴机器人的念头使用机器人自动玩贪吃蛇  首先需要一个能正常玩贪吃蛇的游戏选用winform进行开发,非常快和方便分解需求首先需要一块画布在Form1... 查看详情

如何用pygame制作简单的贪吃蛇游戏(代码片段)

...次就使用pygame库写个简单的贪吃蛇吧,当做熟悉python练手也是不错的。2.安装与导入使用pipinstallpygame进入安装,安装成功后导入所需模块:importpygame,sys,rando 查看详情

如何用pygame制作简单的贪吃蛇游戏(代码片段)

...次就使用pygame库写个简单的贪吃蛇吧,当做熟悉python练手也是不错的。2.安装与导入使用pipinstallpygame进入安装,安装成功后导入所需模块:importpygame,sys,rando 查看详情

py小游戏系列贪吃蛇,儿时的回忆(代码片段)

...玩意的老诗。老规矩,先上效果图这是一个贪吃蛇的小游戏。我们8090后这一代人肯定会碰到过。蛇会随着吃到的食物变得越来越长。然后碰到墙壁或者碰到自己的身体都会输掉游戏。这个是简陋版的贪吃蛇,但是最基本... 查看详情

py小游戏系列贪吃蛇,儿时的回忆(代码片段)

...玩意的老诗。老规矩,先上效果图这是一个贪吃蛇的小游戏。我们8090后这一代人肯定会碰到过。蛇会随着吃到的食物变得越来越长。然后碰到墙壁或者碰到自己的身体都会输掉游戏。这个是简陋版的贪吃蛇,但是最基本... 查看详情

c++入门——实现贪吃蛇游戏(代码片段)

参考《C和C++游戏趣味编程》贪吃蛇游戏键盘控制小蛇上、下、左、右移动,迟到食物后长度加1;蛇头碰到自身或窗口边缘,游戏失败程序框架#include<graphics.h>#include<conio.h>#include<stdio.h>//全局变量定... 查看详情

面向对象案例——贪吃蛇游戏(代码片段)

最近项目上线,近一个星期没更博了,今天来写一个经典的游戏案例——贪吃蛇。在这个简单的案例里可以体会javaScript面向对象开发相关模式,学习使用面向对象的方式分析问题。1.功能实现1.1搭建页面:放一个容器盛放游戏场... 查看详情