cocos2d-x for wp 之Box2D的应用

本文大部分内容是基于fengyun1989的博文,自己只是加深巩固而已

Box2d是一款用于2d游戏的物理引擎。在这个世界里创造出的物体都更接近于真实世界的物体。

首先,在项目添加Box2D.XNA.DLL。

新建一个页面BOX2DLayer并继承于CCLayer

重写init函数,并添加下面这个常量:

由于平时我们都是用像素来描述游戏世界的,而在box2d里是用“米”进行描述的。所以我们需要进行转化单位。设置一个常量,然后在需要的位置上用像素除以它就可以转化成相对应的“米”

public static double PTM_RATIO = 32.0;

 

接下来就是开始创造世界了。

Vector2 gravity = new Vector2(30.0f, 0.0f);bool doSleep = true;world = new World(gravity, doSleep);

首先我们需要模拟出一个重力gravity。这里用一个2维矢量模拟重力并设置了一个值doSleep,用以指明对象不参与碰撞时,是否可以“休眠”。一个休眠的对象将不会花费处理时间,直到它与其实对象发生碰撞的时候才会“醒”过来。

这里说明一下物理世界的重力向量gravity。两个参数分别表示物理世界中的X轴和Y轴方向上的重力数值。“+” “-”表示重力的方向

X轴正值表示向右,Y轴正值表示向上

 

接下来,该是为这个世界添加一些物体的时候了。

我在Android关于box2d应用中看到关于world创建一个物体的步骤:

1.创建物体皮肤 PolygonDef

2.创建物体刚体BodyDef

3.通过皮肤和刚体创建一个物体 body (body=body.createBody(BodyDef )body.createShape(PolygonDef))

 在wp里略有不同。

BodyDef ballBodyDef = new BodyDef();ballBodyDef.type = BodyType.Dynamic;//动态类型ballBodyDef.position=new Vector2((float)(100/PTM_RATIO),(float)(300/PTM_RATIO));ballBodyDef.userData=ball;body=world.CreateBody(ballBodyDef);CircleShape circle=new CircleShape();circle._radius=(float)(26.0/PTM_RATIO);FixtureDef ballShapeDef=new FixtureDef();ballShapeDef.shape=circle;ballShapeDef.density=1.0f;//质量:0代表静态的物体,1代表运动物体ballShapeDef.friction=0.0f;//摩擦ballShapeDef.restitution=1.0f;//恢复力body.CreateFixture(ballShapeDef);

首先一个BodyDef
接下来一个CircleShape

最后一个FixtureDef

相比Android的定义过程,不过是将PolygonDef换成了一个Shape,并将这个Shape付给一个Fixture,最后由这个fixture完成body的创建。

现在详细说明一下上面代码的含义:

我们指定body的类型为dynamic body。默认值是static body,那意味着那个body不能被移动也不会参与仿真。很明显,我们想让篮球参与仿真。
 设置body的user data属性为篮球精灵。你可以设置任何东西,但是,你设置成精灵会很方便,特别是当两个body碰撞的时候,你可以通过这个参数把精灵对象取出来,然后做一些逻辑处理。
这里使用了一个不同的shape类型--circle shape。
在这里,我们需要为这个fixture指定一些参数

其中,说明一下这个restitution(恢复力)。我们都知道,在物理世界是能量守恒的。而这个恢复力就是能量守恒的体现之一。如果设置为1,则物体在世界里的碰撞是完全弹性碰撞。我们也把球的摩擦力设置为0.这样可以防止球在碰撞的时候,由于摩擦损失能量,导致来回碰撞的过程中会有一点点偏差。 

 

接下来,我们必须为我们的世界设置一个围墙,免得球跳出了“屏幕”

View Code
BodyDef groundBodyDef = new BodyDef();groundBodyDef.position = new Vector2(0, 0);Body groundBody = world.CreateBody(groundBodyDef);PolygonShape groundBox = new PolygonShape();//凸多边形FixtureDef boxShapeDef = new FixtureDef();boxShapeDef.shape = groundBox;groundBox.SetAsEdge(new Vector2(0, 0), new Vector2((float)(winSize.width / PTM_RATIO), 0));groundBody.CreateFixture(boxShapeDef);groundBox.SetAsEdge(new Vector2(0, 0), new Vector2(0, (float)(winSize.height / PTM_RATIO)));groundBody.CreateFixture(boxShapeDef);groundBox.SetAsEdge(new Vector2(0, (float)(winSize.height / PTM_RATIO)), new Vector2((float)(winSize.width / PTM_RATIO), (float)(winSize.height / PTM_RATIO)));groundBody.CreateFixture(boxShapeDef);groundBox.SetAsEdge(new Vector2((float)(winSize.width / PTM_RATIO), (float)(winSize.height / PTM_RATIO)),new Vector2((float)(winSize.width / PTM_RATIO), 0));groundBody.CreateFixture(boxShapeDef);


详细解释一下上面的代码:

首先创建一个body定义结构体,并且指定它应该放在左下角。
然后,使用world对象来创建body对象。(注意,这里一定要使用world对象来创建,不能直接new,因为world对象会做一些内存管理操作。)
 接着,为屏幕的每一个边界创建一个多边形shape。这些“shape”仅仅是一些线段。注意,我们把像素转换成了“meter”。通过除以之前定义的比率来实现的。
 再创建一个fixture定义,指定shape为polygon shape。
 再使用body对象来为每一个shape创建一个fixture对象。
注意:一个body对象可以包含许许多多的fixture对象。

在完成上面之后。我们只是定义了物理世界,还没开始进行物理模拟。所以还要对world设置物理模拟:

world.Step(dt, 10, 10);

此函数表示让物理世界开始进行物理模拟,后两个参数含义分别是“速度迭代次数”和“位置迭代次数”。设置他们的范围在8-10之间。
这里的数字越小,精度越小,但是效率更高。数字越大,仿真越精确,但同时耗时更多。8一般是个折中数值。

 

这里要注意,因为物理世界模拟具有持续性,所以应该将设置放在线程中,不断让物理世界进行模拟。

在init()里添加一个this.schedule(tick)。这里的tick就是一个“线程”

在tick里除了添加物理模拟之外,我们要使我们的小球精灵匹配物理仿真。因此,我们遍历world对象里面的所有body,然后看body的user data属性是否为空,如果不为空,就可以强制转换成精灵对象。接下来,就可以根据body的位置来更新精灵的位置了。

View Code
for (Body b = world.GetBodyList(); b != null; b = b.GetNext()){if (b.GetUserData() != null){CCSprite ballData = (CCSprite)b.GetUserData();ballData.position = new CCPoint((float)(b.GetPosition().X * PTM_RATIO),(float)(b.GetPosition().Y * PTM_RATIO));ballData.rotation = -1 * MathHelper.ToDegrees(b.GetAngle());}}

最后在AppDelegate.cs里面的applicationDidFinishLaunching修改场景入口就可以看到效果了。

附上所有代码:

View Code
 1 class BOX2DLayer:CCLayer
 2     {
 3         //定义了一个“像素/米”的比率。当你在cocos2d里面指定一个body在哪个位置时,你使用的单位要是米
 4         public static double PTM_RATIO = 32.0;
 5 
 6         World world;
 7         Body body;
 8         CCSprite ball;
 9 
10         public override bool init()
11         {
12             if (!base.init())
13                 return false;
14             //获取窗口大小
15             CCSize winSize = CCDirector.sharedDirector().getWinSize();
16 
17             CCLabelTTF title = CCLabelTTF.labelWithString("Boxing", "Arial", 24);
18             title.position = new CCPoint(winSize.width / 2, winSize.height / 2 - 50);
19             this.addChild(title, 1);
20 
21             ball = CCSprite.spriteWithFile("images/ball");
22             ball.position = new CCPoint(0, 300);
23             this.addChild(ball);
24 
25             
26          Vector2 gravity = new Vector2(30.0f, 0.0f);
27             bool doSleep = true;
28             world = new World(gravity, doSleep);
29 
30             BodyDef groundBodyDef = new BodyDef();
31             groundBodyDef.position = new Vector2(0, 0);
32             Body groundBody = world.CreateBody(groundBodyDef);
33             PolygonShape groundBox = new PolygonShape();//凸多边形
34             FixtureDef boxShapeDef = new FixtureDef();
35             boxShapeDef.shape = groundBox;
36             groundBox.SetAsEdge(new Vector2(0, 0), new Vector2((float)(winSize.width / PTM_RATIO), 0));
37             groundBody.CreateFixture(boxShapeDef);
38             groundBox.SetAsEdge(new Vector2(0, 0), new Vector2(0, (float)(winSize.height / PTM_RATIO)));
39             groundBody.CreateFixture(boxShapeDef);
40             groundBox.SetAsEdge(new Vector2(0, (float)(winSize.height / PTM_RATIO)), 
41                 new Vector2((float)(winSize.width / PTM_RATIO), (float)(winSize.height / PTM_RATIO)));
42             groundBody.CreateFixture(boxShapeDef);
43             groundBox.SetAsEdge(new Vector2((float)(winSize.width / PTM_RATIO), (float)(winSize.height / PTM_RATIO)),
44                 new Vector2((float)(winSize.width / PTM_RATIO), 0));
45             groundBody.CreateFixture(boxShapeDef);
46 
47             BodyDef ballBodyDef = new BodyDef();
48             ballBodyDef.type = BodyType.Dynamic;//动态类型
49          ballBodyDef.position=new Vector2((float)(100/PTM_RATIO),(float)(300/PTM_RATIO));
50             ballBodyDef.userData=ball;
51 
52             body=world.CreateBody(ballBodyDef);
53             CircleShape circle=new CircleShape();
54             circle._radius=(float)(26.0/PTM_RATIO);
55 
56             FixtureDef ballShapeDef=new FixtureDef();
57             ballShapeDef.shape=circle;
58             ballShapeDef.density=1.0f;//质量:0代表静态的物体,1代表运动物体
59          ballShapeDef.friction=0.0f;//摩擦
60          ballShapeDef.restitution=1.0f;//恢复力
61          body.CreateFixture(ballShapeDef);
62 
63             
64             this.schedule(tick);
65             return true;
66         }
67 
68         void tick(float dt)
69         {
70             world.Step(dt, 10, 10);
71 
72             for (Body b = world.GetBodyList(); b != null; b = b.GetNext())
73             {
74                 if (b.GetUserData() != null)
75                 {
76                     CCSprite ballData = (CCSprite)b.GetUserData();
77                     ballData.position = new CCPoint((float)(b.GetPosition().X * PTM_RATIO),
78                     (float)(b.GetPosition().Y * PTM_RATIO));
79                     ballData.rotation = -1 * MathHelper.ToDegrees(b.GetAngle());
80                 }
81             }
82         }
83 
84         public static new CCLayer node()
85         {
86             BOX2DLayer layer = new BOX2DLayer();
87             if (layer.init())
88             {
89                 return layer;
90             }
91             else
92                 layer = null;
93             return layer;
94         }
95 
96     }

 

 

 

 

转载于:https://www.cnblogs.com/dieaz5/archive/2013/03/23/2977723.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/433767.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python中集合运算_Python中的集合操作与集合运算

Python中的集合是一种无序的,无重复值的数据结构类型。Python中的集合可以用来检测元素检测或消除重复的元素。 一、python 集合概述 (1)Python中的集合元素是无序的,即元素没有顺序问题,也不能像数组、列表、字符串那…

Asp.net 定时任务

1.定时器 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.IO; using System.Text; using System.Web.Security; using System.Web.SessionState; using System.Timers;namespace WebApplication1 {public class Global :…

python程序怎么修改_python文件如何修改

以占用内存的方式修改文件 待修改的文件 word1.txt,文件内容如下:现在要将文中的“汪淼”修改为“WM”,代码如下:#!-*-coding:utf-8-*- old_str 汪淼 new_str WM f1 open(word1.txt,r,encoding"utf-8") #…

mysql 计算近30天总金额_mysql┃一条更新语句是怎么执行的???

本文共:3018字 预计阅读时间:8分钟文章首发于我的微信公众号:哪儿来的moon,欢迎大家关注mysql┃一条更新语句是怎么执行的???前言 通过上一篇文章的内容,大家已经对mysql的基本架构有…

arduinowifi.send怎么获取响应_ChatterBot代码解读-获取对话

这个过程比较复制,安装处理的流程,依次进行代码解读。在定义一个ChatBot后,可以进行对话的训练,这个过程参考:水中的鱼:ChatterBot代码解读-训练数据​zhuanlan.zhihu.com然后就是用如下的代码&…

beautifulsoup网页爬虫解析_Python爬虫神器:PyQuery,解析网页更简单,小白也能学会

图/文:迷神我们做python爬虫,通过requests抓取到内容就需要正则匹配,或者其他解析库解析内容。很多可能和我一样的人,都使用jquery的,那用的还是非常爽的。而pyquery库就是jQuery的Python实现,能够以jQuery…

unityios开发--加载视频以及加载完成之后自动跳转 .

在做游戏或者是虚拟漫游一般都会用到在开始的时候加载一段视频,这个视频可能一个介绍整个游戏或者是整个项目的。在加载完了之后自动的跳转到主画面或一个场景,在前在网上百度了一下找到的大部分都是win的好不容易找到了ios的。 Unity3D中播放游戏视频的…

rnn神经网络模型_一文读懂序列建模(deeplearning.ai)之循环神经网络(RNNs)

作者:Pulkit Sharma,2019年1月21日翻译:陈之炎校对:丁楠雅本文为你详细介绍序列模型,并分析其在不同的真实场景中的应用。简介如何预测一个序列中接下来要发生什么事情是一个非常吸引人的课题,这是我对数据…

am335x uart5配置

任务:配置uart5

ubuntu下制作u盘镜像_deepin下制作win10启动U盘

1.准备①下载multibootusb:http://multibootusb.org/page_download/ ②准备一个win10的镜像文件 ③准备一个U盘,最好先备份U盘数据再格式化一道2.打开multibootusb工具输入开机密码,点击认证3.multibootusb操作部分①选择U盘的第一个分区 ②安…

centos7 安装git_Centos7.4 Yapi 服务搭建

Centos Yapi服务搭建转载请标明原文出处参考以下网址,排名不分先后https://github.com/YMFE/yapihttps://blog.csdn.net/guangzhou007_java/article/details/90779222https://www.jianshu.com/p/994bc7b19b26我的服务器环境阿里云服务器 centos 7.4使用 https://one…

python中execute函数_Python中的函数定义与参数使用

本节知识点:(1)函数定义格式;(2)五种参数使用函数定义 基本语法格式def function_name( parameter_list ): return values函数通常为小写英语单词及其组合,以下划线隔开,例如:sum、mean、cost_calculat…

内存spd规范_C语言内存泄露很严重,如何应对?

原文:https://blog.csdn.net/devcloud/article/details/1083359121.前言 最近部门不同产品接连出现内存泄漏导致的网上问题,具体表现为单板在现网运行数月以后,因为内存耗尽而导致单板复位现象。一方面,内存泄漏问题属于低级错误&…

接口测试的持续集成的工具(git代码管理工具,jenkins持续集成)

持续集成的概念:大白话就是持续的做一件事情,使其使用起来更加流畅;结合测试来讲就是说用工具管理好代码的同时,使代码运行的更加自动以及智能;提升测试效率。 ⽹址:https://git-scm.com/downloads 长这个…

Java学习笔记—UDP通信

一、UDP通信原理 UDP协议(用户数据报协议 User Datagram Protocol)是一种无连接通信协议, 即在数据传输时数据发送端和接收端不建立逻辑链接。因此UDP协议是一种 不可靠的网络协议,它在通信的两端各建立一个Socket对象,但是这两个 Socket只是…

qt调用import sys库_Python模块之 sys 模块

引入1.什么是 sys 模块sys 模块是与 Python 解释器交互的一个接口该模块提供对解释器使用或维护的一些变量的访问和获取它提供了许多函数和变量来处理 Python 运行时环境的不同部分一.常见用法介绍1.sys.argv实现从程序的外部向程序传递参数返回的是一个列表, 第一个元素是程序…

A20 lvds

LVDS0: 数据线 LVDS0-VP0 LVDS0-VN0 LVDS0-VP1 LVDS0-VN1 LVDS0-VP2 LVDS0-VN2 时钟线 LVDS0-VPC LVDS0-VNC 电源线 插座的1,2,3接电源,最终连到 LCD-PWR 背光 另外背光单独在另一个插座上,LVDS0和LVDS1是一致的。 4…

顺丰快递单号的规律_顺丰快递顺丰快递查询单号查询

查询快递前:请先点击上面蓝字” 顺风快递快件单号查询“关注,关注后即可免费查询快递!顺丰快递 顺丰快递查询 顺丰快递单号查询记下货物的订单号码。打开顺丰快递的官方网站。快件追踪中写入要查询的订单号码。输入订单号、验证码…

Java学习笔记—TCP通信

一、TCP通信原理 TCP(Transmission Control Protocol)协议是面向链接的通信协议,即数据传输之前,先在发送端和接收端建立逻辑链接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。TCP通信中必须明确客户端和服务器端…

Python 网页编程- Pyramid 安装测试

http://docs.pylonsproject.org/projects/pyramid/en/1.4-branch/narr/install.html 是我在csdn的博客:http://blog.csdn.net/spaceship20008/article/details/8767884 放在cnblogs做备份 按照介绍操作。 我用的是mint13, python 3.2.3版本。 使用的是virtualenv 开…