cocos2dx游戏--欢欢英雄传说--为敌人添加移动和攻击动作

这里主要为敌人添加了一个移动动作和攻击动作。
移动动作是很简略的我动他也动的方式。
攻击动作是很简单的我打他也打的方式。
效果:

代码:

#ifndef __Progress__
#define __Progress__
#include "cocos2d.h"
USING_NS_CC;

class Progress : public Sprite
{
public:
    bool init(const char* background, const char* fillname);
    /*
    the inputs are SpriteFrame Names.
    they should be loaded into SpriteFrameCache before calling this.
    */
    static Progress* create(const char* background, const char* fill);

    void setFill(ProgressTimer* fill){_fill=fill;}

    void setProgress(float percentage){_fill->setPercentage(percentage);}
    float getProgress() { return _fill->getPercentage(); }

private:
    ProgressTimer* _fill;
};
#endif

Progress.h

#include "Progress.h"

bool Progress::init(const char* background, const char* fillname)
{
    this->initWithSpriteFrameName(background);
    ProgressTimer* fill = ProgressTimer::create(Sprite::createWithSpriteFrameName(fillname));
    this->setFill(fill);
    this->addChild(fill);

    fill->setType(ProgressTimer::Type::BAR);
    fill->setMidpoint(Point(0,0.5));
    fill->setBarChangeRate(Point(1.0, 0));
    fill->setPosition(this->getContentSize()/2);
    fill->setPercentage(100);
    return true;
}

Progress* Progress::create(const char* background, const char* fillname)
{
    Progress* progress = new Progress();
    if(progress && progress->init(background,fillname))
    {
        progress->autorelease();
        return progress;
    }
    else
    {
        delete progress;
        progress = NULL;
        return NULL;
    }
}

Progress.cpp

#ifndef __Player__
#define __Player__
#include "cocos2d.h"
#include "Progress.h"

USING_NS_CC;

class Player : public Sprite
{
public:
    enum PlayerType
    {
        HERO,
        ENEMY
    };
    bool initWithPlayerType(PlayerType type);
    static Player* create(PlayerType type);
    void addAnimation();
    void playAnimationForever(std::string animationName);
    void playAnimation(std::string animationName);
    void walkTo(Vec2 dest);
    Sequence* getSeq() { return _seq; }
    void getHit();
    void autoDoAction(Player* hero);
    void autoAttack(Player* hero);
    Progress* getProgress() { return _progress; }
private:
    PlayerType _type;
    std::string _name;
    int _animationNum = 5;
    float _speed;
    std::vector<int> _animationFrameNums;
    std::vector<std::string> _animationNames;
    Sequence* _seq;
    Progress* _progress;
    bool _isShowBar;
};

#endif

Player.h

#include "Player.h"
#include <iostream>

bool Player::initWithPlayerType(PlayerType type)
{
    std::string sfName = "";
    std::string animationNames[5] = {"attack", "dead", "hit", "stay", "walk"};
    _animationNames.assign(animationNames,animationNames+5);
    switch (type)
    {
    case PlayerType::HERO:
        {
        _name = "hero";
        sfName = "hero-stay0000.png";
        _isShowBar = false;
        int animationFrameNums[5] = {10, 12, 15, 30, 24};
        _animationFrameNums.assign(animationFrameNums, animationFrameNums+5);
        _speed = 125;
        break;
        }
    case PlayerType::ENEMY:
        {
        _name = "enemy";
        sfName = "enemy-stay0000.png";
        _isShowBar = true;
        int animationFrameNums[5] = {21, 21, 24, 30, 24};
        _animationFrameNums.assign(animationFrameNums, animationFrameNums+5);
        _speed = 70;
        break;
        }
    }
    this->initWithSpriteFrameName(sfName);
    this->addAnimation();

    auto size = this->getContentSize();
    _progress = Progress::create("small-enemy-progress-bg.png","small-enemy-progress-fill.png");
    _progress->setPosition( size.width/2, size.height + _progress->getContentSize().height/2);
    this->addChild(_progress);
    if(!_isShowBar)
    {
        _progress->setVisible(false);
    }

    return true;
}
Player* Player::create(PlayerType type)
{
    Player* player = new Player();
    if (player && player->initWithPlayerType(type))
    {
        player->autorelease();
        player->setAnchorPoint(Vec2(0.5, 0));
        return player;
    }
    else
    {
        delete player;
        player = NULL;
        return NULL;
    }
}
void Player::addAnimation()
{
    auto animation = AnimationCache::getInstance()->getAnimation(String::createWithFormat("%s-%s", _name.c_str(),
                                                            _animationNames[0].c_str())->getCString());
    if (animation)
        return;
    for (int i = 0; i < _animationNum; i ++)
    {
        auto animation = Animation::create();
        animation->setDelayPerUnit(1.0f / 10.0f);
        for (int j = 0; j < _animationFrameNums[i]; j ++)
        {
            auto sfName = String::createWithFormat("%s-%s%04d.png", _name.c_str(), _animationNames[i].c_str(), j)->getCString();
            animation->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(sfName));
            if (!animation)
            log("hello ha ha");
        }
        AnimationCache::getInstance()->addAnimation(animation, String::createWithFormat("%s-%s", _name.c_str(),
                                                            _animationNames[i].c_str())->getCString());
    }
}
void Player::playAnimationForever(std::string animationName)
{
    auto str = String::createWithFormat("%s-%s", _name.c_str(), animationName.c_str())->getCString();
    bool exist = false;
    for (int i = 0; i < _animationNum; i ++) {
        if (animationName == _animationNames[i])
        {
            exist = true;
            break;
        }
    }
    if (exist == false)
        return;
    auto animation = AnimationCache::getInstance()->getAnimation(str);
    auto animate = RepeatForever::create(Animate::create(animation));
    this->runAction(animate);
}

void Player::playAnimation(std::string animationName)
{
    auto str = String::createWithFormat("%s-%s", _name.c_str(), animationName.c_str())->getCString();
    bool exist = false;
    for (int i = 0; i < _animationNum; i ++) {
        if (animationName == _animationNames[i])
        {
            exist = true;
            break;
        }
    }
    if (exist == false)
        return;
    auto animation = AnimationCache::getInstance()->getAnimation(str);
    auto func = [&]()
    {
        this->stopAllActions();
        this->playAnimationForever("stay");
        _seq = nullptr;
    };
    auto callback = CallFunc::create(func);
    auto animate = Sequence::create(Animate::create(animation), callback,NULL);
    this->runAction(animate);
}

void Player::walkTo(Vec2 dest)
{
    if (_seq)
        this->stopAction(_seq);
    auto curPos = this->getPosition();
    if (curPos.x > dest.x)
        this->setFlippedX(true);
    else
        this->setFlippedX(false);
    auto diff = dest - curPos;
    auto time = diff.getLength() / _speed;
    auto moveTo = MoveTo::create(time, dest);
    auto func = [&]()
    {
        this->stopAllActions();
        this->playAnimationForever("stay");
        _seq = nullptr;
    };
    auto callback = CallFunc::create(func);
    this->stopAllActions();
    this->playAnimationForever("walk");
    _seq = Sequence::create(moveTo, callback, nullptr);

    this->runAction(_seq);
}

void Player::getHit()
{
    float blood = _progress->getProgress();
    if (_name == "hero")
        blood -= 3;
    else
        blood -= 5;
    _progress->setProgress(blood);
    log(String::createWithFormat("hit now blood is %f", blood)->getCString());
    if (blood <= 0)
    {
        log(String::createWithFormat("%s is dead.", _name.c_str())->getCString());
        auto func = [&]()
        {
            this->stopAllActions();
            this->playAnimation("dead");
        };
        auto callback = CallFunc::create(func);
        _seq = Sequence::create(callback, nullptr);
        this->runAction(_seq);
        this->_progress->setVisible(false);
        this->setVisible(false);
        return;
    }
}

void Player::autoDoAction(Player* hero) // just for _enemy
{
    Vec2 dest = hero->getPosition();
    if (_seq)
        this->stopAction(_seq);
    auto curPos = this->getPosition();
    if (curPos.x > dest.x)
        this->setFlippedX(true);
    else
        this->setFlippedX(false);
    auto diff = dest - curPos;
    if (diff.x > 0) diff.x -= 90;
    else diff.x += 90;
    if (diff.y > 0) diff.y -= 20;
    else diff.y += 20;
    auto time = diff.getLength() / _speed;
    auto moveTo = MoveTo::create(time, dest);
    auto func = [&]()
    {
        this->stopAllActions();
        this->playAnimationForever("stay");
        _seq = nullptr;
    };
    auto callback = CallFunc::create(func);
    this->stopAllActions();
    this->playAnimationForever("walk");
    _seq = Sequence::create(moveTo, callback, nullptr);

    this->runAction(_seq);
}

void Player::autoAttack(Player* hero) // just for _enemy
{
    float blood = _progress->getProgress();
    if (blood <= 0)
        return;
    Vec2 del = this->getPosition() - hero->getPosition();
    if (del.length() <= 100)
    {
        this->playAnimation("attack");
        hero->getHit();
    }
}

Player.cpp

#ifndef __MainScene__
#define __MainScene__

#include "cocos2d.h"
#include "Player.h"
#include "Progress.h"

USING_NS_CC;

class MainScene : public cocos2d::Layer
{
public:
    static cocos2d::Scene* createScene();
    virtual bool init();
    void menuCloseCallback(cocos2d::Ref* pSender);
    CREATE_FUNC(MainScene);
    bool onTouchBegan(Touch* touch, Event* event);
    void attackCallback(Ref* pSender);
private:
    Player* _hero;
    Player* _enemy;
    EventListenerTouchOneByOne* _listener_touch;
    Progress* _progress;
};

#endif

MainScene.h

#include "MainScene.h"

Scene* MainScene::createScene()
{
    auto scene = Scene::create();
    auto layer = MainScene::create();
    scene->addChild(layer);
    return scene;
}
bool MainScene::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    SpriteFrameCache::getInstance()->addSpriteFramesWithFile("images/role.plist","images/role.png");
    SpriteFrameCache::getInstance()->addSpriteFramesWithFile("images/ui.plist","images/ui.pvr.ccz");

    Sprite* background = Sprite::create("images/background.png");
    background->setPosition(origin + visibleSize/2);
    this->addChild(background);

    //add player
    _hero = Player::create(Player::PlayerType::HERO);
    _hero->setPosition(origin.x + _hero->getContentSize().width/2, origin.y + visibleSize.height/2);
    this->addChild(_hero);

    //add enemy1
    _enemy = Player::create(Player::PlayerType::ENEMY);
    _enemy->setPosition(origin.x + visibleSize.width - _enemy->getContentSize().width/2, origin.y + visibleSize.height/2);
    this->addChild(_enemy);

    _hero->playAnimationForever("stay");
    _enemy->playAnimationForever("stay");

    _listener_touch = EventListenerTouchOneByOne::create();
    _listener_touch->onTouchBegan = CC_CALLBACK_2(MainScene::onTouchBegan,this);
    _eventDispatcher->addEventListenerWithSceneGraphPriority(_listener_touch, this);

    auto attackItem = MenuItemImage::create(
                                           "CloseNormal.png",
                                           "CloseSelected.png",
                                           CC_CALLBACK_1(MainScene::attackCallback, this));

    attackItem->setPosition(Vec2(origin.x + visibleSize.width - attackItem->getContentSize().width/2 ,
                                origin.y + attackItem->getContentSize().height/2));

    // create menu, it‘s an autorelease object
    auto menu = Menu::create(attackItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1);

    _progress = Progress::create("player-progress-bg.png","player-progress-fill.png");
    _progress->setPosition(_progress->getContentSize().width/2, this->getContentSize().height - _progress->getContentSize().height/2);
    this->addChild(_progress);

    return true;
}
void MainScene::menuCloseCallback(cocos2d::Ref* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
    MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
    return;
#endif

    Director::getInstance()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}

bool MainScene::onTouchBegan(Touch* touch, Event* event)
{
    Vec2 pos = this->convertToNodeSpace(touch->getLocation());
    _hero->walkTo(pos);
    log("MainScene::onTouchBegan");
    _enemy->autoDoAction(_hero);
    return true;
}

void MainScene::attackCallback(Ref* pSender)
{
    _hero->stopAllActions();
    _hero->playAnimation("attack");
    Vec2 del = _hero->getPosition() - _enemy->getPosition();
    float distance = del.length();
    log(String::createWithFormat("distance == %f", distance)->getCString());
    if (distance <= 100.0) {
        _enemy->getHit();
    }
    _enemy->autoAttack(_hero);
    _progress->setProgress(_hero->getProgress()->getProgress());
}

MainScene.cpp

时间: 2024-10-24 14:36:13

cocos2dx游戏--欢欢英雄传说--为敌人添加移动和攻击动作的相关文章

cocos2dx游戏--欢欢英雄传说--添加游戏背景

经过一段时间的学习cocos2dx,接下来我想要实践开发一个小游戏,我把它命名为“欢欢英雄传说”,项目名将取为HuanHero.环境:cocos2dx环境:cocos2d-x 3.11.1IDE:Code::Blocks 16.01项目类型:cpp项目首先创建一个项目:进入cocos2dx目录,输入: cocos new HuanHero -l cpp -d ./projects/ 这样便在projects目录下新建了一个项目"HuanHero".进入./projects/HuanHe

cocos2dx游戏--欢欢英雄传说--添加攻击按钮

接下来添加攻击按钮用于执行攻击动作.同时修复了上一版移动时的bug.修复后的Player::walkTo()函数: void Player::walkTo(Vec2 dest) { if (_seq) this->stopAction(_seq); auto curPos = this->getPosition(); if (curPos.x > dest.x) this->setFlippedX(true); else this->setFlippedX(false); a

cocos2dx游戏--欢欢英雄传说--添加人物移动

主要的调整就是将HelloWorldScene改成了MainSecne,然后将Player作为了MainScene的私有成员变量来处理.修改了人物图片,使用了网上找到的三国战纪的人物素材代替我之前画的很差劲的人物素材.是gif动画,下载了之后用photeshop分解成了一个个png图片.然后在window下用破解的TexturePacker生成了role.plist和role.png文件.改动后的代码还增加了移动的部分.MainScene.cpp部分代码: _listener_touch = E

英雄传说3 白发魔女 作为RPG游戏的成就分析

通关了psp上的英雄传说3白发魔女,有些感想,这里记录一下. 英雄传说3白发魔女,讲述的故事非常简单,两个主角,杰立欧和克莉丝,由于村庄的风俗在成年之时离开村庄,环绕世界进行巡礼.经过五个特别的国家,每个国家都有一个称为夏路的建筑,在其中需要使用随行携带的银色短剑触发一面魔法镜,然后查看魔法镜中显示的 影像.这些影像是对未来的预测.看完每个夏路的影像后绕回村庄,完成巡礼,从此成人. 而在巡礼过程中,他们不断的得知关于20年前跨国巡礼的白发魔女的传言,白发魔女走了和他们相同的路,在每个国家都留下了

购买李宁Cocos2d-x套餐,送最新出的《Cocos2d-x游戏实战指南》签名书一本

活动时间:2016-10-18至2016-11-30 通过本套餐,可完全了解Cocos2d-x 3.x的相关技术,以及掌握C++语言,并具有一定的项目实战经验. Cocos2d-x游戏开发套餐:http://edu.51cto.com/pack/view/id-114.html <Cocos2d-x游戏实战指南>封面 本书月底出版,触控科技副总裁Jane.微软开放体验和合作事业部开发技术顾问梅颖广.51CTO学院运营总监曹亚莉.哈尔滨工业大学  王峥  联袂推荐 目录 第1章     初识CO

Cocos2d-x游戏开发之lua编辑器 subime 搭建,集成cocos2dLuaApi和自有类

Sublime Text http://baike.baidu.com/view/10701920.htm?from_id=8130415&type=syn&fromtitle=Sublime&fr=aladdin 简介 Sublime Text 是一个代码编辑器(Sublime Text 2是收费软件,但可以无限期试用),也是HTML和散文先进的文本编辑器.Sublime Text是由程序员Jon Skinner于2008年1月份所开发出来,它最初被设计为一个具有丰富扩展功能的V

cocos2dx游戏开发学习笔记1-基本概念

这里主要讲构建整个游戏需要的基本元素,很大部分都摘自cocos2dx官网. 1.Director 导演 导演,顾名思义,就是对整个游戏进行整体控制的. "Director"是一个共享的(单元素集)对象,负责不同场景之间的控制.导演知道当前哪个场景处于活动状态,允许你改变场景,或替换当前的场景,或推出一个新场景.当你往场景堆中推出一个新场景时,"Director"会暂停当前场景,但会记住这个场景.之后场景堆中最顶层的场景跳离时,该场景又会继续活跃.此外"Di

cocos2dx游戏的基本元素

3.1 CCDirector:大总管 bool AppDelegate::applicationDidFinishLaunching() ?{ ?   //初始化导演类 ?   CCDirector *pDirector = CCDirector::sharedDirector(); ?   pDirector-]]>setOpenGLView(&CCEGLView::sharedOpenGLView()); ?   //高分辨率屏幕(例如 Retina 屏幕)的资源管理 ?   //pDi

用cocos2d-html5做的消除类游戏《英雄爱消除》(3)——游戏主界面

游戏主界面,同时也是主程序,包括sprite的生成加入以及游戏状态的控制. 下面同样贴下源码再讲解; /** * Power by html5中文网(html5china.com) * author: jackyWHJ */ var STATE_PLAYING = 0; var STATE_GAMEOVER = 1; var g_sharedGameLayer; var GameLayer = cc.Layer.extend({ _time:0, _timeLabel:null, _timeSt