zoukankan      html  css  js  c++  java
  • cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第三步---主角开跑&同一时候带着刚体

    说明:这里是借鉴:晓风残月 前辈的博客。他是将泰然网的跑酷教程。用cocos2d-x 2.X 版本号重写的,眼下我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记

    在这一步。我们主要是把主角增加到游戏场景中来,并且让它跑动,这里的跑动,实际上也就是运行一组动画,让其看起来像是在跑动,并且相对屏幕的位置也不会改变

    我们会定义一个主角类:Runner。而这一步就要用到 帧动画 的创建和使用等知识点。

    对于Runner,我的设计思路例如以下:

    1.主角有一个动作集合。包含跑动,跳起来,以及蹲下。

    那么就有不同的帧动画,那么这里借鉴到 晓风残月前辈的方法,将帧动画打包命名。之后依据动作名来运行动作

    2.主角须要绑定刚体。而且在不同的动作下的刚体大小不同

    3.我们给主角设定一个状态。那么依据状态,就能知道运行动作和刚体

    反正在这一步主要是看

    那么上马:Runner.h

    #ifndef __Runner__H__
    #define __Runner__H__
    
    #include "cocos2d.h"
    
    enum runnerState{
    	running,
    	jumpUp,
    	jumpDown,
    	crouch
    };
    
    class Runner : public cocos2d::Node{
    public:
    	virtual bool init();
    	CREATE_FUNC(Runner);
    
    	//初始化 action 集合
    	void initActionSet(cocos2d::SpriteFrameCache* frameCache);
    
    	//依据动作名称运行动作
    	void doAction(const char* actionName);//
    
    	void initBody();//初始化物理刚体
    
    	runnerState getState(){ return m_state;};//获取当前的状态,后面要用到
    
    	cocos2d::Size getRunJumpSize(){ return run_jumpSize;};//获取不同一时候候的SIze
    	cocos2d::Size getCrouchSize() { return crouchSize;};
    
    	void Run();
    private:
    	//  须要一个基本的精灵运行动作
    	cocos2d::Sprite* m_runner;
    
    	// 不同的动作须要不同的刚体大小
    	cocos2d::Size run_jumpSize;//跑和跳的大小一样
    	cocos2d::Size crouchSize;//蹲下来的大小
    
    	runnerState m_state;
    };/**/
    
    #endif

    这里的刚体Size仅仅有两个。由于跑的时候和跳起来的时候的精灵大小是几乎相同的,那么处于这两个状态的的刚体绑定大小能够一样。然后下蹲的时候的Size就不同

    Runner.cpp

    #include "Runner.h"
    
    USING_NS_CC;
    
    bool Runner::init(){
    	//载入图片到缓存池
    	auto frameCache = SpriteFrameCache::getInstance();
    	frameCache->addSpriteFramesWithFile("parkour.plist","parkour.png");
    
    	m_runner = Sprite::createWithSpriteFrameName("runner0.png");
    
    	run_jumpSize = m_runner->getContentSize();
    	crouchSize = Sprite::createWithSpriteFrameName("runnerCrouch0.png")->getContentSize();
    
    	this->addChild(m_runner);
    
    	initActionSet(frameCache);//初始化动作集合
    
    	m_state = running;
    
    	initBody();
    
    	return true;
    }
    
    void Runner::initActionSet(SpriteFrameCache* frameCache){
    	SpriteFrame* frame = NULL;
    	//3.0中改用vector 而不是用Array
    	Vector<SpriteFrame*>frameVector;
    	
    	/* 1.----------------载入跑动的Animation-----------------*/
    	for(int i = 0; i <= 7; i ++) {
    		//从缓存池中载入精灵到Vector
    		frame = frameCache->spriteFrameByName(String::createWithFormat("runner%d.png",i)->getCString());
    		frameVector.pushBack(frame);
    	}
    
    	//用vector里面的SpriteFrame列表创建Animation  以及设置一些參数
    	auto run_animation = Animation::createWithSpriteFrames(frameVector,0.1f,-1);
    	//将跑动的 Animation 取名为 running 
    	AnimationCache::getInstance()->addAnimation(run_animation,"running");
    	
    }
    
    void Runner::doAction(const char* actionName){
    	auto animation = AnimationCache::getInstance()->animationByName(actionName);
    	auto action = Animate::create(animation);
    	m_runner->runAction(action);
    }
    
    void Runner::initBody(){
    	//依据不同状态设置不同刚体大小
    	Size bodySize;
    	if(m_state == crouch){
    		bodySize = crouchSize;
    	}
    	else{
    		bodySize = run_jumpSize;
    	}
    
    	//创建runner的刚体
    	auto runerBody = PhysicsBody::createBox(bodySize,PHYSICSBODY_MATERIAL_DEFAULT);
    
    	//绑定刚体
    	this->setPhysicsBody(runerBody);
    }
    
    void Runner::Run(){
    	m_state = running;
    	initBody();
    	doAction("running");
    }
    

    init 函数里面我们做了一些事:

    1.先把图片载入到缓存池,初始化主精灵,和两个Size,以及当前状态

    这里的图片实际上是一张整合了非常多小图片的集合。不同的图片有不同纹理,那么集合到同一图片中纹理就同样的,那么同一纹理的图片,我们就能够降低渲染批次。3.0中的渲染好像是自己主动处理的。看了一篇文章。说是不推荐使用那个SpriteBachNode啦,然后说得也比較抽象,我这里也不特别解释,有好的教程麻烦推荐,谢谢

    2.我们初始化了动作集合,这一步其中,我们仅仅初始化跑动的帧动画

    initActionSet函数其中。我都有具体凝视

    doAction函数中,我们能够依据传入的參数动作名称来运行动作,也就是在initActionSet 其中给动作取名字的那里

    initBody函数其中。依据不同的状态,我们就给主角绑定不同大小的刚体,关于反复setPhysicsBody。你可能会有疑问。本来有一个刚体,换了一个状态。又设定一个刚体能够吗?答案是能够的,我们能够查看源代码

    void Node::setPhysicsBody(PhysicsBody* body)
    {
        /*省略*/
        
        if (_physicsBody != nullptr)
        {
            PhysicsWorld* world = _physicsBody->getWorld();
            _physicsBody->removeFromWorld();
            _physicsBody->_node = nullptr;
            _physicsBody->release();
            
            if (world != nullptr && body != nullptr)
            {
                world->addBody(body);
            }
        }
        
        _physicsBody = body;
        if (body != nullptr)
        {
            Node* parent = getParent();
            Point pos = parent != nullptr ?

    parent->convertToWorldSpace(getPosition()) : getPosition(); _physicsBody->setPosition(pos); _physicsBody->setRotation(getRotation()); } }

    这里我们能够看到,它会推断_physicsBody(也就是Node的刚体)是不是为空。如有已有刚体,会先删除。然后又一次绑定


    好啦,到这里主角类以及初步设置完啦,我们在PlayScene.h 中增加一个成员变量  Runner* m_runner;

    然后在PlayScene.cpp 的init函数中对 m_runner初始化:

    m_runner = Runner::create();
    m_runner->setPosition(runner_posX,ground_hight+m_runner->getRunJumpSize().height/2);
    m_runner->Run();
    this->addChild(m_runner);

    那么这里的runner_posX 就是在 ground_hight  以下定义的一个宏,也就是主角的X坐标位置,我这里定义 80

    OK执行測试如图:


    假设你把那些资源都放在Resouce 文件下了。还能听到背景音乐

    这里我也有一个问题,就是有的人能够插入动态的那种图片,比較好的演示了执行结果。用QQ好像不能对这个屏幕进行截取动态图,求方法推荐可怜

    以下我们就增加PlayScene的背景,以及地图无限滚动,让主角看起来更像是跑动 ,同一时候也为主角的Jump跳跃动作以及Crouch下蹲动作的运行做准备


    个人愚昧观点,欢迎指正与讨论大笑

  • 相关阅读:
    PHP使用引用变量foreach时,切记其他循环不要使用同一个名字的变量
    PHP 获取给定时间的周日时间或月末时间或每天
    MySQL Load Data InFile 文件内容导入数据库和 Into OutFile导出数据到文件
    直接拿来用!最火的iOS开源项目(一)
    12个有趣的C语言问答
    Flex,Flash,AS3,AIR的关系和区别
    Stage3D大冒险
    c/c++程序中内存区划分
    IOS—— strong weak retain assign 学习
    如何提高你的移动开发中AS3/AIR性能
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6802389.html
Copyright © 2011-2022 走看看