这个植物大战僵尸的小游戏Demo 虽然下,但是基本包括了:
1.植物的选取、僵尸的攻击、发射子弹;
2.太阳的生成、碰撞检测等功能;
第一部分:Cocos2d-x简单游戏<植物大战僵尸>代码实现|第一部分:开始场景
第二部分:Cocos2d-x简单游戏<植物大战僵尸>代码实现|第二部分:菜单场景
第三部分:Cocos2d-x简单游戏<植物大战僵尸>代码实现|第三部分:通关场景
第四部分:Cocos2d-x简单游戏<植物大战僵尸>代码实现|第四部分:通关失败场景
第五部分:Cocos2d-x简单游戏<植物大战僵尸>代码实现|第五部分:公用类
第六部分:Cocos2d-x简单游戏<植物大战僵尸>代码实现|第六部分:植物类
第七部分:Cocos2d-x简单游戏<植物大战僵尸>代码实现|第七部分:僵尸类
第八部分:Cocos2d-x简单游戏<植物大战僵尸>代码实现|第八部分:子弹类
第九部分<A>:Cocos2d-x简单游戏<植物大战僵尸>代码实现|第九部分:游戏场景GameScene.h
第九部分<B>:Cocos2d-x简单游戏<植物大战僵尸>代码实现|第九部分:游戏场景GameScene.cpp
#ifndef __MyTest__Plants__
#define __MyTest__Plants__
#include <iostream>
#include "CommonHeader.h"
using namespace std;//引入c++命名空间
//定义宏 伤害系数(攻击力*伤害系数 =血量减少)
#define kAttackForceRatio 1
//定义各种类型的植物
typedef enum {
Sunflower =0,//向日葵
SmallPea ,//小豌豆
MidllePea ,//中等豌豆
ThreeBulletPea,//三发豌豆
Pumpkin,//南瓜
Paprika,//辣椒
Cherry,//樱桃
SmallNut,//小坚果
largeNut,//大坚果
Lilypad,//荷叶
CorpseFlower,//食人花
}PlantsName;
//植物的各种技能
typedef enum {
BulletSkill =0,//子弹
BombSkill,//爆炸
SwallowSkill,//吞噬
CollapseSkill,//压塌
SankSkill,//下沉
ChimeaSkill,//喷火(辣椒的技能)
ObstructSkill,//阻挡(坚果)
GraftingSkill,//可以做嫁接的载体(荷叶)
SunshineShill,//产生太阳
}SpecialSkill;
//场景植物种类
typedef enum {
Aquatic =0,//水生植物
LandMammals,//陆地植物
}PlacePlantsType;
//植物生长的时间
typedef enum {
Day =0,
Night,
}TimePlantsType;
//创建植物类
class Plants :publicCCSprite {
public:
//声明变量
PlacePlantsType placeType;
TimePlantsType timeType;
SpecialSkill specialSkill;
PlantsName plantsName;
CCArray *addZombieAttackThisPlant;//存放攻击这个植物的僵尸
float attackForce;//攻击力
float lifeForce;//生命力
int attackFrequency;//攻击频率
bool needWait;//是否处于冷却状态
int plantInterval;//种植时间间隔(技能冷却时间)
int tempPlantInterval;//(备份)
int needSunshine;//需要的阳光值
int createSunInterval;//产生阳关的间隔
int tempCreateSunInterval;//temp(备份)
int createPeaInterval;//创建豌豆子弹的间隔时间
int tempCreatePeaInterval;//备份豌豆产生子弹的间隔时间
bool canAttack;//是否能攻击
public:
//一些方法的声明
Plants(PlantsName name);//在构造函数中进行初始化植物名称
~Plants();//析构函数
/**************基本植物******************/
void createPlantByName(char *name);//创建植物根据植物名称
void runRepeatAction(CCArray *plistArray);//重复动作(永久动作)
void runOnceAction(CCArray *plistArray);//非永久性动作
/***************辣椒、樱桃、坚果*****************/
void paprikaCherryAction();//辣椒和樱桃的动作(爆炸动作)
void removePlants();//移除植物
void smallNutActionEatOverByZombie();//小坚果动作(被吃受损动作)
void smallNutActionEatOverMoreHarm();//受损更严重
void largeNutActionEatOvetByZombie();//大坚果动作(被吃受损动作)
void largeNutActionEatOverMoreharm();//受损更严重
/**************食人花******************/
void corpseFlowerAction1();//食人花动作1
void corpseFlowerAction2();//食人花动作2
void corpseFlowerAction3();//食人花动作3
/**************南瓜动作******************/
void pumpKinAction(CCSprite *pumpKin,CCPoint point);//南瓜动作
void pumpKinMoveAction(CCNode *sender,CCSprite *pumpKin);//移除南瓜
};
#endif /* defined(__MyTest__Plants__) */
#include "Plants.h"
#include <string.h>//导入字符串头文件
//构造函数---初始化枚举默认值
Plants::Plants(PlantsName name){
plantsName = name;
needWait = false;
canAttack = true;
addZombieAttackThisPlant =CCArray::create();
addZombieAttackThisPlant->retain();//内存retainCount+1
switch (name) {
case Sunflower:{//是太阳花时
placeType = LandMammals;//陆地植物
timeType = Day;//白天
specialSkill = SunshineShill;//照射
lifeForce = 10;//声明力10
plantInterval = 5;//生长速度
tempPlantInterval =5;//备份时间
needSunshine = 50;//需要的阳光数50
createSunInterval =5;//创建阳光的速度
tempCreateSunInterval =5;//备份
char title[] = "SunFlower";
this->createPlantByName(title);
break;
}
case SmallPea:{//小豌豆
placeType = LandMammals;//陆地植物
timeType = Day;//白天
specialSkill = SunshineShill;//照射
lifeForce = 10;//声明力10
plantInterval = 5;//生长速度
tempPlantInterval =5;//备份时间
needSunshine = 100;//需要的阳光数200
createSunInterval =5;//创建阳光的速度
tempCreateSunInterval =5;//备份
char title[] = "PeaShooter";
this->createPlantByName(title);
break;
}
case MidllePea:{//中等豌豆
placeType = LandMammals;//陆地植物
timeType = Day;//白天
specialSkill = SunshineShill;//照射
lifeForce = 10;//声明力10
plantInterval = 5;//生长速度
tempPlantInterval =5;//备份时间
needSunshine = 200;//需要的阳光数200
createSunInterval =5;//创建阳光的速度
tempCreateSunInterval =5;//备份
char title[] = "Repeater";
this->createPlantByName(title);
break;
}
caseThreeBulletPea:{//三个豌豆
placeType = LandMammals;//陆地植物
timeType = Day;//白天
specialSkill = SunshineShill;//照射
lifeForce = 10;//声明力10
plantInterval = 5;//生长速度
tempPlantInterval =5;//备份时间
needSunshine = 325;//需要的阳光数325
createSunInterval =5;//创建阳光的速度
tempCreateSunInterval =5;//备份
char title[] = "Threepeater";
this->createPlantByName(title);
break;
}
case Pumpkin:{//南瓜
placeType = LandMammals;//陆地植物
timeType = Day;//白天
specialSkill = SunshineShill;//照射
lifeForce = 10;//声明力10
plantInterval = 5;//生长速度
tempPlantInterval =5;//备份时间
needSunshine = 50;//需要的阳光数50
char title[] = "Squash";
this->createPlantByName(title);
break;
}
case Paprika:{//辣椒
placeType = LandMammals;//陆地植物
timeType = Day;//白天
specialSkill = SunshineShill;//照射
lifeForce = 10;//声明力10
plantInterval = 5;//生长速度
tempPlantInterval =5;//备份时间
needSunshine = 125;//需要的阳光数125
char title[] = "Jalapeno";
this->createPlantByName(title);
break;
}
case Cherry:{//樱桃
placeType = LandMammals;//陆地植物
timeType = Day;//白天
specialSkill = SunshineShill;//照射
lifeForce = 10;//声明力10
plantInterval = 5;//生长速度
tempPlantInterval =5;//备份时间
needSunshine = 150;//需要的阳光数150
char title[] = "CherryBomb";
this->createPlantByName(title);
break;
}
case SmallNut:{//小坚果
placeType = LandMammals;//陆地植物
timeType = Day;//白天
specialSkill = SunshineShill;//照射
lifeForce = 20;//声明力10
plantInterval = 5;//生长速度
tempPlantInterval =5;//备份时间
needSunshine = 50;//需要的阳光数50
char title[] = "WallNut";
this->createPlantByName(title);
break;
}
case largeNut:{//大坚果
placeType = LandMammals;//陆地植物
timeType = Day;//白天
specialSkill = SunshineShill;//照射
lifeForce = 30;//声明力10
plantInterval = 5;//生长速度
tempPlantInterval =5;//备份时间
needSunshine = 125;//需要的阳光数125
char title[] = "TallNut";
this->createPlantByName(title);
break;
}
case Lilypad:{//荷叶
placeType = LandMammals;//陆地植物
timeType = Day;//白天
specialSkill = SunshineShill;//照射
lifeForce = 10;//声明力10
plantInterval = 5;//生长速度
tempPlantInterval =5;//备份时间
needSunshine = 25;//需要的阳光数25
char title[] = "Lilypad";
this->createPlantByName(title);
break;
}
caseCorpseFlower:{//食人花
placeType = LandMammals;//陆地植物
timeType = Day;//白天
specialSkill = SunshineShill;//照射
lifeForce = 10;//声明力10
plantInterval = 5;//生长速度
tempPlantInterval =5;//备份时间
needSunshine = 150;//需要的阳光数150
char title[] = "Chomper";
this->createPlantByName(title);
break;
}
}
this->setScale(0.5f);
}
/*____________根据植物名称创建植物______________*/
voidPlants::createPlantByName(char name[]){
char temp[50];
//帧缓存
CCSpriteFrameCache *cacheFrame =CCSpriteFrameCache::sharedSpriteFrameCache();
//将缓存的对应plist文件追加到temp
sprintf(temp,"%s_default.plist",name);
//从帧文件中添加精灵
cacheFrame->addSpriteFramesWithFile(temp);
//取出plist文件中的字典
CCDictionary *dic =CCDictionary::createWithContentsOfFile(temp);
CCDictionary *dic2 = (CCDictionary *)dic->objectForKey("frames");
int num = dic2->allKeys()->count();//获取键为frames的字典数
sprintf(temp,"%s-2(被拖移).tiff",name);
this->initWithSpriteFrameName(temp);//创建精灵
CCArray *plistArray = CCArray::createWithCapacity(20);
for (int i =1; i < num; i++) {
sprintf(temp, "%s-%i(被拖移).tiff",name,i);//取出对应精灵图片
CCSpriteFrame *frame = cacheFrame->spriteFrameByName(temp);
plistArray->addObject(frame);//图片加入数组
}
if (strcmp(name,"Jalapeno")== 0 ||strcmp(name, "CherryBomb") ==0) {
this->runOnceAction(plistArray);
}
this->runRepeatAction(plistArray);
}
voidPlants::runOnceAction(CCArray *plistArray){
//创建静态动作
CCAnimation *plistAnimation = CCAnimation::createWithSpriteFrames(plistArray,0.15f);;
//创建动态动作
CCAnimate *plistAnimate = CCAnimate::create(plistAnimation);
//让动作持续--生产辣椒和樱桃
CCCallFunc *callFunc = CCCallFunc::create(this,callfunc_selector(Plants::paprikaCherryAction));
#warning mark------------
CCSequence *sequnece = CCSequence::create(plistAnimate,plistAnimate,callFunc,NULL);;
this->runAction(sequnece);
}
/*____________移除植物______________*/
voidPlants::removePlants(){
this->removeFromParent();
}
/*____________辣椒樱桃______________*/
voidPlants::paprikaCherryAction(){
if (this->plantsName ==Cherry) {//樱桃
this->initWithFile("Boom.gif");
CCCallFunc *func = CCCallFunc::create(this,callfunc_selector(Plants::removePlants));
CCSequence *seq = CCSequence::create(CCDelayTime::create(1),func,NULL);
this->runAction(seq);
}elseif(this->plantsName ==Paprika){//辣椒
//从缓存中读取图片放置到plistArray中
CCSpriteFrameCache *cache =CCSpriteFrameCache::sharedSpriteFrameCache();
cache->addSpriteFramesWithFile("JalapenoAttack_default.plist");
char temp[50];
CCArray *plistArray = CCArray::createWithCapacity(10);
for (int i =1; i<=8; i++) {
sprintf(temp,"JalapenoAttack-%i(被拖移).tiff",i);
CCSpriteFrame *fame = cache->spriteFrameByName(temp);
plistArray->addObject(fame);
}
//创建动作
CCAnimation *animation = CCAnimation::createWithSpriteFrames(plistArray,0.1f);
CCAnimate *animate = CCAnimate::create(animation);
CCSize size = GET_WINSIZE;
this->setPosition(ccp(size.width/2+220,this->getPosition().y));
CCCallFunc *func = CCCallFunc::create(this,callfunc_selector(Plants::removePlants));
CCSequence *seq = CCSequence::create(animate,func,NULL);
this->runAction(seq);
}
}
/*____________小坚果______________*/
voidPlants::smallNutActionEatOverByZombie(){
//先停止所有动作
this->stopAllActions();
//在从缓存中获取
CCSpriteFrameCache *cache =CCSpriteFrameCache::sharedSpriteFrameCache();
cache->addSpriteFramesWithFile("WallNut_cracked1_default.plist");
this->initWithSpriteFrameName("Wallnut_cracked1-11(被拖移).tiff");//第一张
char temp[50];
CCArray *plistArray = CCArray::createWithCapacity(10);
for (int i =1; i<12; i++) {
sprintf(temp,"Wallnut_cracked1-%i(被拖移).tiff",i);
CCSpriteFrame *frame = cache->spriteFrameByName(temp);
plistArray->addObject(frame);
}
CCAnimation *animation = CCAnimation::createWithSpriteFrames(plistArray);
CCAnimate *animate = CCAnimate::create(animation);
this->runAction(animate);
}
/*____________小坚果受损严重______________*/
voidPlants::smallNutActionEatOverMoreHarm(){
this->stopAllActions();
CCSpriteFrameCache *cache =CCSpriteFrameCache::sharedSpriteFrameCache();
cache->addSpriteFramesWithFile("WallNut_cracked2_default.plist");
char temp[50];
CCArray *plistArray = CCArray::createWithCapacity(10);
for (int i =1; i<16; i++) {
sprintf(temp,"Wallnut_cracked2-%i(被拖移).tiff",i);
CCSpriteFrame *frame = cache->spriteFrameByName(temp);
plistArray->addObject(frame);
}
CCAnimation *animation = CCAnimation::createWithSpriteFrames(plistArray);
CCAnimate *animate = CCAnimate::create(animation);
this->runAction(animate);
}
/*____________大坚果______________*/
voidPlants::largeNutActionEatOvetByZombie(){
this->stopAllActions();
char temp[50];
CCArray *plistArray = CCArray::createWithCapacity(10);
CCSpriteFrameCache *cache =CCSpriteFrameCache::sharedSpriteFrameCache();
cache->addSpriteFramesWithFile("TallNutCracked1_default.plist");
for (int i =1;i<14; i++) {
sprintf(temp,"TallnutCracked1-%i(被拖移).tiff",i);
CCSpriteFrame *frame = cache->spriteFrameByName(temp);
plistArray->addObject(frame);
}
CCAnimation *animation = CCAnimation::createWithSpriteFrames(plistArray);
CCAnimate *animate = CCAnimate::create(animation);
this->runAction(animate);
}
/*____________大坚果受损严重______________*/
voidPlants::largeNutActionEatOverMoreharm(){
this->stopAllActions();
char temp[50];
CCArray *plistArray = CCArray::createWithCapacity(10);
CCSpriteFrameCache *cache =CCSpriteFrameCache::sharedSpriteFrameCache();
cache->addSpriteFramesWithFile("TallnutCracked2_default.plist");
for (int i =1; i<13; i++) {
sprintf(temp,"TallnutCracked2-%i(被拖移).tiff",i);
CCSpriteFrame *frame = cache->spriteFrameByName(temp);
plistArray->addObject(frame);
}
CCAnimation *animation = CCAnimation::createWithSpriteFrames(plistArray);
CCAnimate *animate = CCAnimate::create(animation);
this->runAction(animate);
}
/*____________荷叶的三个动作______________*/
void Plants::corpseFlowerAction1(){
//能够袭击
canAttack =true;
this->stopAllActions();
CCSpriteFrameCache *cache = CCSpriteFrameCache::sharedSpriteFrameCache();
cache->addSpriteFramesWithFile("Chomper_default.plist");
char temp[50];
CCArray *plistArray = CCArray::createWithCapacity(10);
for(int i=1;i<=13;i++)
{
sprintf(temp,"Chomper-%i(被拖移).tiff",i);
CCSpriteFrame *frame = cache->spriteFrameByName(temp);
plistArray->addObject(frame);
}
CCAnimation *animation = CCAnimation::createWithSpriteFrames(plistArray,0.1);
CCAnimate *animate = CCAnimate::create(animation);
this->runAction(CCRepeatForever::create(animate));
}
void Plants::corpseFlowerAction2(){
//不能袭击
canAttack =false;
this->stopAllActions();
CCSpriteFrameCache *cache = CCSpriteFrameCache::sharedSpriteFrameCache();
cache->addSpriteFramesWithFile("ChomperAttack_default.plist");
char temp[50];
CCArray *plistArray = CCArray::createWithCapacity(10);
for(int i=1;i<=9;i++)
{
sprintf(temp, "ChomperAttack-%i(被拖移).tiff",i);
CCSpriteFrame *frame = cache->spriteFrameByName(temp);
plistArray->addObject(frame);
}
CCAnimation *animation = CCAnimation::createWithSpriteFrames(plistArray,0.1);
CCAnimate *animate = CCAnimate::create(animation);
CCCallFunc *func = CCCallFunc::create(this, callfunc_selector(Plants::corpseFlowerAction3));
CCSequence *seq = CCSequence::create(animate,func,NULL);
this->runAction(seq);
}
void Plants::corpseFlowerAction3(){
// this->stopAllActions();
CCSpriteFrameCache *cache = CCSpriteFrameCache::sharedSpriteFrameCache();
cache->addSpriteFramesWithFile("ChomperDigest_default.plist");
char temp[50];
CCArray *plistArray = CCArray::createWithCapacity(10);
for(int i=1;i<=6;i++)
{
sprintf(temp, "ChomperDigest-%i(被拖移).tiff",i);
CCSpriteFrame *frame = cache->spriteFrameByName(temp);
plistArray->addObject(frame);
}
CCAnimation *animation = CCAnimation::createWithSpriteFrames(plistArray,0.2);
CCAnimate *animate = CCAnimate::create(animation);
CCCallFunc *func = CCCallFunc::create(this, callfunc_selector(Plants::corpseFlowerAction1));
CCRepeat* forever = CCRepeat::create(animate,5);
CCSequence *seq = CCSequence::create(forever ,func,NULL);
this->runAction(seq);
}
/*____________重复动作______________*/
void Plants::runRepeatAction(CCArray *plistArray){
CCAnimation *plitAnimation=CCAnimation::createWithSpriteFrames(plistArray,0.15f);
CCAnimate *plitAnimate=CCAnimate::create(plitAnimation);
this->runAction(CCRepeatForever::create(plitAnimate));
}
/*____________南瓜______________*/
void Plants::pumpKinAction(CCSprite *pumpKin,CCPoint point){
CCPoint p1 = pumpKin->getPosition();
CCSpriteFrameCache *cache = CCSpriteFrameCache::sharedSpriteFrameCache();
cache->addSpriteFramesWithFile("SquashAttack_default.plist");
char temp[50];
CCArray *plistArray = CCArray::createWithCapacity(10);
for(int i=1;i<=4;i++)
{
sprintf(temp, "SquashAttack-%i(被拖移).tiff",i);
CCSpriteFrame *frame = cache->spriteFrameByName(temp);
plistArray->addObject(frame);
}
CCAnimation *animation = CCAnimation::createWithSpriteFrames(plistArray,0.3);
CCAnimate *animate = CCAnimate::create(animation);
pumpKin->runAction(animate);
CCJumpTo *jumpTo = CCJumpTo::create(0.5, point,50, 1);
CCCallFuncND *funcND = CCCallFuncND::create(NULL, callfuncND_selector(Plants::pumpKinMoveAction),pumpKin);
CCSequence *seq = CCSequence::create(jumpTo,CCDelayTime::create(1.0),funcND,NULL);
pumpKin->runAction(seq);
}
void Plants::pumpKinMoveAction(CCNode *sender,CCSprite *pumpKin){
pumpKin->removeFromParent();
}
/*____________析构______________*/
Plants::~Plants(){
this->addZombieAttackThisPlant->release();
}