• JSBinding / About 2048 sample


    2048 Source

    2048 source code is here:

    https://github.com/gabrielecirulli/2048

    Play here!
    http://gabrielecirulli.github.io/2048/

     

    The code contains 2 parts: logic and presentation(ui, animation, etc.). 

    In order to make it run in Unity editor, JSBinding rewrited presentation part. JSBinding only made slight change to logic part(less than 5 lines).

     

    Presentation code contains:

    1. storage (store last game state)
    2. input manager (handle input)
    3. actuator (ui, animation)

     

    JSBinding's storage code

    It's quite simple, just use PlayerPrefs to store int and string.

    var UnityStorageManager = function () {
        var bestScoreKey = "2048BestScroe";
        var gameStateKey = "2048GameState";
    
        this.getBestScore = function () {
            var bs = UnityEngine.PlayerPrefs.GetInt$$String$$Int32(bestScoreKey, 0);
            return bs;
        }
        this.setBestScore = function (bestScore) {
            UnityEngine.PlayerPrefs.SetInt(bestScoreKey, bestScore);
        }
    
    
        this.clearGameState = function () {
            UnityEngine.PlayerPrefs.SetString(gameStateKey, "");
        }
        this.getGameState = function () {
            var gameState = UnityEngine.PlayerPrefs.GetString$$String$$String(gameStateKey, "");
            if (gameState != null && gameState.length > 0) {
                return JSON.parse(gameState);
            }
        }
        this.setGameState = function (gameState) {
            UnityEngine.PlayerPrefs.SetString(gameStateKey, JSON.stringify(gameState));
        }
    }

     

    JSBinding's input manager code

    It's quite simple as well, not much difference from original. It cooperates with ui_controller, see below.

    var InputManager = function () {
        var events = {};
    
        this.on = function (e, cb) {
            if (!events[e]) {
                events[e] = [];
            }
            events[e].push(cb);
        }
        
        this.emit = function (e, data) {
            var cbs = events[e];
            if (cbs) {
                cbs.forEach(function(cb) {
                    cb(data);
                });
            }
        }
        
        this.keepPlaying = function () {
            //print("InputManager.keeyPlaying");
        }
    }

     

    JSBindng's actuator code

    var Actuator = function (ui) {
    
        this.continueGame = function () {
            print("Actuator.continueGame");
        }
      
        this.actuate = function (grid, metadata) {
            var self = this;
            
            self.clearContainer(self.tileContainer);
            
            grid.cells.forEach(function (column) {
                column.forEach(function (tile) {
                    if (tile) {
                        self.addTile(tile);
                    }
                });
            });
                    
            self.updateScore(metadata.score);
            self.updateBestScore(metadata.bestScore);
    
            if (metadata.terminated) {
                if (metadata.over) {
                    self.message(false); // You lose
                } 
                else if (metadata.won) {
                    self.message(true); // You win!
                }
            }
        }
        
        this.clearContainer = function () {
            ui.clearUITiles();
        }
        
        this.addTile = function (tile) {
            var position  = tile.previousPosition || { x: tile.x, y: tile.y };
            
            var uiTile = ui.getUITile(tile.x, tile.y)        
            uiTile.setValue(tile.value);
            
            if (tile.previousPosition) {
                var previousUITile = ui.getUITile(tile.previousPosition.x, tile.previousPosition.y);
                uiTile.moveFrom(previousUITile.originPos);
            }
            
            else if (tile.mergedFrom) {
                tile.mergedFrom.forEach(function (merged) {
                    //print("merged from (" + merged.x + "," + merged.y + ") -> (" + tile.x + "," + tile.y + ")");
                    var tempUITile = ui.createTempUITile(tile.x, tile.y);
                    tempUITile.setValue(merged.value);
                    var previousUITile = ui.getUITile(merged.previousPosition.x, merged.previousPosition.y);
                    tempUITile.moveFromTo(previousUITile.originPos, uiTile.originPos, true);
                });
                
                uiTile.playMergedAnim();
            }
            
            else {
                uiTile.playBornAnim();
            }
        }
        
        this.message = function (won) {
            //var type    = won ? "game-won" : "game-over";
            //var message = won ? "You win!" : "Game over!";
    
            ui.showResult(won);
        }
        
        this.continueGame = function () { 
            //print("continueGame"); 
        }
        
        var ls = null;
        this.updateScore = function (score) { 
            if (ls == null || ls != score) {
                if (ls != null) {
                    var a = ui.oScore.GetComponent$1(UnityEngine.Animator.ctor);
                    a.set_enabled(true);
                    a.Play$$Int32(0);
                }
    
                ls = score;
                ui.oScore.set_text(score.toString());
            }
        }
        
        var lbs = null;
        this.updateBestScore = function (score) {
            if (lbs == null || lbs != score) {
                if (lbs != null) {
                    var a = ui.oBestScore.GetComponent$1(UnityEngine.Animator.ctor);
                    a.set_enabled(true);
                    a.Play$$Int32(0);
                }
    
                lbs = score;
                ui.oBestScore.set_text(score.toString());
            }
        }
        
    }    

     

    ui_controller (handle Unity stuff)

    It does everything related to Unity. Serialization, input detection, Unity UI stuff, animation, etc.

    var gameManager = null;
    
    jss.define_mb("UIController", function() {
        "use strict";// gameObject
        this.oTileRoot = null;
        
        // text
        this.oScore = null;
        this.oBestScore = null;
    
        // button
        this.oNewGame = null;
        
        var size = 4;    
        var uiTiles = [];
        var inputMgr, actuator, storageMgr;
        
        var keyCode =  [273, 275, 274, 276];
        var keyCodeString = ["Up", "Right", "Down", "Left"];
        var keyCodeData = [0, 1, 2, 3];
        
        var createUITile = function (trans) {
            var t = {
                trans: trans,
                image: trans.GetComponent$1(UnityEngine.UI.Image.ctor),
                
                setValue: function(v) {
                    this.image.set_sprite(UnityEngine.Resources.Load$1$$String(UnityEngine.Sprite.ctor, "2048/"+v.toString()));
                    this.setVisible(true);
                },
    
                moveFromTo : function (fromPos, toPos, destroyAfterFinish) {
                    this.movement.moveFromTo(fromPos, toPos, destroyAfterFinish);
                },
    
                moveFrom: function (fromPos, destroyAfterFinish) {
                    this.moveFromTo(fromPos, this.originPos, destroyAfterFinish);
                },
    
                setVisible: function (visible) {
                    this.image.set_enabled(visible);
                }
            };
            
            t.originPos = t.trans.get_position();
            t.movement = t.trans.GetComponent$1(jss.TileMovement);
            t.animator = t.trans.GetComponent$1(UE.Animator.ctor);
            t.animator.set_enabled(false);
            
            t.playMergedAnim = function () {
                this.animator.set_runtimeAnimatorController(UnityEngine.Resources.Load$1$$String(UnityEngine.RuntimeAnimatorController.ctor, "2048/MergedCtrl"));
                this.animator.set_enabled(true);
                this.animator.Play$$Int32(0);
            }
    
            t.playBornAnim = function () {
                this.animator.set_runtimeAnimatorController(UnityEngine.Resources.Load$1$$String(UnityEngine.RuntimeAnimatorController.ctor, "2048/BornCtrl"));
                this.animator.set_enabled(true);
                this.animator.Play$$Int32(0);
            }
            
            return t;
        }
        
        this.clearUITiles = function () {
            for (var i = 0; i < uiTiles.length; i++) {
                uiTiles[i].setVisible(false);
            }
        }
        
        this.getUITile = function (i, j) {
            return uiTiles[i + j * size];
        }
    
        this.createTempUITile = function (copy_i, copy_j) {
            var transCopy = this.getUITile(copy_i, copy_j).trans;
            var goCopy = transCopy.get_gameObject();
            var go = UnityEngine.Object.Instantiate$$Object(goCopy);
            var trans = go.get_transform();
            trans.SetParent$$Transform$$Boolean(transCopy.get_parent(), false);
            trans.set_position(transCopy.get_position());
            trans.SetSiblingIndex(0);
            return createUITile(trans);
        }
    
        var btn_helper = function (parent, path, active, cb) {
            var btn = parent.FindChild(path).GetComponent$1(UnityEngine.UI.Button.ctor);
            btn.get_gameObject().SetActive(active);
            if (active) {
                btn.get_onClick().RemoveAllListeners();
                btn.get_onClick().AddListener$$UnityAction(cb);
            }
        }
    
        this.oMsgBox = null;
        this.showResult = function (win) {
            this.oMsgBox.SetActive(true);
    
            var trans = this.oMsgBox.get_transform();
    
            var msg = trans.FindChild("Message").GetComponent$1(UnityEngine.UI.Text.ctor);
            msg.set_text(win ? "You won!" : "Game over!");
    
            btn_helper(trans, "NewGameButton", win, function () {
                this.oMsgBox.SetActive(false);
                inputMgr.emit("restart");
            }.bind(this));
    
            btn_helper(trans, "ContinuePlayButton", win, function () {
                this.oMsgBox.SetActive(false);
                inputMgr.emit("keepPlaying");
            }.bind(this));
    
            btn_helper(trans, "RetryButton", !win, function () {
                this.oMsgBox.SetActive(false);
                inputMgr.emit("restart");
            }.bind(this));
        }
        
        this.Start = function () {
            // init ui tiles
            var parent = this.oTileRoot.get_transform();
            var chCount = parent.get_childCount();
            for (var i = 0; i < chCount; i++) {
                var child = parent.GetChild(i);
                uiTiles.push(createUITile(child));
            }
            
            inputMgr = new InputManager();
            actuator = new Actuator(this);
            storageMgr = new UnityStorageManager();
    
            // 
            this.oNewGame.get_onClick().AddListener$$UnityAction(function () {
                inputMgr.emit("restart");
            });
            
            // start game
            gameManager = new GameManager(size, inputMgr, actuator, storageMgr);
        }
        
        this.listen = function () {
            if (UnityEngine.Application.get_isMobilePlatform()) {
                var md = this.md = this.md || {};
    
                var I = UnityEngine.Input;
                if (I.get_touchCount() == 1) {
                    if (md.state == 2) {
                        return;
                    }
    
                    var p = I.get_mousePosition();
                    if (md.state == 0) {
                        md.initpos = p;
                        md.state = 1;
                    } else {
                        var dis = UnityEngine.Vector3.Distance(p, md.initpos);
                        if (dis > 20) {
                            var xd = Math.abs(p.x - md.initpos.x);
                            var yd = Math.abs(p.y - md.initpos.y);
                            if (xd > yd) {
                                inputMgr.emit("move", p.x > md.initpos.x ? 1 : 3);
                            } else {
                                inputMgr.emit("move", p.y > md.initpos.y ? 0 : 2);
                            }
                            md.state = 2;
                        }
                    }
                } else {
                    md.state = 0;
                }
            } else {
                for (var i = 0; i < keyCode.length; i++) {
                    if (UnityEngine.Input.GetKeyDown$$KeyCode(keyCode[i])) {
                        inputMgr.emit("move", keyCodeData[i]);
                        break;
                    }
                }
    
            }
        }
        
        this.Update = function () {
            this.listen();
        };
    });

     

    tilemovement

    Moves tile from pos (i,j) to pos (x,y). If the tile is temporary, destroy it after move.

    jss.define_mb("TileMovement", function () {
        this.Awake = function() {
            this.trans = this.get_transform();
        }
        
        this.moving = false;
        
        var $cv = { Value: UnityEngine.Vector3.get_zero() };
        this.Update = function () {
            if (!this.moving) {
                return;
            }
        
            var newPos = UnityEngine.Vector3.SmoothDamp$$Vector3$$Vector3$$Vector3$$Single(
                    this.trans.get_position(),
                    this.toPos,
                    $cv,
                    0.07);
    
            this.trans.set_position(newPos);
    
            var dis = UnityEngine.Vector3.Distance(newPos, this.toPos);
            if (dis < 0.001) {
                this.moving = false;
    
                if (this.destroyAfterFinish) {
                    UnityEngine.Object.Destroy$$Object(this.get_gameObject());
                }
            }
        }
        
        this.moveFromTo = function (fromPos, toPos, destroyAfterFinish) {
            this.toPos = toPos;
            this.destroyAfterFinish = destroyAfterFinish;
            this.moving = true;
            this.trans.set_position(fromPos);
        }
    });

     

    back to JSBinding / Home

  • 相关阅读:
    CopyOnWriteArrayList源码阅读笔记
    ArrayList源码阅读笔记
    MySQL和Oracle的区别
    思维导图概览SpringCloud
    Java学习之Request篇
    Java学习之servlet篇
    Java学习之数据库连接池
    Java学习之注解篇
    Java爬取先知论坛文章
    Java学习之爬虫篇
  • 原文地址:https://www.cnblogs.com/answerwinner/p/5647220.html
Copyright © 2020-2023  润新知