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);
|