安卓开发矩形和圆形的碰撞检测。

先放上成品图:

思路如下:

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;
            }
        });

    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值