cocos2dx之飞机大战简单版(1)

先说下版本   vs2010+cocos2dx2.2

本章主要是告诉大家如何实现创建背景、飞机、***精灵,并且然后他们动起来,然后做一个碰撞测试,当***和敌方飞机碰撞时就销毁精灵并且加一个爆炸的精灵。

  1. 创建背景、飞机、***精灵

先在GameScene.h中添加以下成员

GameScene();
~GameScene();
void addMonster();
void addBullet1();
void GameLogic(float dt);
void GameLogicaddBullet1(float dt);
void GameLogicaddBullet2(float dt);
void spriteMoveFinished(CCNode *sender);
void keyArrowClicked(int arrow);
void ccTouchesBegan(cocos2d::CCSet *pTouches,cocos2d::CCEvent *pEvent);
void ccTouchesMoved(cocos2d::CCSet *pTouches,cocos2d::CCEvent *pEvent);
cocos2d::CCArray     *_monsters;
    cocos2d::CCArray     *_bullets;
cocos2d::CCSprite    *player;
cocos2d::CCSprite *bgSprite1;
cocos2d::CCSize visibleSize;
cocos2d::CCPoint origin;
int bgHeight;
int monsterSpeed;

在GameScene::init()中添加以下代码

visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    origin = CCDirector::sharedDirector()->getVisibleOrigin();
bgHeight =  (visibleSize.height + origin.y);
    bgSprite1=CCSprite::create("background.png");  
    bgSprite1->setAnchorPoint(ccp(0.5, 0));  
    bgSprite1->setPosition(ccp(visibleSize.width/2 + origin.x,bgHeight));  
      
    this->addChild(bgSprite1, 0);
player = CCSprite::create("player.png");
player->setPosition(ccp(origin.x + visibleSize.width/2,origin.y + player->getContentSize().height/2));
this->addChild(player,1);

这样,很简单我们就创建了一个背景精灵和一个飞机精灵,由于背景和飞机只有一个,所以我们可以考虑把他们设为类的成员

由于***和敌方飞机有很多,所以我们应该把他们单独写为函数,然后在init中设置一个计时器,通过计时器来设置多少秒调用一次函数,在函数中去添加***和敌方飞机精灵

首先先贴上添加***和敌方飞机的函数的代码

void GameScene::addMonster(){
CCSprite* pMonster = CCSprite::create("monster.png");
    int minX = pMonster->getContentSize().width  /2;
    int maxX = visibleSize.width - pMonster->getContentSize().width /2;
    int rangeX = maxX - minX;
    int actualX = (rand() % rangeX) + minX;
pMonster->setPosition(ccp(actualX,origin.y + visibleSize.height - pMonster->getContentSize().height));
this->addChild(pMonster,1);
int time = (origin.y + visibleSize.height - pMonster->getContentSize().height)/monsterSpeed;
    //time s内从原来位置到ccp(actualX,origin.y + pMonster->getContentSize().height/2)位置
    CCMoveTo *actionMove = CCMoveTo::create(time,ccp(actualX,origin.y + pMonster->getContentSize().height/2));
    CCCallFuncN *actionMoveDone = CCCallFuncN::create(this, callfuncN_selector(GameScene::spriteMoveFinished));
    pMonster->runAction(CCSequence::create(actionMove, actionMoveDone, NULL));
void GameScene::addBullet1(){
CCSprite* pBullet = CCSprite::create("bullet1.png");
float x = player->getPositionX();
float y = player->getPositionY();
pBullet->setPosition(ccp(x,y+40));
this->addChild(pBullet,2);
CCMoveTo *actionMove = CCMoveTo::create(1,ccp(x,origin.y + visibleSize.height - pBullet->getContentSize().height));
CCCallFuncN *actionMoveDone = CCCallFuncN::create(this, callfuncN_selector(GameScene::spriteMoveFinished));
    pBullet->runAction(CCSequence::create(actionMove, actionMoveDone, NULL));

第一段代码中首先我们先添加了一个敌方飞机的精灵,注意敌方飞机出现的位置的x值是随机的,所以我们应该把它设为他出现位置的最大x值和最小x值的随机数

然后我们开始设置他的移动,CCMoveTo::create函数中第一个参数是移动的时间,第二个参数是,从原来的点移动到的那个点的值,然后我们设置一个actionMoveDone来设置当敌方飞机移动完了之后就销毁它,销毁的代码我们就设置spriteMoveFinished中

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

最后我们用runAction来移动精灵

在我们了解了如何移动敌方飞机了之后,我们移动***的代码就和容易理解了,几乎是一模一样的

我们现在只是完成了添加敌方飞机和***并让它们动了起来,然后我们还要在init中添加计时器还添加更多敌方飞机和***

在init中添加以下代码:

//生成敌方飞机
this->schedule(schedule_selector(GameScene::GameLogic),0.5);
//生成***
this->schedule(schedule_selector(GameScene::GameLogicaddBullet1),0.3);

上面函数的意思是,0.5s调用一次GameLogic函数,0.3s调用一次GameLogicaddBullet1函数。所以我们只需要在GameLogic中调用addMonster,在GameLogicaddBullet1中调用addBullet1就可以了

void GameScene::GameLogic(float dt)
{
    this->addMonster();
}
void GameScene::GameLogicaddBullet1(float dt){
this->addBullet1();
}

注意一定要在参数中加上float dt,它是表明多少秒调用一次这个函数。

2.通过触屏移动飞机

现在只有敌方飞机和***会移动,我们玩家的飞机还不会移动,下面就教大家如何移动玩家飞机

首先先在init中添加

this->setTouchEnabled(true);

让程序支持触屏

然后重载ccTouchesBegan函数

void GameScene::ccTouchesBegan(cocos2d::CCSet *pTouches,cocos2d::CCEvent *pEvent){
CCTouch *touch = (CCTouch*)pTouches->anyObject();
CCPoint location = this->convertTouchToNodeSpace(touch);
//如果触摸点在屏外则将点设在屏幕边缘
if(location.x < origin.x + player->getContentSize().width/2)
location.x = origin.x + player->getContentSize().width/2;
if(location.x > origin.x + visibleSize.width - player->getContentSize().width/2)
location.x = origin.x + visibleSize.width - player->getContentSize().width/2;
if(location.y < origin.y+player->getContentSize().height/2)
location.y = origin.y+player->getContentSize().height/2;
if(location.y > origin.y + visibleSize.height - player->getContentSize().height/2)
location.y = origin.y + visibleSize.height - player->getContentSize().height/2;

float x1 = player->getPositionX();
float y1 = player->getPositionY();
float x2 = location.x;
float y2 = location.y;
float length = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
float speed  = 480;
float time   = length/speed;
//停止之前的动作
player->stopAllActions();
CCMoveTo *actionMove = CCMoveTo::create(time,location);
    player->runAction(actionMove);
}

前两句是获取触摸点location,如果触摸点在屏幕外就把它设置在里面

因为CCMoveTo第一个参数是时间不是速度,我们为了让移动任何距离的速度都一样我们需要计算一下把时间设为变量,用勾股定理算出移动的长度,然后设置移动的速度,最后就可以算出移动的时间的

我们之前只是重载ccTouchesBegan函数,我们发现飞机只有在我们鼠标点下去的时候才会移动,飞机并不会随着我们鼠标的拖动而移动,所以我们还需要重载ccTouchesMoved函数

void GameScene::ccTouchesMoved(cocos2d::CCSet *pTouches,cocos2d::CCEvent *pEvent){
CCTouch *touch = (CCTouch*)pTouches->anyObject();
CCPoint location = this->convertTouchToNodeSpace(touch);
//如果触摸点在屏外则将点设在屏幕边缘
if(location.x < origin.x+player->getContentSize().width/2)
location.x = origin.x+player->getContentSize().width/2;
if(location.x > origin.x + visibleSize.width - player->getContentSize().width/2)
location.x = origin.x + visibleSize.width - player->getContentSize().width/2;
if(location.y < origin.y+player->getContentSize().height/2)
location.y = origin.y+player->getContentSize().height/2;
if(location.y > origin.y + visibleSize.height - player->getContentSize().height/2)
location.y = origin.y + visibleSize.height - player->getContentSize().height/2;
  
player->setPosition(location);
}

因为每一次拖动鼠标都会调用ccTouchesMoved函数,所以我们用setPosition就可以了

敌方飞机和***都会移动了,我们最后只需要设置碰撞就可以了

3.碰撞测试

因为,敌方飞机和***不是一个精灵所以我们要用一个容器把他们装起来

在init中添加

cocos2d::CCArray     *_monsters;

cocos2d::CCArray     *_bullets;

然后在构造函数中把他们初始化为NULL

在虚构函数中添加

GameScene::~GameScene(){
 if (_monsters)
    {
        _monsters->release();
        _monsters = NULL;
    }
    if (_bullets)
    {
        _bullets->release();
        _bullets = NULL;
    }
}

我们需要在添加飞机和***精灵的时候把他们装进容器里面

分别在addMonster和addBullet1中添加添加以下代码

//给敌方飞机添加标签,并把敌方飞机添加到数组中
pMonster->setTag(1);
    _monsters->addObject(pMonster);
//给***添加标签,并把***添加到数组中
pBullet->setTag(2);
    _bullets->addObject(pBullet);

然后在spriteMoveFinished中添加当销毁飞机和***和把他们从容器中删除

在spriteMoveFinished中添加以下代码

if (sprite->getTag() == 1)
{
_monsters->removeObject(sprite);
}
else if (sprite->getTag() ==2)
{
_bullets->removeObject(sprite);
}

最后我们就可以做碰撞测试了,我们把碰撞做成一个计时器,让他每一帧调用一次来判断碰撞

在init中添加

void GameScene::collision(float dt){
CCArray *bulletsToDelete = CCArray::create();
CCObject *pObject = NULL;
CCObject *pObject2 = NULL;
CCARRAY_FOREACH(_bullets, pObject){                           //遍历***数组
CCSprite *bullet = (CCSprite*)pObject;
CCArray *monstersToDelete = CCArray::create();
CCARRAY_FOREACH(_monsters, pObject2)                      //遍历敌方飞机数组
{
CCSprite *monster = (CCSprite*)pObject2;
if(bullet->boundingBox().intersectsRect(monster->boundingBox()))      //判断***的边界是否碰到敌方飞机的边界       
{
monstersToDelete->addObject(monster);    //***碰到飞机边界的话就放入monstersToDelete中
bulletsToDelete->addObject(bullet);              //同样***也要放入bulletsToDelete中
}           
}
CCARRAY_FOREACH(monstersToDelete, pObject2)//遍历monstersToDelete,把待删除的飞机都删除了
{
CCSprite *monster = (CCSprite*)pObject2;
_monsters->removeObject(monster);
this->removeChild(monster, true);
}
monstersToDelete->release();
}
CCARRAY_FOREACH(bulletsToDelete, pObject)    //遍历bulletsToDelete,把待删除的***都删除了
{
CCSprite *bullet = (CCSprite*)pObject;
_bullets->removeObject(bullet);
//爆炸点
CCSprite *monsterExplosion = CCSprite::create ("monsterExplosion.png");
float x = bullet->getPositionX();
float y = bullet->getPositionY();
monsterExplosion->setPosition (ccp(x,y));
this->removeChild(bullet, true);
//爆炸
this->addChild(monsterExplosion,2);
CCActionInterval * fadeout = CCFadeOut::create(1);
CCCallFuncN *actionMoveDone = CCCallFuncN::create(this, callfuncN_selector(GameScene::spriteMoveFinished));
monsterExplosion->runAction(CCSequence::create(fadeout,actionMoveDone,NULL));
//爆炸音效
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("explosion.mp3");
//分数加一
score += 1;
}
bulletsToDelete->release();
//玩家飞机与敌方飞机碰撞
CCARRAY_FOREACH(_monsters, pObject2)                             //遍历敌方飞机数组
{
CCSprite *monster = (CCSprite*)pObject2;
if(player->boundingBox().intersectsRect(monster->boundingBox()))          //判断玩家飞机的边界是否与敌方飞机碰撞
{
CCSprite *playerExplosion = CCSprite::create("playerExplosion.png");
playerExplosion->setPosition(player->getPosition());
this->addChild(playerExplosion,2);
CCActionInterval * fadeout = CCFadeOut::create(1);
CCCallFuncN *actionMoveDone = CCCallFuncN::create(this, callfuncN_selector(GameScene::spriteMoveFinished));
playerExplosion->runAction(CCSequence::create(fadeout,actionMoveDone,NULL));
//失败画面
GameScene::gameOver();
}
}
}

我们把之前的***数组和敌方飞机容器遍历一边,判断他们是否碰撞,碰撞的话就放到一个待删除的容器中去,最后再遍历这个待删除的容器,把里面的精灵都删除了。

另外我们还需要在删除他们之前添加一个爆炸的精灵,达到飞机爆炸的效果。

接着我们遍历敌方飞机容器,判断它们和玩家飞机是否碰撞,碰撞的话就添加一个爆炸精灵,并且弹出失败的画面。

失败的画面我们会在下一章介绍,在下一章的内容中我们会进一步的完善我们的游戏,现在我们的游戏虽然能玩了但是它还缺少一些游戏的因素,例如分数、画面滚动、主菜单界面等等,我们会在下一章中介绍。

时间: 2024-11-12 02:28:01

cocos2dx之飞机大战简单版(1)的相关文章

Unity 飞机大战增强版

简介: 感谢: 本应用使用<Unity3D\2D手机游戏开发>提供的资源,版权归属其作者,在此感谢作者.此应用时基于原作的二次开发. 增强要素: 1.加入2s cd的机身旋转,旋转时保持无敌状态,人挡杀人... 2.加入0,5s cd的跟踪导弹,导弹随机打击目标敌人. 3.加强小飞机AI,小飞机拥有三种飞行模式,直线,sin曲线,以及追踪玩家.以不同概率随机选择飞行模式. 技术要素: 1.对于玩家飞机,采用简单switch-case有限状态机. 2.对于小飞机AI则使用RAIN AI 行为树.

Cocos2d-x飞机大战教程笔记

咳咳~跟着大神的教程学做Cocos2d-x的飞机大战...鉴于我是那种跟着教程都会出非常多错的人,所以还是一路跟着做些笔记比較好.并且因为是用课余时间,所以仅仅能断断续续地做,写下来也好让自己别忘记~ 2014/4/22  Day01 从apk解压获取素材.再用TexturePacker拼接成plist和png. 话说TexturePacker是收费的啊...7天免费,还能够申请1年的使用期. 之前看书还看到有个神器叫zwoptex,貌似是免费的.可惜仅仅有Mac版...╮(╯_╰)╭Howev

Cocos2d-x 3.0final 终结者系列教程16-《微信飞机大战》实现

看到cocos2d-x推出了3.1版本,真是每月一次新版本,速度, 还有一个好消息就是http://cn.cocos2d-x.org/上线了,祝贺!啥时候把我的视频和教程放上去呢?!!! 本文介绍一款纵版射击游戏的实现,开发环境: win7 vs2012 cocos2d-x3.0final android adt android ndk r9 首先看下最后的效果: (图1,微信飞机大战运行效果) 源码下载地址:http://download.csdn.net/detail/sdhjob/7513

豪华版飞机大战系列(一)

鉴于最近在学习cocos2d-x开发手游,对于学习过程中的一些东西做个总结,也记录下学习历程,同时分享些项目源码来和大家一起学习. 第一次写系列教程,可能中间有疏漏的,看到的还请给提个醒,不好的也多多吐槽,以便自己能更好的以后的开发中基类经验. 此次教程分享下豪华版的飞机大战,老规矩,先上图: 介绍下开发环境:cocos2d-x3.2 alpha + Ubuntu14.04 + eclipse + 命令行终端 + android 用的引擎为3.2版本的,3.0以上的应该都能运行跑下来,windo

Cocos2d-x《雷电大战》(5)-单例模式英雄飞机闪亮登场!

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文将实现用单例模式实现一个英雄飞机类的设计,单例模式是游戏开发中最常用到的一种设计模式,原理也比较简单,仔细研究下就可以掌握好. 来看看效果: Cocos2d-x版本:3.4 工程环境:VS30213 一.单例模式解析 单例模式也称为单件模式.单子模式,可能是使用最广泛的设计模式.其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享.有很多地方需要这样的功

《简单的飞机大战》其实不简单(1)

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="white-space:pre"> </span>这是一个非常简单的<经典飞机大战>游戏,实现的基本功能:包括Boss的随机生成,击中销毁:分数根据击毁Boss的数量增加.附加功能有:道具的不定时产生,当英

Python版飞机大战

前面学了java用java写了飞机大战这次学完python基础后写了个python版的飞机大战,有兴趣的可以看下. 父类是飞行物类是所有对象的父类,setting里面是需要加载的图片,你可以换称自己的喜欢的图片,敌机可以分为敌机和奖励,enemy为普通敌人的父类,award为奖励敌机的父类. 各个类的基本属性 主类的大概逻辑 具体的代码: settings配置 import pygame class Settings(object): """设置常用的属性"&quo

cocos2dx 3.0 飞机大战

因为课程须要.然后又水平有限.所以写了个飞机大战.加上不会画画.所以图片资源也是从微信apk解压出来的,设计思路參考的偶尔e网事. 闲话不说.先讲一下设计.大体上一共分为3个场景.场景以下是Layer 開始场景:WelcomeScene -->WelcomeLayer  类似欢迎界面 游戏主场景:GameScene  --> GameLayer  游戏元素加入 和 碰撞检測 结束场景:GameOverScene -->GameOverLayer 然后是游戏的元素,在GameLayer加入

《简单的飞机大战》事实上不简单(1)

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="white-space:pre"> </span>这是一个很easy的<经典飞机大战>游戏.实现的基本功能:包含Boss的随机生成,击中销毁:分数依据击毁Boss的数量添加. 附加功能有:道具的不定时产生,