Win an Ipad
  Developer   Tutorials   Snake   Game sprites
Lesson 0

Game sprites

Snake consists of head, body and tail. Each part is built by Sprite instance. Most important part is snakehead. Snakehead manages the direction of the snake and collision with food or game borders.

Head sprite

Head is a Sprite instance that defines bitmap image split into four frames. Each frame represents snake head direction - top, left, right, left.

Snakehead frames:

 

Snakehead sprite definition:

include "app://gameObjects/snake/part.ms";
/**
Head part of snake. Head is instance of Sprite.
Defines head movements and handles collisions with other game objects
*/
class Head : Part
{
    //Load images
    var _headImage = Bitmap.fromFile(SNAKE_HEAD_IMAGE);     /**
    Init snake Head
    */
    function init()
    {
        super.init();         //Relative position to the left upper corner, she changes at change direction.
        this._relX = 0;
        this._relY = 0;
        //Variables for saving relative positions.
        this._saveRelX = 0;
        this._saveRelY = 0;         //Init head
        this.relX = -10;
        this.relY = -10;
        this.shiftShadowX = -10;
        this.shiftShadowY = -10;
        this.image = _headImage;
        this.frameWidth = 40;
        this.frameHeight = 40;     }     /**
    Relative X-coordinate
    @param Integer v
    @return Integer
    */
    property relX(v)
    {
        get return this._saveRelX;
        set this._saveRelX = v;
    }     /**
    Relative Y-coordinate
    @param Integer v
    @return Integer
    */
    property relY(v)
    {
        get return this._saveRelY;
        set this._saveRelY = v;
    }     /**
    * Property direction
    * @return Return actual direction
    * @param Symbol v Set direction and relative position, because head is bigger than other snake parts.
    */
    property direction(v)
    {
        get return this._direction;
        set {
            this._direction = v;
            switch(this._direction) {
                case #left: this.frame = 3;this._relX = 2*this.relX; this._relY = this.relY; break;
                case #right: this.frame = 1;this._relX = 0; this._relY = this.relY; break;
                case #up: this.frame = 0;this._relX = this.relX; this._relY = 2*this.relY; break;
                case #down: this.frame = 2;this._relX = this.relX; this._relY = 0; break;
            }
        }
    }     /**
    Event called within Scene onProcess
    @param GameScene sender
    */
    function onProcess(sender)
    {
        //Move head by direction
        switch(this.direction)
        {
            case #left:     this.x -= this.width; break;
            case #right:    this.x += this.width; break;
            case #up:       this.y -= this.height; break;
            case #down:     this.y += this.height; break;
        }
       
        //Check collisions with food
        for (var f in sender.food)
            if (this.intersectsBounds(f)) {
                //Set new random positions
                var stop = false;
                while (!stop) {
                    stop = true;
                    f.x = (1+rand(sender.width/CELL_WIDTH-2))*CELL_WIDTH -10;
                    f.y = (1+rand(sender.height/CELL_HEIGHT-2))*CELL_HEIGHT -10;
                    for (var i in sender.food)
                        if (f != i && f.intersectsBounds(i))
                            stop = false;
                    for (var i in sender.walls)
                        if (f.intersectsBounds(i))
                            stop = false;
                }
                sender.snake.addPart(); //Add new part to the body.
                sender.snake.timer.sleep -= f.speedValue; //It will be more often call method onProcess and snake will be faster.
                sender.score.value += f.score;
                break;
         }         //Check collisions with boundaries
        if (this.x < 0 || this.x > sender.width || this.y < 0 || this.y > sender.height)
            sender.endGame();         //Check collision with walls
        for (var i in sender.walls)
            if (this.intersectsBounds(i)) {
                sender.endGame();
            }     }
}

 

Score Handler


Score is an instance of Paint object that handles game score. Every time the player feeds the snake, points are added to the game score. Adding the points is nice and simple effect that we achieved by setting score Y coordinates and colour alpha channel.

Number frames:

Score sprite definition:

include "app://core/constants.ms";
include "lib://game2d/sprite.ms"; class Score : Sprite
{
    function init()
    {
        super.init();         //Load images
        this._sequence = [0-10];
        this._image = Bitmap.fromFile("app://images/640_960/numbers.png");         this.frameWidth = 25;
        this.frameHeight = 34;         this._value = 0;
        this._right = 0;
        this._top = 0;         this._effect = null;
    }     property value(v)
    {
        get return this._value;
        set {
            var s = v - this._value;
            if (s > 0) {
                this._effect = new Paint();
                this._effect.color = 0x80ffffff;
                this._effect.value = s;
                this._effect.top = this.top;
            }
            this._value = v;
        }
    }     property width(v)
    {
        get return this.frameWidth;
    }     property height(v)
    {
        get return this.frameHeight;
    }     property right(v)
    {
        get return this._right;
        set this._right = v;
    }     property top(v)
    {
        get return this._top;
        set this._top = v;
    }     function draw(canvas)
    {
        this.x = this.right - this.width;
        this.y = this.top + 20;         var str = this.value.toString();
        for (var i = 0; i < str.length; i++) {
            this.frame = str[i] - 48;
            super.draw(canvas);
            this.x += this.frameWidth;
        }         if (this._effect) {             this.x = this.right - (2*this.frameWidth);
            str = this._effect.value.toString();
            for (var i = -1; i < str.length; i++) {                 if (i < 0) {
                    this.frame = 10;
                    this.y = this._effect.top + (this.height - this.frameHeight)/2;
                }else {
                    this.frame = str[i] - 48;
                    this.y = this._effect.top;                 }
                super.draw(canvas,this._effect);
                this.x += this.frameWidth;
            }
        }
    }     function onProcess()
    {
        if (this._effect) {
            if (this._effect.color & 0xff000000) {
                this._effect.color -= 0x02000000;
                this._effect.top += 1;
            }
            else
                this._effect = null;
            return true;
        }
        return false;
    } }

 

Menu Button

Menu button is instance of Game Control class. It is defined in Game scene. Button has two states - normal and pressed. Each state is represented by its image.

Menu button definition:

var bMenu = new SnakeButton({image:G_MENU_BUTTON, pressedImage:G_MENU_BUTTON_P});
bMenu.onClick = function() {
      var menuScene = new MenuScene();
      menuScene.showContinueBttn();
      app.push(menuScene);
}; bMenu.draw = function(canvas)
{
        if (this.visible)
            canvas.drawBitmap(this._drawImage, this.x, this.y);
} bMenu.pointerPressed = function(x,y)
{
        if (this.visible)
            this._drawImage = this._pressedImage;
} bMenu.pointerReleased = function(x,y)
{
        if (this.visible) {
            this._drawImage = this._image;
            if (this.onClick)
                return this.onClick();
       }
} this.add(bMenu);

 

 

 Graphic proposal   Game sprites   Game scenes 
Tutorial details and chapters
Technology:
Difficulty:
Completion:
Snake chapters