今天一天用cocos2d做了一个捕鱼系统的demo,资源取自广为流传的android小游戏叫做年年有余,哎,无论叫做什么吧!之前是用android写的,今天一天用cocos2d从新写了一遍!大家可以用来做为学习cocos2d的demo,或者开发自己捕鱼系统的demo!
先来几张效果图片:
玩法很简单,用手按住鱼,鱼就被抓紧了网内,然后再网破掉之前,将鱼放到鱼缸!就这样!
下面对代码进行解析:
首先定义Fish类:
//Fish 头文件 #pragma once #include "cocos2d.h" #include "cocos-ext.h" #include <vector> using namespace std; using namespace cocos2d; using namespace cocos2d::extension; class Fish : public CCSprite { public: Fish(void); ~Fish(void); bool init(); CCPoint getPoint(); void wander(); int get_score(); void setCoord(int x,int y); private: int image_index ; double coord_x; double coord_y; CCSprite* _image; vector<CCTexture2D*> _textture_vec; int fish_num; }; //Fish 实现代码: #include "Fish.h" #include "GameStruct.h" Fish::Fish(void) { this->fish_num = rand()%3; this->_image = NULL; this->coord_x = rand()%200; this->coord_y = rand()%200; this->image_index = 0; } Fish::~Fish(void) { } bool Fish::init() { CCSprite::init(); this->_image = CCSprite::create(fish_image[this->fish_num][0].c_str()); this->setContentSize(CCSize(60,16)); this->_image->setPosition(CCPoint(30,8)); this->addChild(this->_image); for(int i = 0;i<3;i++) { CCSprite * temp_obj = CCSprite::create(fish_image[this->fish_num][i].c_str()); CCTexture2D *hero_hit = temp_obj->getTexture(); this->_textture_vec.push_back(hero_hit); } return true; } void Fish::setCoord(int x,int y) { this->coord_x = x; this->coord_y = y; } int Fish::get_score() { return this->image_index*2 + 1; } void Fish::wander() { this->image_index ++; if(this->image_index >= 3) { this->image_index = 0; } this->_image->setTexture(this->_textture_vec.at(this->image_index)); float degrees = rand()/rand(); this->setRotation(degrees); int len = 6; double len_x = len*sin(degrees); double len_y = len*cos(degrees); this->coord_x += len_y; this->coord_y += len_x; } CCPoint Fish::getPoint() { return CCPoint(coord_x,coord_y); }
Fish,就是鱼,继承自CCSprite,最终要的一个函数就是wander();用来实现鱼在鱼池中游荡!首先先随机出一个角度来,然后再对Fish进行旋转(rotate),然后再向着头部的防线行走!更新x,y坐标!再移动的同时,要不断变换鱼的图片,因为尾巴要不断的摆动吗!
然后就是FishNet类,故名思议,渔网类
//头文件 #pragma once #include "cocos2d.h" #include "cocos-ext.h" #include "Fish.h" #include <vector> using namespace std; using namespace cocos2d; using namespace cocos2d::extension; class HelloWorld; #define FISHNETSIZE CCSize(90,90) class FishNet : public CCSprite { public: FishNet(HelloWorld* scene); ~FishNet(void); bool init(); void add_fish(Fish* fish); void reset(); void update(float tick); void enable(); void disable(); bool is_enable(); void scatter(); void recycle(); private: int _image_index; CCSprite* _image; vector<CCTexture2D*> _textture_vector; vector<Fish*> fish_vect; bool _enable; HelloWorld* _scene; }; //实现代码 #include "FishNet.h" #include "HelloWorldScene.h" #include "GameStruct.h" FishNet::FishNet(HelloWorld* scene) { this->_image = NULL; this->_image_index = 0; this->_enable = false; this->_scene = scene; } FishNet::~FishNet(void) { } void FishNet::reset() { this->_image_index = 0; } bool FishNet::init() { CCSprite::init(); this->setContentSize(FISHNETSIZE); this->_image = CCSprite::create("fish_net0.png"); this->_image->setPosition(CCSize(FISHNETSIZE.width/2,FISHNETSIZE.height/2)); this->addChild(this->_image); for(int i=0;i<7;i++) { CCSprite* image = CCSprite::create(fish_net_image[i].c_str()); CCTexture2D *textture = image->getTexture(); this->_textture_vector.push_back(textture); } return true; } void FishNet::add_fish(Fish* fish) { fish->setPosition(CCSize(FISHNETSIZE.width/2,FISHNETSIZE.height/2)); this->fish_vect.push_back(fish); this->addChild(fish); } void FishNet::scatter() { for(vector<Fish*>::iterator iter = this->fish_vect.begin();iter != this->fish_vect.end();iter++) { this->removeChild(*iter,true); //(*iter)->setPosition(this->getPosition()); (*iter)->setCoord(this->getPositionX(),this->getPositionY()); this->_scene->generate_fish(*iter); } this->fish_vect.clear(); } void FishNet::recycle() { if(this->is_enable()) { for(vector<Fish*>::iterator iter = this->fish_vect.begin();iter != this->fish_vect.end();iter++) { this->removeChild(*iter,true); this->_scene->add_score((*iter)->get_score()); } this->fish_vect.clear(); } } void FishNet::update(float tick) { this->_image_index ++; if(this->_image_index == 7) { this->_image_index = 0; this->disable(); return ; } this->_image->setTexture(this->_textture_vector.at(this->_image_index)); } void FishNet::enable() { this->_enable = true; } void FishNet::disable() { this->_enable = false; this->scatter(); this->_scene->recycle_fish_net(); } bool FishNet::is_enable() { return this->_enable; }
FIshNet同样继承子CCSprite,几个注意的点:update函数,不断更新渔网的状态!scatter函数,当渔网破裂时,要将渔网里面的鱼全部释放掉!recycle,当渔网达到鱼缸时,并且渔网还没有破裂,那么玩家要得分!
下面是最核心的HelloWorld类,其实更加应该称为池塘类,但是以为是在HelloWorld那个工程上修改了,所以就没有调整!HelloWorld继承子CCLayer!
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "cocos-ext.h" #include "Fish.h" #include "FishNet.h" #include <vector> #define FONT_NAME_DEFAULT "msyh" #define FONT_SIZE_24 24 using namespace std; using namespace cocos2d; class HelloWorld : public cocos2d::CCLayerColor,public CCTouchDelegate { public: virtual bool init(); static cocos2d::CCScene* scene(); void menuCloseCallback(CCObject* pSender); void reset(); void add_score(int inc); void update(float tick); CREATE_FUNC(HelloWorld); void random_generate_fish(); void generate_fish(Fish* fish); void recycle_fish(Fish* fish); void recycle_fish_net(); virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent); //处理用户按下事件 virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent); //处理Touch Move 事件 virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent); //处理用户放开事件 virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent); //处理Touch被打断事件,如来电话了。 private: int score; vector<Fish*> fish_vec; FishNet* fish_net; CCLabelTTF* score_hint; CCLabelTTF* score_label; }; #endif // __HELLOWORLD_SCENE_H__ #include "HelloWorldScene.h" #include <math.h> USING_NS_CC; CCScene* HelloWorld::scene() { // 'scene' is an autorelease object CCScene *scene = CCScene::create(); // 'layer' is an autorelease object HelloWorld *layer = HelloWorld::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } bool HelloWorld::init() { if(! CCLayerColor:: initWithColor(ccc4(255, 255, 255,255))) { return false; } CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin(); CCScale9Sprite* board = CCScale9Sprite::create("board.png"); board->setPosition(CCSize(visibleSize.width/2,20)); this->addChild(board); this->score_hint = CCLabelTTF::create("score : ","Arial",20.0); this->score_hint->setPosition(CCSize(visibleSize.width - 100,20)); this->addChild(this->score_hint); this->score_label = CCLabelTTF::create("0","Arial",20.0); this->score_label->setPosition(CCSize(this->score_hint->getPositionX() + 70,20)); this->addChild(this->score_label); CCScale9Sprite* tank = CCScale9Sprite::create("fish_tank.png"); tank->setPosition(CCSize(30,30)); this->addChild(tank); for(int i=0;i<10;i++) { Fish* fish = new Fish(); fish->init(); fish->setPosition(fish->getPoint()); this->addChild(fish); this->fish_vec.push_back(fish); } this->setTouchEnabled(true); CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true); this->fish_net = new FishNet(this); this->fish_net->init(); this->schedule(schedule_selector(HelloWorld::update),0.2); this->score = 0; return true; } void HelloWorld::reset() { this->score = 0; } void HelloWorld::add_score(int inc) { this->score += inc; CCString* str = CCString::createWithFormat("%d",this->score); this->score_label->setString(str->getCString()); } void HelloWorld::update(float tick) { CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); int generate_cnt = 0; for(vector<Fish*>::iterator iter = this->fish_vec.begin();iter != this->fish_vec.end();iter++) { Fish* fish = *iter; fish->wander(); fish->setPosition(fish->getPoint()); if(fish->getPositionX() > visibleSize.width || fish->getPositionY() > visibleSize.height) { iter = this->fish_vec.erase(iter); this->removeChild(fish,true); generate_cnt++; } } for(int i=0;i<generate_cnt;i++) { random_generate_fish(); } if(this->fish_net->is_enable()) { this->fish_net->update(tick); } } void HelloWorld::random_generate_fish() { Fish* fish = new Fish(); fish->init(); fish->setPosition(fish->getPoint()); this->addChild(fish); this->fish_vec.push_back(fish); } void HelloWorld::generate_fish(Fish* fish) { this->fish_vec.push_back(fish); this->addChild(fish); } void HelloWorld::recycle_fish(Fish* fish) { this->removeChild(fish,true); } void HelloWorld::recycle_fish_net() { this->removeChild(this->fish_net,true); } void HelloWorld::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent) { CCSetIterator it = pTouches->begin(); CCTouch* touch = (CCTouch*)(*it); CCPoint point = convertTouchToNodeSpace(touch); this->fish_net->reset(); this->fish_net->enable(); this->fish_net->setPosition(point); this->addChild(this->fish_net); for(vector<Fish*>::iterator iter = this->fish_vec.begin();iter != this->fish_vec.end();) { Fish* fish = *iter; if(abs(fish->getPositionX() - point.x) <= 15 && abs(fish->getPositionY() - point.y) <= 15) { iter = this->fish_vec.erase(iter); this->removeChild(fish,true); this->fish_net->add_fish(fish); continue; } iter++; } } void HelloWorld::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent) { CCSetIterator it = pTouches->begin(); CCTouch* touch = (CCTouch*)(*it); CCPoint point = convertTouchToNodeSpace(touch); this->fish_net->setPosition(point); if(this->fish_net->is_enable()) { if(this->fish_net->getPositionX() < 90 && this->fish_net->getPositionY() < 90) { this->fish_net->recycle(); this->fish_net->disable(); } } } void HelloWorld::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent) { this->fish_net->disable(); } void HelloWorld::ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent) { } void HelloWorld::menuCloseCallback(CCObject* pSender) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert"); #else CCDirector::sharedDirector()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif #endif }
代码中几个函数体现的很明显了!1:random_generate_fish:不断的随机产生新的鱼;update : 心跳函数,每秒执行5次,不断验证是否有鱼出界,如果出界就回收掉!不断判断渔网是否到达鱼缸,如果到达就回收掉渔网里面的鱼儿,并且给玩家加分! 不断验证渔网是否破坏掉,如果已经损坏,就将渔网里面的鱼放到池塘里面去!
感兴趣的,可以问我要整个工程,原android版的也有!另外太久不写C++了,命名和stl有点生疏了!
希望对大家有帮助,原android工程的年年有余项目,大家也可以找我!