Cocos2d-x简单横版游戏
生活随笔
收集整理的這篇文章主要介紹了
Cocos2d-x简单横版游戏
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
- 簡單橫版游戲
- 作業要求
- 實現效果
- 具體實現
- HelloWorldScene.cpp
- HelloWorldScene.h
- 視頻演示以及資源
簡單橫版游戲
作業要求
- 左邊wasd4個虛擬按鍵能控制角色移動
- 右邊2個虛擬按鍵x,y能控制角色播放不同的幀動畫
- 界面所有字體要求:使用fonts目錄下的arial.ttf,字體大小為36
- 角色不會移動到可視窗口外
- 添加倒計時
- 添加人物血條
- X、Y播放的動畫不能同時播放
- 點擊虛擬按鍵x播放幀動畫并讓血條減少,點擊y播放幀動畫并讓血條增加(加分項)
實現效果
具體實現
HelloWorldScene.cpp
#include "HelloWorldScene.h" #include "SimpleAudioEngine.h" //因為string要用,或者std::string也行 using namespace std; #pragma execution_character_set("utf-8")USING_NS_CC;Scene* HelloWorld::createScene() {return HelloWorld::create(); }// Print useful error message instead of segfaulting when files are not there. 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 HelloWorldScene.cpp\n"); }// on "init" you need to initialize your instance bool HelloWorld::init() {//// 1. super init firstif ( !Scene::init() ){return false;}visibleSize = Director::getInstance()->getVisibleSize();origin = Director::getInstance()->getVisibleOrigin();//創建一張貼圖auto texture = Director::getInstance()->getTextureCache()->addImage("$lucia_2.png");//從貼圖中以像素單位切割,創建關鍵幀auto frame0 = SpriteFrame::createWithTexture(texture, CC_RECT_PIXELS_TO_POINTS(Rect(0, 0, 113, 113)));//使用第一幀創建精靈player = Sprite::createWithSpriteFrame(frame0);player->setPosition(Vec2(origin.x + visibleSize.width / 2,origin.y + visibleSize.height / 2));addChild(player, 3);//hp條Sprite* sp0 = Sprite::create("hp.png", CC_RECT_PIXELS_TO_POINTS(Rect(0, 320, 420, 47)));Sprite* sp = Sprite::create("hp.png", CC_RECT_PIXELS_TO_POINTS(Rect(610, 362, 4, 16)));//使用hp條設置progressBarpT = ProgressTimer::create(sp);pT->setScaleX(90);pT->setAnchorPoint(Vec2(0, 0));pT->setType(ProgressTimerType::BAR);pT->setBarChangeRate(Point(1, 0));pT->setMidpoint(Point(0, 1));pT->setPercentage(100);pT->setPosition(Vec2(origin.x + 14 * pT->getContentSize().width, origin.y + visibleSize.height - 2 * pT->getContentSize().height));addChild(pT, 1);sp0->setAnchorPoint(Vec2(0, 0));sp0->setPosition(Vec2(origin.x + pT->getContentSize().width, origin.y + visibleSize.height - sp0->getContentSize().height));addChild(sp0, 0);// 靜態動畫idle.reserve(1);idle.pushBack(frame0);// 攻擊動畫attack.reserve(17);for (int i = 0; i < 17; i++) {auto frame = SpriteFrame::createWithTexture(texture, CC_RECT_PIXELS_TO_POINTS(Rect(113 * i, 0, 113, 113)));attack.pushBack(frame);}//這里又加入了frame0,原因是,動作結束之后要處理靜止狀態,而不是動作結束之后的狀態attack.pushBack(frame0);auto attackAnimation = Animation::createWithSpriteFrames(attack, 0.1f);AnimationCache::getInstance()->addAnimation(attackAnimation, "attack");// 可以仿照攻擊動畫// 死亡動畫(幀數:22幀,高:90,寬:79)auto texture2 = Director::getInstance()->getTextureCache()->addImage("$lucia_dead.png");// Tododead.reserve(22);for (int i = 0; i < 22; i++) {auto frame = SpriteFrame::createWithTexture(texture2, CC_RECT_PIXELS_TO_POINTS(Rect(79 * i, 0, 79, 90)));dead.pushBack(frame);}dead.pushBack(frame0);auto deadAnimation = Animation::createWithSpriteFrames(dead, 0.1f);AnimationCache::getInstance()->addAnimation(deadAnimation, "dead");// 運動動畫(幀數:8幀,高:101,寬:68)auto texture3 = Director::getInstance()->getTextureCache()->addImage("$lucia_forward.png");// Todorun.reserve(8);for (int i = 0; i < 2; i++) {auto frame = SpriteFrame::createWithTexture(texture3, CC_RECT_PIXELS_TO_POINTS(Rect(68 * i, 0, 68, 101)));run.pushBack(frame);}run.pushBack(frame0);auto runAnimation = Animation::createWithSpriteFrames(run, 0.1f);AnimationCache::getInstance()->addAnimation(runAnimation, "run");auto menu = Menu::create();menu->setPosition(80, 50);addChild(menu);//參考以往代碼,感覺這樣寫比較好auto createDirectionLabel = [this, &menu](string c) {int x = 0, y = 0;auto label = Label::create(c, "arial", 36);auto menuItem = MenuItemLabel::create(label, CC_CALLBACK_1(HelloWorld::moveCallback, this, c));if (c == "W") {y += 1.2 * label->getContentSize().height;}else if (c == "A") {x -= 1.5 * label->getContentSize().width;}else if (c == "D") {x += 1.5 * label->getContentSize().width;}menuItem->setPosition(x, y);menu->addChild(menuItem);};//創建方向鍵createDirectionLabel("W");createDirectionLabel("S");createDirectionLabel("A");createDirectionLabel("D");//X按鈕auto labelX = Label::create("X", "fonts/arial.ttf", 36);auto menuItem = MenuItemLabel::create(labelX, CC_CALLBACK_1(HelloWorld::attackCallback, this));menuItem->setPosition(origin.x + visibleSize.width - 120, -15);menu->addChild(menuItem);//Y按鈕auto labelY = Label::create("Y", "fonts/arial.ttf", 36);menuItem = MenuItemLabel::create(labelY, CC_CALLBACK_1(HelloWorld::deadCallback, this));menuItem->setPosition(origin.x + visibleSize.width - 100, 15);menu->addChild(menuItem);//倒計時time = Label::createWithTTF("180", "fonts/arial.ttf", 36);time->setPosition(origin.x + visibleSize.width / 2, origin.y + visibleSize.height -50);addChild(time);//每一秒時間減少一schedule(schedule_selector(HelloWorld::update), 1.0f);return true; }void HelloWorld::moveCallback(Ref* pSender, string direction) {auto position = player->getPosition();//事實證明,在區間(0,visibleSize.width)之間還是會出界,所以再縮小一點if (isAnimating == false && ((position.x > 50 && direction == "A") || (position.x < visibleSize.width-50 && direction == "D") || (position.y > 50 && direction == "S") || (position.y < visibleSize.height-50 && direction == "W"))) {isAnimating = true;int x, y;if (direction == "W") {x = 0;y = 50;}else if (direction == "A") {x = -50;y = 0;}else if (direction == "S") {x = 0;y = -50;}else if (direction == "D") {x = 50;y = 0;}//移動和動畫是同時執行的auto spawn = Spawn::createWithTwoActions(Animate::create(AnimationCache::getInstance()->getAnimation("run")), MoveBy::create(0.5f, Vec2(x, y)));//執行完之后要將isAnimating置為falseauto sequence = Sequence::create(spawn, CCCallFunc::create(([this]() { isAnimating = false; })), nullptr);player->runAction(sequence);}return; }/* 實現攻擊動作,攻擊工作結束將isAnimating置為false 加分項是實現血條的變化 */ void HelloWorld::attackCallback(Ref * pSender) {if (isAnimating == false) {isAnimating = true;auto sequence = Sequence::create(Animate::create(AnimationCache::getInstance()->getAnimation("attack")),CCCallFunc::create(([this]() {isAnimating = false;})), nullptr);player->runAction(sequence);float percentage = pT->getPercentage();if (percentage < 100) {auto to = ProgressFromTo::create(1.0f, percentage, percentage + 20);pT->runAction(to);}}}/* 死亡動作的實現 */ void HelloWorld::deadCallback(Ref * pSender) {if (isAnimating == false) {isAnimating = true;auto sequence = Sequence::create(Animate::create(AnimationCache::getInstance()->getAnimation("dead")),CCCallFunc::create(([this]() {isAnimating = false;})), nullptr);player->runAction(sequence);float percentage = pT->getPercentage();if (percentage > 0) {auto to = ProgressFromTo::create(2.0f, percentage, percentage - 20);pT->runAction(to);}} }/* update實現倒計時的功能,其中開始的值是180 需要每秒減一,所以需要拿到當前的值,并且減一再賦值回去 其中需要int和string的相互轉換 由于是cocos2d,還有一個新的類型是CCString 這三者之間的轉換參考下面鏈接 https://www.cnblogs.com/leehongee/p/3642308.html */void HelloWorld::update(float dt) {string str = time->getString();int timeLength = atoi(str.c_str());if (timeLength > 0) {timeLength--;CCString* ns = CCString::createWithFormat("%d", timeLength);string s = ns->_string;time->setString(s);}else {unschedule(schedule_selector(HelloWorld::update));} }HelloWorldScene.h
#pragma once #include "cocos2d.h" using namespace cocos2d;class HelloWorld : public cocos2d::Scene { public:static cocos2d::Scene* createScene();virtual bool init();// implement the "static create()" method manuallyCREATE_FUNC(HelloWorld); private:cocos2d::Sprite* player;cocos2d::Vector<SpriteFrame*> attack;cocos2d::Vector<SpriteFrame*> dead;cocos2d::Vector<SpriteFrame*> run;cocos2d::Vector<SpriteFrame*> idle;cocos2d::Size visibleSize;cocos2d::Vec2 origin;cocos2d::Label* time;int dtime;cocos2d::ProgressTimer* pT;//判斷是否在播放動作bool isAnimating;//移動void moveCallback(Ref* pSender, std::string direction);//攻擊void attackCallback(Ref* pSender);//死亡void deadCallback(Ref* pSender);//重寫update,實現倒計時void update(float time)override; };視頻演示以及資源
視頻演示以及資源
總結
以上是生活随笔為你收集整理的Cocos2d-x简单横版游戏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTML小游戏14 —— H5横版冒险游
- 下一篇: 【独立游戏】Sunset——二次元横版动