Boxing Game
Last updated
Last updated
1) File
2) main.js
let ghost = App.loadSpritesheet("ghost.png", 32, 48, {
left: [2],
right: [1],
up: [3],
down: [0],
});
let redBoxing = App.loadSpritesheet("redBoxing.png");
const STATE_INTRO = 3001;
const STATE_INIT = 3002;
const STATE_RULE = 3003;
const STATE_PLAYING = 3004;
const STATE_JUDGE = 3005;
const STATE_END = 3006;
let lastSurvivor = null;
let _start = false;
let _players = App.players;
let _state = STATE_INIT;
let _stateTimer = 0;
let _alive = 0;
let _widget = null;
function init() {
for (let i in _players) {
let p = _players[i];
setHPgage(p, p.tag.hp);
p.sendUpdated();
}
_alive = checkSuvivors();
}
function startState(state) {
_state = state;
_stateTimer = 0;
switch (_state) {
case STATE_INTRO:
for (let i in _players) {
let p = _players[i];
if (p.tag.widget) {
p.tag.widget.destroy();
p.tag.widget = null;
}
}
// Game starts
_start = true;
_widget = App.showWidget("intro.html", "middle", 350, 340);
App.playSound("intro.wav");
break;
case STATE_INIT:
init();
break;
case STATE_RULE:
_widget = App.showWidget("rule.html", "middle", 400, 200);
for (let i in _players) {
let p = _players[i];
p.moveSpeed = 0;
p.sendUpdated();
}
break;
case STATE_PLAYING:
if (_widget) {
_widget.destroy();
_widget = null;
}
_widget = App.showWidget("status.html", "top", 700, 300);
for (let i in _players) {
let p = _players[i];
p.moveSpeed = 80;
p.sendUpdated();
}
break;
case STATE_JUDGE:
break;
case STATE_END:
if (_widget) {
_widget.destroy();
_widget = null;
}
_start = false;
for (let i in _players) {
let p = _players[i];
p.sprite = null;
p.attackSprite = null;
p.title = null;
p.sprite = null;
p.moveSpeed = 80;
p.sendUpdated();
}
Map.clearAllObjects();
break;
}
}
// Functions for displaying HP blocks
function setHPgage(p, hp) {
switch (hp) {
case 5:
p.title = "▮▮▮▮▮";
break;
case 4:
p.title = "▮▮▮▮";
break;
case 3:
p.title = "▮▮▮";
break;
case 2:
p.title = "▮▮";
break;
case 1:
p.title = "▮";
break;
}
}
// Functions for checking the number of surviving players
function checkSuvivors() {
let alive = 0;
for (let i in _players) {
let p = _players[i];
if (p.tag.alive) {
lastSurvivor = p;
++alive;
}
}
return alive;
}
App.onStart.Add(function () {
startState(STATE_INTRO);
});
App.onJoinPlayer.Add(function (p) {
p.tag = {
widget: null,
alive: true,
hp: 5,
shield: false,
time: 1, // Property for setting the invincible status for 1 sec after getting hit
};
p.attackSprite = redBoxing;
// When a new player enters during the game, set the player dead
if (_start) {
p.moveSpeed = 5;
p.sprite = ghost;
p.tag.alive = false;
p.sendUpdated();
}
_players = App.players;
});
App.onLeavePlayer.Add(function (p) {
p.attackSprite = null;
p.title = null;
p.sprite = null;
p.moveSpeed = 80;
p.sendUpdated();
_players = App.players;
});
// When attacking another player
App.onUnitAttacked.Add(function (sender, x, y, target) {
if (_state != STATE_PLAYING) return;
// If the attacker is dead, return
if (!sender.tag.alive) return;
// If the target is alive, and "shield" is "false"
if (target.tag.alive && !target.tag.shield) {
target.tag.hp--; // Reduce the target's health by 1.
// When the target's health becomes 0
if (target.tag.hp == 0) {
target.title = null; // Delete title
target.tag.alive = false; // alive property false
target.sprite = ghost; // Avatar turn into a ghost
target.moveSpeed = 5; // moveSpeed 80 -> 5
target.sendUpdated(); // Update target property
_alive = checkSuvivors();
// When there is a single last survivor
if (_alive == 1) {
if (_widget) {
_widget.destroy();
_widget = null;
}
// Show all connected players the result.html widget
_widget = App.showWidget("result.html", "top", 1055, 500);
// Send the last survivor's nickname to display in the widget
_widget.sendMessage({
alive: _alive,
name: lastSurvivor.name,
});
App.playSound("result.wav");
_stateTimer = 0;
startState(STATE_JUDGE);
}
} else {
// Target becomes invincible for 1 sec after getting hit (shield = true)
target.tag.shield = true;
setHPgage(target, target.tag.hp);
target.sendUpdated();
}
}
});
App.onUpdate.Add(function (dt) {
if (!_start) return;
_stateTimer += dt;
switch (_state) {
case STATE_INTRO:
// Display the intro.html widget for 5 secs and start STATE_INIT
if (_stateTimer >= 5) {
if (_widget) {
_widget.destroy();
_widget = null;
}
App.stopSound();
startState(STATE_INIT);
}
break;
case STATE_INIT:
startState(STATE_RULE);
break;
// Display the rule.html widget for 3 secs and start STATE_PLAYING
case STATE_RULE:
if (_stateTimer >= 3) {
if (_widget) {
_widget.destroy();
_widget = null;
}
startState(STATE_PLAYING);
}
break;
case STATE_PLAYING:
// Update the number of survivors of the status.html widget
if (_widget) {
_widget.sendMessage({
suvivors: _alive,
});
}
for (let i in _players) {
let p = _players[i];
// Skip if the player is dead
if (!p.tag.alive) continue;
// Shield property becomes false after 1 sec
if (p.tag.shield) {
p.tag.time -= dt;
if (p.tag.time <= 0) {
p.tag.shield = false;
p.tag.time = 1; // Reset shield duration to 1 sec
}
}
}
_alive = checkSuvivors();
// Display the result.html widget if the number of a survivor is 1 or 0
if (_alive == 1) {
if (_widget) {
_widget.destroy();
_widget = null;
}
_widget = App.showWidget("result.html", "top", 1055, 500);
_widget.sendMessage({
alive: _alive,
name: lastSurvivor.name,
});
App.playSound("result.wav");
startState(STATE_JUDGE);
} else if (_alive == 0) {
if (_widget) {
_widget.destroy();
_widget = null;
}
_widget = App.showWidget("result.html", "top", 1055, 500);
_widget.sendMessage({
alive: _alive,
});
App.playSound("result.wav");
startState(STATE_JUDGE);
}
break;
//Display the result.html widget for 5 secs and start STATE_END
case STATE_JUDGE:
if (_stateTimer >= 5) {
startState(STATE_END);
}
break;
case STATE_END:
break;
}
});
// Function executes when the app is closed or the game block is destroyed.
App.onDestroy.Add(function () {
// Delete all objects installed by the app
Map.clearAllObjects();
});