Post news RSS Some source code released

Some source code of my game has been released. This might be good for inspiration for other developers and a learning example.

Posted by on

View complete gist here. ( Gist.github.com )
BlockStore.js

 define(function(require, exports, module){
    var _               = require('underscore');
    var utils           = require('client/utils');
    var Phaser          = require('phaser');
    var Block           = require('../actors/Block');
    var PlanetGenerator = require('client/PlanetGenerator')
    var constants       = require('client/constants');
    var EventEmitter    = require('eventEmitter');





    var BlockStore = function(options){
        _.extend(this, {
            api    : null,
            stores : {},
        },options);
        this.__shipsById             = {};
        this.__planetsById           = {};
        this.__planetsByBlockId      = [];
        this.__blocksIdByPlanetId    = {};
        this.__blocksById            = [];
        this.__blocksByPos           = {};
        this.__selectedBlocksHistory = [];
        this.__onPlanetChangeBinded  = this.__onPlanetChange.bind(this);
        this.onBlockUpdated          = new Phaser.Signal();
        this.invalidateInBoundsBlocks();
        this.generateEmptyBlocks();


        var appDispatcher  = options.appDispatcher;
        this.dispatchToken = appDispatcher.register(this.onAppDispatcherAction.bind(this))
    }





    BlockStore.getBoundingBoxStepped = function(view, step){
        // Adjusting so we don't care about negative values
        var adjustX = 0;
        if(view.x < 0){
            adjustX = step * Math.ceil(-view.x/step);
        }
        view.x += adjustX;
        var adjustY = 0;
        if(view.y < 0){
            adjustY = step * Math.ceil(-view.y/step);
        }
        view.y += adjustY;

        var leftBoundingBox = view.x - view.x % step - adjustX;
        var topBoundingBox  = view.y - view.y % step - adjustY;
        var horizontalSteps = Math.ceil((view.width  + view.x % step) / step);
        var verticalSteps   = Math.ceil((view.height + view.y % step) / step);
        var width           = step * horizontalSteps;
        var height          = step * verticalSteps;
        return {
            x               : leftBoundingBox,
            y               : topBoundingBox,
            width           : width,
            height          : height,
            horizontalSteps : horizontalSteps,
            verticalSteps   : verticalSteps,
            leftStep        : leftBoundingBox / step,
            topStep         : topBoundingBox / step,
        }
    }




    _.extend(BlockStore.prototype, EventEmitter.prototype, {
        onAppDispatcherAction: function(payload){
            var action = payload.action;
            switch(action.type){
                case 'players.unlockBlock':
                    // @todo.
                    break;

                default:
                    // do nothing
              }
        },



        selectBlock: function(block){
            this.selectedBlock = block;
            this.__selectedBlocksHistory.push(block);
        },



        getLastXSelectedBlocks: function(howMany){
            return _.last(this.__selectedBlocksHistory, howMany)
        },



        getVisibleBlocks: function(){
            var last2SelectedBlocks = this.getLastXSelectedBlocks(2);
            console.log(last2SelectedBlocks.length)
            return last2SelectedBlocks
        },



        updateAuthorizedBlocks: function(){
            var unlockedBlocksIds = this.stores.authStore.currentPlayer.unlockedBlocksIds;
            unlockedBlocksIds.forEach(function(blockId){
                var block = this.getBlockById(blockId);
                block.setAuthorized(true);
            }.bind(this))
        },



        invalidateInBoundsBlocks: function(){
            this.__inBoundsBlocksAreDirty = true;
        },



        updateInBoundsBlocks: function(){
            if(!this.__inBoundsBlocksAreDirty) return;
            // Use camera
            var cameraVisibleRect = this.stores.cameraStore.getVisibleArea();
            // Don't consider scale.
            // The origin of the blocks is (0, 0)
            var blockSize = constants.BLOCK_SIZE;
            var boundingBoxStepped = BlockStore.getBoundingBoxStepped(cameraVisibleRect, blockSize);
            var inBoundsBlocksIds  = [];
            var inBoundsBlocksById = {};
            var inBoundsBlocks     = [];
            var block;
            var currentPlayer = this.stores.authStore.currentPlayer;
            for(var x = boundingBoxStepped.leftStep; x < boundingBoxStepped.leftStep + boundingBoxStepped.horizontalSteps; x++){
                for(var y = boundingBoxStepped.topStep; y < boundingBoxStepped.topStep + boundingBoxStepped.verticalSteps; y++){
                    block = this.getBlockByXY(x, y);
                    // if(currentPlayer.unlockedBlocksIds.indexOf(block._id) === -1) continue;
                    inBoundsBlocksIds.push(block._id);
                    inBoundsBlocks.push(block);
                    inBoundsBlocksById[block._id] = block;
                }
            }
            this.__inBoundsBlocksIds      = inBoundsBlocksIds;
            this.__inBoundsBlocksById     = inBoundsBlocksById;
            this.__inBoundsBlocks         = inBoundsBlocks;
            this.__inBoundsBlocksAreDirty = false;
        },



        getInBoundsBlocks: function(){
            this.updateInBoundsBlocks();
            return this.__inBoundsBlocks;
        },



        getInBoundsBlocksIds: function(){
            this.updateInBoundsBlocks();
            return this.__inBoundsBlocksIds;
        },



        getInBoundsBlocksById: function(){
            this.updateInBoundsBlocks();
            return this.__inBoundsBlocksById;
        },



        getRenderedBlocks: function(){
            return this.__blocksById.filter(function(block){
                return block.isRendered();
            })
        },



        getOutOfBoundsRenderedBlocks: function(){
            var renderedBlocks             = this.getRenderedBlocks();
            var authorizedAndInBoundsBlocks = this.getAuthorizedAndInBoundsBlocks();
            var outOfBoundsRenderedBlocks  = _.difference(renderedBlocks, authorizedAndInBoundsBlocks);
            return outOfBoundsRenderedBlocks;
        },



        getAuthorizedAndInBoundsBlocks: function(){
            return this.getInBoundsBlocks().filter(function(block){
                return this.blockIdIsAuthorized(block._id);
            }.bind(this))
        },



        blockIdIsAuthorized: function(blockId){
            return this.stores.authStore.currentPlayer.unlockedBlocksIds.indexOf(blockId) !== -1;
        },



        generateEmptyBlocks: function(){
            var i = 1000;
            while(i--){
                var blockPos = PlanetGenerator.getXYFromUlamSpiralIndex(i);
                this.addBlock(new Block({
                    _id  : i,
                    pos  : blockPos,
                    game : this.game,
                }))
            }
        },



        getBlockByWorldPosXY: function(x, y){
            var blockX = Math.floor(x / constants.BLOCK_SIZE);
            var blockY = Math.floor(y / constants.BLOCK_SIZE);
            return this.getBlockByXY(blockX, blockY);
        },



        getAllShips: function(){
            var activeShips = [];
            _.forEach(this.__shipsById, function(ship){
                if(ship.destinationReached) return;
                activeShips.push(ship);
            })
            return activeShips;
        },



        replaceShipId: function(oldShipId, newShipId){
            var ship = this.__shipsById[oldShipId];
            delete this.__shipsById[oldShipId];
            this.__shipsById[newShipId] = ship;
            ship._id = newShipId;
        },



        addShip: function(ship){
            // Can happen when the ship travel between blocks because we
            // get the ships by a certain block, therefore no need to render
            // it again, as it's the exact same ship.
            if(this.hasShip(ship)) return;
            this.__shipsById[ship._id] = ship;
            this.onBlockUpdated.dispatch(ship.from.block);
        },



        hasShip: function(ship){
            return !!this.__shipsById[ship._id];
        },



        removeShipById: function(shipId){
            var ship = this.__shipsById[shipId];
            delete this.__shipsById[shipId];
            this.onBlockUpdated.dispatch(ship.to.block);
        },



        __addPlanet: function(planet){
            if(!planet) throw new Error('no planet')
            var planetId = planet._id;
            if(planetId === void 0) throw new Error('no planet id')
            if(this.__planetsById[planetId]) throw new Error('planet already added')
            this.__planetsById[planetId] = planet;
            if(!this.__planetsByBlockId[planet.block.id]){
                this.__planetsByBlockId[planet.block.id] = [];
            }
            this.__planetsByBlockId[planet.block.id].push(planet);
            planet.onChange = this.__onPlanetChangeBinded;
        },



        __onPlanetChange: function(planet, what){
            this.onBlockUpdated.dispatch(planet.block.id, what, planet);
        },



        setBlockPlanets: function(blockId, planets){
            var _this = this;
            planets.forEach(function(planet){
                _this.__addPlanet(planet)
            })
            this.onBlockUpdated.dispatch(blockId);
        },



        getPlanetsInBlockId: function(blockId){
            var planets = this.__planetsByBlockId[blockId];
            return planets ? planets.slice() : false;
        },



        getPlanetById: function(planetId){
            if(planetId === void 0) throw new Error('add a planet id')
            return this.__planetsById[planetId];
        },



        getAllPlanets: function(){
            return _.extend({}, this.__planetsById);
        },



        addBlock: function(block){
            this.__blocksById[block._id] = block;
            this.__blocksByPos[block.getPosAsString()] = block;
        },



        getBlockByXY: function(x, y){
            return this.__blocksByPos[Block.getPosXYAsString(x, y)];
        },



        getBlockByPosString: function(posString){
            return this.__blocksByPos[posString];
        },



        getBlockByPosObject: function(posObject){
            return this.getBlockByPosString(Block.getPosObjectAsString(posObject));
        },



        getBlockById: function(id){
            return this.__blocksById[id];
        },
    })





    return BlockStore;
});
Post a comment
Sign in or join with:

Only registered members can share their thoughts. So come on! Join the community today (totally free - or sign in with your social account on the right) and join in the conversation.