文章目录
一、项目介绍
这个基于 Swing 框架的"飞翔的小鸟"课程设计项目是一个非常有趣且富有挑战性的 Java 编程练习,可以帮助学生学习图形用户界面编程和游戏开发的基础知识。
该项目的主要目标是开发一个简单的游戏,玩家需要控制一只小鸟在屏幕上飞翔,并躲避出现在路径上的障碍物。这个游戏基于著名的"Flappy Bird"游戏设计,具有以下主要功能和特点:
-
图形用户界面: 使用 Java Swing 库构建游戏界面,包括游戏画面、分数显示、开始/暂停按钮等。
-
角色控制: 玩家可以通过键盘输入或鼠标点击来控制小鸟的上下移动。小鸟的飞行轨迹受重力和玩家输入的影响而变化。
-
碰撞检测: 实现小鸟与障碍物之间的碰撞检测,当小鸟撞到障碍物时游戏结束。
-
分数计算: 记录玩家通过障碍物的次数,并实时显示在界面上。
在实现这个项目时,学生需要掌握以下知识和技能:
- Java 编程基础,包括面向对象编程、事件驱动编程等。
- Java Swing 库的使用,包括窗口、面板、按钮、标签等 GUI 组件的创建和布局。
- 游戏开发的基本原理,如游戏循环、碰撞检测、得分计算等。
通过这个项目的开发,学生不仅可以学习 Java 编程的基础知识,还可以培养问题分析、设计、实现和测试的能力,为未来的软件开发工作奠定基础。同时,这个有趣的游戏项目也可以增强学生的学习动力和创造力。
二、核心代码
小鸟实体类
public class Bird {
/**
* 小鸟初始图
*/
public BufferedImage bufferedImage;
/**
* 动画祯
*/
public BufferedImage[] images;
/**
* 祯下标
*/
public int index;
/**
* 宽高
*/
public int width,height;
/**
* 小鸟大小
*/
public int size;
/**
* 坐标
*/
public int x,y;
/**
* 上抛速度
*/
public double v0;
/**
* 间隔时间
*/
public double t;
/**
* 重力速度
*/
public double g;
/**
* 当前速度
*/
public double speed;
/**
* 经过t时间已走距离
*/
public double s;
/**
* 倾斜角
*/
public double alpha;
/**
* 初始化小鸟
*/
public Bird() {
try {
//初始化小鸟参数
bufferedImage= ImageIO.read(getClass().getResource("/resources/0.png"));
width=bufferedImage.getWidth();
height=bufferedImage.getHeight();
x=130;
y=280;
size=240;
//初始化位移参数
g=4;
v0=20;
speed=v0;
t=0.25;
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;
} catch (IOException e) {
System.out.println("初始化小鸟失败。");
}
}
/**
* 飞行动作,变化一帧
*/
public void fly() {
index++;
bufferedImage=images[(index/12)%8];
}
/**
* 移动一步
*/
public void step() {
//当前移动速度
double v0=speed;
//上抛运动位移
s = v0*t + g*t*t/2;
//上抛后当前坐标位置
y = y - (int)s;
//下次移动速度
speed = v0 - g*t;
//计算斜角
alpha=Math.atan(s/8);
}
/**
* 向上飞行
*/
public void upFly() {
//重置速度
speed = v0;
}
/**
* 检测是否碰到地面
* @param ground 地面
* @return
*/
public boolean isHitGround(Ground ground) {
boolean isHit = y + size/2 > ground.y;
if (isHit) {
System.out.println("已碰到地面。x="+x+" y="+y);
System.out.println("地面坐标 y="+ground.y+" 小鸟体积");
y = ground.y - size/2;
alpha = -3.14159265358979323/2;
}
return isHit;
}
/**
* 检测是否碰到柱子
* @param column
* @return
*/
public boolean isHitColumn(Column column) {
//判断是否在柱子范围内
if (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;
}
}
小鸟相关操作
public class Bird {
//image
BufferedImage image;
//position
int x,y;
//shape
int width,height;
//size
int size;
//speed of bird's drop
double g;
//time between step
double t;
//initial fly speed
double v0;
//current fly spedd
double speed;
//move distance after t times
double s;
//bird's angle
double alpha;
//bird's fly frame
BufferedImage[] images;
//bird's current fly frame
int index;
//bird init
public Bird() throws Exception
{
image=ImageIO.read(getClass().getResourceAsStream("/resource/0.png"));
width=image.getWidth();
height=image.getHeight();
x=132;
y=280;
size=40;
//shift data init
g=4;
v0=20;
t=0.25;
speed=v0;
s=0;
alpha=0;
//fly frame init
images=new BufferedImage[8];
for(int i=0;i<8;i++)
{
images[i]=ImageIO.read(getClass().getResourceAsStream("/resource/"+i+".png"));
}
index=0;
}
//fly move
public void fly()
{
index++;
image=images[(index/12)%8];
}
//move step
public void step()
{
double v0=speed;
//计算上抛运动位移
s=v0*t+g*t*t/2;
//计算鸟的坐标
y=y-(int)s;
//计算下次移动速度
speed= v0-g*t;
//计算角度
alpha=Math.atan(s/8);
}
//fly upward
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.1415926 / 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)
{
//检测是否在柱子的空隙中
return y <= column.y - column.gap / 2 + size / 2 || y >= column.y + column.gap - size / 2;
}
return false;
}
//慢速模式
public void slow()
{
g=g/2;
}
//正常模式
public void fast()
{
g=4;
}
}
游戏启动类
public class BirdGame extends JPanel{
//game background
BufferedImage background;
BufferedImage startImage,endImage;
Ground ground;
Column column1,column2;
Bird bird;
int score;
//慢速模式按钮
JButton slow;
//game state
int state;
public static final int START=0;
public static final int RUNNING=1;
public static final int END=2;
//class init
public BirdGame() throws Exception
{
setLayout(new BorderLayout());
//use fileInputStream instead the getClass()
background = ImageIO.read(getClass().getResourceAsStream("/resource/bg.png"));
startImage=ImageIO.read(getClass().getResourceAsStream("/resource/start.png"));
endImage=ImageIO.read(getClass().getResourceAsStream("/resource/gameover.png"));
//init class
ground=new Ground();
column1=new Column(1);
column2=new Column(2);
bird=new Bird();
score=0;
slow=new JButton();
slow.setBackground(Color.GRAY);
slow.setFont(new Font(Font.SANS_SERIF,Font.BOLD,30));
slow.setText("慢速模式");
slow.setForeground(Color.WHITE);
add(slow,BorderLayout.NORTH);
state=START;
}
//draw
public void paint(Graphics g)
{
//draw background
g.drawImage(background,0,0,null);
//draw ground
g.drawImage(ground.image,ground.x,ground.y,null);
//draw column
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);
//draw bird
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);
//draw score
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 END:
g.drawImage(endImage,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 END:
// 在结束状态,按下鼠标则重置数据,再次转为开始态。
column1 = new Column(1);
column2 = new Column(2);
bird = new Bird();
score = 0;
state = START;
break;
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
// 将***添加到当前的面板上
addMouseListener(l);
//添加按钮监听事件
slow.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(slow.getText().equals("慢速模式"))
{
bird.slow();
slow.setText("正常模式");
}
else
{
bird.fast();
slow.setText("慢速模式");
}
}
});
//移动与重绘
while(true)
{
switch (state)
{
case START:
slow.setEnabled(true);
//小鸟飞行
bird.fly();
//地面移动
ground.step();
break;
case RUNNING:
slow.setEnabled(false);
//ground move
ground.step();
//column move
column1.step();
column2.step();
//bird fly
bird.fly();
//bird move
bird.step();
if(bird.x==column1.x||bird.x== column2.x)
{
score++;
}
//检测是否碰撞
if(bird.hit(ground)||bird.hit(column1)||bird.hit(column2))
{
state=END;
}
break;
}
repaint();
Thread.sleep(1000/60);
}
}
public static void main(String[] args) throws Exception
{
JFrame jf=new JFrame("飞翔的小鸟");
BirdGame birdGame=new BirdGame();
jf.add(birdGame);
jf.setSize(440,670);
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setResizable(false);
jf.setVisible(true);
birdGame.action();
}
}
三、项目展示
游戏启动主界面
玩游戏
游戏失败,得分为2分
四、源码获取
因为页面与源码太多了,所以页面与源码只展示了一部分,完整源码已经打包了,点击下面蓝色链接获取!
标签:课程设计,Java,int,bird,小鸟,小游戏,new,public,ground From: https://blog.csdn.net/2401_84040513/article/details/139869340