最終效果:
思路:
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