先放上成品图:
思路如下:
1.使用的是画布,画出来四个矩形。一个到处滚动的圆球。
2.看下面的图片就知道碰撞检测的原理了,安卓中的X,Y轴如同java中的一样。
3.再将矩形分为8块区域,分别与小球进行检测(方法很笨),但是很有效。
4.一共三个界面(开始游戏界面,选择关卡界面,游戏界面),一共三个Intent,选择关卡中的按钮不可见使用setEnabled(false);
附上游戏界面代码TestHit:
package com.example.administrator.mygame;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
public class TestHit extends View implements Runnable {
int ball_x, ball_y, ball_r, left, top, right, bottom;
int table_l,table_r,table_t,table_b;
int left2,top2,right2,bottom2;
int left3,top3,right3,bottom3;
int offsetX = 5; // 圆移动的X步长
int offsetY = 5; // 圆移动的Y步长
boolean panduan=true;
private Paint paint_Ball, paint_Rect,paint_Table;
public TestHit(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public TestHit(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TestHit(Context context) {
super(context);
init();
}
/**
* 初始化数据
*/
private void init() {
ball_x = 770; // 圆心的X
ball_y = 2000; // 圆心的Y
ball_r = 20; // 圆的半径(半径要大于移动的步长)
left = 180;
top = 320;
right = 300;
bottom = 480;
table_l=560;
table_r=860;
table_t=2100;
table_b=2150;
left2 = 500;
top2 = 680;
right2 = 600;
bottom2 = 900;
left3 = 800;
top3 = 1080;
right3 = 1000;
bottom3 = 1250;
paint_Ball = new Paint();
paint_Ball.setAntiAlias(true);
paint_Ball.setColor(0xfff444f4);
paint_Rect = new Paint();
paint_Rect.setColor(0xff220066);
paint_Table=new Paint();
paint_Table.setColor(0xffdc143c);
new Thread(this).start();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 画圆
canvas.drawCircle(ball_x, ball_y, ball_r, paint_Ball);
// 画矩形
canvas.drawRect(left, top, right, bottom, paint_Rect);
paint_Rect.setColor(0xffafeeee);
canvas.drawRect(left2,top2,right2,bottom2,paint_Rect);
paint_Rect.setColor(0xff006400);
canvas.drawRect(left3,top3,right3,bottom3,paint_Rect);
Rect rect = new Rect(table_l,table_t,table_r,table_b);
canvas.drawRect(rect,paint_Table);
}
@Override
public void run() {
try {
while (panduan) {
Thread.sleep(10);
ball_x += offsetX;
ball_y += offsetY;
// 判断圆和屏幕四周的碰撞
if(ball_y + ball_r >= 2110){
panduan=false;
}
hitAround();
// 判断圆和矩形的碰撞
hitRect();
hitRect2();
hitRect3();
hitRect4();
postInvalidate(); // 刷新
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 判断圆和屏幕四周的碰撞
*/
private void hitAround() {
if (ball_x - ball_r <= 0 || ball_x + ball_r >= 1440) { // 判断和左右两边的碰撞
offsetX *= -1; // 反弹
}
if (ball_y - ball_r <= 0 || ball_y + ball_r >= 2150) { // 判断和上下两边的碰撞
offsetY *= -1; // 反弹
}
}
public void s(){
new Thread(this).start();
}
/**
* 判断圆和矩形的碰撞
*/
private void hitRect() {
// 球在1,3区域的碰撞判断
if (ball_x >= left && ball_x <= right) {
if (ball_y + ball_r >= top && ball_y < top) { // 1区域判断
offsetY *= -1;
top+=20;
bottom+=20;
} else if (ball_y - ball_r <= bottom && ball_y > bottom) { // 3区域判断
offsetY *= -1;
top-=20;
bottom-=20;
}
}
// 球在2,4区域的碰撞判断
if (ball_y >= top && ball_y <= bottom) {
if (ball_x - ball_r <= right && ball_x > right) { // 2区域判断
offsetX *= -1;
left-=10;
right-=10;
} else if (ball_x + ball_r >= left && ball_x < left) { // 4区域判断
offsetX *= -1;
left+=10;
right+=10;
}
}
// 圆在5区域的碰撞判断
if (Math.pow(left - ball_x, 2) + Math.pow(top - ball_y, 2) <= Math.pow(
ball_r, 2) && ball_x < left && ball_y < top) {
offsetX *= -1;
offsetY *= -1;
left+=10;
top+=20;
bottom+=20;
right+=10;
}
// 圆在6区域的碰撞判断
if (Math.pow(ball_x - right, 2) + Math.pow(top - ball_y, 2) <= Math
.pow(ball_r, 2) && ball_x > right && ball_y < top) {
offsetX *= -1;
offsetY *= -1;
left-=10;
top+=20;
bottom+=20;
right-=10;
}
// 圆在7区域的碰撞判断
if (Math.pow(ball_x - right, 2) + Math.pow(ball_y - bottom, 2) <= Math
.pow(ball_r, 2) && ball_x > right && ball_y > bottom) {
offsetX *= -1;
offsetY *= -1;
left-=10;
top-=20;
bottom-=20;
right-=10;
}
// 圆在8区域的碰撞判断
if (Math.pow(left - ball_x, 2) + Math.pow(ball_y - bottom, 2) <= Math
.pow(ball_r, 2) && ball_x < left && ball_y > bottom) {
offsetX *= -1;
offsetY *= -1;
left+=10;
top-=20;
bottom-=20;
right+=10;
}
}
private void hitRect2() {
// 球在1区域的碰撞判断
if (ball_x >= table_l && ball_x <= table_r) {
if (ball_y + ball_r >= table_t && ball_y < table_t) { // 1区域判断
offsetY *= -1;
}
}
}
private void hitRect3() {
// 球在1,3区域的碰撞判断
if (ball_x >= left2 && ball_x <= right2) {
if (ball_y + ball_r >= top2 && ball_y < top2) { // 1区域判断
offsetY *= -1;
top2+=20;
bottom2+=20;
} else if (ball_y - ball_r <= bottom2 && ball_y > bottom2) { // 3区域判断
offsetY *= -1;
top2-=20;
bottom2-=20;
}
}
// 球在2,4区域的碰撞判断
if (ball_y >= top2 && ball_y <= bottom2) {
if (ball_x - ball_r <= right2 && ball_x > right2) { // 2区域判断
offsetX *= -1;
left2-=10;
right2-=10;
} else if (ball_x + ball_r >= left2 && ball_x < left2) { // 4区域判断
offsetX *= -1;
left2+=10;
right2+=10;
}
}
// 圆在5区域的碰撞判断
if (Math.pow(left2 - ball_x, 2) + Math.pow(top2 - ball_y, 2) <= Math.pow(
ball_r, 2) && ball_x < left2 && ball_y < top2) {
offsetX *= -1;
offsetY *= -1;
left2+=10;
top2+=20;
bottom2+=20;
right2+=10;
}
// 圆在6区域的碰撞判断
if (Math.pow(ball_x - right2, 2) + Math.pow(top2 - ball_y, 2) <= Math
.pow(ball_r, 2) && ball_x > right2 && ball_y < top2) {
offsetX *= -1;
offsetY *= -1;
left2-=10;
top2+=20;
bottom2+=20;
right2-=10;
}
// 圆在7区域的碰撞判断
if (Math.pow(ball_x - right2, 2) + Math.pow(ball_y - bottom2, 2) <= Math
.pow(ball_r, 2) && ball_x > right2 && ball_y > bottom2) {
offsetX *= -1;
offsetY *= -1;
left2-=10;
top2-=20;
bottom2-=20;
right2-=10;
}
// 圆在8区域的碰撞判断
if (Math.pow(left2 - ball_x, 2) + Math.pow(ball_y - bottom2, 2) <= Math
.pow(ball_r, 2) && ball_x < left2 && ball_y > bottom2) {
offsetX *= -1;
offsetY *= -1;
left2+=10;
top2-=20;
bottom2-=20;
right2+=10;
}
}
private void hitRect4() {
// 球在1,3区域的碰撞判断
if (ball_x >= left3 && ball_x <= right3) {
if (ball_y + ball_r >= top3 && ball_y < top3) { // 1区域判断
offsetY *= -1;
top3+=20;
bottom3+=20;
} else if (ball_y - ball_r <= bottom3 && ball_y > bottom3) { // 3区域判断
offsetY *= -1;
top3-=20;
bottom3-=20;
}
}
// 球在2,4区域的碰撞判断
if (ball_y >= top3 && ball_y <= bottom3) {
if (ball_x - ball_r <= right3 && ball_x > right3) { // 2区域判断
offsetX *= -1;
left3-=10;
right3-=10;
} else if (ball_x + ball_r >= left3 && ball_x < left3) { // 4区域判断
offsetX *= -1;
left3+=10;
right3+=10;
}
}
// 圆在5区域的碰撞判断
if (Math.pow(left3 - ball_x, 2) + Math.pow(top3 - ball_y, 2) <= Math.pow(
ball_r, 2) && ball_x < left3 && ball_y < top3) {
offsetX *= -1;
offsetY *= -1;
left3+=10;
top3+=20;
bottom3+=20;
right3+=10;
}
// 圆在6区域的碰撞判断
if (Math.pow(ball_x - right3, 2) + Math.pow(top3 - ball_y, 2) <= Math
.pow(ball_r, 2) && ball_x > right3 && ball_y < top3) {
offsetX *= -1;
offsetY *= -1;
left3-=10;
top3+=20;
bottom3+=20;
right3-=10;
}
// 圆在7区域的碰撞判断
if (Math.pow(ball_x - right3, 2) + Math.pow(ball_y - bottom3, 2) <= Math
.pow(ball_r, 2) && ball_x > right3 && ball_y > bottom3) {
offsetX *= -1;
offsetY *= -1;
left3-=10;
top3-=20;
bottom3-=20;
right3-=10;
}
// 圆在8区域的碰撞判断
if (Math.pow(left3 - ball_x, 2) + Math.pow(ball_y - bottom3, 2) <= Math
.pow(ball_r, 2) && ball_x < left3 && ball_y > bottom3) {
offsetX *= -1;
offsetY *= -1;
left3+=10;
top3-=20;
bottom3-=20;
right3+=10;
}
}
}
Activity类:
package com.example.administrator.mygame;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
public class Main3Activity extends Activity {
private TestHit testHit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
testHit = new TestHit(this);
setContentView(testHit);
testHit.setFocusable(true);
testHit.requestFocus();
testHit.s();
testHit.setOnKeyListener(new View.OnKeyListener() {
/**
*
* @param v 事件源(event source)
* @param keyCode 键码
* @param event 事件本身
* @return
*/
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(testHit.panduan==false){
AlertDialog.Builder builder = new AlertDialog.Builder(Main3Activity.this);
builder.setTitle("提示" ) ;
builder.setMessage("出界,游戏结束" ) ;
builder.setPositiveButton("是" ,new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setClass(Main3Activity.this,Main2Activity.class);
startActivity(intent);
finish();
}
});
builder.show();
}
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_UP:
testHit.offsetX+=5;
testHit.offsetY=testHit.offsetX;
Log.e("offsetX","offsetX"+testHit.offsetX);
Log.e("offsetY","offsetY"+testHit.offsetY);
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
if(testHit.table_l==0){
testHit.table_l-=0;
testHit.table_r-=0;
break;
}
testHit.table_l-=20;
testHit.table_r-=20;
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if(testHit.table_r==1440){
testHit.table_l+=0;
testHit.table_r+=0;
break;
}
testHit.table_l+=20;
testHit.table_r+=20;
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
testHit.offsetX-=5;
testHit.offsetY=testHit.offsetX;
Log.e("offsetX","offsetX"+testHit.offsetX);
Log.e("offsetY","offsetY"+testHit.offsetY);
break;
}
return false;
}
});
}
}