在游戏中我们通常会涉及到两个精灵之间的碰撞的计算,那么在Cocos2d-x里面我们通常会用矩形碰撞检测来计算两个精灵在运动的过程中是否碰撞到了。原理很简单,就是当运动的时候通过精灵的矩形坐标进行遍历来计算精灵之间是否有重合,如果有重合那就证明是碰撞上了。

下面看一下下面的例子:

Ball精灵会根据帧速率来进行运动的,下面是Ball精灵的实现代码:

#ifndef _BALL_H_
#define _BALL_H_ #include "cocos2d.h"
/*
创建一个球的精灵
*/
class Paddle; using namespace cocos2d; class Ball : public CCSprite
{
CCPoint m_velocity;
public:
Ball(void);
virtual ~Ball(void); float radius();
//BOOL initWithTexture(CCTexture2D* aTexture);
//virtual void setTexture(CCTexture2D* newTexture);
void move(ccTime delta);
void collideWithPaddle(Paddle* paddle); public:
void setVelocity(CCPoint velocity){m_velocity = velocity;}
CCPoint getVelocity(){return m_velocity;} public:
static Ball* ballWithTexture(CCTexture2D* aTexture);
}; #endif #include "pch.h"
#include "Ball.h"
#include "Paddle.h" Ball::Ball(void)
{
} Ball::~Ball(void)
{
} float Ball::radius()
{
return getTexture()->getContentSize().width / ;
}
//使用CCTexture2D创建ball精灵
Ball* Ball::ballWithTexture(CCTexture2D* aTexture)
{
Ball* pBall = new Ball();
pBall->initWithTexture(aTexture);
pBall->autorelease(); return pBall;
}
//移动ball精灵
void Ball::move(ccTime delta)
{
//根据m_velocity的数值设置ball精灵的位置
this->setPosition( ccpAdd(getPosition(), ccpMult(m_velocity, delta)) ); if (getPosition().x > - radius())
{
setPosition( ccp( - radius(), getPosition().y) );
m_velocity.x *= -;
}
else if (getPosition().x < radius())
{
setPosition( ccp(radius(), getPosition().y) );
m_velocity.x *= -;
}
}
//判断是否碰撞到paddle精灵
void Ball::collideWithPaddle(Paddle* paddle)
{
//获取paddle精灵的矩形位置
CCRect paddleRect = paddle->rect();
//转化成绝对的位置
paddleRect.origin.x += paddle->getPosition().x;
paddleRect.origin.y += paddle->getPosition().y;
//获取paddle精灵的矩形的相关数值
float lowY = paddleRect.getMinY(); //CCRect::getMidY(paddleRect);
float midY = paddleRect.getMidY(); //CCRect::CCRectGetMidY(paddleRect);
float highY =paddleRect.getMaxY();// CCRect::CCRectGetMaxY(paddleRect); float leftX = paddleRect.getMinX();//CCRect::CCRectGetMinX(paddleRect);
float rightX =paddleRect.getMaxX(); //CCRect::CCRectGetMaxX(paddleRect); if (getPosition().x > leftX && getPosition().x < rightX) { bool hit = false;
float angleOffset = 0.0f;
//判断是否碰撞到paddle精灵
if (getPosition().y > midY && getPosition().y <= highY + radius())
{
setPosition( CCPointMake(getPosition().x, highY + radius()) );
hit = true;
angleOffset = (float)M_PI / ;
}
else if (getPosition().y < midY && getPosition().y >= lowY - radius())
{
setPosition( CCPointMake(getPosition().x, lowY - radius()) );
hit = true;
angleOffset = -(float)M_PI / ;
} if (hit)
{
//碰撞到则调整方向
float hitAngle = ccpToAngle(ccpSub(paddle->getPosition(), getPosition())) + angleOffset; float scalarVelocity = ccpLength(m_velocity) * 1.05f;
float velocityAngle = -ccpToAngle(m_velocity) + 0.5f * hitAngle; m_velocity = ccpMult(ccpForAngle(velocityAngle), scalarVelocity);
}
}
}

Paddle精灵相当于是挡板的意思,Paddle精灵是静止的,当Ball精灵碰撞到Paddle精灵的时候,运动的轨迹就会发生变化。

Paddle精灵的代码:

#ifndef _PADDLE_H_
#define _PADDLE_H_ #include "cocos2d.h" using namespace cocos2d;
/*
创建一个挡板精灵
*/
typedef enum tagPaddleState
{
kPaddleStateGrabbed,
kPaddleStateUngrabbed
} PaddleState; class Paddle : public CCSprite, public CCTargetedTouchDelegate
{
PaddleState m_state; public:
Paddle(void);
virtual ~Paddle(void); CCRect rect();
bool initWithTexture(CCTexture2D* aTexture);
virtual void onEnter();
virtual void onExit();
bool containsTouchLocation(CCTouch* touch);
virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);
virtual void ccTouchMoved(CCTouch* touch, CCEvent* event);
virtual void ccTouchEnded(CCTouch* touch, CCEvent* event); virtual void touchDelegateRetain();
virtual void touchDelegateRelease(); static Paddle* paddleWithTexture(CCTexture2D* aTexture);
}; #endif #include "pch.h"
#include "Paddle.h" Paddle::Paddle(void)
{
} Paddle::~Paddle(void)
{
}
//获取paddle精灵的矩形位置
CCRect Paddle::rect()
{
CCSize s = getTexture()->getContentSize();
return CCRectMake(-s.width / , -s.height / , s.width, s.height);
} Paddle* Paddle::paddleWithTexture(CCTexture2D* aTexture)
{
Paddle* pPaddle = new Paddle();
pPaddle->initWithTexture( aTexture );
pPaddle->autorelease(); return pPaddle;
} bool Paddle::initWithTexture(CCTexture2D* aTexture)
{
if( CCSprite::initWithTexture(aTexture) )
{
m_state = kPaddleStateUngrabbed;
} return true;
} void Paddle::onEnter()
{
CCTouchDispatcher* pDispatcher = CCDirector::sharedDirector()->getTouchDispatcher();
pDispatcher->addTargetedDelegate(this, , true);
CCSprite::onEnter();
} void Paddle::onExit()
{
CCTouchDispatcher* pDispatcher = CCDirector::sharedDirector()->getTouchDispatcher();
pDispatcher->removeDelegate(this);
CCSprite::onExit();
} bool Paddle::containsTouchLocation(CCTouch* touch)
{
return rect().containsPoint(convertTouchToNodeSpaceAR(touch));;//CCRect::containsPoint(rect(), convertTouchToNodeSpaceAR(touch));
} bool Paddle::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
if (m_state != kPaddleStateUngrabbed) return false;
if ( !containsTouchLocation(touch) ) return false; m_state = kPaddleStateGrabbed;
return true;
}
//移动paddle精灵
void Paddle::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
CCAssert(m_state == kPaddleStateGrabbed, L"Paddle - Unexpected state!"); CCPoint touchPoint = touch->getLocationInView();
touchPoint = CCDirector::sharedDirector()->convertToGL( touchPoint ); setPosition( CCPointMake(touchPoint.x, getPosition().y) );
} void Paddle::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
CCAssert(m_state == kPaddleStateGrabbed, L"Paddle - Unexpected state!"); m_state = kPaddleStateUngrabbed;
} void Paddle::touchDelegateRetain()
{
this->retain();
} void Paddle::touchDelegateRelease()
{
this->release();
}

下面是实现碰撞的Layer:

//------------------------------------------------------------------
//
// 初始化[碰撞的Layer
//
//------------------------------------------------------------------
PongLayer::PongLayer()
{
m_ballStartingVelocity = CCPointMake(20.0f, -100.0f);
//创建ball精灵
m_ball = Ball::ballWithTexture( CCTextureCache::sharedTextureCache()->addImage("cat.png") );
m_ball->setPosition( CCPointMake(160.0f, 240.0f) );
m_ball->setVelocity( m_ballStartingVelocity );
addChild( m_ball );
m_ball->retain(); //创建4个Paddle精灵
CCTexture2D* paddleTexture = CCTextureCache::sharedTextureCache()->addImage("paddle.png");
m_paddles = new CCArray();
Paddle* paddle = Paddle::paddleWithTexture(paddleTexture);
paddle->setPosition( CCPointMake(, ) );
m_paddles->addObject( paddle ); paddle = Paddle::paddleWithTexture( paddleTexture );
paddle->setPosition( CCPointMake(, - kStatusBarHeight - ) );
m_paddles->addObject( paddle ); paddle = Paddle::paddleWithTexture( paddleTexture );
paddle->setPosition( CCPointMake(, ) );
m_paddles->addObject( paddle ); paddle = Paddle::paddleWithTexture( paddleTexture );
paddle->setPosition( CCPointMake(, - kStatusBarHeight - ) );
m_paddles->addObject( paddle ); CCObject* arrayItem;
CCARRAY_FOREACH(m_paddles, arrayItem){
paddle = (Paddle*)(arrayItem);
if(!paddle)
break;
addChild(paddle);
}
//每一帧刷新ball精灵的运动
schedule( schedule_selector(PongLayer::doStep) );
} PongLayer::~PongLayer()
{
m_ball->release();
m_paddles->release();
} void PongLayer::resetAndScoreBallForPlayer(int player)
{
m_ballStartingVelocity = ccpMult(m_ballStartingVelocity, -1.1f);
m_ball->setVelocity( m_ballStartingVelocity );
m_ball->setPosition( CCPointMake(160.0f, 240.0f) );
} void PongLayer::doStep(ccTime delta)
{
//移动ball精灵
m_ball->move(delta);
Paddle* paddle;
CCObject* arrayItem;
CCARRAY_FOREACH(m_paddles, arrayItem){
paddle = (Paddle*)(arrayItem);
if(!paddle)
break;
//判断ball精灵是否碰到paddle精灵
m_ball->collideWithPaddle( paddle );
}
//判断是否碰到边界
if (m_ball->getPosition().y > - kStatusBarHeight + m_ball->radius())
resetAndScoreBallForPlayer( kLowPlayer );
else if (m_ball->getPosition().y < -m_ball->radius())
resetAndScoreBallForPlayer( kHighPlayer );
m_ball->draw();
}

在helloworld项目中加入该Layer

CCScene* HelloWorld::scene()
{
CCScene * scene = NULL;
do
{ // 'scene'是一个可以自动释放的对象
scene = CCScene::create();
//创建失败跳出循环
CC_BREAK_IF(! scene);
PongLayer *pongLayer = new PongLayer();
scene->addChild(pongLayer);
} while (); // 返回scene
return scene;
}

运行的效果:

[Cocos2d-x For WP8]矩形碰撞检测的更多相关文章

  1. 写一些封装part1 (事件绑定移除,圆形矩形碰撞检测)

    var EventHandle = { addEvent:function(ele,type,handle){ if (ele.addEventListener) { ele.addEventList ...

  2. 旋转矩形碰撞检测 OBB方向包围盒算法

    在cocos2dx中进行矩形的碰撞检测时需要对旋转过的矩形做碰撞检查,由于游戏没有使用Box2D等物理引擎,所以采用了OBB(Oriented bounding box)方向包围盒算法,这个算法是基于 ...

  3. Cocos2d-三维拾取Ray-AABB碰撞检测算法【转】

    1.三维拾取技术 在3D游戏中通常会有这样的需求,用户可以选取3D世界中的某些物体进行如拖拽等操作,这时便需要程序通过将二维屏幕上的点坐标转换为三维世界中的坐标,并进行比对,这个过程就需要用到三维拾取 ...

  4. 2D游戏中的碰撞检测:圆形与矩形碰撞检测(Javascrip版)

    一,原理介绍 这回有点复杂,不过看懂了还是很好理解的.当然,我不敢保证这种算法在任何情况下都会起效果,如果有同学测试时,发现出现错误,请及时联系我. 我们首先来建立一个以圆心为原点的坐标系: 然后要检 ...

  5. canvas中的碰撞检测笔记

    用 canvas 做小游戏或者特效,碰撞检测是少不了的.本文将会涉及普通的碰撞检测,以及像素级的碰撞检测.(本文的碰撞检测均以矩形为例) 普通碰撞检测 普通的矩形碰撞检测比较简单.即已知两个矩形的各顶 ...

  6. 白鹭引擎 - 碰撞检测 ( hitTestPoint )

    1, 矩形碰撞检测 class Main extends egret.DisplayObjectContainer { /** * Main 类构造器, 初始化的时候自动执行, ( 子类的构造函数必须 ...

  7. Cocos2d-x游戏移植到WP8之路 -- c++和c#交互

    Cocos2d-x是眼下最流行的手机游戏引擎之中的一个,开源.轻量.多平台等的诸多特性使得它被非常多国内外手游开发人员所喜爱. 利用Cocos2d-x来开发Windows Phone 8的游戏相同也是 ...

  8. Java游戏之碰撞检测

    在进行Java游戏开发时,我们经常会遇到碰撞检测的问题.如坦克大战中,炮弹与坦克相遇发生爆炸:守卫者游戏中,守卫者发射的箭与怪物相遇使怪物失血:打飞机游戏中,飞机发送的子弹与敌机相遇干掉敌机.这些都需 ...

  9. java图形界面写个小桌面,内置简单小软件

    一.做个这样的效果,双击图标打开相应的应用 二.主界面类,使用JavaSwing的JDesktopPane类创建这个桌面 package com.swing; import java.awt.Bord ...

随机推荐

  1. Arch Linux 安装、配置、美化和优化

    国庆假期玩了下Arch Linux,发现这货跟Ubuntu之流相差甚远,甚难调教,而且安裝过程全命令行,会有各种问题,各种知识... --- 安装引导器--- -------------------- ...

  2. poj 2155:Matrix(二维线段树,矩阵取反,好题)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17880   Accepted: 6709 Descripti ...

  3. HDU5781 ATM Mechine(DP 期望)

    应该是machine 和POJ3783 Balls类型相似. 现在上界为i元,猜错次数最多为j时,开始猜测为k元,有两种情况: 1 猜中:(i - k + 1) * dp[i - k][j] 2 猜不 ...

  4. hdu 4061 福州赛区网络赛A 数学 ***

    a1/sum #include<cstdio> #include<iostream> #include<algorithm> #include<cstring ...

  5. [JavaCore] 微信手机浏览器版本判断

    公司要做微支付,微信浏览器版本要大于5 package com.garinzhang.web.weixin; import org.apache.commons.lang.StringUtils; i ...

  6. RTP timestamp与帧率及时钟频率的关系

    转自:http://blog.csdn.net/jasonhwang/article/details/7316128 RTP timestamp是用时钟频率(clock rate)计算而来表示时间的. ...

  7. 在Salesforce中对某一个Object添加自定义的Button和Link

    在Salesforce中可以对某一个Object添加自定义的Button和Link,来完成特定的逻辑过程,接下来以一个简单的实例来描述整个处理流程,实现的基本功能和我另外一篇文章中描述的功能是一致的( ...

  8. sublime text 2中Emmet8个常用的技巧

    原文链接:http://blog.csdn.net/lmmilove/article/details/9181323 因为开始做web项目,所以最近在用sublime编辑器,知道了一个传说中的emme ...

  9. codeforces724-B. Batch Sort

    想着想着就忘了有什么问题没解决,坑啊 一开始读错题意了,而且一着急写了两大段差不多的代码,冗余度啊,不说了.. 显然的一点,给的数据是绝对离散的,每行都是1~m的排列 难点一.如何移动能使未排序的数组 ...

  10. Quartz.NET配置

    概述 Quartz.NET 在开源任务调度框架中的翘首,它提供了强大任务调度机制,难能可贵的是它同时保持了使用的简单性.Quartz 允许开发人员灵活地定义触发器的调度时间表,并可以对触发器和任务进行 ...