博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
50行代码实现3D模拟真实撒金币动效
阅读量:5791 次
发布时间:2019-06-18

本文共 3993 字,大约阅读时间需要 13 分钟。

我们将会用50行不到的代码来实现一个3D模拟撒金币动效。你只需要一点Egret基础就能够快速上手,如果你不了解Egret,这里有一篇来带你快速入门。

实现效果

源码和在线demo

  • 完整的工程请见:
  • 在线访问地址:

资源准备

图片序列帧在工程的design/coin下。我们需要用TextureMerge工具来创建一个精灵图(SpriteSheet)。具体方式查看 。最后将精灵图导入assets/文件夹,文件名为coin.jsoncoin.png

注意:序列帧图片的文件名为1.png~8.png

加载资源

我们通过精灵图的方式加载这8张序列帧图片。这里有一个工具函数:

const loadSpriteSheet: (keys: string[]) => Promise
复制代码

我们将精灵图的keys传入就可以获取到一个egret.SpriteSheet类型的对象,使用代码:

const keys = ['assets/coin.json', 'assets/coin.png'];const spritesheet = await loadSpriteSheet(keys);复制代码

注意:如果你想用来创建精灵图也是可以的,只是loadSpriteSheet函数需要有少许的变动。

创建序列帧图片动画

这里要引入一个工具类MovieClip(不要太在意类的命名 >.<)。看下API:

constructor MovieClip(    { spritesheet, frames, position, keys,frameInterval} :     {        spritesheet: egret.SpriteSheet;//精灵图        frames: string[];//序列帧的图片的文件名序列        position: number[];//设置动画位置        frameInterval?: number;//相邻图片播放间隔,单位是帧,这会控制动画的播放速度    }): MovieClip复制代码

下面这段代码将金币动画放置在{x:100,y:100}的位置,相邻图片播放间隔是3帧,图片的播放顺序是1.png~8.png

const animation = new MovieClip({    frameInterval: 3,    frames: ['1', '2', '3', '4', '5', '6', '7', '8'],    position: [100, 100],    spritesheet: spritesheet});this.addChild(animation);//显示动画复制代码

对动画增加真实的掉落效果

这里引入物理对象工具类Body

constructor Body({ x, y, vx, vy, gx, gy, host }: {    x: number;//起始x    y: number;//起始y    vx: number;//起始x方向速度    vy: number;//起始y方向速度    gx: number;//x方向重力    gy: number;//y方向重力    host: egret.DisplayObject;//宿主显示对象}): Body复制代码

下面是使用代码:

const x = 750 / 2;const y = 750 / 2;const vx = 10;const vy = -10;const animation = this.createCoinMovieClip(spritesheet);const falling = new Body({    x: x, y: y, vx: vx, vy: vy, gy: 1, host: animation});复制代码

创建3D模拟撒金币

main.ts增加创建单个动画的函数:

createCoinMovieClip(spritesheet) {    const animation = new MovieClip({        frameInterval: 3,        frames: ['1', '2', '3', '4', '5', '6', '7', '8'],        loop: true,        position: [100, 100],        spritesheet: spritesheet    });    return animation;}复制代码

我们来创建100个金币动画,并设置随机的起始位置和速度,重力设置为1。你可以调整其中的各种参数来获得你想要的效果。

let coinsFall = setInterval(() => {    if (count < 100) {        const x = 750 / 2 + Math.random() * 50 - 25;        const y = 750 / 2 + Math.random() * 50 - 25;        const vx = Math.random() * 20 - 10;        const vy = -10 + Math.random() * 10 - 5;        const animation = this.createCoinMovieClip(spritesheet);        const falling = new Body({            x: x, y: y, vx: vx, vy: vy, gy: 1, host: animation        });        this.addChild(animation);        count++;    } else {        //结束    }}, 10)复制代码

完整的代码

可以看出,我们只用了50行不到的代码就实现了一个真实的撒金币效果。

import Body from "./physics/Body";import loadSpriteSheet from "./utils/loadSpriteSheet";import MovieClip from "./movieclip/MovieClip";class Main extends egret.DisplayObjectContainer {    constructor() {        super();        this.once(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);    }    async onAddToStage() {        const keys = ['assets/coin.json', 'assets/coin.png'];        const spritesheet = await loadSpriteSheet(keys);        let count = 0;        let coinsFall = setInterval(() => {            if (count < 100) {                const x = 750 / 2 + Math.random() * 50 - 25;                const y = 750 / 2 + Math.random() * 50 - 25;                const vx = Math.random() * 20 - 10;                const vy = -10 + Math.random() * 10 - 5;                const animation = this.createCoinMovieClip(spritesheet);                const falling = new Body({                    x: x, y: y, vx: vx, vy: vy, gy: 1, host: animation                });                this.addChild(animation);                count++;            } else {                //结束            }        }, 10)    }    createCoinMovieClip(spritesheet) {        const animation = new MovieClip({            frameInterval: 3,            frames: ['1', '2', '3', '4', '5', '6', '7', '8'],            loop: true,            position: [100, 100],            spritesheet: spritesheet        });        return animation;    }}window['Main'] = Main;egret.runEgret();复制代码

转载地址:http://uhmyx.baihongyu.com/

你可能感兴趣的文章
iframe刷新问题
查看>>
数据解码互联网行业职位
查看>>
我所见的讲的最容易理解,逻辑最强的五层网络模型,来自大神阮一峰
查看>>
vue-cli项目打包需要修改的路径问题
查看>>
js实现复选框的操作-------Day41
查看>>
数据结构化与保存
查看>>
[SpringBoot] - 配置文件的多种形式及优先级
查看>>
chrome浏览器开发者工具之同步修改至本地
查看>>
debian7 + wheezy + chromium + flashplayer
查看>>
AOP
查看>>
进阶开发——文档,缓存,ip限速
查看>>
vue中子组件需调用父组件通过异步获取的数据
查看>>
uva 11468 - Substring(AC自己主动机+概率)
查看>>
Mysql 数据备份与恢复,用户创建,授权
查看>>
沉思录
查看>>
Angular.js中的$injector服务
查看>>
构建之法读书笔记01
查看>>
linux - lsof 命令最佳实践
查看>>
kafka性能测试
查看>>
现实世界的Windows Azure:h.e.t软件使用Windows Azure削减50%的成本
查看>>