精灵

内容:

一、添加精灵

二、移动精灵

三、发射炮弹

四、碰撞检测


一、添加精灵

详见:http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Chapter_2_-_How_to_Add_a_sprite#13-add-resources-on-win32

步骤:

1. Add image resources
2. Add a sprite

代码:

		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
		CCSprite *player = CCSprite::create("Player.png", CCRectMake(0, 0, 27, 40) );
		player->setPosition( ccp(player->getContentSize().width/2, winSize.height/2) );
		this->addChild(player);

二、移动精灵

详见:http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Chapter_3_-_How_to_Move_a_sprite

头文件:

	void addTarget();
	void spriteMoveFinished(CCNode *sender);
	void gameLogic(float dt);

1、we should put the enemies into the scene at intervals, add the codes before init() function returns.

		//每秒执行一次
	    this->schedule( schedule_selector(HelloWorld::gameLogic), 1.0 ); 

2、回调函数

void HelloWorld::gameLogic(float dt)
{
	this->addTarget();
}

3、添加敌人的方法

void HelloWorld::addTarget()
{
	CCSprite *target = CCSprite::create("Target.png", CCRectMake(0,0,27,40) );

	// Determine where to spawn the target along the Y axis 计算y坐标的范围
	CCSize winSize = CCDirector::sharedDirector()->getWinSize();
	int minY = target->getContentSize().height/2;
	int maxY = winSize.height - target->getContentSize().height/2;
	int rangeY = maxY - minY;
	// srand( TimGetTicks() );随机生成一个Y值
	int actualY = ( rand() % rangeY ) + minY;

	// Create the target slightly off-screen along the right edge,
	// and along a random position along the Y axis as calculated
	target->setPosition( 
		ccp(winSize.width + (target->getContentSize().width/2), 
		actualY) );//出生在屏幕右侧的外边
	this->addChild(target);

	// Determine speed of the target 穿过横屏的时间
	int minDuration = (int)2.0;
	int maxDuration = (int)4.0;
	int rangeDuration = maxDuration - minDuration;
	// srand( TimGetTicks() );
	int actualDuration = ( rand() % rangeDuration )
		+ minDuration;

	// Create the actions 在限定的时间从开始位置移动到目标位置
	CCFiniteTimeAction* actionMove = 
		CCMoveTo::create( (float)actualDuration,//所需时间			
		ccp(0 - target->getContentSize().width/2, actualY) ); //目标点 屏幕左侧的外边
	CCFiniteTimeAction* actionMoveDone = 
		CCCallFuncN::create( this, 
		callfuncN_selector(HelloWorld::spriteMoveFinished));//动作执行完毕后执行的方法
	target->runAction( CCSequence::create(actionMove, actionMoveDone, NULL) );//执行动作
}

4、销毁该精灵

动作执行完毕后执行的方法,回调函数

void HelloWorld::spriteMoveFinished(CCNode *sender)
{
	CCSprite *sprite = (CCSprite *)sender;
	this->removeChild(sprite, true);
}

三、发射炮弹 

详见:http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Chapter_4_-_How_to_Fire_some_Bullets

Fire some Bullets
1、启用触摸/单击

Now, we want to let the hero fire some bullets to kill the enemies, add the codes below to set the layer touch-enabled.

在init函数中

this->setTouchEnabled(true);

2、添加触摸/单击事件 即发射炮弹

Then we could receive the touch event now.

Declare the callback function "void ccTouchesEnded(cocos2d::CCSet* touches, cocos2d::CCEvent* event);" in HelloWorldScene.h, and implement the function in HelloWorldScene.cpp.

void HelloWorld::ccTouchesEnded(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent)
{
	// Choose one of the touches to work with
	CCTouch* touch = (CCTouch*)( pTouches->anyObject() );
	CCPoint location = touch->locationInView();
	location = CCDirector::sharedDirector()->convertToGL(location);

	// Set up initial location of projectile
	CCSize winSize = CCDirector::sharedDirector()->getWinSize();
	CCSprite *projectile = CCSprite::create("Projectile.png", 
		CCRectMake(0, 0, 20, 20));
	projectile->setPosition( ccp(20, winSize.height/2) );

	// Determinie offset of location to projectile
	int offX = location.x - projectile->getPosition().x;
	int offY = location.y - projectile->getPosition().y;

	// Bail out if we are shooting down or backwards
	if (offX <= 0) return;

	// Ok to add now - we've double checked position
	this->addChild(projectile);

	// Determine where we wish to shoot the projectile to
	int realX = winSize.width
		+ (projectile->getContentSize().width/2);
	float ratio = (float)offY / (float)offX;
	int realY = (realX * ratio) + projectile->getPosition().y;
	CCPoint realDest = ccp(realX, realY);

	// Determine the length of how far we're shooting
	int offRealX = realX - projectile->getPosition().x;
	int offRealY = realY - projectile->getPosition().y;
	float length = sqrtf((offRealX * offRealX) 
		+ (offRealY*offRealY));

	{
		//个人添加,固定Y计算x,再比较两者的长度,取短者
	    float offY2 = winSize.height/2 + (projectile->getContentSize().height/2);
		int realX2 = offY2/ratio;
		if (realX2 < 0)
			realX2 = -realX2;
		realX2 += projectile->getPosition().x; //加上起点位置
		int realY2 = (ratio>0) ?
			(winSize.height + (projectile->getContentSize().height + 2))
			: (-(projectile->getContentSize().height/2));
		int offRealX2 = realX2 - projectile->getPosition().x;
		int offRealY2 = realY2 - projectile->getPosition().y;
		float length2 = sqrtf((offRealX2 * offRealX2) 
			+ (offRealY2*offRealY2));
		if (length2 < length)
		{
			length = length2;
			realDest = ccp(realX2, realY2);
		}
	}

	float velocity = 480/1; // 480pixels/1sec
	float realMoveDuration = length/velocity;

	// Move projectile to actual endpoint
	projectile->runAction( CCSequence::create(
		CCMoveTo::create(realMoveDuration, realDest),
		CCCallFuncN::create(this, 

		callfuncN_selector(HelloWorld::spriteMoveFinished)), 
		NULL) );
}

四、碰撞检测

详见:http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Chapter_5_-_How_to_Detect_the_Collisions

Our hero can fire bullets now, but the bullets are only visual. So how can they kill their enemies?

In this chapter, we will introduce Collision Detection to implement it.

Firstly, it’s necessary to track the enemies and the bullets.

In the game, we add a tag for these two kinds of sprites to identify them. Let tag = 1 if the sprite is an enemy, and tag = 2 mean it is a bullet. Because CCSprite inherits from CCNode, there is already a member variable m_nTag with methods setTag() and getTag(); we can implement this to identify the different types of sprites.

1、定义成员

Add the two member variables below to HelloWorld in HelloWorldScene.h. These are used to store the existing enemies and bullets.

protected:
	cocos2d::CCArray *pTargets;
	cocos2d::CCArray *pProjectiles;  

2、成员初始化和释放

Then initialize the two variables in the construct function, new them in init(), and release them in the destruct function.

HelloWorld::HelloWorld()
	: pTargets(NULL), pProjectiles(NULL)
{
}

HelloWorld::~HelloWorld()
{
	if (pTargets)
	{
		pTargets->release();
		pTargets = NULL;
	}

	if (pProjectiles)
	{
		pProjectiles->release();
		pProjectiles = NULL;
	}
}

//init()
	pTargets = new CCArray;
	pProjectiles = new CCArray;
3、设置炮弹和敌人的标志,添加到成员中

Now modify addTarget() to add a new target to targets array, and set its tag to be 1.

	target->setTag(1);
	pTargets->addObject(target);  
Modify ccTouchesEnded() to add a new bullet to bullets array, and set its tag to be 2.

	projectile->setTag(1);
	pProjectiles->addObject(projectile); 
4、炮弹和敌人超出屏幕范围时,从成员中移除

Then, modify spriteMoveFinished() as follows. Here we remove the sprites from their corresponding arrays.

void HelloWorld::spriteMoveFinished(CCNode *sender)
{
	CCSprite *sprite = (CCSprite *)sender;
	this->removeChild(sprite, true);

	if (sprite->getTag() == 1)
	{
		pTargets->removeObject(sprite);
	}
	else if (sprite->getTag() == 2)
	{
		pProjectiles->removeObject(sprite);
	}
}

5、碰撞检测

The function update() below is used to detect collisions every frame, remove the collided bullet and enemy from the scene.
Declare it in HelloWorldScene.h and Define it in HelloWorldScene.cpp.

void HelloWorld::update(float dt)
{
	CCArray *projectilesToDelete = new CCArray;
	CCArray* targetsToDelete =new CCArray;
	CCObject* it = NULL;
	CCObject* jt = NULL;

	CCARRAY_FOREACH(pProjectiles, it)
	{
		CCSprite *projectile = dynamic_cast<CCSprite*>(it);
		CCRect projectileRect = CCRectMake(
			projectile->getPosition().x - (projectile->getContentSize().width/2),
			projectile->getPosition().y - (projectile->getContentSize().height/2),
			projectile->getContentSize().width,
			projectile->getContentSize().height);

		CCARRAY_FOREACH(pTargets, jt)
		{
			CCSprite *target = dynamic_cast<CCSprite*>(jt);
			CCRect targetRect = CCRectMake(
				target->getPosition().x - (target->getContentSize().width/2),
				target->getPosition().y - (target->getContentSize().height/2),
				target->getContentSize().width,
				target->getContentSize().height);
			if (projectileRect.intersectsRect(targetRect))
			{
				targetsToDelete->addObject(target);
				projectilesToDelete->addObject(projectile);
			}
		}
	}

	CCARRAY_FOREACH(targetsToDelete, jt)
	{
		CCSprite *target = dynamic_cast<CCSprite*>(jt);
		pTargets->removeObject(target);
		this->removeChild(target, true);
	}

	CCARRAY_FOREACH(projectilesToDelete, it)
	{
		CCSprite* projectile = dynamic_cast<CCSprite*>(it);
		pProjectiles->removeObject(projectile);
		this->removeChild(projectile, true);
	}

	projectilesToDelete->release();
	targetsToDelete->release();
}
6、启用检测

Ok, the last thing we should do is adding update() to the schedule to let it be called every frame.

this->schedule( schedule_selector(HelloWorld::update));//每帧都执行一次
Compile and run the project, fire the bullets as you like, then: AH..AH.., the enemies are killed one by one.


tip

Notice that CallbackFunc should be declared as public, otherwise it won't be backcalled.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值