一、写在前面:

《飞扬的小鸟》是一款曾经比较火热的小游戏,本文可以带你你从零开始,一步一步的开发出这款小游戏。

  • 语言
    Java

  • 工具
    IntelliJ IDEA,JDK 16

  • 准备工作

创建好项目后,在正式开始编写代码前,先下载游戏素材放入正确的目录下。开发过程中使用的一些参数,如坐标、尺寸、速度等,你可以直接使用这些参数值,也可以尝试自定义这些参数值。

二、知识要点

  1. Java的基本语法
  2. Java面向对象的三大特征(封装、继承、多态)
  3. Java Swing中常见API的使用 (Swing 包括了图形用户界面器件如:文本框,按钮,分隔窗格和表。)
  4. 鼠标监听
  5. IO流
  6. 线程

三、开发步骤简介

  1. 创建项目flappyBird,然后在src目录下创建两个包,分别为game和resources
  2. 将素材文件全部放入resources文件中
  3. 在测试类文件中,制作窗口面板,并将背景图片放入面板中
  4. 设计游戏道具之「地面」,新建地面类,实现游戏背景中地面的移动
  5. 设计游戏道具之「柱子」,新建柱子类,实现游戏背景中柱子的移动
  6. 设计游戏道具之「小鸟」,新建小鸟类,在类中加入小鸟的各种参数,以及飞行、移动、是否撞柱子和地面等相关的方法
  7. 将小鸟也放入面板中,用数组模拟多帧
  8. 鼠标监听控制小鸟的飞行行为
  9. 添加计分和游戏结束游戏开始的画面

由上述的分析,我们计划创建4个类:

  1. 小鸟类:设置小鸟参数,添加小鸟判断方法
  2. 柱子类:设置柱子参数,添加柱子移动方法
  3. 地面类:设置地面参数,添加地面移动方法
  4. 测试类:绘制游戏界面、添加开始结束、鼠标监听等方法

四、项目代码

注: 代码相关的解释都在代码注释中

1、绘制面板,并将背景图片放置面板中

在game包下面创建测试类BirdGame,并写入以下代码。
注:抛出的异常IDEA都可以直接点击加入,而不用自己写。

package game;import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;// 游戏界面
public class BirdGame extends JPanel {// 背景图片BufferedImage background;// 初始化游戏public BirdGame() throws Exception {// 初始化背景图片background = ImageIO.read(getClass().getResource("/resources/bg.png"));}// 绘制界面public void paint(Graphics g) {// 绘制背景g.drawImage(background, 0, 0, null);}// 启动方法public static void main(String[] args) throws Exception {JFrame frame = new JFrame();  // 创建窗口,JFrame是屏幕上window的对象,能放大、缩小、关闭。BirdGame game = new BirdGame();frame.add(game);frame.setSize(440, 670);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  // 设置窗口frame.setVisible(true);  // 显示窗口}
}

可以运行mian方法,来查看下效果。

2、设计游戏道具之地面

在game包下面定义地面类,并写入以下代码:

package game;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;class Ground {BufferedImage image;  // 图片int x, y;  // 位置int width, height;  // 宽和高// 初始化地面public Ground() throws IOException {image = ImageIO.read(getClass().getResource("/resources/ground.png"));width = image.getWidth();height = image.getHeight();x = 0;y = 500;}// 地面向左移动public void step(){x--;if(x == -109){x = 0;}}
}

3、设计游戏道具之柱子

在game包下面定义柱子类,并写入以下代码:

package game;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;class Column {BufferedImage image;  // 图片int x, y;  // 位置int width, height;  // 宽高int gap;  // 柱子之间的缝隙int distance;  // 柱子之间的距离Random random = new Random();  // 随机数工具// 初始化第N个柱子public Column(int n) throws IOException {image = ImageIO.read(getClass().getResource("/resources/column.png"));width = image.getWidth();height = image.getHeight();gap = 144;distance = 245;x = 550 + (n-1) * distance;y = random.nextInt(218) + 132;}// 柱子向左移动一步public void step(){x--;if (x == -width/2){x = distance * 2 - width / 2;y = random.nextInt(218) + 132;}}
}

4、设计游戏道具之小鸟

在game包下面定义小鸟类,并写入以下代码:

package game;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;class Bird {BufferedImage image;  // 图片int x, y;  // 位置int width, height;   // 宽高int size;  // 大小(用于碰撞检测)double g;  // 重力加速度double t;  // 位移的间隔时间double v0;  // 最初上抛速度double speed;  // 当前上抛速度double s;  // 经过t时间之后的位移double alpha;  // 小鸟的倾角(弧度)BufferedImage[] images;  // 一组图片,记录小鸟的动画帧int index;  // 动画帧数组的下标// 初始化小鸟public Bird() throws IOException {image = ImageIO.read(getClass().getResource("/resources/0.png"));width = image.getWidth();height = image.getHeight();x = 132;y = 280;size = 40;// 初始化位移参数g = 4;v0 = 20;t = 0.25;speed = v0;s = 0;alpha = 0;// 初始化动画帧参数images = new BufferedImage[8];for(int i=0; i<8; i++){images[i] = ImageIO.read(getClass().getResource("/resources/"+ i +".png"));}index = 0;}// 飞行动作 (变化一帧)public void fly(){index ++;image = images[(index / 12) % 8];}// 移动一步public void step(){double v0 = speed;s = v0 * t + g * t * t /2;  // 计算上抛运动位移y = y - (int)s;  // 计算鸟的坐标位置double v = v0 -g * t;  // 计算下次移动速度speed = v;alpha = Math.atan(s / 8);  //计算倾角(反正切函数)}// 向上飞行public void flappy(){speed = v0;   // 重置速度}// 检测小鸟是否碰撞到地面public boolean hit(Ground ground){boolean hit = y + size / 2 > ground.y;if(hit){y = ground.y - size / 2;alpha = -3.14159265358979323 / 2;}return hit;}// 检测小鸟是否撞到柱子public boolean hit(Column column){// 先检查是否在柱子的范围内if (x > column.x - column.width / 2 - size / 2&& x < column.x + column.width / 2 + size / 2){// 再检查是否在柱子的缝隙中if (y > column.y - column.gap / 2 + size / 2&& y < column.y + column.gap /2 - size / 2){return false;}return true;}return false;}
}

5、绘制游戏界面,加入初始化参数、方法、鼠标监听等

5.1 定义游戏参数

在BirdGame文件下增加成员变量,写入以下代码:

// 开始与结束的图片BufferedImage startImage;BufferedImage gameoverImage;Ground ground;  // 地面Column column1, column2; // 柱子,由于同一画面中可能会出现两根柱子,因此我们定义两个柱子对象Bird bird;  // 小鸟int score;  // 游戏分数int state;   // 游戏状态// 状态常量public static final int START = 0;  // 开始public static final int RUNNING = 1;  // 运行public static final int GAME_OVER = 2;  // 结束
5.2 初始化游戏参数

在BirdGame的构造方法里面,初始化上述成员变量,写入以下代码:

public BirdGame() throws IOException {// 初始化背景、开始和结束的图片background = ImageIO.read(getClass().getResource("/resources/bg.png"));startImage = ImageIO.read(getClass().getResource("/resources/start.png"));gameoverImage = ImageIO.read(getClass().getResource("/resources/gameover.png"));// 初始化地面、柱子、小鸟ground = new Ground();column1 = new Column(1);column2 = new Column(2);bird = new Bird();score = 0;   // 初始化分数state = START;  // 初始化状态}

在这里初始化两个柱子是因为一个游戏界面上会出现两个柱子,每当通过一根柱子,分数就加1。

5.3 绘制游戏界面

在paint方法里面,绘制地面、柱子、小鸟、分数、开始图片、结束图片,写入以下代码:

// 绘制界面public void paint(Graphics g){g.drawImage(background, 0, 0, null);  // 绘制背景// 注:画柱子的代码要写在画地面的代码之后,否则地面图片将无法将多余的柱子图片覆盖。g.drawImage(ground.image, ground.x, ground.y, null);   // 绘制地面// 绘制柱子g.drawImage(column1.image, column1.x - column1.width / 2, column1.y - column1.height / 2, null);g.drawImage(column2.image, column2.x - column2.width / 2, column2.y - column2.height / 2, null);// 绘制小鸟 (旋转坐标系)Graphics2D g2 = (Graphics2D) g;g2.rotate(-bird.alpha, bird.x, bird.y);g.drawImage(bird.image, bird.x - bird.width /2, bird.y - bird.height/2,null);g2.rotate(bird.alpha,bird.x,bird.y);// 绘制分数Font f = new Font(Font.SANS_SERIF, Font.BOLD, 40);g.setFont(f);g.drawString("" + score, 40, 60);g.setColor(Color.WHITE);g.drawString(""+score, 40-3, 60-3);// 绘制开始与结束界面switch (state){case START:g.drawImage(startImage, 0, 0, null);break;case GAME_OVER:g.drawImage(gameoverImage, 0, 0, null);break;}}

这个时候运行main方法,就可以看到开始界面的情形了,修改状态state为RUNNING和GAME_OVER还可以看到运行时和结束时的情形。

6、加入游戏动作

6.1 定义开始方法

在BirdGame类中增加开始游戏的方法,并在此方法内编排游戏的动作,写入以下代码:

 public void action() throws InterruptedException {while (true){switch (state) {case START:bird.fly();  // 小鸟做出飞行动作ground.step();  // 地面向左移动一步break;case RUNNING:ground.step();   // 地面向左移动一步column1.step();  // 柱子向左移动一步column2.step();bird.fly();   // 小鸟飞行bird.step();  // 小鸟上下移动一步if (bird.x == column1.x || bird.x == column2.x) {score++;  // 计算分数}// 检查是否发生碰撞if (bird.hit(ground) || bird.hit(column1) || bird.hit(column2)) {state = GAME_OVER;}break;}repaint();   // 重新绘制界面Thread.sleep(1000/60);   // 休眠1000/60毫秒}}
6.2 调用开始方法

在main方法中调用上述方法,写入以下代码:

// 启动方法public static void main(String[] args) throws IOException, InterruptedException {JFrame frame = new JFrame();BirdGame game = new BirdGame();frame.add(game);frame.setSize(440,670);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);game.action();}

这时运行main方法,切换状态就能看见运动的地面和小鸟了。

7、定义操控逻辑

7.1 增加监听事件
在action方法中,增加鼠标单击事件的监听器,写入以下代码(注:增加在while循环的前面):

// 鼠标监听器MouseListener l = new MouseListener(){@Overridepublic void mouseClicked(MouseEvent e) {}// 鼠标按下事件public void mousePressed(MouseEvent e){try{switch (state){case START:// 在开始状态,按下鼠标则为运行状态state = RUNNING;break;case RUNNING:// 在运行状态,按下鼠标则小鸟向上飞行bird.flappy();break;case GAME_OVER:// 在结束状态,按下鼠标则重置数据,再次转为开始状态column1 = new Column(1);column2 = new Column(2);bird = new Bird();score = 0;state = START;break;}}catch(Exception ex){ex.printStackTrace();}}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) {}@Overridepublic void mouseExited(MouseEvent e) {}};// 将监听器添加到当前的面板上addMouseListener(l);

这时运行main方法,就可以开始玩游戏啦,用鼠标来控制小鸟的运动。

以上就是本次的全部代码啦~代码完整且可以运行,有问题可以评论区留言~记得点个赞哦

飞翔的小鸟--Java小游戏实战(代码完整)相关推荐

  1. JAVA小游戏有源代码,非常详细的注释,以及自己做的答辩PPT

    JAVA小游戏--阴阳师版三国战纪 阴阳战纪 具体的实现方法 程序 效果 阴阳战纪 由于疫情原因,我们班的生产实习被告知要在线上举行,然后老师给我们上了三天的网课,教我们用JAVA来制作一个小游戏,因 ...

  2. C语言小游戏实战代码

    07.绘制卡通头像 #include <easyx.h> #include <stdio.h>#define PI 3.14int main() {initgraph(1024 ...

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

    注:学习了java基础后,做出来的一个小作品,可以用来巩固学习 概述: 飞翔的小鸟能够作为Java基础的收官之作,包涵了Java很多的基础知识,在学习完Java基础后,尝试编写一些东西,能够起到很好的 ...

  4. java小游戏------Flappy Bird(飞翔的小鸟含源码)

    前言:本小游戏可作为java入门阶段收尾创作. 需:掌握面向对象的使用,了解多线程和异常处理等知识. 如上图所示:我们需要绘制背景,小鸟,障碍物,当然也包括游戏开始界面以及死亡界面. 一:思路解析: ...

  5. java小游戏-飞翔的小鸟

    java小游戏-ava小游戏-飞翔的小鸟 1 游戏窗口的显示 2 游戏背景添加 3 背景颜色的添加 4 屏幕中绘制小鸟 5 实现小鸟上下移动 6 解决屏幕闪烁问题 7 云彩的添加与移动 8 云彩的自动 ...

  6. 10款Java小游戏(详解+源码)

    开源Java小游戏 前言 下面就给大家介绍十几个开源的Java小游戏,供大家学习交流.资源都下载好共享到我的交流群了,需要的在群内自取853665602不收取任何资源费,毕竟开源才是我们的宗旨. [群 ...

  7. 各种经典java小游戏_Java是这个世界上最好的语言!

    为什么? 请看TIOBE最新发布的编程语言排行榜: TIOBE开发语言排行榜每月更新一次,其结果可以用来检阅开发者的编程技能能否跟上趋势,或是否有必要作出战略改变,以及什么编程语言是应该及时掌握的. ...

  8. 《Java小游戏实现》:坦克大战

    <Java小游戏实现>:坦克大战 前面写了一个简单的聊天小程序,今天开始就写一个坦克大战的游戏,算是对Java相关小知识点的一个应用. 这个游戏的完成,我们也是分步完成,逐步累加,一个一个 ...

  9. java小游戏之捕鱼达人,学了java,妈妈不再担心我去网吧游戏厅了!

    Java小项目捕鱼达人 跪求关注,祝关注我的人都:身体健康,财源广进,福如东海,寿比南山,早上贵子,从不掉发! 捕鱼达人这款游戏,相信和我年纪相仿的朋友,肯定很熟悉.在当时半智能手机和智能手机刚刚出现 ...

最新文章

  1. openSuse 13.1 的触摸板,回来了
  2. Lua 学习笔记(一)环境搭建
  3. 在ssh项目中的中配置数据源c3p0
  4. 小demo, java swing窗口编程(JDK 1.6) (二)
  5. php 使用PDO,防止sql注入 简单说明
  6. JAVA四种遍历Map的方法
  7. ruby继承_Ruby继承
  8. UNIX环境高级编程——pthread_create的问题
  9. 蔚来发布首款自动驾驶车型ET7 补贴前起售价44.8万元
  10. mongodb mongod 参数解释
  11. 二十五、K8s系统强化1- 系统安全与apparmor
  12. 易方达、鹏华、京东数科基金投顾访谈
  13. zen3架构_zen3架构对比zen2架构
  14. 杭电ACM2046题
  15. 工作感想-软件测试工程师
  16. lol8月21号服务器维护,lol维护到几点今天?英雄联盟LOL8月21日维护更新内容
  17. shell习题第15题:看数字找规律
  18. 【开发一个简单的音乐播放器+服务端】【一】
  19. idea2018激活码
  20. 什么是 EventLoop ?

热门文章

  1. 订单号怎样生成才能好用又好看,难倒了20多位产品经理
  2. otn与stn网络_全光网络:OTN与超长距离传输
  3. 热力学统计物理专题:德拜模型
  4. 新冠“照妖镜”,体质弱点现原形。你是啥症状?2023年,请好好善待你的身体!
  5. 鸿蒙系统魅族,魅族宣布接入鸿蒙系统
  6. c++ stl(标准模板库)
  7. 四、资讯安全网词汇表
  8. 电脑内存条分几种,如何分辨呢?
  9. 利用招行香港一卡通和美国Scottrade开设港股和美股的攻略
  10. HTML+CSS:移动端分辨率、视口、Flex布局、文字溢出显示省略号、溢出两行显示省略号