app.ts

作者: skoll | 来源:发表于2021-02-07 20:20 被阅读0次

    import "@babylonjs/core/Debug/debugLayer";
    import "@babylonjs/inspector";
    import "@babylonjs/loaders/glTF";
    import { Engine, Scene, Vector3, Mesh, Color3, Color4, ShadowGenerator, GlowLayer, PointLight, FreeCamera, CubeTexture, Sound, PostProcess, Effect, SceneLoader, Matrix, MeshBuilder, Quaternion, AssetsManager } from "@babylonjs/core";
    import { AdvancedDynamicTexture, StackPanel, Button, TextBlock, Rectangle, Control, Image } from "@babylonjs/gui";
    import {En1} from './environment/en1'

    // 游戏状态枚举
    enum State{Start=0,Game=1,Lose=2,Cutscene=3}

    class App {
    private _scene:Scene;
    private _canvas:HTMLCanvasElement;
    private _engine:Engine;

    private _state:number=0;
    
    private _transition:boolean=false
    
    constructor() {
        
        this._canvas=this._createCanvas()
        this._engine = new Engine(this._canvas, true);
        this._scene = new Scene(this._engine);
        
        window.addEventListener("keydown", (ev) => {
            // Shift+Ctrl+Alt+I
            if (ev.shiftKey && ev.ctrlKey && ev.altKey && ev.keyCode === 73) {
                if (this._scene.debugLayer.isVisible()) {
                    this._scene.debugLayer.hide();
                } else {
                    this._scene.debugLayer.show();
                }
            }
        });
    
        this._main()
    }
    private _createCanvas():HTMLCanvasElement{
        document.documentElement.style['overflow']='hidden'
        document.documentElement.style.overflow='hidden'
        document.documentElement.style.width='100%'
        document.documentElement.style.height='100%'
        document.documentElement.style.margin='0'
        document.documentElement.style.padding='0'
        document.body.style.overflow='hidden'
        document.body.style.width='100%'
        document.body.style.height='100%'
        document.body.style.margin='0'
        document.body.style.padding='0'
    
        this._canvas=document.createElement('canvas')
        this._canvas.style.width="100%"
        this._canvas.style.height="100%"
        this._canvas.id="gameCanvas"
        document.body.appendChild(this._canvas)
        return this._canvas
    }
    
    private async _main():Promise<void>{
        await this._gotoStart()
    
        this._engine.runRenderLoop(()=>{
            switch(this._state){
                case State.Start:
                    this._scene.render()
                case State.Cutscene:
                    this._scene.render()
                    case State.Game:
                        //if 240seconds/ 4mins have have passed, go to the lose state
                        // if (this._ui.time >= 240 && !this._player.win) {
                        //     this._goToLose();
                        //     this._ui.stopTimer();
                        // }
                        // if (this._ui.quit) {
                        //     this._goToStart();
                        //     this._ui.quit = false;
                        // }
                        this._scene.render();
                        break;
                    case State.Lose:
                        this._scene.render();
                        break;
                    default: break;
    
            }
        })
    }
    
    private async _gotoStart(){
        // 登陆界面
        this._scene.detachControl();
        let scene = new Scene(this._engine);
    
        scene.clearColor = new Color4(0, 0, 0, 1);
        let camera = new FreeCamera("camera1", new Vector3(0, 0, 0), scene);
        camera.setTarget(Vector3.Zero()); 
    
        const start=new Sound('startSong','./source/sounds/copycat(revised).mp3',scene,function(){},{
            volume:0.25,
            loop:true,
            autoplay:true
        })
        const sfx=new Sound('select','./source/sounds/vgmenuselect.wav',scene,function(){})
    
        // GUI
    
        const guiMenu = AdvancedDynamicTexture.CreateFullscreenUI("UI");
        guiMenu.idealHeight = 720;
    
        // backgroundImage 
        const imageRect=new Rectangle('titleContainer')
        imageRect.width=0.8
        imageRect.thickness=0
        guiMenu.addControl(imageRect)
    
        const startbg=new Image('startbg','../source/sprites/start.jpeg')
        imageRect.addControl(startbg)
    
        const title = new TextBlock("title", "SUMMER'S FESTIVAL");
        title.resizeToFit = true;
        title.fontFamily = "Ceviche One";
        title.fontSize = "64px";
        title.color = "white";
        title.resizeToFit = true;
        title.top = "14px";
        title.width = 0.8;
        title.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
        imageRect.addControl(title);
    
        const startBtn = Button.CreateSimpleButton("start", "PLAY");
        startBtn.fontFamily = "Viga";
        startBtn.width = 0.2
        startBtn.height = "40px";
        startBtn.color = "white";
        startBtn.top = "-14px";
        startBtn.thickness = 0;
        startBtn.verticalAlignment = Control.VERTICAL_ALIGNMENT_BOTTOM;
        imageRect.addControl(startBtn);
    
    
        Effect.RegisterShader("fade",
            "precision highp float;" +
            "varying vec2 vUV;" +
            "uniform sampler2D textureSampler; " +
            "uniform float fadeLevel; " +
            "void main(void){" +
            "vec4 baseColor = texture2D(textureSampler, vUV) * fadeLevel;" +
            "baseColor.a = 1.0;" +
            "gl_FragColor = baseColor;" +
            "}");
    
        let fadeLevel = 1.0;
        this._transition = false;
        scene.registerBeforeRender(() => {
            if (this._transition) {
                fadeLevel -= .05;
                if(fadeLevel <= 0){
                    this._gotoCutScene();
                    this._transition = false;
                }
            }
        })
    
        startBtn.onPointerClickObservable.add(()=>{
            const postProcess = new PostProcess("Fade", "fade", ["fadeLevel"], null, 1.0, camera);
            postProcess.onApply=(effect)=>{
                effect.setFloat("fadeLevel", fadeLevel);
            }
            this._transition=true
    
            sfx.play()
            scene.detachControl()
        })
    
        await scene.whenReadyAsync()
        this._engine.hideLoadingUI()
        this._scene.dispose()
        // 这里一开始错了
        this._scene=scene
        this._state=State.Start
    }
    
    private async _gotoCutScene(){
        // 主要是展示过场动画
        // this._engine.displayLoadingUI();
        this._scene.detachControl();
    
        let cutScene = new Scene(this._engine);
    
        let camera = new FreeCamera("camera1", new Vector3(0, 0, 0), cutScene);
        camera.setTarget(Vector3.Zero());
        cutScene.clearColor = new Color4(0, 0, 0, 1);
        
        const cutSceneUI = AdvancedDynamicTexture.CreateFullscreenUI("cutscene");
        let transition = 0;
        let canplay = false;
        let finished_anim = false;
        let anims_loaded = 0;
        let animTimer:any;
        let anim2Timer:any;
        let anim = 1;
    
        const beginning_anim=new Image('sparkLife','../source/sprites/beginning_anim.png')
        beginning_anim.stretch = Image.STRETCH_UNIFORM;
        beginning_anim.cellId = 0;
        beginning_anim.cellHeight = 480;
        beginning_anim.cellWidth = 480;
        beginning_anim.sourceWidth = 480;
        beginning_anim.sourceHeight = 480;
        cutSceneUI.addControl(beginning_anim);
        beginning_anim.onImageLoadedObservable.add(() => {
            anims_loaded++;
            console.log(anims_loaded)
        })
    
        const working_anim = new Image("sparkLife", "../source/sprites/working_anim.png");
        working_anim.stretch = Image.STRETCH_UNIFORM;
        working_anim.cellId = 0;
        working_anim.cellHeight = 480;
        working_anim.cellWidth = 480;
        working_anim.sourceWidth = 480;
        working_anim.sourceHeight = 480;
        working_anim.isVisible = false;
        cutSceneUI.addControl(working_anim);
        working_anim.onImageLoadedObservable.add(() => {
            anims_loaded++;
        })
        const dropoff_anim = new Image("sparkLife", "../source/sprites/dropoff_anim.png");
        dropoff_anim.stretch = Image.STRETCH_UNIFORM;
        dropoff_anim.cellId = 0;
        dropoff_anim.cellHeight = 480;
        dropoff_anim.cellWidth = 480;
        dropoff_anim.sourceWidth = 480;
        dropoff_anim.sourceHeight = 480;
        dropoff_anim.isVisible = false;
        cutSceneUI.addControl(dropoff_anim);
        dropoff_anim.onImageLoadedObservable.add(() => {
            anims_loaded++;
        })
        const leaving_anim = new Image("sparkLife", "../source/sprites/leaving_anim.png");
        leaving_anim.stretch = Image.STRETCH_UNIFORM;
        leaving_anim.cellId = 0;
        leaving_anim.cellHeight = 480;
        leaving_anim.cellWidth = 480;
        leaving_anim.sourceWidth = 480;
        leaving_anim.sourceHeight = 480;
        leaving_anim.isVisible = false;
        cutSceneUI.addControl(leaving_anim);
        leaving_anim.onImageLoadedObservable.add(() => {
            anims_loaded++;
        })
        const watermelon_anim = new Image("sparkLife", "../source/sprites/watermelon_anim.png");
        watermelon_anim.stretch = Image.STRETCH_UNIFORM;
        watermelon_anim.cellId = 0;
        watermelon_anim.cellHeight = 480;
        watermelon_anim.cellWidth = 480;
        watermelon_anim.sourceWidth = 480;
        watermelon_anim.sourceHeight = 480;
        watermelon_anim.isVisible = false;
        cutSceneUI.addControl(watermelon_anim);
        watermelon_anim.onImageLoadedObservable.add(() => {
            anims_loaded++;
        })
        const reading_anim = new Image("sparkLife", "../source/sprites/reading_anim.png");
        reading_anim.stretch = Image.STRETCH_UNIFORM;
        reading_anim.cellId = 0;
        reading_anim.cellHeight = 480;
        reading_anim.cellWidth = 480;
        reading_anim.sourceWidth = 480;
        reading_anim.sourceHeight = 480;
        reading_anim.isVisible = false;
        cutSceneUI.addControl(reading_anim);
        reading_anim.onImageLoadedObservable.add(() => {
            anims_loaded++;
        })
    
        //Dialogue animations
        const dialogueBg = new Image("sparkLife", "../source/sprites/bg_anim_text_dialogue.png");
        dialogueBg.stretch = Image.STRETCH_UNIFORM;
        dialogueBg.cellId = 0;
        dialogueBg.cellHeight = 480;
        dialogueBg.cellWidth = 480;
        dialogueBg.sourceWidth = 480;
        dialogueBg.sourceHeight = 480;
        dialogueBg.horizontalAlignment = 0;
        dialogueBg.verticalAlignment = 0;
        dialogueBg.isVisible = false;
        cutSceneUI.addControl(dialogueBg);
        dialogueBg.onImageLoadedObservable.add(() => {
            anims_loaded++;
        })
    
        const dialogue = new Image("sparkLife", "../source/sprites/text_dialogue.png");
        dialogue.stretch = Image.STRETCH_UNIFORM;
        dialogue.cellId = 0;
        dialogue.cellHeight = 480;
        dialogue.cellWidth = 480;
        dialogue.sourceWidth = 480;
        dialogue.sourceHeight = 480;
        dialogue.horizontalAlignment = 0;
        dialogue.verticalAlignment = 0;
        dialogue.isVisible = false;
        cutSceneUI.addControl(dialogue);
        dialogue.onImageLoadedObservable.add(() => {
            anims_loaded++;
        })
    
        // 加载了全部的过场动画
        let dialogueTimer = setInterval(() => {
            if(finished_anim && dialogueBg.cellId < 3){
                dialogueBg.cellId++;
            } else {
                dialogueBg.cellId = 0;
            }
        }, 250);
        // 对话的标志位
    
    
        const skipBtn = Button.CreateSimpleButton("skip", "SKIP");
        skipBtn.fontFamily = "Viga";
        skipBtn.width = "45px";
        skipBtn.left = "-14px";
        skipBtn.height = "40px";
        skipBtn.color = "white";
        skipBtn.top = "14px";
        skipBtn.thickness = 0;
        skipBtn.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
        skipBtn.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_RIGHT;
        cutSceneUI.addControl(skipBtn);
    
        skipBtn.onPointerDownObservable.add(()=> {
            cutScene.detachControl();
            clearInterval(animTimer);
            clearInterval(anim2Timer);
            clearInterval(dialogueTimer);
            this._engine.displayLoadingUI();
            canplay = true;
        });
    
        // 跳过剧情动画的操作
    
        const next = Button.CreateImageOnlyButton("next", "../source/sprites/arrowBtn.png");
        next.rotation = Math.PI / 2;
        next.thickness = 0;
        next.verticalAlignment = Control.VERTICAL_ALIGNMENT_BOTTOM;
        next.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_RIGHT;
        next.width = "64px";
        next.height = "64px";
        next.top = "-3%";
        next.left = "-12%";
        next.isVisible = false;
        cutSceneUI.addControl(next);
    
        next.onPointerUpObservable.add(() => {
            if (transition == 8) { 
                cutScene.detachControl();
                this._engine.displayLoadingUI(); 
                transition = 0;
                canplay = true;
            } else if(transition < 8){
                transition++;
                dialogue.cellId++;
            }
        })
        // 下一步操作
        
        // 自动处理动画的逻辑
        cutScene.onBeforeRenderObservable.add(()=>{
            if(anims_loaded==8){
                this._engine.hideLoadingUI()
                anims_loaded=0;
    
                animTimer=setInterval(()=>{
                    switch(anim) {
                        case 1:
                            if(beginning_anim.cellId == 9){ //each animation could have a different number of frames
                                anim++;
                                beginning_anim.isVisible = false; // current animation hidden
                                working_anim.isVisible = true; // show the next animation
                            } else {
                                beginning_anim.cellId++;
                            }
                            break;
                        case 2:
                            if(working_anim.cellId == 11){
                                anim++;
                                working_anim.isVisible = false;
                                dropoff_anim.isVisible = true;
                            } else {
                                working_anim.cellId++;
                            }
                            break;
                        case 3:
                            if(dropoff_anim.cellId == 11){
                                anim++;
                                dropoff_anim.isVisible = false;
                                leaving_anim.isVisible = true;
                            } else {
                                dropoff_anim.cellId++;
                            }
                            break;
                        case 4:
                            if(leaving_anim.cellId == 9){
                                anim++;
                                leaving_anim.isVisible = false;
                                watermelon_anim.isVisible = true;
                            } else {
                                leaving_anim.cellId++;
                            }
                            break;
                        default:
                            break;
                    }   
                },250)
    
                anim2Timer=setInterval(()=>{
                    switch(anim) {
                        case 5:
                            if(watermelon_anim.cellId == 8){
                                anim++;
                                watermelon_anim.isVisible = false;
                                reading_anim.isVisible = true;
                            } else {
                                watermelon_anim.cellId++;
                            }
                            break;
                        case 6:
                            if(reading_anim.cellId == 11){
                                reading_anim.isVisible = false;
                                finished_anim = true;
                                dialogueBg.isVisible = true;
                                dialogue.isVisible = true;
                                next.isVisible = true;
                            } else {
                                reading_anim.cellId++;
                            }
                            break;
                    }
                },750)
    
    
            }
    
            if(finishedLoading&&canplay){
                canplay=true
                this._goToGame()
            }
        })
    
    
    
        // 最后的处理
        await cutScene.whenReadyAsync();
        this._scene.dispose();
        this._state = State.Cutscene;
        this._scene = cutScene;
    
        var finishedLoading=false
        await this._setUpGame().then((res)=>{
            finishedLoading=true
        })
    }
    
    private async _goToLose():Promise<void>{
        this._engine.displayLoadingUI();
        //--SCENE SETUP--
        this._scene.detachControl();
        let scene = new Scene(this._engine);
        scene.clearColor = new Color4(0, 0, 0, 1);
        let camera = new FreeCamera("camera1", new Vector3(0, 0, 0), scene);
        camera.setTarget(Vector3.Zero());
        //--GUI--
        const guiMenu = AdvancedDynamicTexture.CreateFullscreenUI("UI");
        const mainBtn = Button.CreateSimpleButton("mainmenu", "MAIN MENU");
        mainBtn.width = 0.2;
        mainBtn.height = "40px";
        mainBtn.color = "white";
        guiMenu.addControl(mainBtn);
        mainBtn.onPointerUpObservable.add(() => {
            this._gotoStart();
        });
        //--SCENE FINISHED LOADING--
        await scene.whenReadyAsync();
        this._engine.hideLoadingUI(); 
        this._scene.dispose();
        this._scene = scene;
        this._state = State.Lose;
    }
    private async _goToGame():Promise<void>{
        
    }
    
    private async _setUpGame(){
        let scene=new Scene(this._engine)
        const environment = new En1(scene);
        // this._environment = environment; //class variable for App
        await environment.load();
    }
    

    }
    new App();

    相关文章

      网友评论

          本文标题:app.ts

          本文链接:https://www.haomeiwen.com/subject/joqtxltx.html