android 游戏 重力
引用:http://d-android.com/developer/thread-4539-1-1.html
?在重力傳感器中,雖然我也實現了一個圓形會根據手機反轉的角度而擁有不同的速度,但是其內置加速度算法都是Android?os封裝好的,而今天我們要講的重力系統就是去模擬這個加速度,從而讓一個自由落體的圓形,感覺跟現實中的皮球一樣有質有量!下落的時候速度加快,反彈起來以后速度慢慢減下來~
OK,先上兩張截圖,然后簡單介紹之后進行講解:
??
Demo:簡介:(咳咳、玩的有點H,狂點按鈕搞的滿屏都是 - -)? ?? ?當你點擊模擬器任意按鍵的時候會隨機在屏幕上生成一個隨機大小、隨即顏色、隨即位置、不停閃爍的一個圓形,并且圓形都擁有重力,在做自由落體,當圓形觸到屏幕底部的時候會反彈,并且反彈的高度一次比一次低!? ?? ?這個實例中,為了好看,我沒有讓圓形最終慢到停下來,會一直在一個高度進行的反彈,下落;還有一點:對于圓形當從一個高度自由落體的時候可能它在X坐標系上沒有發生改變,當然這屬于理想狀態,因為現實生活中,一般X/Y坐標系都會有變動,在此Demo中,我主要把垂直下落并且反彈的功能做出來了,關于水平的加速度我沒做,第一是因為和垂直的處理思路基本一致,第二點我沒時間?- -...好了 不廢話!先介紹一下我自定義的圓形類:MyArc.java
package?com.himi;??
import java.util.Random;??
import android.graphics.Canvas;??
import android.graphics.Color;??
import android.graphics.Paint;??
import android.graphics.RectF;??
/**?
* @author Himi?
* @自定義圓形類?
*/??
public?class MyArc {??
? ? private int arc_x, arc_y, arc_r;//圓形的X,Y坐標和半徑??
? ? private float speed_x = 1.2f, speed_y = 1.2f;//小球的x、y的速度??
? ? private float vertical_speed;//加速度??
? ? private float horizontal_speed;//水平加速度,大家自己試著添加吧??
? ? private final float ACC = 0.135f;//為了模擬加速度的偏移值??
? ? private final float RECESSION = 0.2f;//每次彈起的衰退系數? ?
? ? private boolean isDown = true;//是否處于下落??狀態??
? ? private Random ran;//隨即數庫??
? ? /**?
? ???* @定義圓形的構造函數?
? ???* @param x 圓形X坐標?
? ???* @param y 圓形Y坐標?
? ???* @param r 圓形半徑?
? ???*/??
? ? public MyArc(int x, int y, int r) {??
? ?? ???ran = new Random();??
? ?? ???this.arc_x = x;??
? ?? ???this.arc_y = y;??
? ?? ???this.arc_r = r;??
? ? }??
? ? public void drawMyArc(Canvas canvas, Paint paint) {//每個圓形都應該擁有一套繪畫方法??
? ?? ???paint.setColor(getRandomColor());//不斷的獲取隨即顏色,對圓形進行填充(實現圓形閃爍效果)??
? ?? ???canvas.drawArc(new RectF(arc_x + speed_x, arc_y + speed_y, arc_x + 2 *??
? ?? ?? ?? ?? ? arc_r + speed_x, arc_y + 2 * arc_r + speed_y), 0, 360, true, paint);??
? ? }??
? ? /**?
? ???* @return?
? ???* @返回一個隨即顏色?
? ???*/??
? ? public int getRandomColor() {??
? ?? ???int ran_color = ran.nextInt(8);??
? ?? ???int temp_color = 0;??
? ?? ???switch (ran_color) {??
? ?? ???case 0:??
? ?? ?? ?? ?temp_color = Color.WHITE;??
? ?? ?? ?? ?break;??
? ?? ???case 1:??
? ?? ?? ?? ?temp_color = Color.BLUE;??
? ?? ?? ?? ?break;??
? ?? ???case 2:??
? ?? ?? ?? ?temp_color = Color.CYAN;??
? ?? ?? ?? ?break;??
? ?? ???case 3:??
? ?? ?? ?? ?temp_color = Color.DKGRAY;??
? ?? ?? ?? ?break;??
? ?? ???case 4:??
? ?? ?? ?? ?temp_color = Color.RED;??
? ?? ?? ?? ?break;??
? ?? ???case 6:??
? ?? ?? ?? ?temp_color = Color.GREEN;??
? ?? ???case 7:??
? ?? ?? ?? ?temp_color = Color.GRAY;??
? ?? ???case 8:??
? ?? ?? ?? ?temp_color = Color.YELLOW;??
? ?? ?? ?? ?break;??
? ?? ???}??
? ?? ???return temp_color;??
? ? }??
? ? /**?
? ???* 圓形的邏輯?
? ???*/??
? ? public void logic() {//每個圓形都應該擁有一套邏輯??
? ?? ???if (isDown) {//圓形下落邏輯??
/*--備注1-*/speed_y += vertical_speed;//圓形的Y軸速度加上加速度??
? ?? ?? ?? ?int count = (int) vertical_speed++;??
? ?? ?? ?? ?//這里拿另外一個變量記下當前速度偏移量??
? ?? ?? ?? ?//如果下面的for (int i = 0; i < vertical_speed++; i++) {}這樣就就死循環了 - -??
? ?? ?? ?? ?for (int i = 0; i < count; i++) {//備注1??
/*--備注2-*/??vertical_speed += ACC;??
? ?? ?? ?? ?}??
? ?? ???} else {//圓形反彈邏輯??
? ?? ?? ?? ?speed_y -= vertical_speed;??
? ?? ?? ?? ?int count = (int) vertical_speed--;??
? ?? ?? ?? ?for (int i = 0; i < count; i++) {??
? ?? ?? ?? ?? ? vertical_speed -= ACC;??
? ?? ?? ?? ?}??
? ?? ???}??
? ?? ???if (isCollision()) {??
? ?? ?? ?? ?isDown = !isDown;//當發生碰撞說明圓形的方向要改變一下了!??
? ?? ?? ?? ?vertical_speed -= vertical_speed * RECESSION;//每次碰撞都會衰減反彈的加速度??
? ?? ???}??
? ? }??
? ? /**?
? ???* 圓形與屏幕底部的碰撞?
? ???* @return?
? ???* @返回true 發生碰撞?
? ???*/??
? ? public boolean isCollision() {??
? ?? ???return arc_y + 2 * arc_r + speed_y >= MySurfaceViee.screenH;??
? ? }??
}??
復制代碼
代碼比較簡單主要講解下幾個備注:備注1:? ?? ? 估計有些同學看到這里有點小暈,我解釋下,大家都知道自由落體的時候,速度是越來越快的,這是收到加速度的影響,所以這里我們對原有的圓形y速度基礎上再加上加速度! 備注2:雖然加速度影響了圓形原有的速度,但是我們的加速度也不是恒定的,為了模擬真實球體的自由下落,這里我們不僅對加速度增加了偏移量ACC,而且我們還要對其變化的規律進行模擬,讓下次的加速度偏移量成倍增加!所以為什么要for循環的時候把加速度的值當成for循環的一個判定條件!好了,下面來看我們SurfaceView!
package com.himi;??
import java.util.Random;??
import java.util.Vector;??
import android.content.Context;??
import android.graphics.Canvas;??
import android.graphics.Color;??
import android.graphics.Paint;??
import android.util.Log;??
import android.view.KeyEvent;??
import android.view.SurfaceHolder;??
import android.view.SurfaceView;??
import android.view.SurfaceHolder.Callback;??
public class MySurfaceViee extends SurfaceView implements Callback, Runnable {??
? ? private Thread th;??
? ? private SurfaceHolder sfh;??
? ? private Canvas canvas;??
? ? private Paint paint;??
? ? private boolean flag;??
? ? public static int screenW, screenH;??
? ? private Vector<MyArc> vc;//這里定義裝我們自定義圓形的容器??
? ? private Random ran;//隨即庫??
? ? public MySurfaceViee(Context context) {??
? ?? ???super(context);??
? ?? ???this.setKeepScreenOn(true);??
? ?? ???vc = new Vector<MyArc>();??
? ?? ???ran = new Random();//備注1??
? ?? ???sfh = this.getHolder();??
? ?? ???sfh.addCallback(this);??
? ?? ???paint = new Paint();??
? ?? ???paint.setAntiAlias(true);??
? ?? ???setFocusable(true);??
? ? }??
? ? public void surfaceCreated(SurfaceHolder holder) {??
? ?? ???flag = true;//這里都是上一篇剛講過的。。。??
? ?? ???th = new Thread(this);??
? ?? ???screenW = this.getWidth();??
? ?? ???screenH = this.getHeight();??
? ?? ???th.start();??
? ? }??
? ? public void draw() {??
? ?? ???try {??
? ?? ?? ?? ?canvas = sfh.lockCanvas();??
? ?? ?? ?? ?canvas.drawColor(Color.BLACK);??
? ?? ?? ?? ?if (vc !=?null) {//當容器不為空,遍歷容器中所有圓形畫方法??
? ?? ?? ?? ?? ? for (int i = 0; i < vc.size(); i++) {??
? ?? ?? ?? ?? ?? ???vc.elementAt(i).drawMyArc(canvas, paint);??
? ?? ?? ?? ?? ? }??
? ?? ?? ?? ?}??
? ?? ???} catch (Exception e) {??
? ?? ?? ?? ?// TODO: handle exception??
? ?? ???} finally {??
? ?? ?? ?? ?try {??
? ?? ?? ?? ?? ? if (canvas != null)??
? ?? ?? ?? ?? ?? ???sfh.unlockCanvasAndPost(canvas);??
? ?? ?? ?? ?} catch (Exception e2) {??
? ?? ?? ?? ?}??
? ?? ???}??
? ? }??
? ? private void logic() {//主邏輯??
? ?? ???if (vc != null) {//當容器不為空,遍歷容器中所有圓形邏輯??
? ?? ?? ?? ?for (int i = 0; i < vc.size(); i++) {??
? ?? ?? ?? ?? ? vc.elementAt(i).logic();??
? ?? ?? ?? ?}??
? ?? ???}??
? ? }??
? ? @Override??
? ? public boolean onKeyDown(int keyCode, KeyEvent event) {??
? ?? ???//當按鍵事件響應,我們往容器中仍個我們的圓形實例??
? ?? ???vc.addElement(new MyArc(ran.nextInt(this.getWidth()), ran.nextInt(100), ran.nextInt(50)));??
? ?? ???return true;??
? ? }??
? ? public void run() {??
? ?? ???// TODO Auto-generated method stub??
? ?? ???while (flag) {??
? ?? ?? ?? ?logic();??
? ?? ?? ?? ?draw();??
? ?? ?? ?? ?try {??
? ?? ?? ?? ?? ? Thread.sleep(100);??
? ?? ?? ?? ?} catch (Exception ex) {??
? ?? ?? ?? ?}??
? ?? ???}??
? ? }??
? ? public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {??
? ?? ???Log.v("Himi", "surfaceChanged");??
? ? }??
? ? public void surfaceDestroyed(SurfaceHolder holder) {??
? ?? ???flag = false;??
? ? }??
} ?
轉載于:https://www.cnblogs.com/sode/archive/2011/09/29/2194970.html
總結
以上是生活随笔為你收集整理的android 游戏 重力的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: i-doIT 0.9.9-7发布 CMD
- 下一篇: IE9浏览Flash页面时显示错位并不停