在游戏中我们通常会涉及到两个精灵之间的碰撞的计算,那么在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. 关于配置Spring框架的多个propertyConfigurer的问题

    http://blog.csdn.net/aa427/article/details/38375259

  2. C#的LINQ to Object

    using System; using System.Collections; using System.Collections.Generic; using System.IO; using Sys ...

  3. vim、gvim加载文件慢

    1. strace -f -T -o vim.strace vim 2. vim --startuptime "vim-time.txt" 3. gvim -f

  4. 在ubuntu上搭建开发环境2---Win7、Ubuntu双系统正确删除Ubuntu

    这种删除ubuntu的方式就是针对本博客中搭建双系统的方式:http://www.cnblogs.com/xumenger/p/4459963.html 如果ubuntu不是以wubi方式安装的,那么 ...

  5. OCJP(1Z0-851) 模拟题分析(八)over

    Exam : 1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam 以下分析全都是我自己分析或者参考网上的,定有 ...

  6. 数据结构之图 Part2 - 3

    十字链表 简单的说就是邻接表和逆邻接表的合体,解决了原邻接表或者逆邻接表出度和入度的计算无法兼得的问题. using System; using System.Collections.Generic; ...

  7. 实现Activity刷新 (转)

    目前刷新Acitivity,只想到几种方法.仅供参考,如果您有更好的方法,请赐教. 程序界面: 点击refresh view可以刷新界面,点击write content可以在EditText中自动写入 ...

  8. 使用Aspose.Cell.dll导出Excel总结

    这两天项目上用Aspose导出Excel来着.开始感觉挺简单的,但是实际操作起来还是挺复杂的,调试占的时间很长.主要是动态生成列.合并单元格.调样式占了很长时间,还是总结一下吧. 基础操作: //EX ...

  9. 使用canvas实现擦玻璃效果---转载

    <!DOCTYPE html> <html> <head lang="zh"> <meta name="viewport&quo ...

  10. RPC和Socket,RMI和RPC之间的关系

    远程通信机制RPC与RMI的关系 http://blog.csdn.net/zolalad/article/details/25161133       1.RPC RPC(Remote Proced ...