基于Cocos2d-x开发guardCarrot--7 《保卫萝卜2》关卡选择页面开发
《保卫萝卜2》关卡选择页面开发
我们已经实现完《保卫萝卜2》主页面上解锁天天向上玩法(链接:https://blog.csdn.net/qq135595696/article/details/123012891),接下来我们实现关卡选择页面的开发。同样,在开发之前,我们先看一下完成后的效果图,如下如所示。
分析《保卫萝卜2》的关卡选择页面,可以明显得到,我们应该把这个场景逻辑上分为两个层,一个是背景层,一个UI层。其中,背景层里是一个滚动视图,滚动整个地图。UI层存放一些简单的按钮和图片等节点。
我们在项目中新建一个筛选器ChooseLevel,用来存放关卡选择场景的相关文件,如下图所示。
其中,ChooseLevel.h、ChooseLevel.cpp用来管理关卡选择页面场景。 在该场景之上又加载了一个UI层。根据分析得出,该场景中首先需要一个ScrollView类来滚动整个背景地图,接下来我们先创建ScrollView对象,代码如下:
//背景滚动界面auto scrollView = ScrollView::create();//设置滚动方向scrollView->setDirection(ScrollView::Direction::HORIZONTAL);//开启触摸事件scrollView->setTouchEnabled(true);//设置内容大小scrollView->setContentSize(Director::getInstance()->getVisibleSize());//隐藏滚动条scrollView->setScrollBarEnabled(false);this->addChild(scrollView);//创建背景地图Sprite* imageView = nullptr;string filePath;float nextPosX = 0.f;for (int i = 0; i < 14; i++){filePath = "ChooseLevel/Map/stage_map_" + to_string(i) + ".png";imageView = Sprite::create(filePath);//更改锚点位置是因为第14张地图跟前面的13张地图宽度不一致imageView->setAnchorPoint(Vec2(0, 0.5));imageView->setPosition(nextPosX, Director::getInstance()->getVisibleSize().height / 2);nextPosX += imageView->getContentSize().width;scrollView->addChild(imageView);}//设置ScrollView的布局容器大小scrollView->setInnerContainerSize(Size(nextPosX, Director::getInstance()->getVisibleSize().height));
上述代码创建了ScrollView对象,同时规定其滚动方向为水平方向,同时开启其触摸事件、设置其内容大小为整个屏幕的大小。
紧接着,创建背景地图。在ScrollView中,子节点的坐标需要我们自己设定,这里通过一个for循环干净利索地台添加了14张背景图。最后设定了ScrollView的布局容器大小,这里nextPosX的值等于14张背景图宽度的总和。
最后只需要在ChooseLevel类中的init()函数调用即可。接下来,实现UI层的开发。
显然,UI层需要实现左上角的三个按钮、中间的打折信息按钮以及右上角的的生命星显示,如下图所示:
可以明显看出,左上角的三个按钮的后面有一张背景图片,这张背景图始终位于当前屏幕的左上角,所以可以将它的锚点设置为(0,1),坐标设置为(0, Director::getInstance()->getVisibleSize().height),代码如下(首先我们创建UI层的Layer):
//UI按钮控件auto layerUI = Layer::create();this->addChild(layerUI);auto leftPanelPinfo = AutoPolygon::generatePolygon("ChooseLevel/stagemap_toolbar_leftbg.png");//该背景图始终在屏幕的左上角auto leftPanel = Sprite::create(leftPanelPinfo);leftPanel->setAnchorPoint(Vec2(0, 1));leftPanel->setPosition(0, Director::getInstance()->getVisibleSize().height);leftPanel->setScale(0.7);layerUI->addChild(leftPanel);
上面的代码保证了三个按钮的背景始终在屏幕的左上角,那么剩下的这3个按钮我们应该作为背景图片的子节点,使得三个按钮和按钮背景图片“绑”成了一个整体,这样的相对布局保证了3个按钮的坐标不会随屏幕大小的不一致而产生位置错乱,代码如下:
//创建背景图精灵的子节点(三个按钮)string toolbarHomeFilePath = "ChooseLevel/stagemap_toolbar_home.png";_toolbarHome = Button::create(toolbarHomeFilePath, toolbarHomeFilePath, "");_toolbarHome->setAnchorPoint(Vec2(0, 0));_toolbarHome->setPosition(Vec2(10, 10));//启用缩放动画_toolbarHome->setPressedActionEnabled(true);leftPanel->addChild(_toolbarHome);string toolbarShopFilePath = "ChooseLevel/stagemap_toolbar_shop.png";_toolbarShop = Button::create(toolbarShopFilePath, toolbarShopFilePath, "");_toolbarShop->setAnchorPoint(Vec2(0, 0));_toolbarShop->setPosition(Vec2(125, 10));_toolbarShop->setPressedActionEnabled(true);leftPanel->addChild(_toolbarShop);
//初始化首页按钮、商店按钮、排行榜按钮的三个事件_toolbarHome->addTouchEventListener([](Ref* sender, Widget::TouchEventType type) {if (type == ui::Widget::TouchEventType::ENDED){auto mainScene = MainScene::createScene();Director::getInstance()->replaceScene(mainScene);}});_toolbarShop->addTouchEventListener([](Ref* sender, Widget::TouchEventType type) {if (type == ui::Widget::TouchEventType::ENDED){log("open the shop");}});_toolbarLeaderboard->addTouchEventListener([](Ref* sender, Widget::TouchEventType type) {if (type == ui::Widget::TouchEventType::ENDED){log("open the leaderboard");}});
在代码中,我们可以发现“首页”按钮仅采用一张图片,所以我们应该给按钮启用被按下时的缩放操作。最后,给“首页”按钮添加触摸事件监听器,实现了住页面场景MainScene的切换。另外,在代码中用于判断时间是否在触摸结束时才响应实现逻辑代码,在开发中更多的按钮事件响应都应该放在触摸事件结束之后,而不是触摸释放之前。另外两个按钮同理。参考上述代码即可。
在中间促销按钮中,需要添加一个BMFont来表示当前打多少折扣。定义私有变量cocos2d::Label* _discountText;来表示当前打多少折扣,这样就可以通过该变量来控制显示的折扣,代码如下:
//创建中间的促销按钮string discountTagStoneFilePath = "ChooseLevel/zh/discount_tag_stone.png";_discountTagStone = Button::create(discountTagStoneFilePath, discountTagStoneFilePath, "");_discountTagStone->setAnchorPoint(Vec2(0.5, 1));_discountTagStone->setPosition(Vec2(Director::getInstance()->getVisibleSize().width / 2, Director::getInstance()->getVisibleSize().height));_discountTagStone->setScale(0.7);_discountText = Label::createWithBMFont("ChooseLevel/discount.fnt", "8");_discountTagStone->addChild(_discountText);_discountText->setAnchorPoint(Vec2(0, 0));_discountText->setPosition(160, 65);layerUI->addChild(_discountTagStone);
//初始化中间的促销按钮_discountTagStone->addTouchEventListener([](Ref* sender, Widget::TouchEventType type) {if (type == ui::Widget::TouchEventType::ENDED){log("open the discountTagStone");}});
右上角的生命星组成与中间限时折扣按钮发类似,最底层为一张背景图,顶层为生命星数量文本,实现起来比较简单,代码如下:
//创建右上角 生命星按钮string toolbarRightbgFilePath = "ChooseLevel/stagemap_toolbar_rightbg.png";_toolbarRightbg = Button::create(toolbarRightbgFilePath, toolbarRightbgFilePath, "");_toolbarRightbg->setAnchorPoint(Vec2(1, 1));_toolbarRightbg->setPosition(Director::getInstance()->getVisibleSize());_toolbarRightbg->setScale(0.7);layerUI->addChild(_toolbarRightbg);//创建生命星星的图片背景auto starImage = Sprite::create("ChooseLevel/zh/stagemap_toolbar_overten.png");starImage->setAnchorPoint(Vec2(1, 1));starImage->setPosition(Director::getInstance()->getVisibleSize());starImage->setScale(0.7);layerUI->addChild(starImage);auto text = Label::createWithSystemFont("010", "Arial", 24);text->setAnchorPoint(Vec2(0, 0));text->setPosition(Vec2(220, 73));starImage->addChild(text);
//初始化右上角生命星星事件_toolbarRightbg->addTouchEventListener([](Ref* sender, Widget::TouchEventType type) {if (type == ui::Widget::TouchEventType::ENDED){log("click the toolbarRightbg");}});
最后,在ChooseLevel类中的init()函数中调用这些方法,在运行该场景就可以得到文章开头的场景效果。
至此,我们已经开发了主页面场景和关卡选择场景ChooseLevel。虽然ChooseLevel还未开发完,但是已经可以将两个场景串联起来,从而实现场景的切换。点击主页面中的“开始冒险”菜单按钮,可以切换到关卡选择场景。此事件可以通过“开始冒险”的事件监听器进行实现,代码如下:
_startGameBtn->addTouchEventListener([](Ref* sender, Widget::TouchEventType type) {switch (type){case ui::Widget::TouchEventType::BEGAN:{SimpleAudioEngine::getInstance()->playEffect("Sound/MainMenu/Select.mp3", false, 1.0f, 1.0f, 1.0f);break;}case ui::Widget::TouchEventType::ENDED:{//log("_startGameBtn ENDERD");//跳转场景auto chooseLevel = ChooseLevel::createScene();Director::getInstance()->replaceScene(chooseLevel);break;}default:break;}});
TIPS:注意需要#include “ChooseLevel.h”。
源代码
最后,附上ChooseLevel.h、ChooseLevel.cpp的源代码。
ChooseLevel.h
#pragma once
#include "cocos2d.h"
#include "ui/CocosGUI.h"
#include <string.h>class ChooseLevel :public cocos2d::Scene
{public:static cocos2d::Scene* createScene();virtual bool init();CREATE_FUNC(ChooseLevel);private:void InitUI();void InitEvent();private:cocos2d::ui::Button* _toolbarHome;cocos2d::ui::Button* _toolbarShop;cocos2d::ui::Button* _toolbarLeaderboard;cocos2d::ui::Button* _discountTagStone;cocos2d::Label* _discountText;cocos2d::ui::Button* _toolbarRightbg;static float discountText;
};
ChooseLevel.cpp
#include "ChooseLevel.h"
#include "MainScene.h"USING_NS_CC;
using namespace cocos2d::ui;
using namespace std;float ChooseLevel::discountText = 7.5;cocos2d::Scene* ChooseLevel::createScene()
{return ChooseLevel::create();
}bool ChooseLevel::init()
{if (!Scene::init())return false;InitUI();InitEvent();return true;
}void ChooseLevel::InitUI()
{//背景滚动界面auto scrollView = ScrollView::create();scrollView->setDirection(ScrollView::Direction::HORIZONTAL);scrollView->setTouchEnabled(true);scrollView->setContentSize(Director::getInstance()->getVisibleSize());scrollView->setScrollBarEnabled(false);this->addChild(scrollView);Sprite* imageView = nullptr;string filePath;float nextPosX = 0.f;for (int i = 0; i < 14; i++){filePath = "ChooseLevel/Map/stage_map_" + to_string(i) + ".png";imageView = Sprite::create(filePath);//更改锚点位置是因为第14张地图跟前面的13张地图宽度不一致imageView->setAnchorPoint(Vec2(0, 0.5));imageView->setPosition(nextPosX, Director::getInstance()->getVisibleSize().height / 2);nextPosX += imageView->getContentSize().width;scrollView->addChild(imageView);}scrollView->setInnerContainerSize(Size(nextPosX, Director::getInstance()->getVisibleSize().height));//UI按钮控件auto layerUI = Layer::create();this->addChild(layerUI);auto leftPanelPinfo = AutoPolygon::generatePolygon("ChooseLevel/stagemap_toolbar_leftbg.png");//该背景图始终在屏幕的左上角auto leftPanel = Sprite::create(leftPanelPinfo);leftPanel->setAnchorPoint(Vec2(0, 1));leftPanel->setPosition(0, Director::getInstance()->getVisibleSize().height);leftPanel->setScale(0.7);layerUI->addChild(leftPanel);//创建背景图精灵的子节点(三个按钮)string toolbarHomeFilePath = "ChooseLevel/stagemap_toolbar_home.png";_toolbarHome = Button::create(toolbarHomeFilePath, toolbarHomeFilePath, "");_toolbarHome->setAnchorPoint(Vec2(0, 0));_toolbarHome->setPosition(Vec2(10, 10));_toolbarHome->setPressedActionEnabled(true);leftPanel->addChild(_toolbarHome);string toolbarShopFilePath = "ChooseLevel/stagemap_toolbar_shop.png";_toolbarShop = Button::create(toolbarShopFilePath, toolbarShopFilePath, "");_toolbarShop->setAnchorPoint(Vec2(0, 0));_toolbarShop->setPosition(Vec2(125, 10));_toolbarShop->setPressedActionEnabled(true);leftPanel->addChild(_toolbarShop);string toolbarLeaderboardFilePath = "ChooseLevel/stagemap_toolbar_leaderboard.png";_toolbarLeaderboard = Button::create(toolbarLeaderboardFilePath, toolbarLeaderboardFilePath, "");_toolbarLeaderboard->setAnchorPoint(Vec2(0, 0));_toolbarLeaderboard->setPosition(Vec2(235, 10));_toolbarLeaderboard->setPressedActionEnabled(true);leftPanel->addChild(_toolbarLeaderboard);//创建中间的促销按钮string discountTagStoneFilePath = "ChooseLevel/zh/discount_tag_stone.png";_discountTagStone = Button::create(discountTagStoneFilePath, discountTagStoneFilePath, "");_discountTagStone->setAnchorPoint(Vec2(0.5, 1));_discountTagStone->setPosition(Vec2(Director::getInstance()->getVisibleSize().width / 2, Director::getInstance()->getVisibleSize().height));_discountTagStone->setScale(0.7);_discountText = Label::createWithBMFont("ChooseLevel/discount.fnt", "8");_discountTagStone->addChild(_discountText);_discountText->setAnchorPoint(Vec2(0, 0));_discountText->setPosition(160, 65);layerUI->addChild(_discountTagStone);//创建右上角 生命星按钮string toolbarRightbgFilePath = "ChooseLevel/stagemap_toolbar_rightbg.png";_toolbarRightbg = Button::create(toolbarRightbgFilePath, toolbarRightbgFilePath, "");_toolbarRightbg->setAnchorPoint(Vec2(1, 1));_toolbarRightbg->setPosition(Director::getInstance()->getVisibleSize());_toolbarRightbg->setScale(0.7);layerUI->addChild(_toolbarRightbg);//创建生命星星的图片背景auto starImage = Sprite::create("ChooseLevel/zh/stagemap_toolbar_overten.png");starImage->setAnchorPoint(Vec2(1, 1));starImage->setPosition(Director::getInstance()->getVisibleSize());starImage->setScale(0.7);layerUI->addChild(starImage);auto text = Label::createWithSystemFont("010", "Arial", 24);text->setAnchorPoint(Vec2(0, 0));text->setPosition(Vec2(220, 73));starImage->addChild(text);
}void ChooseLevel::InitEvent()
{//初始化首页按钮、商店按钮、排行榜按钮的三个事件_toolbarHome->addTouchEventListener([](Ref* sender, Widget::TouchEventType type) {if (type == ui::Widget::TouchEventType::ENDED){auto mainScene = MainScene::createScene();Director::getInstance()->replaceScene(mainScene);}});_toolbarShop->addTouchEventListener([](Ref* sender, Widget::TouchEventType type) {if (type == ui::Widget::TouchEventType::ENDED){log("open the shop");}});_toolbarLeaderboard->addTouchEventListener([](Ref* sender, Widget::TouchEventType type) {if (type == ui::Widget::TouchEventType::ENDED){log("open the leaderboard");}});//初始化中间的促销按钮_discountTagStone->addTouchEventListener([](Ref* sender, Widget::TouchEventType type) {if (type == ui::Widget::TouchEventType::ENDED){log("open the discountTagStone");}});//初始化右上角生命星星事件_toolbarRightbg->addTouchEventListener([](Ref* sender, Widget::TouchEventType type) {if (type == ui::Widget::TouchEventType::ENDED){log("click the toolbarRightbg");}});}static void problemLoading(const char* filename)
{printf("Error while loading:%s\n", filename);printf("Depending on how you compiled you might have to add 'Resources/' in front of filenames in ChooseLevel.cpp\n");
}
效果展示
基于Cocos2d-x开发guardCarrot--7 《保卫萝卜2》关卡选择页面开发相关推荐
- 测试学开发——第一课:环境搭建与页面开发介绍。
1 环境搭建: jdk配置+eclipse下载 请参考:https://www.cnblogs.com/ForestDeer/p/6647402.html 2测试页面快速开发技巧 http://www ...
- python集成开发环境运行快捷键_Python初学者选择集成开发环境必看 python开发
编程语言在进行编程时,都需要借助一定的集成开发环境和代码编辑器,Python编程亦如此,以下是在Python初学者在选择Python编辑器时,可以从以下几个方面着手: 1. 保存和重载代码文件 如果一 ...
- Taro跨端开发探索19——商城小程序确认订单页面开发
前言 截止到昨天,我们已经将商城小程序的所有tabBar下对应的所有页面.到现在可以说我们的小程序的业务逻辑已经完成了70%了,剩下的逻辑比较重点的就是订单和售后页面了. 今天我们开始探索确认订单页面 ...
- 网站开发(周五):项目前端页面开发(实战)
第一.前端基础简介 前端网页:根据此前项目需求分析可知,我们需要开发网站首页.文章分类页.搜索页.正文页.标签页,而一个最基本网页模版有三部分,网页顶部导航条.网页中部主体.网页底部,其中顶部和底部布 ...
- Flutter黑马头条项目开发(二.底部切换导航和新闻页面开发)
底部四个切换导航 它分为首页,问答,视频和我的四大模块 创建lib/home/home.dart首页文件,使用的是bottomNavigationBar组件,官网也有介绍 它有一个onTap函数,这个 ...
- java开发调用海康威视摄像头的web端页面开发心得
最近在开发过程中 需要用到海康威视的摄像头 在web端展示 在各种百度之后 发现网上很难找到一个 简便,可靠的教程 在摸索着完成项目之后 ,决定写一篇攻略 造福有需求的小伙伴 言归正传 首先需 ...
- 开发好还是实施好_公众号开发 选择模板好还是选择定制发好
微信公众号是很多企业和商家在微信上进行营销推广时会使用到的工具之一.但由于微信公众号的基础功能比较简单,往往无法满足企业运营的需求,因此很多企业表示要增加一些功能,也就是对公众号进行二次开发. 公众号 ...
- eclipse android开发环境搭建_聊聊Spring boot2.X开发环境搭建和基本开发
对Spring Boot的开发环境进行搭建,并对它的特点做进一步的了解,才能更好地对Spring Boot有更深入的介绍.但是无论如何都需要先来搭建Spring Boot的工程. 搭建Spring B ...
- 接口开发指的是什么_企业在什么情况下要选择定制开发软件
软件定制开发是指软件开发商依据我们的需求停止量身定制的开发,软件定制开发相关于单纯产品的施行周期长.本钱高.风险大.假如根据定制开发的工作量或水平来分,我们能够分为完整定制开发和局部定制开发,完整定制 ...
- 该如何选择Java开发和嵌入式开发
首先,Java开发和嵌入式开发都是目前IT行业内比较常见的开发岗位,也都有大量的从业人员,所以从就业的角度来看,学习Java开发和嵌入式开发都是不错的选择.Java语言的应用领域包括Web开发.And ...
最新文章
- 73款阿里巴巴开源软件详解
- 患者信息可视化及关联规则可视化
- DataTable 排序
- 织梦百度php主动推送代码示例,织梦百度php主动推送代码示例,亲试绝对成功!...
- opencv图像处理9-图像金字塔
- Hibernate:More than one row with the given identifier was found解决办法
- 字节Java全能手册火了!Redis/Nginx/Dubbo/Spring全家桶/啥都有
- with ...as ...
- IceE-1.3.0的移植过程及错误Time.h:36: error: expected type-specifier before ‘time-转
- Java 和C# 最大的不同是对底层的控制能力不同
- java中的UDP总结
- Python图像处理(Pillow/PIL)入门
- 西游记中牛魔王的雄厚实力和家业地盘
- c语言最简单的程序流程图,高手帮忙画个流程图简单的俄罗斯方块C语言程 – 手机爱问...
- 康奈尔大学计算机硕士要求,康奈尔大学计算机硕士
- IDEA settings.xml 阿里云配置备份
- 【Window10】自定义菜单——显示桌面
- 什么才是一个量化交易策略的核心?
- 蓝牙、红外线与wifi 区别以及不同频段无线电磁波的穿墙和绕过障碍物能力(转)
- 后缀自动机(SAM)讲解 + Luogu p3804【模板】后缀自动机 (SAM)