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坐标.两个坐标之间的差要是大于一定数值就判断它从高处落下要进行打滚缓冲.至此跑酷熊猫已经像一个游戏的样 ...
随机推荐
-
No.23
腓利比书3:19:"他们的结局就是沉沦,他们的神就是自己的肚腹,他们以自己的羞辱为荣耀,专以地上的事为念". 谨记!
-
zTree插件之多选下拉菜单代码
zTree插件之多选下拉菜单代码 css和js <!--ztree树结构--> <link rel="stylesheet" type="text/cs ...
-
union select
union select 联合查询 ,即合并(取交集,结果中没有重复行)前后两个查询:前提是前后查询视图必须拥有相同数量的列,列也必需拥有相同的数据类型. union all select 则取的是两 ...
-
微信开发_微信教程__微信通讯框架V1.0
做个广告先, PHP千人群(6848027) C++群 (1414577) 看雪汇编&反汇编群(15375777) 看雪汇编&反汇编2群(4915800) 转载不一定注明出处,只要推荐 ...
-
ios开发实践之UIDatePicker(已对之前无法解决的问题做了解答)
需求:要做一个生日选择的控件,但除了选择之外还需要自定义几个控件,跟生日选择控件组合一起. 做法:自定义了一个UIImageView,并且作为背景.在这个背景view上再添加其他button和时间选择 ...
-
C# 网上收集的一些所谓的开源项目
C#开源 商业协作和项目管理平台-TeamLab 网络视频会议软件-VMukti 驰骋工作流程引擎-ccflow [免费]正则表达式测试工具-Regex-Tester Windows-Phone-7- ...
-
delphi 利用 InterlockedCompareExchange 实现主线程维一锁等待
在进行资源锁定时,一般是线程之间进行交互,很少需要在主线程也对资源进行锁定. 不过在一些复杂的业务中,存在子线程与主线程的交互,且一些资源也同步在主线程中使用时,主线程资源锁,就有存在的必要. 假定有 ...
-
Quartz.NET 任务调度教程。
https://www.cnblogs.com/yaopengfei/p/9216229.html
-
毫秒转时间(java.js)
SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); GregorianCalendar gc ...
-
asp.net mvc 微信公众号token验证
本人的公众号要申请成为开发者,必须经过token认证.微信公众号的官方代码只列出了PHP代码的实例,明显是歧视.net用户.我用的asp.net mvc中的web api,结果调了好久都没有成功,最后 ...