最终效果:
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