Merge commit 'refs/pull/5071/head' of git://github.com/cocos2d/cocos2d-x into merge5071

This commit is contained in:
James Chen 2014-01-26 16:41:35 +08:00
commit a4a010465c
10 changed files with 493 additions and 22 deletions

View File

@ -58,7 +58,7 @@ typedef struct PhysicsContactData
/**
* @brief Contact infomation. it will created automatically when two shape contact with each other. and it will destoried automatically when two shape separated.
*/
class PhysicsContact : Event
class PhysicsContact : public Event
{
public:

View File

@ -55,7 +55,7 @@ typedef struct PhysicsRayCastInfo
{
PhysicsShape* shape;
Point start;
Point end;
Point end; //< in lua, it's name is "ended"
Point contact;
Vect normal;
float fraction;

View File

@ -1615,7 +1615,7 @@ void physics_raycastinfo_to_luaval(lua_State* L, const PhysicsRayCastInfo& info)
point_to_luaval(L, info.start);
lua_rawset(L, -3); /* table[key] = value, L: table */
lua_pushstring(L, "end"); /* L: table key */
lua_pushstring(L, "ended"); /* L: table key */
point_to_luaval(L, info.end);
lua_rawset(L, -3); /* table[key] = value, L: table */
@ -1632,6 +1632,26 @@ void physics_raycastinfo_to_luaval(lua_State* L, const PhysicsRayCastInfo& info)
lua_rawset(L, -3); /* table[key] = value, L: table */
}
void physics_contactdata_to_luaval(lua_State* L, const PhysicsContactData* data)
{
if (nullptr == L || nullptr == data)
return;
lua_newtable(L); /* L: table */
lua_pushstring(L, "points");
points_to_luaval(L, data->points, data->count);
lua_rawset(L, -3);
lua_pushstring(L, "normal");
point_to_luaval(L, data->normal);
lua_rawset(L, -3);
lua_pushstring(L, "POINT_MAX");
lua_pushnumber(L, data->POINT_MAX);
lua_rawset(L, -3);
}
void size_to_luaval(lua_State* L,const Size& sz)
{
if (NULL == L)

View File

@ -205,6 +205,7 @@ extern void color4b_to_luaval(lua_State* L,const Color4B& cc);
extern void color4f_to_luaval(lua_State* L,const Color4F& cc);
extern void physics_material_to_luaval(lua_State* L,const PhysicsMaterial& pm);
extern void physics_raycastinfo_to_luaval(lua_State* L, const PhysicsRayCastInfo& info);
extern void physics_contactdata_to_luaval(lua_State* L, const PhysicsContactData* data);
extern void affinetransform_to_luaval(lua_State* L,const AffineTransform& inValue);
extern void fontdefinition_to_luaval(lua_State* L,const FontDefinition& inValue);
extern void array_to_luaval(lua_State* L,Array* inValue);

View File

@ -155,6 +155,11 @@ public:
EVENT_MOUSE_SCROLL,
EVENT_SPINE,
EVENT_PHYSICS_CONTACT_BEGIN,
EVENT_PHYSICS_CONTACT_PRESOLVE,
EVENT_PHYSICS_CONTACT_POSTSOLVE,
EVENT_PHYSICS_CONTACT_SEPERATE,
};
typedef int Handler;

View File

@ -900,7 +900,6 @@ int lua_cocos2dx_physics_PhysicsShape_getPolyonCenter(lua_State* tolua_S)
if (nullptr == arg0){
LUA_PRECONDITION( arg0, "Invalid Native Object");
}} while (0);
ok &= luaval_to_int32(tolua_S, 3,(int *)&arg1);
if(!ok)
{
CC_SAFE_FREE(arg0);
@ -1138,6 +1137,114 @@ tolua_lerror:
return 0;
}
static int tolua_cocos2dx_EventListenerPhysicsContact_registerScriptHandler(lua_State* tolua_S)
{
if (nullptr == tolua_S)
return 0;
int argc = 0;
EventListenerPhysicsContact* self = nullptr;
#if COCOS2D_DEBUG >= 1
tolua_Error tolua_err;
if (!tolua_isusertype(tolua_S, 1, "EventListenerPhysicsContact", 0, &tolua_err)) goto tolua_lerror;
#endif
self = static_cast<EventListenerPhysicsContact*>(tolua_tousertype(tolua_S,1,0));
#if COCOS2D_DEBUG >= 1
if (nullptr == self) {
tolua_error(tolua_S,"invalid 'self' in function 'tolua_cocos2dx_EventListenerPhysicsContact_registerScriptHandler'\n", nullptr);
return 0;
}
#endif
argc = lua_gettop(tolua_S) - 1;
if (argc == 2)
{
#if COCOS2D_DEBUG >= 1
if (!toluafix_isfunction(tolua_S,2,"LUA_FUNCTION",0,&tolua_err) ||
!tolua_isnumber(tolua_S, 3, 0, &tolua_err))
{
goto tolua_lerror;
}
#endif
LUA_FUNCTION handler = toluafix_ref_function(tolua_S,2,0);
ScriptHandlerMgr::HandlerType type = static_cast<ScriptHandlerMgr::HandlerType>((int)tolua_tonumber(tolua_S, 3, 0));
switch (type)
{
case ScriptHandlerMgr::HandlerType::EVENT_PHYSICS_CONTACT_BEGIN:
{
ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, type);
self->onContactBegin = [handler](EventCustom* event, const PhysicsContact& contact) -> bool{
LuaStack* stack = LuaEngine::getInstance()->getLuaStack();
stack->pushObject(event, "EventCustom");
stack->pushObject(const_cast<PhysicsContact*>(&contact), "PhysicsContact");
bool ret = stack->executeFunctionByHandler(handler, 2);
stack->clean();
return ret;
};
}
break;
case ScriptHandlerMgr::HandlerType::EVENT_PHYSICS_CONTACT_PRESOLVE:
{
ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, type);
self->onContactPreSolve = [handler](EventCustom* event, const PhysicsContact& contact, const PhysicsContactPreSolve& solve) -> bool{
LuaStack* stack = LuaEngine::getInstance()->getLuaStack();
stack->pushObject(event, "EventCustom");
stack->pushObject(const_cast<PhysicsContact*>(&contact), "PhysicsContact");
tolua_pushusertype(stack->getLuaState(), const_cast<PhysicsContactPreSolve*>(&solve), "PhysicsContactPreSolve");
bool ret = stack->executeFunctionByHandler(handler, 3);
stack->clean();
return ret;
};
}
break;
case ScriptHandlerMgr::HandlerType::EVENT_PHYSICS_CONTACT_POSTSOLVE:
{
ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, type);
self->onContactPostSolve = [handler](EventCustom* event, const PhysicsContact& contact, const PhysicsContactPostSolve& solve){
LuaStack* stack = LuaEngine::getInstance()->getLuaStack();
stack->pushObject(event, "EventCustom");
stack->pushObject(const_cast<PhysicsContact*>(&contact), "PhysicsContact");
tolua_pushusertype(stack->getLuaState(), const_cast<PhysicsContactPostSolve*>(&solve), "PhysicsContactPostSolve");
stack->executeFunctionByHandler(handler, 3);
stack->clean();
};
}
break;
case ScriptHandlerMgr::HandlerType::EVENT_PHYSICS_CONTACT_SEPERATE:
{
ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, type);
self->onContactSeperate = [handler](EventCustom* event, const PhysicsContact& contact){
LuaStack* stack = LuaEngine::getInstance()->getLuaStack();
stack->pushObject(event, "EventCustom");
stack->pushObject(const_cast<PhysicsContact*>(&contact), "PhysicsContact");
stack->executeFunctionByHandler(handler, 2);
stack->clean();
};
}
break;
default:
break;
}
return 0;
}
CCLOG("'registerScriptHandler' has wrong number of arguments: %d, was expecting %d\n", argc, 2);
return 0;
#if COCOS2D_DEBUG >= 1
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'registerScriptHandler'.",&tolua_err);
return 0;
#endif
}
int register_all_cocos2dx_physics_manual(lua_State* tolua_S)
{
lua_pushstring(tolua_S, "cc.PhysicsBody");
@ -1254,7 +1361,14 @@ int register_all_cocos2dx_physics_manual(lua_State* tolua_S)
lua_pushnumber(tolua_S, PhysicsWorld::DEBUGDRAW_ALL);
lua_rawset(tolua_S,-3);
}
lua_pop(tolua_S, 1);
lua_pushstring(tolua_S, "EventListenerPhysicsContact");
lua_rawget(tolua_S, LUA_REGISTRYINDEX);
if (lua_istable(tolua_S,-1))
{
tolua_function(tolua_S, "registerScriptHandler", tolua_cocos2dx_EventListenerPhysicsContact_registerScriptHandler);
}
lua_pop(tolua_S, 1);
tolua_constant(tolua_S, "PHYSICS_INFINITY", PHYSICS_INFINITY);

View File

@ -343,6 +343,10 @@ cc.Handler.EVENT_MOUSE_UP = 49
cc.Handler.EVENT_MOUSE_MOVE = 50
cc.Handler.EVENT_MOUSE_SCROLL = 51
cc.Handler.EVENT_SPINE = 52
cc.Handler.EVENT_PHYSICS_CONTACT_BEGIN = 53
cc.Handler.EVENT_PHYSICS_CONTACT_PRESOLVE = 54
cc.Handler.EVENT_PHYSICS_CONTACT_POSTSOLVE = 55
cc.Handler.EVENT_PHYSICS_CONTACT_SEPERATE = 56
cc.EVENT_UNKNOWN = 0
cc.EVENT_TOUCH_ONE_BY_ONE = 1
@ -352,8 +356,8 @@ cc.EVENT_MOUSE = 4
cc.EVENT_ACCELERATION = 5
cc.EVENT_CUSTOM = 6
cc.PHYSICSSHAPE_MATERIAL_DEFAULT = {0.0, 0.5, 0.5}
cc.PHYSICSBODY_MATERIAL_DEFAULT = {0.1, 0.5, 0.5}
cc.PHYSICSSHAPE_MATERIAL_DEFAULT = {density = 0.0, restitution = 0.5, friction = 0.5}
cc.PHYSICSBODY_MATERIAL_DEFAULT = {density = 0.1, restitution = 0.5, friction = 0.5}
cc.GLYPHCOLLECTION_DYNAMIC = 0
cc.GLYPHCOLLECTION_NEHE = 1
cc.GLYPHCOLLECTION_ASCII = 2

View File

@ -1151,7 +1151,6 @@ bool PhysicsDemoSlice::slice(PhysicsWorld &world, const PhysicsRayCastInfo& info
Point normal = info.end - info.start;
normal = normal.getPerp().normalize();
float dist = info.start.dot(normal);
dist = dist;
clipPoly(dynamic_cast<PhysicsShapePolygon*>(info.shape), normal, dist);
clipPoly(dynamic_cast<PhysicsShapePolygon*>(info.shape), -normal, -dist);

View File

@ -26,7 +26,7 @@ local function initWithLayer(layer, callback)
cc.Director:getInstance():getRunningScene():getPhysicsWorld():setDebugDrawMask(debug and cc.PhysicsWorld.DEBUGDRAW_ALL or cc.PhysicsWorld.DEBUGDRAW_NONE)
end
layer.toggleDebug = toggleDebugCallback;
layer.toggleDebug = function(self) toggleDebugCallback(nil) end;
cc.MenuItemFont:setFontSize(18)
local item = cc.MenuItemFont:create("Toogle debug")
item:registerScriptTapHandler(toggleDebugCallback)
@ -291,9 +291,6 @@ local function PhysicsDemoJoints()
for j in range(0, 3) do
local offset = cc.p(VisibleRect:leftBottom().x + 5 + j * width + width/2, VisibleRect:leftBottom().y + 50 + i * height + height/2);
box:addShape(cc.PhysicsShapeEdgeBox:create(cc.size(width, height), cc.PHYSICSSHAPE_MATERIAL_DEFAULT, 1, offset));
print("i,j")
print(i)
print(j)
local index = i*4 + j
if index == 0 then
local sp1 = makeBall(layer, cc.p(offset.x - 30, offset.y), 10);
@ -597,14 +594,340 @@ local function PhysicsDemoRayCast()
return layer
end
local function registerOnEnter()
layer:registerOn(PhysicsDemoLogoSmash)
local function PhysicsDemoOneWayPlatform()
local layer = cc.Layer:create()
local function onEnter()
local touchListener = cc.EventListenerTouchOneByOne:create();
touchListener:registerScriptHandler(onTouchBegan, cc.Handler.EVENT_TOUCH_BEGAN);
touchListener:registerScriptHandler(onTouchMoved, cc.Handler.EVENT_TOUCH_MOVED);
touchListener:registerScriptHandler(onTouchEnded, cc.Handler.EVENT_TOUCH_ENDED);
local eventDispatcher = layer:getEventDispatcher()
eventDispatcher:addEventListenerWithSceneGraphPriority(touchListener, layer);
local ground = cc.Node:create();
ground:setPhysicsBody(cc.PhysicsBody:createEdgeSegment(cc.p(VisibleRect:leftBottom().x, VisibleRect:leftBottom().y + 50), cc.p(VisibleRect:rightBottom().x, VisibleRect:rightBottom().y + 50)));
layer:addChild(ground);
local platform = makeBox(VisibleRect:center(), cc.size(200, 50));
platform:getPhysicsBody():setDynamic(false);
layer:addChild(platform);
local ball = makeBall(layer, cc.p(VisibleRect:center().x, VisibleRect:center().y - 50), 20);
ball:getPhysicsBody():setVelocity(cc.p(0, 150));
ball:getPhysicsBody():setTag(DRAG_BODYS_TAG);
ball:getPhysicsBody():setMass(1.0);
layer:addChild(ball);
local function onContactBegin(event, contact)
return contact:getContactData().normal.y < 0;
end
local contactListener = cc.EventListenerPhysicsContactWithBodies:create(platform:getPhysicsBody(), ball:getPhysicsBody());
contactListener:registerScriptHandler(onContactBegin, cc.Handler.EVENT_PHYSICS_CONTACT_BEGIN);
eventDispatcher:addEventListenerWithSceneGraphPriority(contactListener, layer);
end
initWithLayer(layer, onEnter)
Helper.titleLabel:setString("One Way Platform")
return layer
end
local function PhysicsDemoActions()
local layer = cc.Layer:create()
local function onEnter()
local touchListener = cc.EventListenerTouchOneByOne:create()
touchListener:registerScriptHandler(onTouchBegan, cc.Handler.EVENT_TOUCH_BEGAN)
touchListener:registerScriptHandler(onTouchMoved, cc.Handler.EVENT_TOUCH_MOVED)
touchListener:registerScriptHandler(onTouchEnded, cc.Handler.EVENT_TOUCH_ENDED)
local eventDispatcher = layer:getEventDispatcher()
eventDispatcher:addEventListenerWithSceneGraphPriority(touchListener, layer)
local node = cc.Node:create();
node:setPhysicsBody(cc.PhysicsBody:createEdgeBox(cc.size(VisibleRect:getVisibleRect().width, VisibleRect:getVisibleRect().height)));
node:setPosition(VisibleRect:center());
layer:addChild(node);
local sp1 = addGrossiniAtPosition(layer, VisibleRect:center());
local sp2 = addGrossiniAtPosition(layer, cc.p(VisibleRect:left().x + 50, VisibleRect:left().y));
local sp3 = addGrossiniAtPosition(layer, cc.p(VisibleRect:right().x - 20, VisibleRect:right().y));
local sp4 = addGrossiniAtPosition(layer, cc.p(VisibleRect:leftTop().x + 50, VisibleRect:leftTop().y-50));
sp4:getPhysicsBody():setGravityEnable(false);
local actionTo = cc.JumpTo:create(2, cc.p(100,100), 50, 4);
local actionBy = cc.JumpBy:create(2, cc.p(300,0), 50, 4);
local actionUp = cc.JumpBy:create(2, cc.p(0,50), 80, 4);
local actionByBack = actionBy:reverse();
sp1:runAction(cc.RepeatForever:create(actionUp));
sp2:runAction(cc.RepeatForever:create(cc.Sequence:create(actionBy, actionByBack)));
sp3:runAction(actionTo);
sp4:runAction(cc.RepeatForever:create(cc.Sequence:create(actionBy:clone(), actionByBack:clone())));
end
initWithLayer(layer, onEnter)
Helper.titleLabel:setString("Actions")
return layer
end
local function PhysicsDemoPump()
local layer = cc.Layer:create()
local function onEnter()
layer:toggleDebug();
local distance = 0.0;
local rotationV = 0.0;
local function onTouchBeganEx(touch, event)
onTouchBegan(touch, event)
distance = touch:getLocation().x - VisibleRect:center().x;
return true;
end
local function onTouchMovedEx(touch, event)
onTouchMoved(touch, event);
distance = touch:getLocation().x - VisibleRect:center().x;
end
local function onTouchEndedEx(touch, event)
onTouchEnded(touch, event)
distance = 0;
end
local touchListener = cc.EventListenerTouchOneByOne:create()
touchListener:registerScriptHandler(onTouchBeganEx, cc.Handler.EVENT_TOUCH_BEGAN)
touchListener:registerScriptHandler(onTouchMovedEx, cc.Handler.EVENT_TOUCH_MOVED)
touchListener:registerScriptHandler(onTouchEndedEx, cc.Handler.EVENT_TOUCH_ENDED)
local eventDispatcher = layer:getEventDispatcher()
eventDispatcher:addEventListenerWithSceneGraphPriority(touchListener, layer)
local function update()
for _, body in ipairs(cc.Director:getInstance():getRunningScene():getPhysicsWorld():getAllBodies()) do
if body:getTag() == DRAG_BODYS_TAG and body:getPosition().y < 0.0 then
body:getNode():setPosition(cc.p(VisibleRect:leftTop().x + 75, VisibleRect:leftTop().y + math.random() * 90, 0));
body:setVelocity(cc.p(0, 0));
end
end
local gear = cc.Director:getInstance():getRunningScene():getPhysicsWorld():getBody(1);
if gear then
if distance ~= 0.0 then
rotationV = rotationV + distance/2500.0;
end
if rotationV > 30 then rotationV = 30.0 end
if rotationV < -30 then rotationV = -30.0 end
gear:setAngularVelocity(rotationV);
rotationV = rotationV*0.995;
end
end
layer:scheduleUpdateWithPriorityLua(update, 0);
local node = cc.Node:create();
local body = cc.PhysicsBody:create();
body:setDynamic(false);
local staticMaterial = cc.PhysicsMaterial(cc.PHYSICS_INFINITY, 0, 0.5);
body:addShape(cc.PhysicsShapeEdgeSegment:create(
cc.p(VisibleRect:leftTop().x + 50, VisibleRect:leftTop().y),
cc.p(VisibleRect:leftTop().x + 50, VisibleRect:leftTop().y-130), staticMaterial, 2.0));
body:addShape(cc.PhysicsShapeEdgeSegment:create(
cc.p(VisibleRect:leftTop().x + 190, VisibleRect:leftTop().y),
cc.p(VisibleRect:leftTop().x + 100, VisibleRect:leftTop().y-50), staticMaterial, 2.0));
body:addShape(cc.PhysicsShapeEdgeSegment:create(
cc.p(VisibleRect:leftTop().x + 100, VisibleRect:leftTop().y-50),
cc.p(VisibleRect:leftTop().x + 100, VisibleRect:leftTop().y-90), staticMaterial, 2.0));
body:addShape(cc.PhysicsShapeEdgeSegment:create(
cc.p(VisibleRect:leftTop().x + 50, VisibleRect:leftTop().y-130),
cc.p(VisibleRect:leftTop().x + 100, VisibleRect:leftTop().y-145), staticMaterial, 2.0));
body:addShape(cc.PhysicsShapeEdgeSegment:create(
cc.p(VisibleRect:leftTop().x + 100, VisibleRect:leftTop().y-145),
cc.p(VisibleRect:leftBottom().x + 100, VisibleRect:leftBottom().y + 80), staticMaterial, 2.0));
body:addShape(cc.PhysicsShapeEdgeSegment:create(
cc.p(VisibleRect:leftTop().x + 150, VisibleRect:leftTop().y-80),
cc.p(VisibleRect:leftBottom().x + 150, VisibleRect:leftBottom().y + 80), staticMaterial, 2.0));
body:addShape(cc.PhysicsShapeEdgeSegment:create(
cc.p(VisibleRect:leftTop().x + 150, VisibleRect:leftTop().y-80),
cc.p(VisibleRect:rightTop().x -100, VisibleRect:rightTop().y-150), staticMaterial, 2.0));
body:setCategoryBitmask(1);
for _ in range(1, 6) do
local ball = makeBall(layer, cc.p(VisibleRect:leftTop().x + 75 + math.random() * 90, VisibleRect:leftTop().y), 22, cc.PhysicsMaterial(0.05, 0.0, 0.1));
ball:getPhysicsBody():setTag(DRAG_BODYS_TAG);
layer:addChild(ball);
end
node:setPhysicsBody(body);
layer:addChild(node);
local vec =
{
cc.p(VisibleRect:leftTop().x + 102, VisibleRect:leftTop().y-148),
cc.p(VisibleRect:leftTop().x + 148, VisibleRect:leftTop().y-161),
cc.p(VisibleRect:leftBottom().x + 148, VisibleRect:leftBottom().y + 20),
cc.p(VisibleRect:leftBottom().x + 102, VisibleRect:leftBottom().y + 20)
};
local world = cc.Director:getInstance():getRunningScene():getPhysicsWorld();
-- small gear
local sgear = cc.Node:create();
local sgearB = cc.PhysicsBody:createCircle(44);
sgear:setPhysicsBody(sgearB);
sgear:setPosition(cc.p(VisibleRect:leftBottom().x + 125, VisibleRect:leftBottom().y));
layer:addChild(sgear);
sgearB:setCategoryBitmask(4);
sgearB:setCollisionBitmask(4);
sgearB:setTag(1);
world:addJoint(cc.PhysicsJointPin:construct(body, sgearB, sgearB:getPosition()));
-- big gear
local bgear = cc.Node:create();
local bgearB = cc.PhysicsBody:createCircle(100);
bgear:setPhysicsBody(bgearB);
bgear:setPosition(cc.p(VisibleRect:leftBottom().x + 275, VisibleRect:leftBottom().y));
layer:addChild(bgear);
bgearB:setCategoryBitmask(4);
world:addJoint(cc.PhysicsJointPin:construct(body, bgearB, bgearB:getPosition()));
-- pump
local pump = cc.Node:create();
local center = cc.PhysicsShape:getPolyonCenter(vec);
pump:setPosition(center);
local pumpB = cc.PhysicsBody:createPolygon(vec, cc.PHYSICSBODY_MATERIAL_DEFAULT, cc.p(-center.x, -center.y));
pump:setPhysicsBody(pumpB);
layer:addChild(pump);
pumpB:setCategoryBitmask(2);
pumpB:setGravityEnable(false);
world:addJoint(cc.PhysicsJointDistance:construct(pumpB, sgearB, cc.p(0, 0), cc.p(0, -44)));
-- plugger
local seg = {cc.p(VisibleRect:leftTop().x + 75, VisibleRect:leftTop().y-120), cc.p(VisibleRect:leftBottom().x + 75, VisibleRect:leftBottom().y-100)};
local segCenter = cc.p((seg[2].x + seg[1].x)/2, (seg[2].y + seg[1].y)/2);
seg[2] = cc.p(seg[2].x - segCenter.x, seg[2].y - segCenter.y);
seg[1] = cc.p(seg[1].x - segCenter.x, seg[1].y - segCenter.y);
local plugger = cc.Node:create();
local pluggerB = cc.PhysicsBody:createEdgeSegment(seg[1], seg[2], cc.PhysicsMaterial(0.01, 0.0, 0.5), 20);
pluggerB:setDynamic(true);
pluggerB:setMass(30);
pluggerB:setMoment(100000);
plugger:setPhysicsBody(pluggerB);
plugger:setPosition(segCenter);
layer:addChild(plugger);
pluggerB:setCategoryBitmask(2);
sgearB:setCollisionBitmask(5);
world:addJoint(cc.PhysicsJointPin:construct(body, pluggerB, cc.p(VisibleRect:leftBottom().x + 75, VisibleRect:leftBottom().y-90)));
world:addJoint(cc.PhysicsJointDistance:construct(pluggerB, sgearB,
pluggerB:world2Local(cc.p(VisibleRect:leftBottom().x + 75, VisibleRect:leftBottom().y)), cc.p(44, 0)));
end
initWithLayer(layer, onEnter)
Helper.titleLabel:setString("Pump")
Helper.subtitleLabel:setString("touch screen on left or right")
return layer
end
local function PhysicsDemoSlice()
local layer = cc.Layer:create()
local function onEnter()
layer:toggleDebug()
local sliceTag = 1;
local function clipPoly(shape, normal, distance)
local body = shape:getBody();
local count = shape:getPointsCount();
local points = {}
local j = count - 1
for i in range(0, count-1) do
local a = body:local2World(shape:getPoint(j));
local aDist = cc.pDot(a, normal) - distance;
if aDist < 0.0 then
points[#points + 1] = a;
end
local b = body:local2World(shape:getPoint(i));
local bDist = cc.pDot(b, normal) - distance;
if aDist*bDist < 0.0 then
local t = math.abs(aDist)/(math.abs(aDist) + math.abs(bDist));
points[#points + 1] = cc.pLerp(a, b, t);
end
j = i
end
local center = cc.PhysicsShape:getPolyonCenter(points);
local node = cc.Node:create();
local polyon = cc.PhysicsBody:createPolygon(points, cc.PHYSICSBODY_MATERIAL_DEFAULT, cc.p(-center.x, -center.y));
node:setPosition(center);
node:setPhysicsBody(polyon);
polyon:setVelocity(body:getVelocityAtWorldPoint(center));
polyon:setAngularVelocity(body:getAngularVelocity());
polyon.tag = sliceTag;
layer:addChild(node);
end
local function slice(world, info)
if info.shape:getBody().tag ~= sliceTag then
return true;
end
if not info.shape:containsPoint(info.start) and not info.shape:containsPoint(info.ended) then
local normal = cc.p(info.ended.x - info.start.x, info.ended.y - info.start.y);
normal = cc.pNormalize(cc.pPerp(normal));
local dist = cc.pDot(info.start, normal);
clipPoly(info.shape, normal, dist);
clipPoly(info.shape, cc.p(-normal.x, -normal.y), -dist);
info.shape:getBody():removeFromWorld();
end
return true;
end
local function onTouchEnded(touch, event)
cc.Director:getInstance():getRunningScene():getPhysicsWorld():rayCast(slice, touch:getStartLocation(), touch:getLocation());
end
local touchListener = cc.EventListenerTouchOneByOne:create();
touchListener:registerScriptHandler(function() return true end, cc.Handler.EVENT_TOUCH_BEGAN);
touchListener:registerScriptHandler(onTouchEnded, cc.Handler.EVENT_TOUCH_ENDED);
local eventDispatcher = layer:getEventDispatcher()
eventDispatcher:addEventListenerWithSceneGraphPriority(touchListener, layer);
local ground = cc.Node:create();
ground:setPhysicsBody(cc.PhysicsBody:createEdgeSegment(cc.p(VisibleRect:leftBottom().x, VisibleRect:leftBottom().y + 50),
cc.p(VisibleRect:rightBottom().x, VisibleRect:rightBottom().y + 50)));
layer:addChild(ground);
local box = cc.Node:create();
local points = {cc.p(-100, -100), cc.p(-100, 100), cc.p(100, 100), cc.p(100, -100)};
box:setPhysicsBody(cc.PhysicsBody:createPolygon(points));
box:setPosition(VisibleRect:center());
box:getPhysicsBody().tag = sliceTag;
layer:addChild(box);
end
initWithLayer(layer, onEnter)
Helper.titleLabel:setString("Slice")
Helper.subtitleLabel:setString("click and drag to slice up the block")
return layer
end
function PhysicsTest()
cclog("PhysicsTest")
local scene = cc.Scene:createWithPhysics()
Helper.usePhysics = true
Helper.createFunctionTable = {
PhysicsDemoLogoSmash,
@ -612,6 +935,10 @@ function PhysicsTest()
PhysicsDemoClickAdd,
PhysicsDemoRayCast,
PhysicsDemoJoints,
PhysicsDemoActions,
PhysicsDemoPump,
PhysicsDemoOneWayPlatform,
PhysicsDemoSlice,
}
scene:addChild(Helper.createFunctionTable[1]())

View File

@ -37,12 +37,13 @@ classes = Event(.*(Physics).*) Physics.*
skip = PhysicsBody::[getJoints createPolygon createEdgeChain createEdgePolygon],
PhysicsShape::[recenterPoints getPolyonCenter],
PhysicsShapeBox::[getPoints],
PhysicsShapeEdgeBox::[getPoints],
PhysicsShapePolygon::[getPoints],
PhysicsShapeEdgePolygon::[getPoints],
PhysicsShapeEdgeChain::[getPoints],
PhysicsWorld::[getScene queryPoint queryRect rayCast]
PhysicsShapeBox::[^getPoints$],
PhysicsShapeEdgeBox::[^getPoints$],
PhysicsShapePolygon::[^getPoints$],
PhysicsShapeEdgePolygon::[^getPoints$],
PhysicsShapeEdgeChain::[^getPoints$],
PhysicsWorld::[getScene queryPoint queryRect rayCast],
PhysicsContact::[getData setData]
rename_functions =