PuTsangTo-单撸游戏开发04 给角色添加基本动画

一、 跳跃与移动的优化与完善

先给上一次的内容做一次补救,也就是上一次中还留存的,由于键盘按键事件的第一次回调与后续回调之间会间隔个小半秒带来的跳跃落地后动作延迟的情况。

最终的键盘按下回调的处理代码是这样的:

onKeyPressed: function (keyCode, event) {
        switch(keyCode) {
            case cc.KEY.left:
                this.direction = ‘idle_left‘;
                if (this.stay) {
                    this.move = ‘move_left‘;
                } else {
                    this.moveAfterJump = ‘move_left‘;
                }
                break;
            case cc.KEY.right:
                this.direction = ‘idle_right‘;
                if (this.stay) {
                    this.move = ‘move_right‘;
                } else {
                    this.moveAfterJump = ‘move_right‘;
                }
                break;
            case cc.KEY.alt:
                if(this.stay){
                    this.stay = false;
                    this.jumpSpeed = this.jump;
                    this.moveAfterJump = this.move;
                }
                break;
            case cc.KEY.down:
                if (this.stay) {
                    this.move = 4;
                } else {
                    this.moveAfterJump = 4;
                }
                break;
            default:
                break;
        }
    },

键盘松开的回调事件处理代码是这样的:

onKeyReleased: function (keyCode, event) {
        switch(keyCode) {
            case cc.KEY.left:
                if(!this.stay) {
                    if (this.moveAfterJump === ‘move_left‘) {
                        this.moveAfterJump = ‘idle_left‘;
                    }
                } else {
                    if (this.move === ‘move_left‘) {
                        this.move = ‘idle_left‘;
                    }
                }
                break;
            case cc.KEY.right:
                if(!this.stay) {
                    if (this.moveAfterJump === ‘move_right‘) {
                        this.moveAfterJump = ‘idle_right‘;
                    }
                } else {
                    if (this.move === ‘move_right‘) {
                        this.move = ‘idle_right‘;
                    }
                }
                break;
            default:
                break;
        }
    },

整体思路很简单:

1. 键盘按下事件区分当前是否正在跳跃(stay的值)

正在跳跃则只改变朝向并预定落地后的运动,否则直接改变朝向并执行运动

2. 键盘松开事件区分松开的按键是否与当前生效的按键一致(有可能是已经被覆盖掉无效了的按键,比如说左移时按下右移,左移其实已经失效了)

如果松开的按键正是当前正在生效的按键,那就停止它,否则不需要做什么处理。(当然还是要区分是否正在跳跃)

下一个问题就是角色离开当前平台(没有跳跃) 时会做到悬空效果,因为没有做碰撞离开事件的处理,现在就把它加上:

onCollisionExit: function (other, self) {
        var otherTop = other.world.aabb.y + other.world.aabb.height;
        var selfBottom = self.world.aabb.y;
        // 自身底部与目标顶部的偏移
        var out = otherTop - selfBottom;
        // 偏移
        if(Math.abs(out) < 10) {
            this.stay = false;
        }
    } 

与此同时,如代码中所见的,现在把方向与移动的值都改为了字符串值,而不再使用数字值,这是为了方便后续添加动画,并且其值更加明了,idle_left/right代表站立朝左/右,move_left/right代表左右移动。

二、 美术资源

现在开始小白要变身了,不能一直当小白,笔者就用自己一个周末学会得PS皮毛来把我们的第一个角色给画出来,想了想就选用画起来最简单的一只口袋妖怪好了,没错就是他:

纯PS画笔画出来的,这里要隔空感谢一下腾讯课堂上名叫战翼的CG免费课程老师的PS工具预设。下面是整套高清雷电球套图:

包括了左右两个朝向的雷电球,还有就是完整一圈的滚动动作帧,画得很丑还请包涵毕竟本职是个写代码的。

三、资源的使用

首先要把我们的雷电球套图制作成cocos的图集资源,使用的是TexturePacker工具,然后直接拖拽到CocosCreator中:

直接拖一帧到player的spirit上,角色就变身成为雷电球了:

四、动画资源

接下来就是本文的重头戏动画了,首先要给player添加动画组件:

然后就把我们需要的四种动画给编辑出来,分别是:朝左静止,朝右静止,向左滚动,向右滚动,也就是4个动画clip:

最终得到的就是下图中这么四个动画,把他们都像上图中一样拖到player的动画clip里。

关于CocosCreator的动画编辑器感觉没什么难度虽然笔者也并没有用的很多,但是想达到的目的也只是创建最简单的帧动画而已,要做的事情无非就是:

给角色添加动画组件 -> 选中角色进入动画编辑器 -> 创建新clip -> 一帧一帧拖图片 -> 选择循环播放或者别的 -> 保存并拖到角色动画组件的clip数组中

五、脚本控制动画

接下来要使用脚本来控制动画。

要实现的效果是:角色左右移动时会展现滚动的动画,停下时会根据当前朝向展现左右站立的形象,原地跳跃时不会滚动,移动跳跃时会保持滚动形态。

说白了就是根据前面定义好的direction和move值来控制动画clip的播放啦。

正是为此才将这两个变量值改用字符串,也就是直接是动画clip的名字,在播放动画时能比较方便。

现在新建一个function专门接收朝向和运动参数,并判断出需要播放何种动画。并在键盘按下、键盘松开、碰撞进入、碰撞离开这四个事件发生时执行:

currentAnim: ‘‘,
    DoAnim: function(od, nd, om, nm) {
        if (this.stay) {
            // 移动优先
            if (om != nm && nm != this.currentAnim) {
                this.anim.play(nm);
            }
        } else {
            // 朝向优先
            if (od != nd && nd != this.currentAnim) {
                this.anim.play(nd);
            }
        }
    },

currentAnim用于存放当前正在播放的动画,因为cocos的机制动画重复调用play()时会先停止当前然后重新播放,这是不符合我们想要的效果的,所以只有当需要播放的动画当前不在播放时才需要播放它。

并且播放那种动画的判断需要根据新旧朝向和新旧移动来判断,因为只有朝向或移动发生改变时才需要更改当前的动画不是吗。

在前面讲到的四种事件中,要在事件处理的一开始就记录旧的朝向和移动,并在最后记录新的朝向和移动(这些事件做的事情就是将朝向或移动从旧的变成新的),然后再执行这个DoAnim方法,就可以了:

onKeyReleased: function (keyCode, event) {
        var oldDirection = this.direction;
        var oldMove = this.move;
        switch(keyCode) {
            ...
        }
        this.DoAnim(oldDirection, this.direction, oldMove, this.move);
    },

至此putsangto的第一个场景下,雷电球已经可以走走跳跳了,对于笔者边学边做来说好歹是迈出了一两步,接下来要做的事情还有很多,待续待续。

时间: 2024-10-11 17:57:50

PuTsangTo-单撸游戏开发04 给角色添加基本动画的相关文章

cocos2d-x ios游戏开发初认识(七) 简单的动画

前面有一节说了帧动画,就是让精灵改变自己的位置.形状.大小来实现相应的动作,这讲主要是要通过一些方法来实现精灵的移动,产生各种炫丽的动画,也可能让你找到一点游戏场景. 下面具体根据代码分析: 为了清晰最好将前几节的代码注释掉. //根据前面的知识先创建一个菜单 CCMenuItemFont *item =CCMenuItemFont::create("开始游戏",this, menu_selector(MainScene::onMenuItem));//点击事件 //添加到菜单栏里面

Unity3D 游戏开发构架篇 ——角色类的设计与持久化

在游戏开发中,游戏角色占了很大的篇幅,可以说游戏中所有的内容都是由主角所带动.这里就介绍一下角色类的设计和持久化. 一.角色类应用场景和设计思想 游戏中的角色类型不一而足,有不同的技能,有不同的属性等等.有些一个玩家只有一个角色,有些一个玩家可以有多个角色.这里就目前项目来描述一下角色类的构造,思路都是类似的. 早期我写角色类都是直接一个Class,然后想到什么属性就往里面添加,如果游戏过程中需要对属性的修改,逻辑判断也写在这个类中,这样必然导致类的庞大和臃肿,最后你自己也忘记了自己写在什么地方

【Unity NGUI游戏开发之二】TweenPosition位移动画(一):不相对于Anchor的位移动画

下面学些下NGUI的TweenPosition位移动画,一般的位移动画需求分为不想对于Anchor锚点的位移动画和相对于Anchor的位移动画(主要看是否考虑屏幕分辨率),下面介绍两种游戏中最常用的不相对于Anchor的TweenPosition用法: 用法1.NGUI的控件从PosA位置移动到PosB位置,播放动画 用法2.在游戏中需要动态创建带有TweenPosition组件动画的对象,对象创建.移动.到达指定位置.销毁的过程.eg.游戏中玩家吃金币,迟到金币后转换为分数,分数播放一个Twe

零基础unity3d游戏开发系列目录

零基础Unity3D游戏开发系列 第一章:游戏开发与游戏引擎(一) 零基础Unity3D游戏开发系列 第一章:游戏开发与游戏引擎(二) 零基础Unity3D游戏开发系列 第二章:Unity3D概览(一)界面... 零基础Unity3D游戏开发系列 第二章:Unity3D概览(一)创建与打开项目I 零基础unity3d游戏开发系列 第二章:unity3d概览(一)创建与打开项目II 零基础Unity3D游戏开发系列 第二章:Unity3D概览(一)创建与打开项目III 零基础Unity3D游戏开发

iOS 游戏开发 博客

1. http://www.cnblogs.com/kesalin/archive/2012/11/10/ios_game_dev_resource.html   ( iOS游戏开发教程) 最近几天仔细了解了iOS游戏开发引擎,常用的cocos2d,Unity引擎,那么Unity是非免费的,而cocos2d则是免费开源的: 最后促使我选择cocos2d的原因有两点: 1.最重要的原因是它对应的开发工具,尤其是 “ParticleDesigner”,粒子系统编辑器,非常的喜欢(需付费$7.99美元

【Unity NGUI游戏开发之三】TweenPosition位移动画(二):相对于UIAnchor不同分辨率下的完美适配位移动画

Unity中的UI我们采用的是NGUI,NGUI的界面位移动画,我们一般使用的是TweenPosition. 一种是简单的相对位移,不考虑分辨率适配问题,只需要简单的从位置A到位置B,已经在文中介绍了: [Unity NGUI游戏开发之二]TweenPosition位移动画(一):不相对于Anchor的位移动画 另外一种是考虑到屏幕分辨率适配的位移动画,我们游戏中大多遇到的是这种情况. eg.我们想让一个UI从屏幕外沿着屏幕的左边移动到屏幕的中央,TweenPositon播放动画,在960*64

HTML5 2D平台游戏开发——角色动作篇之蓄力技

在很多动作游戏中,玩家操控的角色可以施放出比普通攻击更强力的蓄力技,一般操作为按住攻击键一段时间然后松开,具体效果像下面这张图: 要实现这个操作首先要记录下按键被按住的时间,初始是0: this.sabreChargeTime = 0; 接下来是能够施放技能所需要的时间,超过这个时间后松开按键,即可施放出技能,否则无效: this.MAX_SABRE_CHARGE_TIME = 150; 代码结构如下: if (key[74]) {//攻击 this.updateSabreCharge(); /

HTML5 2D平台游戏开发——角色动作篇之指令技

一般在动作游戏中,玩家可以通过对输入设备输入一系列的指令让角色完成某个或多个特定的动作.以格斗游戏<拳皇>为例,键入↓→↓← + A or C可以触发IORI的必杀技八稚女: 通过一系列输入最终让角色完成某个动作,就是指令技.其原理是通过将玩家的键入与指令技列表中的键位进行比对,如果一致,就匹配成功.以下是JavaScript的简单实现: class Instruct { constructor(callback) { this.instructs = {}; this.MAX_INTERVA

Unity3D游戏开发之自由视角状态下的角色控制(二)

在测试Unity3D游戏开发之自由视角状态下的角色控制这个项目的时候意外地发现了一个Bug.Bug出现在如下位置: [csharp] view plaincopyprint? //设置玩家跟随角度 if(Target.GetComponent<NoLockiVew_Player>().State==NoLockiVew_Player.PlayerState.Walk) { Target.rotation=Quaternion.Euler(new Vector3(0,mX,0)); } 该方法主