自定义控件(游戏)之一愤怒的小鸟

最终效果:

2017-09-20-02mzFfff.gif

思路:
1.先画柱子
2.在画小鸟,而小鸟的Y坐标始终在屏幕的中间,点击更改小鸟的X坐标
3.当柱子X的左边小于小鸟的X而右边大于小鸟的X就代表小鸟正在经过该柱子
4.加入碰撞机制

画柱子:

      柱子是在屏幕中间最大次数会出现2次,所以需要一个集合来存储最大画柱子的个数,当柱子的X为0时就代表柱子已经超出屏幕之外直接移除,当移除之后紧接着加入一个新柱子,柱子分为上柱 和 下柱,

代码(部分):

 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;
    //点击次数
    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("点击次数:" + 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: " + "小鸟正在经过" + "小鸟坐标:" + 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;
            }

        }

    }

}

希望该代码对你的自定义控件有所启发 0.0

---XINHAO_HAN

如果那块有不懂得请联我哟...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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,699评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,124评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,127评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,342评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,356评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,057评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,654评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,572评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,095评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,205评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,343评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,015评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,704评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,196评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,320评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,690评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,348评论 2 358

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,245评论 25 707
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,440评论 0 17
  • 【文|霖霆】 又到年底了,李大娘最近几天都不怎么出门,不为别的,就是为了等村支书送来扶贫款。 李大娘膝下无儿,只有...
    仓语亭阅读 871评论 18 23
  • 期待, 我期待明媚的暖阳, 阳光下的一隅, 一杯茶一本书, 时间从细碎的光线中, 悄然流逝…… 期待, 我期待微醉...
    蒹葭essay阅读 135评论 0 0
  • 火车到站,已经接近午夜,尽管西北的天长,但也长不过地球的自转,大街上华灯已经初上,出站口森严的安检时不时抽查出站的...
    谁偷了蚂蚁阅读 299评论 0 0