91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》
  • 首頁 > 
  • 教程 > 
  • 開發技術 > 
  • 【移動開發】Android游戲開發SurfaceView應用----手指發動小球(小球碰撞檢測例子)

【移動開發】Android游戲開發SurfaceView應用----手指發動小球(小球碰撞檢測例子)

發布時間:2020-07-05 07:24:19 來源:網絡 閱讀:3184 作者:zhf651555765 欄目:開發技術

     為了復習一下SurfaceView的使用,在此寫了一個經典的小球碰撞檢測例子程序,希望能夠夠幫助正在學習游戲的人。

先看一下效果圖:

【移動開發】Android游戲開發SurfaceView應用----手指發動小球(小球碰撞檢測例子)

   下面我們就來逐一分析一下它的實現過程:

1.啟動入口:

import android.os.Bundle;
import android.app.Activity;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //全屏設置
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        //將畫布放進去
        GameView gameView = new GameView(this);
        setContentView(gameView);
    }
}


2.小球類

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
/**
 * 小球實例
 * @author ZHF
 *
 */
public class Ball {
    int x, y;  //小球的實時位置
    int startX, startY;   //小球的初始位置
    float vX, vY;    //小球的速度
    int r; //小球的半徑
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
    double startTimeX;  //開始時間
    double startTimeY;  //開始時間
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
    BallThread ballThread;  //小球移動線程
    Paint paint = new Paint();  //畫筆
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
    public Ball(int x, int y, float vX, float vY, int r) {
        this.x = x;
        this.y = y;
        this.startX = x;
        this.startY = y;
        this.vX = vX;
        this.vY = vY;
        this.r = r;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
        //為每個小球實例化一個獨立的線程,在抬手時開啟線程
        ballThread = new BallThread(this);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
        paint.setColor(Color.RED);  //小球為紅色實心
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
    /**繪畫方法**/
    public void drawSelf(Canvas canvas) {
        canvas.drawCircle(x, y, r, paint);
    }
}


3.障礙物類:

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
/**
 * 障礙物
 *
 * @author ZHF
 *
 */
public class Obstruction {
    int x, y;
    int hWeight;  //寬度和高度一樣
    Paint paint = new Paint();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
    public Obstruction(int x, int y, int hWeight) {
        this.x = x;
        this.y = y;
        this.hWeight = hWeight;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
        paint.setColor(Color.GREEN);  //設置畫筆顏色
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
    }
    public void drawSelf(Canvas canvas) {
        canvas.drawRect(x - hWeight, y - hWeight, x + hWeight, y + hWeight, paint);
    }
}

以上代碼比較簡單,在此不多做解釋,下面主要來看一下兩個主要線程類:


4.小球移動線程(碰撞檢測):

/**
 * 小球移動和碰撞檢測線程
 * @author ZHF
 *
 */
public class BallThread extends Thread {
    boolean flag;   //標記線程是否開啟
    Ball ball;  //小球
    double currentTime;  //當前時間
                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
    public BallThread(Ball ball) {
        flag = true;
        this.ball = ball;
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
    @Override
    public void run() {
        while(flag) {
            //調試:碰撞檢測開始時間
            long startTime = System.currentTimeMillis();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
             //計算出小球移動的時間片:將每次刷新分成若干時間小片段,用于計算每次時間小片段小球移動的距離
            currentTime = System.nanoTime();
            double timeSpanX = (currentTime - ball.startTimeX) /1000 /1000 /1000;
            double timeSpanY = (currentTime - ball.startTimeY) /1000 /1000 /1000;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
            int xBackup = ball.x; //保存小球的碰撞前的位置
            int yBackup = ball.y;
            ball.x = (int) (ball.startX + ball.vX * timeSpanX);//小球移動的距離
            ball.y = (int) (ball.startY + ball.vY * timeSpanY);
                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
            //邊界碰撞檢測
            if((ball.vX > 0 && (ball.x + ball.r) >= 479) || (ball.vX < 0 && (ball.x - ball.r) <= 0)) {
                ball.x = xBackup;
                ball.vX = 0 - ball.vX;  //速度反向
                ball.startTimeX = System.nanoTime();  //重新記錄開始時間
                ball.startX = ball.x;  //重新記錄開始位置
            }
            if((ball.vY > 0 && (ball.y + ball.r) >= 799) || (ball.vY < 0 && (ball.y - ball.r) <= 0)) {
                ball.y = yBackup;
                ball.vY = 0 - ball.vY;   //速度反向
                ball.startTimeY = System.nanoTime();   //重新記錄開始時間
                ball.startY = ball.y;   //重新記錄開始位置
            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
            //障礙物碰撞檢測
            for(int i = 0; i < GameView.obstructList.size(); i++) {
                Obstruction o = GameView.obstructList.get(i);
                if(Math.abs(ball.x - o.x) < (ball.r + o.hWeight) && Math.abs(ball.y - o.y) < (ball.r + o.hWeight)){
                    if(Math.abs(xBackup - o.x) >= (ball.r + o.hWeight)) {
                        ball.x = xBackup;
                        ball.vX =  0 - ball.vX;
                        ball.startTimeX = System.nanoTime();
                        ball.startX = ball.x;
                    }
                    if(Math.abs(yBackup - o.y) >= (ball.r + o.hWeight)) {
                        ball.y = yBackup;
                        ball.vY = 0 - ball.vY;
                        ball.startTimeY = System.nanoTime();
                        ball.startY = ball.y;
                    }
                    break; //跳出循環
                }
            }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
            //調試:碰撞檢測結束時間     實驗證明碰撞加測基本不耗時間
            long endTime = System.currentTimeMillis();
            System.out.println(endTime + "----" + startTime + "= " +(endTime - startTime));
                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
            try {
                Thread.sleep(10);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

分析:

   1.我們將刷新時間分割成:將每次刷新時間分成若干時間小片段timeSpanX和timeSpanY,用于計算每次時間小片段小球移動的距離.

   2.我們在小球與邊界碰撞之前,記錄一下時間startTime,在其與邊界碰撞之后,我們將其x軸、y軸方向上做一系列的操作(方向取反,回到碰撞前位置,重新記錄開始時間)其實,我通過調試發現碰撞時間基本可以忽略.

【移動開發】Android游戲開發SurfaceView應用----手指發動小球(小球碰撞檢測例子)

   3.我們這里的碰撞檢測是邊界檢測,只考慮小球與障礙物、邊界的碰撞,沒有考慮小球之間的碰撞,有興趣的同學可以自行研究一下。


5.繪畫線程:

2

import android.graphics.Canvas;
import android.util.Log;
import android.view.SurfaceHolder;
/**
 * 繪畫主界面線程
 * @author ZHF
 *
 */
public class DrawThread extends Thread {
                                                                                                                                                                                                                                                                                             
    boolean flag;  //標記線程是否開啟
    GameView gameView;
    SurfaceHolder holder;
    Canvas canvas;
                                                                                                                                                                                                                                                                                             
    public DrawThread(GameView gameView) {
        flag = true;
        this.gameView = gameView;
        holder = gameView.getHolder();  //獲取畫布鎖
    }
    @Override
    public void run() {
        while(flag) {
            //獲取當前繪畫開始時間
            long startTime = System.currentTimeMillis();
            synchronized(holder) {
                canvas = holder.lockCanvas(); //獲取當前被鎖住的畫布
                if(canvas != null) {
                    gameView.draw(canvas); //對畫布進行操作
                    holder.unlockCanvasAndPost(canvas); //釋放畫布
                }
            }
            long endTime = System.currentTimeMillis();
            int diffTime = (int) (endTime - startTime);
            Log.d("DrawTime", diffTime+"");
                                                                                                                                                                                                                                                                                                     
            while(diffTime <= 2) {
                diffTime = (int) (System.currentTimeMillis() - startTime);
                Thread.yield(); //將線程的所有權交給另一個線程
            }
        }
    }
}

   分析:

     1. 首先,我們將畫布鎖住之后,對其進行繪畫,畫完之后自然要釋放畫布啦

2. 為了優化程序,我們計算出繪畫所用時間,當繪畫時間過長時,暫停當前正在執行的線程對象,通知CPU來執行其他線程(注意:這里的其他也包含當前線程)

6.主界面:

import java.util.ArrayList;
import java.util.Random;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/**
 * 游戲主界面
 * @author ZHF
 *
 */
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
    SurfaceHolder holder;
    DrawThread drawThread;  //繪畫線程
                                                                                                                                                                                               
    Ball[] ballArray = new Ball[5];  //裝小球的數組
    int ballPointer = 0;  //當前指向數組中第幾個球
                                                                                                                                                                                               
    static ArrayList<Obstruction> obstructList = new ArrayList<Obstruction>();   //裝障礙物的集合
                                                                                                                                                                                               
    int xDown, yDown;  //記錄手指按下時的坐標
                                                                                                                                                                                               
    public GameView(Context context) {
        super(context);
        holder = getHolder();  //獲取畫布鎖
        holder.addCallback(this);  //添加回調
                                                                                                                                                                                                   
        //初始化障礙物
        Random random = new Random();
        for(int i = 0; i < 3; i++) {
            Obstruction o = new Obstruction(random.nextInt(380) + 50, random.nextInt(700) + 50, 50);
            obstructList.add(o); //將創出的障礙物對象添加到集合中去
        }
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        drawThread = new DrawThread(this);
        drawThread.start();    //開啟繪畫線程
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        //畫布發生變化,eg:轉屏操作,處理畫布操作
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        //銷毀畫布操作
        drawThread.flag = false;  //停掉線程
        drawThread = null; //GC會及時發現并處理掉該對象
    }
    public void draw(Canvas canvas) {
        canvas.drawColor(Color.BLACK);  //背景顏色
        Paint paint = new Paint();
        paint.setTextSize(25);
        paint.setColor(Color.WHITE);  //文字顏色
        canvas.drawText("小球碰撞檢測", 50, 20, paint);
                                                                                                                                                                                                   
        //畫出小球
        for(int i = 0; i < 5; i++) {
            if(ballArray[i] != null) {
                ballArray[i].drawSelf(canvas);  //當前小球繪畫出自己
            }
        }
        //畫出障礙物
        for(int i = 0; i < obstructList.size(); i++) {
            obstructList.get(i).drawSelf(canvas);
        }
    }
                                                                                                                                                                                               
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
                                                                                                                                                                                                   
        if(event.getAction() == 0) {  //按下
            //記錄按下時X,Y的坐標
            xDown = x;
            yDown = y;
            //生成第一個球
            Ball ball = new Ball(x, y, 0, 0, 20);
            if(ballArray[ballPointer] != null) {
                ballArray[ballPointer].ballThread.flag = false;  //關閉小球移動線程
                ballArray[ballPointer].ballThread = null;
            }
            ballArray[ballPointer] = ball;
                                                                                                                                                                                                       
        } else if(event.getAction() == 1) { //抬起
            int xOffset = x - xDown;
            int yOffset = y - yDown;
            double sin = yOffset / Math.sqrt(xOffset * xOffset + yOffset * yOffset);
            double cos = xOffset / Math.sqrt(xOffset * xOffset + yOffset * yOffset);
                                                                                                                                                                                                       
            ballArray[ballPointer].startTimeX = System.nanoTime(); //當前小球開始時間
            ballArray[ballPointer].startTimeY = System.nanoTime();
            ballArray[ballPointer].vX = (float) (500 * cos);  //當前小球的速度
            ballArray[ballPointer].vY = (float) (500 * sin);
            ballArray[ballPointer].ballThread.start();   //開啟小球移動線程
                                                                                                                                                                                                       
            ballPointer ++;  //下一個小球
            if(ballPointer >= 5) {
                ballPointer = 0;
            }
        }
        return true;
    }
}

分析:

   1.這里我們啟動小球移動線程方式:采用手指觸屏滑動,記錄按下、抬起位置,通過計算角度得出算出發射方向。

   2.每次發出小球后下標ballPointer ++指向下一個小球,當到達數組上限后,重新返回到下標0.



   ok! 到此功能已經實現,想要完整源碼在此下載:http://download.csdn.net/detail/zhf651555765/5775035


附件:http://down.51cto.com/data/2363159
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

汉源县| 武邑县| 嵊州市| 玉树县| 黄龙县| 普格县| 石门县| 长海县| 馆陶县| 谷城县| 手机| 沅江市| 吕梁市| 佛山市| 浦东新区| 曲靖市| 达拉特旗| 遂溪县| 榕江县| 阿拉善盟| 新余市| 天峻县| 习水县| 皋兰县| 鹤壁市| 南康市| 游戏| 泽库县| 九寨沟县| 贺州市| 通许县| 铜鼓县| 东乌珠穆沁旗| 陕西省| 宁乡县| 阿拉善右旗| 保定市| 眉山市| 菏泽市| 云林县| 黑龙江省|