사용자 정의 E에서 (🍮)))

Akashic Advent Calendar 2019 7일째 보도입니다.
Akashic Engine은 화면에 이미지와 텍스트 등을 표시하기 위해 다양한 종류를 준비했다.그것들은 모두 g.E의 파생류로 실현되었다.이 글은 좀 이상한g.E의 파생류로서 append()의 요소를 모두 푸딩처럼 끌어낸 E(앞으로는 사용자 정의 E)를 실현하고자 한다.

목표 확인


일단 완성형부터 확인해보자.

푸딩의 초상화 사용여기의 물건.
푸딩이 눌리면 팝업됩니다.푸딩의 이미지는 사용자 정의 E에서 동작하는 g.Sprite로 표시됩니다.

두 가지 과제


푸딩을 실현하기 위해서는 떨림 운동과 이미지 변형 두 가지 기능이 필요하다.하나하나 연구하다.

떨리는 운동


나는 떨리는 운동을 고려할 것이다.푸딩이 변형되면 원래의 모양을 회복합니다.이것은 용수철의 운동과 유사하다.
스프링 중 하나는 고정되고 다른 하나는 연결점을 고려한다.질점을 이동할 때, 그것은 진동하여 원래의 위치로 돌아갈 것이다.
+∂∂∂∂∂∂∂∂∂∂∂∂∂∂∂∂∂∂∂∂∂∂∂●
|-------- len ---------|
  • +: 스프링을 고정하는 위치.
  • ●:질점
  • len: 스프링의 자연 길이(미신축, 원시 길이).
  • 스프링 동작에 필요한 매개변수도 있습니다.
  • k: 용수철 계수.용수철의 신축력을 얻는 데 쓰이는 양.
  • m: 질점의 무게.
  • d: 질점 속도를 감소시키는 계수.
  • 이를 사용하여 용수철 앞부분에 설치된 질점의 운동을 전선 형식으로 표현해 보세요.
    /**
     * バネの先端に取り付けられた質点の位置と速度を求める。
     * 
     * @param dt 経過時間。
     * @param x 質点の位置。
     * @param v 質点の速度。
     */
    function massSpringSolver(dt: number, x: number, v: number): { x: number, v: number } {
        const k = 64; // バネ係数。
        const len = 10; // バネの自然長。
        const m = 1; // バネの先端に繋がれた質点の質量。
        const d = 0.95; // 徐々に減速させるための値。
    
        const dx = x - len; // バネの伸び縮みを求める。
        const f = -dx * k; // 伸び縮みにバネ係数をかけて、質点に加わる力を求める。
        const a = f / m; // 質点に加わっている力を質点の質量で割って、加速度を求める。
    
        v += a * dt; // 質点を加速させる。
        v *= d; // 質点が徐々に静止するよう、速度を減衰させる。
        x += v * dt; // 速度に応じて質点の位置を更新する。
    
        return { x, v }; // 新しい質点の位置と速度を返す。
    }
    
    진동하면서 천천히 제자리로 돌아가는 처리를 할 수 있다.

    이미지 변형


    다음은 질점 운동 변형 이미지를 사용하는 것을 고려한다.
    Akashic Engine을 담당하는 렌더링 기능g.Renderer은 이미지의 변환, 회전, 확대/축소에 행렬을 사용합니다.행렬은 2행 3열로 코드에 1차원 그룹으로 표시됩니다.
    const matrix = [
        a, b,
        c, d,
        e, f
    ];
    
    이 여섯 개의 수치는 어떤 작용을 합니까?상세히 말하면 생략, (a,b)는 X축을 변형시키고, (c,d)는 Y축을 변형시키는 작용을 한다.
    다음 행렬은 변환, 회전, 배율 조정되지 않습니다.
    const matrix = [
        1, 0,
        0, 1,
        0, 0
    ];
    
    다음 행렬은 Y축 방향을 따라 두 배로 확대됩니다.
    const matrix = [
        1, 0,
        0, 2,
        0, 0
    ];
    
    만약 대열에 스프링의 힘으로 운동하는 질점의 위치를 잘 편입시키면 잡아당기는 변형으로 실현될 수 있다.

    완성


    진동하는 방법과 그것을 변형시키는 방법을 알게 되었다.이러한 내용이 포함된 사용자 정의 EPuddinizer 코드는 다음과 같습니다.
    interface PuddinizerParameterObject extends g.EParameterObject {
        /** バネ定数 */
        k: number;
    
        /** 質量 */
        m: number;
    
        /** 減衰係数 */
        d: number;
    }
    
    class Puddinizer extends g.E {
        private k: number;
        private m: number;
        private d: number;
        private px: number;
        private py: number;
        private vx: number;
        private vy: number;
    
        constructor(param: PuddinizerParameterObject) {
            super(param);
    
            this.k = param.k;
            this.m = param.m;
            this.d = param.d;
            this.px = 0;
            this.py = 0;
            this.vx = 0;
            this.vy = 0;
    
            // 毎フレーム自身を更新する。
            this.update.add(() => this.onUpdate());
        }
    
        /**
         * プリンを突っつく。
         *
         * @param px 質点の位置(X成分)
         * @param py 質点の位置(Y成分)
         * @param vx 質点の速度(X成分)
         * @param vy 質点の速度(Y成分)
         */
        poke(px: number, py: number, vx: number, vy: number): void {
            this.px = px;
            this.py = py;
            this.vx = vx;
            this.vy = vy;
        }
    
        renderSelf(renderer: g.Renderer, camera?: g.Camera): boolean {
            // ここで設定した行列が子の E に作用する。
            renderer.transform([
                1, 0,
                // Y軸を表す成分に質点の位置を加味する。
                0 + this.px, 1 + this.py,
                0, 0
            ]);
            return true;
        }
    
        private onUpdate(): void {
            const dt = 1 / g.game.fps;
    
            const ax = (-this.px * this.k) / this.m;
            const ay = (-this.py * this.k) / this.m;
    
            this.vx *= this.d;
            this.vy *= this.d;
            this.vx += ax * dt;
            this.vy += ay * dt;
            this.px += this.vx * dt;
            this.py += this.vy * dt;
    
            this.modified();
        }
    }
    
    진동의 계산은 onUpdate(), 그 행렬을 사용하는 설정은 renderSelf()이다.
    이전의 토론과 다음과 같은 몇 가지 차이가 있으니 주의하십시오.
  • 평면상의 진동을 계산하기 위해 px,py 두 변수로 질점의 위치를 표시한다.
  • 위치(0,0)에 고정된 자연 길이 0의 스프링에 질점을 연결하여 진동을 계산한다.
  • 밀어붙일 사용자 정의 E의 실현은 다음과 같다.Puddinizer의 프레젠테이션이 가능합니다GitHub에서 가져오기.

    마지막


    이 글에서 우리는 하위 요소에 대해 운동을 하는 사용자 정의 E를 실현했다.질량과 용수철 상수를 바꾸면 다양한 질감을 표현할 수 있다.게임이라면 슬라이더의 피해 표현도 사용할 수 있다.

    좋은 웹페이지 즐겨찾기