从图书馆借了本木头的书籍,以下实例来自书籍,写在这里仅作笔记。。
游戏内容大概如下:
1.一个Sprite在地图上一直在跑,Sprite可以跳跃(其实是地图不断向左滚动)
2.途中有金币,Sprite吃金币,左上方的Score会++,并且会有+15的字样出现
1.创建实体类Entity,这是一个基类,主要用来绑定一个精灵,返回一个精灵
#ifndef Entity_H#define Entity_H#include "cocos2d.h"using namespace cocos2d;class Entity:public CCNode{public: Entity(); ~Entity(); CCSprite* getSprite(); void bindSprite(CCSprite* sprite);private: CCSprite* m_sprite;};#endif
#include "Entity.h"Entity::Entity(){ m_sprite=NULL;}Entity::~Entity(){};CCSprite* Entity::getSprite(){ return this->m_sprite;}void Entity::bindSprite(CCSprite* sprite){ this->m_sprite=sprite; this->addChild(m_sprite);}
2.创建一个玩家主角类,可以jump,吃金币等
#ifndef _Player_H#define _Player_H#include "cocos2d.h"#include "Entity.h"using namespace cocos2d;#define JUMP_ACTION_TAG 1;class Player:public Entity{public: Player(); ~Player(); CREATE_FUNC(Player); virtual bool init();public: void jump(); void jumpEnd(); void hit();//主角和怪物撞击(玩家受伤害) int getMoney(); CCRect getBoundingBox();/*获取碰撞范围*/ void resetData(); void actionEnd();private: bool m_isJumping; int m_money;/*金钱*/};#endif
#include "Player.h"#include "FlowWord.h"Player::Player(){ m_isJumping=false; m_money=0;/*初始金钱为0*/}Player::~Player(){}bool Player::init(){ return true;}void Player::jump(){ if(!getSprite()) { return; } if(m_isJumping)/*如果主角还在跳跃中,则不重复跳跃*/ { return; } m_isJumping=true; /*创建动作,2s,原地跳跃(即落地的地点相对于起跳地点x偏移0,y偏移0),高度250,弹跳次数1*/ CCJumpBy* jump=CCJumpBy::create(1.5f,ccp(0,0),200,1); /*callFunc也是一个动作,作用是调用一个函数*/ CCCallFunc* callFunc = CCCallFunc::create(this, callfunc_selector(Player::jumpEnd)); /*组合动作*/ CCActionInterval* jumpActions=CCSequence::create(jump,callFunc,NULL); runAction(jumpActions);}void Player::jumpEnd(){ m_isJumping=false;}void Player::hit(){ if(getSprite()==NULL) { return; } /*加钱特效提示*/ FlowWord* flowword=FlowWord::create(); this->addChild(flowword); flowword->showWord("+15",getSprite()->getPosition()); m_money+=15; /*创建4种动作对象*/ CCMoveBy* backMove=CCMoveBy::create(0.1f,ccp(-20,0)); CCMoveBy* forwardMove=CCMoveBy::create(0.1f,ccp(20,0)); CCRotateBy* backRotate=CCRotateBy::create(0.1f,-5,0); CCRotateBy* forwardRotate=CCRotateBy::create(0.1f,5,0); /*分别组合成两种动作(同时执行)*/ CCSpawn* backActions=CCSpawn::create(backMove,backRotate,NULL); CCSpawn* forwardActions=CCSpawn::create(forwardMove,forwardRotate,NULL); CCCallFunc* callFunc=CCCallFunc::create(this,callfunc_selector(Player::actionEnd)); CCActionInterval* actions=CCSequence::create(backActions,forwardActions,callFunc,NULL); //this->stopAllActions(); //resetData(); this->runAction(actions);}void Player::resetData(){ if(m_isJumping) { m_isJumping=false; } this->setPosition(ccp(200,500/4)); this->setScale(1.0f); setRotation(0);}int Player::getMoney(){ return m_money;}CCRect Player::getBoundingBox(){ if(getSprite()==NULL){ return CCRectMake(0,0,0,0); } /*由于Sprite是放在Player上的,所以要检测Player的碰撞范围*/ CCSize spriteSize=getSprite()->getContentSize(); CCPoint entityPos=this->getPosition();//获取player中心点 //获取Player左下角的坐标值 int x=entityPos.x-spriteSize.width/2; int y=entityPos.y-spriteSize.height/2; return CCRectMake(x,y,spriteSize.width,spriteSize.height);}void Player::actionEnd(){ this->setScale(1.0f); setRotation(0);}3.创建怪物类(金币),继承于实体类 --
#ifndef _Monster_H_#define _Monster_H_#include "Entity.h"#include "cocos2d.h"#include "Player.h"#include "ccMacros.h"USING_NS_CC;class Monster:public Entity{public: Monster(); ~Monster(); CREATE_FUNC(Monster); virtual bool init(); public: void show(); void hide(); void reset();//重置怪物数据 bool isAlive();//是否活动状态 bool isCollideWithPlayer(Player* player);//检测是否碰撞private: bool m_isAlive;};#endif
#include "Monster.h"Monster::Monster(){}Monster::~Monster(){}bool Monster::init(){ return true;}void Monster::show(){ if(getSprite()!=NULL) { this->setVisible(true); m_isAlive=true;/*标记为活动状态*/ }}void Monster::hide(){ if(getSprite()!=NULL) { this->setVisible(false); reset(); m_isAlive=false;/*标记为活动状态*/ }}void Monster::reset(){ if(getSprite()!=NULL) { /*初始化怪物坐标,宽度(800-2800),高度(100-200)*/ this->setPosition(ccp(800+CCRANDOM_0_1()*2000,200-CCRANDOM_0_1()*100)); }}bool Monster::isAlive(){ return m_isAlive;}bool Monster::isCollideWithPlayer(Player* player){ CCRect playerRect=player->getBoundingBox(); CCPoint monsterPos=getPosition(); /*判断是否有交集*/ return playerRect.containsPoint(monsterPos);}
4.创建怪物管理器类(MonsterManger),用来管理怪物的显示和隐藏
#ifndef __MonsterManger_H__#define __MonsterManger_H__#include "cocos2d.h"#include "Player.h"USING_NS_CC;#define MAX_MONSTER_NUM 10class MonsterManger:public CCNode{public: MonsterManger(); ~MonsterManger(); CREATE_FUNC(MonsterManger); virtual bool init(); virtual void update(float dt);/*重写update函数*/ void bindPlayer(Player* player);private: void createMonsters();/*创建Monster对象*/private: CCArray* m_monsterArr;/*存放怪物数组*/ Player* m_player;};#endif
#include "MonsterManger.h"#include "Monster.h"MonsterManger::MonsterManger(){}MonsterManger::~MonsterManger(){}bool MonsterManger::init(){ bool bRet=false; do { createMonsters();/*创建怪物*/ this->scheduleUpdate();/*启用update*/ bRet=true; } while (0); return bRet; }void MonsterManger::createMonsters(){ m_monsterArr=CCArray::create(); m_monsterArr->retain();/*防止数组被释放*/ Monster* monster=NULL; CCSprite* sprite=NULL; for(int i=0;ibindSprite(CCSprite::create("monster.png")); monster->reset(); this->addChild(monster); /*将怪物添加到管理器(CCNode)中*/ m_monsterArr->addObject(monster);/*添加到数组中,便于管理*/ }}void MonsterManger::update(float dt){ CCObject* obj=NULL; Monster* monster=NULL; CCARRAY_FOREACH(m_monsterArr,obj)/*循环遍历怪物数组,重复出现在屏幕上*/ { monster=(Monster*) obj; if(monster->isAlive())/*活动状态*/ { monster->setPositionX(monster->getPositionX()-3);//左移 if(monster->getPositionX()<0) { monster->hide(); }else if(monster->isCollideWithPlayer(m_player)){ m_player->hit(); monster->hide(); } }else/*非活动状态*/ { monster->show();// } }}void MonsterManger::bindPlayer(Player* player){ this->m_player=player; this->m_player->retain();//引用计数 +1}
5.创建文字飘动效果,(在主角身上显示"+15"特效)
#ifndef __FlowWord_H__#define __FlowWord_H__#include "cocos2d.h"USING_NS_CC;class FlowWord:public CCNode{public: FlowWord(); ~FlowWord(); CREATE_FUNC(FlowWord); virtual bool init();public: void showWord(const char* text, CCPoint pos); void flowEnd();private: CCLabelTTF* m_textLab;};#endif
#include "FlowWord.h"FlowWord::FlowWord(){}FlowWord::~FlowWord(){}bool FlowWord::init(){ m_textLab=CCLabelTTF::create("","Arial",30); m_textLab->setColor(ccc3(255,0,0)); m_textLab->setVisible(false); this->addChild(m_textLab); return true;}void FlowWord::showWord(const char* str,CCPoint pos){ m_textLab->setString(str); m_textLab->setPosition(pos); m_textLab->setAnchorPoint(ccp(1,0)); m_textLab->setVisible(true); //先放大后缩小 CCActionInterval* scaleLarge=CCScaleTo::create(0.3f,2.5f,2.5f); CCActionInterval* scaleSmall=CCScaleTo::create(0.4f,0.5f,0.5f); //回调动作,移除效果 CCCallFunc* callFunc=CCCallFunc::create(this,callfunc_selector(FlowWord::flowEnd)); CCActionInterval* actions=CCSequence::create(scaleLarge,scaleSmall,callFunc,NULL); m_textLab->runAction(actions);}void FlowWord::flowEnd(){ m_textLab->setVisible(false); /*true: 从父节点移除,并移除节点的动作和回调函数*/ m_textLab->removeFromParentAndCleanup(true);}6.创建游戏场景类,所有游戏的效果都在这上面展示
#ifndef __TollgateScene_H__#define __TollgateScene_H__#include "cocos2d.h"#include "cocos-ext.h"#include "Player.h"using namespace cocos2d;using namespace cocos2d::extension;class TollgateScene : public CCLayer {public: static CCScene* scene(); virtual bool init(); CREATE_FUNC(TollgateScene); virtual void update(float delta);private: void initBG(); /* 初始化关卡背景 */ void createJumpBtn();/*创建跳跃按钮*/ void jumpEvent(CCObject* pSender,CCControlEvent event);/*响应按钮点击事件*/ void createScoreLab();/*创建分数标签*/ void createTimeSlider();/*创建时间条*/private: CCSprite* m_bgSprite1; CCSprite* m_bgSprite2; Player* m_player; CCLabelTTF* m_scoreLab;//分数标签 CCControlSlider* m_TimeSlider;//时间条 int m_score; /*得分*/ int m_curTime; /*当前时间*/};#endif
#include "TollgateScene.h"#include "MonsterManger.h"CCScene* TollgateScene::scene() { CCScene* scene = NULL; do { scene = CCScene::create(); CC_BREAK_IF(!scene); TollgateScene* layer = TollgateScene::create(); CC_BREAK_IF(!layer); scene->addChild(layer, 1); } while (0); return scene;}bool TollgateScene::init() { bool bRet = false; do { CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); /*游戏标题图片*/// CCSprite* titleSprite = CCSprite::create("title.png");// titleSprite->setPosition(ccp(visibleSize.width / 2, visibleSize.height - 50));// this->addChild(titleSprite, 2); /*创建猪脚*/ CCSprite* sprite = CCSprite::create("sprite.png"); //sprite->setFlipX(true); m_player = Player::create(); m_player->bindSprite(sprite); m_player->setPosition(ccp(200, visibleSize.height / 4)); this->addChild(m_player,1); /*初始化背景图片*/ initBG(); /*创建按钮*/ createJumpBtn(); /*设置启用CCNode的update()函数,游戏会在每一帧调用update()函数*/ this->scheduleUpdate(); /*创建怪物管理器(管理器里面放了很多怪物)*/ MonsterManger* monsterManger=MonsterManger::create(); monsterManger->bindPlayer(m_player); this->addChild(monsterManger,4); /*创建分数标签*/ createScoreLab(); /*创建时间条*/ createTimeSlider(); bRet = true; } while (0); return bRet;}void TollgateScene::initBG() { CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); m_bgSprite1 = CCSprite::create("tollgateBG.jpg"); m_bgSprite1->setPosition(ccp(visibleSize.width / 2, visibleSize.height / 2)); this->addChild(m_bgSprite1, 0); m_bgSprite2 = CCSprite::create("tollgateBG.jpg"); m_bgSprite2->setPosition(ccp(visibleSize.width + visibleSize.width / 2, visibleSize.height / 2)); m_bgSprite2->setFlipX(true); this->addChild(m_bgSprite2, 0);}void TollgateScene::update(float delta){ CCSize mapSize=m_bgSprite1->getContentSize();//地图大小 int posX1=m_bgSprite1->getPositionX(); //地图1的x坐标 int posX2=m_bgSprite2->getPositionX(); //地图2的x坐标 int iSpeed = 2; //地图滚动的速度 posX1-=iSpeed; //两张地图一起向左滚动 posX2-=iSpeed; //创建无限循环 if(posX1<=-mapSize.width/2) { posX1=mapSize.width+mapSize.width/2; posX2=mapSize.width/2; } if(posX2<=-mapSize.width/2) { posX1=mapSize.width/2; posX2=mapSize.width+mapSize.width/2; } m_bgSprite1->setPositionX(posX1); m_bgSprite2->setPositionX(posX2); /*分数增加*/ m_score=m_player->getMoney(); m_scoreLab->setString(CCString::createWithFormat("Score:%d",m_score)->getCString()); m_TimeSlider->setValue(--m_curTime); }void TollgateScene::createJumpBtn(){ CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize(); /*按钮标题*/ CCLabelTTF* jumpLabel=CCLabelTTF::create("Jump","Arial",35); /*按钮状态图片*/ CCScale9Sprite* jumpNorBG=CCScale9Sprite::create("button.png"); CCScale9Sprite* jumpLightBG=CCScale9Sprite::create("buttonHighlighted.png"); /*创建按钮*/ CCControlButton* jumpBtn=CCControlButton::create(jumpLabel,jumpNorBG); jumpBtn->setPosition(ccp(visibleSize.width-80,50)); jumpBtn->setBackgroundSpriteForState(jumpLightBG,CCControlStateHighlighted); /*添加事件*/ jumpBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(TollgateScene::jumpEvent), CCControlEventTouchDown); this->addChild(jumpBtn);}void TollgateScene::jumpEvent(CCObject* pSender,CCControlEvent event){ m_player->jump();}void TollgateScene::createScoreLab(){ m_score=m_player->getMoney(); CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize(); m_scoreLab=CCLabelTTF::create("Score:"+m_score,"Arial",35); m_scoreLab->setAnchorPoint(ccp(0,1)); m_scoreLab->setPosition(ccp(0,visibleSize.height)); this->addChild(m_scoreLab);}void TollgateScene::createTimeSlider(){ CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize(); m_curTime=10000; m_TimeSlider=CCControlSlider::create( CCSprite::create("background.png"), CCSprite::create("progress.png"), CCSprite::create("sliderThumb.png") ); m_TimeSlider->setPosition(ccp( m_TimeSlider->getContentSize().width/2, visibleSize.height-m_TimeSlider->getContentSize().height-m_scoreLab->getContentSize().height )); m_TimeSlider->setTouchEnabled(false); m_TimeSlider->setMaximumValue(10000); m_TimeSlider->setMinimumValue(0); m_TimeSlider->setValue(m_curTime); this->addChild(m_TimeSlider,3);}
运行效果如下
源码