当前位置:操作系统 > 安卓/Android >>

android 游戏开发之物理小球的应用

游戏开发不同于应用,一切都是自定义,所以对于控件什么的也没有什么好讲的,下面简单作一个案例,其实也是书本上的,最近在学习,顺便总结下.
首先我们要开发对象.Movable.java
package com.jj.ball;

import android.graphics.Bitmap;
import android.graphics.Canvas;

/***
 * 小球对象
 *
 * @author zhangjia
 *
 */
public class Moveable {
 int startX = 0;// 初始X坐标
 int startY = 0;// 初始Y坐标
 int x;// 时时X,
 int y;// 时时Y

 float startVX = 0f;// 初始竖直方向的速度
 float startVY = 0f;// 初始水平方向的速度

 float v_x = 0f;// 时时竖直方向速度
 float v_y = 0f;// 时时水平方向速度

 int r;// 半径

 double timeX;// 水平运动时间
 double timeY;// 竖直运动时间

 Bitmap bitmap = null;// 小球

 BallThread bt = null;

 boolean bFall = false;// 小球是否已经从木板下落

 float impactFactor = 0.25f;// 小球撞地后速度的损失系数.

 /***
  * 构造方法
  *
  * @param x
  * @param y
  * @param r
  * @param bitmap
  */
 public Moveable(int x, int y, int r, Bitmap bitmap) {
  super();
  this.x = x;
  this.startX = x;
  this.startY = y;
  this.y = y;
  this.r = r;
  this.bitmap = bitmap;
  timeX = System.nanoTime();
  this.v_x = BallView.V_MIN
    + (int) ((BallView.V_MAX - BallView.V_MIN) * Math.random());// 初始水平速度
  bt = new BallThread(this);// 创建并启动BallThread
  bt.start();
 }

 /***
  * 绘画
  */
 public void drawSelf(Canvas canvas) {
  canvas.drawBitmap(bitmap, x, y, null);
 }

}
这里面无外乎就是一些小球的属性,涉及到了BallThread物理引擎,下面接着介绍.
首先你要明白:
微妙,纳秒,秒之间的换算
微秒,时间单位,符号μs
1,000,000 微秒 = 1秒
纳秒,时间单位,符号ns
1,000,000,000纳秒=1秒
另外你要明白:一些物理公式:比如说如何求:竖直方向的距离,水平方向移动距离,以及移动过程中的水平,竖直的速度等等,这些都是我们高一的物理知识,虽说我们N年没有触碰过了,但是现在回忆起来还是瞒不错的.在这里我感慨一下:中国教育课程五花八门,真正现实中我们用得到的又有几个?NND,坑爹青春啊.
还有一点:就是小球在撞击地面和上升到最高处都是极端位置,然后再次进行运动的话,都是一次新的运动.不过想大家都明白的,只是我看后感慨游戏确实比应用好多了,起码逻辑思维是应用不能媲美的.
package com.jj.ball;

/***
 * 小球物理引擎
 *
 * @author zhangjia
 *
 */
public class BallThread extends Thread {
 private Moveable moveable;// 小球对象
 private boolean flag = false;// 线程标识
 private int sleepSpan = 30;// 休眠时间
 private float g = 200;// 重力加速度
 private double currentTime;// 记录当前事件

 /***
  * 构造方法
  *
  * @param moveable
  */
 public BallThread(Moveable moveable) {
  super();
  this.moveable = moveable;
  this.flag = true;
 }

 @Override
 public void run() {
  while (flag) {
   currentTime = System.nanoTime();// 获取当前时间,单位为纳秒
   double timeSpanX = (double) ((currentTime - moveable.timeX) / 1000 / 1000 / 1000);// 获取从玩家开始到现在水平方向走过的时间
   // 处理水平方向上的运动
   moveable.x = (int) (moveable.startX + moveable.v_x * timeSpanX);
   // 处理竖直方向上的运动
   if (moveable.bFall) {
    double timeSpanY = (double) ((currentTime - moveable.timeY) / 1000 / 1000 / 1000);
    moveable.y = (int) (moveable.startY + moveable.startVY
      * timeSpanY + timeSpanY * timeSpanY * g / 2);
    moveable.v_y = (float) (moveable.startVY + g * timeSpanY);
    // 判断小球是否到达最高点
    if (moveable.startVY < 0
      && Math.abs(moveable.v_y) <= BallView.UP_ZERO) {
     moveable.timeY = System.nanoTime(); // 设置新的运动阶段竖直方向上的开始时间
     moveable.v_y = 0; // 设置新的运动阶段竖直方向上的实时速度
     moveable.startVY = 0; // 设置新的运动阶段竖直方向上的初始速度
     moveable.startY = moveable.y; // 设置新的运动阶段竖直方向上的初始位置
    }
    // 判断小球是否撞地
    if (moveable.y + moveable.r * 2 >= BallView.GROUND_LING
      && moveable.v_y > 0) {// 判断撞地条件
     // 改变水平方向的速度
     moveable.v_x = moveable.v_x * (1 - moveable.impactFactor); // 衰减水平方向上的速度
     // 改变竖直方向的速度
     moveable.v_y = 0 - moveable.v_y
       * (1 - moveable.impactFactor); // 衰减竖直方向上的速度并改变方向
     if (Math.abs(moveable.v_y) < BallView.DOWN_ZERO) { // 判断撞地后的速度,太小就停止
      this.flag = false;
     } else { // 撞地后的速度还可以弹起继续下一阶段的运动
      // 撞地之后水平方向的变化
      moveable.startX = moveable.x; // 设置新的运动阶段的水平方向的起始位置
      moveable.timeX = System.nanoTime(); // 设置新的运动阶段的水平方向的开始时间
      // 撞地之后竖直方向的变化
      moveable.startY = moveable.y; // 设置新的运动阶段竖直方向上的起始位置
      moveable.timeY = System.nanoTime(); // 设置新的运动阶段竖直方向开始运动的时间
      moveable.startVY = moveable.v_y; // 设置新的运动阶段竖直方向上的初速度
     }
    }
   } else if (moveable.x + moveable.r / 2 >= BallView.WOOD_EDGE) {// 判断球是否移出了挡板
    moveable.timeY = System.nanoTime(); // 记录球竖直方向上的开始运动时间
    moveable.bFall = true; // 设置表示是否开始下落标志位
   }
   try {
    Thread.sleep(sleepSpan); // 休眠一段时间
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 }

}
在这里我要简单补充一点,或许大家都明白懂得,但是我在这里疑惑了,问题是:判断小球是否撞地moveable.y + moveable.r * 2 >= BallView.GROUND_LING在这里为什么半径要乘以2呢,如果这样想的话,那么你就是把中心放在小球的球心了,但是我们里面涉及的X,Y等等都是按照小球的左上角来计算的.就相当于最外面有一个矩形框在包裹着.其实这是用到碰撞检测技术中的(矩(圆柱)形检测).这样我们就很自然的明白了为什么半径乘以2了.判断小球是否移出挡板moveable.x + moveable.r / 2 >= BallView.WOOD_EDGE.在现实中,不可能小球还没有离开挡板就开始下落吧,如果是这样就不符合现实状况了,所以就在小球还差1/4之离开挡板之时开始下落,这样就和现实接轨了.(其实看起来没有什么区别,但是你要明

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,