BangleApps/apps/invader/app.js

452 lines
12 KiB
JavaScript
Raw Normal View History

2022-05-28 17:53:00 +00:00
// Brian Kumanchik
2022-05-27 19:28:06 +00:00
// Started 05-25-22
// My Invader Demo, for Bangle.js 2, written JavaScript - using Espruino Web IDE
2022-05-28 21:15:33 +00:00
// note: resolution is 176x176
// to do:
// upload to official app page
2022-05-29 15:21:23 +00:00
// make invader clock
2022-05-27 23:42:20 +00:00
2022-05-27 19:28:06 +00:00
// - variables -----------------------------------------
// invader variables
2022-05-27 23:42:20 +00:00
var inv_x = 77;
var inv_y = 20;
var i_anim_delay = 10; // invader animation (and move) delay
var inv_frame = 1; // invader start animation frame
var ix_speed = 6; // march speed
var i_dir = 1; // 1 = right, 0 = left
var been_hit = false; // invader hit state
2022-05-28 17:53:00 +00:00
// - shoot variables
2022-05-28 20:22:44 +00:00
var inv_shot_x = -32;
var inv_shot_y = -32;
2022-05-27 23:42:20 +00:00
var inv_fire_pause = 30;
2022-05-28 20:22:44 +00:00
var inv_fired = false; // invader fired state
2022-05-28 17:53:00 +00:00
// - explode variables
2022-05-27 23:42:20 +00:00
var been_hit = false; // invader hit state
var bx = -32; // blast x
var by = -32; // blast y
2022-05-28 17:53:00 +00:00
var blast_delay = 15; // invader blast delay - pause after explosion
var boom_play = false;
2022-05-27 19:28:06 +00:00
// turret variables
2022-05-28 17:53:00 +00:00
var tur_x = 77;
var tur_y = 148;
var shot_fired = false; // turret fired state
var sx = -20; // turret shot starting x - off screen
var sy = -20; // turret shot starting y - off screen
var turret_been_hit = false;
2022-05-28 21:15:33 +00:00
var turret_blast_delay = 25; // keep blast active on screen for 60 frames
2022-05-28 17:53:00 +00:00
var turret_exp_frame = 1; // turret explode start animation frame
2022-05-28 20:22:44 +00:00
var turret_anim_delay = 3; // turret explode animation delay
2022-05-28 17:53:00 +00:00
var explosion_play = false;
2022-05-27 19:28:06 +00:00
// misc variables
2022-05-28 20:22:44 +00:00
var score = 0; // starting score
var lives = 3; // starting lives
var game_state = 0; // game state - 0 = game not started, 1 = game running, 3 = game over
var ang = 0.1;
var start_been_pressed = false; // stops double press on restart
var fire_been_pressed = false; // stops auto fire
2022-05-27 19:28:06 +00:00
// input(screen controller) variables
2022-05-28 17:53:00 +00:00
var BTNL, BTNR, BTNF, BTNS; // button - left, right, fire, start
2022-05-27 19:28:06 +00:00
var tap = {};
2022-05-28 21:15:33 +00:00
// use tapping on screen for left, right, fire, start
2022-05-27 19:28:06 +00:00
Bangle.on('drag',e=>tap=e);
BTNL = { read : _=>tap.b && tap.x < 88 && tap.y > 88};
BTNR = { read : _=>tap.b && tap.x > 88 && tap.y > 88};
BTNF = { read : _=>tap.b && tap.x > 88 && tap.y < 88};
2022-05-28 17:53:00 +00:00
BTNS = { read : _=>tap.b && tap.x < 88 && tap.y < 88};
2022-05-27 19:28:06 +00:00
// - sprites -------------------------------------------
// invader sprites
2022-05-28 17:53:00 +00:00
var invader_a =
require("heatshrink").decompress(atob("hcIwkBiIBBAQoECCQQFBgEQAIMBEhUBDoYWDAYI="));
var invader_b =
2022-05-27 23:42:20 +00:00
require("heatshrink").decompress(atob("hcIwkBiIBBAQMQAoQEBgISCAYUQAIQAEB4YEBEAgEDAYIA=="));
2022-05-27 19:28:06 +00:00
var boom =
2022-05-27 23:42:20 +00:00
require("heatshrink").decompress(atob("hcJwkBiMQAIURgMQAgIKBAIICFAIMAAwIWBBAYSIEAgrDiA="));
2022-05-27 19:28:06 +00:00
var inv_shot =
2022-05-27 23:42:20 +00:00
require("heatshrink").decompress(atob("gcFwkBiERiAABAYQ"));
2022-05-27 19:28:06 +00:00
// turret sprites
2022-05-28 17:53:00 +00:00
var turret =
2022-05-27 23:42:20 +00:00
require("heatshrink").decompress(atob("h8IwkBiIABAYYACgAHFiEABggADCAInFgITBAAgOPA=="));
2022-05-28 17:53:00 +00:00
var tur_exp_a =
2022-05-27 23:42:20 +00:00
require("heatshrink").decompress(atob("h8IwkBiMRiACBAAwJEiAABBQgZCAAkAiAJBBoIUBgIABBgQACDIQ9ECQIA=="));
2022-05-28 17:53:00 +00:00
var tur_exp_b =
2022-05-27 23:42:20 +00:00
require("heatshrink").decompress(atob("h8IwkBiIBBAAUBiADCiMQAwQFDCIYXEB4IABgMAEYQXBiEAAQIQBAoIABDAQUCAAIVBA"));
2022-05-27 19:28:06 +00:00
var shot =
2022-05-27 23:42:20 +00:00
require("heatshrink").decompress(atob("gMDwkBAoIA=="));
// function to move and animate invader
2022-05-28 17:53:00 +00:00
function move_anim_inv() {
// invader anim code
i_anim_delay -= 1;
if ((i_anim_delay < 0) && !(been_hit)) {
i_anim_delay = 10;
inv_frame += 1;
if (inv_frame > 2) {
inv_frame = 1;
}
// move right
if (i_dir == 1){
inv_x += ix_speed;
if (inv_x >= 142) {
inv_y += 8; // step down
i_dir = -1;
}
2022-05-27 23:42:20 +00:00
}
2022-05-28 17:53:00 +00:00
// move left
if (i_dir < 1){
inv_x -= ix_speed;
if (inv_x <= 10) {
inv_y += 8; // step down
i_dir = 1;
}
}
}
}
2022-05-27 23:42:20 +00:00
// function to make invader fire
2022-05-28 17:53:00 +00:00
function invader_fire() {
inv_fire_pause -= 1;
2022-05-27 23:42:20 +00:00
2022-05-28 17:53:00 +00:00
if (!(inv_fired)) { // so once invader shot is fired it doesn't follow the invader still
inv_shot_x = inv_x + 8;
inv_shot_y = inv_y + 18;
}
if (inv_fire_pause < 0) {
inv_fired = true;
inv_shot_y += 8;
}
2022-05-27 23:42:20 +00:00
}
2022-05-28 17:53:00 +00:00
// function to make turret explode (when hit) then start back in center
function turret_hit() {
if (turret_been_hit) {
if (!(explosion_play)) {
2022-05-28 21:15:33 +00:00
//Bangle.buzz();
2022-05-28 17:53:00 +00:00
//Bangle.beep();
}
2022-05-27 23:42:20 +00:00
2022-05-28 17:53:00 +00:00
explosion_play = true;
turret_anim_delay -= 1;
turret_blast_delay -= 1;
2022-05-27 23:42:20 +00:00
2022-05-28 17:53:00 +00:00
if (turret_anim_delay < 0) {
turret_exp_frame += 1;
if (turret_exp_frame > 2) {
2022-05-28 21:15:33 +00:00
Bangle.buzz();
2022-05-28 17:53:00 +00:00
turret_exp_frame = 1;
}
turret_anim_delay = 3;
}
2022-05-27 23:42:20 +00:00
2022-05-28 17:53:00 +00:00
if (turret_blast_delay < 0) {
turret_blast_delay = 21;
turret_been_hit = false;
explosion_play = false;
tur_x = 77; // reset turret x
tur_y = 148; // reset turret y
}
}
}
// function to make invader explode (when hit) then randomly start somewhere else
function invader_hit() {
if (been_hit) {
if (!(boom_play)) {
Bangle.buzz();
//Bangle.beep();
}
2022-05-27 19:28:06 +00:00
2022-05-28 17:53:00 +00:00
inv_shot_x = -32; // hide shot
inv_shot_y = -32; // hide shot
inv_fire_pause = 30; // and reset pause
boom_play = true;
blast_delay -= 1;
if (blast_delay < 0) {
blast_delay = 15;
boom_play = false;
been_hit = false;
bx = -32; // move boom off screen (following invader)
by = -32;
2022-05-28 21:15:33 +00:00
// generate a random rounded number between 10 and 142;
inv_x = Math.floor(Math.random() * 142) + 10;
2022-05-28 17:53:00 +00:00
inv_y = 20; // move invader back up after being hit
i_dir = 1; // reset invader direction
}
}
}
2022-05-27 19:28:06 +00:00
// - setup stuff ---------------------------------------
function gameStart() {
2022-05-28 17:53:00 +00:00
setInterval(onFrame, 50);
2022-05-27 19:28:06 +00:00
}
2022-05-28 20:22:44 +00:00
// - main loop -------------------------------------------------------------
2022-05-27 19:28:06 +00:00
function onFrame() {
2022-05-28 17:53:00 +00:00
2022-05-28 21:15:33 +00:00
// game not started state (title screen) ***************************
2022-05-28 20:22:44 +00:00
if(game_state == 0) {
g.clear();
if (!(BTNS.read())) {
start_been_pressed = false; // stops double press on restart
}
// draw text during game over state
g.setFont("4x6", 4); // set font and size x 2
g.setColor(0,1,0); // set color (black)
g.drawString("INVADER", 33, 55);
// just animate invader
// invader anim code
i_anim_delay -= 1;
if(i_anim_delay < 0) {
2022-05-29 15:21:23 +00:00
i_anim_delay = 15;
2022-05-28 20:22:44 +00:00
inv_frame += 1;
if (inv_frame > 2) {
inv_frame = 1;
}
}
// draw sprites during game over state
2022-05-28 21:15:33 +00:00
// next 2 line for a rotating invader on the title screen
2022-05-28 20:22:44 +00:00
//ang += 0.1;
//g.drawImage(invader_a, 88, 98, {scale:4, rotate:ang});
if(inv_frame == 1) {
g.drawImage(invader_a, 88-22, 85, {scale:4});
}
else if(inv_frame == 2) {
g.drawImage(invader_b, 88-22, 85, {scale:4});
}
// reset stuff
if(BTNS.read() && !(start_been_pressed)) {
turret_been_hit = false;
tur_x = 77; // reset turret to center of screen
tur_y = 148; // reset turret y
inv_x = 77; // reset invader to center of screen
inv_y = 20; // reset invader back to top
i_dir = 1; // reset invader direction
lives = 3; // reset lives
score = 0; // reset score
explosion_play = false;
game_state = 1;
2022-05-28 21:15:33 +00:00
turret_blast_delay = 25;
2022-05-28 20:22:44 +00:00
}
g.flip();
}
2022-05-28 21:15:33 +00:00
// game over state *************************************************
2022-05-28 20:22:44 +00:00
if(game_state == 3) {
2022-05-27 19:28:06 +00:00
g.clear();
2022-05-28 17:53:00 +00:00
// draw text during game over state
g.setFont("4x6", 2); // set font and size x 2
g.setColor(0,0,0); // set color (black)
g.drawString("SCORE:" + score ,5, 5);
g.drawString("LIVES:" + lives ,117, 5);
g.drawString("GAME OVER", 52, 80);
// draw sprites during game over state
// - invader frame 2
g.drawImage(invader_b, inv_x, inv_y, {scale:2});
g.drawImage(tur_exp_b, tur_x, tur_y, {scale:2});
g.drawImage(inv_shot, inv_shot_x, inv_shot_y, {scale:2});
// reset stuff
if(BTNS.read()) {
2022-05-28 21:15:33 +00:00
//turret_been_hit = false;
//tur_x = 77; // reset turret to center of screen
//tur_y = 148; // reset turret y
//inv_x = 77; // reset invader to center of screen
//inv_y = 20; // reset invader back to top
//i_dir = 1; // reset invader direction
//lives = 3; // reset lives
//score = 0; // reset score
//explosion_play = false;
2022-05-28 20:22:44 +00:00
game_state = 0;
start_been_pressed = true;
2022-05-28 21:15:33 +00:00
//turret_blast_delay = 25;
2022-05-28 17:53:00 +00:00
}
g.flip();
}
2022-05-28 21:15:33 +00:00
// not game over state (game running) ******************************
2022-05-28 20:22:44 +00:00
if(game_state == 1) {
2022-05-28 17:53:00 +00:00
g.clear();
2022-05-28 20:22:44 +00:00
if (!(BTNF.read())) {
fire_been_pressed = false; // stops auto fire
}
2022-05-27 23:42:20 +00:00
// call function to move and animate invader
move_anim_inv();
2022-05-28 17:53:00 +00:00
2022-05-27 23:42:20 +00:00
// call function to make invader fire
invader_fire();
2022-05-27 19:28:06 +00:00
// check input (screen presses)
2022-05-28 17:53:00 +00:00
if(BTNL.read() && tur_x >= 12 && !(turret_been_hit)) {
2022-05-27 23:42:20 +00:00
tur_x -= 6;
2022-05-27 19:28:06 +00:00
}
2022-05-28 17:53:00 +00:00
else if(BTNR.read() && tur_x <= 140 && !(turret_been_hit)) {
2022-05-27 23:42:20 +00:00
tur_x += 6;
2022-05-27 19:28:06 +00:00
}
2022-05-28 20:22:44 +00:00
else if(BTNF.read() && !(turret_been_hit) && !(fire_been_pressed) && !(shot_fired)) {
2022-05-28 17:53:00 +00:00
shot_fired = true;
2022-05-28 20:22:44 +00:00
fire_been_pressed = true; // stops auto fire
2022-05-28 17:53:00 +00:00
sx=tur_x + 12;
sy=tur_y - 7;
}
// check for turret shot going off screen before allowing to fire again
if (shot_fired) {
sy -= 8;
if (sy < 22) {
shot_fired = false;
sx = -32;
sy = -32;
}
2022-05-27 19:28:06 +00:00
}
2022-05-27 23:42:20 +00:00
// check for invader shot going off screen before allowing to fire again
if (inv_shot_y > 150
) {
2022-05-28 17:53:00 +00:00
inv_fired = false;
inv_shot_x = inv_x - 1;
inv_shot_y = inv_y + 7;
inv_fire_pause = 30;
}
// check for turret shot and invader collision
if ((sx >= inv_x) && (sx <= inv_x + 20) && (sy <= inv_y + 14)) {
sx = -32;
sy = -32;
been_hit = true;
score += 10;
}
// check for invader shot and turret collision
if ((inv_shot_x + 4) >= (tur_x) && (inv_shot_x) <= (tur_x + 24) && (inv_shot_y + 8) >= (tur_y + 6)) {
if (!(turret_been_hit)) {
lives -= 1;
if (lives == 0) {
2022-05-28 21:15:33 +00:00
game_state = 3;
Bangle.buzz();
2022-05-28 17:53:00 +00:00
}
turret_been_hit = true;
}
}
2022-05-27 19:28:06 +00:00
// - draw sprites ----------------------------------
2022-05-28 17:53:00 +00:00
// invader sprites
if(!(been_hit)) {
if(inv_frame == 1) {
// - invader frame 1
g.drawImage(invader_a, inv_x, inv_y, {scale:2});
}
else if(inv_frame == 2) {
// - invader frame 2
g.drawImage(invader_b, inv_x, inv_y, {scale:2});
}
2022-05-27 23:42:20 +00:00
}
2022-05-28 17:53:00 +00:00
else {
// - invader explosion
g.drawImage(boom, inv_x, inv_y, {scale:2});
2022-05-27 23:42:20 +00:00
}
// - invader shot
if (inv_fired) {
2022-05-28 17:53:00 +00:00
g.drawImage(inv_shot, inv_shot_x, inv_shot_y, {scale:2});
2022-05-27 23:42:20 +00:00
}
else {
g.drawImage(inv_shot, -32, -32, {scale:2});
2022-05-28 17:53:00 +00:00
}
2022-05-27 23:42:20 +00:00
2022-05-28 20:22:44 +00:00
// turret sprites
2022-05-28 17:53:00 +00:00
if(!(turret_been_hit)) {
// - undamaged turret
g.drawImage(turret, tur_x, tur_y, {scale:2});
}
else {
if(turret_exp_frame == 1) {
// - turret explosion frame 1
g.drawImage(tur_exp_a, tur_x, tur_y, {scale:2});
}
else if(turret_exp_frame == 2) {
// - turret explosion frame 2
g.drawImage(tur_exp_b, tur_x, tur_y, {scale:2});
}
}
// - turret shot
g.drawImage(shot, sx, sy, {scale:2});
// call function to make invader explode then randomly start somewhere else
invader_hit();
// call function to make turret explode (when hit) then start back in center
turret_hit();
2022-05-27 19:28:06 +00:00
// - draw text -------------------------------------
2022-05-28 17:53:00 +00:00
g.setFont("4x6", 2); // set font and size x 2
g.setColor(0,0,0); // set color (black)
g.drawString("SCORE:" + score ,5,5);
2022-05-28 20:22:44 +00:00
g.drawString("LIVES:" + lives ,117,5);
2022-05-27 19:28:06 +00:00
g.flip();
}
2022-05-28 20:22:44 +00:00
} // end main loop ---------------------------------------------------------
2022-05-27 19:28:06 +00:00
gameStart();