feat: snake game

feat: unit.random
feat: ui.center
This commit is contained in:
Mahdi Dibaiee
2015-12-12 09:44:22 +03:30
parent f34f78112e
commit 6ef4f8890f
13 changed files with 468 additions and 19 deletions

View File

@ -45,10 +45,15 @@ var Interface = (function () {
this.cursor = (0, _ansi2.default)(this.output).hide();
this.columns = this.output.columns;
this.rows = this.output.rows;
this.input.addListener('data', function (data) {
var always = listeners.filter(function (listener) {
return listener.key === '';
});
always.forEach(function (listener) {
return listener.fn();
});
var key = Object.keys(keys).find(function (value, i) {
return keys[value] === data;
});
@ -80,8 +85,30 @@ var Interface = (function () {
}, {
key: 'onKey',
value: function onKey(key, fn) {
if (typeof key === 'function') {
fn = key;
key = '';
}
listeners.push({ key: key, fn: fn });
}
}, {
key: 'columns',
get: function get() {
return this.output.columns;
}
}, {
key: 'rows',
get: function get() {
return this.output.rows;
}
}, {
key: 'center',
get: function get() {
return {
x: this.output.columns / 2,
y: this.output.rows / 2
};
}
}]);
return Interface;

View File

@ -54,6 +54,12 @@ var Unit = (function () {
this.x = x;
this.y = y;
}
}, {
key: 'random',
value: function random() {
this.x = Math.max(1, Math.floor(Math.random() * this.output.columns));
this.y = Math.max(1, Math.floor(Math.random() * this.output.rows));
}
}, {
key: 'speed',
value: function speed() {

0
build/log Normal file
View File

189
build/snake.js Normal file
View File

@ -0,0 +1,189 @@
'use strict';
var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; })();
var _unit = require('./classes/unit');
var _unit2 = _interopRequireDefault(_unit);
var _interface = require('./classes/interface');
var _interface2 = _interopRequireDefault(_interface);
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var log = _fs2.default.createWriteStream(__dirname + '/log');
var FRAME = 100;
var ui = new _interface2.default();
var snake = [];
var UP = 0;
var DOWN = 1;
var LEFT = 2;
var RIGHT = 3;
var head = createPart();
head.color = '#71da29';
head.dieOnExit = true;
createPart();
createPart();
var point = new _unit2.default(ui);
point.shape = '+';
point.color = '#f3ff6a';
point.random();
var score = 0;
var stop = false;
function loop() {
if (stop) return;
ui.clear();
point.draw();
snake.forEach(function (part, i) {
part.draw();
if (i > 0) part.findWay(i);
part.move();
});
if (head.collides(point)) {
point.random();
createPart();
score++;
FRAME--;
}
if (head.collides(snake.slice(2))) {
gameover();
}
ui.cursor.goto(0, 0).yellow().write('Score: ' + score);
ui.cursor.reset();
setTimeout(loop, FRAME);
}
loop();
ui.onKey('right', function () {
changeDirection(RIGHT);
});
ui.onKey('down', function () {
changeDirection(DOWN);
});
ui.onKey('up', function () {
changeDirection(UP);
});
ui.onKey('left', function () {
changeDirection(LEFT);
});
ui.onKey(function () {
if (!stop) return;
stop = false;
snake = [];
head = createPart();
head.color = '#71da29';
createPart();
createPart();
score = 0;
point.random();
loop();
});
function changeDirection(dir) {
head.direction = dir;
}
function createPart() {
var part = new _unit2.default(ui);
var last = snake[snake.length - 1];
var direction = undefined;
if (!last) {
direction = UP;
} else {
direction = last.direction;
}
part.shape = '•';
part.color = '#bdfe91';
part.direction = direction;
part.changeTo = null;
part.findWay = function (i) {
var ahead = snake[i - 1];
if (this.changeTo !== null) {
this.direction = this.changeTo;
this.changeTo = null;
}
if (this.direction !== ahead.direction) {
this.changeTo = ahead.direction;
}
};
part.speed = function () {
var multiplier = arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0];
var direction = part.direction;
var x = direction == LEFT ? -1 : direction == RIGHT ? 1 : 0;
var y = direction == UP ? -1 : direction == DOWN ? 1 : 0;
return [x * multiplier, y * multiplier];
};
var _part$speed = part.speed();
var _part$speed2 = _slicedToArray(_part$speed, 2);
var dX = _part$speed2[0];
var dY = _part$speed2[1];
dX *= -1;
dY *= -1;
var x = last ? last.x + dX : ui.center.x;
var y = last ? last.y + dY : ui.center.y;
part.go(x, y);
snake.push(part);
return part;
}
function gameover() {
var MSG = 'Game Over!';
ui.cursor.goto(ui.center.x - MSG.length / 2, ui.center.y);
ui.cursor.red();
ui.cursor.bold();
ui.write(MSG);
ui.cursor.reset();
ui.cursor.hex('#f65590');
var RETRY = 'Press any key to play again';
ui.cursor.goto(ui.center.x - RETRY.length / 2, ui.center.y + 2);
ui.write(RETRY);
stop = true;
}
process.on('exit', function () {
ui.cursor.horizontalAbsolute(0).eraseLine();
ui.cursor.show();
log.end();
});

View File

@ -11,15 +11,17 @@ var _interface2 = _interopRequireDefault(_interface);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var FRAME = 20;
var ENEMY_SPAWN_RATE = 400;
var ENEMY_SPAWN_RATE = 1000;
var RELOAD_TIME = 200;
var ui = new _interface2.default();
var player = new _unit2.default(ui);
player.go(1, ui.output.rows / 2);
player.go(1, ui.center.y);
player.shape = '=>';
player.color = '#77d6ff';
player.bold = true;
player.canShoot = true;
var explosion = new _unit2.default(ui);
explosion.dead = true;
@ -43,6 +45,8 @@ setInterval(function () {
enemy.shape = '*';
missle.dead = true;
ENEMY_SPAWN_RATE -= 5;
score++;
}
@ -80,18 +84,25 @@ ui.onKey('up', function () {
ui.onKey('left', function () {
player.move(-1, 0);
});
ui.onKey('space', function () {
if (!player.canShoot) return;
player.canShoot = false;
var missle = new _unit2.default(ui);
missle.go(player.x, player.y);
missle.shape = '+';
missle.dieOnExit = true;
missles.push(missle);
setTimeout(function () {
player.canShoot = true;
}, RELOAD_TIME);
});
setInterval(function () {
if (enemies.length > 5) return;
(function loop() {
var enemy = new _unit2.default(ui);
enemy.go(Math.random() * ui.output.columns, 0);
enemy.shape = 'o';
@ -103,7 +114,9 @@ setInterval(function () {
};
enemies.push(enemy);
}, 1000);
setTimeout(loop, ENEMY_SPAWN_RATE);
})();
process.on('exit', function () {
ui.cursor.horizontalAbsolute(0).eraseLine();