Android Canvas打飛機(jī)之主角秀

上一篇講過(guò)游戲背景圖的加載以及場(chǎng)景運(yùn)動(dòng)效果草姻,如果還需要了解的請(qǐng)<a href="http://www.reibang.com/p/a87a9ed6a8b2">移駕這里</a>
今天要研究的是游戲主角戰(zhàn)機(jī)的運(yùn)動(dòng)以及邏輯的實(shí)現(xiàn)。

1.創(chuàng)建一個(gè)主角的類(lèi)DrawPlayer虑灰。

package com.tangyx.game.holder;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;

import com.tangyx.game.R;
import com.tangyx.game.util.BitmapUtils;
import com.tangyx.game.util.ScreenUtils;
import com.tangyx.game.util.SizeUtils;

/**
 * Created by tangyx on 2016/12/22.
 *
 */

public class DrawPlayer extends DrawGame {
    /**
     * 主角
     */
    private Bitmap mPlayer;
    private float mPlayerX;
    private float mPlayerY;
    /**
     * 主角的控制位置
     */
    private Bitmap mCollect;
    private float mCollectX;
    private float mCollectY;
    private int mCollectCount;
    private Paint mCollectPaint;
    /**
     * 尾氣噴氣
     */
    private Bitmap mPlayerBlow;
    private float mSpeedAngle=0.05f;
    private float mBlowAngle = 1;
    private Matrix mBlowMatrix;

    public DrawPlayer(Context context,int player) {
        super(context,player);
    }

    @Override
    void initialize(Object... objects) {
        mPlayer = BitmapUtils.ReadBitMap(getContext(), (Integer) objects[0]);
        int wh = SizeUtils.dp2px(getContext(),20);
        mPlayer = BitmapUtils.getBitmap(mPlayer,wh,wh);
        mPlayerBlow = BitmapUtils.ReadBitMap(getContext(), R.drawable.playblow0);
        mPlayerBlow = BitmapUtils.getBitmap(mPlayerBlow,wh,wh);
        mCollect = BitmapUtils.ReadBitMap(getContext(),R.drawable.collect);
        wh = SizeUtils.dp2px(getContext(),30);
        mCollect = BitmapUtils.getBitmap(mCollect,wh,wh);
        int screenW = ScreenUtils.getScreenWidth(getContext());
        int screenH = ScreenUtils.getScreenHeight(getContext());
        //初始化戰(zhàn)機(jī)的位置
        mPlayerX = screenW/2-mPlayer.getWidth()/2;
        mPlayerY = screenH-mPlayer.getHeight()-screenH/10;
        mCollectX = screenW/2-mCollect.getWidth()/2;
        mCollectY = mPlayerY+mPlayer.getHeight()+mCollect.getHeight()/2;
        mBlowMatrix = new Matrix();
        mCollectPaint = new Paint();
        mCollectPaint.setAntiAlias(true);
    }

    @Override
    void onDraw(Canvas canvas) {
        mPaint.setAlpha(255);
        canvas.drawBitmap(mPlayer,mPlayerX,mPlayerY,mPaint);
        canvas.drawBitmap(getBlowAnimation(), (mPlayerX-mPlayerBlow.getWidth()/4),mPlayerY+mPlayerBlow.getHeight()/1.5f,mPaint);
    }

    /**
     * 尾氣噴氣動(dòng)畫(huà)
     */
    private Bitmap getBlowAnimation(){
        mBlowAngle += mSpeedAngle;
        float sx =1.5f;
        float sy = mBlowAngle;
        mBlowMatrix.reset();
        mBlowMatrix.postScale(sx,sy);
        if(mBlowAngle>=1.2||mBlowAngle<1){
            mSpeedAngle=-mSpeedAngle;
        }
        return Bitmap.createBitmap(mPlayerBlow,0,0,mPlayerBlow.getWidth(),mPlayerBlow.getHeight(),mBlowMatrix,true);
    }

    /**
     * 繪制操作的位置按鈕
     */
    public void onDrawCollect(Canvas canvas,String text){
        if(mCollectCount==(Integer.MAX_VALUE-1)){
            mCollectCount=0;
        }
        mCollectPaint.setTextSize(20f);
        mCollectCount++;
        if(mCollectCount%2==0){
            mCollectPaint.setAlpha(0);
        }else{
            mCollectPaint.setAlpha(255);
        }
        mCollectX = mPlayerX-(mCollect.getWidth()-mPlayer.getWidth())/2;
        mCollectY = mPlayerY+mPlayer.getHeight()+mCollect.getHeight()/2;
        canvas.drawBitmap(mCollect,mCollectX,mCollectY,mCollectPaint);
        String fire = getContext().getString(R.string.fire);
        Rect rect = getTextRect(fire,mCollectPaint);
        float tx = mCollectX+(mCollect.getWidth()-rect.width())/2;
        float ty = mCollectY+mCollect.getHeight()/2+rect.height()/2;
        //點(diǎn)擊這個(gè)地方游戲繼續(xù)
        canvas.drawText(fire, tx, ty, mCollectPaint);
        int w = ScreenUtils.getScreenWidth(getContext());
        int h = ScreenUtils.getScreenHeight(getContext());
        mPaint.setTextSize(SizeUtils.sp2px(getContext(),20));
        //游戲暫停提示語(yǔ)
        rect = getTextRect(text,mPaint);
        canvas.drawText(text,(w-rect.width())/2 ,h/3, mPaint);
    }

    @Override
    void updateGame() {

    }

    public void setPlayerX(float mPlayerX) {
        this.mPlayerX = mPlayerX-mPlayer.getWidth()/1.5f;
    }

    public void setPlayerY(float mPlayerY) {
        this.mPlayerY = mPlayerY-mPlayer.getHeight() * 2.5f;
    }

    public float getCollectX() {
        return mCollectX;
    }

    public float getCollectY() {
        return mCollectY;
    }


    public Bitmap getCollect() {
        return mCollect;
    }
}

主角戰(zhàn)機(jī)組成部分:飛機(jī)+尾部噴氣+手指操作按鈕钝凶。
1.戰(zhàn)機(jī)部分就跟簡(jiǎn)單,默認(rèn)開(kāi)始坐標(biāo)在屏幕底部中心位置甫何。

Paste_Image.png
canvas.drawBitmap(mPlayer,mPlayerX,mPlayerY,mPaint);

2.因?yàn)槭菓?zhàn)機(jī)出吹,肯定需要尾部火焰噴氣效果嘛,不然不夠炫辙喂。
火焰的位置就是位于戰(zhàn)機(jī)的尾部捶牢,所以前面繪制完成戰(zhàn)機(jī)以后鸠珠,通過(guò)得到戰(zhàn)機(jī)的x,y計(jì)算出噴氣的位置秋麸。

canvas.drawBitmap(getBlowAnimation(), (mPlayerX-mPlayerBlow.getWidth()/4),mPlayerY+mPlayerBlow.getHeight()/1.5f,mPaint);

其中有一個(gè)getBlowAnimation的方法渐排,通過(guò)它實(shí)時(shí)更改火焰圖片的高度來(lái)給人一種噴射的感覺(jué)。

Paste_Image.png

其中主要是通過(guò)Matrix類(lèi)來(lái)完成一些特效灸蟆,這個(gè)類(lèi)也是非常非常非常的重要驯耻,在<a >官網(wǎng)</a>有詳細(xì)的介紹,可自行查看炒考。
3.戰(zhàn)機(jī)是通過(guò)我們用手按住屏幕來(lái)移動(dòng)可缚,所以我們需要提供一個(gè)可操控的位置,操控的位置也是一張圖片斋枢,它的位置一直緊隨著噴氣的底部帘靡,而噴氣是緊隨戰(zhàn)機(jī),所以操作動(dòng)作就是去移動(dòng)戰(zhàn)機(jī)在屏幕的位置瓤帚。

Paste_Image.png

操作按鈕中心就是一個(gè)FIRE的字體描姚,字體和按鈕通過(guò)<a >Paint</a>設(shè)置透明度的變化產(chǎn)生一個(gè)閃爍的效果,并且手離開(kāi)屏幕的時(shí)候操作按鈕就會(huì)出現(xiàn)戈次,并且提示游戲狀態(tài)以及下一步操作轩勘,手按下屏幕的時(shí)候就按鈕就會(huì)消失并且游戲繼續(xù)。

device-2016-12-23-105428.png

---------我是分割線(xiàn)----------
這里只是把戰(zhàn)機(jī)繪制出來(lái)朝扼,那怎么讓?xiě)?zhàn)機(jī)跟隨我的手指運(yùn)動(dòng)呢赃阀?
回到<b>GameView</b>類(lèi),既然是手勢(shì)操作擎颖,你想到的是什么榛斯?我想到就是實(shí)現(xiàn)onTouchEvent。
1.暫時(shí)給游戲定義三個(gè)狀態(tài)

Paste_Image.png

2.默認(rèn)是游戲加載到可操作狀態(tài)READY搂捧。
當(dāng)游戲可以操作的時(shí)候驮俗,這時(shí)候把手放到操作按鈕的位置(上圖的白色圓圈),就可以變更游戲狀態(tài)為ING允跑。點(diǎn)擊其他位置不做任何變化王凑。

Paste_Image.png

3.手指移動(dòng)變更戰(zhàn)機(jī)的位置x,y聋丝。

Paste_Image.png

4.手離開(kāi)屏幕索烹,游戲進(jìn)入暫停狀態(tài)。

Paste_Image.png

5.在GameView的onGameDraw方法中調(diào)用主角繪制弱睦。

/**
     * 繪制內(nèi)容以及更新內(nèi)容
     */
    private void onGameDraw(){
        if(mCanvas==null)return;
        mCanvas.drawColor(Color.WHITE);
        //背景
        mDrawBackground.onDraw(mCanvas);
        mDrawBackground.updateGame();
        //主角
        mPlayer.onDraw(mCanvas);
        mPlayer.updateGame();
        //判斷當(dāng)前游戲狀態(tài)
        switch (GAME_STATE){
            case ING:
                break;
            case READY:
                mPlayer.onDrawCollect(mCanvas,getContext().getString(R.string.reading));
                break;
            case PAUSE:
                mPlayer.onDrawCollect(mCanvas,getContext().getString(R.string.conution));
                break;
        }
    }```



![player.gif](http://upload-images.jianshu.io/upload_images/3982371-222c5de5c612988b.gif?imageMogr2/auto-orient/strip)

主角戰(zhàn)機(jī)的核心思路就是以上部分百姓,最后是提供持續(xù)更新的源碼。
<a >源碼傳送門(mén)</a>

<a href="http://www.reibang.com/p/a87a9ed6a8b2">上一篇</a>     <a href="http://www.reibang.com/p/966a3e9d8bdf">下一篇</a>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末况木,一起剝皮案震驚了整個(gè)濱河市垒拢,隨后出現(xiàn)的幾起案子旬迹,更是在濱河造成了極大的恐慌,老刑警劉巖求类,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奔垦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡尸疆,警方通過(guò)查閱死者的電腦和手機(jī)椿猎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)仓技,“玉大人鸵贬,你說(shuō)我怎么就攤上這事〔蹦恚” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵兆衅,是天一觀(guān)的道長(zhǎng)地沮。 經(jīng)常有香客問(wèn)我,道長(zhǎng)羡亩,這世上最難降的妖魔是什么摩疑? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮畏铆,結(jié)果婚禮上雷袋,老公的妹妹穿的比我還像新娘。我一直安慰自己辞居,他們只是感情好楷怒,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著瓦灶,像睡著了一般鸠删。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贼陶,一...
    開(kāi)封第一講書(shū)人閱讀 49,764評(píng)論 1 290
  • 那天刃泡,我揣著相機(jī)與錄音,去河邊找鬼碉怔。 笑死烘贴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的撮胧。 我是一名探鬼主播桨踪,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼趴樱!你這毒婦竟也來(lái)了馒闷?” 一聲冷哼從身側(cè)響起酪捡,我...
    開(kāi)封第一講書(shū)人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纳账,沒(méi)想到半個(gè)月后逛薇,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疏虫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年永罚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卧秘。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡呢袱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出翅敌,到底是詐尸還是另有隱情羞福,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布蚯涮,位于F島的核電站治专,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏遭顶。R本人自食惡果不足惜张峰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望棒旗。 院中可真熱鬧喘批,春花似錦、人聲如沸铣揉。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)老速。三九已至粥喜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間橘券,已是汗流浹背额湘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旁舰,地道東北人锋华。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像箭窜,于是被迫代替她去往敵國(guó)和親毯焕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,744評(píng)論 25 707
  • 上一篇的主角已經(jīng)登場(chǎng),如果你還沒(méi)見(jiàn)過(guò)纳猫,可以通過(guò)這里進(jìn)行查看 主角秀 主角登場(chǎng)沒(méi)有武器是不行的婆咸,所以這一篇的核心就是...
    Galaxy北愛(ài)閱讀 987評(píng)論 0 8
  • 上一篇 實(shí)現(xiàn)了主角打中敵機(jī),敵機(jī)死亡并且顯示爆炸效果芜辕,今天這里主要來(lái)實(shí)現(xiàn)主角被敵機(jī)碰撞以及被敵機(jī)子彈打中的效果和邏...
    Galaxy北愛(ài)閱讀 556評(píng)論 0 4
  • 上一篇文章已經(jīng)是去年的事情了尚骄,去年我們把主角和敵機(jī)都已經(jīng)完美的繪制到了畫(huà)布,并且做了對(duì)應(yīng)的移動(dòng)動(dòng)畫(huà)和手勢(shì)操作效果侵续,...
    Galaxy北愛(ài)閱讀 582評(píng)論 0 6
  • “結(jié)盟倔丈!”短短幾秒就有了一個(gè)私聊群∽次希可能是看《奔跑吧》多了需五。 別人都三人為伍,突然蹦出一大叔求帶轧坎,想想宏邮,我們隊(duì)沒(méi)男...
    晨曦晨語(yǔ)閱讀 305評(píng)論 0 1