热卖商品
新闻详情
[Cocos2d-x For WP8]矩形碰撞检测 - weixin_30500105的..._CSDN博客
来自 : CSDN技术社区
发布时间:2021-03-25
在游戏中我们通常会涉及到两个精灵之间的碰撞的计算 那么在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;}
运行的效果
转载于:https://www.cnblogs.com/linzheng/p/3279517.html
相关资源:晨晨网络留言板本文链接: http://dtothewp.immuno-online.com/view-740329.html
发布于 : 2021-03-25
阅读(0)
最新动态
2021-03-25
2021-03-25
2021-03-25
2021-03-25
2021-03-25
2021-03-25
2021-03-25
2021-03-25
2021-03-25
2021-03-25
2021-03-25
2021-03-25