TouchTest 阅读学习笔记


class Ball : public CCSprite
{
    CCPoint m_velocity;
public:
    Ball(void);
    virtual ~Ball(void);
    float radius();
    // 用来移动精灵对象
    void move(float delta);	
    // 对与paddle做碰撞处理									
    void collideWithPaddle(Paddle* paddle);						
public:
    void setVelocity(CCPoint velocity){m_velocity = velocity;}
    CCPoint getVelocity(){return m_velocity;}
public:
	// 绑定一个2d纹理
    static Ball* ballWithTexture(CCTexture2D* aTexture);		
};

// 这里我们绑定给定的图片纹理,在不用时自动释放精灵对象
Ball* Ball::ballWithTexture(CCTexture2D* aTexture)
{
    Ball* pBall = new Ball();
    pBall->initWithTexture(aTexture);
    pBall->autorelease();
    return pBall;
}

void Ball::move(float delta)
{
	// 计算移动距离,并设置球的位置
    this->setPosition( ccpAdd(getPosition(), ccpMult(m_velocity, delta)) );
    // 若球的位置越过了左边、右边的可视区域边界,修正球的位置并把速度的x方向反向处理
    if (getPosition().x > VisibleRect::right().x - radius()) 
    {
        setPosition( ccp( VisibleRect::right().x - radius(), getPosition().y) );
        m_velocity.x *= -1;
    } 
    else if (getPosition().x < VisibleRect::left().x + radius()) 
    {
        setPosition( ccp(VisibleRect::left().x + radius(), getPosition().y) );
        m_velocity.x *= -1;
    }
}
// 设定板子的边界,
CCRect Paddle::rect()
{
    CCSize s = getTexture()->getContentSize();
    return CCRectMake(-s.width / 2, -s.height / 2, s.width, s.height);
}
void Ball::collideWithPaddle(Paddle* paddle)
{
	// 获取板子的边界,精灵的默认锚点为(0.5,0.5),position就是中心点,这里还原为原来的paddle边界,取得边界值
    CCRect paddleRect = paddle->rect();
    paddleRect.origin.x += paddle->getPosition().x;
    paddleRect.origin.y += paddle->getPosition().y;
    
    float lowY  = paddleRect.getMinY();
    float midY  = paddleRect.getMidY();
    float highY = paddleRect.getMaxY();
    float leftX  = paddleRect.getMinX();
    float rightX = paddleRect.getMaxX();
    // 球的x是否在碰撞范围内
    if (getPosition().x > leftX && getPosition().x < rightX) {
    
        bool hit = false;
        float angleOffset = 0.0f; 
        
        if (getPosition().y > midY && getPosition().y <= highY + radius()) 
        {
        	// 碰下面的板子,设定角度偏移
            setPosition( ccp(getPosition().x, highY + radius()) );
            hit = true;
            angleOffset = (float)M_PI / 2;
        }
        else if (getPosition().y < midY && getPosition().y >= lowY - radius()) 
        {
        	// 碰撞上面的板子,设定角度偏移
            setPosition( ccp(getPosition().x, lowY - radius()) );
            hit = true;
            angleOffset = -(float)M_PI / 2;
        }
        
        if (hit) 
        {
        	// 重定向速度方向和位置(下面怎么计算的不理解,物理知识弱爆了)
			CCPoint cp1 = ccpSub(paddle->getPosition(), getPosition());
			float angle1 = ccpToAngle(cp1);
            float hitAngle = angle1 + angleOffset;
            
            float scalarVelocity = ccpLength(m_velocity) * 1.05f;
			float angle2 = ccpToAngle(m_velocity);
            float velocityAngle = -angle2 + 0.5f * hitAngle;
            
            m_velocity = ccpMult(ccpForAngle(velocityAngle), scalarVelocity);
        }
    }    
} 

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 CCObject* copyWithZone(CCZone *pZone);
    virtual void touchDelegateRetain();
    virtual void touchDelegateRelease();
    static Paddle* paddleWithTexture(CCTexture2D* aTexture);
};

// 给paddle增加绑定纹理
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;
}


// 注册屏幕触摸处理事件
onEnter :	CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
onExit  :	CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);

// 若paddle包含数目点,设置捕获状态
bool Paddle::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
    if (m_state != kPaddleStateUngrabbed) return false;
    if ( !containsTouchLocation(touch) ) return false;
    m_state = kPaddleStateGrabbed;
    return true;
}
// 捕获paddle后,重新设置paddle位置
void Paddle::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
    CCAssert(m_state == kPaddleStateGrabbed, "Paddle - Unexpected state!");    
    CCPoint touchPoint = touch->getLocation();
    setPosition( ccp(touchPoint.x, getPosition().y) );
}
// 释放捕获,设置状态
void Paddle::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
    CCAssert(m_state == kPaddleStateGrabbed, "Paddle - Unexpected state!");    
    
    m_state = kPaddleStateUngrabbed;
} 
// 创建paddle的copy处理
CCObject* Paddle::copyWithZone(CCZone *pZone)
{
	this->retain();
	return this;
}

void Paddle::touchDelegateRetain()
{
    this->retain();
}

void Paddle::touchDelegateRelease()
{
    this->release();
}

// 测试场景
class PongScene : public TestScene
{
public:
    PongScene();
    virtual void runThisTest();
    virtual void MainMenuCallback(CCObject* pSender);
};

class Ball;
class PongLayer : public CCLayer
{
private:
    Ball*       m_ball;
    CCArray*    m_paddles;
    CCPoint     m_ballStartingVelocity; 
public:
    PongLayer();
    ~PongLayer();


    void resetAndScoreBallForPlayer(int player);
    void doStep(float delta);
};

PongLayer::PongLayer()
{
    m_ballStartingVelocity = ccp(20.0f, -100.0f);
    // 创建球精灵,并绑定纹理,设定速度值
    m_ball = Ball::ballWithTexture( CCTextureCache::sharedTextureCache()->addImage(s_Ball) );
    m_ball->setPosition( VisibleRect::center() );
    m_ball->setVelocity( m_ballStartingVelocity );
    addChild( m_ball );
    m_ball->retain();
    // 创建平板的纹理,绑定到精灵上
    CCTexture2D* paddleTexture = CCTextureCache::sharedTextureCache()->addImage(s_Paddle);
    CCArray *paddlesM = CCArray::createWithCapacity(4);
    
    Paddle* paddle = Paddle::paddleWithTexture(paddleTexture);
    paddle->setPosition( ccp(VisibleRect::center().x, VisibleRect::bottom().y + 15) );
    paddlesM->addObject( paddle );
    
    paddle = Paddle::paddleWithTexture( paddleTexture );
    paddle->setPosition( ccp(VisibleRect::center().x, VisibleRect::top().y - kStatusBarHeight - 15) );
    paddlesM->addObject( paddle );
    
    paddle = Paddle::paddleWithTexture( paddleTexture );
    paddle->setPosition( ccp(VisibleRect::center().x, VisibleRect::bottom().y + 100) );
    paddlesM->addObject( paddle );
    
    paddle = Paddle::paddleWithTexture( paddleTexture );
    paddle->setPosition( ccp(VisibleRect::center().x, VisibleRect::top().y - kStatusBarHeight - 100) );
    paddlesM->addObject( paddle );
    // 将创建的4个精灵平板加入到数组中
    m_paddles = (CCArray*)paddlesM->copy();
    // 将平板对象加入到场景层中
    CCObject* pObj = NULL;
    CCARRAY_FOREACH(m_paddles, pObj)
    {
        paddle = (Paddle*)(pObj);
        if(!paddle)
            break;
        addChild(paddle);
    }
    // 每帧调度doStep方法
    schedule( schedule_selector(PongLayer::doStep) );
}
// 重置球数据,包括位置和速度
void PongLayer::resetAndScoreBallForPlayer(int player)
{
    m_ballStartingVelocity = ccpMult(m_ballStartingVelocity, -1.0f);
    m_ball->setVelocity( m_ballStartingVelocity );
    m_ball->setPosition( VisibleRect::center() );
}

void PongLayer::doStep(float delta)
{
	// 移动球
    m_ball->move(delta);
    // 检测球与平板的碰撞与否,并作相应的处理
    Paddle* paddle = NULL;
    CCObject* pObj = NULL;
    CCARRAY_FOREACH(m_paddles, pObj)
    {
        paddle = (Paddle*)(pObj);
        if(!paddle)
            break;
        m_ball->collideWithPaddle( paddle );
    }
    // 球的y值超过了可视区域,重新球数据
    if (m_ball->getPosition().y > VisibleRect::top().y - kStatusBarHeight + m_ball->radius())
        resetAndScoreBallForPlayer( kLowPlayer );
    else if (m_ball->getPosition().y < VisibleRect::bottom().y-m_ball->radius())
        resetAndScoreBallForPlayer( kHighPlayer );
    // 每帧绘制球
    m_ball->draw();
} 








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值