java游戏制作-飞翔的鸟游戏

一.准备工作

首先创建一个新的Java项目命名为“飞翔的鸟”,并在src中创建一个包命名为“com.qiku.bird",在这个包内分别创建4个类命名为“Bird”、“BirdGame”、“Column”、“Ground”,并向需要的图片素材导入到包内。

二.代码呈现

package com.qiku.bird;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;/** 小鸟类* */
public class Bird {int x;// 坐标int y;int width; // 宽高int height;BufferedImage image; // 图片BufferedImage[] images; // 小鸟所有图片public Bird() {// 初始化数组 保存八张图片images = new BufferedImage[8];// 使用循环结构 将小鸟所有图片 存入数组for (int i = 0; i < images.length; i++) {try {images[i] = ImageIO.read(Bird.class.getResourceAsStream(i + ".png"));} catch (IOException e) {e.printStackTrace();}}image = BirdGame.bird_image;width = image.getWidth();height = image.getHeight();x = 120;y = 240;}// 小鸟飞翔的方法int index = 0;public void fly() {image = images[index % images.length];index++;}// h = v * t + g * t * t / 2int g = 6; //重力加速度double t = 0.15; // 下落时间double v = 0; // 初速度double h = 0; // 下落距离//小鸟下落一次public void down() {h = v * t + g * t * t / 2; // 具体下落的距离v = v + g * t; // 末速度 = 当前速度 + 重力加速度 * 时间y += (int) h;}// 小鸟向上飞public void up() {// 给一个 负方向的初速度v = -30;}/** 小鸟撞地面* */public boolean hitGround(Ground ground) {boolean isHit = this.y + this.height >= ground.y;return isHit;}// 小鸟撞天花板public boolean hitCeiling() {boolean isHit = this.y <= 0;return isHit;}// 小鸟撞柱子public boolean hitColumn(Column c) {boolean b1 = this.x + this.width >= c.x;boolean b2 = this.x <= c.x + c.width;boolean b3 = this.y <= c.y + c.height / 2 - c.gap / 2;boolean b4 = this.y + this.height >= c.y + c.height / 2 + c.gap / 2;// 满足b1 b2表示水平方向 相撞 b1 b2 b3 同时满足 撞上柱子 b1 b2 b4 同时满足撞下柱子return b1 && b2 && (b3 || b4);}}

package com.qiku.bird;
import javax.imageio.ImageIO;
import javax.swing.*;import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;/*** 游戏启动类* 使用extends 关键字 继承JPanel 画板类 ==> 于是BirdGame 就具备了画板类的功能*/
public class BirdGame extends JPanel {//    定义游戏状态public static final int START = 0;  // 开始public static final int RUNNING = 1;  // 运行public static final int GAME_OVER = 2;  // 结束// 游戏当前状态 默认0 开始状态int state = START;int score = 0; //玩家得分static BufferedImage bg = null; // 背景图片static BufferedImage start = null; //开始图片static BufferedImage ground_image = null; // 地面static BufferedImage bird_image = null; // 小鸟static BufferedImage column_image = null; // 柱子static BufferedImage gameOver_image = null; // game游戏// 静态代码块 一般用于加载静态资源(视频,音频,图片等)static {// 将本地的图片bg.png读取到程序中的bgtry {bg = ImageIO.read(BirdGame.class.getResourceAsStream("bg.png"));start = ImageIO.read(BirdGame.class.getResourceAsStream("start.png"));ground_image = ImageIO.read(BirdGame.class.getResourceAsStream("ground.png"));column_image = ImageIO.read(BirdGame.class.getResourceAsStream("column.png"));bird_image = ImageIO.read(BirdGame.class.getResourceAsStream("0.png"));gameOver_image = ImageIO.read(BirdGame.class.getResourceAsStream("gameover.png"));} catch (IOException e) {e.printStackTrace();}}Ground ground;//声明地面Bird bird;Column column1;Column column2;// BirdGame 的构造方法public BirdGame() {bird = new Bird();ground = new Ground();column1 = new Column();column2 = new Column();// 柱子2的x坐标 = 柱子1的坐标基础上+244保持水平间距column2.x = column1.x + column1.distance;}/** 用于在画板上绘制内容的方法* 想在画板上显示什么 在这个方法写就行了* @param g 画笔*  */@Overridepublic void paint(Graphics g) {// g.fillRect(0,0,100,200); // 设置颜色落笔点 宽高g.drawImage(bg, 0, 0, null); // 画背景if (state == START) {g.drawImage(start, 0, 0, null);  // 开始图片}g.drawImage(column1.image, column1.x, column1.y, null); // 画柱子g.drawImage(column2.image, column2.x, column2.y, null); // 画柱子2g.drawImage(bird.image, bird.x, bird.y, null); //小鸟图片g.drawImage(ground.image, ground.x, ground.y, null);  // 地面图片if (state == GAME_OVER) {g.drawImage(gameOver_image, 0, 0, null); // 结束图片}// 画分数Font font = new Font("微软雅黑", Font.BOLD, 25); // 创建字体g.setFont(font);  // 给画笔设置字体g.setColor(Color.BLACK);  // 设置字体黑色颜色g.drawString("分数:  " + score, 30, 50);g.setColor(Color.WHITE);  // 设置字体白色颜色g.drawString("分数:  " + score, 28, 48);}// 判断小鸟与柱子是否相撞 游戏结束public boolean isGameOver() {boolean isHit = bird.hitGround(ground) || bird.hitCeiling() || bird.hitColumn(column1) || bird.hitColumn(column2);return isHit;}// 游戏流程控制的方法public void action() throws Exception {frame.addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {System.out.println(e.getKeyCode());if(e.getKeyCode() == 32){if (state == START) {  // 如果是开始状态 单击转换运行state = RUNNING;}if (state == RUNNING) {bird.up(); //小鸟上升}if (state == GAME_OVER) {bird = new Bird();column1 = new Column();column2 = new Column();column2.x = column1.x + column1.distance;score = 0;state = START;}}}});// 给当前对象()添加鼠标单击事件this.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) { // 鼠标单击执行代码if (state == START) {  // 如果是开始状态 单击转换运行state = RUNNING;}if (state == RUNNING) {bird.up(); //小鸟上升}if (state == GAME_OVER) {bird = new Bird();column1 = new Column();column2 = new Column();column2.x = column1.x + column1.distance;score = 0;state = START;}}});// 死循环 {}的代码会一直反复执行while (true) {if (state == START) {ground.step(); // 地面移动bird.fly(); // 小鸟飞翔} else if (state == RUNNING) {ground.step(); // 地面移动column1.step(); // 柱子1移动column2.step(); // 柱子2移动bird.fly(); // 小鸟飞翔bird.down(); // 小鸟下落if (isGameOver() == true) {state = GAME_OVER;}// 设置增加分数if (bird.x == column1.x + column1.width + 1 || bird.x == column2.x + column2.width + 1) {score +=5;}}repaint(); //重画 即重新执行paint 方法Thread.sleep(10); //每隔10毫秒,让程序休眠一次}}static  JFrame frame = new JFrame();// main方法 - 程序的入口(即:有main方法 程序才能运行)public static void main(String[] args) throws Exception {BirdGame game = new BirdGame(); // 创建画板对象frame.setSize(432, 644);//设置宽高frame.setLocationRelativeTo(null); // 居中显示frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭窗口,同时使程序结束frame.setVisible(true); //设置可见性frame.add(game); // 将画板放到画框上frame.setTitle("飞翔的小鸟");// 设置标题frame.setResizable(false);// 设置不允许玩家拖动界面// 调用actiongame.action();}}

package com.qiku.bird;import java.awt.image.BufferedImage;/** 柱子类* */
public class Column {int x;// 坐标int y;int width; // 宽高int height;BufferedImage image; // 图片int gap; //上下柱子之间的间隙int distance; //水平方向柱子之间的距离int min = -(1200 / 2 - 144 / 2);int max = 644 - 146 - 144 / 2 - 1200 / 2;public Column() {gap = 144;distance = 244;image = BirdGame.column_image;width = image.getWidth();height = image.getHeight();x = BirdGame.bg.getWidth();y = (int) (Math.random() * (max - min) + min);}public void step() {x--;if (x <= -width) {x = BirdGame.bg.getWidth();y = (int) (Math.random() * (max - min) + min);}}
}

package com.qiku.bird;import java.awt.image.BufferedImage;/*
* 地面类
* */
public class Ground {int x ;// 地面坐标int y ;int width ; // 地面的宽高int height;BufferedImage image; // 地面图片public Ground(){image = BirdGame.ground_image;x = 0;y = BirdGame.bg.getHeight() - image.getHeight();width = image.getWidth();height = image.getHeight();}/** 地面走一步的方法* */public void step(){x--;if(x <= 432 - width){x=0;}}
}

三.结果呈现

         

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/206746.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Youtube运营如何打破0播放?你需要的技巧、策略与工具

对于有跨境意向的内容创作者或者品牌企业来说&#xff0c;YouTube是因其巨大的潜在受众群和商业价值成为最值得投入变现与营销计划的平台。 据统计&#xff0c;98% 的美国人每月访问 YouTube&#xff0c;近三分之二的人每天访问。但是&#xff0c;YouTube还远未达到过度饱和的…

12-25v转3.3v高清水下钓鱼摄像头电源供电芯片方案

高清水下钓鱼摄像头电源芯片方案&#xff1a;12-25V转3.3V&#xff0c;支持超宽电压输入范围和30米长线视频放大 在水下钓鱼摄像头设计中&#xff0c;为了实现高清画质和稳定的电源供应&#xff0c;需要一款能够将12-25V转换为3.3V输出的高效电源芯片。这款电源芯片不仅支持高…

Vue批量全局处理undefined和null转为““ 空字符串

我们在处理后台返回的信息&#xff0c;有的时候返回的是undefined或者null&#xff0c;这种字符串容易引起用户的误解&#xff0c;所以需要我们把这些字符串处理一下。 如果每个页面都单独处理&#xff0c;那么页面会很冗余&#xff0c;并且后期如果有修改容易遗漏&#xff0c…

员工微信私下收红包,企业如何加强监管

随着智能手机的普及和社交软件的兴起&#xff0c;越来越多的企业和员工开始使用微信等社交应用程序进行日常工作交流和业务协作。然而&#xff0c;与此同时&#xff0c;一些行业的员工在微信上私下收取红包的问题也日益严重&#xff0c;这不仅违反了公司的规定&#xff0c;也损…

python基础-numpy

numpy中shape (1,X) 和 &#xff08;X&#xff0c;&#xff09;的区别 参考 首先放结论&#xff1a;shape(x,)是一维数组&#xff0c;ndim1,[1,2,3,…x] ;shape(1,x)是二维&#xff1f;数组&#xff0c;ndim2,[[1,2,3,…n]] 由于array.shape 表示数组的维度&#xff0c;返回一…

爆款文章有诀窍,内容创作者如何能持续产出优质内容

内容营销人有没有这么一种共鸣&#xff1a;10 万 那么多&#xff0c;为什么不能多我一个&#xff1f; 通常&#xff0c;我们把浏览量 / 阅读量高、转评赞数量高的内容看作爆款&#xff0c;而数据如果达到 10 万 则是超级爆款。因为&#xff0c;阅读量高意味着内容得到了大量的曝…

WMware虚拟机与主机互相共享文件安装VMware Tools灰色无法点击安装解决方案

一、背景 虚拟机与主机互传文件最简单的方法&#xff0c;就是给虚拟机系统安装VMware Tools。 安装VMware Tools后虚拟机系统和主机的文件可以相互拖拽&#xff0c;文字也可以任意粘贴复制。 二、遇到的问题 使用VMware时&#xff0c;安装VMware Tools或者重新安装VMware To…

Cesium实现热力图功能

效果图如下&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdev…

经典双指针算法试题(二)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、有效三角形的个数1、题目讲解2、讲解算法原理3、代码实现 二、查找总价格为目标值的两个商…

SSM之Mybatis框架

1 概述 1.1 什么是Mybayis 它是一款半自动的ORM持久层框架&#xff0c;具有较高的SQL灵活性&#xff0c;支持高级映射(一对一&#xff0c;一对多)&#xff0c;动态SQL&#xff0c;延迟加载和缓存等特性&#xff0c;但它的数据库无关性较低。 1.2 什么是ORM ORM&#xff08;…

FlinkCDC实现主数据与各业务系统数据的一致性(瀚高、TIDB)

文章末尾附有flinkcdc对应瀚高数据库flink-cdc-connector代码下载地址 1、业务需求 目前项目有主数据系统和N个业务系统,为保障“一数一源”,各业务系统表涉及到主数据系统的字段都需用主数据系统表中的字段进行实时覆盖,这里以某个业务系统的一张表举例说明:业务系统表Ta…

FindMy技术用于充电宝

充电宝是一种便捷的充电器&#xff0c;方便个人随身携带&#xff0c;能够自行储备电能&#xff0c;为主流电子设备提供充电服务。它广泛应用于没有外部电源供应的场所&#xff0c;例如旅行、户外活动或紧急情况下&#xff0c;为用户的手持设备提供持续的电力支持&#xff0c;确…