精灵

来源:互联网 发布:体积配箍率计算软件 编辑:程序博客网 时间:2024/03/29 20:39

内容:

一、添加精灵

二、移动精灵

三、发射炮弹

四、碰撞检测


一、添加精灵

详见: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 calculatedtarget->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 withCCTouch* touch = (CCTouch*)( pTouches->anyObject() );CCPoint location = touch->locationInView();location = CCDirector::sharedDirector()->convertToGL(location);// Set up initial location of projectileCCSize 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 projectileint offX = location.x - projectile->getPosition().x;int offY = location.y - projectile->getPosition().y;// Bail out if we are shooting down or backwardsif (offX <= 0) return;// Ok to add now - we've double checked positionthis->addChild(projectile);// Determine where we wish to shoot the projectile toint 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 shootingint 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/1secfloat realMoveDuration = length/velocity;// Move projectile to actual endpointprojectile->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.



原创粉丝点击