1 3.0物理系统PhysicsWorld

T07PhysicsWorld.h

#ifndef
__T07PhysicsWorld_H__

#define
__T07PhysicsWorld_H__

#include
"T32.h"

class
T07PhysicsWorld :
public
Layer

{

public:

CREATE_FUNC(T07PhysicsWorld);

bool
init();

Scene*
getScene(){
return (Scene*)getParent();
}

};

#endif

T07PhysicsWorld.cpp

#include
"T07PhysicsWorld.h"

bool
T07PhysicsWorld::init()

{

Layer::init();

PhysicsBody*
bodyA;

PhysicsBody*
bodyB;

{

//后面的三个参数值分别表示的是:密度,弹性值,摩擦力

PhysicsBody*
body =
PhysicsBody::createCircle(20,
PhysicsMaterial(1.0f, 1.0f, 0.0f));

bodyA =
body;

//创建精灵

Sprite*
sprite =
Sprite::create();

//设置

sprite->setPhysicsBody(body);

addChild(sprite);

//设置精灵的位置

sprite->setPosition(winSize.width
/ 2, winSize.height
/ 2);

//设置速度

body->setVelocity(Vect(100,
200));

}

{

PhysicsBody*
body =
PhysicsBody::createEdgeBox(winSize,
PhysicsMaterial(1.0f, 1.0f, 0.0f));

bodyB =
body;

Sprite*
sprite =
Sprite::create();

addChild(sprite);

sprite->setPhysicsBody(body);

sprite->setPosition(winSize.width
/ 2, winSize.height
/ 2);

}

{

bodyA->setContactTestBitmask(0x1);

bodyB->setContactTestBitmask(0x1);

bodyA->setGroup(1);

bodyB->setGroup(2);

//设置精灵的

auto
ev =
EventListenerPhysicsContactWithBodies::create(bodyA,
bodyB);

ev->onContactBegin
= [](PhysicsContact&
contact){

CCLog("Began
Contact...........");

return
true;

};

_eventDispatcher->addEventListenerWithSceneGraphPriority(ev,
this);

}

{

auto
ev =
EventListenerPhysicsContactWithShapes::create(bodyA->getShapes().at(0),

bodyB->getShapes().at(0));

ev->onContactBegin
= [](PhysicsContact&
contact){

CCLog("Shape
Began Contact...........");

return
true;

};

_eventDispatcher->addEventListenerWithSceneGraphPriority(ev,
this);

}

{

auto
ev =
EventListenerPhysicsContactWithGroup::create(3);

ev->onContactBegin
= [](PhysicsContact&
contact){

CCLog("Group
Began Contact...........");

return
true;

};

_eventDispatcher->addEventListenerWithSceneGraphPriority(ev,
this);

}

return
true;

}

TMenu.h

#ifndef
__TMenu_H__

#define
__TMenu_H__

#include
"T32.h"

class
TMenu :
public
Layer

{

public:

CREATE_FUNC(TMenu);

bool
init();

bool
TouchBegan(Touch*,
Event*);

};

#endif

TMenu.cpp

#include
"TMenu.h"

#include
"TBack.h"

#include
"T01CPP11.h"

#include
"T02Vector.h"

#include
"T03Map.h"

#include
"T04Label.h"

#include
"T05Touch.h"

#include
"T06Box2D.h"

#include
"T07PhysicsWorld.h"

static
const
char*
title[] = {

"T01CPP11",

"T02Vector",

"T04Label",

"T05Touch",

"T06Box2D",

"T07PhysicsWorld"

};

bool
TMenu::init()

{

Layer::init();

Menu*
menu =
Menu::create();

addChild(menu);

for (int
i = 0;
i <
sizeof(title)
/ sizeof(*title);
++i)

{

MenuItemFont*
item =
MenuItemFont::create(title[i],
[](Ref*
sender){

MenuItem*
item = (MenuItem*)sender;

int
i =
item->getTag()
- 1000;

Layer*
l =
NULL;

if (title[i]
== "T01CPP11")  
l =
T01CPP11::create();

if (title[i]
== "T02Vector")  
l =
T02Vector::create();

if (title[i]
== "T04Label")
l =
T04Label::create();

if (title[i]
== "T05Touch")
l =
T05Touch::create();

if (title[i]
== "T06Box2D")
l =
T06Box2D::create();

if (title[i]
== "T07PhysicsWorld")
l =
T07PhysicsWorld::create();

if (l)

{

TBack*
b =
TBack::create();

Scene*
s =
Scene::createWithPhysics();

PhysicsWorld*
world =
s->getPhysicsWorld();

world->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);

s->addChild(b);

s->addChild(l);

Director::getInstance()->pushScene(s);

}

});

menu->addChild(item);

item->setTag(1000
+ i);

}

menu->alignItemsVertically();

//
触摸

auto
ev =
EventListenerTouchOneByOne::create();

#if 0

ev->onTouchBegan
= [](Touch*,
Event*){

return
true;

};

#endif

//ev->onTouchBegan = std::bind(&TMenu::TouchBegan, this, std::placeholders::_1, std::placeholders::_2);

ev->onTouchBegan
= CC_CALLBACK_2(TMenu::TouchBegan,
this);

ev->onTouchMoved
= [&](Touch*
touch,
Event*){

setPositionY(getPositionY()
+ touch->getDelta().y);

};

_eventDispatcher->addEventListenerWithSceneGraphPriority(ev,
this);

return
true;

}

bool
TMenu::TouchBegan(/*TMEnu*
this, */Touch*,
Event*)

{

return
true;

}

运行结果:

射线的做法

T08RayCast.h

#ifndef
__T08RayCast_H__

#define
__T08RayCast_H__

#include
"T32.h"

class
T08RayCast :public
Layer

{

public:

CREATE_FUNC(T08RayCast);

bool
init();

void
onEnter();

void
update(float);

Sprite*
_cat;

int
_angle;

int
_distance;

float
_nearDis;

PhysicsShape*
_food;

DrawNode*
_drawNode;

};

#endif

T08RayCast.cpp

#include
"T08RayCast.h"

void
T08RayCast::onEnter()

{

Layer::onEnter();

Scene*
scene = (Scene*)getParent();

scene->getPhysicsWorld()->setGravity(Vec2(0,
0));

}

bool
T08RayCast::init()

{

Layer::init();

//
创建猫,猫不是Body,只是一个简单的精灵

{

Sprite*
cat =
Sprite::create("CloseNormal.png");

addChild(cat);

cat->setPosition(winSize.width
/ 2, winSize.height
/ 2);

_cat =
cat;

}

//
投放食物,食物必须是body

{

auto
ev =
EventListenerTouchOneByOne::create();

ev->onTouchBegan
= [&](Touch*
touch,
Event*){

//得到触摸点

Vec2
pt =
touch->getLocation();

//创建一个圆形的PhysicsBody

PhysicsBody*
body =
PhysicsBody::createCircle(10);

Sprite*
sprite =
Sprite::create();

sprite->setPhysicsBody(body);

addChild(sprite);

sprite->setPosition(pt);

return
true;

};

_eventDispatcher->addEventListenerWithSceneGraphPriority(ev,
this);

}

{

_angle = 0;     
//角度

_distance = 100;
//距离

_nearDis =
_distance + 100;

_food =
NULL;

_drawNode =
NULL;

}

scheduleUpdate();

return
true;

}

void
T08RayCast::update(float
dt)

{

Scene*
scene = (Scene*)getParent();

PhysicsWorld*
world =
scene->getPhysicsWorld();

//获得猫的位置

Vec2
start =
_cat->getPosition();

Vec2
end;

//当前时刻扫描到的终点位置

end.x
= start.x
+ sinf(_angle
/ 180.0 * M_PI)*_distance;

end.y
= start.y
+ cosf(_angle
/ 180.0 * M_PI)*_distance;

//
显示扫描距离

if (_drawNode)
_drawNode->removeFromParent();

//下面的代码用于画线段

_drawNode =
DrawNode::create();

_drawNode->drawSegment(start,
end, 1,
Color4F(1, 0, 0, 1));

addChild(_drawNode);

//
扫描回调函数

//bool(PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data)

auto
callback = [&](PhysicsWorld&
world,
const
PhysicsRayCastInfo&
info,
void*
data){

if (info.shape
== NULL)

return
true;

//如果点包含猫的点

float
dis =
info.contact.getDistance(_cat->getPosition());

if (dis
< _nearDis)

{

_nearDis =
dis;

_food =
info.shape;

}

//
扫描到一个就不要再继续了

return
false;

};

//通过rayCast画一条射线

world->rayCast(callback,
start,
end,
NULL);

//每次角度加2

_angle += 2;

//如果角度为360

if (_angle
== 360)

{

//如果存在食物

if (_food)

{

//
吃掉食物

Node*
node =
_food->getBody()->getNode();

//将猫的的位置数值到新的位置

_cat->setPosition(node->getPosition());

node->removeFromParent();

_food =
NULL;

_nearDis =
_distance + 100;

}

_angle = 0;

}

}

运行结果:

1 3.0物理系统PhysicsWorld

T07PhysicsWorld.h

#ifndef
__T07PhysicsWorld_H__

#define
__T07PhysicsWorld_H__

#include
"T32.h"

class
T07PhysicsWorld :
public
Layer

{

public:

CREATE_FUNC(T07PhysicsWorld);

bool
init();

Scene*
getScene(){
return (Scene*)getParent();
}

};

#endif

T07PhysicsWorld.cpp

#include
"T07PhysicsWorld.h"

bool
T07PhysicsWorld::init()

{

Layer::init();

PhysicsBody*
bodyA;

PhysicsBody*
bodyB;

{

//后面的三个参数值分别表示的是:密度,弹性值,摩擦力

PhysicsBody*
body =
PhysicsBody::createCircle(20,
PhysicsMaterial(1.0f, 1.0f, 0.0f));

bodyA =
body;

//创建精灵

Sprite*
sprite =
Sprite::create();

//设置

sprite->setPhysicsBody(body);

addChild(sprite);

//设置精灵的位置

sprite->setPosition(winSize.width
/ 2, winSize.height
/ 2);

//设置速度

body->setVelocity(Vect(100,
200));

}

{

PhysicsBody*
body =
PhysicsBody::createEdgeBox(winSize,
PhysicsMaterial(1.0f, 1.0f, 0.0f));

bodyB =
body;

Sprite*
sprite =
Sprite::create();

addChild(sprite);

sprite->setPhysicsBody(body);

sprite->setPosition(winSize.width
/ 2, winSize.height
/ 2);

}

{

bodyA->setContactTestBitmask(0x1);

bodyB->setContactTestBitmask(0x1);

bodyA->setGroup(1);

bodyB->setGroup(2);

//设置精灵的

auto
ev =
EventListenerPhysicsContactWithBodies::create(bodyA,
bodyB);

ev->onContactBegin
= [](PhysicsContact&
contact){

CCLog("Began
Contact...........");

return
true;

};

_eventDispatcher->addEventListenerWithSceneGraphPriority(ev,
this);

}

{

auto
ev =
EventListenerPhysicsContactWithShapes::create(bodyA->getShapes().at(0),

bodyB->getShapes().at(0));

ev->onContactBegin
= [](PhysicsContact&
contact){

CCLog("Shape
Began Contact...........");

return
true;

};

_eventDispatcher->addEventListenerWithSceneGraphPriority(ev,
this);

}

{

auto
ev =
EventListenerPhysicsContactWithGroup::create(3);

ev->onContactBegin
= [](PhysicsContact&
contact){

CCLog("Group
Began Contact...........");

return
true;

};

_eventDispatcher->addEventListenerWithSceneGraphPriority(ev,
this);

}

return
true;

}

TMenu.h

#ifndef
__TMenu_H__

#define
__TMenu_H__

#include
"T32.h"

class
TMenu :
public
Layer

{

public:

CREATE_FUNC(TMenu);

bool
init();

bool
TouchBegan(Touch*,
Event*);

};

#endif

TMenu.cpp

#include
"TMenu.h"

#include
"TBack.h"

#include
"T01CPP11.h"

#include
"T02Vector.h"

#include
"T03Map.h"

#include
"T04Label.h"

#include
"T05Touch.h"

#include
"T06Box2D.h"

#include
"T07PhysicsWorld.h"

static
const
char*
title[] = {

"T01CPP11",

"T02Vector",

"T04Label",

"T05Touch",

"T06Box2D",

"T07PhysicsWorld"

};

bool
TMenu::init()

{

Layer::init();

Menu*
menu =
Menu::create();

addChild(menu);

for (int
i = 0;
i <
sizeof(title)
/ sizeof(*title);
++i)

{

MenuItemFont*
item =
MenuItemFont::create(title[i],
[](Ref*
sender){

MenuItem*
item = (MenuItem*)sender;

int
i =
item->getTag()
- 1000;

Layer*
l =
NULL;

if (title[i]
== "T01CPP11")  
l =
T01CPP11::create();

if (title[i]
== "T02Vector")  
l =
T02Vector::create();

if (title[i]
== "T04Label")
l =
T04Label::create();

if (title[i]
== "T05Touch")
l =
T05Touch::create();

if (title[i]
== "T06Box2D")
l =
T06Box2D::create();

if (title[i]
== "T07PhysicsWorld")
l =
T07PhysicsWorld::create();

if (l)

{

TBack*
b =
TBack::create();

Scene*
s =
Scene::createWithPhysics();

PhysicsWorld*
world =
s->getPhysicsWorld();

world->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);

s->addChild(b);

s->addChild(l);

Director::getInstance()->pushScene(s);

}

});

menu->addChild(item);

item->setTag(1000
+ i);

}

menu->alignItemsVertically();

//
触摸

auto
ev =
EventListenerTouchOneByOne::create();

#if 0

ev->onTouchBegan
= [](Touch*,
Event*){

return
true;

};

#endif

//ev->onTouchBegan = std::bind(&TMenu::TouchBegan, this, std::placeholders::_1, std::placeholders::_2);

ev->onTouchBegan
= CC_CALLBACK_2(TMenu::TouchBegan,
this);

ev->onTouchMoved
= [&](Touch*
touch,
Event*){

setPositionY(getPositionY()
+ touch->getDelta().y);

};

_eventDispatcher->addEventListenerWithSceneGraphPriority(ev,
this);

return
true;

}

bool
TMenu::TouchBegan(/*TMEnu*
this, */Touch*,
Event*)

{

return
true;

}

运行结果:

射线的做法

T08RayCast.h

#ifndef
__T08RayCast_H__

#define
__T08RayCast_H__

#include
"T32.h"

class
T08RayCast :public
Layer

{

public:

CREATE_FUNC(T08RayCast);

bool
init();

void
onEnter();

void
update(float);

Sprite*
_cat;

int
_angle;

int
_distance;

float
_nearDis;

PhysicsShape*
_food;

DrawNode*
_drawNode;

};

#endif

T08RayCast.cpp

#include
"T08RayCast.h"

void
T08RayCast::onEnter()

{

Layer::onEnter();

Scene*
scene = (Scene*)getParent();

scene->getPhysicsWorld()->setGravity(Vec2(0,
0));

}

bool
T08RayCast::init()

{

Layer::init();

//
创建猫,猫不是Body,只是一个简单的精灵

{

Sprite*
cat =
Sprite::create("CloseNormal.png");

addChild(cat);

cat->setPosition(winSize.width
/ 2, winSize.height
/ 2);

_cat =
cat;

}

//
投放食物,食物必须是body

{

auto
ev =
EventListenerTouchOneByOne::create();

ev->onTouchBegan
= [&](Touch*
touch,
Event*){

//得到触摸点

Vec2
pt =
touch->getLocation();

//创建一个圆形的PhysicsBody

PhysicsBody*
body =
PhysicsBody::createCircle(10);

Sprite*
sprite =
Sprite::create();

sprite->setPhysicsBody(body);

addChild(sprite);

sprite->setPosition(pt);

return
true;

};

_eventDispatcher->addEventListenerWithSceneGraphPriority(ev,
this);

}

{

_angle = 0;     
//角度

_distance = 100;
//距离

_nearDis =
_distance + 100;

_food =
NULL;

_drawNode =
NULL;

}

scheduleUpdate();

return
true;

}

void
T08RayCast::update(float
dt)

{

Scene*
scene = (Scene*)getParent();

PhysicsWorld*
world =
scene->getPhysicsWorld();

//获得猫的位置

Vec2
start =
_cat->getPosition();

Vec2
end;

//当前时刻扫描到的终点位置

end.x
= start.x
+ sinf(_angle
/ 180.0 * M_PI)*_distance;

end.y
= start.y
+ cosf(_angle
/ 180.0 * M_PI)*_distance;

//
显示扫描距离

if (_drawNode)
_drawNode->removeFromParent();

//下面的代码用于画线段

_drawNode =
DrawNode::create();

_drawNode->drawSegment(start,
end, 1,
Color4F(1, 0, 0, 1));

addChild(_drawNode);

//
扫描回调函数

//bool(PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data)

auto
callback = [&](PhysicsWorld&
world,
const
PhysicsRayCastInfo&
info,
void*
data){

if (info.shape
== NULL)

return
true;

//如果点包含猫的点

float
dis =
info.contact.getDistance(_cat->getPosition());

if (dis
< _nearDis)

{

_nearDis =
dis;

_food =
info.shape;

}

//
扫描到一个就不要再继续了

return
false;

};

//通过rayCast画一条射线

world->rayCast(callback,
start,
end,
NULL);

//每次角度加2

_angle += 2;

//如果角度为360

if (_angle
== 360)

{

//如果存在食物

if (_food)

{

//
吃掉食物

Node*
node =
_food->getBody()->getNode();

//将猫的的位置数值到新的位置

_cat->setPosition(node->getPosition());

node->removeFromParent();

_food =
NULL;

_nearDis =
_distance + 100;

}

_angle = 0;

}

}

运行结果:

1.物理系统PhysicsWorld,RayCast的更多相关文章

  1. Atitit 游戏引擎---物理系统(1)------爆炸效果

    Atitit 游戏引擎---物理系统(1)------爆炸效果 1.1. 动画框架的来源flex,jqueryuijs,anim , cocos2d 1 1.2. Jqueryui的特效库 1 1.3 ...

  2. 物理系统迁移虚拟化P2V技术

    企业搭建虚拟化平台之后的第一件事肯定是将现有的服务器应用业务转移到虚拟服务器上,这就是虚拟化整合服务器的第一步,也是虚拟化程序的基础功能之一:P2V的转化功能. AD:   企业搭建虚拟化平台之后的第 ...

  3. nVidia的物理系统

    PhysX PhysX(wiki en  中文,physx wiki   physx wiki2)是nVidia公司一款跨平台实时物理引擎,可使用硬件(GPU.PPU: Physics Process ...

  4. Physics(物理系统)

    物理: Physics            Box2d   Unity 内置NVDIA PhysX物理引擎 刚体:要使一个物体在物理控制下,简单添加一个刚体给它.这时,物体将受重力影响,并可以与其他 ...

  5. Unity物理系统的触发器

    如何触发触发器函数? 触发器中相互的,当其中一个是触发器,两个物体进入碰撞,双方的触发器函数都会触发. 两个碰撞盒穿入? 解决办法:给其中一个添加刚体 触发器的物理配置 以上是个人理解,看过API之后 ...

  6. Unity3D学习笔记(四):物理系统碰撞和预制体

    Rigidbody(刚体组件):加了此组件游戏物体就变成刚体了 ----Mass(质量,单位kg):重力G = 质量m * 重力加速度g(g=9.81 m/s^2) --------冲量守恒定理 动量 ...

  7. 【腾讯GAD暑期训练营游戏程序班】游戏中的物理系统作业说明文档

    一.需求分析• 添加一辆新NPC车,可以让其与主角车碰撞:• 添加一些新物件,能够与车互动,在其触发事件将其移除:• 添加一些无法撞动的事件:• 添加NPC车的自动移动逻辑:• 在课上赛车的示例上添加 ...

  8. Swift游戏实战-跑酷熊猫 11 欢迎进入物理世界

    物理模拟是一个奇妙的事情,以此著名的游戏有愤怒的小鸟.我们在这节将会一起来了解如何设置重力,设置物理包围体,碰撞的检测. 要点: 设置物理检测的代理: 让主场景遵循SKPhysicsContactDe ...

  9. Unity Animation System(动画系统)

    动画系统: 支持:动画融合,混合,叠加动画,行走循环的时间同步,动画层,控制动画的各个方面(时间,速度,融合权重)   带有每顶点1.2或4骨骼的蒙皮网格,以及支持基于物理的布娃娃系统和程序动画.   ...

随机推荐

  1. mongo 服务化与删除

    MONGO  服务化 使用超级用户进入cmd到D:\mongodb\bin> 日志文件需要提前创建 mongod --bind_ip 0.0.0.0 --logpath D:\mongodb\d ...

  2. [APIO 2016]Gap

    Description 题库链接 给你一个长度为 \(N\) 的单调递增序列 \(A\) .交互时允许你调用 MinMax(s, t, &mn, &mx) 函数,表示序列元素的值在 \ ...

  3. [HNOI 2016]序列

    Description 题库链接 给你一个长度为 \(n\) 的序列 \(A\) ,给出 \(q\) 组询问.每次询问 \([l,r]\) ,求该区间内所有的子序列中最小值的和. \(1\leq n, ...

  4. 【HNOI2017】影魔

    题目描述 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄. 每一个灵魂,都有着自 ...

  5. [BZOJ]1079 着色方案(SCOI2008)

    相邻色块不同的着色方案,似乎这道题已经见过3个版本了. Description 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块.所有油漆刚好足够 ...

  6. 华科机考:a+b

    时间限制:1秒     空间限制:32768K 题目描述 实现一个加法器,使其能够输出a+b的值. 输入描述: 输入包括两个数a和b,其中a和b的位数不超过1000位. 输出描述: 可能有多组测试数据 ...

  7. class-map与policy-map 配置与qos模版

    将subnet-a 与subnet-b 归入类class1 中.Router1(config)# ip access-list extended subnet-a Router1(config-std ...

  8. drools 手动创建kmoudle.xml文件

    @Test public void test() { KieServices kieServices = KieServices.Factory.get(); KieResources resourc ...

  9. 初识Redis系列之二:安装及简单使用

    仅介绍windows下的安装 一:下载地址:https://github.com/MSOpenTech/redis/releases. Redis 支持 32 位和 64 位.这个需要根据你系统平台的 ...

  10. supervisor使用,配置和安装(包括监控守护进程httpd,keepalived)

    yum -y install supervisor(如果安装不成功,需要更新源,yum -y install epel) 或者: wget --no-check-certificate https:/ ...