分享一个《捕鱼》的客户端游戏

  今天一天用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工程的年年有余项目,大家也可以找我!

  

你可能感兴趣的:(客户端)