這篇文章主要介紹Java如何實現(xiàn)Flappy Bird游戲,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
成都創(chuàng)新互聯(lián)公司云計算的互聯(lián)網(wǎng)服務(wù)提供商,擁有超過13年的服務(wù)器租用、重慶服務(wù)器托管、云服務(wù)器、網(wǎng)絡(luò)空間、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗,已先后獲得國家工業(yè)和信息化部頒發(fā)的互聯(lián)網(wǎng)數(shù)據(jù)中心業(yè)務(wù)許可證。專業(yè)提供云主機、網(wǎng)絡(luò)空間、申請域名、VPS主機、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
具體內(nèi)容如下
1.首先在mainActivity.xml中放置一個View,ID為viewDraw
2.開始編程,程序中自定義一個View類的子類,與viewDraw關(guān)聯(lián),程序除了放置如一個view控件,沒有其他控件,程序上面的所有圖片都是通過控制canvas畫圖實現(xiàn)
3.游戲是依據(jù)flappybird的游戲過程重新寫的算法,功能與原版游戲相似,可能有些地方不足,完全是學(xué)習(xí)練習(xí)編程而已,做的不好見諒
4.原圖片大小為384*512,在展示圖片時將圖片進行了放大,盡可能滿足800*1280的全屏展示,如果你使用三星Note10,這個程序可以直接復(fù)制粘貼運行,否則,可能會遇到圖片畫錯位置的問題,請適當(dāng)調(diào)整
5.程序游戲中使用到的圖片最后,只需要按照圖片上的名字命名該圖片,并導(dǎo)入到程序的圖片資源中,就能順利運行本程序
代碼:
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; // 圖形當(dāng)前坐標 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; // 構(gòu)造方法 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) { // 通過發(fā)送消息更新界面 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);//設(shè)置字體大小 } 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; } } /***************計算分數(shù)************************/ for(c=0;c<3;c++) { if(pillar[c].x==100) point++; } /****************地面移動***********************/ a-=SPEED; /****************判斷碰撞,+32判斷下側(cè)柱子,-170判斷上側(cè)柱子***********************/ 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) { /*******************顯示分數(shù)**********************/ Paint p1 = new Paint(); p1.setAntiAlias(true); p1.setColor(Color.WHITE); p1.setTextSize(20);//設(shè)置字體大小 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);//設(shè)置字體大小 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
以上是“Java如何實現(xiàn)Flappy Bird游戲”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!