自定義控件(游戲)之一憤怒的小鳥

最終效果:

2017-09-20-02mzFfff.gif

思路:
1.先畫柱子
2.在畫小鳥,而小鳥的Y坐標始終在屏幕的中間,點擊更改小鳥的X坐標
3.當柱子X的左邊小于小鳥的X而右邊大于小鳥的X就代表小鳥正在經(jīng)過該柱子
4.加入碰撞機制

畫柱子:

      柱子是在屏幕中間最大次數(shù)會出現(xiàn)2次,所以需要一個集合來存儲最大畫柱子的個數(shù),當柱子的X為0時就代表柱子已經(jīng)超出屏幕之外直接移除,當移除之后緊接著加入一個新柱子,柱子分為上柱 和 下柱,

代碼(部分):

 public void startTopAndBoom(boolean isStart) {


        DataBean dataBean = new DataBean();


        dataBean.topTopX = 0;
        dataBean.topLiftX = this.getRight();
        dataBean.topRightX = this.getRight() + 200;

        //下邊的舉行
        dataBean.boomBoomX = this.getBottom();
        Log.e("startTopAndBoom", "onLayout: " + this.getBottom());
        dataBean.boomLiftX = this.getRight();
        dataBean.boomRightX = this.getRight() + 200;

        dataBean.topLiftX = getRight();
        dataBean.topRightX = getRight() + 200;

        dataBean.boomLiftX = getRight();
        dataBean.boomRightX = getRight() + 200;

        if (!isStart)
            if (arr.size() == 0)
                arr.add(dataBean);


        if (isStart)
            arr.add(dataBean);
        ran = new Random();
        int Y = ran.nextInt(this.getBottom());

        Log.e("---", "startTopAndBoom: " + Y);
        if (Y < (this.getBottom() - 500)) {
            dataBean.topBoomX = Y - 500;
            dataBean.boomTopX = Y;
            // Log.e("----", "上邊矩形的下 " + topBoomX + "----" + "下邊矩形的上" + boomTopX);
        } else if (Y < 500) {
            dataBean.topBoomX = 0;
            dataBean.boomTopX = 500;
        } else {
            dataBean.topBoomX = this.getBottom() - 500;
            dataBean.boomTopX = this.getBottom();

        }


    }

全部代碼

package com.example.downlist.view;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import com.example.downlist.utils.UIUtlis;

import java.util.ArrayList;
import java.util.Random;

/**
 * 憤路的小鳥
 */

public class XiaoNiaoView extends ViewGroup implements View.OnClickListener {


    private boolean isStart = false;
    ArrayList<DataBean> arr = new ArrayList<>();

    private int niao = 400;

    private int boomX = this.getBottom(); //矩形的下邊

    private Paint paint;
    private Random ran;
    //判斷有沒有掛
    private boolean isLift = true;

    //控制線程速度
    private int threadGo = 5;

    //上下落標記
    private boolean isUp = false;

    //最終落下的速度
    private int luoxia = 0;
    //小鳥左邊
    private int nLift;
    //小鳥右邊
    private int nRight;
    //積分器
    private int count;
    //點擊次數(shù)
    private int thCount = 0;

    public XiaoNiaoView(Context context) {
        super(context);
        drawRect();
        startNiao();
    }

    public XiaoNiaoView(Context context, AttributeSet attrs) {
        super(context, attrs);
        drawRect();
        startNiao();
    }

    public XiaoNiaoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        drawRect();
        startNiao();

    }

    @Override
    protected void onLayout(boolean b, int i, int i1, int i2, int i3) {

        nLift = (this.getRight() / 2) + 80;
        nRight = (this.getRight() / 2) - 80;
        startTopAndBoom(false);

        this.setOnClickListener(this);


    }

    public void startTopAndBoom(boolean isStart) {


        DataBean dataBean = new DataBean();


        dataBean.topTopX = 0;
        dataBean.topLiftX = this.getRight();
        dataBean.topRightX = this.getRight() + 200;

        //下邊的舉行
        dataBean.boomBoomX = this.getBottom();
        Log.e("startTopAndBoom", "onLayout: " + this.getBottom());
        dataBean.boomLiftX = this.getRight();
        dataBean.boomRightX = this.getRight() + 200;

        dataBean.topLiftX = getRight();
        dataBean.topRightX = getRight() + 200;

        dataBean.boomLiftX = getRight();
        dataBean.boomRightX = getRight() + 200;

        if (!isStart)
            if (arr.size() == 0)
                arr.add(dataBean);


        if (isStart)
            arr.add(dataBean);
        ran = new Random();
        int Y = ran.nextInt(this.getBottom());

        Log.e("---", "startTopAndBoom: " + Y);
        if (Y < (this.getBottom() - 500)) {
            dataBean.topBoomX = Y - 500;
            dataBean.boomTopX = Y;
            // Log.e("----", "上邊矩形的下 " + topBoomX + "----" + "下邊矩形的上" + boomTopX);
        } else if (Y < 500) {
            dataBean.topBoomX = 0;
            dataBean.boomTopX = 500;
        } else {
            dataBean.topBoomX = this.getBottom() - 500;
            dataBean.boomTopX = this.getBottom();

        }


    }

    //操控小鳥線程

    public void startNiao() {
        UIUtlis.runOnThread(new Runnable() {
            @Override
            public void run() {
                while (isLift) {


                    try {
                        Thread.sleep(threadGo);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    if (isUp) {
                        niao -= 3;

                        if (niao < luoxia) {
                            isUp = false;
                            threadGo = 5;
                        }

                    } else {
                        niao += 3;
                    }


                }
            }
        });
    }

    //線程專門畫上下矩形的

    public void drawRect() {
        paint = new Paint();
        setWillNotDraw(false);
        invalidate();

        // Log.e("----", "drawRect: " + "----" );
        UIUtlis.runOnThread(new Runnable() {
            @Override
            public void run() {
                while (isLift) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    for (int i = 0; i < arr.size(); i++) {
                        arr.get(i).topLiftX -= 2;
                        arr.get(i).topRightX -= 2;

                        arr.get(i).boomLiftX -= 2;
                        arr.get(i).boomRightX -= 2;

                        if (arr.get(i).topLiftX == 100 || arr.get(i).topLiftX == 101) {


                            UIUtlis.runOnUIThread(new Runnable() {
                                @Override
                                public void run() {
                                    startTopAndBoom(true);
                                }
                            });


                        }

                        if (arr.get(i).topLiftX <= -200) {
                            arr.remove(i);
                        }
                    }


                    UIUtlis.runOnUIThread(new Runnable() {
                        @Override
                        public void run() {
                            invalidate();
                        }
                    });
                }
            }
        });
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.parseColor("#123456"));
        paint.setAntiAlias(true);
        paint.setTextSize(50);
        canvas.drawText("當前得分:" + count, 60, 60, paint);
        canvas.drawText("點擊次數(shù):" + thCount, 60, 100, paint);
        for (int i = 0; i < arr.size(); i++) {

            if (!(arr.get(i).isColor)) {
                paint.setColor(Color.parseColor("#123456"));
                //畫上邊的矩形
                canvas.drawRect(arr.get(i).topLiftX, arr.get(i).topTopX, arr.get(i).topRightX, arr.get(i).topBoomX, paint);
                //Log.e("----", "run: " + arr.get(i).topLiftX + "----" + arr.get(i).topRightX);
                //畫下邊矩形
                canvas.drawRect(arr.get(i).boomLiftX, arr.get(i).boomTopX, arr.get(i).boomRightX, arr.get(i).boomBoomX, paint);
                paint.setTextSize(20);
                paint.setColor(Color.parseColor("#ffffff"));
                canvas.drawText("上:" + arr.get(i).topBoomX, arr.get(i).topLiftX, arr.get(i).topBoomX, paint);

                if (arr.get(i).boomTopX > 400) {
                    paint.setColor(Color.parseColor("#ffffff"));
                    canvas.drawText("下:" + arr.get(i).boomTopX, arr.get(i).topLiftX, arr.get(i).boomTopX + 60, paint);
                } else {
                    paint.setColor(Color.parseColor("#ffffff"));
                    canvas.drawText("異常柱子:" + arr.get(i).boomTopX, arr.get(i).topLiftX, arr.get(i).boomTopX + 60, paint);
                }

                if (arr.get(i).boomTopX > 400) {
                    paint.setColor(Color.parseColor("#ffffff"));
                    canvas.drawText("當前位置:" + arr.get(i).topLiftX, arr.get(i).topLiftX, arr.get(i).boomTopX + 120, paint);
                } else {
                    paint.setColor(Color.parseColor("#ffffff"));
                    canvas.drawText("當前位置:" + arr.get(i).topLiftX, arr.get(i).topLiftX, arr.get(i).boomTopX + 120, paint);
                }

            } else {
                paint.setColor(Color.parseColor("#0000ff"));
                //畫上邊的矩形
                canvas.drawRect(arr.get(i).topLiftX, arr.get(i).topTopX, arr.get(i).topRightX, arr.get(i).topBoomX, paint);
                //Log.e("----", "run: " + arr.get(i).topLiftX + "----" + arr.get(i).topRightX);
                //畫下邊矩形
                canvas.drawRect(arr.get(i).boomLiftX, arr.get(i).boomTopX, arr.get(i).boomRightX, arr.get(i).boomBoomX, paint);
                paint.setTextSize(20);
                paint.setColor(Color.parseColor("#ffffff"));
                canvas.drawText("上:" + arr.get(i).topBoomX, arr.get(i).topLiftX, arr.get(i).topBoomX, paint);

                if (arr.get(i).boomTopX > 400) {
                    paint.setColor(Color.parseColor("#ffffff"));
                    canvas.drawText("下:" + arr.get(i).boomTopX, arr.get(i).topLiftX, arr.get(i).boomTopX + 60, paint);
                } else {
                    paint.setColor(Color.parseColor("#ffffff"));
                    canvas.drawText("異常柱子:" + arr.get(i).boomTopX, arr.get(i).topLiftX, arr.get(i).boomTopX + 60, paint);
                }
                if (arr.get(i).boomTopX > 400) {
                    paint.setColor(Color.parseColor("#ffffff"));
                    canvas.drawText("當前位置:" + arr.get(i).topLiftX, arr.get(i).topLiftX, arr.get(i).boomTopX + 120, paint);
                } else {
                    paint.setColor(Color.parseColor("#ffffff"));
                    canvas.drawText("當前位置:" + arr.get(i).topLiftX, arr.get(i).topLiftX, arr.get(i).boomTopX + 120, paint);
                }
            }
        }


        //開始畫小鳥


        canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), android.R.mipmap.sym_def_app_icon), this.getRight() / 2, niao, paint);
        paint.setColor(Color.parseColor("#ad0015"));
        canvas.drawText("小鳥位置: X:" + niao + " Y :", this.getRight() / 2, niao + 100, paint);

        if (!isLift) {
            paint.setTextSize(100);
            paint.setColor(Color.parseColor("#000000"));
            canvas.drawText("你掛了!", getWidth() / 2 - 100, this.getRight() / 2, paint);
        } else {
            canvas.drawText("", getWidth() / 2 - 100, this.getRight() / 2, paint);
        }


        ifDied();
    }


    @Override
    public void onClick(View view) {

        luoxia = niao - 150;
        threadGo = 2;
        isUp = true;
        thCount++;
    }


    //判斷小鳥越界死亡
    private void ifDied() {


        if (niao < -1 || niao > this.getBottom()) {
            isLift = false;
        }

        for (int i = 0; i < arr.size(); i++) {

            if (arr.get(i).boomLiftX == nLift || arr.get(i).boomLiftX == nLift + 1 || arr.get(i).boomLiftX == nLift + 2) {
                count++;
            }

            if (arr.get(i).boomLiftX < (nLift) && arr.get(i).boomRightX > (nRight + 30)) {
                Log.e("---", "ifDied: " + "小鳥正在經(jīng)過" + "小鳥坐標:" + nLift + "  矩形左:" + arr.get(i).boomLiftX + "矩形右:" + arr.get(i).boomRightX);
                arr.get(i).isColor = true;


                if (niao < arr.get(i).topBoomX || niao > arr.get(i).boomTopX) {
                    if (arr.get(i).boomTopX > 500) {
                        isLift = false;
                    }

                }


            } else {
                arr.get(i).isColor = false;
            }

        }

    }

}

希望該代碼對你的自定義控件有所啟發(fā) 0.0

---XINHAO_HAN

如果那塊有不懂得請聯(lián)我喲...0.0 哈哈

使用 --直接加入布局就可以了

<?xml version="1.0" encoding="utf-8"?>
<com.example.downlist.view.XiaoNiaoView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mySheView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


   
</com.example.downlist.view.XiaoNiaoView>

Demo下載:
鏈接: https://pan.baidu.com/s/1i5P6WML 密碼: 3283

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末刀疙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子兑凿,更是在濱河造成了極大的恐慌芜抒,老刑警劉巖赤赊,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異吵血,居然都是意外死亡,警方通過查閱死者的電腦和手機偷溺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門蹋辅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人挫掏,你說我怎么就攤上這事侦另。” “怎么了尉共?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵褒傅,是天一觀的道長。 經(jīng)常有香客問我袄友,道長殿托,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任剧蚣,我火速辦了婚禮支竹,結果婚禮上,老公的妹妹穿的比我還像新娘鸠按。我一直安慰自己礼搁,他們只是感情好,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布目尖。 她就那樣靜靜地躺著馒吴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瑟曲。 梳的紋絲不亂的頭發(fā)上募书,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天,我揣著相機與錄音测蹲,去河邊找鬼莹捡。 笑死,一個胖子當著我的面吹牛扣甲,可吹牛的內(nèi)容都是我干的篮赢。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼琉挖,長吁一口氣:“原來是場噩夢啊……” “哼启泣!你這毒婦竟也來了?” 一聲冷哼從身側響起示辈,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤寥茫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后矾麻,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纱耻,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡芭梯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了弄喘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片玖喘。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蘑志,靈堂內(nèi)的尸體忽然破棺而出累奈,到底是詐尸還是另有隱情,我是刑警寧澤急但,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布澎媒,位于F島的核電站,受9級特大地震影響波桩,放射性物質發(fā)生泄漏戒努。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一突委、第九天 我趴在偏房一處隱蔽的房頂上張望柏卤。 院中可真熱鬧,春花似錦匀油、人聲如沸缘缚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽桥滨。三九已至,卻和暖如春弛车,著一層夾襖步出監(jiān)牢的瞬間齐媒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工纷跛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留喻括,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓贫奠,卻偏偏與公主長得像唬血,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子唤崭,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,515評論 25 707
  • ¥開啟¥ 【iAPP實現(xiàn)進入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程拷恨,因...
    小菜c閱讀 6,358評論 0 17
  • 【文|霖霆】 又到年底了,李大娘最近幾天都不怎么出門谢肾,不為別的腕侄,就是為了等村支書送來扶貧款。 李大娘膝下無兒,只有...
    倉語亭閱讀 860評論 18 23
  • 期待冕杠, 我期待明媚的暖陽微姊, 陽光下的一隅, 一杯茶一本書拌汇, 時間從細碎的光線中柒桑, 悄然流逝…… 期待弊决, 我期待微醉...
    蒹葭essay閱讀 128評論 0 0
  • 火車到站噪舀,已經(jīng)接近午夜,盡管西北的天長飘诗,但也長不過地球的自轉与倡,大街上華燈已經(jīng)初上,出站口森嚴的安檢時不時抽查出站的...
    誰偷了螞蟻閱讀 293評論 0 0