Jump to content

How to separate logic into separate files?


Vignarg
 Share

Recommended Posts

Hello all, first time post. 

 

I'm trying to separate my logic into separate files. I understand the statemanager enough to separate states. I can separate parts that have a constructor easily enough ( like a hero), and those create/update according to the rules in those files just fine. But I can't seem to manage it when there's no direct construction. 

 

Specifically this time, I'm trying to do it with the camera. I put the logic in the teststage file, and it works fine. I'm trying to separate it out, as I want the same logic to be called from any level I call it from, rather than write it into every level state. 

 

Written with TS. 

 

Camera File:

/// <reference path="../phaser/phaser.d.ts"/>module Logram {    export class LogramCamera extends Phaser.Camera {        cursors: Phaser.CursorKeys;        size: Phaser.Rectangle = new Phaser.Rectangle(0, 0, 1, 1);        zoomAmount: number = 0;        zooming: boolean;        //constructor(game: Phaser.Game, id: number, x: number, y: number, width: number, height: number) {        //    super(game, null, x, y, width, height);        //    this.cursors = game.input.keyboard.createCursorKeys();        //    this.size.setTo(0, 0, 960, 960);        //    this.game.camera.focusOnXY(0, 0);        //    this.game.input.onDown.add(this.startZoom, this);        //    this.game.input.onUp.add(this.stopZoom, this);          //}        create() {            this.cursors = this.game.input.keyboard.createCursorKeys();            this.size.setTo(0, 0, 960, 960);            this.game.camera.focusOnXY(0, 0);            this.game.input.onDown.add(this.startZoom, this);            this.game.input.onUp.add(this.stopZoom, this);           }        update() {            if (this.zooming) {                console.log("zooming true");                this.game.camera.scale.x += this.zoomAmount;                this.game.camera.scale.y += this.zoomAmount;                this.game.camera.bounds.x = this.game.camera.scale.x * this.size.x;                this.game.camera.bounds.y = this.game.camera.scale.y * this.size.y;                this.game.camera.bounds.width = this.game.camera.scale.x * this.size.width;                this.game.camera.bounds.height = this.game.camera.scale.y * this.size.height;                //console.log(this.game.camera.bounds);            }            if (this.cursors.up.isDown) {                this.game.camera.y -= 4;            }            else if (this.cursors.down.isDown) {                this.game.camera.y += 4;            }            if (this.cursors.left.isDown) {                this.game.camera.x -= 4;            }            else if (this.cursors.right.isDown) {                this.game.camera.x += 4;            }        }        startZoom(pointer) {            this.zooming = true;            if (pointer.button === Phaser.Mouse.LEFT_BUTTON) {                this.zoomAmount = 0.005;            }            else {                this.zoomAmount = -0.005;            }        }        stopZoom(pointer) {            this.zooming = false;        }    }} 

teststage state:

/// <reference path="../phaser/phaser.d.ts"/>/// <reference path="../js/camera.ts"/>module Logram {    export class teststage extends Phaser.State {        map: Phaser.Tilemap;        layer: Phaser.TilemapLayer;                  create() {            this.map = this.game.add.tilemap('map');            //add tileset            this.map.addTilesetImage('tileset');            //create the layer            this.layer = this.map.createLayer('Tile Layer 1');            //set the world size to match the size of the layer            this.game.world.setBounds(0, 0, 960, 960);        }            }} 

Just to try, I tried changing the camera.ts's create() to construct and contruct a "LogramCamera," and that worked kinda. That is, anything I console.logged in the file appeared in the console, but it still didn't zoom or pan around the map. So even with a constructor I couldn't figure it out in this case. Still, there's got to be an easier way to just separate out my code. I'm sure I'm just missing something small and obvious. 

Link to comment
Share on other sites

I'm not sure what you mean by "calling 'game.camera' in your methods without replacing 'game.camera' " but I suspect it's part of my problem lol. 

 

So I've never instantiated the game.camera. I guess i assumed a default was created when I instantiated the game, since I was able to manipulate it by using that same camera.ts code (which is basically word for word from the examples package) in the teststage.js. I could just leave it there, but this mess will only compound going forward if I can't separate my code into other files, so I wanted to tackle it early. 

 

Oh wait ... are you saying instead of using this.game.camera in the camera.ts's update method, I should be saying Phaser.game.camera?  (I'm at work or I'd test if that's what you're saying). 

Link to comment
Share on other sites

So your context clues helped me figure it out after fiddling for a while. 

 

I inferred I should have instantiated a camera, as well as specifically called an update. So I changed it to this

 

camera.ts:

/// <reference path="../phaser/phaser.d.ts"/>module Logram {        export class LogramCamera extends Phaser.Camera {        cursors: Phaser.CursorKeys;        size: Phaser.Rectangle = new Phaser.Rectangle(0, 0, 1, 1);        zoomAmount: number = 0;        zooming: boolean;                constructor(game: Phaser.Game, cursors: Phaser.CursorKeys, x: number, y: number, width: number, height: number) {            super(game, null, x, y, width, height);            this.cursors = cursors;            this.size.setTo(x, y, width, height);            this.focusOnXY(0, 0);                                                game.input.onDown.add(this.startZoom, this);            game.input.onUp.add(this.stopZoom, this);        }        update() {                        if (this.zooming) {                this.game.camera.scale.x += this.zoomAmount;                this.game.camera.scale.y += this.zoomAmount;                this.game.camera.bounds.x = this.game.camera.scale.x * this.size.x;                this.game.camera.bounds.y = this.game.camera.scale.y * this.size.y;                this.game.camera.bounds.width = this.game.camera.scale.x * this.size.width;                this.game.camera.bounds.height = this.game.camera.scale.y * this.size.height;                     }            if (this.cursors.up.isDown) {                this.game.camera.y -= 4;                console.log("cursor pressed");            }            else if (this.cursors.down.isDown) {                this.game.camera.y += 4;            }            if (this.cursors.left.isDown) {                this.game.camera.x -= 4;            }            else if (this.cursors.right.isDown) {                this.game.camera.x += 4;            }        }        startZoom(pointer) {            this.zooming = true;            if (pointer.button === Phaser.Mouse.LEFT_BUTTON) {                this.zoomAmount = 0.005;              }            else {                if (!this.game.camera.atLimit) {                    this.zoomAmount = -0.005;                }            }        }        stopZoom(pointer) {            this.zooming = false;        }            }} 

And then created and called the update directly:

 

/// <reference path="../phaser/phaser.d.ts"/>/// <reference path="../js/camera.ts"/>module Logram {    export class teststage extends Phaser.State {        camera: LogramCamera;        map: Phaser.Tilemap;        layer: Phaser.TilemapLayer;        cursors: Phaser.CursorKeys;                  create() {            this.map = this.game.add.tilemap('map');            this.cursors = this.game.input.keyboard.createCursorKeys();            //add tileset            this.map.addTilesetImage('tileset');            //create the layer            this.layer = this.map.createLayer('Tile Layer 1');            //set the world size to match the size of the layer            this.game.world.setBounds(0, 0, 960, 960);            this.camera = new LogramCamera(this.game, this.cursors, 0, 0, this.world.width, this.world.height);        }                update() {            this.camera.update();         }    }} 

I still feel shaky on a few details after trying to tackle this whole thing. Starting with these two posts, they seemed to indicate similar solutions, but I was anytime to get a prototype going. I'm 90% sure my confusion is from trying to emulate JS in TS. I kept trying to start something within the class brackets, but intellisense just gave me flack after like an hour of fiddling. 

 

I also did this tutorial for Phaser in Typescript which is what led me to believe I could update() in another file (camera.ts( without manually calling its update function from my given state's update() (teststage.ts) like I did in this post. It usually works in other games, but not this time. I'm not really sure why that is. 

 

At any rate, thanks for helping me. I know this is newbie stuff but I found it quite frustrating after a couple days of no headway. 

 

 

Link to comment
Share on other sites

It's totally frustrating, I agree. ( = Nothing worse than wanting to just write your game but not get it out there. That's what the forum is for, though.

 

Phaser does create a camera by default, after you instantiate your game and the game boots the world (literally). Here's the line in Phaser.World that instantiates the camera: https://github.com/photonstorm/phaser/blob/db641ca82e608470bd7902de3447d048d9715ab5/src/core/World.js#L68

 

Looks like you're replacing it, but not in enough places; i.e. not just "game.camera" but also "game.world.camera". You don't have to call "update" on your own camera. The stage will call it, but it calls it through "game.world.camera", not "game.camera". So update it in both places and you should be good.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...