打字稿:无法从另一个模块调用函数

时间:2013-03-09 18:45:37

标签: javascript typescript

我目前的项目是一款简单的多人游戏。客户端和服务器都是用Typescript编写的。客户端只处理输入并呈现游戏,所有逻辑都在服务器端实现。

服务器代码使用nodejs执行,结构如下

  • main.ts包含一个快速服务器,并使用客户端脚本提供html文件。此外,它设置了socket.io,创建了一个新的Game实例,并为每个连接的套接字创建了一个Player的新实例。

  • game.ts导出类GamePlayerGame实际上只是所有重要数据的容器。它存储所有玩家的列表和所有游戏对象的列表。 Game实现方法requestSpawn(...),它检查是否可能生成新的gameObject。类Player只是socket.io套接字的包装器。它处理传入和传出的消息。如果客户端尝试生成GameObject,则会向服务器发送一条消息,并将消息发送到存储在Player实例中的套接字。然后,Player实例会调用requestSpawn来尝试生成所需的GameObject

  • GameObjects.ts导出接口GameObject以及此接口的各种实现。

游戏运行如下:

  1. 某人点击了html-canvas
  2. 打包新的“REQUESTSPAWN”消息并将其发送到服务器
  3. Player个实例收到该邮件并在其requestSpawn
  4. 的实例上调用Game
  5. Game实例在正确位置创建正确类型的新GameObject,并将其添加到GameObjects
  6. 列表中
  7. 现在应该更新这个新的GameObject
  8. 它不是。 这是相关的代码:

    game.ts

    import go = module("GameObjects"); 
    import util = module("Utilities");
    
    //...
    
    export class Game {
        private players: Player[];
        public gameObjects:go.GameObject[];
        private gameObjectCounter: number;
    
        constructor() {
            this.players = [];
            this.gameObjectCounter = 0;
            this.gameObjects = [];
            var prev = Date.now();
            var deltaTime = Date.now() - prev;
            setInterval(() =>{ deltaTime = Date.now() - prev; prev = Date.now(); this.update(deltaTime); }, 200);
        }
    
        broadcast(msg: Message) {
            this.players.forEach((player) => { player.send(msg); });
        }
    
        requestSpawn(msg:RequestSpawnMessage, clientID:number): bool {
            var pos = new util.Vector2(msg.x, msg.y);        
            var o: go.GameObject;
            switch (msg.tag) {
                case UID.FACTORY:                                        
                    o = new go.Factory(pos.clone(), this.players[clientID], this.newGameObject());
                case UID.ROBOT:
                    o = new go.Robot(pos.clone(), this.players[clientID], this.newGameObject());
            }
            this.broadcast(new SpawnMessage(msg.tag, o.id, clientID, pos.x, pos.y));
            this.gameObjects.push(o);
            console.log(this.gameObjects);
            o.update(1);
            console.log("tried to update the factory");
            return true;
        }
    
        update(deltaTime){
            this.gameObjects.forEach((object) =>{object.update(deltaTime); });
        }
    
        addPlayer(socket: Socket) {        
            var player = new Player(this, socket, this.players.length);
            this.players.push(player);
        }
        newGameObject() : number {
            return this.gameObjectCounter++;
        }
    }
    

    GameObjects.ts

    export import util = module("Utilities");
    export import s = module("server");
    export import g = module("game");
    
    export interface GameObject{
        tag: g.UID;
        id:number;
        player: g.Player;
        clientId: number;
        pos:util.Vector2;
        getPos():util.Vector2;
        setPos(newPos:util.Vector2);
        // !TODO how to make that const?
        boundingBox: util.Rectangle;
        update(deltaTime:number);
    }
    
    export class Factory implements GameObject {
        tag: g.UID;
        id: number;
        player: g.Player;
        clientId: number;
        server: s.Server;
        //variables for handling the delay between spawning robots
        private current_time: number;
        public delay: number;
        boundingBox: util.Rectangle;
    
        public static dimensions = new util.Vector2(30, 30);
        constructor(pos: util.Vector2, player:g.Player, id: number) {
            this.pos = pos;
            this.tag = g.UID.FACTORY;
            this.player = player;
            this.clientId = this.player.getID();
            this.current_time = 0;
            this.delay = 1;
            this.id = id;
            this.boundingBox = new util.Rectangle(pos, Factory.dimensions.x, Factory.dimensions.y);
            console.log("just created a factory");
            //this.update(1);
        }
    
        pos: util.Vector2;
        getPos() { return this.pos; }
        setPos(pos: util.Vector2) { this.pos = pos; }
    
        public once = true;
        //check if it's time to create a new robot
        public update(deltaTime: number) {
            console.log("updating a factory");
    
            //this code will produce a robot just once, this is handy for development, since there's not so much waiting time
            if (this.once) { this.player.requestSpawn(g.UID.ROBOT, this.pos.x, this.pos.y); console.log("just spawned a robot"); }
            this.once = false;
            /*this.current_time += deltaTime/1000;
            if (this.current_time > this.delay*(Factory.count+1)/(Mine.count+1)) {
                this.current_time = 0;
                this.spawnRobot();
            }*/
        }
    }
    
    
    //this will be the fighting robot meant to destroy enemy factories
    export class Robot implements GameObject{
        tag: g.UID;
        id: number;
        player:g.Player;
        clientId: number;
        game: g.Game;
        boundingBox: util.Rectangle;
        // ! TODO constants should have capital letters.
        public static radius = 15;
        constructor(pos:util.Vector2,player:g.Player,id:number){ 
            this.tag = g.UID.ROBOT;
            this.player=player;
            this.clientId = this.player.getID();
            this.boundingBox = new util.Rectangle(pos, Robot.radius, Robot.radius);
        }
    
        pos:util.Vector2;
        getPos(){return this.pos;}
        setPos(pos:util.Vector2){this.pos=pos;}
    
        //now the robot is moved by keyboard input but soon it will check the gameObjects array and search for the closest enemy,
        //in order to attack it
        public update(deltaTime: number) {
    
        }
    }
    

    现在,工厂实例的更新方法的第一次调用产生一个机器人,之后工厂“休眠”。机器人在更新方法中什么都不做。

    我想引导你看两行代码:   - 在requestSpawn方法中,GameObject会立即更新deltaTime = 1

    这意味着在产生工厂之后,也应该产生一个机器人。但这不会发生。我在console.log方法中添加了requestSpawn次调用。它成功地打印出“刚刚尝试更新工厂”,但是没有任何反应。 所以我认为更新方法无法正常工作,并在那里添加了console.log调用。这是Factory's update方法的第一行,应该打印“更新工厂”。但这从未发生过。

    我真的很困惑。应该调用该方法,但事实并非如此。虽然它是公开的,但我认为问题可能与访问权限有关。所以这是第二行代码,我想指出:   - 在工厂的构造函数中,我已经注释了对this.update(1)的调用。

    我认为至少自己的构造函数应该能够调用update方法。的确是。如果未注释掉该行,则会调用update一次。然后工厂尝试生成一个新机器人并在其requestSpawn()实例上调用Game。结果,创建了一个新的机器人,并向所有客户发出SpawnMessage。机器人甚至出现在客户端的浏览器选项卡中。

    因此,很明显该方法未被调用。一切正常,消息解析,工厂更新和机器人创建都是正确的。唯一的问题是所有来自Game内的更新调用都不会被执行。出了什么问题?

0 个答案:

没有答案