当前位置:首页 > 代码 > 正文

cocos2d碰撞源代码(cocos2d解密)

admin 发布:2022-12-19 19:01 149


今天给各位分享cocos2d碰撞源代码的知识,其中也会对cocos2d解密进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

cocos2d update dt 什么意思

代码的意思就是,先遍历所有子弹的其中一个子弹,然后遍历每一个target,看target是否与这个子弹的位置重合,如果是的话就说明是碰撞了,然后再消除target和子弹。 检测碰撞的代码就这一句话:CCRect::CCRectIntersectsRect(projectileRect, tar.

如何使用Cocos Code IDE和Cocos2d-x开发《一个都不能落下》游戏

1.创建新工程

打开Cocos Code IDE,切换到Lua工作环境

选择菜单,新建一个Cocos Lua项目,输入项目名:NoOneLeftBehind。

点击下一步设置屏幕方向和分辨率,确认完成

这个时候你就可以点击运行按钮,没有问题的话示例demo就会弹出。

因为分辨率被我们更改过的关系,游戏画面有点变形。

2.游戏逻辑

现在我们就可以往游戏项目中添加自己的代码了。由于游戏的代码细节并不是本文的重点,所以这里只简单地介绍《一个都不能落下》的实现原理。整个游戏项目源码可以在我的Github上下载。

A.main.lua是游戏的入口,在main()函数中我们可以找到场景跳转的代码,这在接口上和Cocos2d-x是保持一致的,因此我们可以很容易上手。在这里我们更改第一个场景为主菜单场景。

--create scene

local scene = require("MenuScene")

local menuScene = scene.createScene()

if cc.Director:getInstance():getRunningScene() then

cc.Director:getInstance():replaceScene(menuScene)

else

cc.Director:getInstance():runWithScene(menuScene)

end

B.MenuScene.lua是游戏的主菜单,四种难度的游戏模式可以在这里进行选择。你可以用下面这种方式创建一个menu。

--create menu

local function menuCallbackOpenNormal()

cc.Director:getInstance():replaceScene(require("GameScene").createScene(2))

end

local normal = cc.MenuItemImage:create("normal.png", "normal.png")

normal:setPosition(0, 150)

normal:registerScriptTapHandler(menuCallbackOpenNormal)

...

local menu = cc.Menu:create(normal, nightmare, hell, inferno)

self:addChild(menu)

C.GameScene.lua是游戏的主场景,通过传进来的heroCount设置同时显示几个hero。

--add hero

function GameLayer:addControllers()

local visibleSize = cc.Director:getInstance():getVisibleSize()

local startY = 30

local gap = (visibleSize.height - startY) / self._heroCount

for i=1, self._heroCount do

local controller = require("HeroController").createController(self, startY + gap * (i - 1))

table.insert(self._controllers, i, controller)

end

end

D.在这里我们对英雄和他作用的环境进行了封装。然后在GameScene的每一帧调用HeroController的onUpdate函数,在这个函数中检测一个随机定时器来判断是否应该生成一个新的障碍物。

-- create block

function HeroController:onUpdate()

self.frameIndex = self.frameIndex +1

if self.frameIndex = self.nextKeyFrameIndex then

local block = require("Block").new()

block:init()

self._layer:addChild(block)

block:setPositionY(self._positionY + block:getContentSize().height / 2)

self:resetTimer()

end

end

E.物理引擎。Hero和,Ground,Block的碰撞这里采用了Cocos2d-x集成的物理引擎。以下代码反映了Hero和Block的碰撞检测。

-- collision detection

self.touchListener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN)

cc.Director:getInstance():getEventDispatcher():addEventListenerWithSceneGraphPriority(self.touchListener, self)

local function onContactBegin(contact)

self:unscheduleUpdate()

cc.Director:getInstance():getEventDispatcher():removeEventListener(self.touchListener)

cc.Director:getInstance():getEventDispatcher():removeEventListener(self.contactListener)

cc.Director:getInstance():replaceScene(require("GameOver").create(self._heroCount, score))

end

self.contactListener = cc.EventListenerPhysicsContact:create();

self.contactListener:registerScriptHandler(onContactBegin, cc.Handler.EVENT_PHYSICS_CONTACT_BEGIN);

local eventDispatcher = self:getEventDispatcher()

eventDispatcher:addEventListenerWithSceneGraphPriority(self.contactListener, self);

F.Block类,封装了障碍物,每一帧向左移动。如果超出了屏幕则删除。

--move the block

function update(dt)

self:setPositionX(self:getPositionX() - 3.5)

if (self:getPositionX() 0) then

self:unscheduleUpdate()

self:removeFromParentAndCleanup()

end

end

self:scheduleUpdateWithPriorityLua(update, 0)

3.各平台打包

点击打包按钮,

如果没有添加本地代码,会提示添加本地代码。

A.Android打包

选择打包为APK,选择debug签名或者自定义签名,选择SDK版本,确认生成。

B.iOS平台打包

选择打包为IPA,选择证书和平台,确认生成。

..

.

如何使用cocos2d和box2d来制作一个Breakout游戏:PART

大家也可以到Ray的网站查看本教程的中文版本。Simple Breakout Game ScreenshotBbox2d是一个非常强大的物理引擎库,同时它与cocos2d结合非常适合在iphone上面做游戏开发。著名的angry birds,tiny wings都是用box2d写的。你可以用它做好多事情,当然,最好的学习方法就是使用它来创建一个简单的游戏。在这个教程中,我们将一步一步创建一个简单的breakout游戏,完成碰撞检测,篮球反弹物理效果,通过touch拖动paddle(就是上图的白色矩形),以及胜利/失败的场景。 (Jump to part two of the series.)如果你还不了解cocos2d和box2d,你可能先要读一读 《如何使用cocos2d制作一个简单的iphone游戏》 以及《在cocos2d里面如何使用box2d物理引擎:弹球》.好了,是时候制作breakout了! 一个永远反弹的球S首先,打开Xcode,选择 cocos2d-0.99.1 Box2d Application template创建一个工程,命名为“ Box2DBreakout”. 删除掉模板代码,因此你会有一个空的工程来重新开始—具体步骤可以参照 《在cocos2d里面如何使用box2d物理引擎:弹球》 这个教程。一旦你有了一个很好的干净的工程后,接下来,在HelloWorldScene.h中导入下面的头文件: #import "Box2D.h" 同时在HelloWorld类中添加以下成员变量: b2World *_world; b2Body *_groundBody; b2Fixture *_bottomFixture; b2Fixture *_ballFixture; 然后在HelloWorldScene.mm文件顶部定义比率: #define PTM_RATIO 32 这个比率我们在上一个教程中已经讨论过了,这里就不再啰嗦了。 然后,在init方法中加入下列代码: CGSize winSize = [CCDirector sharedDirector].winSize; // Create a world b2Vec2 gravity = b2Vec2(0.0f, 0.0f); bool doSleep = true; _world = new b2World(gravity, doSleep); // Create edges around the entire screen b2BodyDef groundBodyDef; groundBodyDef.position.Set(0,0); _groundBody = _world-CreateBody(groundBodyDef); b2PolygonShape groundBox; b2FixtureDef groundBoxDef; groundBoxDef.shape = groundBox; groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO, 0)); _bottomFixture = _groundBody-CreateFixture(groundBoxDef); groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(0, winSize.height/PTM_RATIO)); _groundBody-CreateFixture(groundBoxDef); groundBox.SetAsEdge(b2Vec2(0, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO)); _groundBody-CreateFixture(groundBoxDef); groundBox.SetAsEdge(b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, 0)); _groundBody-CreateFixture(groundBoxDef); 好,这个代码和我们上一个教程中,为整个屏幕创建一个盒子边界差不多。然后,这一次,我们把重力设置为0,因为,在我们的breakout游戏中,我们并不需要重力!注意,我们存储了底部的fixture的一个指针,以方便后面使用(在后面的教程中,我们将用来追踪什么时候篮球与顶部相碰撞了)。现在,下载我制作的 篮球图片 并且拖到Resources文件夹中,确保 “Copy items into destination group’s folder (if needed)” 被复选中。让我们往场景里面添加一个精灵吧。紧接着上面的代码,加入下面的代码片段: // Create sprite and add it to the layer CCSprite *ball = [CCSprite spriteWithFile:@"Ball.jpg" rect:CGRectMake(0, 0, 52, 52)]; ball.position = ccp(100, 100); ball.tag = 1; [self addChild:ball]; 这里没什么疑问,我们已经做过好多次类似的事情了。注意,我们为篮球设置了一个tag标识,后面你会看到,这个tag标记有什么用。 接下来,为shape创建一个body: // Create ball body b2BodyDef ballBodyDef; ballBodyDef.type = b2_dynamicBody; ballBodyDef.position.Set(100/PTM_RATIO, 100/PTM_RATIO); ballBodyDef.userData = ball; b2Body * ballBody = _world-CreateBody(ballBodyDef); // Create circle shape b2CircleShape circle; circle.m_radius = 26.0/PTM_RATIO; // Create shape definition and add to body b2FixtureDef ballShapeDef; ballShapeDef.shape = circle; ballShapeDef.density = 1.0f; ballShapeDef.friction = 0.f; ballShapeDef.restitution = 1.0f; _ballFixture = ballBody-CreateFixture(ballShapeDef); 这个看起来和上一篇教程中的也很像。再巩固一下吧,为了创建一个body对象,我们先要创建一个body定义结构,然后再创建body,接着是shape,再指定fixture结构,最后是创建fixture对象。 更新:注意,我们也把球的摩擦力设置为0.这样可以防止球在碰撞的时候,由于摩擦损失能量,导致来回碰撞的过程中会有一点点偏差。 好了,是时候做一些完全不同的事了!紧接上面的代码: b2Vec2 force = b2Vec2(10, 10); ballBody-ApplyLinearImpulse(force, ballBodyDef.position); 这里往球上面施加了一个冲力(impulse),这样可以让它初始化的时候朝一个特定的方向运动。 最后一件事情,就是在init方法中,增加一个tick调度方法: [self schedule:@selector(tick:)]; 下面是tick方法的实现: - (void)tick:(ccTime) dt { _world-Step(dt, 10, 10); for(b2Body *b = _world-GetBodyList(); b; b=b-GetNext()) { if (b-GetUserData() != NULL) { CCSprite *sprite = (CCSprite *)b-GetUserData(); sprite.position = ccp(b-GetPosition().x * PTM_RATIO, b-GetPosition().y * PTM_RATIO); sprite.rotation = -1 * CC_RADIANS_TO_DEGREES(b-GetAngle()); } } } 当然,这里也和上一个教程中的一样,没有什么特别的。 最后一件事我们永远不忘记!那就是清理: - (void)dealloc { delete _world; _groundBody = NULL; [super dealloc]; } 好了,让我们试一下吧。编译并运行工程,你将会看到一个球无限地在屏幕里面来回弹!—-很酷吧!增加Paddle如果没有一个paddle的话,那么就不可能称其为一个breakout游戏。下载我制作的paddle图片 然后把它拖到Resources文件夹中,同时确保 “Copy items into destination group’s folder (if needed)” 被复选上。然后在HelloWorldScene.h文件中往HelloWorld类中添加下列成员变量: b2Body *_paddleBody; b2Fixture *_paddleFixture; 然后,在init方法中构建paddle body: // Create paddle and add it to the layer CCSprite *paddle = [CCSprite spriteWithFile:@"Paddle.jpg"]; paddle.position = ccp(winSize.width/2, 50); [self addChild:paddle]; // Create paddle body b2BodyDef paddleBodyDef; paddleBodyDef.type = b2_dynamicBody; paddleBodyDef.position.Set(winSize.width/2/PTM_RATIO, 50/PTM_RATIO); paddleBodyDef.userData = paddle; _paddleBody = _world-CreateBody(paddleBodyDef); // Create paddle shape b2PolygonShape paddleShape; paddleShape.SetAsBox(paddle.contentSize.width/PTM_RATIO/2, paddle.contentSize.height/PTM_RATIO/2); // Create shape definition and add to body b2FixtureDef paddleShapeDef; paddleShapeDef.shape = paddleShape; paddleShapeDef.density = 10.0f; paddleShapeDef.friction = 0.4f; paddleShapeDef.restitution = 0.1f; _paddleFixture = _paddleBody-CreateFixture(paddleShapeDef); 我不想花太多的时间解释上面的内容了。因为,和之前的创建篮球的body的过程差不太多。这里只给出不同的地方:当你创建CCSprite的时候,你并不需要指定精灵的大小。如果你传递一个文件名给它,它会自动计算出大小。注意,这里不是使用circle shape了。这一次,我们使用polygon shape。我们使用一个辅助方法来创建shape,当然,其形状是个盒子。我们使用了SetAsBox方法来指定shape相对于body的位置,这个方法在构建复杂的对象的时候比较有用。这里,我们只是让shape在body中间。我把paddle的密度设置得比球要大得多,同时调节了一下其它的参数。(这些参数要靠试,按照真实的高中物理知识去计算,可能得不到)同时,我们存储paddleBody和paddleFixture的引用,为了方便后面使用。如果你编译并运行的话,你将会看到屏幕中间有一个paddle,而且球碰到它将会反弹。 然后,这还不是很有趣,因为我们还不能移动paddle!移动Paddle移动paddle需要touch事件,所以先在init方法中允许touch事件: self.isTouchEnabled = YES; 然后,在HelloWorldScene.h的HelloWorld类中添加下面的成员变量: b2MouseJoint *_mouseJoint; 现在,让我们实现touch方法!首先是ccTouchesBegan: - (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { if (_mouseJoint != NULL) return; UITouch *myTouch = [touches anyObject]; CGPoint location = [myTouch locationInView:[myTouch view]]; location = [[CCDirector sharedDirector] convertToGL:location]; b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO); if (_paddleFixture-TestPoint(locationWorld)) { b2MouseJointDef md; md.bodyA = _groundBody; md.bodyB = _paddleBody; md.target = locationWorld; md.collideConnected = true; md.maxForce = 1000.0f * _paddleBody-GetMass(); _mouseJoint = (b2MouseJoint *)_world-CreateJoint(md); _paddleBody-SetAwake(true); } } 呃,好多新知识!让我们一点一点来讨论。 首先,我们把touch坐标转换成coocs2d坐标(convertToGL)然后,再转换成Box2d坐标(locationWorld)。 然后,我们使用paddle fixture的一个方法来测试这个touch点是否在fixture内部。 如果是的话,我们就创建一个所谓的”鼠标关节“。在Box2d里面,一个鼠标关节用来让一个body朝着一个指定的点移动—在这里个例子中,就是用户点的方向。 当你创建一个mouse joint后,你赋值给它两个body。第一个没有被使用,通常都是设置成ground body。第二个,就是你想让它移动的body,在这个例子中就是paddle。 接下来,你指定移动的终点—这个例子中就是用户点击的位置。 然后,你告诉box2d,但bodyA和bodyB碰撞的时候,把它当成是碰撞,而不是忽略它。这个很重要!因为,我之前没有设置它为ture,结果不行!因此,当我们用鼠标拖动这个paddle的时候,它并不会与屏幕的边界相碰撞,而且有时候,我的paddle直接就飞出屏幕之外了。这个非常非常奇怪,不过我现在知道是为什么了。因为没有设置bodyA和bodyB是可碰撞的。 你然后指定移动body的最大的力是多少。如果你减少这个数值的话,paddle body响应鼠标移动时就会慢一些。但是,我们想让paddle快速地响应鼠标的变化。 最后,我们把这个关节加入到world中,同时,保存这个指针,因为后面有用。同时,我们还要把body设置成苏醒的(awake)。之所以要这么做,是因为如果body在睡觉的话,那么它就不会响应鼠标的移动! 好了,接下来,让我们添加ccTouchesMoved方法: -(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { if (_mouseJoint == NULL) return; UITouch *myTouch = [touches anyObject]; CGPoint location = [myTouch locationInView:[myTouch view]]; location = [[CCDirector sharedDirector] convertToGL:location]; b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO); _mouseJoint-SetTarget(locationWorld); } 这个方法的开头部分和ccTouchesBegan差不多—我们把touch坐标转换成Box2d坐标。唯一的区别就是,我们更新了鼠标关节的目标位置(也就是我们想让paddle移动的位置的)。 接下来,我们添加ccTouchesCacelled和ccTouchesEnded方法: -(void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { if (_mouseJoint) { _world-DestroyJoint(_mouseJoint); _mouseJoint = NULL; } } - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { if (_mouseJoint) { _world-DestroyJoint(_mouseJoint); _mouseJoint = NULL; } } 我们在这些方法中做的只有一件事,就是在我们移动完paddle或者取消移动之后销毁mouse joint。 编译并运行,你现在可以用鼠标移动paddle了,同时可以让它与篮球相互碰撞了! 很好。。。不过,等一下,这还不是一个breakout!我们不可以把paddle移动到任何位置,我们只能在屏幕底部左右来回移动它!限制Paddle的移动我们可以很容易地限制paddle的移动,只需要添加另外一个关节,叫做prismatic joint。这个关节会限制一个body的移动沿着一根指定的轴。 因此,我们可以使用这种方法来限制paddle相对于地面移动,也就是说只能沿着x轴移动。 让我们看看相关代码。往init方法中加入下列代码: // Restrict paddle along the x axis b2PrismaticJointDef jointDef; b2Vec2 worldAxis(1.0f, 0.0f); jointDef.collideConnected = true; jointDef.Initialize(_paddleBody, _groundBody, _paddleBody-GetWorldCenter(), worldAxis); _world-CreateJoint(jointDef); 第一件事情就是指定一个沿着x轴的向量。然后,我们需要指定collideConnected为true,因此,我们的球才能够正确的反弹,而不是飞到屏幕之外去。 然后,初始化关节,指定paddle和ground两个body,再使用world对象来创建关节! 更新:我第一次尝试去修正这个bug的时候,我通过直接调整球的速度,使用SetLinearVelocity方法。然后,Steve Oldmeadow也指出,这非常不好!它会破坏物理仿真,最好的方法是通过调用SetLinearDamping方法,间接影响速度。因此,现在这个教程就是这个做的。(damping就是阻尼的意思) 接下来,在tick方法中添加下列代码,具体位置是在获得user data之后: if (sprite.tag == 1) { static int maxSpeed = 10; b2Vec2 velocity = b-GetLinearVelocity(); float32 speed = velocity.Length(); if (speed maxSpeed) { b-SetLinearDamping(0.5); } else if (speed maxSpeed) { b-SetLinearDamping(0.0); } } 这里,我们判断sprite的tag,看是否是球的tag。如果是的话,我们就检查它的速度,如果太大的话,就设置它的阻尼为0.5,这样可以让它慢下来。 如果你编译并运行的话,你将会看到一个球以非常适中的速度在屏幕四周来回反弹。给我源代码!这里是本教程的 完整源代码 。这只是一部分,第二部分的教程会包含一个完整的breakout的源码。接下来呢?目前为止,我们已经有一个篮球在屏幕四周来回反弹了,同时还有一个paddle可以用鼠标来控制其移动。在下个教程中,我们将创建一些方块,当球碰到它们的时候,方块就会消失。

cocos creator怎么做碰撞检测

在cocos2d-x中已经提供了矩形与矩形的碰撞检测以及点与矩形的碰撞检测,如下:

检测矩形与矩形碰撞的函数:

bool intersectsRect(const CCRect rect) 使用方法: rect1.intersectsRect(rect2);

检测点与矩形碰撞的函数: bool containsPoint(const CCPoint point) 使用方法: rect.containsPoint(point);

下面重点说矩形与圆形的碰撞检测: PS:先说一下cocos2d-x中的矩形Rect,Rect的构造有四个参数,x, y, width, height,

关于cocos2d碰撞源代码和cocos2d解密的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

版权说明:如非注明,本站文章均为 AH站长 原创,转载请注明出处和附带本文链接;

本文地址:http://ahzz.com.cn/post/19110.html


取消回复欢迎 发表评论:

分享到

温馨提示

下载成功了么?或者链接失效了?

联系我们反馈

立即下载