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

简介:

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


相关文章
|
12月前
|
安全 程序员
学做游戏最重要的是学什么
解决问题的能力是一个人的最核心的技能,也是判断一个人游戏开发水平高低的决定性因素。你在做任何事情,尤其是刚接触一个新领域时,一定会遇到各种各样的问题,而其中大部分的问题你都从来没有遇到过。这个时候咋办呢? 最好最快的方式莫过于有一个有经验的老师可以带一带你,他可以指导一些方法和经验,回答你的一些疑问,告诉你哪里可能有“坑”......(小蚂蚁目前做的就是这些事情)。
76 0
|
12月前
|
Java
手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏18玩家攻击动画实现
手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏18玩家攻击动画实现
130 0
|
12月前
|
Java
手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏19敌人可以被打死
手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏19敌人可以被打死
104 0
|
12月前
|
人工智能 算法 固态存储
这才是模块化电脑该有的样子:一人打造的超迷你计算机,震动了整个极客圈
这才是模块化电脑该有的样子:一人打造的超迷你计算机,震动了整个极客圈
109 0
|
人工智能 算法 5G
手机秒变投篮机,还能模拟投篮真实手感,腾讯微视技术「家底」到底有多厚?
小小的 AR 投篮机背后包含着哪些技术?我们和腾讯微视技术团队聊了聊。
147 0
手机秒变投篮机,还能模拟投篮真实手感,腾讯微视技术「家底」到底有多厚?
|
机器学习/深度学习 存储 算法
全家要用机器人上货了?!50公里外VR操控,延迟不到一秒,网友:不愧是你,霓虹
全家要用机器人上货了?!50公里外VR操控,延迟不到一秒,网友:不愧是你,霓虹
132 0
漫画通信:惊呆了,手机登录还可以这么玩!
注册登录一直是使用APP的门槛和必经之路,面对用户在登录APP、注册、观看H5等环节都需要反复登录的痛点,你的APP该怎么提升用户体验呢?这里有青铜、白银、黄金、铂金几种段位供您选择。
772 0
漫画通信:惊呆了,手机登录还可以这么玩!
漫画通信:有了它,终于可以放心买买买了
神算李开始试水自营电商,但是频繁接到用户投诉,说个人信息遭受泄露!神算李十分疑惑:客户信息究竟在哪个环节泄露的?怎么能保障客户信息安全呢?且看阿里云通信隐私面单锦囊妙计如何为他答疑解惑。
976 0
漫画通信:有了它,终于可以放心买买买了
|
数据采集 小程序 API
手把手教你成为小程序流量头号玩家!
小程序开发中应该注意哪些搜索引擎优化手段
1181 0
火星漫游车着陆点最终确定,将于2021年于奥克夏平原开启探索之旅
奥克夏平原,是一个在过去很有可能拥有大片水域的区域,或许可以帮助科学家找到火星生命的蛛丝马迹。
373 0

热门文章

最新文章