October 3, 2014

Tower of Fun - Part 2

Pixel art makes all the difference


Expanding on the previous, I decided to improve the art in the game.


SOURCE

PLAY




One step at a time, ya? So far, the game looks like this:


enter image description here


The above used these simple tiles:

enter image description here


And, then I had them replaced with these:

enter image description here


If you look closer, each of the tile sprites have only 2 colors in them. They took less than 30 mins to draft and when I loaded up the game with these tiles I was surprised. I realized how simple art alone could add huge value to the game. See for yourself,


enter image description here






Eye of the beholder


To add more depth, I drew the walls, actually be walls, rather than look like flat sprites on the ground, like the above.


enter image description here


Wrote a simple tiler.js which took the default Dungeon map array which had only values for 0, 1 and 2 (wall, room and corridor - ie, wall, grass and ground) - and returned an array with indices to one of the sprties in the upgraded tileSheet.




// Tile Library
// This stores the tile indices for the sprite sheet
// Allows independance from sprite sheet ordering, as we now only have to edit the library
// instead of the tileMapTranslate function
var tileLibrary = {
    wall: {
        front: 0,
        flat: 1,
    },
    room: 2,
    corridor: 3,
    blank: 4
};

Right after the dungeon is created, we call upon tiler.js primary function, tileMapTranslate() to do our bidding, our Game.Play,create() in main.js. tileMapTranslate() goes through every tile in the map and assigns the correct tile index to it based on it’s neighbors. For example, every 1 and 2 would become a grass and ground tile respectively. It gets slightly complex for walls, for we need to ensure that top and bottom walls are face-walls, while the left, right and filler walls are flat-top walls.




// Create new Dungeon and generate it
        this.dungeon = new Dungeon();
        this.dungeon.generate(this.MAP_SIZE);
        this.map = this.dungeon.getMap();

        // Translate the map into a spriteMap (check tiler.js)
        this.tileSpriteMap = tileMapTranslate(this.map);

        // Assign the tileSprite indices to the actual tileMap object
        for (var i=0; i<this.MAP_SIZE; i++) {
            for(var j=0; j<this.MAP_SIZE; j++) {
                this.tileMap.putTile(this.tileSpriteMap[i][j], i, j, this.layer0);
            }
        }

Now, isn’t this pretty? Such GFX!


enter image description here






Player is Move


Having a static player sprite gets old real quick. Hence animation!


enter image description hereenter image description hereenter image description hereenter image description here


The player sprite asset is no longer a single sprite, but is a spritesheet, with each frame building up the animation:


enter image description here


We add these animations to the Player in the create() function, after the Player sprite object has been created. In this case, each animation has 4 frames, and they are indexed from left to right and top to bottom in the spritesheet.




//  Assign Player Animations
        this.player.animations.add('left', [8, 9, 10, 11], this.PLAYERFRAME_SPEED, true);
        this.player.animations.add('right', [12, 13, 14, 15], this.PLAYERFRAME_SPEED, true);
        this.player.animations.add('up', [4, 5, 6, 7], this.PLAYERFRAME_SPEED, true);
        this.player.animations.add('down', [0, 1, 2, 3], this.PLAYERFRAME_SPEED, true);

To control the animation on the Player object, i just kick it off when the user inputs a direction to move in. This code would go in the update() part.




        // Move Up/Down
        if (this.cursors.up.isDown) {
           this.player.body.velocity.y = -this.PLAYER_SPEED;
           this.player.animations.play('up');
           moving++;
        } else if (this.cursors.down.isDown) {
           this.player.body.velocity.y = this.PLAYER_SPEED;
           this.player.animations.play('down');
           moving++;
        }

Since, Phaser’s AnimationManager plays the animation on loop by default (though, AnimationManager can take more instructions on how to deal with animations), the animations on the Player have to stop when the Player isn’t moving.




        //  Standing still
        if(!moving){
            this.player.animations.stop(null,true);
            // this.player.frame = 0;
        }

SOURCE

PLAY




I have been using Aseprite to draw all my pixel art. It’s a great tool and free if you compile it yourself, else it’s also available for 10$. That’s cheaper than a medium size pizza. It comes with a stunning feature set where you get to animate in layers, tiled the sprites, support for spritesheets, etc. Head on over and check it out:

AespriteLogo


Back to Tower of Fun

No comments:

Post a Comment

You got something to say? Wait! I need to get my microphone array online.