coco2d-x 皮球弹跳翻案实现

cocos2d 皮球弹跳翻案实现

Dionysos 2014-4-14

       今天,策划提了个翻案,要求实现皮球的弹跳效果,并且能够实现模拟真实世界,要求有皮球收缩效果。下午,粗略的尝试下,大概效果是实现。当然还有很多细节,要在具体实现。先把代码放出来,能实现加入Box2D,在放一个新版本。代码如下:

BallFall.h

#ifndef __BALL_FALL_H__
#define __BALL_FALL_H__

#include "cocos2d.h"

USING_NS_CC;

class BallFall : public CCSprite
{
private:
	CCSprite*	m_spBall;
	float		m_fGravity;			///< 重力
	float		m_fRebound;			///< 反弹力
	float		m_fVelocity;		///< 速度
	float		m_fHorizontalLine;	///< 水平线
	int			m_iScale;			///< 形变次数
	int			m_iScaleType;			///< 球是否挤压

	void initData(const char* ballName, float fHorizontalLine);

public:
	BallFall();
	virtual ~BallFall();
	bool initDate(void);

	static BallFall* create(const char* ballName, float fHorizontalLine);
	virtual bool init(const char* ballName, float fHorizontalLine = 0.0f);

public:
	void FallUpdate(float delta);
	void openSchedule(void);
	void closeSchedule(void);
	void setHorizontalLine(float horizontalLine);
};
#endif

BallFall.cpp

#include "BallFall.h"

BallFall::BallFall()
{

}

BallFall::~BallFall()
{

}

///@brief 精灵创建
///
///@param[in] ballName--精灵路径 fHorizontalLine--水平线位置(这里代表y轴位置)
///@return 精灵对象
///@retval 
///@post 
///@author DionysosLai, 906391500@qq.com
///@version 1.0
///@data 2014-04-14
BallFall* BallFall::create(const char* ballName, float fHorizontalLine)
{
	BallFall *pSprite = new BallFall();
	if (pSprite && pSprite->init(ballName, fHorizontalLine))
	{
		pSprite->autorelease();
		return pSprite;
	}
	CC_SAFE_DELETE(pSprite);
	return NULL;
}

bool BallFall::init(const char* ballName, float fHorizontalLine)
{
	if (!CCSprite::init())
	{
		return false;
	}
	initData(ballName, fHorizontalLine);
	return true;
}

///@brief 数据初始化
///
///@param[in] ballName--精灵路径 fHorizontalLine--水平线位置(这里代表y轴位置)
///@return 无
///@retval 
///@post 
///@author DionysosLai, 906391500@qq.com
///@version 1.0
///@data 2014-04-14
void BallFall::initData(const char* ballName, float fHorizontalLine)
{
	m_fGravity	= 1.0f;		///< 重力
	m_fRebound	= 0.0f;			///< 反弹力
	m_fVelocity	= 0.0f;			///< 速度
	m_fHorizontalLine	= fHorizontalLine;		///< 水平线
	m_iScale	= 3;

	m_spBall = CCSprite::create(ballName);
	m_spBall->setPosition(CCPointZero);
	addChild(m_spBall);
}

///@brief 设置水平位置
///
///@param[in] horizontalLine--水平线位置(这里代表y轴位置)
///@return 无
///@retval 
///@post 
///@author DionysosLai, 906391500@qq.com
///@version 1.0
///@data 2014-04-14
void BallFall::setHorizontalLine(float horizontalLine)
{
	m_fHorizontalLine = horizontalLine;
}

void BallFall::openSchedule(void)
{
	schedule(schedule_selector(BallFall::FallUpdate), 0.05f);
}

void BallFall::closeSchedule(void)
{
	unschedule(schedule_selector(BallFall::FallUpdate));
}

///@brief 皮球弹跳主要函数 主要完成位置更新,速度更新,反弹力跟新等
///
///@param[in] 
///@return 无
///@retval 
///@post 
///@author DionysosLai, 906391500@qq.com
///@version 1.0
///@data 2014-04-14
void BallFall::FallUpdate(float delta)
{
	CCPoint	pointBall	= this->getPosition();
	CCSize	sizeBall	= m_spBall->getContentSize();	
	/// 首先监测球是否碰到地面了
	if (0.2 > pointBall.y-m_fHorizontalLine-sizeBall.height/2.0f)		///< 这里不用0.0, 是保证误差存在
	{
		if (0 == m_iScaleType) 
		{			
			m_fRebound = m_fVelocity/4.f;
			if (m_fRebound <= -5.5f )
			{
				m_fRebound = -5.5f;			///< 调整反弹力,否则会越跳越高
			}
			if (m_fRebound >= -0.2f)
			{
				closeSchedule();
			}
			m_fVelocity = -m_fGravity-m_fRebound;		///< 速度调整
			pointBall.y += m_fVelocity;
			this->setPosition(pointBall);

		}
		else
		{
			float scaleBallY = m_spBall->getScaleY();
			if (1 == m_iScaleType)
			{
				m_spBall->setScaleY(scaleBallY - 0.1f);
				m_iScale--;
				if (0 >= m_iScale)
				{
					m_iScaleType = 2;
				}
			}
			else
			{
				m_spBall->setScaleY(scaleBallY + 0.1f);
				scaleBallY = m_spBall->getScaleY();
				if (scaleBallY >= 1.0f)
				{
					m_iScaleType = 0;
				}
			}
		}
	}
	else
	{
		pointBall.y += m_fVelocity;
		/// 监测是否碰到地面了
		if (0.2 > pointBall.y-m_fHorizontalLine-sizeBall.height/2.0f)
		{
			pointBall.y	= m_fHorizontalLine+sizeBall.height/2.0f;
			m_iScale = -(int)(m_fVelocity/6);
			if (m_iScale >= 3)
			{
				m_iScale = 3;
			}
			m_iScaleType = 1;
		}
		else
		{
			m_fVelocity += -m_fGravity-m_fRebound;		///< 速度调整
		}

		if (0.0 != m_fRebound)
		{
			m_fRebound += 1.f;
			if (0.1 < m_fRebound)
			{
				m_fRebound = 0.0f;
			}
		}		
		this->setPosition(pointBall);
	}
}

用法如下:

	/// 添加“球”精灵
	BallFall* bf = BallFall::create("01.png", 0.0f);
	bf->setPosition(ccp(visibleSize.width/2.0f, visibleSize.height));
	bf->openSchedule();
	this->addChild(bf, 2);

皮球效果还有几个方面要提高:

1.      皮球变形时,是两边一起变形,改进方案是一边变形即可;

2.      皮球变形时,位置未调整,气球比较小,看不出来,如果比较大,那肯定有“悬空”感觉------等着测试发bug吧,因此要调整;

3.      只能实现y轴弹跳,下次改进翻案:传入下落的高度,但地面可以根据手机倾斜角度发生变化(。。。好像游戏地面不能倾斜吧);

4.      皮球静止是,应该是随机向左右两边移动,这样跟真实(尝试加入小石头,碰到小石头,皮球形变,弹跳方向均发生变化。)

===就想到这里了。




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值