分享一個《捕魚》的用戶端遊戲,《捕魚》用戶端
今天一天用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 FISHNETSIZECCSize(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_2424using 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工程的年年有餘項目,大家也可以找我!