java小游戏——飞翔的小鸟(java初学作品)

这篇具有很好参考价值的文章主要介绍了java小游戏——飞翔的小鸟(java初学作品)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

注:学习了java基础后,做出来的一个小作品,可以用来巩固学习

概述:

飞翔的小鸟能够作为Java基础的收官之作,包涵了Java很多的基础知识,在学习完Java基础后,尝试编写一些东西,能够起到很好的查漏补缺的作用。这里实现了Java小游戏飞翔的小鸟的一些基本功能。另外,随着学习水平的提高,以后也有可能会进行不断地改进。

同时,以下代码我也会尽我所能做好注释解释清楚

编写要求:

Java基础知识的掌握,Java的三大特性(多态,封装,继承),窗口的绘制,画笔的使用,io流,异常处理,数组,集合等

目录

概述:

编写要求:

游戏思路:

具体分析:

app包:

GameApp类:实现游戏的启动运行

main包:

GameFrame类:游戏主窗口类

Bird类:编写与小鸟有关的内容的类

Coloud类:

Barrier类:

GameBarrierLayer类:

Barrierpool类:

GameFrontGround类:

GameTime类:

Music类:

util包:


游戏共用到了三个包app包,放入游戏运行的入口类;main包,存放实现游戏各功能类的包;util包,存放游戏工具类以及一些常量的包;13个类,每个类都有各自的不同功能,方便进行查找和修改。

具体分析:

app包:

GameApp类:实现游戏的启动运行

GameApp类作为游戏的入口,进行初始化主窗口类的对象,来加载主窗口类的内容

代码为:



import main.GameFrame;


public class GameApp {
    public static void main(String[] args){
//实例化GameFrame类
        new GameFrame();
    }
}

main包:

GameFrame类:游戏主窗口类

所有游戏中绘制的内容都在这个窗口中完成,进行编写的功能具体有:实例化各类;

初始化游戏中一些内容的对象;

添加监听事件;

重写update方法实现双缓冲技术,避免屏幕闪烁问题,同时添加上游戏暂停结束的画面;

代码具体的实现

package main;

import static util.Constant.*;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;

//游戏的主窗口类,所有在游戏中绘制的内容都在此窗口中完成
//GameFrame继承Frame,使GameFrame类有创建窗口的功能
public class GameFrame extends Frame {

    //实例化GameBackGround中的类
    private GameBackGround gameBackGround;

    //实例化小鸟的类
    private Bird bird;

    //实例化障碍物层类
    private GameBarrierLayer gameBarrierLayer;

    //实例化前景类
    private GameFrontGround gameFrontGround;

    //实例化云彩类
    private Cloud cloud;

    //存放图片的 图片
    //设置一张图片
    //传进图片的长度和高度
    private BufferedImage buffimg = new BufferedImage(FRAM_WIDTH, FRAM_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR);


    //定义一个构造方法初始化一些参数
    public GameFrame(){
        //窗口是否可见
        setVisible(true);
        //窗口大小(没有定义静态之前,需要使用类名进行调用)
//        setSize(Constant.FRAM_WIDTH, Constant.FRAM_HEIGHT);
        //如果把Constant=包定义成静态的,后面加上.*,则可以省略Constant的调用
        setSize(FRAM_WIDTH, FRAM_HEIGHT);

        //窗口标题
        setTitle(FRAM_TITLE);
        //窗口的初始化位置
        setLocation(FRAM_X, FRAM_Y);
        //窗口的大小不可改变
        setResizable(false);
        //给窗口添加关闭事件

        /*该代码为在  Swing  程序中添加一个窗口监听器,
        并为窗口关闭事件添加一个监听函数。当用户关闭窗口时,
        代码会调用  System  类的  exit()  方法,将程序正常结束。
        由于传入的窗口适配器是匿名内部类,
        这意味着我们可以简单地在构建对象时指定事件,
        而不用创建新的自定义窗口适配器类。
        */
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);//结束程序
            }
        });

        //在构造器中调用下面初始化的对象
        initGame();

        //启动线程
        new run().start();

        //添加监听
        /*KeyAdapter是一个类
        KeyAdapter中已经实现了对键盘事件的监听方法,
        但这些方法的实现是空的,我们需要在使用时重写这些方法,
        根据需求处理键盘事件。*/
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
//调用add方法,实现相应的键盘监听
                add(e);
            }

            @Override
            public void keyReleased(KeyEvent e) {
                minu(e);
            }
        });



    }

    //初始化对象
    /*在GameFrame类中,
    实例化了GameBackGround类的对象gameBackGround,
    即在GameFrame对象初始化的同时也初始化了gameBackGround对象。
    这是因为在游戏的主窗口中,需要在窗口中绘制游戏的背景。
    在GameBackGround类中封装了绘制背景的方法,
    因此需要创建一个GameBackGround对象,通过调用其方法来绘制背景。
    同时,在GameBackGround类中还包含了游戏中玩家、敌人、子弹等对象的初始化,
    这些对象同样需要在GameFrame中使用,因此需要实例化GameBackGround类的对象。*/
    public void initGame(){
//分别实例化GameBackGround类,Bird类,GameFrontGround类,GameBarrierLayer类的对象,
        gameBackGround = new GameBackGround();
        bird = new Bird();

        gameFrontGround = new GameFrontGround();

        gameBarrierLayer = new GameBarrierLayer();

    }

    //写一个线程
    /*
    * 这是一个继承自Thread类的run类。
    * 它重写了Thread类中的run方法。
    * 在这个run方法中,它执行了repaint()方法,
    * 这个方法会调用paint()方法重新绘制组件。
    * 在多线程环境下,这个类的实例可以与其他线程并发执行。
    * 当这个线程启动时,它会自动调用run方法。
    * 所以在这个run方法中,它会反复调用repaint方法来不断刷新界面。
     */
    class run extends Thread{
        @Override
        public void run(){
            while (true) {
                repaint();
                try {
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }
//定义初始化是否开始的状态为true,在后面方便实现游戏暂停
    public static boolean isStarted = true;
    //写一个update方法,所有需要绘制的内容都在这里面绘制
    
    /*这段代码是Java中的重写方法,通常用于在每次图形界面需要更新时,
    自动调用该方法。

具体而言,该方法首先调用了gameBackGround对象的draw方法,绘制了背景图像。
然后调用了bird对象的draw方法,绘制了小鸟图像。

这里需要注意的是,Graphics对象是一个类似于画布的实例,
draw方法则是用来在画布上绘制图像的方法。因此,在调用draw方法时,
需要将该对象作为参数传递进去,使得绘制的图像可以正确显示在画布上。
实现了游戏界面的绘制

需要注意的是,该方法实现了双缓冲技术,即先将需要绘制的所有元素绘制在缓存图片上,
然后再一次性绘制到屏幕上,避免了图像闪烁等问题。*/
@Override
    public void update(Graphics g){
//进行判断,如果小鸟的生命值大于0,并且处于游戏开始状态,执行代码
        if (bird.life > 0 && isStarted == true){
//播放音乐
            Music.playMusic();
            //得到图片的画笔
            Graphics graphics = buffimg.getGraphics();
            //把所有要绘制的东西全部放在这张图片上,绘制背景,小鸟,前景,障碍物
            gameBackGround.draw(graphics);
            bird.draw(graphics);
            gameFrontGround.draw(graphics);
            gameBarrierLayer.draw(graphics,bird);

            //然后一次性把这张图片绘制在屏幕中
            g.drawImage(buffimg, 0, 0, null);

        }//如果小鸟的生命值大于0,游戏处于暂停状态,执行下列代码
else if(bird.life > 0 && isStarted == false){
            //停止播放音乐
            Music.stopMusic();
//           设置字体颜色为白色
            g.setColor(Color.WHITE);
//        设置字体,风格,字号
            g.setFont(new Font("微软雅黑", 1, 40));
            //打印游戏暂停时的提示语)
            g.drawString("点击空格键开始", 120, 180);
        }
        else{//小鸟死亡时执行下列语句
//        停止播放音乐
            Music.stopMusic();
//        定义游戏结束的提示
            String over = "游戏结束";
//        设置字体的颜色为红色
            g.setColor(Color.red);
//        设置字体,风格,字号
            g.setFont(new Font("微软雅黑", 1,60));
//        字体打印的语句,xy对应的位置
            g.drawString(over, 180, 200);
//        重新开始的提示语
            String reset = "Space Reset Game";
//        打印的内容,对应xy轴的位置
            g.drawString(reset, 25, 300);
        }

    }
    //调整up与down的true与false情况
    //fly等于1,up为true,为5,up为false
    //按键
    public void add(KeyEvent e){
        switch(e.getKeyCode()){
            case KeyEvent.VK_UP:
//        如果点击的是上建,up定义为true,Bird类中会根据up的值定义小鸟的飞行状态
                bird.fly(1);
                break;
//        点击的是空格键
            case KeyEvent.VK_SPACE:
//        如果小鸟生命值为0,小鸟死亡时
                if (bird.life == 0){
//        重新开始游戏
                    restart();
                }else{
//        小鸟没有死亡,isStarted取相反值,使游戏停止
                    isStarted = !isStarted;                
                }
                break;
        }

    }
    //松键方法
    public void minu(KeyEvent e){
        switch (e.getKeyCode()){
//        松开向上按键,调用小鸟类中的fly方法,up定义为false,小鸟飞翔状态改变
            case KeyEvent.VK_UP:
                bird.fly(5);
                break;
        }
    }
    public void restart(){
        //清空障碍物
        gameBarrierLayer.restant();
        //小鸟回原来位置
        bird.restarDraw();
        //重新定义是否开始的状态为true
         isStarted = true;

    }

}

Bird类:编写与小鸟有关的内容的类

定义小鸟的初始状态;给小鸟添加矩形框,方便进行碰撞检测;定义控制小鸟移动,改变小鸟移动,重新定义小鸟位置与生命值的方法

package main;

import static util.Constant.*;
import util.GameUtil;

import java.awt.*;
import java.awt.image.BufferedImage;

public class Bird {
    //定义一个加速度acceleration
    private int acceleration =0;

    //给小鸟添加矩形框
    private Rectangle rect;

    //小鸟设定生命值
    public int  life = 3;

    //定义一个数组,存放小鸟图片,三张
    private BufferedImage[] images;
    public static final int BIRD_IMAGE_COUNT = 3;

    //小鸟移动的方向
    private boolean up = false, down = false;

    //小鸟初始化速度
    private int speed = 4;

    //小鸟状态,小鸟的状态等于对应的数字时,把小鸟的图片换成对应的图片
    private int state;
    public static final int STATE_NORMAL = 0;//平着飞
    public static final int STATE_UP = 1;//向上飞
    public static final int STATE_DOWN = 2;//向下飞

    //小鸟位置
    private int x = 150, y = 200;

    //构造方法中对资源初始化
    public Bird(){
        //初始化集合用来存储小鸟的个数

        /*这段代码是用来初始化小鸟对象的构造方法,
        其中主要包含了对小鸟图片资源的初始化。
        具体来说,
        该构造方法通过定义一个名为images的实例变量来存储小鸟的图片资源,
        其长度为BIRD_IMAGE_COUNT,即小鸟图片的数量。
        接下来使用了一个for循环,循环次数为BIRD_IMAGE_COUNT,
        即将每张小鸟图片的路径传进GameUtil.loadBufferedImage方法中,
        获得对应的BufferedImage对象后存入images数组中,
        使得小鸟对象的images变量存储了所有小鸟图片资源。
        其中loadBufferedImage是一种自定义的方法,
        用于将指定路径的图片文件读入内存并返回对应的BufferedImage对象。
        在游戏中,小鸟的各个动作需要对应不同的图片资源,
        因此此步骤对所有小鸟图片资源的读取和存储是十分必要的。
         */
        images = new BufferedImage[BIRD_IMAGE_COUNT];
        for (int i = 0; i < BIRD_IMAGE_COUNT; i++) {
            //把路径传进来,把每张小鸟图片的路径传入GameUtil.loadBufferedImage方法中
            images[i] = GameUtil.loadBufferedImage(BIRD_IMG[i]);

        }
        //定义矩形框的宽高,宽高为小鸟图片的宽高
        int w = images[0].getWidth();
        int h = images[0].getHeight();
//        实例化矩形框
        rect = new Rectangle(w,h);
    }
    //绘制小鸟
    public void draw(Graphics g){
//        调用控制小鸟移动的方法
        flyLogic();

        //画出对应的小鸟图片
        //小鸟图片放到数组中。直接使用数组即可
        g.drawImage(images[state], x, y, null);
        //绘制小鸟矩形
//        g.drawRect(x, y, (int)rect.getWidth(), rect.height);
        //给矩形的宽高进行赋值
        rect.x = this.x;
        rect.y = this.y;
    }

    //控制小鸟移动的方向
    public void flyLogic(){
    //点击上建,up的值为true
        if (up == true){
//            y -= speed;
//        小鸟的加速度自减
            acceleration--;
//        设置小鸟y坐标的移动
            y+=acceleration;
//    如果加速度小于10,令加速度等于-10
            if (acceleration < -10){
                acceleration = -10;
            }
//        如果y坐标小于20,令y坐标不变,加速度为0
            if (y < 20){
                y = 20;
                acceleration = 0;
            }
        }
//松开向上箭头键,up为false,情况与上面类似
        if (up != true){
//            y += speed;
            acceleration++;
            y+=acceleration;
            if (acceleration > 10){
                acceleration = 10;

            }
            if (y > 475){
                y = 475;
                acceleration = 0;
            }
        }
    }
    //改变小鸟状态的方法
    public void fly(int fly){
        switch(fly){
            case 1:
                state = 1;
                up = true;
                break;
            case 5:
                state = 2;
                up = false;
                break;
        }
    }
    //定义矩形框的get方法,方便障碍物画矩形框
    public Rectangle getRect() {
        return rect;
    }
    //重新绘制小鸟位置与小鸟生命值
    public void restarDraw(){
        life = 3;
        x = 200;
        y = 200;
    }
}

Coloud类:与云彩有关的类

详细有云彩速度,位置的定义,画出云彩的方法,判断云彩是否飞出屏幕以外的方法

package main;


import java.awt.*;
import java.awt.image.BufferedImage;

//云彩类
public class Cloud {
    //云彩图片
    private BufferedImage img;

    //云彩速度
    private int speed;
    //云彩位置
    private int x, y;
    //构造函数 空参实参
//    在调用实参构造方法时进行赋值
    public Cloud(){}
    public Cloud(BufferedImage img, int speed, int x, int y){
        this.img = img;
        this.speed = speed;
        this.x = x;
        this.y = y;

    }
    //写一个draw方法画出云彩
    public void draw(Graphics g){
//    实现云的移动,云在x轴上以speed的速度不断移动
        x -= speed;
//    画出云的位置,参数分别为云的图片,xy轴的坐标,转换了更多图像时要通知的对象
        g.drawImage(img, x, y, null);
    }

    //判断云彩是否飞出屏幕以外,根据返回值的类型在GameFrontGround类中判断是否需要移除云
    public boolean isOutFrame(){
//        如果云的x坐标小于-50
        if(x < -50){
//        返回true
            return true;
        }else{
            return false;
        }
    }
}

Barrier类:障碍物类

与障碍物有关的操作的编写,定义障碍物的矩形,速度,存放障碍物的数组,障碍物的状态;

静态代码块初始化障碍物的参数,在加载类时优先执行;

draw方法,绘制障碍物;

绘制四种障碍物的方法;

给障碍物绘制矩形用于进行碰撞检测的方法;

判断绘制障碍物时机的方法;

package main;


import util.Constant;
import util.GameUtil;

import java.awt.*;
import java.awt.image.BufferedImage;

//障碍物类
public class Barrier {
    //用于判断障碍物是否要进行移动
    private boolean mob = true;
    //定义一个矩形
    private  Rectangle rect;

    //定义障碍物的速度
    private int speed = 3;
    //定义一个数组,来存放障碍物的三种图片
    private static BufferedImage[] imgs;

    //障碍物状态
    private boolean visible;

    //写一个静态代码块,初始化参数,在加载类时会优先执行
    static {
        //记录障碍物图片的张数
        final int COUNT = 3;

        //类加载时初始化三张障碍物图片,传入图片个数
        imgs = new BufferedImage[COUNT];
        for (int i = 0; i < COUNT; i++) {
            //把图片存放到障碍物的数组中
            imgs[i] = GameUtil.loadBufferedImage(Constant.BARRIER_IMG_PATH[i]);

        }

    }
    //定义障碍物的位置,宽高,类型,创建障碍物图像时能够使用到
    private int x, y;
    private int width, height;//height是障碍物的一个属性,每个障碍物的高度都可能不同
    private int type;
//    绘制不同种障碍物类型的参数
    public static final int TYPE_TOP_NORMAL = 0;
    public static final int TYPE_BOTTOM_NORMAL = 2;
    public static final int TYPE_NOVER_NORMAL = 4;
    public static final int TYPE_MOBLE = 6;

    //获得障碍物的宽度和高度
    //中间
//    imgs[]数组中第一张图片的宽高
    public static final int BARRIRE_WIDTH = imgs[0].getWidth();
    public static final int BARRIRE_HEIGHT = imgs[0].getHeight();
    //上下朝向
//    分别为imgs[]数组中第二张图片的宽高
    public static final int BARRIRE_HEAD_WIDTH = imgs[1].getWidth();
    public static final int BARRIRE_HEAD_HEIGHT = imgs[1].getHeight();

    //定义构造器
    public Barrier(){
        //初始化矩形参数
        rect = new Rectangle();
    }
   
    //编写draw方法,根据不同的类型绘制障碍物
    public void draw(Graphics g){
        switch(type){
            case TYPE_TOP_NORMAL:
//        画出从上到下的障碍物
                drawTopNormal(g);
                break;
//        画出从下到上的障碍物
            case TYPE_BOTTOM_NORMAL:
                drawNormalTop(g);
                break;
//        画出中间的障碍物
            case TYPE_NOVER_NORMAL:
                drawHoverNormal(g);
                break;
//        画出中间移动的障碍物
            case TYPE_MOBLE:
                drawMobile(g);
                break;

        }
    }
    //绘制从上到下的障碍物
    public void drawTopNormal(Graphics g){

        //求出所需要的障碍物的块数
        //高度减去头的高度,再除以中间的高度加1就是中间障碍物所需要的块数
        int count = (height - BARRIRE_HEAD_HEIGHT)/BARRIRE_HEIGHT+1;

        //使用for循环绘制中间障碍物
        for (int i = 0; i < count; i++) {
            //drawImage方法用来绘制图片
            g.drawImage(imgs[0], x, y+i*BARRIRE_HEIGHT, null);

        }
        //绘制头
        int y = height - BARRIRE_HEAD_HEIGHT;
//    画出imgs数组中第三张图片,参数分别为对应的图片,xy轴的坐标,转换更多图像时
//要通知的对象,这里不进行通知
        g.drawImage(imgs[2], x - (BARRIRE_HEAD_WIDTH - BARRIRE_WIDTH)/2, y, null);
//    头的左边左移,实现障碍物的移动
        x -= speed;
        if (x < -50){
//        设置visible的值,判断是否需要移除障碍物
            visible = false;
        }
//        调用绘制矩形框的方法绘制矩形框
        rect(g);

    }
    //绘制从下往上的障碍物
    public void drawNormalTop(Graphics g){
        //障碍物所需要的块数
        int count = height / BARRIRE_HEIGHT + 1;

        //for循环绘制中间障碍物
        for (int i = 0; i < count; i++) {
//        drawImage方法画出图片,
            g.drawImage(imgs[0], x, y+imgs[1].getHeight()+i*imgs[0].getHeight(), null);

        }

        //绘制头
        int y = Constant.FRAM_HEIGHT-height;
//        this.y = y;
        g.drawImage(imgs[1], x - (BARRIRE_HEAD_WIDTH-BARRIRE_WIDTH)/2, y, null);

        x -= speed;

        //如果障碍物除了屏幕以外,状态改为false
        if (x < -50){
            visible = false;
        }
        rect(g);
    }

    //绘制中间的障碍物
    public void drawHoverNormal(Graphics g){

        //求出所需要的障碍物的块数
        //高度减去头的高度,再除以中间的高度加1就是中间障碍物所需要的块数
        int count = (height - BARRIRE_HEAD_HEIGHT) / BARRIRE_HEIGHT;
//        System.out.println(count+"aaaa");
        //绘制上头
        g.drawImage(imgs[1], x, y, null);
        //使用for循环绘制中间障碍物
        for (int i = 0; i < count; i++) {
            //drawImage方法用来绘制图片
            g.drawImage(imgs[0], x, y+BARRIRE_HEAD_HEIGHT+i*BARRIRE_HEIGHT, null);

        }
        rect(g);
        //绘制下头
        int y11 = y+height - BARRIRE_HEAD_HEIGHT;
//        System.out.println(y);
        g.drawImage(imgs[2], x, y11, null);

        x -= speed;
        if (x < -50){
            visible = false;
        }


    }

    //绘制可以移动的障碍物
    public void drawMobile(Graphics g){

        //求出所需要的障碍物的块数
        //高度减去头的高度,再除以中间的高度加1就是中间障碍物所需要的块数
        int count = (height - BARRIRE_HEAD_HEIGHT) / BARRIRE_HEIGHT;
//        System.out.println(count+"aaaa");
        //绘制上头
        g.drawImage(imgs[1], x, y, null);
        //使用for循环绘制中间障碍物
        for (int i = 0; i < count; i++) {
            //drawImage方法用来绘制图片
            g.drawImage(imgs[0], x, y+BARRIRE_HEAD_HEIGHT+i*BARRIRE_HEIGHT, null);

        }
//        调用画矩形框的方法绘制矩形框
        rect(g);
        //绘制下头
        int y11 = y+height - BARRIRE_HEAD_HEIGHT;
        g.drawImage(imgs[2], x, y11, null);

        x -= speed;
        if (x < -50){
            visible = false;
        }
        //让障碍物移动
        if (mob){
            y+=5;
            if(y >=250){
                mob = false;
            }
        }else if (!mob){
            y-=5;
            if (y<=100){
                mob = true;
            }
        }

    }

    /*rect(Graphics  g):
    绘制障碍物碰撞的矩形。
    该方法接收一个  Graphics  对象  g,
    用于在指定区域绘制障碍物的矩形。
    它使用障碍物的  x、y  坐标来确定绘制的矩形的位置,
    使用障碍物图片数组  imgs[0]  的宽度  w1  来
    确定矩形的宽度,而  height  则作为矩形的高度。
    在绘制矩形时,使用了预设的颜色  Color.red。*/
    //绘制障碍物碰撞的矩形
    public void rect(Graphics g){
        int x1 = this.x;
        int y1 = this.y;
        int w1 = imgs[0].getWidth();
        g.setColor(Color.red);
//        g.drawRect(x1, y1, w1, height);
        //调用障碍物矩形参数的方法
        setRecyangle(x1, y1, w1, height);

    }

    /*setRecyangle(int  x,  int  y,  int  width,  int  height):
    障碍物的矩形参数。该方法接收四个整数参数,
    分别表示矩形的位置和大小。
    它将这四个参数值赋值给对象的矩形参数  rect,
    以便后续在游戏中进行碰撞检测。*/
    //障碍物的矩形参数
    public void setRecyangle(int x, int y, int width, int height){
        rect.x = x;
        rect.y = y;
        rect.width = width;
        rect.height = height;

    }


    //判断什么时候绘制障碍物,可以调节障碍物之间的距离,让游戏简单或困难
    public boolean isInFrame(){
        return 600-x>180;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }
    public boolean getVisible(){
        return visible;
    }
    public void setVisible(boolean visible){
        this.visible = visible;
    }

    public Rectangle getRect() {
        return rect;
    }
}

GameBarrierLayer类:障碍物层类

定义一个数据记录小鸟飞行的最大时间;

实例化时间类,获取随机数,定义List集合存放障碍物,定义构造器初始化数据;

编写drw方法绘制障碍物;

编写logic方法定义游戏开始,暂停,结束状态;

编写insert方法获得障碍物对象,添加障碍物;

ran方法产生随机数;

判断小鸟发生碰撞的方法;

清空障碍物池;

储存和得到数据方法;

package main;


import java.awt.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

//障碍物层类
public class GameBarrierLayer {

    //定义一个数据
    private int txt;

    //实例化时间类
    private GameTime gameTime;


    private Random random = new Random();
    /*这是一个Java类定义,主要作用是创建一个障碍物图层,
    并且使用ArrayList来存储障碍物对象。

代码中的  "List<Barrier>  barriers"  是一个成员变量,
表示一个障碍物对象的列表,其中每个障碍物对象的类型是  "Barrier"。

在构造函数中,使用  "ArrayList<>()"  初始化了  "barriers"  列表,
该列表将用于存储障碍物对象。
由于  "ArrayList"  类实现了  "List"  接口,
因此它提供了一些方便的方法来管理和访问列表中的元素。

因此,在创建  "GameBarrierLayer"  对象时,
可以使用构造函数来初始化  "barriers"  列表,
然后将其用于存储障碍物对象。
*/

    //定义一个数组存放障碍物
    private List<Barrier> barriers;

    //定义构造器初始化数组
    public GameBarrierLayer(){
        barriers = new ArrayList<>();
        gameTime = new GameTime();
    }

    //绘制障碍物
    /*该代码是一个游戏中生成障碍物的功能实现。
    在draw方法中,首先通过for循环遍历所有已存在的障碍物对象并进行绘制。
    接着调用logic方法,该方法用于检测是否需要生成新的障碍物。

在logic方法中,首先判断已存在的障碍物数量是否为0,
若为0则调用ran方法生成一个随机数作为障碍物的高度,
并创建上下两个障碍物对象。这两个对象的x坐标都为600,
即在屏幕最右边生成,并分别设置其高度为numberTop和500-numberDown。

若已存在障碍物,
则检测最后一个障碍物是否已经完全进入屏幕内(即其x坐标是否小于0),
若已经进入则和上述过程相同再生成一个新的障碍物对。

总的来说,这段代码的作用是实现游戏中不断生成障碍物的效果,
并且保证生成的障碍物数量始终能够满足游戏的需求。
*/
    public void draw(Graphics g,Bird bird){
//    如果不使用循环进行编写
        //new一个障碍物类
//        Barrier barrier = new Barrier(200, 0, 200, 0);
//        barrier.draw(g);
//        barriers.add(barrier);
//        barriers.get(0).draw(g);
//        Barrier barrier1 = new Barrier(300, 0, 300, 2);
//        barriers.add(barrier1);
//        barriers.get(1).draw(g);
      

//    定义了一个循环变量i,初始值为0,每次循环自增1,
//    直到i小于barriers的大小(即barriers列表中元素的数量)时循环结束。
        for(int i = 0; i < barriers.size(); i++){
//        通过get(i)方法从barriers列表中获取当前元素
//        并给barrier变量赋值,用于之后的操作。
            Barrier barrier = barriers.get(i);
//    判断barrier元素的可见属性是否为true,
//    如果是,就执行下一行的代码;否则执行else语句块中的代码。

            if (barrier.getVisible() == true){
//调用barrier元素的draw()方法来绘制该元素的外观,
//    即在屏幕上显示。
                barrier.draw(g);
            }else{
//    从barriers列表中移除当前元素并将其赋给remove变量。

                Barrier remove =barriers.remove(i);
//   将remove元素放回对象池(可以理解为回收该对象,
//以便之后重复利用)。

                Barrierpool.setPool(remove);
//由于remove元素被移除后,
//后面的元素都往前移了一位,
//所以需要将循环变量i减去1以便下一次循环能正确地处理所有元素。
                i--;
            }

        }
//    判断小鸟是否发生碰撞
        collideBird(bird);
//    
        logic(g,bird);
    }

/*游戏的主要逻辑部分。首先判断是否已经生成了障碍物,如果没有则调用  `ran()`  方法生成随机数来决定生成障碍物的种类和数量,并开始计时。然后根据障碍物种类和数量调用  `insert()`  方法创建相应数量的障碍物对象,添加到  `barriers`  集合中。

如果已经存在障碍物,则显示已经坚持的时间和当前小鸟的生命值,并根据上一次的最高记录调用  `getTxt()`  方法获取最高纪录,如果当前时间比最高纪录长,则更新最高纪录并调用  `setTxt()`  方法保存到文件中。接着判断最后一个障碍物是否已经完全进入屏幕内,如果是则再次随机生成障碍物种类和数量,并调用  `insert()`  方法创建新的障碍物对象后添加到  `barriers`  集合中。最后刷新游戏窗口,并继续下一次循环*/
    public void logic(Graphics g,Bird bird){
//    如果障碍物集合为空
        if(barriers.size() == 0){
//    随机数方法,得到两个随机数
            ran();
            //添加计时
            gameTime.begin();


            //障碍物从屏幕最右边生成
            //上方
//            Barrier top = new Barrier(600, 0, numberTop, 0);
//            barriers.add(top);
            //下方
//            Barrier down = new Barrier(600, 500-numberDown, numberDown, 2);
//            barriers.add(down);
//  获取到一个障碍物并进行赋值,上方的 
            insert(600, 0, numberTop, 0);
//    获取到一个下方的障碍物并进行赋值,同时把障碍物存入集合中
            insert(600, 500-numberDown, numberDown, 2);

        }else{
//        获得游戏时间,并把游戏时间打印出来
            long differ = gameTime.differ();
//设置字体,格式,大小
            g.setFont(new Font("微软雅黑", 1, 20));
//设置字体颜色
            g.setColor(Color.black);
//画出经历的时间
            g.drawString("坚持了"+differ+"秒", 30, 50);
//画出小鸟生命值剩余情况
            g.drawString("小鸟生命:"+bird.life,450,50);
//获得文本内储存的数据
            txt = getTxt();
            if (differ <= txt){
//如果经历的时间小于文本内储存的数据,打印最高成绩为文本内数据
                g.drawString("最高成绩 :"+txt, 200, 50);
            }else{
                //否则,储存最高记录
                setTxt(String.valueOf(differ));
//                打印最高记录
                g.drawString("最高成绩:"+differ, 200, 50);
            }
            //判断最后一个障碍物是否完全进入屏幕内
            Barrier last = barriers.get(barriers.size() - 1);
//如果进入屏幕内
            if (last.isInFrame()){
//重新生成随机数
                ran();
//    生成的随机数小于50
                if(number < 50){
// 画
                    insert(600, 50, 350, 4);
//                    System.out.println("440的障碍物");
                }else if(number > 450){
                    insert(600, 125, 200, 6);
//                    System.out.println("220的一个障碍物");
                }else{
                    insert(600, 0, numberTop, 0);
                    insert(600, 500-numberDown, numberDown, 2);
                }
//                //障碍物从屏幕最右边生成.创建上下两个障碍物对象
//                //上方
//                Barrier top = new Barrier(600, 0, numberTop, 0);
//                barriers.add(top);
//                //下方
//                Barrier down = new Barrier(600, 500-numberDown, numberDown, 2);
//                barriers.add(down);

            }
        }
    }
    //从池中获取对象,把参数封装成barrier存入barriers数组中
    /*这段代码的作用是往一个存储障碍物的列表中添加一个新的障碍物,
总体来说,这段代码是实现了从对象池中获取一个Barrier对象,
并通过给其属性赋值的方式来创建一个新的障碍物,
最后将其添加到存储障碍物的列表中。
这种方式可以避免频繁地创建和销毁对象带来的性能问题。
*/
//定义了一个公共方法insert,传入参数包括障碍物的位置和类型信息
    public void insert(int x, int y, int num, int type){
//    从一个对象池中获取一个Barrier对象,并赋值给top变量
        Barrier top = Barrierpool.getPool();
//    给top对象设置x坐标
        top.setX(x);
//    给top对象设置y坐标。

        top.setY(y);
//    //给top对象设置长度
        top.setHeight(num);

//    给top对象设置类型。
        top.setType(type);
//设置visiable的值为true
        top.setVisible(true);
//    将top对象添加到一个存储障碍物的列表中。
        barriers.add(top);
    }

    //上方障碍物高度
    private int numberTop;
    //下方障碍物高度
    private int numberDown;
    //中间悬浮的障碍物
    private int number;

    //产生三个100~500的随机数的方法
    public void ran(){
        numberTop = random.nextInt(400)+100;
        numberDown = random.nextInt(400)+100;
        number = random.nextInt(500);


        //如果管道重合(两个管道的高度和大于450,小鸟无法飞过),重新生成随机数
        if (numberTop + numberDown >= 450){
            ran();
        }
    }
    //判断障碍物与小鸟发生碰撞
    public boolean collideBird(Bird bird){
        for (int i = 0; i < barriers.size(); i++) {
//    获得障碍池中的障碍物对象
            Barrier barrier = barriers.get(i);
//    矩形框的碰撞方法,判断矩形框是否有重合
            if (barrier.getRect().intersects(bird.getRect())){
                System.out.println("撞上了");
//    撞上后小鸟的生命值减一
                bird.life--;
//    移除与小鸟相撞的障碍物对象
                barriers.remove(barrier);

            }
        }

        return false;

    }
    //清空障碍物池的方法
    public void restant(){
        barriers.clear();
    }

    //创建一个File,传入记录最高分数文件的路径,创建的文件内传入一个数字,否则会报出异常
    static File file = new File("传入txt文件的路径");
    //储存数据了,写入一个字符串到文件中
    public static void setTxt(String str){
//    创建一个FileWrite的对象,该对象是FileWriter的实现类,置为null,方便异常处理
        FileWriter fileWriter = null;
        try {//利用传入的文件对象,创建FileWriter对象,指定写入的文件
            fileWriter = new FileWriter(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {//调用write方法,把参数str写入到文件中
            fileWriter.write(str);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {//关闭文件
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    //得到文件中的数据
    public int getTxt(){
//创建一个名为in的BufferedReader对象,该对象取至file文件,null方便进行异常处理
        BufferedReader in = null;
//    通过readLine方法逐行读取文件内容,并将其解析为整数值,赋值给read
        try {//利用传入的文件file,创建BufferedReader的对象
            in = new BufferedReader(new FileReader(file));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
//        String s = in.readLine();
        int read = 0;

        try {//从文件中读取一行字符串,并将其转换为整型值
            read = Integer.parseInt(in.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {//关闭文件流
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }//返回读到的整型值
        return read;
    }

}

Barrierpool类:障碍物池类

创建用于管理池中所有对象的容器

定义池中初始化对象的个数和池中对象的最大个数

使用静态代码块初始化池中的对象

分别定义从从池中获取对象和把对象归还容器的方法

package main;


import java.util.List;
import java.util.ArrayList;

/*每次需要障碍物的时候都会创建一个对象,占用大量内存,需要创建一个对象池类
为了避免反复创建和销毁对象,使用对象池来创建好一些对象,
使用的时候从池中获得,使用完毕后,归还*/
public class Barrierpool {

    /*这段代码是一个使用对象池技术实现的管理器。
对象池是一种重复利用已经创建的对象来避免重复创建和
销毁对象的技术,从而提高程序性能。

在这个示例中,对象池中存储的是Barrier对象。
这个对象池使用一个静态的List<Barrier>来存储对象,
而不是每次需要一个Barrier对象时都重新创建。
对象池的大小是之前定义的initCount。*/
    //用于管理池中所有对象的容器
     private static List<Barrier> pool = new ArrayList<>();
    //池中初始化对象的个数
    public static final int initCount = 16;
    //对象池中最大个数
    public static final int maxCount = 20;

    /*初始化对象池的过程在static块中进行,
    这个块是在类加载时运行的,并且只会执行一次。
    在这个示例中,
    static块创建了initCount个Barrier对象,
    并将它们添加到对象池中。
    这样,在需要Barrier对象的时候,
    程序可以从对象池中获取可用的对象,
    而不是重新创建一个新的对象。
     */
    //初始化池中的对象
    static{
        for (int i = 0; i < initCount; i++) {
            pool.add(new Barrier());
        }
    }

    //从池中获取一个对像
    public static Barrier getPool(){
        //获得池中对象的个数
        int size = pool.size();
        //如果池中有对象才可以拿对象
        if (size > 0){
            //移除并返回对象
            System.out.println("拿走一个");
            return pool.remove(size - 1);
        }else{
            //池中没有对象,只能new
            System.out.println("新的对象");
            //新定义一个对象,返回给方法
            return new Barrier();
        }
    }
    //把对象归还容器
    public static  void setPool(Barrier barrier){
        //如果池中障碍物的数量小于最大数量
        if (pool.size() < maxCount){
            //向池中添加障碍物
            pool.add(barrier);
            System.out.println("容器归还了");
        }
    }
}

GameFrontGround类:背景类

定义云彩的个数,存放云彩的集合,云彩的飞行速度;

得到资源图片,制造随机数的函数;

构造器初始化数据;

绘制云彩的方法;

控制云彩个数的方法;

package main;

import util.GameUtil;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

//背景类
public class GameFrontGround {
    //云彩的个数
    private static final int CLOUND_COUNT = 2;
    //存放云彩的容器
    /*这行代码是定义了一个名为clouds的List对象,
    其中存储了一组Cloud对象。
    这个List是Java中的一种集合,
    使用它可以把若干个元素放在一起,
    进行批量操作,比如添加元素、遍历元素、
    删除元素等等。
    具体的使用方式可能需要根据具体的场景和业务需求来进行调整。
    */
    private List<Cloud> clouds;
    //云彩飞行的速度
    private static final int CLOUND_SPEED = 1;
    /*这行代码定义了一个类型
    为  BufferedImage  数组的变量  img。

BufferedImage  是  Java  中表示图像的类,
它是一个实现了  RenderedImage  接口的缓存图像类,
可以用于操作和修改图像数据。
数组表示可以存储多张图片数据的数组,
每个元素代表一张图片,可以对每张图片单独进行操作。
因此,private  BufferedImage[]  img;
 定义了一个变量  img,
 它可以存储多张  BufferedImage  图像,
 可以对每张图片进行单独处理。*/
    //使用到的图片资源
    private BufferedImage[] img;

    //制造随机数的函数
    private Random random;

    //构造器初始化数据
    public GameFrontGround(){

        /*这行代码声明了一个名
    为  "clouds"  的  ArrayList(动态数组)对象,
    并对其进行初始化。在这个例子中,
    "<>"  符号表示  ArrayList  存储的是未知类型的元素,
这样声明和初始化  ArrayList  对象后,
就可以在其中存储和操作元素。通常,
开发人员使用  add()  方法将元素添加到  ArrayList中,
使用  get()  方法访问  ArrayList  中的特定元素,
使用  size()  方法获取  ArrayList  的大小等。*/
        //实例化存放云彩的容器
        clouds = new ArrayList<>();
        //定义数组中储存元素的最大数量
        img = new BufferedImage[CLOUND_COUNT];
        //容器中添加云彩图片
        for (int i = 0; i < CLOUND_COUNT; i++) {
            //调用GameUtil方法中的loadBufferedImage方法来获取图片添加到
            //img数组中
            img[i] = GameUtil.loadBufferedImage("newBird\\img\\cloud"+i+".png");//括号内填写图片的路径
        }
        //创建一个随机数的对象
        random = new Random();
    }

    //绘制云彩
    public void draw(Graphics g){
//        //传入图片(创建对象)
        //没有使用循环
//        Cloud cloud = new Cloud(img[1], CLOUND_SPEED, 300, 300);
//        //把云彩添加到容器中
//        //clouds是一个集合
//        clouds.add(cloud);
        //调用方法控制云彩的个数
        logic();
        for (int i = 0; i < clouds.size(); i++) {
            //画出云彩
            clouds.get(i).draw(g);
        }
    }
    //控制云彩个数的方法
    private void logic(){
        //产生一个0~500的随机数
        //Math.random()方法产生一个0~1的随机数
        //如果生成的随机数小于8
        if((int)(500*Math.random())< 8){
            ///生成一个新的云的图像,使用了随机的图片速度,位移参数
            Cloud cloud = new Cloud(img[random.nextInt(CLOUND_COUNT)], CLOUND_SPEED, 600, random.nextInt(180));
            //将新生成的云添加到云列表中
            clouds.add(cloud);
        }
        //去除云彩
        for (int i = 0; i < clouds.size(); i++) {
            //得到云
            Cloud cloud = clouds.get(i);
            //如果当前的云对象已经移出了场景
            if(cloud.isOutFrame()){
                //将当前云对象从云列表删除
                clouds.remove(i);
                //将当前遍历到的云对象的下标减一,以便下一次循环能够正确遍历到所有的云对象
                i--;
                System.out.println("云被移除了"+cloud);
            }
        }
    }
}

GameTime类:时间类

定义变量开始时间,游戏结束时的时间,时间差;

计算时间差的方法

计时开始的方法;

package main;

public class GameTime {
    //开始
    private long beginTime;
    //结束
    private long endTime;
    //时间差
    private long differ;

    public GameTime(){}
    //计时开始方法,System调用方法,计算从起始时间开始到现在的时间
    public void begin(){
        beginTime = System.currentTimeMillis();
    }

    //时间差方法
    public long differ(){
        //获得从起始时间开始到游戏结束时的时间
        endTime = System.currentTimeMillis();
//        得到时间差,除以1000是以秒为单位
        return differ = (endTime - beginTime)/1000;
    }
}

Music类:音乐类

声明背景音乐文件

静态代码块加载背景音乐文件

循环播放音乐的方法

停止播放音乐的方法

package main;

import javax.sound.sampled.*;
import java.io.File;

public class Music {
    //声明了名为music的private static Clip变量,表示音乐文件
    private static Clip music;
    //加载背景音乐文件,并将其储存在music变量中
    static{
        File bgMusicFile = new File("newBird\\\\img\\\\bgm2.wav");
        try{
            AudioInputStream ais = AudioSystem.getAudioInputStream(bgMusicFile);
            music = AudioSystem.getClip();
            music.open(ais);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public static void playMusic(){
        //循环播放
        music.loop(Clip.LOOP_CONTINUOUSLY);
    }
    //停止播放音乐
    public static void stopMusic(){
        music.stop();
    }
}

util包:

Constant类:初始化游戏中需要用到的一些参数

定义窗口大小的变量;

定义窗口标题,窗口初始化位置;

定义背景颜色;

定义数组存放小鸟图片的路径;

定义数组存放障碍物图片资源的路径;

package util;

import java.awt.*;

//初始化需要用到的参数
public class Constant {
    //窗口的大小
    //定义静态的组最终变量作为宽高
    public static final int FRAM_WIDTH = 600;
    public static final int FRAM_HEIGHT = 500;
    //窗口的标题
    //静态的最终变量作为窗口的标题
    public static final String FRAM_TITLE = "飞翔的小鸟";

    //窗口初始化的位置
    //静态最终变量
    public static final int FRAM_X = 200;
    public static final int FRAM_Y = 200;

    //图片的路径
    public static final String BK_IMG_OATH = "newBird\\img\\bird_bk.png";

    //定义背景的颜色
    public static final Color BK_COLOR = new Color(0X4B4CF);

    //存放三张小鸟图片的路径
    public static final String[] BIRD_IMG = {
            "newBird\\img\\bird_normal.png",
            "newBIrd\\img\\bird_up.png",
            "newBird\\img\\bird_down.png"
    };
    //定义障碍物图片资源(路径)
    public static final String[] BARRIER_IMG_PATH = {
            "newBird\\img\\barrier.png",
            "newBird\\img\\barrier_up.png",
            "newBird\\img\\barrier_down.png"
    };
}

GameUtil:定义加载图片的工具

装载图片文章来源地址https://www.toymoban.com/news/detail-496122.html

package util;


import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.IOException;

//加载图片工具类
public class GameUtil {
    //装载图片
    public static BufferedImage loadBufferedImage(String imgPath){
        try{
            /*这里是创建一个输入流,
            用来读取指定路径下的文件,
            imgPath是文件路径。在该方法中,
            我们使用FileInputStream将图片文件读入内存中,
            返回BufferedImage对象。
             */
            return ImageIO.read(new FileInputStream(imgPath));
        }catch(IOException e){
            e.printStackTrace();
        }
        return null;
    }
}

到了这里,关于java小游戏——飞翔的小鸟(java初学作品)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python版经典小游戏愤怒的小鸟源代码,基于pygame+pymunk

    Python版经典小游戏愤怒的小鸟源代码,基于pygame+pymunk 程序依赖:pygame 2.0.1, pymunk 5.5.0 直接运行main.py 完整代码下载地址:Python版经典小游戏愤怒的小鸟源代码 tool.py 完整代码下载地址:Python版经典小游戏愤怒的小鸟源代码

    2024年02月16日
    浏览(55)
  • Python期末作品:连连看小游戏

    设计一个连连看小游戏: 功能:实现图案之间的消除、背景音乐的播放、停止。 目的:掌握字符串、列表、列表推导式、选择结构、正则表达式、函数的定义与调用、面向对象的程序设计、文件操作、GUI编程、多媒体编程等知识。 软件方面:pycharm、PS、亿图图示 库模块:

    2024年02月09日
    浏览(44)
  • UE4初学者设计小游戏(一)

    目录 一、设计简介及故事概要 二、环境设计与场景搭建 1. 将天空球改成黑夜 1 2. 通过画刷(BSP)搭建逃脱石头屋 2 3. 添加地形 5 4. 添加氛围元素 5 5. 感应灯 7 三、游戏机关蓝图设计 1.手电筒设计 8 2.设计开关门 9 6. 天梯设计 12 7. 加血装置 13 四、UI设计 2. 开始界面 14 3. 暂停

    2024年02月06日
    浏览(45)
  • Java小游戏

    一、需求                二、思路一          HP当然是怪物的一个属性成员,而武器是角色的一个属性成员,类型可以使字符串,用于描述目前角色所装备的武器。角色类有一个攻击方法,以被攻击怪物为参数,当实施一次攻击时,攻击方法被调用,而这个方法首先判

    2024年02月11日
    浏览(30)
  • Java小游戏—贪吃蛇

    摘 要 近年来,java作为一种新的编程语言,以其简单性、可移植性和平台无关性等优点,得到了各个国家广泛地认可。本文基于java技术和Eclipse开发环境,设计并实现了一个操作简单、界面美观的“贪吃蛇”游戏。“贪吃蛇”游戏是一个经典的游戏,它因操作简单、娱乐性强

    2024年02月03日
    浏览(47)
  • Java小游戏 王者荣耀

    GameFrame类 所需图片:   TurretBlue类   TurretRed类 Champion类 所需图片: 单个: move包:     ChampionDaji类  所需图片:   MinionBlue类  MinionRed类  Bullet类 Background类 所需图片   以下代码所需图片(Bear类、Bird类、BlueBuff类、RedBuff类、Wolf类、Xiyi类):  Bird类 BlueBuff类 RedBuff类 Wolf类

    2024年02月04日
    浏览(42)
  • Java实现王者荣耀小游戏

    主要功能 键盘W,A,S,D键:控制玩家上下左右移动。按钮一:控制英雄发射一个矩形攻击红方小兵。按钮控制英雄发射魅惑技能,伤害小兵并让小兵停止移动。技能三:攻击多个敌人并让小兵停止移动。普攻:对小兵造成基础伤害。小兵每隔一段时间自动生成,在王者峡谷下路

    2024年02月04日
    浏览(45)
  • Java制作“简易王者荣耀”小游戏

    第一步是创建项目 项目名自拟 第二部创建个包名 来规范class 然后是创建类 GameFrame   运行类 运行结果如下:

    2024年02月04日
    浏览(53)
  • Java小游戏-俄罗斯方块

    摘 要 随着时代的不断发展,个人电脑也在不断普及,一些有趣的桌面游戏已经成为人们在使用计算机进行工作或工作之余休闲娱乐的首选,从最开始的Windows系统自带的黑白棋、纸牌、扫雷等游戏开始,到现在目不暇接的各种游戏,游戏已经成为人们在使用计算机进行工作或

    2024年02月03日
    浏览(54)
  • 万年历【小游戏】(Java课设)

    Java实现的小游戏 适合作为Java课设!!! jdk1.8+Idea或eclipse 本系统源码地址:https://download.csdn.net/download/qq_50954361/87801830 更多Java课设系统源码地址:更多Java课设系统源码地址 更多Java小游戏运行效果展示:更多Java小游戏运行效果展示 Java课设部署教程:Java课设部署教程 注意事

    2024年02月15日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包