在游戏中我们通常会涉及到两个精灵之间的碰撞的计算,那么在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 / 2;
}
//使用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 > 320 - radius()) {setPosition( ccp( 320 - radius(), getPosition().y) );m_velocity.x *= -1;} else if (getPosition().x < radius()) {setPosition( ccp(radius(), getPosition().y) );m_velocity.x *= -1;}
}
//判断是否碰撞到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 / 2;}else if (getPosition().y < midY && getPosition().y >= lowY - radius()) {setPosition( CCPointMake(getPosition().x, lowY - radius()) );hit = true;angleOffset = -(float)M_PI / 2;}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 / 2, -s.height / 2, 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, 0, 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(4);Paddle* paddle = Paddle::paddleWithTexture(paddleTexture);paddle->setPosition( CCPointMake(160, 15) );m_paddles->addObject( paddle );paddle = Paddle::paddleWithTexture( paddleTexture );paddle->setPosition( CCPointMake(160, 480 - kStatusBarHeight - 15) );m_paddles->addObject( paddle );paddle = Paddle::paddleWithTexture( paddleTexture );paddle->setPosition( CCPointMake(160, 100) );m_paddles->addObject( paddle );paddle = Paddle::paddleWithTexture( paddleTexture );paddle->setPosition( CCPointMake(160, 480 - kStatusBarHeight - 100) );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 > 480 - 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 (0);// 返回scenereturn scene;
}

运行的效果:

[Cocos2d-x For WP8]矩形碰撞检测相关推荐

  1. 矩形碰撞检测和圆形碰撞检测。

    矩形碰撞检测: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  2. 手游《奔跑吧?骚年!》技术分享(四):矩形碰撞检测

    手游<奔跑吧?骚年!>技术分享(四):矩形碰撞检测 今天来分享一下游戏中的碰撞处理,基本上横版2D游戏内的物体,都可以用矩形来表示(有时也需要用三角形来检测).通常就判断一下是否碰撞是不够 ...

  3. java矩形碰撞检测_旋转矩形的Java碰撞检测?

    我正在编写我的第一个 java游戏,到目前为止: 我做了一个可以用WSAD走动的矩形,他总是面向鼠标指向的地方.此外,如果你点击,他会射击你的鼠标指向的子弹(并且子弹旋转以面向那个方向).我也制造了跟 ...

  4. WP7进阶】——XNA游戏平面矩形碰撞检测

    碰撞检测在几乎任何游戏都是很关键的一个部分,而碰撞检测又决定了游戏的流畅性,它对流畅性的影响如何之大的原因,在于碰撞检测算法越是精确到位,游戏将会运行得越缓慢.在碰撞检测方面,很明显需要在准确性和性能 ...

  5. 2D游戏中的碰撞检测:圆形与矩形碰撞检测(JavascriptC++版)

    这几天放寒假了,时间也多了起来,当然又有时间搞搞程序了.哈哈~ 昨天在开发我的塔防游戏时突然发现人物实际攻击范围比规定的范围小,按理说应该是一样大的,但偏偏不是,我被这个问题搞得糊里糊涂的,一直没想出 ...

  6. 弹幕射击游戏中旋转矩形碰撞检测的算法描述

    分离轴法是根据两个多边形的几何中心在任意矢量方向的法线上的投影存在交叉的条件来做出的方法[32].换而言之,如果可以找出这样一个方向,将两个多边形投影在此方向的法线上的投影不交叉,则说明碰撞未发生,如 ...

  7. python矩形碰撞检测算法_矩形的碰撞检测(模仿俄罗斯方块)

    原博文 2016-11-20 16:11 − 以前一直以为玄之又玄的碰撞检测算法,其实也不过是一些加减法.看来还是写的太少,大多时候只是停留在望而止步的层次. 矩形的碰撞检测原理就是两个矩形的x值+宽 ...

  8. python矩形碰撞检测算法_简易夺旗游戏(python像素级碰撞检测之颜色碰撞)

    以下是部分代码预览: """ 简易夺旗游戏(python像素级碰撞检测之颜色碰撞) 按上下左右方向箭头操作小虫子去碰到小旗子,游戏就胜利了, 否则如果碰到黑色,游戏就失败 ...

  9. 2d游戏碰撞检测C语言,2D游戏中的碰撞检测:圆形与矩形碰撞检测(Javascrip版)...

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

最新文章

  1. matlab操作入门实验报告,MATLAB基本操作实验报告.doc
  2. 大型网站架构模式之一
  3. ITK:查找图像的更高导数
  4. Python:程序设计方法学、体育竞技分析
  5. Linux PS 命令详解
  6. linux工程师如何查询时间,查询Linux系统最后重启时间的三个方法
  7. 深入理解C#的装箱和拆箱
  8. flume channel monitor实现源码分析
  9. datagrid--新增
  10. Lora如何组网?有哪些简单的Lora组网协议?
  11. Embarcadero.ERStudio安装
  12. 各种说明方法的答题格式_说明文方法的答题格式
  13. 小技巧 大智慧 实例集
  14. Robot Framework自动化测试教程-通过RIDE创建工程、测试套、测试用例、测试资源、变量文件,引入测试库
  15. 2021-04-06-MSF之永恒之蓝
  16. 一、与电视有关的视觉特性:
  17. RSA加密及AES对称加密代码实现
  18. php判断一个数是不是素数,php用函数判断一个数是否素数
  19. 表结构设计器EZDML常见问题(2019年11月整理)
  20. 【C语言】博客之旅从学习C语言开始

热门文章

  1. python mp4提取音频加入另一段视频_使用 PHP-FFMpeg 操作视频/音频文件
  2. 【小白自学Python时踩的那些坑,你值得拥有】
  3. python大牛分享一些对python的看法
  4. Python爱好者,这里有一个库可以帮助你作为新手掌握人工智能!
  5. 分享如何在Ubuntu 16.04下CUDA8.0
  6. 机械制造与自动化专业学习单片机容易吗?如何学习单片机?
  7. 黑白球JAVA_桶中取黑白球 - jiacut的个人页面 - OSCHINA - 中文开源技术交流社区
  8. 与猜数问题有关的游戏C语言,猜数字游戏(C语言版)
  9. FFT ---- 2021牛客多校第一场 H Hash Function
  10. Pairs Forming LCM LightOJ - 1236[数论+组合计数]