jbox2d android教程,Jbox2d实践应用
开门见山,一针见血~~先来一张图片再说!
前言
JBox2D是开源的物理引擎Box2D的Java版本,可以直接用于Android。由于JBox2D的图形渲染使用的是Processing库,因此在Android平台上使用JBox2D时,图形渲染工作只能自行开发。该引擎能够根据开发人员设定的参数,如重力、密度、摩擦系数和弹性系数等,自动地进行2D刚体物理运动的全方位模拟。
开发前准备
首先我们得上github上下载对应的jbox2d库,具体链接github.com/jbox2d/jbox2d,我们发现下载下来的是zip包,我们可是要的jar包啊。。ok,这里我们就先自行解压再说。解压完毕发现它是一个maven工程,全部是源码,我擦嘞,这可咋办,不是gradle结构的。好这里我们就要使用gradle命令把maven工程转成gradle结构,这里我们需要自己编译jar包。
方法一:用gradle编译maven工程
1.先cmd进入到刚下载解压出来的jbox2d文件目录,执行maven工程转gradle工程命令 gradle init --type pom
2.接着我们进去编译好的工程目录,进入路径 jbox2d-master\gradle\wrapper,里面有个gradle-wrapper.properties文件,在这里,我们打开并修改自己gradle已经缓存有的版本,这里我修改成distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip,不然是编译不了的。
3.ok,接下来我们导入工程。我们需要编译给我们自己用的jar也是通过这里的jbox2d-library进行编译的,我们在右边的gradle选项卡中找到对应的jbox2d-library/Task/build/assemble,双击进行编译。如下图:
心里喜滋滋的准备生成jar包....居然提示报错了,关键是没有提示报错的内容。这里十分抓狂,github上down下来的难道没有维护和更新吗?。。这里我们上去看了看最近都有人在更新,这咋办....不知道如何下手,很多人都在这里放弃了,不要灰心,我们来看第四步。
4.我们用命令行看看报错内容。
这里window使用命令是:gradlew :jbox2d-library(模块名称):assemble(任务)
mac命令为:gradle :jbox2d-library(模块名称):assemble(任务)
5.好这里可以看到报的什么错,结果只是一个简单的错误,包名引用错误,自行改一下源码,重新编译即可打包出jar。
方法二:用maven命令直接编译maven工程
2.在cmd的命令行的输入mvn install (注:这里是在jbox2d-master目录下执行的命令)
好吧,maven就两个步骤就可以了.......
前方高能预警~GO!GO!GO!开始撸码
我们来先了解一下Jbox2d基本概念:
1. 刚体(rigid body)/物体(body)
一块十分坚硬的物质,它上面的任何两点之间的距离是完全不变的。它们就像钻石那样的坚硬。
2. 形状(shape)
一块严格依附于物体的 2D碰撞几何结构,形状具有摩擦和恢复的材料性质。
3.固定装置(fixture):
fixture绑定一个形状到物体,增加材料属性,例如密度,摩擦,恢复。
4.约束
一个约束就是消除物体自由度的物理连接,在2D中,一个物体有3个自由度(水平,垂直,旋转),比如秒针,固定后,消除了想x,y的自由度,只剩下旋转一个自由度
5.世界 world
一个物理世界就是物体,形状和约束相互作用的集合。Box2D支持创建多个世界,但这通常是不必要的。
思路:
1.创建一个JboxImpl类,专门用于管理刚体和世界的创建和逻辑计算
2.自定义一个view,这里为了方便直接继承FrameLayout,并且在真实屏幕中将JboxImpl中计算出刚体运动的坐标绑定给真实的view(也就是这里的image),根据重力感应不停的回调绘制。
3.MainActivity中做重力感应的注册,回调的变化传递到jboxView进行界面重绘。
JboxView类
将屏幕的宽高传递给世界@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
jboxImpl.setWorlSize(w,h);
}
初始化世界与创建刚体@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
jboxImpl.createWorld();
//子viwe创建tag 设置body
int childCount = getChildCount();
for (int i =0; i< childCount; i++) {
View view = getChildAt(i);
//body为空时创建刚体
if (!jboxImpl.isBodyView(view) || changed) {
jboxImpl.creatBody(view);
}
}
}
开启世界与做刚体运动的view绘制@Override
protected void onDraw(Canvas canvas) {
jboxImpl.startWorld();
int childCount = getChildCount();
for (int i =0; i< childCount; i++) {
View view = getChildAt(i);
if (jboxImpl.isBodyView(view)) {
view.setX(jboxImpl.getViewX(view));
view.setY(jboxImpl.getViewY(view));
view.setRotation(jboxImpl.getViewRotaion(view));
}
}
invalidate();
}
JboxImpl类
创建世界
public void createWorld() {
if (mWorld == null) {
mWorld = new World(new Vec2(0, 10.0f));
//创建左右边界静止刚体
updateVertiacalBounds();
//创建上下边界静止刚体
updateHorizontalBounds();
}
}
开始世界
public void startWorld(){
if (mWorld != null) {
mWorld.step(dt, mVelocityIterations, mPosiontIterations);
}
}
创建世界的上下边界,这里上下边界是一个静止的刚体
private void updateHorizontalBounds() {
BodyDef bodyDef = new BodyDef();
//创建静止刚体
bodyDef.type = BodyType.STATIC;
//定义的形状
PolygonShape box = new PolygonShape();
float boxWidth = switchPositionToBody(mWidth);
//设置边界高度为1
float boxHeight = switchPositionToBody(mRatio);
box.setAsBox(boxWidth, boxHeight); //确定为矩形
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = box;
fixtureDef.density = mDesity;
fixtureDef.friction = 0.8f;//摩擦系数
fixtureDef.restitution = 0.5f; //补偿系数
bodyDef.position.set(0, -boxHeight);
Body topBody = mWorld.createBody(bodyDef); //创建一个真实的上边 body
topBody.createFixture(fixtureDef);
bodyDef.position.set(0, switchPositionToBody(mHeight) + boxHeight);
Body bottomBody = mWorld.createBody(bodyDef);//创建一个真实的下边 body
bottomBody.createFixture(fixtureDef);
}
创建运动刚体
public void creatBody(View view) {
BodyDef bodyDef = new BodyDef();
bodyDef.setType(BodyType.DYNAMIC);
bodyDef.position.set(switchPositionToBody( view.getX() + (view.getWidth() / 2) )
,switchPositionToBody(view.getY() + (view.getHeight() / 2)) );
Shape shape = null;
Boolean isCircle = (Boolean) view.getTag(R.id.dn_view_circle_tag);
if (isCircle != null && isCircle) {
shape = craeteCircleShape( switchPositionToBody(view.getWidth() / 2) );
} else {
Log.i("kaka","createBody veiw tag is not circle!!!");
return;
}
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.setShape(shape);
fixtureDef.friction = 0.8f;//摩擦系数
fixtureDef.density = mDesity;
fixtureDef.restitution = 0.5f;//补偿系数
Body body = mWorld.createBody(bodyDef);
body.createFixture(fixtureDef);
view.setTag(R.id.dn_view_body_tag, body);
body.setLinearVelocity(new Vec2(mRandom.nextFloat(), mRandom.nextFloat()));
}
MainActivity类
主要实现SensorEventListener接口
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
float x = event.values[0];
float y = event.values[1] * 2.0f;
jboxView.onSensorChanged(-x, y);
}
}
总结:
其实jbox2d提供的接口运用起来并不是很难,难的物理学部分计算都在jbox2d中计算好了,他会返回给我们坐标值,这里的坐标值是世界中的坐标值。我们需要将它转化成真实屏幕的坐标值重绘就ok了。一个view对应世界中的一个刚体。
好了今天先写到这里。~~~~~~~
jbox2d android教程,Jbox2d实践应用相关推荐
- [教程] Android PHP 最佳实践视频教程
这几个月实在太忙了,一直没有时间关顾博客,不过好在日前花费了不少心血的视频教程<Android+PHP最佳实践>已经在华章教育和China-Pub上线了,在这里给大家简短的推荐一下吧:本系 ...
- OpenGL ES 2.0 for Android教程(九):添加触摸反馈
OpenGL ES 2 第九章:添加触摸反馈 文章传送门 OpenGL ES 2.0 for Android教程(一) OpenGL ES 2.0 for Android教程(二) OpenGL ES ...
- Android软件安全开发实践(下)
Android软件安全开发实践(下) Android开发是当前最火的话题之一,但很少有人讨论这个领域的安全问题.本系列将分两期,探讨Android开发中常见的安全隐患和解决方案.第一期将从数据存储.网 ...
- Android Studio Gradle实践之多渠道自动化打包+版本号管理
转: Android Studio Gradle实践之多渠道自动化打包+版本号管理 上次介绍了Android Studio的安装.配置和基本使用.这次讲一下Android Studio用到的打包工具G ...
- Android 持续集成实践(三)——编写 .gitlab-ci.yml 实现自动化
文章目录 前言 系列文章 Android 持续集成实践(三)--编写 .gitlab-ci.yml 实现自动化 要实现的效果 定义 gitlab-ci 工作场景阶段 定义 build 任务 定义 re ...
- Android 持续集成实践(二)——配置 Docker + gitlab-runner 实现线上自动编译
文章目录 前言 系列文章 Android 持续集成实践(二)--配置 Docker + gitlab-runner 实现线上自动编译 安装 Docker 安装 gitlab-runner 安装 注册 ...
- Android 持续集成实践(四)——配置 WebHook 通知编译结果
文章目录 前言 系列文章 Android 持续集成实践(四)--配置 WebHook 通知编译结果 团队沟通工具 创建团队 创建讨论组 添加 BearyChat 机器人 配置 WebHook gitl ...
- Android游戏开发实践指南(华章程序员书库)
<Android游戏开发实践指南(华章程序员书库)> 基本信息 原书名:Learning Android Game Programming:A Hands-On Guide to Buil ...
- wireshark的使用教程--用实践的方式帮助我们理解TCP/IP中的各个协议是如何工作的
wireshark的使用教程 --用实践的方式帮助我们理解TCP/IP中的各个协议是如何工作的 wireshark是一款抓包软件,比较易用,在平常可以利用它抓包,分析协议或者监控网络,是一个比较好的 ...
最新文章
- pycharm 黄色(黄字)高亮警告 Default argument value is mutable 原因及解决办法(mutable 可变对象与 immutable不可变对象)
- alter system flush shared_pool的作用 .
- Windows 使用命令执行 sql 脚本文件
- MongoDB数据分布不均的解决方案
- python画正方体_python绘制立方体的方法
- 漫话:为什么你下载小电影的时候进度总是卡在99%就不动了?
- 输出数组元素(c语言)
- UVALive 6437 Power Plant 【最小生成树 + 思维】
- 思科模拟器完成实验报告
- Vue3+elementplus搭建通用管理系统实例十五:界面美化及样式调整
- 夜光带你走进C# 游戏开发等(七十九)擅长的领域
- [附源码]java+ssm计算机毕业设计java磐基建筑机械租赁有限公司机械租赁系统41c32【源码、数据库、LW、部署】
- Java游戏培训机构哪家专业
- Android实现拍照相册图片上传功能
- kettle 邮件服务器,kettle 实用功能之三 ---- 使用 kettle 群发动态内容的邮件。
- Python 编辑器哪个好用
- 【TDA2x学习】3、软件架构分析
- 使用Sawyer机器人实现抓取任务(前期准备)
- 从线性空间到再生核希尔伯特空间(RKHS)
- 蚂蚁金服的暴富还未开始,Zoom的神话却仍在继续!