目录
操作系统:UOS1060专业版本。
cocos2dx:版本4.0
环境搭建教程:统信UOS下配置安装cocos2dx开发环境
本课主要内容:
文章地址:https://arv000.blog.csdn.net/article/details/132736243
开发设计思路如下,我们将游戏界面分为两个主要部分,游戏菜单部分、游戏部分。游戏菜单部分无论在那一关卡几乎不变,因此可以抽象在一个layer里面进行处理,那么不通过的关卡都能复用这个菜单界面就可以了。菜单部分需要分为两节课来讲解,这节课主要内容还是进行布局。以及每个按钮的监听内容方便后面处理,并且后面的课程中会讲解的按钮逻辑。
需要添加新资源的内容,因此需要添加新的plist文件到游戏中。在Scene/LoadingScene.cpp文件中的LoadingScene::loadSource()函数中,添加以下代码用来加载新的资源:
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("ingame_gui-hd.plist");
添加跳转游戏场景代码
上一节课,学习了如何新建游戏难度选择,当用户点击“进入游戏”时需要跳跳转到游戏场景。在ChooseDifficultyScene.cpp文件中找到sprite_start_mode精灵给精灵添加按钮响应函数ChooseDifficultyScene::touchPlayGame。
- auto sprite_start_mode = MenuItemSprite::create(Sprite::createWithSpriteFrameName("levelSelect_startMode_0001.png"),
- Sprite::createWithSpriteFrameName("levelSelect_startMode_0002.png"),
- CC_CALLBACK_1(ChooseDifficultyScene::touchPlayGame,this));
ChooseDifficultyScene::touchPlayGame内容如下:
获取当前选中的游戏难度并且,跳转到游戏场景中。
- void ChooseDifficultyScene::touchPlayGame(Ref *pSpender)
- {
- Director::getInstance()->replaceScene(GameScene::createGameScene(getLevel(),getDifficulty()));
- }
新建文件Scene/GameScene.cpp、Scene/GameScene.h,这里只是添加了游戏菜单层所以在游戏场景中代码比较简单。
GameScene.cpp内容如下:
- #include "GameScene.h"
- #include "../Layer/PlayerStateMenuLayer.h"
-
-
- Scene *GameScene::createGameScene(int level, int difficulty)
- {
- auto scene = new GameScene();
- if(scene && scene->initGame(level,difficulty)){
- scene->autorelease();
- return scene;
- }
- CC_SAFE_FREE(scene);
- return nullptr;
- }
-
- bool GameScene::initGame(int level, int difficulty)
- {
- auto playerStateMenuLayer = PlayerStateMenuLayer::create();
- addChild(playerStateMenuLayer);
- return true;
- }
GameScene.h内容如下:
- #ifndef __SCENE_GAME_SCENE_H__
- #define __SCENE_GAME_SCENE_H__
- #include "cocos2d.h"
-
- USING_NS_CC;
- class GameScene : public Scene
- {
- public:
- static Scene *createGameScene(int level,int difficulty);
-
- private:
- virtual bool initGame(int level,int difficulty);
- };
-
- #endif // __SCENE_GAME_SCENE_H__
游戏菜单中包括很多共性内容例如:生命值、金币、怪物波数、扩展功能雷石、扩展功能伞扩展功能锦囊(六侠)。
新建文件Layer/PlayerStateMenuLayer.cpp、Layer/PlayerStateMenuLayer.h
Layer/PlayerStateMenuLayer.cpp文件内容:
- #include "PlayerStateMenuLayer.h"
-
-
- bool PlayerStateMenuLayer::init()
- {
- if( !Layer::init() ){
- return false;
- }
- win_size_ = Director::getInstance()->getWinSize();
- initSprite();
- initEvent();
-
- return true;
- }
-
- void PlayerStateMenuLayer::initSprite()
- {
- // 显示 生命值,金币,怪物波数的背景
- sprite_state_ = Sprite::createWithSpriteFrameName("hud_background.png");
- sprite_state_->setAnchorPoint(Point(0,1));
- sprite_state_->setPosition(Point(20,win_size_.height - 20 + 100));
- addChild(sprite_state_);
-
- // 生命值
- label_life_ = Label::createWithTTF("0","fonts/arial.ttf",20);
- label_life_->setPosition(Point(sprite_state_->getContentSize().width*0.25,sprite_state_->getContentSize().height*0.75));
- sprite_state_->addChild(label_life_);
-
- // 金币值
- label_gold_ = Label::createWithTTF("0","fonts/arial.ttf",20);
- label_gold_->setPosition(Point(sprite_state_->getContentSize().width*0.75,sprite_state_->getContentSize().height*0.75));
- sprite_state_->addChild(label_gold_);
-
- // 当前怪物波数
- label_wave_ = Label::createWithTTF("0","fonts/arial.ttf",20);
- label_wave_->setPosition(Point(sprite_state_->getContentSize().width*0.5,sprite_state_->getContentSize().height*0.25));
- sprite_state_->addChild(label_wave_);
-
- // 暂停按钮
- sprite_pause_ = Sprite::createWithSpriteFrameName("hud_buttons_0001.png");
- sprite_pause_->setAnchorPoint(Point(1,1));
- sprite_pause_->setPosition(Point(win_size_.width -20,win_size_.height - 20 + 100));
- addChild(sprite_pause_);
-
- // // 拓展功能:雷石
- sprite_thunder_stone_ = Sprite::createWithSpriteFrameName("power_portrait_fireball_0001.png");
- sprite_thunder_stone_->setAnchorPoint(Point(0,0));
- sprite_thunder_stone_->setPosition(Point(10,-20));
- sprite_thunder_stone_->setName("inactive");
- addChild(sprite_thunder_stone_,1);
-
- // 拓展功能:伞兵
- sprite_paratrooper_ = Sprite::createWithSpriteFrameName("power_portrait_reinforcement_0001.png");
- sprite_paratrooper_->setAnchorPoint(Point(0,0));
- sprite_paratrooper_->setPosition(Point(120,-20));
- sprite_paratrooper_->setName("inactive");
- addChild(sprite_paratrooper_,1);
-
-
- // 拓展功能:锦囊
- sprite_pack_ = Sprite::createWithSpriteFrameName("power_portrait_backpack_0001.png");
- sprite_pack_->setAnchorPoint(Point(1,0));
- sprite_pack_->setPosition(Point(win_size_.width - 10,-20));
- sprite_pack_->setName("inactive");
- addChild(sprite_pack_,1);
-
- // 锦囊背景
- sprite_back_pack_ = Sprite::createWithSpriteFrameName("backPack_hover.png");
- sprite_back_pack_->setAnchorPoint(Point(1,0));
- sprite_back_pack_->setPosition(Point(win_size_.width - 60,30));
- sprite_back_pack_->setVisible(true);
- addChild(sprite_back_pack_,-1);
-
- for(int i = 1; i <=6 ; i ++){
- int num = 3;
- if(num > 0){
- stringForSkillFileName = StringUtils::format("backPack_icons_000%d.png",i);
- }else{
- stringForSkillFileName = StringUtils::format("backPack_icons_off_000%d.png",i+1);
- }
- sprite_backPack_icons_[i] = Sprite::createWithSpriteFrameName(stringForSkillFileName);
- sprite_backPack_icons_[i]->setAnchorPoint(Point(1,0));
- sprite_backPack_icons_[i]->setPosition(Point(640 - 85 * i,-20));
-
- sprite_backPack_icons_[i]->setTag(i);
- sprite_backPack_icons_[i]->setName(StringUtils::format("shop%d",i));
- sprite_back_pack_->addChild(sprite_backPack_icons_[i],0);
-
- auto numLeft = Label::createWithTTF(StringUtils::format("%d",num),"fonts/arial.ttf",20);
- numLeft->setPosition(Point(sprite_backPack_icons_[i]->getContentSize().width/4*3,sprite_backPack_icons_[i]->getContentSize().height/4));
- numLeft->setTag(101);
- sprite_backPack_icons_[i]->addChild(numLeft);
- }
- // 倒计时涂层
- timer_stone_ = ProgressTimer::create(Sprite::createWithSpriteFrameName("power_loading.png"));
- timer_stone_->setAnchorPoint(Point(0,0));
- timer_stone_->setReverseDirection(true);
- timer_stone_->setPosition(Point(10,-20));
- timer_stone_->setPercentage(50);
- addChild(timer_stone_,1,100);
-
- // 倒计时涂层
- timer_paratrooper_ = ProgressTimer::create(Sprite::createWithSpriteFrameName("power_loading.png"));
- timer_paratrooper_->setAnchorPoint(Point(0,0));
- timer_paratrooper_->setReverseDirection(true);
- timer_paratrooper_->setPosition(Point(120,-20));
- timer_paratrooper_->setPercentage(100);
- addChild(timer_paratrooper_,1,200);
-
- }
-
- void PlayerStateMenuLayer::initEvent()
- {
- // 添加暂停 按钮的监听。
- auto sprite_pause_listener = EventListenerTouchOneByOne::create();
- sprite_pause_listener->onTouchBegan = CC_CALLBACK_2(PlayerStateMenuLayer::onTouchBeganSpirtePause,this);
- sprite_pause_listener->onTouchEnded = CC_CALLBACK_2(PlayerStateMenuLayer::onTouchEnedSpirtePause,this);
- sprite_pause_listener->setSwallowTouches(true);
- _eventDispatcher->addEventListenerWithSceneGraphPriority(sprite_pause_listener,sprite_pause_);
-
- // 添加雷石监听
- auto sprite_thunder_stone_listener = EventListenerTouchOneByOne::create();
- sprite_thunder_stone_listener->onTouchBegan = CC_CALLBACK_2(PlayerStateMenuLayer::onTouchBeganSpriteThunderStone,this);
- sprite_thunder_stone_listener->onTouchEnded = CC_CALLBACK_2(PlayerStateMenuLayer::onTouchEnedSSpriteThunderStone,this);
- sprite_thunder_stone_listener->setSwallowTouches(true);
- _eventDispatcher->addEventListenerWithSceneGraphPriority(sprite_thunder_stone_listener,sprite_thunder_stone_);
-
- // 添加伞兵监听
- auto sprite_paratrooper_listener = EventListenerTouchOneByOne::create();
- sprite_paratrooper_listener->onTouchBegan = CC_CALLBACK_2(PlayerStateMenuLayer::onTouchBeganSpriteParatrooper,this);
- sprite_paratrooper_listener->onTouchEnded = CC_CALLBACK_2(PlayerStateMenuLayer::onTouchBeganSpriteParatrooper,this);
- sprite_paratrooper_listener->setSwallowTouches(true);
- _eventDispatcher->addEventListenerWithSceneGraphPriority(sprite_paratrooper_listener,sprite_paratrooper_);
-
- // 添加锦囊监听
- auto sprite_pack_listener = EventListenerTouchOneByOne::create();
- sprite_pack_listener->onTouchBegan = CC_CALLBACK_2(PlayerStateMenuLayer::onTouchBeganSpritePack,this);
- sprite_pack_listener->onTouchEnded = CC_CALLBACK_2(PlayerStateMenuLayer::onTouchBeganSpritePack,this);
- sprite_pack_listener->setSwallowTouches(true);
- _eventDispatcher->addEventListenerWithSceneGraphPriority(sprite_pack_listener,sprite_pack_);
- }
-
- bool PlayerStateMenuLayer::onTouchBeganSpirtePause(Touch *touch, Event *event)
- {
- return true;
- }
-
- void PlayerStateMenuLayer::onTouchEnedSpirtePause(Touch *touch, Event *event)
- {
-
- }
-
- bool PlayerStateMenuLayer::onTouchBeganSpriteThunderStone(Touch *touch, Event *event)
- {
- return false;
- }
-
- void PlayerStateMenuLayer::onTouchEnedSSpriteThunderStone(Touch *touch, Event *event)
- {
-
- }
-
- bool PlayerStateMenuLayer::onTouchBeganSpriteParatrooper(Touch *touch, Event *event)
- {
- return false;
- }
-
- void PlayerStateMenuLayer::onTouchEnedSSpriteParatrooper(Touch *touch, Event *event)
- {
-
- }
-
- bool PlayerStateMenuLayer::onTouchBeganSpritePack(Touch *touch, Event *event)
- {
- return false;
- }
-
- void PlayerStateMenuLayer::onTouchEnedSSpritePack(Touch *touch, Event *event)
- {
-
- }
-
- void PlayerStateMenuLayer::onEnterTransitionDidFinish()
- {
- sprite_state_->runAction(MoveBy::create(0.2f,Point(0,-100)));
- }
Layer/PlayerStateMenuLayer.h文件内容:
- #ifndef __LAYER_PLAYER_STATE_MENU_LAYER_H__
- #define __LAYER_PLAYER_STATE_MENU_LAYER_H__
-
- #include "cocos2d.h"
- USING_NS_CC;
-
- class PlayerStateMenuLayer : public Layer
- {
- public:
- virtual bool init();
- void initSprite();
- void initEvent();
- // implement the "static create()" method manually
- CREATE_FUNC(PlayerStateMenuLayer)
- private:
- Size win_size_;
- Sprite * sprite_state_;
- Sprite * sprite_pause_;
- Label *label_life_;
- Label* label_gold_;
- Label* label_wave_;
-
- Sprite* sprite_thunder_stone_; // 雷石
- Sprite* sprite_paratrooper_; // 伞兵
- Sprite* sprite_pack_; // 锦囊
- Sprite* sprite_back_pack_; // 锦囊背景。六侠背景
- // 六侠
- Sprite* sprite_backPack_icons_[6];
- std::string stringForSkillFileName;
- //
- ProgressTimer *timer_stone_;
- ProgressTimer *timer_paratrooper_;
- // ===== 精灵响应函数 =========
- // 监听暂停精灵
- bool onTouchBeganSpirtePause(Touch* touch,Event *event);
- void onTouchEnedSpirtePause(Touch* touch,Event *event);
-
- // 监听雷石精灵
- bool onTouchBeganSpriteThunderStone(Touch* touch,Event *event);
- void onTouchEnedSSpriteThunderStone(Touch* touch,Event *event);
-
- // 监听伞兵 精灵
- bool onTouchBeganSpriteParatrooper(Touch* touch,Event *event);
- void onTouchEnedSSpriteParatrooper(Touch* touch,Event *event);
-
- // 监听锦囊 精灵
- bool onTouchBeganSpritePack(Touch* touch,Event *event);
- void onTouchEnedSSpritePack(Touch* touch,Event *event);
-
- void onEnterTransitionDidFinish();
-
- };
-
- #endif // __LAYER_PLAYER_STATE_MENU_LAYER_H__
Cocos2d-x 4.0 中的 `ProgressTimer` 是一个用于创建进度条效果的工具类。它允许你根据百分比或比例来显示进度,并且可以用于各种游戏和应用中的加载条、生命值条等。下面是一个详细的例子,以及涉及的知识点。
### 示例:创建一个水平进度条
首先,确保你已经设置好了 Cocos2d-x 4.0 的开发环境。
1. 创建一个新的 Cocos2d-x 4.0 项目。
2. 打开你的项目,并在场景中添加一个进度条。
- #include "cocos2d.h"
-
- class MyScene : public cocos2d::Scene {
- public:
- virtual bool init() override {
- if (!Scene::init()) {
- return false;
- }
-
- // 创建一个进度条
- auto progress = cocos2d::ProgressTimer::create(cocos2d::Sprite::create("progressbar.png"));
- progress->setType(cocos2d::ProgressTimer::Type::BAR);
- progress->setMidpoint(cocos2d::Vec2(0, 0.5)); // 设置起始点为左边中点
- progress->setBarChangeRate(cocos2d::Vec2(1, 0)); // 设置只在水平方向改变
- progress->setPercentage(50); // 设置初始百分比为 50%
-
- // 设置进度条位置
- progress->setPosition(cocos2d::Director::getInstance()->getVisibleSize() / 2);
-
- // 添加进度条到场景
- this->addChild(progress);
-
- return true;
- }
-
- CREATE_FUNC(MyScene);
- };
在这个示例中,我们创建了一个水平进度条,通过使用 `ProgressTimer` 来实现。具体说明如下:
最后,将进度条添加到场景中。
3. 创建一个进度条的外观图片("progressbar.png"),并将其放置在项目资源目录下。
4. 运行项目,你将看到一个水平进度条显示在屏幕中央。
"setSwallowTouches" 是 Cocos2d-x 游戏引擎中的一个方法,通常用于触摸事件的处理。这个方法是 cocos2d::Layer
类的一部分,用于设置是否吞噬(swallow)触摸事件。
当一个层(Layer)设置了吞噬触摸事件(setSwallowTouches(true)
),它将会拦截并处理所有传递给它的触摸事件,阻止这些事件继续传递到底层的层或场景。这通常用于处理触摸事件的优先级,确保在多个重叠的层中只有一个层能够响应触摸事件。