50行代碼實現3D模擬真實撒金幣動效

咱們將會用50行不到的代碼來實現一個3D模擬撒金幣動效。你只須要一點Egret基礎就可以快速上手,若是你不瞭解Egret,這裏有一篇3分鐘建立hello world來帶你快速入門。html

實現效果

源碼和在線demo

資源準備

圖片序列幀在工程的design/coin下。咱們須要用TextureMerge工具來建立一個精靈圖(SpriteSheet)。具體方式查看 這裏 。最後將精靈圖導入assets/文件夾,文件名爲coin.jsoncoin.pnggit

注意:序列幀圖片的文件名爲1.png~8.pnggithub

加載資源

咱們經過精靈圖的方式加載這8張序列幀圖片。這裏有一個工具函數:web

const loadSpriteSheet: (keys: string[]) => Promise<egret.SpriteSheet>
複製代碼

咱們將精靈圖的keys傳入就能夠獲取到一個egret.SpriteSheet類型的對象,使用代碼:json

const keys = ['assets/coin.json', 'assets/coin.png'];
const spritesheet = await loadSpriteSheet(keys);
複製代碼

注意:若是你想用TexturePacker來建立精靈圖也是能夠的,只是loadSpriteSheet函數須要有少量的變更。dom

建立序列幀圖片動畫

這裏要引入一個工具類MovieClip(不要太在乎類的命名 >.<)。看下API:async

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
複製代碼

下面是使用代碼:oop

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();
複製代碼
相關文章
相關標籤/搜索