当前位置: 首页 > news >正文

spine 动画层 动态权重

 前奏.业务背景

这边想实现一个功能,项目中有 一只猫 猫的头会盯着逗猫棒移动。因为素材还没到所以这里使用了 spine 自带的猫头鹰。他的动画 刚好挺有针对性:(关联上篇)icon-default.png?t=O83Ahttps://blog.csdn.net/nicepainkiller/article/details/144113214

一共有六组动画:

        idel  空闲动画全身都会动 多帧动画

        blink 眨眼睛动画 头不动 多帧动画

        其余几个动画只有有头会动 单帧动画 只有一帧

  •     blink  眼睛在中间的动画 会眨眼睛
  •     down 眼睛朝下看 单帧
  •     left     眼睛朝左看 单帧
  •     right   眼睛朝右看 单帧
  •     up      眼睛朝上看 单帧
  •     idel    空闲动画 全身动

 猫头鹰眼睛可以盯着 屏幕物体移动,实现效果如下 :

最初想的实现方式是:类似 Unity3D 有一个二位动画权重的东西。但是找遍 cocos creator  API 发现没找到,

那么只能纯手撸了:

        思路就是动态控制 动画层的权重来显示不同动画头上,头右,头下,头左)的播放权重。

实操1.逗猫棒位置计算

首先就确定一个屏幕可以拖动的元素,并且计算出一个区域,用来确定 向量 Vec2:

  1. 屏幕触点 转 屏幕坐标
  2. 根据屏幕坐标计算出 用来表示范围的  一个 向量
核心代码:
//获取 触点坐标位置
touchMove(event: EventTouch) {//更新 拖拽元素位置console.log('touchMove');this.potion.x = event.getLocationX();this.potion.y = event.getLocationY();//触点坐标转 屏幕坐标this.worldPostion = this.camera.screenToWorld(this.potion);//屏幕坐标转 局部坐标this.node.position = this.nodeParent.getComponent(UITransform).convertToNodeSpaceAR(this.worldPostion);//console.log("this.node.position:", this.node.position);//计算向量this.localPostion.x = clamp(this.node.position.x, -this.range, this.range) / this.range;this.localPostion.y = clamp(this.node.position.y, -this.range, this.range) / this.range;//console.log("this.localPostion:", this.localPostion);this.spinMerge1.updateAnimation(this.localPostion);
}
功能完整代码:
import { _decorator, Component, Node, EventTouch, Camera, Vec3, UITransform, Vec2, clamp, director, view } from 'cc';
import { SpinMerge1 } from './SpinMerge1';
const { ccclass, property } = _decorator;@ccclass('TouchMove')
export class TouchMove extends Component {@property({ type: Node })private nodeParent: Node;@property({ type: Camera })private camera: Camera;//控制 Spine 动画的脚步@property({ type: SpinMerge1 })private spinMerge1: SpinMerge1;private potion: Vec3 = new Vec3();private worldPostion: Vec3 = new Vec3();private localPostion: Vec2 = new Vec2();private range: number;onLoad() {this.node.on(Node.EventType.TOUCH_START, this.touchStart, this);this.node.on(Node.EventType.TOUCH_MOVE, this.touchMove, this);this.node.on(Node.EventType.TOUCH_END, this.touchEnd, this)this.node.on(Node.EventType.TOUCH_CANCEL, this.touchCancel, this)}start() {this.range = view.getVisibleSize().width / 2;}//展示只有 在拖拽情况下才显示的 元素 equipmentFlytouchStart(event: EventTouch) {//Log.trace('touchStart');console.log('touchStart');}//获取 触点坐标位置touchMove(event: EventTouch) {//更新 拖拽元素位置console.log('touchMove');this.potion.x = event.getLocationX();this.potion.y = event.getLocationY();//触点坐标转 屏幕坐标this.worldPostion = this.camera.screenToWorld(this.potion);//屏幕坐标转 局部坐标this.node.position = this.nodeParent.getComponent(UITransform).convertToNodeSpaceAR(this.worldPostion);//console.log("this.node.position:", this.node.position);//计算向量this.localPostion.x = clamp(this.node.position.x, -this.range, this.range) / this.range;this.localPostion.y = clamp(this.node.position.y, -this.range, this.range) / this.range;//console.log("this.localPostion:", this.localPostion);this.spinMerge1.updateAnimation(this.localPostion);}//结束拖拽 隐藏拖拽元素touchCancel(event: EventTouch) {console.log('touchCancel');this.node.position = new Vec3();this.spinMerge1.resetAnimation();}//结束拖拽touchEnd(event: EventTouch) {console.log('touchEnd');this.node.position = new Vec3();this.spinMerge1.resetAnimation();}}

实操2.猫头鹰盯着逗猫棒

猫头随着物体移动的核心就是

      通过动画层混合 分别控制 头上,头右,头下,头左 动画权重,做到动态控制展示的权重。

 

核心代码:
public updateAnimation(vec2: Vec2) {//console.log('updateAnimation:', vec2);this.ver2Normal.x = Math.abs(vec2.x);this.ver2Normal.y = Math.abs(vec2.y);//右上if (vec2.x > 0 && vec2.y > 0) {this.trackleft.alpha = 0.0;this.trackdown.alpha = 0.0;this.trackright.alpha = this.ver2Normal.x;this.trackUp.alpha = clamp(this.ver2Normal.y, 0, 1 - this.ver2Normal.x);//右下} else if (vec2.x > 0 && vec2.y < 0) {this.trackUp.alpha = 0;this.trackleft.alpha = 0;this.trackright.alpha = this.ver2Normal.x;this.trackdown.alpha = clamp(this.ver2Normal.y, 0, 1 - this.ver2Normal.x);//左下} else if (vec2.x < 0 && vec2.y < 0) {this.trackUp.alpha = 0;this.trackright.alpha = 0;this.trackleft.alpha = this.ver2Normal.x;this.trackdown.alpha = clamp(this.ver2Normal.y, 0, 1 - this.ver2Normal.x);//左上} else if (vec2.x < 0 && vec2.y > 0) {this.trackright.alpha = 0;this.trackdown.alpha = 0;this.trackleft.alpha = this.ver2Normal.x;this.trackUp.alpha = clamp(this.ver2Normal.y, 0, 1 - this.ver2Normal.x);} else {this.trackUp.alpha = 0;this.trackright.alpha = 0;this.trackdown.alpha = 0;this.trackleft.alpha = 0;}}
完整代码:
import { _decorator, Component, Node, sp, Button, Vec2, clamp } from 'cc';
const { ccclass, property } = _decorator;@ccclass('SpinMerge1')
export class SpinMerge1 extends Component {@property({ type: sp.Skeleton })private spinAnimation: sp.Skeleton;private trackUp: sp.spine.TrackEntry;private trackright: sp.spine.TrackEntry;private trackdown: sp.spine.TrackEntry;private trackleft: sp.spine.TrackEntry;private ver2Normal: Vec2 = new Vec2();start() {this.spinAnimation.setAnimation(0, 'idle', true);//猫头鹰的动画名 left right 反了//所以我们这里的顺序是: 上 -> 右 -> 下 -> 左 this.trackUp = this.spinAnimation.setAnimation(1, 'up', true);this.trackright = this.spinAnimation.setAnimation(4, 'left', true);this.trackdown = this.spinAnimation.setAnimation(3, 'down', true);this.trackleft = this.spinAnimation.setAnimation(2, 'right', true);//眨眼睛动画this.spinAnimation.addAnimation(5, 'blink', true, 2);this.trackUp.alpha = 0;this.trackright.alpha = 0;this.trackdown.alpha = 0;this.trackleft.alpha = 0;}onBtnTop() {this.trackUp.alpha = 1;this.trackright.alpha = 0;this.trackdown.alpha = 0;this.trackleft.alpha = 0;}onBtnRight() {this.trackUp.alpha = 0;this.trackright.alpha = 1;this.trackdown.alpha = 0;this.trackleft.alpha = 0;}onBtnBottom() {this.trackUp.alpha = 0;this.trackright.alpha = 0;this.trackdown.alpha = 1;this.trackleft.alpha = 0;}onBtnleft() {this.trackUp.alpha = 0;this.trackright.alpha = 0;this.trackdown.alpha = 0;this.trackleft.alpha = 1;}onBtnRightTop() {this.trackleft.alpha = 0.0;this.trackdown.alpha = 0.0;this.trackright.alpha = 0.5;this.trackUp.alpha = 0.5;}onBtnRightBottom() {this.trackUp.alpha = 0;this.trackleft.alpha = 0;this.trackright.alpha = 0.5;this.trackdown.alpha = 0.5;}onBtnleftBottom() {this.trackUp.alpha = 0;this.trackright.alpha = 0;this.trackleft.alpha = 0.5;this.trackdown.alpha = 0.5;}onBtnleftTop() {this.trackdown.alpha = 0;this.trackright.alpha = 0;this.trackleft.alpha = 0.5;this.trackUp.alpha = 0.5;}public updateAnimation(vec2: Vec2) {//console.log('updateAnimation:', vec2);this.ver2Normal.x = Math.abs(vec2.x);this.ver2Normal.y = Math.abs(vec2.y);//右上if (vec2.x > 0 && vec2.y > 0) {this.trackleft.alpha = 0.0;this.trackdown.alpha = 0.0;this.trackright.alpha = this.ver2Normal.x;this.trackUp.alpha = clamp(this.ver2Normal.y, 0, 1 - this.ver2Normal.x);//右下} else if (vec2.x > 0 && vec2.y < 0) {this.trackUp.alpha = 0;this.trackleft.alpha = 0;this.trackright.alpha = this.ver2Normal.x;this.trackdown.alpha = clamp(this.ver2Normal.y, 0, 1 - this.ver2Normal.x);//左下} else if (vec2.x < 0 && vec2.y < 0) {this.trackUp.alpha = 0;this.trackright.alpha = 0;this.trackleft.alpha = this.ver2Normal.x;this.trackdown.alpha = clamp(this.ver2Normal.y, 0, 1 - this.ver2Normal.x);//左上} else if (vec2.x < 0 && vec2.y > 0) {this.trackright.alpha = 0;this.trackdown.alpha = 0;this.trackleft.alpha = this.ver2Normal.x;this.trackUp.alpha = clamp(this.ver2Normal.y, 0, 1 - this.ver2Normal.x);} else {this.trackUp.alpha = 0;this.trackright.alpha = 0;this.trackdown.alpha = 0;this.trackleft.alpha = 0;}}public resetAnimation() {this.trackUp.alpha = 0;this.trackright.alpha = 0;this.trackdown.alpha = 0;this.trackleft.alpha = 0;}}

工程下载

http://www.lryc.cn/news/494415.html

相关文章:

  • 《Python基础》之Python中可以转换成json数据类型的数据
  • 在oracle下载jdk显示400 Bad Request Request Header Or Cookie Too Large
  • MongoDB注入攻击测试与防御技术深度解析
  • 【Java基础入门篇】前言
  • Oracle 建表的存储过程
  • 【Debug】hexo-github令牌认证 Support for password authentication was removed
  • torch.is_floating_point(input)
  • 【分布式】分布式事务
  • Spring Data 简介
  • 【娱乐项目】基于批处理脚本与JavaScript渲染视频列表的Web页面
  • [MySQL]流程控制语句
  • Flink在Linux系统上的安装与入门
  • 微信小程序Webview与H5通信
  • Debezium Engine监听binlog实现缓存更新与业务解耦
  • docker搭建socks5代理
  • scanf函数和printf函数的格式化输入输出
  • Day31 贪心算法 part05
  • uniapp连接mqtt频繁断开原因和解决方法
  • 【数据结构-队列】力扣641. 设计循环双端队列
  • leetcode3250. 单调数组对的数目 I,仅需1s
  • 安全基线检查
  • C#读取本地图像的方法总结
  • 力扣81:搜索旋转排序数组II
  • 信息系统项目管理-论文写作方法之背景二
  • 使用ffmpeg命令实现视频文件间隔提取帧图片
  • 我们项目要升级到flutter架构的几点原因
  • 【简单好抄保姆级教学】javascript调用本地exe程序(谷歌,edge,百度,主流浏览器都可以使用....)
  • ElasticSearch为什么不能在query阶段直接返回_id,从而避免fetch?
  • 网安瞭望台第5期 :7zip出现严重漏洞、识别网络钓鱼诈骗的方法分享
  • 获 2023 年度浙江省科学技术进步奖一等奖 | 网易数智日报