- 浏览: 170800 次
- 性别:
- 来自: 西安
文章分类
最新评论
-
解老毕:
非常谢谢
Android 物理引擎使用(1)---APEngine -
蓝月儿:
真好 很有帮助 学习学习,
Android Zip压缩解压缩 -
常思己过:
总结的很好,简洁明了
Android Zip压缩解压缩 -
tocute:
請問 如果我只是單純地想要對surfaceview 做旋轉我 ...
MediaPlayer 用法(一) -
liuborama:
很有帮助,多谢了
Android Zip压缩解压缩
APE(Actionscript Physics Engine) 是一个 ActionScript3 写成的物理引擎,用于模拟现实中物体发生的运动和碰撞。它是免费、开源的,遵循 MIT 协议。很适合做简单的物理游戏.
现提供了 Alpha, Java Port, 和 C++ SDL Ports 三个版本 .
这里我把官网上的一个Demo移植到了Android上,模拟器上的帧率是5帧左右,真机在HTC Magic G2 上测试也只是6,7帧的样子.我把代码上传上来大家看看能不能优化,还有如果有真机的话希望把在你机子上运行的速度和真机的配置说一下,比较一下各类机器的差异.
package Test.APEngineTest;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint.Style;
import java.lang.Runnable;
import java.util.ArrayList;
import ape.*;
public class ApeTest extends SurfaceView implements Runnable, SurfaceHolder.Callback{
// APEngine 世界
private APEngine APEngine = new APEngine();
// 两个轮子
private SpringConstraint wheelConnector;
private WheelParticle wheelParticleA;
private WheelParticle wheelParticleB;
// 车身
private RectangleParticle rotatingRect;
// 世界中需要刷新的所有物理列表
private ArrayList paintQueue;
private Canvas mCanvas = null;
private Paint mPaint = null;
SurfaceHolder mSurfaceHolder = null;
public static final int SCREEN_WIDTH = 320;
public static final int SCREEN_HEIGHT= 480;
public static final int PLAY_HEIGHT = 400;
public static final int SPEED = 15;
public static final double keySpeed = 0.2;
//计算帧率
// private long mFPSLockTime = 0;
private long mFPSShowTime = 0; //
private long mNowTime = 0; //现在的时间
private int mLoopCount = 0; //循环次数
private float mFPS = 0.0f; //帧速
// private float mFPSTime = (1000.0f/30); //每帧最大执行时间(默认30帧)
private Paint mFPSPaint = new Paint();
public ApeTest(Context context)
{
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
mSurfaceHolder = this.getHolder();
mSurfaceHolder.addCallback(this);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Style.STROKE);
APEngine.setDefaultPaint(mPaint);
InitWorld();
}//end of func
public void InitWorld()
{
// set up the events, main loop handler, and the engine. you don't have to use
// enterframe. you just need to call the ApeEngine.step() method wherever
// and however your handling your program cycle.
// the argument here is the deltaTime value. Higher values result in faster simulations.
APEngine.init((double)1/4);
// SELECTIVE is better for dealing with lots of little particles colliding,
// as in the little rects and circles in this example
APEngine.setCollisionResponseMode(APEngine.SELECTIVE);
// gravity -- particles of varying masses are affected the same
APEngine.addMasslessForce(new Vector(0,3));
// surfaces
RectangleParticle floor = new RectangleParticle(325,324,649,50,0,true,1,0.3,0);
APEngine.addParticle(floor);
RectangleParticle floorBumpA = new RectangleParticle(400,295,90,30, 0.4,true,1,0.3,0);
APEngine.addParticle(floorBumpA);
RectangleParticle floorBumpB = new RectangleParticle(330,295,90,30,-0.4,true,1,0.3,0);
//APEngine.addParticle(floorBumpB);
RectangleParticle floorLeftAngle = new RectangleParticle(80,290,120,20,0.5,true,1,0.3,0);
APEngine.addParticle(floorLeftAngle);
RectangleParticle leftWall = new RectangleParticle(15,99,30,500,0,true,1,0.3,0);
APEngine.addParticle(leftWall);
RectangleParticle rightWall = new RectangleParticle(634,99,30,500,0,true,1,0.3,0);
APEngine.addParticle(rightWall);
// 桥 开始点
RectangleParticle bridgeStart = new RectangleParticle(80,70,150,25,0,true,1,0.3,0);
APEngine.addParticle(bridgeStart);
// 桥结束点
RectangleParticle bridgeEnd = new RectangleParticle(380,70,100,25,0,true,1,0.3,0);
APEngine.addParticle(bridgeEnd);
RectangleParticle bridgeEndAngle = new RectangleParticle(455,102,100,25,0.8,true,1,0.3,0);
APEngine.addParticle(bridgeEndAngle);
RectangleParticle rightWallAngle = new RectangleParticle(595,102,100,25,-0.8,true,1,0.3,0);
APEngine.addParticle(rightWallAngle);
// 旋转矩形rotator
rotatingRect = new RectangleParticle(525,180,70,14,0,true,1,0.3,0);
APEngine.addParticle(rotatingRect);
// 小矩形
RectangleParticle littleRect = new RectangleParticle(525,180,10,10,0,false,1,0.3,0);
APEngine.addParticle(littleRect);
// 把旋转矩形和小矩形用皮筋连接到一起
SpringConstraint rotConnector = new SpringConstraint((AbstractParticle)rotatingRect.getCornerParticles().get(1), (AbstractParticle)littleRect, 0.2);
APEngine.addConstraint(rotConnector);
// bridge
CircleParticle bridgePA = new CircleParticle(200,70,4,false,1,0.3,0);
APEngine.addParticle(bridgePA);
CircleParticle bridgePB = new CircleParticle(240,70,4,false,1,0.3,0);
APEngine.addParticle(bridgePB);
CircleParticle bridgePC = new CircleParticle(280,70,4,false,1,0.3,0);
APEngine.addParticle(bridgePC);
SpringConstraint bridgeConnA = new SpringConstraint((AbstractParticle)bridgeStart.getCornerParticles().get(1), bridgePA, 0.9);
bridgeConnA.setCollidable(true);
bridgeConnA.setCollisionRectWidth(10);
bridgeConnA.setCollisionRectScale(0.6);
APEngine.addConstraint(bridgeConnA);
SpringConstraint bridgeConnB = new SpringConstraint(bridgePA, bridgePB, 0.9);
bridgeConnB.setCollidable(true);
bridgeConnB.setCollisionRectWidth(10);
bridgeConnB.setCollisionRectScale(0.6);
APEngine.addConstraint(bridgeConnB);
SpringConstraint bridgeConnC = new SpringConstraint(bridgePB, bridgePC, 0.9);
bridgeConnC.setCollidable(true);
bridgeConnC.setCollisionRectWidth(10);
bridgeConnC.setCollisionRectScale(0.6);
APEngine.addConstraint(bridgeConnC);
SpringConstraint bridgeConnD = new SpringConstraint(bridgePC, (AbstractParticle)bridgeEnd.getCornerParticles().get(0), 0.9);
bridgeConnD.setCollidable(true);
bridgeConnD.setCollisionRectWidth(10);
bridgeConnD.setCollisionRectScale(0.6);
APEngine.addConstraint(bridgeConnD);
// 汽车
wheelParticleA = new WheelParticle(60,10,20,false,1,0.3,0,1);
wheelParticleA.setMass(2);
APEngine.addParticle(wheelParticleA);
wheelParticleB = new WheelParticle(140,10,20,false,1,0.3,0,1);
wheelParticleB.setMass(2);
APEngine.addParticle(wheelParticleB);
wheelConnector = new SpringConstraint(wheelParticleA, wheelParticleB,0.5);
wheelConnector.setCollidable(true);
wheelConnector.setCollisionRectWidth((double)10);
wheelConnector.setCollisionRectScale((double)0.9);
APEngine.addConstraint(wheelConnector);
// little boxes
for (int i = 0; i < 10; i++) {
double px = (7 * i) + 120;
APEngine.addParticle(new RectangleParticle(px,200,10,5,Math.random() * Math.PI,false,1.8,0.1,0.0));
APEngine.addParticle(new CircleParticle(px+40,210,3.5,false,1.8,0.1,0.0));
}
/*
After adding all the particles and constraints, you can retrieve them using the
getXXX methods from the APEngine class. Then you can go through them and paint them
when necessary. Alternatively you can keep track of them yourself by manually adding
them to your own lists.
*/
paintQueue = APEngine.getAll();
}//end of func
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
{
}
public void surfaceCreated(SurfaceHolder holder)
{
Log.v("surfaceCreated()", "线程启动前");
new Thread(this).start();
}
public void surfaceDestroyed(SurfaceHolder holder)
{
//alive = false;
}
//触摸屏事件
@Override
public boolean onTouchEvent(android.view.MotionEvent event){
//XTouch.OnTouch(event.getAction(), event.getX(), event.getY());
if (wheelParticleA==null || wheelParticleB==null) {
return false;
}
if (event.getAction() == android.view.MotionEvent.ACTION_DOWN) {
if (event.getX() < 240) {
wheelParticleA.setAngularVelocity(-keySpeed);
wheelParticleB.setAngularVelocity(-keySpeed);
}else {
wheelParticleA.setAngularVelocity(keySpeed);
wheelParticleB.setAngularVelocity(keySpeed);
}
}
else if (event.getAction() == android.view.MotionEvent.ACTION_UP) {
wheelParticleA.setAngularVelocity(0);
wheelParticleB.setAngularVelocity(0);
}
return super.onTouchEvent(event);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
switch (keyCode)
{
case KeyEvent.KEYCODE_BACK:
android.os.Process.killProcess(android.os.Process.myPid());
break;
case KeyEvent.KEYCODE_DPAD_UP:
//moveFlag = 1;
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
//moveFlag = 2;
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
//moveFlag = 3;
wheelParticleA.setAngularVelocity(-keySpeed);
wheelParticleB.setAngularVelocity(-keySpeed);
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
//moveFlag = 4;
wheelParticleA.setAngularVelocity(keySpeed);
wheelParticleB.setAngularVelocity(keySpeed);
break;
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event)
{
//moveFlag = 0;
wheelParticleA.setAngularVelocity(0);
wheelParticleB.setAngularVelocity(0);
return super.onKeyUp(keyCode, event);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
public void run() {
boolean bStop = false;
Log.v("Thread1)", "is Running");
while(!bStop)
{
// 获取画布
mCanvas = mSurfaceHolder.lockCanvas();
// 缩小到2/3大小,J2SE移植过来时太大没有改变,直接缩放Canvas
mCanvas.scale(2f/3, 2f/3);
// 清屏
ClearScreen(mCanvas);
// 更新计算物理世界的数据
UpdateWorld(mCanvas);
PaintWorld(mCanvas);
PaintFps(mCanvas);
// 锁帧
// try {
// Thread.sleep(SPEED);
// }
// catch (InterruptedException e)
// {
// }
//解锁画布,提交画好的图像
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
}
public void PaintWorld(Canvas canvas)
{
APEngine.setDefaultContatiner(canvas);
for (int i = 0; i < paintQueue.size(); i++) {
//TG TODO need to write code that determined the type of objects and sets their method.
if (paintQueue.get(i) instanceof RectangleParticle)
((RectangleParticle)paintQueue.get(i)).paint();
else if (paintQueue.get(i) instanceof CircleParticle)
((CircleParticle)paintQueue.get(i)).paint();
else if (paintQueue.get(i) instanceof SpringConstraint)
((SpringConstraint)paintQueue.get(i)).paint();
}
}//end of func
public void UpdateWorld(Canvas canvas)
{
APEngine.step();
rotatingRect.setRotation(rotatingRect.getRotation() + 0.03);
}//end of func
public void ClearScreen(Canvas canvas)
{
//清屏
canvas.drawColor(Color.WHITE);
}
/**
* 计算显示帧速
* @param canvas
*/
public void PaintFps(Canvas canvas)
{
mLoopCount += 1;
mNowTime = System.currentTimeMillis();
if ((mNowTime - mFPSShowTime)>=1000) {
mFPS = (float)(mLoopCount*10000/(mNowTime-mFPSShowTime))/10;
mLoopCount = 0;
mFPSShowTime = mNowTime;
}
//XDebug.Print("XGameView", "PaintFPS");
canvas.drawText(String.valueOf(mFPS)+" FPS", 100, 20, mFPSPaint);
}//end of func
}//end of class
参考:
官方网站: http://www.cove.org/ape/
官方API: http://www.cove.org/ape/docs/api/
官方SVN: http://ape.googlecode.com/svn/
中文API参考: http://wenku.baidu.com/view/193e97cfa1c7aa00b52acb47.html
官方提供了两个Demo
Demo1: http://www.cove.org/ape/demo1.htm
Demo2: http://www.cove.org/ape/demo2.htm
APEngine
优点: 简单易用,文件很少很适合学习阅读
缺点: 是不支持多边形
发表评论
-
Android系统自带样式(android:theme)(转)
2015-09-12 22:37 785android:theme="@android:s ... -
Android 工程打包 要做的几个
2014-12-22 09:31 0<!--StartFragment--> ... -
INSTALL_FAILED_MISSING_FEATURE
2014-10-10 11:56 801使用eclipse编译后,安装运行出现 Installa ... -
EditText 键盘输入类型
2014-04-02 20:19 810EditText 需要指定默认输入类型 加入android ... -
强制退出应用
2010-11-24 17:38 1048/** * 强制退出 */ ... -
MediaPlayer 用法(一)
2010-10-20 17:59 20200使用SurfaceView播放视频,其实很简单,但是经常会碰见 ... -
Matrix 基本使用方法(一)
2010-10-20 11:16 13359java.lang.Object ↳ ... -
Android Zip压缩解压缩
2010-09-01 15:28 23105研究了一下Android上Zip的用法,写了个类把常用的几种方 ... -
Android SDCard操作(文件读写,容量计算)
2010-08-25 18:03 8710android.os.Environment 提供访问 ... -
Android开发环境配置
2010-08-22 22:37 3481下载所需要的软件 J ...
相关推荐
Android 2D物理引擎——APEngine,是一种用于创建动态、交互式2D游戏场景的关键技术。在移动设备上,物理引擎使得游戏中的物体能够模拟真实世界中的运动规则,如重力、碰撞检测、摩擦力等,从而提升游戏的真实感和...
android-support-v4-v7-v13-v14-v17(官方最新完整版),官方最新版的,压缩包内包含android-support-v4、android-support-v7-appcompat,android-support-v7-cardview,android-support-v7-gridlayout,android-support-...
通过使用Android-x86项目提供的ISO文件,用户可以在x86架构的设备上运行Android系统。这对于开发者、教育者以及普通用户来说都具有重要的意义。不仅可以方便地测试和调试Android应用程序,还可以在更大的屏幕上享受...
http://s1.eoeandroid.com/sdk/4.1/android-sdk_r20-windows.zip(推荐) http://s1.eoeandroid.com/sdk/4.1/installer_r20-windows.exe Mac版: http://s1.eoeandroid.com/sdk/4.1/android-sdk_r20-macosx.zip ...
使用“android-ndk-r26b-windows.zip”,开发者需要解压到指定目录,并将其添加到Android Studio的环境变量中,以便在构建过程中使用。同时,Android Studio提供了对NDK的集成支持,可以在IDE内进行NDK相关的开发和...
本文将深入探讨Android高级进阶中的一个关键话题:如何使用JPCT-AE(Java 3D Physics Test Application Environment)3D引擎来构建一个立方体的源码实例。JPCT-AE是一个轻量级且功能强大的3D引擎,适用于Java和...
最新android studio 2015/10/12日更新 2015/10/12 android-studio-bundle-141.2288178-windows
android可用的commons-codec-1.9
android-x86-4.4-r1.iso 用在虚拟机中的安桌系统。
ksoap2-android-assembly-2.6.5-jar-with-dependencies.jar 要是需要最新的,下载地址: http://code.google.com/p/ksoap2-android/
标题中的“android-sdk-windows-1.5_r3.zip-tools”表明这是一个针对Windows平台的Android SDK的早期版本,具体为1.5_r3。这个压缩包包含的是SDK中的“tools”目录,里面通常装有用于Android应用开发和设备管理的...
android-x86-2.2-generic.iso 安卓 虚拟机镜像
Android x86 即运行于 x86 PC上的Android操作系统,目前已经支持大部分安卓程序。Android X86平台是由Beyounn和Cwhuang主持设计的。项目的主要目的在于为X86平台...资源来源:https://www.fosshub.com/Android-x86.html
在本文中,我们将深入探讨"android-studio-ide-141.1890965-linux.zip"这个压缩包,了解如何在Linux环境下安装、配置及高效使用Android Studio。 首先,下载的"android-studio-ide-141.1890965-linux.zip"是针对...
标题中的"android-sdk-4.2.2 android-sdk-4.2.2-platforms"指的是Android SDK的一个特定版本,即Android 4.2.2(API级别17),该版本的SDK平台组件。这个版本是Android操作系统的 Jelly Bean 版本的一部分,发布于...
1. **android-support-v4.jar** 这是Android支持库中最基础的组件,提供了对Android API Level 4(即Android 1.6 Donut)及更高版本的支持。它包含了许多关键功能,如Fragment、Loader、AsyncTask、View Pager等。...
android-sdk-windows-1.5_r1
1. **Android-Universal-Image-Loader介绍** Android-Universal-Image-Loader是一个开源的Android图片加载库,由Sergey Tarasevich创建。它提供了异步图片加载、缓存策略、错误占位图、加载进度显示等多种特性,...
强大的网络请求库,主要特征如下: 处理异步Http请求,并通过匿名内部类处理回调结果 Http请求均位于非UI线程,...通过线程池处理并发请求 处理文件上传、下载 响应结果自动打包JSON格式 自动处理连接断开时请求重连
Android中滑屏初探 ---- scrollTo 以及 scrollBy方法使用说明 Android中滑屏初探 ---- scrollTo 以及 scrollBy方法使用说明 Android中滑屏初探 ---- scrollTo 以及 scrollBy方法使用说明