原标题:Java 开发打飞机小游戏(附完整源码)
上图
写在前面
技术源于分享,所以今天抽空把自己之前用java做过的小游戏整理贴出来给大家参考学习。java确实不适合写桌面应用,这里只是通过这个游戏让大家理解oop面向对象编程的过程,纯属娱乐。代码写的很简单,也很容易理解,并且注释写的很清楚了,还有问题,自己私下去补课学习。
完整代码敌飞机
importjava.util.Random;
敌飞机: 是飞行物,也是敌人
publicclassAirplaneextendsFlyingObjectimplementsEnemy{
privateintspeed = 3; //移动步骤
/** 初始化数据 */
publicAirplane{
this.image = ShootGame.airplane;
width = image.getWidth;
height = image.getHeight;
y = -height;
Random rand = newRandom;
x = rand.nextInt(ShootGame.WIDTH - width);
}
/** 获取分数 */
@Override
publicintgetScore{
return5;
}
/** //越界处理 */
@Override
publicbooleanoutOfBounds{
returny>ShootGame.HEIGHT;
}
/** 移动 */
@Override
publicvoidstep{
y += speed;
}
}
分数奖励
/**
* 奖励
*/
publicinterfaceAward{
intDOUBLE_FIRE = 0; //双倍火力
intLIFE = 1; //1条命
/** 获得奖励类型(上面的0或1) */
intgetType;
}
蜜蜂
importjava.util.Random;
/** 蜜蜂 */
publicclassBeeextendsFlyingObjectimplementsAward{
privateintxSpeed = 1; //x坐标移动速度
privateintySpeed = 2; //y坐标移动速度
privateintawardType; //奖励类型
/** 初始化数据 */
publicBee{
this.image = ShootGame.bee;
width = image.getWidth;
height = image.getHeight;
y = -height;
Random rand = newRandom;
x = rand.nextInt(ShootGame.WIDTH - width);
awardType = rand.nextInt( 2); //初始化时给奖励
}
/** 获得奖励类型 */
publicintgetType{
returnawardType;
}
/** 越界处理 */
@Override
publicbooleanoutOfBounds{
returny>ShootGame.HEIGHT;
}
/** 移动,可斜着飞 */
@Override
publicvoidstep{
x += xSpeed;
y += ySpeed;
if(x > ShootGame.WIDTH-width){
xSpeed = - 1;
}
if(x < 0){
xSpeed = 1;
}
}
}
子弹类:是飞行物体
/**
* 子弹类:是飞行物
*/
publicclassBulletextendsFlyingObject{
privateintspeed = 3; //移动的速度
/** 初始化数据 */
publicBullet( intx, inty){
this.x = x;
this.y = y;
this.image = ShootGame.bullet;
}
/** 移动 */
@Override
publicvoidstep{
y-=speed;
}
/** 越界处理 */
@Override
publicbooleanoutOfBounds{
returny
}
}
敌人的分数
/**
* 敌人,可以有分数
*/
publicinterfaceEnemy{
/** 敌人的分数 */
intgetScore;
}
飞行物(敌机,蜜蜂,子弹,英雄机)
importjava.awt.image.BufferedImage;
/**
* 飞行物(敌机,蜜蜂,子弹,英雄机)
*/
publicabstractclassFlyingObject{
protectedintx; //x坐标
protectedinty; //y坐标
protectedintwidth; //宽
protectedintheight; //高
protectedBufferedImage image; //图片
publicintgetX{
returnx;
}
publicvoidsetX( intx){
this.x = x;
}
publicintgetY{
returny;
}
publicvoidsetY( inty){
this.y = y;
}
publicintgetWidth{
returnwidth;
}
publicvoidsetWidth( intwidth){
this.width = width;
}
publicintgetHeight{
returnheight;
}
publicvoidsetHeight( intheight){
this.height = height;
}
publicBufferedImage getImage{
returnimage;
}
publicvoidsetImage(BufferedImage image){
this.image = image;
}
/**
* 检查是否出界
* @returntrue 出界与否
*/
publicabstractbooleanoutOfBounds;
/**
* 飞行物移动一步
*/
publicabstractvoidstep;
/**
* 检查当前飞行物体是否被子弹(x,y)击(shoot)中
* @paramBullet 子弹对象
* @returntrue表示被击中了
*/
publicbooleanshootBy(Bullet bullet){
intx = bullet.x; //子弹横坐标
inty = bullet.y; //子弹纵坐标
returnthis.x
}
}
英雄机
importjava.awt.image.BufferedImage;
/**
* 英雄机:是飞行物
*/
publicclassHeroextendsFlyingObject{
privateBufferedImage[] images = {}; //英雄机图片
privateintindex = 0; //英雄机图片切换索引
privateintdoubleFire; //双倍火力
privateintlife; //命
/** 初始化数据 */
publicHero{
life = 3; //初始3条命
doubleFire = 0; //初始火力为0
images = newBufferedImage[]{ShootGame.hero0, ShootGame.hero1}; //英雄机图片数组
image = ShootGame.hero0; //初始为hero0图片
width = image.getWidth;
height = image.getHeight;
x = 150;
y = 400;
}
/** 获取双倍火力 */
publicintisDoubleFire{
returndoubleFire;
}
/** 设置双倍火力 */
publicvoidsetDoubleFire( intdoubleFire){
this.doubleFire = doubleFire;
}
/** 增加火力 */
publicvoidaddDoubleFire{
doubleFire = 40;
}
/** 增命 */
publicvoidaddLife{ //增命
life++;
}
/** 减命 */
publicvoidsubtractLife{ //减命
life--;
}
/** 获取命 */
publicintgetLife{
returnlife;
}
/** 当前物体移动了一下,相对距离,x,y鼠标位置 */
publicvoidmoveTo( intx, inty){
this.x = x - width/ 2;
this.y = y - height/ 2;
}
/** 越界处理 */
@Override
publicbooleanoutOfBounds{
returnfalse;
}
/** 发射子弹 */
publicBullet[] shoot{
intxStep = width/ 4; //4半
intyStep = 20; //步
if(doubleFire> 0){ //双倍火力
Bullet[] bullets = newBullet[ 2];
bullets[ 0] = newBullet(x+xStep,y-yStep); //y-yStep(子弹距飞机的位置)
bullets[ 1] = newBullet(x+ 3*xStep,y-yStep);
returnbullets;
} else{ //单倍火力
Bullet[] bullets = newBullet[ 1];
bullets[ 0] = newBullet(x+ 2*xStep,y-yStep);
returnbullets;
}
}
/** 移动 */
@Override
publicvoidstep{
if(images.length> 0){
image = images[index++/ 10%images.length]; //切换图片hero0,hero1
}
}
/** 碰撞算法 */
publicbooleanhit(FlyingObject other){
intx1 = other.x - this.width/ 2; //x坐标最小距离
intx2 = other.x + this.width/ 2+ other.width; //x坐标最大距离
inty1 = other.y - this.height/ 2; //y坐标最小距离
inty2 = other.y + this.height/ 2+ other.height; //y坐标最大距离
intherox = this.x + this.width/ 2; //英雄机x坐标中心点距离
intheroy = this.y + this.height/ 2; //英雄机y坐标中心点距离
returnherox>x1 && heroxy1 && heroy
}
}
游戏启动主类
importjava.awt.Font;
importjava.awt.Color;
importjava.awt.Graphics;
importjava.awt.event.MouseAdapter;
importjava.awt.event.MouseEvent;
importjava.util.Arrays;
importjava.util.Random;
importjava.util.Timer;
importjava.util.TimerTask;
importjava.awt.image.BufferedImage;
importjavax.imageio.ImageIO;
importjavax.swing.ImageIcon;
importjavax.swing.JFrame;
importjavax.swing.JPanel;
/**
*
*/
publicclassShootGameextendsJPanel{
publicstaticfinalintWIDTH = 400; // 面板宽
publicstaticfinalintHEIGHT = 654; // 面板高
/** 游戏的当前状态: START RUNNING PAUSE GAME_OVER */
privateintstate;
privatestaticfinalintSTART = 0;
privatestaticfinalintRUNNING = 1;
privatestaticfinalintPAUSE = 2;
privatestaticfinalintGAME_OVER = 3;
privateintscore = 0; // 得分
privateTimer timer; // 定时器
privateintintervel = 1000/ 100; // 时间间隔(毫秒)
publicstaticBufferedImage background;
publicstaticBufferedImage start;
publicstaticBufferedImage airplane;
publicstaticBufferedImage bee;
publicstaticBufferedImage bullet;
publicstaticBufferedImage hero0;
publicstaticBufferedImage hero1;
publicstaticBufferedImage pause;
publicstaticBufferedImage gameover;
privateFlyingObject[] flyings = {}; // 敌机数组
privateBullet[] bullets = {}; // 子弹数组
privateHero hero = newHero; // 英雄机
static{ // 静态代码块,初始化图片资源
try{
background = ImageIO.read(ShootGame . class
. getResource(" background. png")) ;
start = ImageIO.read(ShootGame . class. getResource(" start. png"));
airplane = ImageIO
.read(ShootGame . class. getResource(" airplane. png"));
bee = ImageIO.read(ShootGame . class. getResource(" bee. png"));
bullet = ImageIO.read(ShootGame . class. getResource(" bullet. png"));
hero0 = ImageIO.read(ShootGame . class. getResource(" hero0. png"));
hero1 = ImageIO.read(ShootGame . class. getResource(" hero1. png"));
pause = ImageIO.read(ShootGame . class. getResource(" pause. png"));
gameover = ImageIO
.read(ShootGame . class. getResource(" gameover. png"));
} catch(Exception e) {
e.printStackTrace;
}
}
/** 画 */
@Override
publicvoidpaint(Graphics g){
g.drawImage(background, 0, 0, null); // 画背景图
paintHero(g); // 画英雄机
paintBullets(g); // 画子弹
paintFlyingObjects(g); // 画飞行物
paintScore(g); // 画分数
paintState(g); // 画游戏状态
}
/** 画英雄机 */
publicvoidpaintHero(Graphics g){
g.drawImage(hero.getImage, hero.getX, hero.getY, null);
}
/** 画子弹 */
publicvoidpaintBullets(Graphics g){
for( inti = 0; i < bullets.length; i++) {
Bullet b = bullets[i];
g.drawImage(b.getImage, b.getX - b.getWidth / 2, b.getY,
null);
}
}
/** 画飞行物 */
publicvoidpaintFlyingObjects(Graphics g){
for( inti = 0; i < flyings.length; i++) {
FlyingObject f = flyings[i];
g.drawImage(f.getImage, f.getX, f.getY, null);
}
}
/** 画分数 */
publicvoidpaintScore(Graphics g){
intx = 10; // x坐标
inty = 25; // y坐标
Font font = newFont(Font.SANS_SERIF, Font.BOLD, 22); // 字体
g.setColor( newColor( 0xFF0000));
g.setFont(font); // 设置字体
g.drawString( "SCORE:"+ score, x, y); // 画分数
y=y+ 20; // y坐标增20
g.drawString( "LIFE:"+ hero.getLife, x, y); // 画命
}
/** 画游戏状态 */
publicvoidpaintState(Graphics g){
switch(state) {
caseSTART: // 启动状态
g.drawImage(start, 0, 0, null);
break;
casePAUSE: // 暂停状态
g.drawImage(pause, 0, 0, null);
break;
caseGAME_OVER: // 游戏终止状态
g.drawImage(gameover, 0, 0, null);
break;
}
}
publicstaticvoidmain(String[] args){
JFrame frame = newJFrame( "Fly");
ShootGame game = newShootGame; // 面板对象
frame.add(game); // 将面板添加到JFrame中
frame.setSize(WIDTH, HEIGHT); // 设置大小
frame.setAlwaysOnTop( true); // 设置其总在最上
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 默认关闭操作
frame.setIconImage( newImageIcon( "images/icon.jpg").getImage); // 设置窗体的图标
frame.setLocationRelativeTo( null); // 设置窗体初始位置
frame.setVisible( true); // 尽快调用paint
game.action; // 启动执行
}
/** 启动执行代码 */
publicvoidaction{
// 鼠标监听事件
MouseAdapter l = newMouseAdapter {
@Override
publicvoidmouseMoved(MouseEvent e){ // 鼠标移动
if(state == RUNNING) { // 运行状态下移动英雄机--随鼠标位置
intx = e.getX;
inty = e.getY;
hero.moveTo(x, y);
}
}
@Override
publicvoidmouseEntered(MouseEvent e){ // 鼠标进入
if(state == PAUSE) { // 暂停状态下运行
state = RUNNING;
}
}
@Override
publicvoidmouseExited(MouseEvent e){ // 鼠标退出
if(state == RUNNING) { // 游戏未结束,则设置其为暂停
state = PAUSE;
}
}
@Override
publicvoidmouseClicked(MouseEvent e){ // 鼠标点击
switch(state) {
caseSTART:
state = RUNNING; // 启动状态下运行
break;
caseGAME_OVER: // 游戏结束,清理现场
flyings = newFlyingObject[ 0]; // 清空飞行物
bullets = newBullet[ 0]; // 清空子弹
hero = newHero; // 重新创建英雄机
score = 0; // 清空成绩
state = START; // 状态设置为启动
break;
}
}
};
this.addMouseListener(l); // 处理鼠标点击操作
this.addMouseMotionListener(l); // 处理鼠标滑动操作
timer = newTimer; // 主流程控制
timer.schedule( newTimerTask {
@Override
publicvoidrun{
if(state == RUNNING) { // 运行状态
enterAction; // 飞行物入场
stepAction; // 走一步
shootAction; // 英雄机射击
bangAction; // 子弹打飞行物
outOfBoundsAction; // 删除越界飞行物及子弹
checkGameOverAction; // 检查游戏结束
}
repaint; // 重绘,调用paint方法
}
}, intervel, intervel);
}
intflyEnteredIndex = 0; // 飞行物入场计数
/** 飞行物入场 */
publicvoidenterAction{
flyEnteredIndex++;
if(flyEnteredIndex % 40== 0) { // 400毫秒生成一个飞行物--10*40
FlyingObject obj = nextOne; // 随机生成一个飞行物
flyings = Arrays.copyOf(flyings, flyings.length + 1);
flyings[flyings.length - 1] = obj;
}
}
/** 走一步 */
publicvoidstepAction{
for( inti = 0; i < flyings.length; i++) { // 飞行物走一步
FlyingObject f = flyings[i];
f.step;
}
for( inti = 0; i < bullets.length; i++) { // 子弹走一步
Bullet b = bullets[i];
b.step;
}
hero.step; // 英雄机走一步
}
/** 飞行物走一步 */
publicvoidflyingStepAction{
for( inti = 0; i < flyings.length; i++) {
FlyingObject f = flyings[i];
f.step;
}
}
intshootIndex = 0; // 射击计数
/** 射击 */
publicvoidshootAction{
shootIndex++;
if(shootIndex % 30== 0) { // 300毫秒发一颗
Bullet[] bs = hero.shoot; // 英雄打出子弹
bullets = Arrays.copyOf(bullets, bullets.length + bs.length); // 扩容
System.arraycopy(bs, 0, bullets, bullets.length - bs.length,
bs.length); // 追加数组
}
}
/** 子弹与飞行物碰撞检测 */
publicvoidbangAction{
for( inti = 0; i < bullets.length; i++) { // 遍历所有子弹
Bullet b = bullets[i];
bang(b); // 子弹和飞行物之间的碰撞检查
}
}
/** 删除越界飞行物及子弹 */
publicvoidoutOfBoundsAction{
intindex = 0; // 索引
FlyingObject[] flyingLives = newFlyingObject[flyings.length]; // 活着的飞行物
for( inti = 0; i < flyings.length; i++) {
FlyingObject f = flyings[i];
if(!f.outOfBounds) {
flyingLives[index++] = f; // 不越界的留着
}
}
flyings = Arrays.copyOf(flyingLives, index); // 将不越界的飞行物都留着
index = 0; // 索引重置为0
Bullet[] bulletLives = newBullet[bullets.length];
for( inti = 0; i < bullets.length; i++) {
Bullet b = bullets[i];
if(!b.outOfBounds) {
bulletLives[index++] = b;
}
}
bullets = Arrays.copyOf(bulletLives, index); // 将不越界的子弹留着
}
/** 检查游戏结束 */
publicvoidcheckGameOverAction{
if(isGameOver== true) {
state = GAME_OVER; // 改变状态
}
}
/** 检查游戏是否结束 */
publicbooleanisGameOver{
for( inti = 0; i < flyings.length; i++) {
intindex = - 1;
FlyingObject obj = flyings[i];
if(hero.hit(obj)) { // 检查英雄机与飞行物是否碰撞
hero.subtractLife; // 减命
hero.setDoubleFire( 0); // 双倍火力解除
index = i; // 记录碰上的飞行物索引
}
if(index != - 1) {
FlyingObject t = flyings[index];
flyings[index] = flyings[flyings.length - 1];
flyings[flyings.length - 1] = t; // 碰上的与最后一个飞行物交换
flyings = Arrays.copyOf(flyings, flyings.length - 1); // 删除碰上的飞行物
}
}
returnhero.getLife <= 0;
}
/** 子弹和飞行物之间的碰撞检查 */
publicvoidbang(Bullet bullet){
intindex = - 1; // 击中的飞行物索引
for( inti = 0; i < flyings.length; i++) {
FlyingObject obj = flyings[i];
if(obj.shootBy(bullet)) { // 判断是否击中
index = i; // 记录被击中的飞行物的索引
break;
}
}
if(index != - 1) { // 有击中的飞行物
FlyingObject one = flyings[index]; // 记录被击中的飞行物
FlyingObject temp = flyings[index]; // 被击中的飞行物与最后一个飞行物交换
flyings[index] = flyings[flyings.length - 1];
flyings[flyings.length - 1] = temp;
flyings = Arrays.copyOf(flyings, flyings.length - 1); // 删除最后一个飞行物(即被击中的)
// 检查one的类型(敌人加分,奖励获取)
if(one instanceofEnemy) { // 检查类型,是敌人,则加分
Enemy e = (Enemy) one; // 强制类型转换
score += e.getScore; // 加分
} else{ // 若为奖励,设置奖励
Award a = (Award) one;
inttype = a.getType; // 获取奖励类型
switch(type) {
caseAward.DOUBLE_FIRE:
hero.addDoubleFire; // 设置双倍火力
break;
caseAward.LIFE:
hero.addLife; // 设置加命
break;
}
}
}
}
/**
* 随机生成飞行物
*
* @return飞行物对象
*/
publicstaticFlyingObject nextOne{
Random random = newRandom;
inttype = random.nextInt( 20); // [0,20)
if(type < 4) {
returnnewBee;
} else{
returnnewAirplane;
}
}
}
一只独孤的程序猿
https://blog.csdn.net/wclxyn/article/details/110159708
关注公众号,你想要的Java都在这里返回搜狐,查看更多
责任编辑: