在游戏中我们通常会涉及到两个精灵之间的碰撞的计算,那么在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. MySQL 监控

    •Table_locks_immediate  The number of times that a request for a table lock could be granted immedia ...

  2. Unity依赖注入使用

    构造器注入(Constructor Injection):IoC容器会智能地选择选择和调用适合的构造函数以创建依赖的对象.如果被选择的构造函数具有相应的参数,IoC容器在调用构造函数之前会自定义创建相 ...

  3. map find 是线程安全的吗

    测试环境gcc4.8.2     iterator find ( const key_type& k ); const_iterator find ( const key_type& ...

  4. 重温WCF之会话Session(九)

    转载地址:http://blog.csdn.net/tcjiaan/article/details/8281782 每个客户端在服务器上都有其的独立数据存储区,互不相干,就好像A和服务器在单独谈话一样 ...

  5. Pyqt QComboBox 省市区县联动效果

    在Qt中, QComboBox方法窗口组件允许用户从列表清单中选择,在web中就是select标签,下拉选项. 省市区县的联动就是currentIndexChanged 获取当前的Index,通过这个 ...

  6. MySQL5.7更改密码时出现ERROR 1054 (42S22): Unknown column 'password' in 'field list'

    转自:http://blog.csdn.net/u010603691/article/details/50379282 新安装的MySQL5.7,登录时提示密码错误,安装的时候并没有更改密码,后来通过 ...

  7. Eclipse+CDT+GDB调试android NDK程序(转)

    Eclipse+CDT+gdb调试android ndk程序 先介绍一下开发环境,在这个环境下,up主保证是没有问题的. ubuntu 11.10 eclipse 3.7(indego) for ja ...

  8. 用 C# 实现一个简单的 Rest Service 供外部调用

    用 C#  实现一个简单的 Restful Service 供外部调用,大体总结为4点: The service contract (the methods it offers). How do yo ...

  9. supervisor(二)event

    supervisor的event机制其实,就是一个监控/通知的框架.抛开这个机制实现的过程来说的话,event其实就是一串数据,这串数据里面有head和body两部分.咱们先弄清楚event数据结构, ...

  10. 【spring 注解 错误】使用controller 作为后台给前台ajax交互数据出错

    controller作为后台与前台的ajax进行交互,后台的方法处理完成返回一个boolean类型的值,想传给前台用来判断是否执行成功,BUT,问题来了: 严重: Servlet.service() ...