JavaSE实战项目:飞翔的小鸟(完整版)

10月11日 收藏 0 评论 0 java开发

JavaSE实战项目:飞翔的小鸟(完整版)

转载声明:文章来源https://blog.csdn.net/zjdzka/article/details/110917088

1.前言

首先,我先说一下这个项目,这个项目题材的来自牛客网的开源项目
我在这里做一个我自己在开发此项目的心得体会和经验交流,并且带领大家了解从0去入手一个项目的完整思路
这里是结果展示图:


2.分析

①素材准备
在开发此项目之前,我们需要去先下载一些关于飞翔的小鸟素材图片
小鸟的飞翔图片
地面背景图片
柱子图片
以及开始结束图片

那么这里我为大家提供百度网盘链接,大家需要可自行下载
链接:https://pan.baidu.com/s/12ww0HQ6KluVP-fcC40iXXQ
提取码:zjd8
复制这段内容后打开百度网盘手机App,操作更方便哦

②代码构思
本项目主要针对JAVASE刚学完想巩固练习,却没有项目着手的同学,用的都是一些基础性的知识
运用到的知识点:
1.面向对象:封装继承多态
2.数组
3.常用类Math
4.swing组件:图形界面工具
5.鼠标监听
6.IO流
7.多线程

逻辑步骤分析:
1.先实现窗口的制作,并且将背景图放入窗口面板
2.设计地面类,实现游戏背景地面移动
3.设计柱子类,实现游戏背景柱子移动
4.设计小鸟类,在类中添加小鸟相关方法
   初始化小鸟相关参数, 判断小鸟是否碰撞柱子与地面
5.把小鸟放在面板中
6.鼠标监听控制小鸟飞行的轨迹
7.添加计分和游戏结束游戏开始的画面

代码分类:
由上述的分析,我们可以大致分析计划创建4个类
1.小鸟类:设置小鸟参数,添加小鸟判断方法
2.柱子类:设置柱子参数,添加柱子移动方法
3.地面类:设置地面参数,添加地面移动方法
4.测试类:添加开始结束、鼠标监听等方法

3.代码实现及展示

代码中数学参数来自牛客网测试
①小鸟类:

package FlyBirdGame;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;

class Bird {
//图片
BufferedImage image;
//位置
int x,y;
//宽,高
int width,height;
//大小
int size;

//重力加速度
double g;
//位移的间隔时间
double t;
//最初上抛速度
double v0;
//当前上抛速度
double speed;
//经过时间t后的位移
double s;
//小鸟的倾角
double alpha;

//一组图片,记录小鸟的动画帧
BufferedImage[] images;
//动画帧数组的下标
int index;

//初始化小鸟
public Bird() throws Exception{
//初始化基本参数
image = ImageIO.read(new File("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(new File(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;
}
}

②地面类:

package FlyBirdGame;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;

public class Ground {
//图片
BufferedImage image;
//位置
int x,y;
//宽高
int width,height;

//初始化地面
public Ground() throws Exception {
image = ImageIO.read(new File("ground.png"));
width = image.getWidth();
height = image.getHeight();
x=0;
y=500;
}

//向左移动一步
public void step(){
x--;
if(x==-109){
x = 0;
}
}
}

③柱子类:

package FlyBirdGame;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Random;

public class Column {
//图片
BufferedImage image;
//位置
int x,y;
//宽高
int width,height;
//柱子间缝隙
int gap;
//柱子间距离
int distance;
//随机数工具
Random random = new Random();

/**
* 初始化第n个柱子
*/
public Column(int n) throws Exception{
image = ImageIO.read(new File("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;
}
}
}

④测试类:

package FlyBirdGame;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;

public class BirdGame extends JPanel {
//背景图片
BufferedImage background;
//开始图片
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;//结束

/**
* 初始化游戏
*/
public BirdGame() throws Exception{
//初始化
background = ImageIO.read(new File("bg.png"));
startImage = ImageIO.read(new File("start.png"));
gameOverImage = ImageIO.read(new File("gameover.png"));

//初始化地面,柱子,小鸟
ground = new Ground();
column1 = new Column(1);
column2 = new Column(2);
bird = new Bird();

//初始化分数
score = 0;
//初始化状态
state = START;
}
/**
* 绘制界面
*/
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);
g2.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;
}
}
// 开始游戏
public void action() throws Exception {
// 鼠标监听器
MouseListener l = new MouseAdapter() {
// 鼠标按下事件
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();
}
}
};
// 将监听器添加到当前的面板上
addMouseListener(l);
// 不断的移动与重绘
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();
// 休眠 1000/60 毫秒
Thread.sleep(1000 / 60);
}
}
/**
* 启动方法
*/
public static void main(String[] args) throws Exception {
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();
}

}

4.心得分享

对于一些刚入门java的小伙伴来说,可能里面用到的一些方法,不是很熟悉
这里建议大家可以通过API查询
可以学习了解一下swing、鼠标监听以及ImageIO等代码中涉及到的知识
帮助大家顺利完成本次的小项目!!!

C 0条回复 评论
大白牙和爆米花

刚接触Spring框架,一个Method method直接把我看晕了

发表于 2022-08-29 23:00:00
0 0
pyyyyy

UI设计发展前景怎么样

发表于 2021-12-12 23:00:00
0 0