【Cocos游戏实战】功夫小子第七课之游戏主功能场景逻辑功能和暂停功能场景的分析和实现
CSDN的markdown编辑器是吃屎了么!
!。什么玩意。!写了一半写不了东西还全没了,搞个毛线!
本节课的视频教程地址是:第七课在此
假设本教程有帮助到您,希望您能点击进去观看一下,并且如今注冊成为极客学院的会员,能够免费领取30天学习时间,免费拿极客学院VIP,1000+高清视频。学习Android、HTML5、iOS各种开发技术,限时领取。手快的戳:http://e.jikexueyuan.com/invite/index.html?ZnJvbV9jb2RlPVkxblJUZSZ1bmFtZT1TdW9vTCZjaGFubmVsPWludml0ZV8xMDB3X3NoYXJlYnV0dG9uX2RpcmVjdDE=。验证手机号码和邮箱号码会赠送三天的会员时间。手机端首次也能够领取五天的会员时间哦(即使是购买年会员眼下也不过年费260)。成为极客学院学习会员能够无限制的下载和观看全部的学院站点的视频。谢谢您的支持!
转载请注明出处:http://blog.csdn.net/suool/article/details/47128637
不想再重写一遍了。简短点。这节课要实现和学习的内容有:(假设想看具体内容的请戳上面的连接,看下视频的教程更好)
1.人物的运动状态控制——跳起。受伤,死亡推断。和怪物的打斗逻辑
2.碰撞检測(我们这个游戏因为是横版且人物仅仅可以在左右走。因此变化的坐标仅仅有X,所以检測起来也是非常easy的。
)
很多其它关于碰撞检測的东西见:http://shahdza.blog.51cto.com/2410787/1548097
3.关卡的失败和胜利推断以及相关的场景的分析和实现
4.暂停功能场景的分析和实现
关于跳起的动作这里简单的解释一下。
由于要模拟人物跳起后的一个近抛物线的运动轨迹,因此我们这里让Y轴的速度不断变化,而X轴不变,这个原理学过高中物理应该都明确。
这个函数就是:
float velocity = 0.0f; // 跳起速度
float getVelocity(); // 获取跳跃的速度
逻辑的东西解释起来比較复杂,先把代码贴出来吧。
/*!
* \file GameLayer.h
* \date 2015/06/13 16:55
*
* \author SuooL
* Contact: hu1020935219@gmail.com
*
* \brief 游戏场景
*
* TODO: long description
*
* \note
*/ #ifndef __GameLayer__H__
#define __GameLayer__H__ #include <iostream>
#include "cocos2d.h"
#include "SimpleAudioEngine.h"
#include "ActionTool.h"
#include "GlobalData.h"
#include "GlobalDefine.h"
#include "extensions/cocos-ext.h"
#include "Monster.h" USING_NS_CC;
using namespace extension; class Hero;
class ProgressBar;
class GameMap; class GameLayer : public Layer
{
public: static Scene* createScene();
virtual bool init(); // 暂停
void gamePause(Ref* pSender); void gameOver(float delta);
void gameVictory(float delta);
// 技能--拳击--脚踢--超级技能--蹦
void fistAttack(Ref* pSender, Control::EventType type);
void footAttack(Ref* psender, Control::EventType type);
void comboAttack(Ref* pSender, Control::EventType type);
void jump(Ref* pSender, Control::EventType type); // 前进,后退
void forward(Ref* pSender, Control::EventType type);
void backward(Ref* pSender, Control::EventType type); bool isAttackMonster(Hero * hero, Monster* monster); virtual void update(float delta); CREATE_FUNC(GameLayer); private: // 英雄&怪物
Hero* m_pHero;
Monster* m_pMonster1; GameMap* myMap; // 背景条
Sprite* m_pBG;
// 血条。能量前景条
ProgressTimer* m_pHPBar;
ProgressTimer* m_pMPBar; ControlButton * m_pComboBtn;
Sprite* m_pComboPic; RenderTexture* render;
RenderTexture* renderResult; float velocity = 0.0f; // 跳起速度
float getVelocity(); // 获取跳跃的速度 bool m_bDirection; // 行走的方向
bool m_bRun; // 是否在跑
bool m_bJump; // 是否在跳 }; #endif
实现文件为:
/*!
* \class GameLayer
*
* \ingroup GroupName
*
* \brief
*
* TODO: long description
*
* \note
*
* \author SuooL
*
* \version 1.0
*
* \date 六月 2015
*
* Contact: hu1020935219@gmail.com
*
*/
#include "GameLayer.h"
#include "GameMap.h"
#include "Hero.h"
#include "Monster.h"
#include "PauseLayer.h"
#include "GateMapLayer.h"
#include "MonsterOne.h"
#include "extensions/cocos-ext.h"
#include "cocostudio/CocoStudio.h" USING_NS_CC;
using namespace CocosDenshion;
using namespace cocos2d::extension; //引用cocos2d::extension命名空间 Scene* GameLayer::createScene()
{
Scene* scene = Scene::create();
GameLayer* layer = GameLayer::create();
scene->addChild(layer); return scene;
} bool GameLayer::init()
{
if (!Layer::init())
{
return false;
} if (getBoolFromXML(MUSIC_KEY))
{
float music = getFloatFromXML(MUSICVOL)*100.0f;
aduioEngine->setBackgroundMusicVolume(getFloatFromXML(MUSICVOL));
if (SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying())
{
aduioEngine->pauseBackgroundMusic();
aduioEngine->playBackgroundMusic("Sound/gameBGM.wav", true);
}
else
aduioEngine->playBackgroundMusic("Sound/gameBGM.wav", true);
}
else
aduioEngine->pauseBackgroundMusic(); velocity = 10.0f;
m_bDirection = false;
m_bRun = false;
m_bJump = false; SpriteFrameCache::getInstance()->addSpriteFramesWithFile("pnglist/mapBefore.plist");
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("pnglist/mapRoad.plist"); String *bgName = String::createWithFormat("bgmap%d.png", m_iSelectGate);
String *midName = String::createWithFormat("MapMiddle%d.png", m_iSelectGate);
String *groundName = String::createWithFormat("MapGround%d.png", m_iSelectGate);
String *beforeName = String::createWithFormat("MapBefore%d.png", m_iSelectGate);
String *comoboName = String::createWithFormat("comboBtn%d.png", m_iSelectGate); auto bgPic = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(bgName->getCString()));
bgPic->setPosition(WINSIZE.width / 2, WINSIZE.height / 2);
this->addChild(bgPic, 0);
myMap = GameMap::create();
myMap->InitMap(midName->getCString(), groundName->getCString(), beforeName->getCString());
this->addChild(myMap, 1); // 界面控制键初始化
// 技能键
auto m_pFistBG = Scale9Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("fist.png"));
auto m_pFistBtn = ControlButton::create(m_pFistBG);
m_pFistBtn->setPreferredSize(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("fist.png"))->getContentSize()); auto m_pFootBG = Scale9Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("foot.png"));
auto m_pFootBtn = ControlButton::create(m_pFootBG);
m_pFootBtn->setPreferredSize(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("foot.png"))->getContentSize()); auto m_pJumpBG = Scale9Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("jump.png"));
auto m_pJumpBtn = ControlButton::create(m_pJumpBG);
m_pJumpBtn->setPreferredSize(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("jump.png"))->getContentSize()); auto m_pComboBG = Scale9Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(comoboName->getCString()));
m_pComboBtn = ControlButton::create(m_pComboBG);
m_pComboBtn->setPreferredSize(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(comoboName->getCString()))->getContentSize()); // 按键背景
auto m_pFistPic = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("quan.png"));
auto m_pFootPic = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("jiao.png"));
auto m_pJumpPic = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("tiao.png"));
m_pComboPic = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("tiao.png")); auto m_pFistPicSize = m_pFistPic->getContentSize();
m_pFistBtn->setPosition(ccp(m_pFistPicSize.width / 2, m_pFistPicSize.height / 2));
m_pFistBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(GameLayer::fistAttack), Control::EventType::TOUCH_UP_INSIDE); auto m_pFootPicSize = m_pFootPic->getContentSize();
m_pFootBtn->setPosition(ccp(m_pFootPicSize.width / 2, m_pFootPicSize.height / 2));
m_pFootBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(GameLayer::footAttack), Control::EventType::TOUCH_UP_INSIDE); auto m_pJumpPicSize = m_pJumpPic->getContentSize();
m_pJumpBtn->setPosition(ccp(m_pJumpPicSize.width / 2.0 - 1.5, m_pJumpPicSize.height / 2));
m_pJumpBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(GameLayer::jump), Control::EventType::TOUCH_UP_INSIDE); auto m_pComboPicSize = m_pComboPic->getContentSize();
m_pComboBtn->setPosition(ccp(m_pComboPicSize.width / 2 - 1.5, m_pComboPicSize.height / 2));
m_pComboBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(GameLayer::comboAttack), Control::EventType::TOUCH_UP_INSIDE); m_pFistPic->addChild(m_pFistBtn, 1);
m_pFootPic->addChild(m_pFootBtn, 1);
m_pJumpPic->addChild(m_pJumpBtn, 1);
m_pComboPic->addChild(m_pComboBtn, 1); m_pFistPic->setPosition(WINSIZE.width - 230, 76);
m_pFootPic->setPosition(WINSIZE.width - 73, 76);
m_pJumpPic->setPosition(WINSIZE.width - 60, 220);
m_pComboPic->setPosition(WINSIZE.width - 387, 76); m_pComboPic->setVisible(false); this->addChild(m_pFistPic, 1);
this->addChild(m_pFootPic, 1);
this->addChild(m_pJumpPic, 1);
this->addChild(m_pComboPic, 1); // 行走控制键。暂停键
auto puaseGameItem = MenuItemSprite::create(
Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("pauseNormal.png")),
Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("pauseSelected.png")),
CC_CALLBACK_1(GameLayer::gamePause, this)); // Pause auto backwardBG = Scale9Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("directionNormal.png"));
auto backwardSelBG = Scale9Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("directionSelected.png"));
auto backwardBtn = ControlButton::create(backwardBG);
backwardBtn->setBackgroundSpriteForState(backwardSelBG, Control::State::HIGH_LIGHTED);
backwardBtn->setZoomOnTouchDown(false);
backwardBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(GameLayer::backward), Control::EventType::TOUCH_DOWN);
backwardBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(GameLayer::backward), Control::EventType::TOUCH_UP_INSIDE);
backwardBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(GameLayer::backward), Control::EventType::DRAG_OUTSIDE);
backwardBtn->setPreferredSize(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("directionNormal.png"))->getContentSize()); auto forwardBG = Scale9Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("directForNor.png"));
auto forwardSelBG = Scale9Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("directForSel.png"));
auto forwardBtn = ControlButton::create(forwardBG);
forwardBtn->setBackgroundSpriteForState(forwardSelBG, Control::State::HIGH_LIGHTED);
forwardBtn->setZoomOnTouchDown(false);
forwardBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(GameLayer::forward), Control::EventType::TOUCH_DOWN);
forwardBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(GameLayer::forward), Control::EventType::TOUCH_UP_INSIDE);
forwardBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(GameLayer::forward), Control::EventType::DRAG_OUTSIDE);
forwardBtn->setPreferredSize(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("directForNor.png"))->getContentSize()); puaseGameItem->setPosition(WINSIZE.width - 50, WINSIZE.height - 48);
backwardBtn->setPosition(117, 70);
forwardBtn->setPosition(304, 70); auto menuWalk = Menu::create(puaseGameItem, NULL);
menuWalk->setPosition(Point::ZERO);
this->addChild(backwardBtn, 1);
this->addChild(forwardBtn, 1);
this->addChild(menuWalk, 1); // 状态条
m_pBG = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("barGround.png")); m_pHPBar = ProgressTimer::create(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("HPBar.png")));
m_pHPBar->setType(ProgressTimer::Type::BAR);
m_pHPBar->setMidpoint(ccp(0, 0.5));
m_pHPBar->setBarChangeRate(ccp(1, 0));
m_pHPBar->setPercentage(100); m_pMPBar = ProgressTimer::create(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("MPBar.png")));
m_pMPBar->setType(ProgressTimer::Type::BAR);
m_pMPBar->setMidpoint(ccp(0, 0.5));
m_pMPBar->setBarChangeRate(ccp(1, 0));
m_pMPBar->setPercentage(0); m_pHPBar->setPosition(240, 45);
m_pMPBar->setPosition(226, 30); m_pBG->addChild(m_pHPBar);
m_pBG->addChild(m_pMPBar); m_pBG->setPosition(260, WINSIZE.height - 60); this->addChild(m_pBG, 1); // 英雄
m_pHero = Hero::create();
m_pHero->InitHeroSprite("idle.png", 1);
m_pHero->setPosition(100, 360);
this->addChild(m_pHero, 3); MonsterOne *monster = MonsterOne::createWithMapAndHero(myMap, m_pHero); this->scheduleUpdate();
return true;
} // 拳击
void GameLayer::fistAttack(Ref* pSender, Control::EventType type)
{
if (m_pHero->IsRunning || m_pHero->IsAttack || m_pHero->IsHurt || m_pHero->m_bIsJumping)
{
return;
}
PLAYEFFECT;
m_pHero->AttackAnimation("fist", 0.1f, m_bDirection);
} // 腿击
void GameLayer::footAttack(Ref* psender, Control::EventType type)
{
if (m_pHero->IsRunning || m_pHero->IsAttack || m_pHero->IsHurt || m_pHero->m_bIsJumping)
{
return;
}
PLAYEFFECT;
m_pHero->AttackAnimation("leg", 0.1f, m_bDirection);
} //
void GameLayer::jump(Ref* pSender, Control::EventType type)
{ if (m_pHero->IsRunning || m_pHero->IsAttack || m_pHero->IsHurt || m_bJump)
{
return;
} if (getBoolFromXML(SOUND_KEY))
{
aduioEngine->setEffectsVolume(getFloatFromXML(SOUNDVOL));
aduioEngine->playEffect("Sound/Jump.wav");
} m_bJump = true;
} void GameLayer::comboAttack(Ref* pSender, Control::EventType type)
{
if (m_pHero->IsAttack || m_pHero->m_bIsJumping == true || m_pHero->m_bCanCrazy)
{
return;
}
if (getBoolFromXML(SOUND_KEY))
{
aduioEngine->setEffectsVolume(getFloatFromXML(SOUNDVOL));
aduioEngine->playEffect("Sound/combo.wav");
}
m_pHero->m_bCanCrazy = true;
switch (m_iSelectGate)
{
case 1:
m_pHero->AttackAnimation("combo", 0.1, m_bDirection);
break;
case 2:
m_pHero->AttackAnimation("bakandao", 0.1, m_bDirection);
break;
case 3:
m_pHero->AttackAnimation("gun", 0.1, m_bDirection);
break;
default:
break;
}
} void GameLayer::gamePause(Ref* pSender)
{
//能够直接使用pause方法暂停当前的场景,可是这样做有一个bug,就是不能够屏蔽触摸事件,所以採用截图的方法
//Director::getInstance()->pause(); /*截取当前场景的图片而且保存*/ auto size = Director::getInstance()->getWinSize();
//RenderTexture是一个纹理渲染类,我们须要把要渲染的当前场景放进去,这是初始化它的大小
render = RenderTexture::create(size.width, size.height);
//開始获取内容
render->begin();
//是用节点的visit方法增加到渲染中
Director::getInstance()->getRunningScene()->visit();
//结束
render->end();
render->retain(); //3.0 截屏须要在截完屏的下一帧才干处理RenderTexture,这点要注意
auto _schedule = this->getScheduler();
auto replaceScene = [&](float tm)
{
//最后切换场景
Director::getInstance()->pushScene(PauseLayer::createScene(render));
};
_schedule->schedule(replaceScene, this, 0.0f, 0, 0.0f, false, "screenshot");
} void GameLayer::backward(Ref* pSender, Control::EventType type)
{
if (m_pHero->IsAttack && m_pHero->m_bIsJumping == true)
{
return;
}
switch (type)
{
case cocos2d::extension::Control::EventType::TOUCH_DOWN:
m_bRun = true;
m_bDirection = true;
break;
case cocos2d::extension::Control::EventType::DRAG_INSIDE:
break;
case cocos2d::extension::Control::EventType::DRAG_OUTSIDE:
m_bRun = false;
m_pHero->StopAnimation();
break;
case cocos2d::extension::Control::EventType::DRAG_ENTER:
break;
case cocos2d::extension::Control::EventType::DRAG_EXIT:
break;
case cocos2d::extension::Control::EventType::TOUCH_UP_INSIDE:
m_bRun = false;
m_pHero->StopAnimation();
break;
case cocos2d::extension::Control::EventType::TOUCH_UP_OUTSIDE:
break;
case cocos2d::extension::Control::EventType::TOUCH_CANCEL:
break;
case cocos2d::extension::Control::EventType::VALUE_CHANGED:
break;
default:
break;
}
} void GameLayer::forward(Ref* pSender, Control::EventType type)
{
if (m_pHero->IsAttack && m_pHero->m_bIsJumping == true)
{
return;
}
switch (type)
{
case cocos2d::extension::Control::EventType::TOUCH_DOWN:
m_bRun = true;
m_bDirection = false;
break;
case cocos2d::extension::Control::EventType::DRAG_INSIDE:
break;
case cocos2d::extension::Control::EventType::DRAG_OUTSIDE:
m_bRun = false;
m_pHero->StopAnimation();
break;
case cocos2d::extension::Control::EventType::DRAG_ENTER:
break;
case cocos2d::extension::Control::EventType::DRAG_EXIT:
break;
case cocos2d::extension::Control::EventType::TOUCH_UP_INSIDE:
m_bRun = false;
m_pHero->StopAnimation();
break;
case cocos2d::extension::Control::EventType::TOUCH_UP_OUTSIDE:
break;
case cocos2d::extension::Control::EventType::TOUCH_CANCEL:
break;
case cocos2d::extension::Control::EventType::VALUE_CHANGED:
break;
default:
break;
}
} void GameLayer::gameOver(float delta)
{
// 对声音的处理
if (getBoolFromXML(MUSIC_KEY))
{
float music = getFloatFromXML(MUSICVOL)*100.0f;
aduioEngine->setBackgroundMusicVolume(getFloatFromXML(MUSICVOL));
if (SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying())
{
aduioEngine->pauseBackgroundMusic();
aduioEngine->playBackgroundMusic("Sound/failure.wav", true);
}
else
aduioEngine->playBackgroundMusic("Sound/failure.wav", true);
}
else
aduioEngine->pauseBackgroundMusic();
// 弹出游戏失败的界面
auto bgSprite = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("heiping.png"));
bgSprite->setPosition(WINSIZE.width / 2, WINSIZE.height / 2);
this->addChild(bgSprite, 5);
auto bgTitle = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("bgTitle.png"));
bgTitle->setPosition(WINSIZE.width / 2 + 23, WINSIZE.height / 2 + 17);
auto faliureTitle = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("faliure.png"));
faliureTitle->setPosition(WINSIZE.width / 2, WINSIZE.height / 2 + 227);
auto energyTitle = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("tili.png"));
energyTitle->setPosition(WINSIZE.width / 2, WINSIZE.height / 2 - 23);
auto tips = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("tipsNext.png"));
tips->setPosition(WINSIZE.width / 2, WINSIZE.height / 2 - 227); auto m_pEnergyLabel = LabelTTF::create("- 1", "", 45);
m_pEnergyLabel->setColor(ccc3(0, 255, 255));
m_pEnergyLabel->setPosition(300, 60); bgSprite->addChild(bgTitle);
bgSprite->addChild(faliureTitle);
bgSprite->addChild(energyTitle);
bgSprite->addChild(tips); // 获取事件分发器
auto dispatcher = Director::getInstance()->getEventDispatcher();
// 触摸监听器
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = [](Touch* touch, Event* event){return true; };
listener->onTouchMoved = [](Touch* touch, Event* event){};
listener->onTouchEnded = [](Touch* touch, Event* event){
Director::getInstance()->replaceScene(GateMapLayer::createScene());
};
listener->setSwallowTouches(true);
dispatcher->addEventListenerWithSceneGraphPriority(listener, bgSprite);
} void GameLayer::gameVictory(float delta)
{
// 对声音的处理
if (getBoolFromXML(MUSIC_KEY))
{
float music = getFloatFromXML(MUSICVOL)*100.0f;
aduioEngine->setBackgroundMusicVolume(getFloatFromXML(MUSICVOL));
if (SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying())
{
aduioEngine->pauseBackgroundMusic();
aduioEngine->playBackgroundMusic("Sound/victory.wav", true);
}
else
aduioEngine->playBackgroundMusic("Sound/victory.wav", true);
}
else
aduioEngine->pauseBackgroundMusic(); if (m_iSelectGate == 1)
{
setBoolToXML(GATEONE, true);
}
else if (m_iSelectGate == 2)
{
setBoolToXML(GATETWO, true);
}
else
setBoolToXML(GATETHREE, true); // 弹出游戏胜利的界面
auto bgSprite = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("heiping.png"));
bgSprite->setPosition(WINSIZE.width / 2, WINSIZE.height / 2);
this->addChild(bgSprite, 5);
auto bgTitle = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("bgTitle.png"));
bgTitle->setPosition(WINSIZE.width / 2 + 23, WINSIZE.height / 2 + 17);
auto victoryTitle = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("victory.png"));
victoryTitle->setPosition(WINSIZE.width / 2, WINSIZE.height / 2 + 227);
auto energyTitle = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("tili.png"));
energyTitle->setPosition(WINSIZE.width / 2 + 116, WINSIZE.height / 2 - 23);
auto moneyTitle = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("jinbi.png"));
moneyTitle->setPosition(WINSIZE.width / 2 - 275, WINSIZE.height / 2 - 27);
auto tips = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("tipsNext.png"));
tips->setPosition(WINSIZE.width / 2, WINSIZE.height / 2 - 227);
bgSprite->addChild(bgTitle);
bgSprite->addChild(victoryTitle);
bgSprite->addChild(energyTitle);
bgSprite->addChild(moneyTitle);
bgSprite->addChild(tips); // 获取事件分发器
auto dispatcher = Director::getInstance()->getEventDispatcher();
// 触摸监听器
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = [](Touch* touch, Event* event){return true; };
listener->onTouchMoved = [](Touch* touch, Event* event){};
listener->onTouchEnded = [](Touch* touch, Event* event){
Director::getInstance()->replaceScene(GateMapLayer::createScene());
};
listener->setSwallowTouches(true);
dispatcher->addEventListenerWithSceneGraphPriority(listener, bgSprite);
} bool GameLayer::isAttackMonster(Hero * hero, Monster* monster)
{
bool hero_dire = hero->HeroDirecton;
bool monster_dire = monster->MonsterDirecton;
float hero_x = hero->getPositionX();
float monster_x = monster->getPositionX() + myMap->getPositionX();
if (hero_dire)
{
if (monster_x <= hero_x)
{
return true;
}
}
else
{
if (monster_x >= hero_x)
{
return true;
}
} return false;
} float GameLayer::getVelocity()
{
velocity = velocity - 0.3f;
return velocity;
} void GameLayer::update(float delta)
{
// 人物跳起
if (m_bJump)
{
getVelocity(); if (velocity >= 0.1) // 速度不为0
{
m_pHero->JumpUpAnimation("jumpup", 0.1f, m_bDirection);
if (m_bDirection == false)
{
if (m_pHero->getPositionX() <= WINSIZE.width - 8)//不让精灵超出右边,8能够改成你喜欢的
{
if (!m_pHero->JudgePosition(WINSIZE) || myMap->JudgeMap(m_pHero)) //精灵没到达窗体中间位置或者地图已经移动到边缘了,精灵才干够移动。否则仅仅播放动画
m_pHero->setPosition(ccp(m_pHero->getPosition().x + m_pHero->m_iSpeed, m_pHero->getPosition().y + velocity)); //向右走
else
{
m_pHero->setPosition(ccp(m_pHero->getPosition().x, m_pHero->getPosition().y + velocity)); //向左走
}
//以下是移动地图
myMap->MoveMap(m_pHero);
}
else
m_pHero->setPosition(ccp(m_pHero->getPosition().x, m_pHero->getPosition().y + velocity)); //向左走
}
else
{
if (m_pHero->getPositionX() >= 8)//不让精灵超出左边,8能够改成你喜欢的
{
if (!m_pHero->JudgePosition(WINSIZE) || myMap->JudgeMap(m_pHero))//精灵没到达窗体中间位置或者地图已经移动到边缘了,精灵才干够移动,否则仅仅播放动画
m_pHero->setPosition(ccp(m_pHero->getPosition().x - m_pHero->m_iSpeed, m_pHero->getPosition().y + velocity)); //向左走
else
{
m_pHero->setPosition(ccp(m_pHero->getPosition().x, m_pHero->getPosition().y + velocity)); //向左走
}
//以下是移动地图
myMap->MoveMap(m_pHero);
}
else
m_pHero->setPosition(ccp(m_pHero->getPosition().x, m_pHero->getPosition().y + velocity)); //向左走
} }
else
{
m_pHero->JumpDownAnimation("jumpdown", 0.1f, m_bDirection);
if (m_bDirection == false)
{
if (m_pHero->getPositionX() <= WINSIZE.width - 8)//不让精灵超出右边,8能够改成你喜欢的
{
if (!m_pHero->JudgePosition(WINSIZE) || myMap->JudgeMap(m_pHero))//精灵没到达窗体中间位置或者地图已经移动到边缘了,精灵才干够移动。否则仅仅播放动画
m_pHero->setPosition(ccp(m_pHero->getPosition().x + m_pHero->m_iSpeed, m_pHero->getPosition().y + velocity)); //向右走
else
{
m_pHero->setPosition(ccp(m_pHero->getPosition().x, m_pHero->getPosition().y + velocity)); //向左走
}
//以下是移动地图
myMap->MoveMap(m_pHero);
}
else
m_pHero->setPosition(ccp(m_pHero->getPosition().x, m_pHero->getPosition().y + velocity)); //向左走
}
else
{
if (m_pHero->getPositionX() >= 8)//不让精灵超出左边,8能够改成你喜欢的
{
if (!m_pHero->JudgePosition(WINSIZE) || myMap->JudgeMap(m_pHero))//精灵没到达窗体中间位置或者地图已经移动到边缘了。精灵才干够移动。否则仅仅播放动画
m_pHero->setPosition(ccp(m_pHero->getPosition().x - m_pHero->m_iSpeed, m_pHero->getPosition().y + velocity)); //向左走
else
{
m_pHero->setPosition(ccp(m_pHero->getPosition().x, m_pHero->getPosition().y + velocity)); //向左走
}
//以下是移动地图
myMap->MoveMap(m_pHero);
}
else
m_pHero->setPosition(ccp(m_pHero->getPosition().x, m_pHero->getPosition().y + velocity)); //向左走
}
} if (m_pHero->getPositionY() <= 359)
{
m_pHero->JumpEnd();
m_pHero->setPosition(ccp(m_pHero->getPosition().x + 3, 360));
velocity = 10.0f;
m_bJump = false;
}
} // 人物移动
if (m_bRun && m_bDirection == false && m_pHero->IsHurt == false && m_pHero->IsAttack == false && m_pHero->m_bIsJumping == false)
{
m_pHero->SetAnimation("run", 0.07f, m_bDirection);
if (m_pHero->getPositionX() <= WINSIZE.width - 8)//不让精灵超出右边,8能够改成你喜欢的
{
if (!m_pHero->JudgePosition(WINSIZE) || myMap->JudgeMap(m_pHero))//精灵没到达窗体中间位置或者地图已经移动到边缘了。精灵才干够移动,否则仅仅播放动画
m_pHero->setPosition(ccp(m_pHero->getPosition().x + m_pHero->m_iSpeed, m_pHero->getPosition().y)); //向右走
//以下是移动地图
myMap->MoveMap(m_pHero);
}
}
else if (m_bRun && m_bDirection == true && m_pHero->IsHurt == false && m_pHero->m_bIsJumping == false)
{
m_pHero->SetAnimation("run", 0.07f, m_bDirection);
if (m_pHero->getPositionX() >= 8)//不让精灵超出左边,8能够改成你喜欢的
{
if (!m_pHero->JudgePosition(WINSIZE) || myMap->JudgeMap(m_pHero))//精灵没到达窗体中间位置或者地图已经移动到边缘了,精灵才干够移动,否则仅仅播放动画
m_pHero->setPosition(ccp(m_pHero->getPosition().x - m_pHero->m_iSpeed, m_pHero->getPosition().y)); //向右走
//以下是移动地图
myMap->MoveMap(m_pHero);
}
} // 主角和怪物攻击碰撞检測
if (m_pHero->IsAttack)
{
for (auto monster : monsterShowList)
{
// 怪物没死
if (monster->Isdead == false && isAttackMonster(m_pHero, monster) && m_pHero->m_bIsJumping == false)
{
// 得到两点x的距离, 记得怪物的坐标要加上地图的
float x = m_pHero->getPositionX() - (monster->getPositionX() + myMap->getPositionX()); //先计算怪物和英雄的距离
auto dis = fabs(x);
if (dis <= 150)
{
if (monster->m_iType == 1)
{
monster->HurtAnimation("monsterHurt", monster->MonsterDirecton, 0.2f, 1);
}
else if (monster->m_iType == 2)
{
monster->HurtAnimation("lionHurt", monster->MonsterDirecton, 0.2f, 1);
}
else
{
monster->HurtAnimation("stoneHurt", monster->MonsterDirecton, 0.2f, 1);
}
}
// if (this->isRectCollision(CCRectMake(m_pHero->getPositionX(), m_pHero->getPositionY(), m_pHero->GetSprite()->getContentSize().width-30, m_pHero->GetSprite()->getContentSize().height-20),
// CCRectMake(monster->getPositionX(), monster->getPositionY(), monster->GetSprite()->getContentSize().width - 30, monster->GetSprite()->getContentSize().height - 20)))
// {
// monster->HurtAnimation("monsterHurt", monster->MonsterDirecton, 0.2f, 1);
// }
}
}
} for (auto monster : monsterShowList)
{
if (!monster->Isdead)
{
if (monster->IsAttack && m_pHero->IsDead == false && m_pHero->m_bIsJumping == false)
{
// 得到两点x的距离, 记得怪物的坐标要加上地图的
float x = m_pHero->getPositionX() - (monster->getPositionX() + myMap->getPositionX()); //先计算怪物和英雄的距离
auto dis = fabs(x);
if (dis <= 130)
{
m_pHero->HurtByMonsterAnimation("hurt", 0.2f, m_bDirection);
m_pHPBar->setPercentage(m_pHero->percentage);
}
}
}
} m_pMPBar->setPercentage(m_pHero->m_iCurrentMp);
if (m_pMPBar->getPercentage() >= 100)
{
m_pComboPic->setVisible(true);
}
else
{
m_pComboPic->setVisible(false);
} // 主角和怪物攻击碰撞检測
if (m_pHero->IsAttack && m_pHero->m_bCanCrazy)
{
for (auto monster : monsterShowList)
{
// 怪物没死
if (monster->Isdead == false && isAttackMonster(m_pHero, monster) && m_pHero->m_bIsJumping == false)
{
// 得到两点x的距离, 记得怪物的坐标要加上地图的
float x = m_pHero->getPositionX() - (monster->getPositionX() + myMap->getPositionX()); //先计算怪物和英雄的距离
auto dis = fabs(x);
if (dis <= 350)
{
monster->HurtAnimation("monsterHurt", monster->MonsterDirecton, 0.2f, 1);
}
// if (this->isRectCollision(CCRectMake(m_pHero->getPositionX(), m_pHero->getPositionY(), m_pHero->GetSprite()->getContentSize().width-30, m_pHero->GetSprite()->getContentSize().height-20),
// CCRectMake(monster->getPositionX(), monster->getPositionY(), monster->GetSprite()->getContentSize().width - 30, monster->GetSprite()->getContentSize().height - 20)))
// {
// monster->HurtAnimation("monsterHurt", monster->MonsterDirecton, 0.2f, 1);
// }
}
}
} // 游戏结束判定
if (m_pHero->IsDead)
{
// 游戏结束
this->scheduleOnce(schedule_selector(GameLayer::gameOver), 1.0f);
this->unscheduleUpdate();
}
// 怪物全死
if (m_bFlag3 == false)
{
bool noMonster = true;
for (auto monster : monsterShowList)
{
if (!monster->Isdead)
{
noMonster = false;
}
}
if (noMonster)
{
this->scheduleOnce(schedule_selector(GameLayer::gameVictory), 2.0f);
this->unscheduleUpdate();
}
}
}
关于暂停场景的实现例如以下,由于暂停要实现一个动态的开关效果,并且背景是游戏暂停的场景。所以做了一个截图,传递给这个场景,代码实现例如以下:
/*!
* \file PauseLayer.h
*
* \author SuooL
* \date 六月 2015
*
* 暂停界面
*/ #ifndef __PauseLayer__H__
#define __PauseLayer__H__
#include "cocos2d.h"
#include "extensions/cocos-ext.h" USING_NS_CC;
using namespace cocos2d::extension; class PauseLayer : public Layer {
public:
static Scene* createScene(RenderTexture* rt);
virtual bool init();
CREATE_FUNC(PauseLayer); Sprite* spriteOn;
Sprite* spriteDown; void musicSet(Ref* pSender); private: }; #endif
实现文件为:
/*!
* \file PauseLayer.cpp
* \date 2015/04/08 15:30
*
* \author SuooL
* Contact: 1020935219@qq.com
*
* \brief 暂停界面
*
* \version 1.0
*
* TODO: long description
*
* \note
*/
#include "PauseLayer.h"
#include "GlobalDefine.h"
#include "GlobalData.h"
#include "GameLayer.h"
#include "StartLayer.h"
#include "cocos2d.h"
#include "extensions/cocos-ext.h" USING_NS_CC;
using namespace cocos2d::extension; Scene* PauseLayer::createScene(RenderTexture* rt)
{
Scene* scene = Scene::create();
PauseLayer* layer = PauseLayer::create(); auto sprite = Sprite::createWithTexture(rt->getSprite()->getTexture());
sprite->setPosition(WINSIZE.width / 2, WINSIZE.height / 2);
sprite->setFlippedY(true);
// sprite->setColor(cocos2d::ccGRAY);
scene->addChild(sprite, 0); scene->addChild(layer); return scene;
} bool PauseLayer::init()
{
if (!Layer::init())
{
return false;
} auto size = Director::getInstance()->getWinSize(); // 背景黑色的图片
spriteOn = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("pauseBG1.png"));
spriteDown = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("pauseBG2.png"));
spriteOn->setPosition(size.width / 2, size.height + spriteOn->getContentSize().height / 2);
spriteDown->setPosition(size.width / 2, - (spriteDown->getContentSize().height / 2));
this->addChild(spriteOn);
this->addChild(spriteDown); /*
继续游戏button: X:630.5 Y349.0
声音按键:X:190.0 Y294.0
重置键button:X346.0 Y:294.0
返回关卡界面键button:X890.0 Y:294.0
下一关键button:X1053.0 Y:294.0
*/
// 继续游戏button
auto resumeItem = MenuItemSprite::create(
Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("playNormal.png")),
Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("playSelected.png")),
[&](Ref * ref){
PLAYEFFECT;
//弹出保存的场景
auto moveOn = MoveBy::create(0.5f, Point(0, (spriteOn->getContentSize().height)));
auto moveDown = MoveBy::create(0.5f, Point(0, -spriteDown->getContentSize().height));
CallFunc* replace = CallFunc::create([](){Director::getInstance()->popScene();});
Action* resume = Sequence::create(moveOn, replace, NULL);
spriteDown->runAction(moveDown);
spriteOn->runAction(resume);
});
resumeItem->setPosition(spriteOn->getContentSize().width / 2-5, 110.0f); // 返回游戏主界面
auto startItem = MenuItemSprite::create(
Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("backNormal.png")),
Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("backSelected.png")),
[](Ref * ref){
PLAYEFFECT;
//弹出保存的场景
Director::getInstance()->replaceScene(StartLayer::createScene());});
startItem->setPosition(890.0f, 180.0f); // 又一次開始游戏
auto againItem = MenuItemSprite::create(
Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("againNormal.png")),
Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("againSelected.png")),
[](Ref * ref){
PLAYEFFECT;
//弹出保存的场景
Director::getInstance()->replaceScene(GameLayer::createScene());});
againItem->setPosition(346.0f, 180.0f);
// 下一关
auto nextItem = MenuItemSprite::create(
Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("nextNormal.png")),
Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("nextSelected.png")),
[](Ref * ref){
PLAYEFFECT;
//弹出保存的场景
if (m_iSelectGate++ < 3)
{
Director::getInstance()->replaceScene(GameLayer::createScene());
}
});
nextItem->setPosition(1053.0f, 180.0f); // 声音设置button
auto musicOn = MenuItemSprite::create(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("musicOn.png")),
Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("musicOff.png")));
auto musicOff = MenuItemSprite::create(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("musicOff.png")),
Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("musicSelected.png")));
auto musciToggle = MenuItemToggle::createWithTarget(this, menu_selector(PauseLayer::musicSet), musicOn, musicOff, NULL);
musciToggle->setPosition(190.0f, 180.0f); auto menu = Menu::create(resumeItem, startItem, againItem, nextItem,musciToggle, NULL);
menu->setPosition(Point::ZERO);
spriteOn->addChild(menu); auto moveDown = MoveBy::create(0.6f, Point(0, - (spriteOn->getContentSize().height)));
auto moveUp = MoveBy::create(0.6f, Point(0, spriteDown->getContentSize().height));
spriteOn->runAction(moveDown);
spriteDown->runAction(moveUp); } void PauseLayer::musicSet(Ref* pSender)
{
PLAYEFFECT;
auto musicTemp = (MenuItemToggle*)pSender;
if (getBoolFromXML(SOUND_KEY))
{
aduioEngine->setEffectsVolume(getFloatFromXML(SOUNDVOL));
aduioEngine->playEffect("");
}
if (musicTemp->getSelectedIndex() == 1)
{
SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
}
else
{
aduioEngine->setBackgroundMusicVolume(getFloatFromXML(MUSICVOL));
SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}
}
代码的凝视已经很具体了。
假设您有不明确的地方能够留言或者邮箱我:1020935219@qq.com
整个project的源代码已经开源,地址是:https://github.com/SuooL/KungfuBoy
下一课将会说明下打包APK和项目打包过程及打包后会出现的一些问题及其解决办法。
【Cocos游戏实战】功夫小子第七课之游戏主功能场景逻辑功能和暂停功能场景的分析和实现的更多相关文章
- 【Cocos游戏实战】功夫小子第八课之游戏打包和相关问题说明
至此,功夫小子系列的Cocos2d-x的实战文章就结束了. 源代码地址: https://github.com/SuooL/KungfuBoy 如须要资源请邮件我 1020935219@qq.com ...
- 【Cocos游戏实战】功夫小子第五课之帮助场景和选关功能的实现
功夫小子之帮助场景和选关功能的实现 转载请注明出处:http://blog.csdn.net/suool/article/details/46661231 本节课的视频教程地址是: hmsr=teac ...
- 【C语言探索之旅】 第二部分第七课:文件读写
内容简介 1.课程大纲 2.第二部分第七课: 文件读写 3.第二部分第八课预告: 动态分配 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏 ...
- 【C语言探索之旅】 第一部分第七课:循环语句
内容简介 1.课程大纲 2.第一部分第七课: 循环语句 3.第一部分第八课预告: 第一个C语言小游戏 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编 ...
- Java 测试驱动开发--“井字游戏” 游戏实战
TDD 介绍 TDD是测试驱动开发(Test-Driven Development)的英文简称,是敏捷开发中的一项核心实践和技术,也是一种设计方法论.TDD的原理是在开发功能代码之前,先编写单元测试用 ...
- Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录
一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...
- Kali Linux Web 渗透测试视频教程— 第七课 OpenVas
Kali Linux Web 渗透测试视频教程— 第七课 OpenVas 文/玄魂 视频教程地址:http://edu.51cto.com/course/course_id-1887.html 目录 ...
- Swift语言实战晋级-第9章 游戏实战-跑酷熊猫-1
学习目标 一.进一步学习Swift的游戏制作 二.掌握SKNode,SKSpriteNode的运用 三.了解SpriteKit的物理系统 四.掌握动作(SKAction)的运用 在这一章,我们要通过制 ...
- Swift游戏实战-跑酷熊猫 14 熊猫打滚
这节内容我们来实现熊猫打滚.思路是这样的,当熊猫起跳时记录他的Y坐标,落到平台上的时候再记录它的Y坐标.两个坐标之间的差要是大于一定数值就判断它从高处落下要进行打滚缓冲.至此跑酷熊猫已经像一个游戏的样 ...
随机推荐
- Object.observe() 观察对象
这个对象方法可以用来异步观察对javascript对象的改动: // Let's say we have a model with data var model = {}; // Which we ...
- [原创]Faster R-CNN论文翻译
Faster R-CNN论文翻译 Faster R-CNN是互怼完了的好基友一起合作出来的巅峰之作,本文翻译的比例比较小,主要因为本paper是前述paper的一个简单改进,方法清晰,想法自然.什 ...
- 新增加的HTTP状态码 -- 103
IETF公布了新的HTTP状态码-103, 总结一下就是提前预加载(css.js)文档,提升用户的访问速度. Summary: a new status code that lets the serv ...
- jQuery_事件学习
一.click事件 click事件----鼠标单击事件 $('.bt').click(function() { alert("本身的事件");}) 当class为bt的div被但单 ...
- Git(1)----Eclipse安装Git插件
一.从官网选择系统版本下载Git并安装 地址:https://git-scm.com/downloads/ 二.打开Eclipse 1. 第一种安装方法: help-->Install New ...
- c#读取并分析sql Server2005数据库日志
用过logExplorer的朋友都会被他强悍的功能吸引,我写过一篇详细的操作文档可以参考http://blog.csdn.net/jinjazz/archive/2008/05/19/2459692. ...
- [转载] 详细讲解Hadoop中的简单数据库HBase
转载自http://www.csdn.net/article/2010-11-28/282614 数据模型 HBase数据库使用了和Bigtable非常相似的数据模型.用户在表格里存储许多数据行.每个 ...
- Python之Threading模块
Thread 先引入一个例子: >>> from threading import Thread,currentThread,activeCount >>> > ...
- 【转】使用PowerDesigner的建模创建升级管理数据库
使用PowerDesigner的建模创建升级管理数据库 PowerDesigner是一种著名的CASE建摸工具,最开始为数据库建模设计,即物理模型(Physical Data Model)用于生成数据 ...
- ssh远程登录,禁止root登录
1,useradd xiaobingpasswd xiaobing (设置密码) 2,禁止root登陆,修改 /etc/ssh/sshd_configPermitRootLogin yes 改为 Pe ...