为什么没有分享源代码?因为不喜欢别人传播这份代码,也怕被抄袭。
最近工作比较少,一直忙于2D地图绘制,刚好自己没事,想写个游戏玩,小时候经常在游戏机上玩打砖块,所以接下来就用canvas绘图实现一个打砖块游戏,部分代码以及思路供大家参考:
首先打砖块需求要理清:底板发出小球,通过撞击砖块得分,每次底板接住小球,继续反射撞击砖块。
知道需求后,接下来梳理代码设计思路:
1.画出底板,在固定高度上随着手势只能横向运动;
代码使用:canvas的drawline方法,需要在onTouchEvent()中记录出手指的x值,然后根据x值绘制底板
2.画砖块,砖块可以定义一个二维数组来填充以及判断是否显示,颜色可以在初始化的时候,随机设定。
代码使用:可以定义砖块class,包含是否显示和color两个参数,然后定义10*10二维数组,在init()是否,Math.random()方法随机显示以及匹配颜色。然后使用Paint.setColor设置颜色,根据砖块index以及高宽度,使用canvas.drawRect()绘制出砖块
3.画小球,刚开始需要将小球固定在底板中间,手指按下横向拖动底板,小球也要随底板运动,这里需要对左右屏幕边界进行判断处理,当手指抬起,小球默认以某一角度发射,然后通过在左右上三个边界反射返回底板,然后底板接住小球弹射循环,否则底板没接住停止弹射。
4.小球与底板接触后,需要有一个停留时间,这段时间小球随底板运动改变整个x值,并且小球反射角度根据底板的运动速率而发生变化。这段时间结束,小球重新以一个新角度弹起。
5.小球触碰砖块:这块逻辑是比较有趣的,例如:当小球碰到砖块的下边,需要小球弹回,当小球碰到砖块左边,需要小球弹射到右边,所以这个时候,上下左右边界需要定义为变量,随着弹射而改变,当计算小球碰到砖块左边,则砖块的左边为右边界,然后计算小球的弹射角度及方向,还有隐藏砖块。
3.4.5步代码如下
/**
* 画出运动的小球球哦
*
* @param canvas
*/
private void drawBall(Canvas canvas) {
if (isRefresh) {
mRunX = RUN_DISTANCE * Math.cos(Math.toRadians(mBallDegree));// 小球横向运动距离
mRunY = RUN_DISTANCE * Math.sin(Math.toRadians(mBallDegree));// 小球纵向运动距离
mBallX += mRunX;// 小球x坐标
mBallY -= mRunY;// 小球y坐标
for (int i = 0; i < mBrick.length; i++) {// 判断小球是否碰撞砖块
boolean isCrash = false;
for (int j = 0; j < mBrick[i].length; j++) {
if (mBrick[i][j] == 1) {
float x1 = i * (float) mBrickWidth;// 砖块左边坐标
float x2 = (i + 1) * (float) mBrickWidth;// 砖块右边坐标
float y1 = j * BRICK_HEIGHT;// 砖块上边坐标
float y2 = (j + 1) * BRICK_HEIGHT;// 砖块下边坐标
double ballTopX = mBallX, ballTopY = mBallY// 小球上边坐标
- BALL_RADIUS;
if (ballTopX > x1 && ballTopX < x2 && ballTopY > y1
&& ballTopY < y2) {// 小球碰到砖块下边
mBoundTop = y2;// 上边界变为砖块下坐标
isCrash = true;// 撞上了
mBrick[i][j] = 0;// 砖块消失
break;
}
double ballBottomX = mBallX, ballBottomY = mBallY
+ BALL_RADIUS;// 小球下边坐标
if (ballBottomX > x1 && ballBottomX < x2
&& ballBottomY > y1 && ballBottomY < y2) {// 小球碰到砖块上边
mBoundBottom = y1;
isCrash = true;
mBrick[i][j] = 0;
break;
}
double ballLeft= mBallX - BALL_RADIUS, ballLeftY = mBallY;// 小球坐边坐标
if (ballLeft > x1 && ballLeft < x2 && ballLeftY > y1
&& ballLeftY < y2) {// 小球碰到砖块右边
mBoundLeft = x2;
isCrash = true;
mBrick[i][j] = 0;
break;
}
double ballRightX = mBallX + BALL_RADIUS, ballRightY = mBallY;
if (ballRightX > x1 && ballRightX < x2
&& ballRightY > y1 && ballRightY < y2) {// 小球碰到砖块左边
mBoundRight = x1;
isCrash = true;
mBrick[i][j] = 0;
break;
}
}
}
if (isCrash) {// 如果碰上了,则通知用户
if (onCrashBrickListener != null) {
onCrashBrickListener.onCrashBrick();
}
break;
}
}
if (!isSendMsg) {
if (mRunX > 0 && mRunY > 0) {// 小球运行方向为右上方
if (mBallX + BALL_RADIUS >= mBoundRight) {// 当小球运动接触到右边,则角度为180度翻转,并且需要将mBallX设置为宽度
mBallX = mBoundRight - BALL_RADIUS;
mBallDegree = 180 - mBallDegree;
}
if (mBallY - BALL_RADIUS <= mBoundTop) {// 当小球运动接触到上边,则角度镜像增加mBallDegree,并且需要mBallY设置为BALL_WIDTH
mBallY = mBoundTop + BALL_RADIUS;
mBallDegree = -mBallDegree;
}
}
if (mRunX < 0 && mRunY > 0) {// 运动方向为左上方
if (mBallY - BALL_RADIUS <= mBoundTop) {// 当小球已经接触到上边,则角度
mBallY = mBoundTop + BALL_RADIUS;
mBallDegree = -mBallDegree;
}
if (mBallX - BALL_RADIUS <= mBoundLeft) {// 当小球接触到左边
mBallX = mBoundLeft + BALL_RADIUS;
mBallDegree = 180 - mBallDegree;
}
}
if (mRunX > 0 && mRunY < 0) {// 小球运动方向为右下方
if (mBallX + BALL_RADIUS >= mBoundRight) {// 当小球接触到右边
mBallX = mBoundRight - BALL_RADIUS;
mBallDegree = 180 - mBallDegree;
}
if (mBallY + BALL_RADIUS >= mBoundBottom) {// 当小球接触到下边
mBallY = mBoundBottom - BALL_RADIUS;
mBallDegree = -mBallDegree;
}
}
if (mRunX < 0 && mRunY < 0) {// 运动方向为左下方
if (mBallX - BALL_RADIUS <= mBoundLeft) {// 当小球接触到左边
mBallX = mBoundLeft + BALL_RADIUS;
mBallDegree = -mBallDegree - 180;
}
if (mBallY + BALL_RADIUS >= mBoundBottom) {// 当小球接触到下边
mBallY = mBoundBottom - BALL_RADIUS;
mBallDegree = -mBallDegree;
}
}
mBallDegree = (mBallDegree + 360) % 360;// 将角度变为正值
}
if (mBallY == getHeight() - BOADR_HEIGHT - BOARD_LINE_HEIGHT / 2
- BALL_RADIUS) {// 如果小球在底边时候
if (mBallX > mBoardX - BOARD_WIDTH
&& mBallX < mBoardX + BOARD_WIDTH) {// 当小球碰搬,则接住了
isRefresh = false;// 此刻不要刷新
mSaveBoardX = mBoardX;
mSaveBallX = mBallX;
if (!isSendMsg) {
isSendMsg = true;
postDelayed(new Runnable() {// 延迟30毫秒,产生小球在底边接触时的移动效果
@Override
public void run() {
isRefresh = true;
isSendMsg = false;
mTracker.computeCurrentVelocity(30);
DTLog.i("横向速度:"
+ mTracker.getXVelocity()
+ " 角度: " + mBallDegree);
mBallDegree += mBallDegree
* mTracker.getXVelocity()
/ VELOCITY_MAX;// 根据速率计算小球改变的角度
if (mBallDegree >= 0
&& mBallDegree <= 10)
mBallDegree = 10;
if (mBallDegree >= 170
&& mBallDegree <= 180) {
mBallDegree = 170;
}
invalidate();
}
}, BALL_BOARD_STEP_TIME);
}
} else {
DTUIUtil.showToastSafe("没接住");
initValue();
}
}
}
initBallBound();//重新定义边界
canvas.drawCircle((float) mBallX, (float) mBallY, BALL_RADIUS, mPaint);//绘制小球
}
以上就是我的2D绘图板打砖块的思路以及部分代码