Cocos2d-x 3.0final 终结者系列教程13-贪食蛇游戏案例(全)

2023-11-08 04:32

本文主要是介绍Cocos2d-x 3.0final 终结者系列教程13-贪食蛇游戏案例(全),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

快过节了,谢谢了屈原,我们爱你。

应该多几个向屈大人一样跳江的,这样我们就可以放假纪念啦。

---------------------------------快过节了,弄个案例,大家不妨假期做做,

运行效果展示:



全部代码和资源:

http://download.csdn.net/detail/sdhjob/7424329

1.准备资源

背景图片menuback.png:


节点图片

greenstar.png   

redstar.png      

yellowstar.png 

2.创建一个新项目(如何配置环境和创建新项目,参考前面教程):

cocos new -p com.xdl.game -l cpp -d ~/Desktop/test0515 snamegame

3.添加文件

首先将HelloWoldScene.h HelloWorld.cpp移走,然后添加GameScene.h GameScene.cpp HelpScene.h HelpScene.cpp MainMenu.h MainMenu.cpp

加上原来自动生成的AppDelegate.h 和AppDelegate.cpp共8个文件

4.编码

AppDelegate.h (这个文件基本没改动)

#ifndef  _APP_DELEGATE_H_

#define  _APP_DELEGATE_H_

#include "cocos2d.h"

class  AppDelegate : private cocos2d::Application

{

public:

    AppDelegate();

    virtual ~AppDelegate();

    virtual bool applicationDidFinishLaunching();

    virtual void applicationDidEnterBackground();

    virtual void applicationWillEnterForeground();

};

#endif // _APP_DELEGATE_H_

AppDelegate.cpp 

#include "AppDelegate.h"

#include "MainMenu.h"

#include "SimpleAudioEngine.h"    

USING_NS_CC;

using namespace CocosDenshion;

AppDelegate::AppDelegate() {

}

AppDelegate::~AppDelegate() 

{

}

bool AppDelegate::applicationDidFinishLaunching() {

    // initialize director

    auto director = Director::getInstance();

    auto glview = director->getOpenGLView();

    if(!glview) {

        glview = GLView::create("My Game");

        director->setOpenGLView(glview);

    }

    // turn on display FPS

    director->setDisplayStats(false);

    // set FPS. the default value is 1.0/60 if you don't call this

    director->setAnimationInterval(1.0 / 60);

    // create a scene. it's an autorelease object

    auto scene = MainMenu::createScene();

    // run

    director->runWithScene(scene);

    //开始播放背景音乐

    SimpleAudioEngine::getInstance()->playBackgroundMusic("background.mp3");

    return true;

}


// This function will be called when the app is inactive. When comes a phone call,it's be invoked too

void AppDelegate::applicationDidEnterBackground() {

    Director::getInstance()->stopAnimation();

    // if you use SimpleAudioEngine, it must be pause

    SimpleAudioEngine::getInstance()->pauseBackgroundMusic();

}


// this function will be called when the app is active again

void AppDelegate::applicationWillEnterForeground() {

    Director::getInstance()->startAnimation();

    // if you use SimpleAudioEngine, it must resume here

    SimpleAudioEngine::getInstance()->resumeBackgroundMusic();

}

说明: 在入口类中加入了背景音乐的播放,并且入口场景设计为MainMenu,往下看

MainMenu.h

#ifndef __snakegame__MainMenu__

#define __snakegame__MainMenu__

#include "cocos2d.h"

USING_NS_CC;

class MainMenu:public Layer{

public:

    static Scene * createScene();

    CREATE_FUNC(MainMenu);

    virtual bool init();

    void menuCallBack(Ref * object);

};

#endif


MainMenu.cpp

#include "MainMenu.h"

#include "GameScene.h"

#include "HelpScene.h"

Scene * MainMenu::createScene()

{   auto scene=Scene::create();

    auto layer=MainMenu::create();

    scene->addChild(layer);

    return scene;

}

 bool MainMenu::init(){

     if(!Layer::init())

    {

    return false;

    }

     auto size=Director::getInstance()->getWinSize();

     //添加背景

     auto spriteBK=Sprite::create("menuback.png");

     spriteBK->setPosition(Point(size.width/2,size.height/2));

     this->addChild(spriteBK);

     //添加2个菜单条目

     auto menuItemStart=MenuItemFont::create("Start", CC_CALLBACK_1(MainMenu::menuCallBack,this));

     menuItemStart->setTag(1);

     auto menuItemHelp=MenuItemFont::create("Help", CC_CALLBACK_1(MainMenu::menuCallBack,this));

     menuItemHelp->setTag(2);

     auto menu=Menu::create(menuItemStart,menuItemHelp,NULL);

     menu->setPosition(Point::ZERO);

     menuItemStart->setPosition(Point(size.width-menuItemStart->getContentSize().width-100,menuItemStart->getContentSize().height+10));

     menuItemHelp->setPosition(Point(size.width-menuItemHelp->getContentSize().width-10,menuItemHelp->getContentSize().height+10));

     this->addChild(menu);

     return true;

}

void MainMenu::menuCallBack(Ref * object){

    auto target=(Node *)object;

    Scene * scene;

    switch (target->getTag()) {

        case 1://startgame

            scene=Game::createScene();

            break;

        case 2://Helpgame

            scene=Help::createScene();

            break;

        default:

            break;

    }

    Director::getInstance()->replaceScene(scene);

  }

说明:在菜单场景中实现了跳转到帮助场景和游戏场景,往下看:

HelpScene.h

#ifndef __snakegame__HelpScene__

#define __snakegame__HelpScene__

#include "cocos2d.h"

USING_NS_CC;

class Help:public Layer{

public:

    static Scene * createScene();

    CREATE_FUNC(Help);

    virtual bool init();

    void menuCallBack(Ref * object);

};

#endif

HelpScene.cpp

#include "HelpScene.h"

#include "MainMenu.h"

Scene * Help::createScene(){

    auto scene=Scene::create();

    auto layer=Help::create();

    scene->addChild(layer);

    return scene;

   }

bool  Help::init(){

    if(!Layer::init())

        {

        return  false;

        }

      auto size=Director::getInstance()->getWinSize();

    //添加背景

    auto spriteBK=Sprite::create("menuback.png");

    spriteBK->setPosition(Point(size.width/2,size.height/2));

    spriteBK->setOpacity(75);

    this->addChild(spriteBK);

    //帮助信息

    auto labelScore=Label::create("帮助信息", "宋体", 25);

    labelScore->setPosition(Point(size.width-80,size.height-50));

    this->addChild(labelScore);

    //返回按钮

    auto menuItemBack=MenuItemFont::create("Back", CC_CALLBACK_1(Help::menuCallBack,this));

    auto menu=Menu::create(menuItemBack,NULL);

    menu->setPosition(Point::ZERO);

    menuItemBack->setPosition(Point(size.width-menuItemBack->getContentSize().width-100,menuItemBack->getContentSize().height+10));

    this->addChild(menu);

    return true;

}

void  Help::menuCallBack(Ref * object){

    auto scene=MainMenu::createScene();

    Director::getInstance()->replaceScene(scene);

}

说明:这里只是实现了一个帮助信息显示,可以返回到菜单,下面看游戏场景

GameScene.h

#ifndef __snakegame__GameScene__

#define __snakegame__GameScene__

#include "cocos2d.h"

USING_NS_CC;

enum class ENUM_DIR{

    DIR_UP,

    DIR_DOWN,

    DIR_LEFT,

    DIR_RIGHT,

    DIR_STOP

};

class SnakeNode:public Sprite

{

    public :

    enum ENUM_DIR m_dir;//移动方向

    int nodeType;       //节点类型1蛇头 2 身体 3 食物

    int m_row,m_col;    //当前节点的行列坐标

   

    static SnakeNode* create(int type);

    virtual bool init(int type);

    void setPositionRC(int row,int col);//设置节点的坐标

};

class Game:public Layer{

public:

    SnakeNode * spFood;//食物

    SnakeNode * spHead;//蛇头

     int m_score;

    Vector<SnakeNode *> allBody;//身体

    static Scene * createScene();

    CREATE_FUNC(Game);

    virtual bool init();

    void menuCallBack(Ref * object);

    void gameLogic(float t);

    void newBody();//添加一个新的身体节点

    void moveBody();//移动所有的身体节点

};

#endif

GameScene.cpp

//

//  GameScene.cpp

//  Created by shen on 14-5-27.

//


#include "GameScene.h"

#include "MainMenu.h"

#include "SimpleAudioEngine.h"

using namespace CocosDenshion;

Scene * Game::createScene(){

    auto scene=Scene::create();

    auto layer=Game::create();

    scene->addChild(layer);

    return scene;


}

SnakeNode* SnakeNode::create(int type)

{

    SnakeNode *pRet = new SnakeNode();

    if (pRet && pRet->init(type))

        {

            pRet->autorelease();

            return pRet;

        }

    else

        {

            delete pRet;

            pRet = NULL;

            return NULL;

        }

}


bool SnakeNode::init(int type){

    if(!Sprite::init())

    {

     return false;

    }

    ///根据类型不同初始化不同的纹理

    switch (type) {

        case 1://蛇头

        {auto sprite=Sprite::create("redstar.png");

            sprite->setAnchorPoint(Point::ZERO);

            this->addChild(sprite);

            m_dir=ENUM_DIR::DIR_RIGHT;//向右移动

        }

            break;

        case 2://身体

        {auto sprite=Sprite::create("greenstar.png");

            sprite->setAnchorPoint(Point::ZERO);

            this->addChild(sprite);

           

        }

            m_dir=ENUM_DIR::DIR_STOP;//

            break;

        case 3://食物

        {auto sprite=Sprite::create("yellowstar.png");

            sprite->setAnchorPoint(Point::ZERO);

            this->addChild(sprite);

        }

             m_dir=ENUM_DIR::DIR_STOP;//

            break;

        default:

            break;

    }

    return true;

}

void SnakeNode::setPositionRC(int row,int col)//设置节点的坐标

{    this->m_row=row;

     this->m_col=col;

      setPosition(Point(col*32,row*32));

}

bool  Game::init(){

    if(!Layer::init())

    {

    return  false;

    }

    //添加地图

    auto draw=DrawNode::create();

    draw->setAnchorPoint(Point::ZERO);

    draw->setPosition(Point::ZERO);

    this->addChild(draw);

    for(int i=0;i<11;i++)

    {

    draw->drawSegment(Point(0,32*i), Point(320,32*i), 1, Color4F(1,1,1,1));

    draw->drawSegment(Point(32*i,0), Point(32*i,320), 1, Color4F(1,1,1,1));

    }

    //添加蛇头

    spHead=SnakeNode::create(1);

    

    

    this->addChild(spHead);

    //添加身体

    //添加食物

     spFood=SnakeNode::create(3);

 

    int row=rand()%10;

    int col=rand()%10;

    spFood->setPositionRC(row,col);

    this->addChild(spFood);

    auto size=Director::getInstance()->getWinSize();

    //添加背景

    auto spriteBK=Sprite::create("menuback.png");

    spriteBK->setPosition(Point(size.width/2,size.height/2));

    spriteBK->setOpacity(75);

    this->addChild(spriteBK);

    //分数显示

    m_score=0;

    auto labelScore=Label::create("分数:0", "宋体", 25);

    labelScore->setTag(110);

    labelScore->setPosition(Point(size.width-80,size.height-50));

    this->addChild(labelScore);

    //返回按钮

    auto menuItemBack=MenuItemFont::create("Back", CC_CALLBACK_1(Game::menuCallBack,this));

    auto menu=Menu::create(menuItemBack,NULL);

    menu->setPosition(Point::ZERO);

    menuItemBack->setPosition(Point(size.width-menuItemBack->getContentSize().width-50,menuItemBack->getContentSize().height+10));

    this->addChild(menu);

     //计划任务

    this->schedule(schedule_selector(Game::gameLogic),0.5);

    //加入用户触摸事件侦听

    auto listener=EventListenerTouchOneByOne::create();

    listener->setSwallowTouches(true);

    listener->onTouchBegan=[&](Touch * t,Event * e){

        //改变贪食蛇移动的方向

        int col=t->getLocation().x/32;

        int row=t->getLocation().y/32;

        int spHeadCol=spHead->getPositionX()/32;

        int spHeadRow=spHead->getPositionY()/32;

        if(abs(spHeadCol-col)>abs(spHeadRow-row))

        {

           if(spHeadCol<col)

            {

            spHead->m_dir=ENUM_DIR::DIR_RIGHT;

            }else

            {

                spHead->m_dir=ENUM_DIR::DIR_LEFT;

            }

        }

        else

            {if(spHeadRow<row)

                {

                spHead->m_dir=ENUM_DIR::DIR_UP;

                }else

                    {

                    spHead->m_dir=ENUM_DIR::DIR_DOWN;

                    }

        

        }

        

        return true;

    };

    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

    return true;

}

void  Game::menuCallBack(Ref * object){

    auto scene=MainMenu::createScene();

    Director::getInstance()->replaceScene(scene);

}

void Game::gameLogic(float t)

{   moveBody();//移动所有身体节点

    //蛇头移动

    switch (spHead->m_dir) {

        case ENUM_DIR::DIR_RIGHT:

            spHead->runAction(MoveBy::create(0.3, Point(32,0)));

            spHead->m_col++;

            break;

        case ENUM_DIR::DIR_LEFT:

            spHead->runAction(MoveBy::create(0.3, Point(-32,0)));

            spHead->m_col--;

            break;

        case ENUM_DIR::DIR_DOWN:

            spHead->runAction(MoveBy::create(0.3, Point(0,-32)));

            spHead->m_row--;

            break;

        case ENUM_DIR::DIR_UP:

            spHead->runAction(MoveBy::create(0.3, Point(0,32)));

            spHead->m_row++;

            break;

   

        default:

            break;

    }

    //碰撞检测

    if(spHead->m_row==spFood->m_row&&

       spHead->m_col==spFood->m_col)

    {  //音效的播放

        SimpleAudioEngine::getInstance()->playEffect("eat.wav");

        //分数增加

        this->m_score+=100;

        Label * label=(Label *)this->getChildByTag(110);

        char strscore[20];

        sprintf(strscore, "分数:%d",m_score);

        label->setString(strscore);

      //食物产生新的位置

        int row=rand()%10;

        int col=rand()%10;

        spFood->setPositionRC(row,col);

      //添加节点

        newBody();

    }

}

void Game::newBody()//添加一个新的身体节点

{

    auto bodynode=SnakeNode::create(2);

    //设置这个节点的方向和坐标

    if(allBody.size()>0)//有身体节点

    { //最后一个身体的节点

         auto lastbody=allBody.at(allBody.size()-1);

      bodynode->m_dir=lastbody->m_dir;

       

        switch (bodynode->m_dir) {

            case ENUM_DIR::DIR_UP:

                bodynode->setPositionRC(lastbody->m_row-1, lastbody->m_col);

                break;

            case ENUM_DIR::DIR_DOWN:

                bodynode->setPositionRC(lastbody->m_row+1, lastbody->m_col);

                break;

            case ENUM_DIR::DIR_LEFT:

                bodynode->setPositionRC(lastbody->m_row, lastbody->m_col+1);

                break;

            case ENUM_DIR::DIR_RIGHT:

                bodynode->setPositionRC(lastbody->m_row, lastbody->m_col-1);

                break;

            default:

                break;

        }


    }else

    { //新节点的方向等于蛇头的方向

        bodynode->m_dir=spHead->m_dir;

        switch (bodynode->m_dir) {

            case ENUM_DIR::DIR_UP:

                bodynode->setPositionRC(spHead->m_row-1, spHead->m_col);

                break;

            case ENUM_DIR::DIR_DOWN:

                bodynode->setPositionRC(spHead->m_row+1, spHead->m_col);

                break;

            case ENUM_DIR::DIR_LEFT:

                bodynode->setPositionRC(spHead->m_row, spHead->m_col+1);

                break;

            case ENUM_DIR::DIR_RIGHT:

                bodynode->setPositionRC(spHead->m_row, spHead->m_col-1);

                break;

            default:

                break;

        }

    }

    //添加节点到当前图层

    this->addChild(bodynode);

    //添加节点到集合中

    allBody.pushBack(bodynode);

}

void Game::moveBody()//移动所有的身体节点

{

    if(allBody.size()==0){return;}

    for(auto bodynode:allBody)

    {

    switch (bodynode->m_dir) {

        case ENUM_DIR::DIR_RIGHT:

            bodynode->runAction(MoveBy::create(0.3, Point(32,0)));

            bodynode->m_col++;

            break;

        case ENUM_DIR::DIR_LEFT:

            bodynode->runAction(MoveBy::create(0.3, Point(-32,0)));

            bodynode->m_col--;

            break;

        case ENUM_DIR::DIR_DOWN:

            bodynode->runAction(MoveBy::create(0.3, Point(0,-32)));

            bodynode->m_row--;

            break;

        case ENUM_DIR::DIR_UP:

            bodynode->runAction(MoveBy::create(0.3, Point(0,32)));

            bodynode->m_row++;

            break;

        default:

            break;

        }

     }

    //移动完成之后,改变每个body的方向

    for(int i=allBody.size()-1;i>0;i--)

    { //每个节点的 方向调整为它前一个节点的方向

        allBody.at(i)->m_dir=allBody.at(i-1)->m_dir;

    }

    allBody.at(0)->m_dir=spHead->m_dir;

}

--------------------------------------------祝你成功-----------------------

这篇关于Cocos2d-x 3.0final 终结者系列教程13-贪食蛇游戏案例(全)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/367884

相关文章

MySQL 中的 JSON 查询案例详解

《MySQL中的JSON查询案例详解》:本文主要介绍MySQL的JSON查询的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 的 jsON 路径格式基本结构路径组件详解特殊语法元素实际示例简单路径复杂路径简写操作符注意MySQL 的 J

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

如何为Yarn配置国内源的详细教程

《如何为Yarn配置国内源的详细教程》在使用Yarn进行项目开发时,由于网络原因,直接使用官方源可能会导致下载速度慢或连接失败,配置国内源可以显著提高包的下载速度和稳定性,本文将详细介绍如何为Yarn... 目录一、查询当前使用的镜像源二、设置国内源1. 设置为淘宝镜像源2. 设置为其他国内源三、还原为官方

Maven的使用和配置国内源的保姆级教程

《Maven的使用和配置国内源的保姆级教程》Maven是⼀个项目管理工具,基于POM(ProjectObjectModel,项目对象模型)的概念,Maven可以通过一小段描述信息来管理项目的构建,报告... 目录1. 什么是Maven?2.创建⼀个Maven项目3.Maven 核心功能4.使用Maven H

IDEA自动生成注释模板的配置教程

《IDEA自动生成注释模板的配置教程》本文介绍了如何在IntelliJIDEA中配置类和方法的注释模板,包括自动生成项目名称、包名、日期和时间等内容,以及如何定制参数和返回值的注释格式,需要的朋友可以... 目录项目场景配置方法类注释模板定义类开头的注释步骤类注释效果方法注释模板定义方法开头的注释步骤方法注

Python虚拟环境终极(含PyCharm的使用教程)

《Python虚拟环境终极(含PyCharm的使用教程)》:本文主要介绍Python虚拟环境终极(含PyCharm的使用教程),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录一、为什么需要虚拟环境?二、虚拟环境创建方式对比三、命令行创建虚拟环境(venv)3.1 基础命令3

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

Python中使用正则表达式精准匹配IP地址的案例

《Python中使用正则表达式精准匹配IP地址的案例》Python的正则表达式(re模块)是完成这个任务的利器,但你知道怎么写才能准确匹配各种合法的IP地址吗,今天我们就来详细探讨这个问题,感兴趣的朋... 目录为什么需要IP正则表达式?IP地址的基本结构基础正则表达式写法精确匹配0-255的数字验证IP地

MySQL高级查询之JOIN、子查询、窗口函数实际案例

《MySQL高级查询之JOIN、子查询、窗口函数实际案例》:本文主要介绍MySQL高级查询之JOIN、子查询、窗口函数实际案例的相关资料,JOIN用于多表关联查询,子查询用于数据筛选和过滤,窗口函... 目录前言1. JOIN(连接查询)1.1 内连接(INNER JOIN)1.2 左连接(LEFT JOI

python连接本地SQL server详细图文教程

《python连接本地SQLserver详细图文教程》在数据分析领域,经常需要从数据库中获取数据进行分析和处理,下面:本文主要介绍python连接本地SQLserver的相关资料,文中通过代码... 目录一.设置本地账号1.新建用户2.开启双重验证3,开启TCP/IP本地服务二js.python连接实例1.