Skip to content

Instantly share code, notes, and snippets.

@katjad
Created December 3, 2019 15:09
Show Gist options
  • Save katjad/c8287aec9e433d849273d9a5c9142389 to your computer and use it in GitHub Desktop.
Save katjad/c8287aec9e433d849273d9a5c9142389 to your computer and use it in GitHub Desktop.
Space Invaders 2
const term = require( 'terminal-kit' ).terminal ;
const termkit = require( 'terminal-kit' )
const ScreenBuffer = termkit.ScreenBuffer;
const INVADERS_WIDTH = 90;
const NO_PER_ROW = 11;
const ROWS = 5;
const COLUMN_WIDTH = 7;
const ROW_HEIGHT = 4;
const FRAMES_TILL_MOVE = 12;
let countframes = 0;
let viewport, sprites = {};
let x, y, startx, xshoot;
let startState, moveRight = true;
let logMsg = 'log me';
const log = (str, x=10, y=5) => {
term.moveTo( x, y ).white(str)
}
// /òó\ /òó\
// \/ /\
// v v
// M M M M
// < > > <
// dôb dôb
// ^ ^ v v
// ṁ
// d[_]b
const drawSprite = (sprite, x, y) => {
sprite.draw({ dst: sprites.invaders, x: x, y: y })
}
const addSpaceInvaders = () => {
const inv1string = (startState) ? '^^\nMM\n><' : 'vv\nMM\n<>';
const inv2string = (startState) ? ' \ndôb\n^ ^' : ' \ndôb\nv v';
const inv3string = (startState) ? ' \n/òó\\\n \\/ ' : ' \n/òó\\\n /\\ ';
sprites.invader1 = ScreenBuffer.createFromString(
{ attr: { color: 'blue' } }, inv1string
)
sprites.invader2 = ScreenBuffer.createFromString(
{ attr: { color: 'white' } }, inv2string
)
sprites.invader3 = ScreenBuffer.createFromString(
{ attr: { color: 'green' } }, inv3string
)
const spriteArray = [sprites.invader1,
sprites.invader2,
sprites.invader2,
sprites.invader3,
sprites.invader3 ]
ypos = 0
spriteArray.forEach(sprite => {
let xpos = 0;
[...Array(NO_PER_ROW)].forEach((_, i) => {drawSprite(sprite, xpos, ypos); xpos += COLUMN_WIDTH })
ypos += ROW_HEIGHT
})
}
const createInvadersBuffer = () => {
sprites.invaders = new ScreenBuffer({
dst: viewport,
width: INVADERS_WIDTH,
height: ROW_HEIGHT * ROWS,
x: x,
y: y
})
// sprites.invaders.fill({ attr: { bgColor: 'black' } })
}
const createShooter = () => {
sprites.shooter = ScreenBuffer.createFromString(
{ attr: { color: 'white' } }, ' ^ \nd[_]b'
)
}
const drawShooter = () => {
sprites.shooter.draw({
dst: viewport,
x: xshoot,
y: viewport.height - 2
})
}
terminate = () => {
term.hideCursor( false ) ;
term.grabInput( false ) ;
setTimeout( function() {
term.moveTo( 1 , term.height , '\n\n' ) ;
process.exit() ;
} , 100 ) ;
}
inputs = key =>
{
switch ( key )
{
case 'LEFT' :
if (xshoot >= startx + 5) {
xshoot -= 2;
}
break ;
case 'RIGHT' :
if (xshoot < startx + INVADERS_WIDTH -10) {
xshoot += 2;
}
break ;
case 'UP' :
//shootBullets();
break;
case 'q':
case 'CTRL_C':
terminate() ;
break ;
}
}
const nextPosition = () => {
if (moveRight) {
if (sprites.invaders.x < startx + INVADERS_WIDTH - (COLUMN_WIDTH*NO_PER_ROW)) {
sprites.invaders.x += 2;
} else {
sprites.invaders.y += ROW_HEIGHT / 2;
moveRight = false;
}
} else {
if (sprites.invaders.x >= startx) {
sprites.invaders.x -= 2;
} else {
sprites.invaders.y += ROW_HEIGHT / 2;
moveRight = true;
}
}
}
const showText = () => {
term.moveTo.eraseLine(startx + 5, 2).white(
'Left and Right Arrow keys: move the player - Q/Ctrl-C: Quit'
);
}
const animate = () => {
term.clear();
viewport.clear();
showText();
log(logMsg); // LOGGING
drawShooter();
sprites.invaders.draw();
viewport.draw();
if (countframes % FRAMES_TILL_MOVE === 0) {
nextPosition();
startState = !startState;
addSpaceInvaders();
}
countframes += 1;
setTimeout( animate, 1000 / 60 );
}
const init = callback => {
termkit.getDetectedTerminal((error, detectedTerm) => {
if (error) {
throw new Error('Cannot detect terminal.')
}
terminal = detectedTerm;
twidth = terminal.width;
theight = terminal.height;
x = (twidth > INVADERS_WIDTH) ? (twidth - INVADERS_WIDTH) / 2 : 10;
startx = x;
xshoot = twidth / 2;
y = (theight > ROW_HEIGHT*ROWS) ? theight - (ROW_HEIGHT*ROWS + 25) : 2;
term.clear();
inputs();
viewport = new ScreenBuffer({
dst: terminal,
width: Math.min( terminal.width ),
height: Math.min( terminal.height - 1),
y: 2,
noFill: true
});
createInvadersBuffer();
addSpaceInvaders();
sprites.invaders.draw();
createShooter();
showText();
term.hideCursor();
term.grabInput() ;
term.on( 'key' , inputs ) ;
callback();
})
}
init(() => animate())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment