Java实现Flappy Bird游戏源码

本文实例为大家分享了Java实现Flappy Bird游戏的具体代码,供大家参考,具体内容如下

1.首先在mainActivity.xml中放置一个View,ID为viewDraw

2.开始编程,程序中自定义一个View类的子类,与viewDraw关联,程序除了放置如一个view控件,没有其他控件,程序上面的所有图片都是通过控制canvas画图实现

3.游戏是依据flappybird的游戏过程重新写的算法,功能与原版游戏相似,可能有些地方不足,完全是学习练习编程而已,做的不好见谅

4.原图片大小为384*512,在展示图片时将图片进行了放大,尽可能满足800*1280的全屏展示,如果你使用三星Note10,这个程序可以直接复制粘贴运行,否则,可能会遇到图片画错位置的问题,请适当调整

5.程序游戏中使用到的图片最后,只需要按照图片上的名字命名该图片,并导入到程序的图片资源中,就能顺利运行本程序

代码:

public class MainActivity extends Activity
{
 static final int IMG_WIDTH=384; //图片的长宽
 static final int IMG_HEIGHT=512;
 private View viewDraw;

 @Override
 protected void onCreate(Bundle savedInstanceState)
 {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 viewDraw = (View) findViewById(R.id.viewDraw);
 MyView v = new MyView(viewDraw.getContext(), null);

 setContentView(v);
 }

 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event)
 {
 if (keyCode == KeyEvent.KEYCODE_BACK)
 {
 finish();
 return true;
 }
 return super.onKeyDown(keyCode, event);
 }
 //定义水管障碍物类
 class Obstacle
 {
 int x;
 int h;
 public Obstacle()
 {
 x=0;
 h=0;
 }
 }
 //自定义View子类,完成动画的刷新
 class MyView extends View implements Runnable
 {
 static final int SPEED=2;
 // 图形当前坐标
 private int x = 20, y = 20,a,b,c,birdHeight,time,point,v,record;
 Obstacle pillar[]= new Obstacle[3];

 boolean bInit,bCourse,bGame,bGameOver;

 RefreshHandler mRedrawHandler;

 Bitmap birdUpBitmap,birdDownBitmap,birdMiddleBitmap,groundBitmap,otherStartBitmap;
 Bitmap courseUpBitmap,courseDownBitmap,courseMiddleBitmap;
 Bitmap pillarUpBitmap,pillarDownBitmap,gameOverBitmap,recordBitmap,playAgainBitmap,listBitmap,goldBitmap,silverBitmap,bronzeBitmap,whiteGoldBitmap,gameBackgroundBitmap;

 // 构造方法
 public MyView(Context context, AttributeSet attrs)
 {
 super(context, attrs);
 // TODO Auto-generated constructor stub
 // 获得焦点
 setFocusable(true);
 bInit=false;
 bCourse=false;
 bGame=false;
 bGameOver=false;
 //障碍物初始化
 pillar[0]=new Obstacle();
 pillar[1]=new Obstacle();
 pillar[2]=new Obstacle();
 //载入图片
 otherStartBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.other_start);
 birdUpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bird_up);
 birdDownBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bird_down);
 birdMiddleBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bird_middle);
 groundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background_ground);
 pillarDownBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pillar_downside);
 pillarUpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pillar_upside);
 gameOverBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.other_gameover);
 recordBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.other_record);
 playAgainBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.other_restart);
 listBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.other_list);
 bronzeBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.medals_bronze);
 silverBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.medals_silver);
 goldBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.medals_gold);
 whiteGoldBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.medals_whitegold);
 //游戏界面刷新handler
 mRedrawHandler = new RefreshHandler();

 // 启动线程
 new Thread(this).start();
 }

 @Override
 public void run()
 {
 // TODO Auto-generated method stub

 while (true)
 {
 // 通过发送消息更新界面
 Message m = new Message();
 m.what = 0x101;
 mRedrawHandler.sendMessage(m);
 try
 {
 Thread.sleep(20);
 } catch (InterruptedException e)
 {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 }
 }

 //游戏画面更新
 void gameDraw(Canvas canvas)
 {
 if(!bInit)
 {
 Bitmap bm;
 bm = BitmapFactory.decodeResource(getResources(), R.drawable.other_load);
 canvas.drawBitmap(bm, 0, 0, null);
 Paint p1 = new Paint();
 p1.setAntiAlias(true);
 p1.setColor(Color.WHITE);
 p1.setTextSize(20);//设置字体大小
 }
 else if(bInit)
 {
 if(!bCourse)
 {
 a-=SPEED;
 if(a<=0)
 a=384;

 canvas.drawBitmap(otherStartBitmap, 0, 0, null);
 canvas.drawBitmap(groundBitmap, a, 448, null);
 canvas.drawBitmap(groundBitmap, a-384, 448, null);

 b=a%128;
 if(b>=0&&b<32)
 {
 canvas.drawBitmap(birdMiddleBitmap, 175, 220, null);
 }
 if(b>=32&&b<64)
 {
 canvas.drawBitmap(birdUpBitmap, 175, 216, null);
 }
 if(b>=64&&b<96)
 {
 canvas.drawBitmap(birdMiddleBitmap, 175, 220, null);
 }
 if(b>=96&&b<=128)
 {
 canvas.drawBitmap(birdDownBitmap, 175, 224, null);
 }
 canvas.drawBitmap(groundBitmap, a, 448, null);
 }
 else if (bCourse)
 {
 if(!bGame)
 {
 time += 1;

 int temp = time % 64;
 if (temp >= 0 && temp < 16)
 canvas.drawBitmap(courseUpBitmap, 0, 0, null);
 if (temp >= 16 && temp < 32)
 canvas.drawBitmap(courseMiddleBitmap, 0, 0, null);
 if (temp >= 32 && temp < 48)
 canvas.drawBitmap(courseDownBitmap, 0, 0, null);
 if (temp >= 48 && temp < 64)
 canvas.drawBitmap(courseMiddleBitmap, 0, 0, null);
 a-=SPEED;
 if(a<=0)
 a=384;
 canvas.drawBitmap(groundBitmap, a, 448, null);
 canvas.drawBitmap(groundBitmap, a-384, 448, null);

 }
 else if(bGame)
 {
 if(!bGameOver)
 {
 time+=1;

 /***************计算高度************************/
 v+=9.8;
 if(v>120)
 v=120;
 else if(v<-150)
 v=-150;
 if(v>=0)
 birdHeight+=((v*5.0)/77);
 else if(v<0)
 birdHeight+=((v*4.5)/77);
 if(birdHeight<0)
 birdHeight=0;
 else if(birdHeight>415)
 birdHeight=415;

 /***************柱子的移动**********************/
 for(c=0;c<3;c++)
 {
  pillar[c].x-=SPEED;
  if(pillar[c].x<=-70)
  pillar[c].x=650;
 if(pillar[c].x==512)
 {
  pillar[c].h=(new Random()).nextInt(200)+200;
 }
 }

 /***************计算分数************************/
 for(c=0;c<3;c++)
 {
 if(pillar[c].x==100)
  point++;
 }

 /****************地面移动***********************/
 a-=SPEED;

 /****************判断碰撞,+32判断下侧柱子,-170判断上侧柱子***********************/
 if(pillar[0].x>=30&&pillar[0].x<=145&&(pillar[0].h<(birdHeight+32)||(pillar[0].h-170)>birdHeight))
  bGameOver=true;
 if(pillar[1].x>=30&&pillar[1].x<=145&&(pillar[1].h<(birdHeight+32)||(pillar[1].h-170)>birdHeight))
  bGameOver=true;
 if(pillar[2].x>=30&&pillar[2].x<=145&&(pillar[2].h<(birdHeight+32)||(pillar[2].h-170)>birdHeight))
 bGameOver=true;
 //是否碰到地面
 if(birdHeight>414)
 bGameOver=true;
 }

 /***************显示图像************************/
 //显示背景
 canvas.drawBitmap(gameBackgroundBitmap, 0, 0, null);

 //显示柱子
 for(c=0;c<3;c++)
 {
 canvas.drawBitmap(pillarDownBitmap, pillar[c].x, pillar[c].h, null);
 canvas.drawBitmap(pillarUpBitmap, pillar[c].x, pillar[c].h-420, null);
 }

 if(a<=0)
 a=384;
 canvas.drawBitmap(groundBitmap, a, 448, null);
 canvas.drawBitmap(groundBitmap, a-384, 448, null);

 int temp=time%16;
 if(temp>=0&&temp<4)
 canvas.drawBitmap(birdMiddleBitmap, 100, birdHeight, null);
 if(temp>=4&&temp<8)
 canvas.drawBitmap(birdUpBitmap, 100, birdHeight, null);
 if(temp>=8&&temp<12)
 canvas.drawBitmap(birdMiddleBitmap, 100, birdHeight, null);
 if(temp>=12&&temp<16)
 canvas.drawBitmap(birdDownBitmap, 100, birdHeight, null);

 if(!bGameOver)
 {
 /*******************显示分数**********************/
 Paint p1 = new Paint();
 p1.setAntiAlias(true);
 p1.setColor(Color.WHITE);
 p1.setTextSize(20);//设置字体大小
 canvas.drawText("score:"+point, 171, 50, p1);
 canvas.drawText("acc:"+v, 171, 80, p1);
 canvas.drawText("H:"+birdHeight, 171, 110, p1);
 }
 else if(bGameOver)
 {
 canvas.drawBitmap(gameOverBitmap, 55, 60, null);
 canvas.drawBitmap(recordBitmap, 35, 150, null);
 canvas.drawBitmap(playAgainBitmap, 35, 350, null);
 canvas.drawBitmap(listBitmap, 200, 350, null);

 if(point>=10&&point<20)
 canvas.drawBitmap(bronzeBitmap, 67, 200, null);
 if(point>=20&&point<30)
 canvas.drawBitmap(silverBitmap, 67, 200, null);
 if(point>=30&&point<40)
 canvas.drawBitmap(goldBitmap, 67, 200, null);
 if(point>=40)
 canvas.drawBitmap(whiteGoldBitmap, 67, 200, null);

 Paint p1 = new Paint();
 p1.setAntiAlias(true);
 p1.setColor(Color.WHITE);
 p1.setTextSize(20);//设置字体大小
 canvas.drawText(""+point, 260, 210, p1);
 //最高纪录
 canvas.drawText("1000", 260, 268, p1);

 }
 }
 }
 } 

 // 实例化画笔
 Paint p = new Paint();
 p.setColor(Color.BLACK);
 p.setColor(Color.WHITE);
 canvas.drawText("init: "+bInit+" course: "+bCourse+" game: "+bGame+" over: "+bGameOver, 0, 10, p);
 }

 @Override
 protected void onDraw(Canvas canvas)
 {
 // TODO Auto-generated method stub
 super.onDraw(canvas);
 canvas.drawColor(Color.BLACK);
 //这里的操作是为了在我的平板电脑竖屏尽量全屏显示,原图片很小,我的屏幕分辨率为1280*800,如果不需要对图片进行缩放,可以在只而立只保留gameDraw()部分
 canvas.save();
 canvas.translate(16, 80);
 float scale=(float) 2.0;
 canvas.scale(scale, scale);
 canvas.clipRect(0, 0, IMG_WIDTH, IMG_HEIGHT);
 gameDraw(canvas);
 canvas.restore();
 }

 // 更新界面处理器
 class RefreshHandler extends Handler
 {
 @Override
 public void handleMessage(Message msg)
 {
 // TODO Auto-generated method stub
 if (msg.what == 0x101)
 {
 MyView.this.update();
 MyView.this.invalidate();
 }
 super.handleMessage(msg);
 }
 }

 // 更新坐标
 private void update()
 {
 }
 //触屏事件
 @Override
 public boolean onTouchEvent(MotionEvent event)
 {
 switch (event.getPointerCount())
 {
 case 1:
 return onSingleTouchEvent(event);
 case 2:
 return onDoubleTouchEvent(event);
 default:
 return false;
 }
 }
 //单手指触屏处理
 private boolean onSingleTouchEvent(MotionEvent event)
 {
 int x = (int) event.getX();
 int y = (int) event.getY();

 switch (event.getAction())
 {
 case MotionEvent.ACTION_UP:
 if(!bInit)
 {
 a=-2;
 bInit=true;
 }
 else if(bInit)
 {
 if(!bCourse)
 {
 if((new Random()).nextInt(3)==0)
 {
 gameBackgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background_night);
 courseDownBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.intro_night_down);
 courseUpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.intro_night_up);
 courseMiddleBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.intro_night_middle);
 }
 else
 {
 gameBackgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background_day);
 courseDownBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.intro_day_down);
 courseUpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.intro_day_up);
 courseMiddleBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.intro_day_middle);
 }
 time = 0;
 a=0;

 bCourse=true;
 }
 else if(bCourse)
 {
 if(!bGame)
 {
 time=0;
 birdHeight=150;
 point=0;
 pillar[0].x=700;
 pillar[1].x=940;
 pillar[2].x=1180;
 a=0;
 b=0;
 c=0;

 bGame=true;
 }
 else if(bGame)
 {
 if(!bGameOver)
 v-=250;
 else if(bGameOver)
 {
 bGameOver=false;
 bCourse=false;
 bGame=false;
 }
 }
 }
 }
 break;
 case MotionEvent.ACTION_DOWN:

 break;
 case MotionEvent.ACTION_MOVE:

 break;
 }
 return true;
 }
 //双指触屏处理
 private boolean onDoubleTouchEvent(MotionEvent event)
 {
 switch (event.getAction() & MotionEvent.ACTION_MASK)
 {
 case MotionEvent.ACTION_POINTER_UP:

 break;
 case MotionEvent.ACTION_POINTER_DOWN:
 {

 break;
 }
 case MotionEvent.ACTION_MOVE:

 postInvalidate();
 break;
 }
 return true;
 }
 }
}

图片:

background_day.png

background_ground.png

background_night.png

bird_down.png

bird_middle.png

bird_up.png

intro_day_down.png

intro_day_middle.png

intro_day_up.png

intro_night_down.png

intro_night_middle.png

intro_night_up.png

medals_bronze.png

medals_gold.png

medals_silver.png

medals_whitegold.png

other_gameover.png

other_list.png

other_load.png

other_record.png

other_restart.png

other_start.png

pillar_downside.png

pillar_upside.png

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java实现猜拳游戏

    本文实例为大家分享了java实现猜拳游戏的具体代码,供大家参考,具体内容如下 package com.farsight.session7; import java.util.Scanner; /** * 根据输入的数字,判断数组strs的值 然后进行逻辑判断 */ public class 猜拳 { public static void main(String[] args) { String[] strs = { "石头", "剪刀", "布"

  • Java实现的打地鼠小游戏完整示例【附源码下载】

    本文实例讲述了Java实现的打地鼠小游戏.分享给大家供大家参考,具体如下: 这里涉及到java线程和GUI的相关知识,一个简单的java小游戏打地鼠,有兴趣的朋友可以优化一下.先来看看运行效果: 具体代码: Mouse.java: import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import java.awt

  • Java Swing实现扫雷小游戏

    swing设计扫雷心得,供大家参考,具体内容如下 最近学习swing学习之余做了一个小游戏:扫雷 1.前期设计 2.实现 其实完成这个游戏的核心就在于对数组的操纵,下面贴主要代码Main.java: package first; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.GridLayout; import java.awt.Image; import java.

  • 小伙熬夜用Java重现经典超级马里奥代码实例

    说起Java,很多人都想问,Java这么火但是Java能干什么呢?Java主要是做企业级的应用开发,其实Java还可以做游戏开发,Java不仅开发过电脑端的游戏,手游也有开发过,经典的游戏有很多,比如<我的世界>.<吃豆>等等,今天小编来分享一个用Java开发超级马里奥. 游戏界面展示: 游戏代码如下: 以上所述是小编给大家介绍的Java重现经典超级马里奥详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的.在此也非常感谢大家对我们网站的支持!

  • java实现flappy Bird小游戏

    本文实例为大家分享了java实现flappy Bird游戏的具体代码,供大家参考,具体内容如下 整个游戏由3个类构成.Bird类,Pipe类,stage类 第一步:首先写一个Bird类 //鸟类 public class Bird { private int flyHeight;//飞行高度 private int xpos;//距离y轴(窗口左边缘)的位置, public static int Up=1;//向上飞 public static int Down=-1;//向下飞 public

  • java连连看游戏菜单设计

    本文实例为大家分享了java连连看游戏菜单的具体实现代码,供大家参考,具体内容如下 先写GUI. 首先初始化框架,菜单,按钮,需要把菜单和按钮都添加在框架中.注意添加的顺序,首先要设置菜单,再设置框架,再设置按钮,如果交换了设置菜单和框架的顺序,会导致菜单显示不出,被框架挡住.对菜单设置了三个选项,第一个选项有五个下拉按键,用循环添加,第二个和第三个选项的下拉按键直接添加. GUI代码如下: package gui; import java.awt.Font; import javax.swin

  • java实现简单扫雷小游戏

    本文实例为大家分享了java实现扫雷游戏的具体代码,供大家参考,具体内容如下 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.GridLayout; import java.awt.Insets; import java.awt.Label; import java.awt.event.ActionEvent; import java.awt.event

  • Java版AI五子棋游戏

    本文实例为大家分享了java五子棋游戏的具体代码,供大家参考,具体内容如下 AI思路:通过判断棋盘上每个空位的分数,去分数最高的几个点,随机下棋 分数计算思路:能成5个说明能赢了,给最高分 不能成5个,对方能成5个,说明对方要赢了,给第二高分 能成活4,给第三高分 能成活3,给第四高分 能成冲4,给第五高分 能成冲3,给第六高分 能成活2,给第七高分 能成冲2,给第八高分 其他,给最低分 分数设定可自己定义. 因为是去年写的了,思路记得大概就是这样.最近根据书上写了个棋类游戏的设计框架,待完善后

  • java实现斗地主游戏

    感想: 第一次写博客,感觉编辑器挺复杂厉害的,感觉自己的内容挺简单的.有什么问题请多多指教! 思路: 1.创建一个扑克牌的实体类Poker,设置了四个参数:花色.数字.牌值(判断大小).是否地主牌,实现getset方法和构造方法: 2.创建一个玩家的实体类Player,设置了四个参数: 初始牌集合,排序后牌集合,牌值集合,是否地主,实现getset方法和构造方法: 3.洗牌:循环嵌套花色数组跟数字数组生成52个Poker,手动加入大小王Poker,放进map(int,Poker)里面,利用Col

  • java实现24点游戏

    游戏规则 从扑克中每次取出4张牌.使用加减乘除,第一个能得出24者为赢.(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏. 基本要求 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式 列出表达式无重复 用户初始生命值为一给定值(比如3),初始分数为0.随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局. 使用计时器要求用户在规定时间内输入表达式,如

随机推荐