博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Cocos2d-x For WP8]矩形碰撞检测
阅读量:5777 次
发布时间:2019-06-18

本文共 8868 字,大约阅读时间需要 29 分钟。

    在游戏中我们通常会涉及到两个精灵之间的碰撞的计算,那么在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);    // 返回scene    return scene;}

运行的效果:

转载地址:http://eyuyx.baihongyu.com/

你可能感兴趣的文章
SMA推出Powerwall兼容Sunny Boy Storage逆变器
查看>>
云路由 vyatta 体验(二)NAT
查看>>
Python version 2.7 required, which was not foun...
查看>>
centos7.3 下安装 composer,解决Failed to decode zlib stream错误
查看>>
Git 常用命令
查看>>
在Postgres 数据库中生成36位的UUID代码
查看>>
小黑小波比.功能测试登录用户
查看>>
Java enum用法详解
查看>>
去云端的多条途径
查看>>
Docker容器从一知半解到入门
查看>>
关于“方法参数”
查看>>
Redis命令总结
查看>>
unable to write 'random state'错误解决
查看>>
context:annotation-config vs component-scan
查看>>
结构体和类的内存对齐原则-这一次弄清楚了对齐的本质规则
查看>>
Centos编译安装Nginx和PHP
查看>>
Linux-grep命令
查看>>
exgcd、二元一次不定方程学习笔记
查看>>
经典sql
查看>>
CSS3边框会动的信封
查看>>