在游戏中我们通常会涉及到两个精灵之间的碰撞的计算,那么在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. jQuery – 8.事件和事件参数

        事件 (*)JQuery中的事件绑定:$("#btn").bind("click",function(){}),每次都这么调用太麻烦,所以jQuery可 ...

  2. SQL在INNER JOIN时,也可以将子查询加入进来

    这个语法有点神奇,记下. 但觉得用处有限吧. mysql> SELECT a.account_id, a_cust_id, a.open_date, a.product_cd -> FRO ...

  3. SQL Server 2014 BI新特性(二)结合Data Explorer和GeoFlow进行数据分析

    Data Explorer和GeoFlow作为Excel的新功能被写入到即将发布的SQL Server 2014当中.Data Explorer为业务分析人员提供了一种数据获取,整理以及组织的方式,通 ...

  4. git 本地仓库和远程仓库及本地分支和远程分支

    从远程git仓库签出代码:   $ git clone git://aaa.com/git_project.git (远程git服务器项目所在地址) 当你需要克隆远程项目到本地时,默认会把项目保存在名 ...

  5. python生成RSS(PyRSS2Gen)

    既然能够用python解析rss,那么也顺带研究下生成rss. 其实很简单,只是生成一个比较特殊点的xml文档而已. 这里我使用了PyRss2Gen,用法很简单,看代码就知道了,如下: import ...

  6. IIS配置php运行环境默认加载的php.ini路径

    第一步: 把PHP的安装路径添加到环境变量Path中,右键 “我的电脑” -> 高级 -> 环境变量 -> 系统变量,追加 D:PHP-5.2.8\; 第二步: 新建“系统变量” P ...

  7. POJ 3241 Object Clustering 曼哈顿最小生成树

    Object Clustering   Description We have N (N ≤ 10000) objects, and wish to classify them into severa ...

  8. loj1011 状态压缩

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1011 思路:最近的开始做dp了...很明显的一道状态压缩题,dp[n][state]表 ...

  9. 以管理身份运行cmd

    搜索出cmd程序,然后右键-以管理员身份运行

  10. Java学习笔记(二)——变量与常量

    一.java中的关键字 Java 语言中有一些具有特殊用途的词被称为关键字.关键字对 Java 的编译器有着特殊的意义,在程序中应用时一定要慎重哦!! 二.认识Java标识符 1.定义 标识符就是用于 ...