feat: snake game
feat: unit.random feat: ui.center
This commit is contained in:
parent
f34f78112e
commit
6ef4f8890f
@ -12,3 +12,7 @@ node-games
|
|||||||
spacecraft
|
spacecraft
|
||||||
----------
|
----------
|
||||||
![spacecraft](https://raw.githubusercontent.com/mdibaiee/node-games/master/spacecraft.png)
|
![spacecraft](https://raw.githubusercontent.com/mdibaiee/node-games/master/spacecraft.png)
|
||||||
|
|
||||||
|
snake
|
||||||
|
-----
|
||||||
|
![snake](https://raw.githubusercontent.com/mdibaiee/node-games/master/snake.png)
|
||||||
|
@ -45,10 +45,15 @@ var Interface = (function () {
|
|||||||
|
|
||||||
this.cursor = (0, _ansi2.default)(this.output).hide();
|
this.cursor = (0, _ansi2.default)(this.output).hide();
|
||||||
|
|
||||||
this.columns = this.output.columns;
|
|
||||||
this.rows = this.output.rows;
|
|
||||||
|
|
||||||
this.input.addListener('data', function (data) {
|
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) {
|
var key = Object.keys(keys).find(function (value, i) {
|
||||||
return keys[value] === data;
|
return keys[value] === data;
|
||||||
});
|
});
|
||||||
@ -80,8 +85,30 @@ var Interface = (function () {
|
|||||||
}, {
|
}, {
|
||||||
key: 'onKey',
|
key: 'onKey',
|
||||||
value: function onKey(key, fn) {
|
value: function onKey(key, fn) {
|
||||||
|
if (typeof key === 'function') {
|
||||||
|
fn = key;
|
||||||
|
key = '';
|
||||||
|
}
|
||||||
listeners.push({ key: key, fn: fn });
|
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;
|
return Interface;
|
||||||
|
@ -54,6 +54,12 @@ var Unit = (function () {
|
|||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
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',
|
key: 'speed',
|
||||||
value: function speed() {
|
value: function speed() {
|
||||||
|
189
build/snake.js
Normal file
189
build/snake.js
Normal 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();
|
||||||
|
});
|
@ -11,15 +11,17 @@ var _interface2 = _interopRequireDefault(_interface);
|
|||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
var FRAME = 20;
|
var FRAME = 20;
|
||||||
var ENEMY_SPAWN_RATE = 400;
|
var ENEMY_SPAWN_RATE = 1000;
|
||||||
|
var RELOAD_TIME = 200;
|
||||||
|
|
||||||
var ui = new _interface2.default();
|
var ui = new _interface2.default();
|
||||||
|
|
||||||
var player = new _unit2.default(ui);
|
var player = new _unit2.default(ui);
|
||||||
player.go(1, ui.output.rows / 2);
|
player.go(1, ui.center.y);
|
||||||
player.shape = '=>';
|
player.shape = '=>';
|
||||||
player.color = '#77d6ff';
|
player.color = '#77d6ff';
|
||||||
player.bold = true;
|
player.bold = true;
|
||||||
|
player.canShoot = true;
|
||||||
|
|
||||||
var explosion = new _unit2.default(ui);
|
var explosion = new _unit2.default(ui);
|
||||||
explosion.dead = true;
|
explosion.dead = true;
|
||||||
@ -43,6 +45,8 @@ setInterval(function () {
|
|||||||
enemy.shape = '*';
|
enemy.shape = '*';
|
||||||
missle.dead = true;
|
missle.dead = true;
|
||||||
|
|
||||||
|
ENEMY_SPAWN_RATE -= 5;
|
||||||
|
|
||||||
score++;
|
score++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,18 +84,25 @@ ui.onKey('up', function () {
|
|||||||
ui.onKey('left', function () {
|
ui.onKey('left', function () {
|
||||||
player.move(-1, 0);
|
player.move(-1, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.onKey('space', function () {
|
ui.onKey('space', function () {
|
||||||
|
if (!player.canShoot) return;
|
||||||
|
|
||||||
|
player.canShoot = false;
|
||||||
|
|
||||||
var missle = new _unit2.default(ui);
|
var missle = new _unit2.default(ui);
|
||||||
missle.go(player.x, player.y);
|
missle.go(player.x, player.y);
|
||||||
missle.shape = '+';
|
missle.shape = '+';
|
||||||
missle.dieOnExit = true;
|
missle.dieOnExit = true;
|
||||||
|
|
||||||
missles.push(missle);
|
missles.push(missle);
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
player.canShoot = true;
|
||||||
|
}, RELOAD_TIME);
|
||||||
});
|
});
|
||||||
|
|
||||||
setInterval(function () {
|
(function loop() {
|
||||||
if (enemies.length > 5) return;
|
|
||||||
|
|
||||||
var enemy = new _unit2.default(ui);
|
var enemy = new _unit2.default(ui);
|
||||||
enemy.go(Math.random() * ui.output.columns, 0);
|
enemy.go(Math.random() * ui.output.columns, 0);
|
||||||
enemy.shape = 'o';
|
enemy.shape = 'o';
|
||||||
@ -103,7 +114,9 @@ setInterval(function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enemies.push(enemy);
|
enemies.push(enemy);
|
||||||
}, 1000);
|
|
||||||
|
setTimeout(loop, ENEMY_SPAWN_RATE);
|
||||||
|
})();
|
||||||
|
|
||||||
process.on('exit', function () {
|
process.on('exit', function () {
|
||||||
ui.cursor.horizontalAbsolute(0).eraseLine();
|
ui.cursor.horizontalAbsolute(0).eraseLine();
|
||||||
|
1
index.js
1
index.js
@ -7,6 +7,7 @@ if (!game) {
|
|||||||
console.log('');
|
console.log('');
|
||||||
console.log('Games');
|
console.log('Games');
|
||||||
console.log('- spacecraft');
|
console.log('- spacecraft');
|
||||||
|
console.log('- snake');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "node-games",
|
"name": "node-games",
|
||||||
"version": "1.0.2",
|
"version": "2.0.0",
|
||||||
"description": "Simple node console games",
|
"description": "Simple node console games",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -23,10 +23,13 @@ export default class Interface {
|
|||||||
|
|
||||||
this.cursor = ansi(this.output).hide();
|
this.cursor = ansi(this.output).hide();
|
||||||
|
|
||||||
this.columns = this.output.columns;
|
|
||||||
this.rows = this.output.rows;
|
|
||||||
|
|
||||||
this.input.addListener('data', data => {
|
this.input.addListener('data', data => {
|
||||||
|
let always = listeners.filter(listener => {
|
||||||
|
return listener.key === '';
|
||||||
|
});
|
||||||
|
|
||||||
|
always.forEach(listener => listener.fn());
|
||||||
|
|
||||||
let key = Object.keys(keys).find((value, i) => {
|
let key = Object.keys(keys).find((value, i) => {
|
||||||
return keys[value] === data;
|
return keys[value] === data;
|
||||||
});
|
});
|
||||||
@ -41,6 +44,14 @@ export default class Interface {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get columns() {
|
||||||
|
return this.output.columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
get rows() {
|
||||||
|
return this.output.rows;
|
||||||
|
}
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
this.output.write('\u001b[2J\u001b[0;0H');
|
this.output.write('\u001b[2J\u001b[0;0H');
|
||||||
}
|
}
|
||||||
@ -50,6 +61,17 @@ export default class Interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onKey(key, fn) {
|
onKey(key, fn) {
|
||||||
|
if (typeof key === 'function') {
|
||||||
|
fn = key;
|
||||||
|
key = '';
|
||||||
|
}
|
||||||
listeners.push({ key, fn });
|
listeners.push({ key, fn });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get center() {
|
||||||
|
return {
|
||||||
|
x: this.output.columns / 2,
|
||||||
|
y: this.output.rows / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,11 @@ export default class Unit {
|
|||||||
this.y = y;
|
this.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
speed() {
|
speed() {
|
||||||
let signs = [Math.random() > 0.5 ? -1 : 1, Math.random() > 0.5 ? -1 : 1];
|
let signs = [Math.random() > 0.5 ? -1 : 1, Math.random() > 0.5 ? -1 : 1];
|
||||||
return [Math.random() * signs[0], Math.random() * signs[1]];
|
return [Math.random() * signs[0], Math.random() * signs[1]];
|
||||||
|
169
src/snake.js
Normal file
169
src/snake.js
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
import Unit from './classes/unit';
|
||||||
|
import Interface from './classes/interface';
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
let log = fs.createWriteStream(__dirname + '/log');
|
||||||
|
|
||||||
|
let FRAME = 100;
|
||||||
|
|
||||||
|
let ui = new Interface();
|
||||||
|
|
||||||
|
let snake = [];
|
||||||
|
const UP = 0;
|
||||||
|
const DOWN = 1;
|
||||||
|
const LEFT = 2;
|
||||||
|
const RIGHT = 3;
|
||||||
|
let head = createPart();
|
||||||
|
head.color = '#71da29';
|
||||||
|
head.dieOnExit = true;
|
||||||
|
createPart();
|
||||||
|
createPart();
|
||||||
|
|
||||||
|
let point = new Unit(ui);
|
||||||
|
point.shape = '+';
|
||||||
|
point.color = '#f3ff6a';
|
||||||
|
point.random();
|
||||||
|
|
||||||
|
let score = 0;
|
||||||
|
|
||||||
|
let stop = false;
|
||||||
|
function loop() {
|
||||||
|
if (stop) return;
|
||||||
|
ui.clear();
|
||||||
|
|
||||||
|
point.draw();
|
||||||
|
|
||||||
|
snake.forEach((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', () => {
|
||||||
|
changeDirection(RIGHT);
|
||||||
|
});
|
||||||
|
ui.onKey('down', () => {
|
||||||
|
changeDirection(DOWN);
|
||||||
|
});
|
||||||
|
ui.onKey('up', () => {
|
||||||
|
changeDirection(UP);
|
||||||
|
});
|
||||||
|
ui.onKey('left', () => {
|
||||||
|
changeDirection(LEFT);
|
||||||
|
});
|
||||||
|
|
||||||
|
ui.onKey(() => {
|
||||||
|
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() {
|
||||||
|
let part = new Unit(ui);
|
||||||
|
let last = snake[snake.length - 1];
|
||||||
|
|
||||||
|
let direction;
|
||||||
|
if (!last) {
|
||||||
|
direction = UP;
|
||||||
|
} else {
|
||||||
|
direction = last.direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
part.shape = '•';
|
||||||
|
part.color = '#bdfe91';
|
||||||
|
part.direction = direction;
|
||||||
|
part.changeTo = null;
|
||||||
|
|
||||||
|
part.findWay = function(i) {
|
||||||
|
let 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(multiplier = 1) {
|
||||||
|
let { direction } = part;
|
||||||
|
let x = direction == LEFT ? -1 :
|
||||||
|
direction == RIGHT ? 1 : 0;
|
||||||
|
let y = direction == UP ? -1 :
|
||||||
|
direction == DOWN ? 1 : 0;
|
||||||
|
|
||||||
|
return [x * multiplier, y * multiplier];
|
||||||
|
}
|
||||||
|
|
||||||
|
let [dX, dY] = part.speed();
|
||||||
|
dX *= -1;
|
||||||
|
dY *= -1;
|
||||||
|
|
||||||
|
let x = last ? last.x + dX : ui.center.x;
|
||||||
|
let y = last ? last.y + dY : ui.center.y;
|
||||||
|
|
||||||
|
part.go(x, y);
|
||||||
|
|
||||||
|
snake.push(part);
|
||||||
|
return part;
|
||||||
|
}
|
||||||
|
|
||||||
|
function gameover() {
|
||||||
|
const 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');
|
||||||
|
const 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();
|
||||||
|
});
|
@ -2,15 +2,17 @@ import Unit from './classes/unit';
|
|||||||
import Interface from './classes/interface';
|
import Interface from './classes/interface';
|
||||||
|
|
||||||
const FRAME = 20;
|
const FRAME = 20;
|
||||||
const ENEMY_SPAWN_RATE = 400;
|
let ENEMY_SPAWN_RATE = 1000;
|
||||||
|
let RELOAD_TIME = 200;
|
||||||
|
|
||||||
let ui = new Interface();
|
let ui = new Interface();
|
||||||
|
|
||||||
let player = new Unit(ui);
|
let player = new Unit(ui);
|
||||||
player.go(1, ui.output.rows / 2);
|
player.go(1, ui.center.y);
|
||||||
player.shape = '=>';
|
player.shape = '=>';
|
||||||
player.color = '#77d6ff';
|
player.color = '#77d6ff';
|
||||||
player.bold = true;
|
player.bold = true;
|
||||||
|
player.canShoot = true;
|
||||||
|
|
||||||
let explosion = new Unit(ui);
|
let explosion = new Unit(ui);
|
||||||
explosion.dead = true;
|
explosion.dead = true;
|
||||||
@ -34,6 +36,8 @@ setInterval(() => {
|
|||||||
enemy.shape = '*';
|
enemy.shape = '*';
|
||||||
missle.dead = true;
|
missle.dead = true;
|
||||||
|
|
||||||
|
ENEMY_SPAWN_RATE -= 5;
|
||||||
|
|
||||||
score++;
|
score++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,18 +76,25 @@ ui.onKey('up', () => {
|
|||||||
ui.onKey('left', () => {
|
ui.onKey('left', () => {
|
||||||
player.move(-1, 0);
|
player.move(-1, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.onKey('space', () => {
|
ui.onKey('space', () => {
|
||||||
|
if (!player.canShoot) return;
|
||||||
|
|
||||||
|
player.canShoot = false;
|
||||||
|
|
||||||
let missle = new Unit(ui);
|
let missle = new Unit(ui);
|
||||||
missle.go(player.x, player.y);
|
missle.go(player.x, player.y);
|
||||||
missle.shape = '+';
|
missle.shape = '+';
|
||||||
missle.dieOnExit = true;
|
missle.dieOnExit = true;
|
||||||
|
|
||||||
missles.push(missle);
|
missles.push(missle);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
player.canShoot = true;
|
||||||
|
}, RELOAD_TIME)
|
||||||
});
|
});
|
||||||
|
|
||||||
setInterval(() => {
|
(function loop() {
|
||||||
if (enemies.length > 5) return;
|
|
||||||
|
|
||||||
let enemy = new Unit(ui);
|
let enemy = new Unit(ui);
|
||||||
enemy.go(Math.random() * ui.output.columns, 0);
|
enemy.go(Math.random() * ui.output.columns, 0);
|
||||||
enemy.shape = 'o';
|
enemy.shape = 'o';
|
||||||
@ -95,7 +106,9 @@ setInterval(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enemies.push(enemy);
|
enemies.push(enemy);
|
||||||
}, 1000);
|
|
||||||
|
setTimeout(loop, ENEMY_SPAWN_RATE);
|
||||||
|
}());
|
||||||
|
|
||||||
process.on('exit', function() {
|
process.on('exit', function() {
|
||||||
ui.cursor.horizontalAbsolute(0).eraseLine()
|
ui.cursor.horizontalAbsolute(0).eraseLine()
|
||||||
|
Loading…
Reference in New Issue
Block a user