/**** * Classes ****/ /** * config { * x : Number || 0, * y : Number || 0, * rotation : Number || 0, * } **/ var ConfigContainer = Container.expand(function (config) { var self = Container.call(this); config = config || {}; ; self.x = config.x || 0; self.y = config.y || 0; self.rotation = config.rotation || 0; ; return self; }); var Textbox = ConfigContainer.expand(function (message, config) { var self = ConfigContainer.call(this, config); config = config || {}; ; var background = self.addChild(new BorderedShape({ width: config.width, height: config.height, weight: 10, anchorY: 1 })); var textboxTail = self.attachAsset('textboxTail', { y: 1, x: 20 }); var logo = self.addChild(new BorderedSymbol('logo', { x: -20, y: 20, anchorX: 0, anchorY: 1, height: config.height + 40 })); var typedText = self.addChild(new TypedText(message, { x: logo.width, y: -config.height / 2, anchorY: 0.5, delay: 50 })); ; self.setText = setText; ; function setText(newText) { typedText.setText(newText); } ; return self; }); var Table = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); ; var currentY = 0; var spawnPoints = []; var indices = []; for (var i = 0; i < TABLE_SLICES; i++) { var tableSliceId = 'tableSlice' + (i + 1); var tableSlice = self.attachAsset(tableSliceId, { x: 0, y: currentY, anchorX: 0.5, anchorY: 0 }); var scaleRatio = config.width / tableSlice.width; tableSlice.width = config.width; tableSlice.height *= scaleRatio; currentY += tableSlice.height; var holeCount = TABLE_HOLES[i]; var offset = TABLE_HOLE_GAP * (holeCount - 1) / 2; for (var j = 0; j < holeCount; j++) { indices.push(indices.length); spawnPoints.push(self.addChild(new ConfigContainer({ x: -offset + TABLE_HOLE_GAP * j, y: currentY }))); } } ; self.spawn = spawn; self.despawn = despawn; ; function spawn() { if (leaders.length > 0) { var slotIndex = indices.splice(Math.floor(Math.random() * indices.length), 1)[0]; var className = leaders.splice(Math.floor(Math.random() * leaders.length), 1)[0]; leaderList.push(spawnPoints[slotIndex].addChild(new className({ className: className, slotIndex: slotIndex }))); } } function despawn(slotIndex, className) { indices.push(slotIndex); leaders.push(className); } ; return self; }); var StartButton = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); ; var startButtonAsset = self.attachAsset('startButton', { anchorX: 0.5, anchorY: 0.5 }); ; return self; }); // Create an instance of StartButton in the middle of the screen var Leader = ConfigContainer.expand(function (imageId, config) { var self = ConfigContainer.call(this, config); ; var countdownTime = LEADER_DURATION; var leaderAsset = self.attachAsset(imageId, { anchorX: 0.5, anchorY: 0 }); var censorAsset = self.addChild(new BorderedShape({ y: 45, anchorX: 0.5, anchorY: 0, width: 110, height: 25, fill: '#000000', border: '#FFFFFF' })); self.scale.set(Math.random() < 0.5 ? -1 : 1, 1); ; self.update = update; self.tryBonk = tryBonk; self.slotIndex = config.slotIndex; self.className = config.className; self.leaderAsset = leaderAsset; self.censorAsset = censorAsset; self.points = LEADER_POINTS_TROLL; self.bonked = false; ; function update() { if (countdownTime === LEADER_DURATION) { if (self.y > -leaderAsset.height) { self.y = Math.max(-leaderAsset.height, self.y - leaderAsset.height / LEADER_SPAWN_TIME); } else { countdownTime--; } } else if (countdownTime > 0) { countdownTime--; } else { if (self.y < 0) { self.y += leaderAsset.height / LEADER_SPAWN_TIME; } else { return true; } } } function tryBonk(pointX, pointY) { if (!self.bonked) { var parent = self.parent; var rx = TABLE_HOLE_WIDTH * 0.5; var dx = pointX - GAME_WIDTH * 0.5 - parent.x; var cdy = pointY - (table.y + parent.y - rx); var ody = pointY - (table.y + parent.y + TABLE_HOLE_OFFSET); if (pointWithinCircle(dx, cdy, rx) || pointWithinOval(dx, ody, rx, TABLE_HOLE_DEPTH * 0.5)) { countdownTime = 0; self.bonked = true; return true; } } } ; return self; }); var LeaderTroll6 = Leader.expand(function (config) { var self = Leader.call(this, 'leaderTroll6', config); ; return self; }); var LeaderTroll5 = Leader.expand(function (config) { var self = Leader.call(this, 'leaderTroll5', config); ; self.censorAsset.y += 45; ; return self; }); var LeaderTroll4 = Leader.expand(function (config) { var self = Leader.call(this, 'leaderTroll4', config); ; self.censorAsset.y -= 5; ; return self; }); var LeaderTroll3 = Leader.expand(function (config) { var self = Leader.call(this, 'leaderTroll3', config); ; self.censorAsset.y += 8; ; return self; }); var LeaderTroll2 = Leader.expand(function (config) { var self = Leader.call(this, 'leaderTroll2', config); ; var leaderHat = self.attachAsset('leaderTrollHat', { anchorX: 0.5, anchorY: 0.25, rotation: -0.3 }); self.censorAsset.x += 20; self.censorAsset.y += 5; ; return self; }); var LeaderTroll1 = Leader.expand(function (config) { var self = Leader.call(this, 'leaderTroll1', config); ; self.censorAsset.x += 20; ; return self; }); var LeaderGreat1 = Leader.expand(function (config) { var self = Leader.call(this, 'leaderGreat1', config); var baseTryBonk = self.tryBonk; self.tryBonk = tryBonk; self.points = LEADER_POINTS_GREAT; ; function tryBonk(x, y) { if (baseTryBonk(x, y)) { if (MESSAGE_WRONG.length) { textbox.setText(MESSAGE_WRONG.splice(Math.floor(Math.random() * MESSAGE_WRONG.length), 1)[0]); messageTimer = MESSAGE_REFRESH; } return true; } } ; return self; }); var ImpactParticle = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); ; var elapsedTicks = 0; var selectedAsset = 'hammerParticle' + (1 + Math.floor(Math.random() * PARTICLE_HAMMER_ASSETS)); var particle = self.attachAsset(selectedAsset, { rotation: PARTICLE_HAMMER_ROTATION * (Math.random() - 0.5), anchorX: 0.5, anchorY: 0.5 }); ; self.update = update; ; function update() { elapsedTicks++; if (elapsedTicks <= PARTICLE_HAMMER_STAGE_2) { var scale = 1 + (PARTICLE_HAMMER_SCALE_MAX - 1) * elapsedTicks / PARTICLE_HAMMER_STAGE_2; particle.scale.set(scale, scale); } else if (elapsedTicks > PARTICLE_HAMMER_STAGE_2 && elapsedTicks <= PARTICLE_HAMMER_STAGE_2 + PARTICLE_HAMMER_STAGE_3) { var progress = 1 - (elapsedTicks - PARTICLE_HAMMER_STAGE_2) / PARTICLE_HAMMER_STAGE_3; var scale = PARTICLE_HAMMER_SCALE_MAX * progress; particle.alpha = progress; particle.scale.set(scale); } else { return true; } } ; return self; }); var HammerParticle = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); config = config || {}; ; var xFlip = config.xFlip || 1; var stage = 1; var elapsedTicks = 0; var hammer = self.attachAsset('hammer', { anchorX: 0.75, anchorY: 0.75, scale: { x: xFlip, y: 1 } }); hammer.x = -xFlip * hammer.width * 0.6; ; self.update = update; ; function update() { elapsedTicks++; if (stage === 1) { if (elapsedTicks <= PARTICLE_HAMMER_STAGE_1) { hammer.rotation += xFlip * PARTICLE_HAMMER_SPIN / PARTICLE_HAMMER_STAGE_1; } else { elapsedTicks = 0; stage++; handleImpactPoint(self.x, self.y); } } else if (stage === 2) { if (elapsedTicks <= PARTICLE_HAMMER_STAGE_2) { var alpha = 1 - elapsedTicks / PARTICLE_HAMMER_STAGE_2; hammer.alpha = alpha; } else { return true; } } } ; return self; }); /** * config { * x : Number || 0, // See: ConfigContainer * y : Number || 0, // See: ConfigContainer * rotation : Number || 0, // See: ConfigContainer * anchorX : Number || 0, * anchorY : Number || 1, * size : Number || TEXT_DEFAULT_SIZE, * weight : Number || TEXT_DEFAULT_WEIGHT, * font : String || TEXT_DEFAULT_FONT, * fill : String || TEXT_DEFAULT_FILL, * border : String || TEXT_DEFAULT_BORDER, * } **/ var BorderedText = ConfigContainer.expand(function (text, config) { var self = ConfigContainer.call(this, config); config = config || {}; ; var anchorX = config.anchorX !== undefined ? config.anchorX : 0; var anchorY = config.anchorY !== undefined ? config.anchorY : 1; var size = config.size !== undefined ? config.size : TEXT_DEFAULT_SIZE; var weight = config.weight !== undefined ? config.weight : TEXT_DEFAULT_WEIGHT; var font = config.font !== undefined ? config.font : TEXT_DEFAULT_FONT; var textFill = config.fill !== undefined ? config.fill : TEXT_DEFAULT_FILL; var borderFill = config.border !== undefined ? config.border : TEXT_DEFAULT_BORDER; var textAssets = []; var mainAsset; ; self.setText = setText; self.setFill = setFill; ; function setText(newText) { for (var i = 0; i < textAssets.length; i++) { textAssets[i].setText(newText); } } function setFill(newFill) { textFill = newFill; mainAsset.fill = newFill; } function buildTextAssets(newText) { for (var i = 0; i < TEXT_OFFSETS.length; i++) { var main = i === TEXT_OFFSETS.length - 1; var fill = main ? textFill : borderFill; var textAsset = textAssets[i]; if (textAsset) { textAsset.destroy(); } textAsset = self.addChild(new Text2(newText, { fill: fill, font: font, size: size })); textAsset.anchor = { x: anchorX, y: anchorY }; // NOTE: Cannot be set in config textAsset.x = TEXT_OFFSETS[i][0] * weight; // NOTE: Cannot be set in config textAsset.y = TEXT_OFFSETS[i][1] * weight; // NOTE: Cannot be set in config textAssets[i] = textAsset; } mainAsset = textAssets[TEXT_OFFSETS.length - 1]; } ; buildTextAssets(text); return self; }); var TypedText = BorderedText.expand(function (text, config) { var self = BorderedText.call(this, text, config); var baseSetText = self.setText; config = config || {}; ; var counter = 0; var delay = config.delay; var interval; ; self.setText = setText; self.completed = false; ; function setText(newText) { if (interval) { LK.clearInterval(interval); } self.completed = false; text = newText; counter = 0; interval = LK.setInterval(updateText, delay); updateText(); } function updateText() { var subText = text.substr(0, ++counter).replace(/#/g, ''); baseSetText(subText); if (counter === text.length) { LK.clearInterval(interval); self.completed = true; } } ; setText(text); return self; }); /** * var config = { * x : Number || 0, // See: ConfigContainer * y : Number || 0, // See: ConfigContainer * rotation : Number || 0, // See: ConfigContainer * anchorX : Number || .5, * anchorY : Number || .5, * scale : Number || undefined, * scaleX : Number || scale, * scaleY : Number || scale, * weight : Number || TEXT_DEFAULT_WEIGHT, * width : Number || undefined, // Auto-calculated if left undefined and height is set * height : Number || undefined, // Auto-calculated if left undefined and width is set * tint : String || 0xFFFFFF, // Not tinted by default * border : String || TEXT_DEFAULT_BORDER, * } **/ var BorderedSymbol = ConfigContainer.expand(function (symbol, config) { var self = ConfigContainer.call(this, config); config = config || {}; var width = config.width !== undefined ? config.width : undefined; var height = config.height !== undefined ? config.height : undefined; var scale = config.scale !== undefined ? config.scale : undefined; var scaleX = config.scaleX !== undefined ? config.scaleX : scale; var scaleY = config.scaleY !== undefined ? config.scaleX : scale; var weight = config.weight !== undefined ? config.weight : TEXT_DEFAULT_WEIGHT; var anchorX = config.anchorX !== undefined ? config.anchorX : .5; var anchorY = config.anchorY !== undefined ? config.anchorY : .5; var symbolTint = config.tint !== undefined ? config.tint : 0xFFFFFF; var borderTint = config.border !== undefined ? config.border : TEXT_DEFAULT_BORDER; var mainSymbol; var symbolAssets = []; ; self.setSymbol = buildSymbolAssets; self.setTint = setTint; ; function setTint(newTint) { // NOTE: Tinting is currently broken (cannot use string) // mainSymbol.tint = newTint; // symbolConfig.tint = newTint } function buildSymbolAssets(newSymbol) { for (var i = 0; i < TEXT_OFFSETS.length; i++) { var main = i === TEXT_OFFSETS.length - 1; var symbolAsset = symbolAssets[i]; if (symbolAsset) { symbolAsset.destroy(); } symbolAsset = self.attachAsset(newSymbol, { // tint: main ? symbolTint : borderTint, tint: main ? 0xFFFFFF : 0x000000, // NOTE: Tinting is currently broken (cannot use string) x: TEXT_OFFSETS[i][0] * weight, y: TEXT_OFFSETS[i][1] * weight, anchorX: anchorX, anchorY: anchorY }); if (width !== undefined && height === undefined) { height = symbolAsset.height * (width / symbolAsset.width); } else if (height !== undefined && width === undefined) { width = symbolAsset.width * (height / symbolAsset.height); } symbolAsset.width = width; symbolAsset.height = height; if (scaleX !== undefined && scaleY !== undefined) { symbolAsset.scale.set(scaleX, scaleY); } symbolAssets[i] = symbolAsset; } mainSymbol = symbolAssets[TEXT_OFFSETS.length - 1]; } ; buildSymbolAssets(symbol); return self; }); /** * config { * x : Number || 0, // See: ConfigContainer * y : Number || 0, // See: ConfigContainer * rotation : Number || 0, // See: ConfigContainer * anchorX : Number || 0, * anchorY : Number || 0, * width : Number || 100, * height : Number || 100, * weight : Number || TEXT_DEFAULT_WEIGHT, * shape : String || 'square', * fill : String || TEXT_DEFAULT_FILL, * border : String || TEXT_DEFAULT_BORDER, * } **/ var BorderedShape = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); config = config || {}; ; var anchorX = config.anchorX !== undefined ? config.anchorX : 0; var anchorY = config.anchorY !== undefined ? config.anchorY : 0; var width = config.width !== undefined ? config.width : 100; var height = config.height !== undefined ? config.height : 100; var weight = config.weight !== undefined ? config.weight : TEXT_DEFAULT_WEIGHT; var shape = config.shape !== undefined ? config.shape : 'shapeRectangle'; var frontTint = hexToHex(config.fill !== undefined ? config.fill : TEXT_DEFAULT_FILL); var borderTint = hexToHex(config.border !== undefined ? config.border : TEXT_DEFAULT_BORDER); var background = self.attachAsset(shape, { x: weight * 2 * (anchorX - 0.5), y: weight * 2 * (anchorY - 0.5), tint: borderTint, width: width + 2 * weight, height: height + 2 * weight, anchorX: anchorX, anchorY: anchorY }); var foreground = self.attachAsset(shape, { tint: frontTint, width: width, height: height, anchorX: anchorX, anchorY: anchorY }); ; return self; }); /**** * Initialize Game ****/ // Assets will be automatically initialized based on usage in the code. var game = new LK.Game({ backgroundColor: 0xD3D3D3 // Init game with light grey background }); /**** * Game Code ****/ ; //============================================================================== // Global constants & settings //============================================================================== ; // Math constants / pre-calculations var MATH_2_PI = Math.PI * 2; var MATH_HALF_PI = Math.PI / 2; var MATH_QUARTER_PI = Math.PI / 4; var MATH_HALF_ROOT_3 = Math.sqrt(3) / 2; // Required by: TEXT_OFFSETS, BorderedText, BorderedSymbol, BorderedShape, SymbolText var MATH_APPROX_ZERO = 0.0000001; ; // Text settings var TEXT_OFFSETS = [[0, 1], [MATH_HALF_ROOT_3, 0.5], [MATH_HALF_ROOT_3, -0.5], [0, -1], [-MATH_HALF_ROOT_3, -0.5], [-MATH_HALF_ROOT_3, 0.5], [0, 0]]; // Required by: BorderedText, BorderedSymbol, BorderedShape, SymbolText var TEXT_DEFAULT_WEIGHT = 6; // Required by: BorderedText, BorderedSymbol, BorderedShape, SymbolText var TEXT_DEFAULT_BORDER = '#000000'; // Required by: BorderedText, BorderedSymbol, BorderedShape, SymbolText var TEXT_DEFAULT_FILL = '#FFFFFF'; // Required by: BorderedText, SymbolText var TEXT_DEFAULT_FONT = 'Arial'; // Required by: BorderedText, SymbolText var TEXT_DEFAULT_SIZE = 50; // Required by: BorderedText, SymbolText var TEXT_DEFAULT_MARGIN = 10; // Required by: SymbolText ; // Game constants var GAME_TICKS = 60; var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var GAME_COUNTDOWN = 60 * GAME_TICKS; var GAME_COOLDOWN = 5 * GAME_TICKS; ; // Particle settings var PARTICLE_HAMMER_SPIN = MATH_QUARTER_PI * 2.5; var PARTICLE_HAMMER_STAGE_1 = Math.round(0.075 * GAME_TICKS); var PARTICLE_HAMMER_STAGE_2 = Math.round(0.075 * GAME_TICKS); var PARTICLE_HAMMER_STAGE_3 = Math.round(0.4 * GAME_TICKS); var PARTICLE_HAMMER_ASSETS = 5; var PARTICLE_HAMMER_ROTATION = MATH_QUARTER_PI; var PARTICLE_HAMMER_SCALE_MAX = 2.0; // Leader settings var LEADER_DURATION = Math.round(1.25 * GAME_TICKS); var LEADER_SPAWN_MIN = 2 * GAME_TICKS; var LEADER_SPAWN_VAR = 1 * GAME_TICKS; var LEADER_SPAWN_FACTOR = 0.96; var LEADER_SPAWN_TIME = Math.round(0.075 * GAME_TICKS); var LEADER_SPAWN_CUTOFF = 1 * GAME_TICKS; var LEADER_SPAWN_SNEAKY = 0.2; var LEADER_POINTS_TROLL = 1; var LEADER_POINTS_GREAT = -2; // Table settings var TABLE_WIDTH = 2500; var TABLE_DEPTH = 1500; var TABLE_CENTER_Y = GAME_HEIGHT / 2 + 125; var TABLE_SLICES = 6; var TABLE_HOLES = [1, 2, 3, 2, 1, 0]; var TABLE_HOLE_WIDTH = 334; var TABLE_HOLE_DEPTH = 230; var TABLE_HOLE_OFFSET = -83; var TABLE_HOLE_GAP = 776; var TABLE_BUTTON_INDEX = 4; // Messages var MESSAGE_REFRESH = 9 * GAME_TICKS; var MESSAGE_INTRO = 'Blue Lizard Entertainment proudly presents: #####Whac-a-Mo...##########\n... Whac-a-##########Politician? Are we T###R###Y###I###N###G### to get sued.########## Again?'; var MESSAGE_START = 'And off you go... Good luck.##########\nYou\'ll probably need it for this messy beta game.'; var MESSAGE_WRONG = ['Apparently you shouldn\'t bonk the Kiwi.', 'This isn\'t Kiwi Clicker.']; var MESSAGE_OUTRO = 'Well, that\'s all there is... Good job! Thanks for playing.'; var MESSAGE_EXTRA = 'That\'s a Sneaky one that... Good job! Thanks for playing.'; var MESSAGE_RANDO = []; MESSAGE_RANDO.push('Was this game a "Bobby-proposal"?'); MESSAGE_RANDO.push('Oh, we are S###O###O###O### getting sued for this.'); MESSAGE_RANDO.push('These people are the pinnacle leaders of humanity, surely not?'); MESSAGE_RANDO.push('The Europeans politicians seem...########## Okay?########## For once.'); MESSAGE_RANDO.push('This game must be divine punishment for milking a bad M###M###O### for\nover a decade.'); MESSAGE_RANDO.push('I\'m just here as a distraction to keep you from beating the company\nhighscores.'); MESSAGE_RANDO.push('Let\'s play spin the bottle on which game development company is\nhalving their workforce next.'); ; //============================================================================== // Global variables //============================================================================== ; var started = false; var ended = false; var score = 0; var countdown = GAME_COUNTDOWN; var spawnTime = LEADER_SPAWN_MIN; var spawnTimer = spawnTime; var messageTimer = MESSAGE_REFRESH; var leaders = [LeaderGreat1, LeaderTroll1, LeaderTroll2, LeaderTroll3, LeaderTroll4, LeaderTroll5, LeaderTroll6]; var leaderList = []; var particleList = []; ; var background = game.addChild(new Container()); var midground = game.addChild(new Container()); var foreground = game.addChild(new Container()); var table = background.addChild(new Table({ x: GAME_WIDTH / 2, y: GAME_HEIGHT / 2 - 600, width: TABLE_WIDTH })); var startButton = midground.addChild(new StartButton({ x: GAME_WIDTH / 2, y: TABLE_CENTER_Y })); ; var textbox = game.addChild(new Textbox(MESSAGE_INTRO, { x: 100, y: GAME_HEIGHT - 100, width: GAME_WIDTH - 200, height: 200 })); var countdownText = LK.gui.top.addChild(new BorderedText(Math.ceil(countdown / GAME_TICKS), { anchorX: 0.5, anchorY: 0, size: 200 })); var scoreText = LK.gui.topRight.addChild(new BorderedText(score, { x: -20, anchorX: 1, anchorY: 0, size: 100 })); ; //============================================================================== // Game events //============================================================================== ; game.on('down', function (obj) { var event = obj.event; var pos = event.getLocalPosition(game); var dx = Math.abs(GAME_WIDTH / 2 - pos.x) / TABLE_WIDTH; var dy = Math.abs(TABLE_CENTER_Y - pos.y) / TABLE_DEPTH; if (dx + dy <= 0.5) { particleList.push(foreground.addChild(new HammerParticle({ xFlip: pos.x < GAME_WIDTH / 2 ? -1 : 1, x: pos.x, y: pos.y }))); } }); ; LK.on('tick', function () { if (started) { if (ended) { if (--countdown < 0) { LK.showGameOver(); } } else { handleSpawnTimer(); handleMessageRefresh(); countdownText.setText(Math.ceil(countdown / GAME_TICKS)); if (--countdown < 0) { handleGameEnd(); } } for (var i = leaderList.length - 1; i >= 0; i--) { var leader = leaderList[i]; if (leader.update()) { table.despawn(leader.slotIndex, leader.className); leader.destroy(); leaderList.splice(i, 1); } } } for (var i = particleList.length - 1; i >= 0; i--) { if (particleList[i].update()) { particleList[i].destroy(); particleList.splice(i, 1); } } }); ; //============================================================================== // Global functions //============================================================================== ; // Handlers ; function handleSpawnTimer() { if (--spawnTimer <= 0 && countdown > LEADER_SPAWN_CUTOFF) { spawnTimer += spawnTime; spawnTime = spawnTime * LEADER_SPAWN_FACTOR; LK.setTimeout(table.spawn, Math.random() * LEADER_SPAWN_VAR); } } function handleMessageRefresh() { if (--messageTimer <= 0 && MESSAGE_RANDO.length) { textbox.setText(MESSAGE_RANDO.splice(Math.floor(Math.random() * MESSAGE_RANDO.length), 1)[0]); messageTimer = MESSAGE_REFRESH; } } function handleImpactPoint(x, y) { if (!started) { var dx = GAME_WIDTH / 2 - x; var dy = TABLE_CENTER_Y - y; if (pointWithinOval(dx, dy, startButton.width * 0.5, startButton.height * 0.5)) { started = true; startButton.destroy(); startButton = undefined; textbox.setText(MESSAGE_START); messageTimer = MESSAGE_REFRESH; particleList.push(midground.addChild(new ImpactParticle({ x: x, y: y }))); } } else { for (var i = leaderList.length - 1; i >= 0; i--) { var leader = leaderList[i]; if (leader.tryBonk(x, y)) { score = Math.max(0, LK.getScore() + leader.points); scoreText.setText(score); LK.setScore(score); particleList.push(midground.addChild(new ImpactParticle({ x: x, y: y }))); break; } } } } function handleGameEnd() { ended = true; countdown = GAME_COOLDOWN; if (Math.random() <= LEADER_SPAWN_SNEAKY) { LK.setTimeout(table.spawn, 2 * LEADER_SPAWN_VAR); textbox.setText(MESSAGE_EXTRA); } else { textbox.setText(MESSAGE_OUTRO); } } ; // Library ; function hexToHex(input) { if (typeof input === 'string') { return parseInt(input.replace(/^#/, ''), 16); } else if (typeof input === 'number') { return '#' + input.toString(16).padStart(6, '0'); } return input; } function pointWithinCircle(dx, dy, r) { if (dx >= -r && dx <= r && dy >= -r && dy <= r) { // Quick rectangle-check return dx * dx + dy * dy <= r * r; } return false; } function pointWithinOval(dx, dy, rx, ry) { if (dx >= -rx && dx <= rx && dy >= -ry && dy <= ry) { // Quick rectangle-check var rx2 = rx * rx; var ry2 = ry * ry; return ry2 * dx * dx + rx2 * dy * dy <= ry2 * rx2; } return false; }
===================================================================
--- original.js
+++ change.js
@@ -133,12 +133,14 @@
}));
self.scale.set(Math.random() < 0.5 ? -1 : 1, 1);
;
self.update = update;
+ self.tryBonk = tryBonk;
self.slotIndex = config.slotIndex;
self.className = config.className;
self.leaderAsset = leaderAsset;
self.censorAsset = censorAsset;
+ self.points = LEADER_POINTS_TROLL;
self.bonked = false;
;
function update() {
if (countdownTime === LEADER_DURATION) {
@@ -156,15 +158,20 @@
return true;
}
}
}
- function tryBonk() {
+ function tryBonk(pointX, pointY) {
if (!self.bonked) {
- // TODO: Check if collision before performing
- scoreText.setText(++score);
- self.countdown = 0;
- self.bonked = true;
- return true;
+ var parent = self.parent;
+ var rx = TABLE_HOLE_WIDTH * 0.5;
+ var dx = pointX - GAME_WIDTH * 0.5 - parent.x;
+ var cdy = pointY - (table.y + parent.y - rx);
+ var ody = pointY - (table.y + parent.y + TABLE_HOLE_OFFSET);
+ if (pointWithinCircle(dx, cdy, rx) || pointWithinOval(dx, ody, rx, TABLE_HOLE_DEPTH * 0.5)) {
+ countdownTime = 0;
+ self.bonked = true;
+ return true;
+ }
}
}
;
return self;
@@ -216,9 +223,22 @@
return self;
});
var LeaderGreat1 = Leader.expand(function (config) {
var self = Leader.call(this, 'leaderGreat1', config);
+ var baseTryBonk = self.tryBonk;
+ self.tryBonk = tryBonk;
+ self.points = LEADER_POINTS_GREAT;
;
+ function tryBonk(x, y) {
+ if (baseTryBonk(x, y)) {
+ if (MESSAGE_WRONG.length) {
+ textbox.setText(MESSAGE_WRONG.splice(Math.floor(Math.random() * MESSAGE_WRONG.length), 1)[0]);
+ messageTimer = MESSAGE_REFRESH;
+ }
+ return true;
+ }
+ }
+ ;
return self;
});
var ImpactParticle = ConfigContainer.expand(function (config) {
var self = ConfigContainer.call(this, config);
@@ -277,12 +297,8 @@
} else {
elapsedTicks = 0;
stage++;
handleImpactPoint(self.x, self.y);
- particleList.push(midground.addChild(new ImpactParticle({
- x: self.x,
- y: self.y
- })));
}
} else if (stage === 2) {
if (elapsedTicks <= PARTICLE_HAMMER_STAGE_2) {
var alpha = 1 - elapsedTicks / PARTICLE_HAMMER_STAGE_2;
@@ -553,8 +569,10 @@
// Game constants
var GAME_TICKS = 60;
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
+var GAME_COUNTDOWN = 60 * GAME_TICKS;
+var GAME_COOLDOWN = 5 * GAME_TICKS;
;
// Particle settings
var PARTICLE_HAMMER_SPIN = MATH_QUARTER_PI * 2.5;
var PARTICLE_HAMMER_STAGE_1 = Math.round(0.075 * GAME_TICKS);
@@ -563,48 +581,52 @@
var PARTICLE_HAMMER_ASSETS = 5;
var PARTICLE_HAMMER_ROTATION = MATH_QUARTER_PI;
var PARTICLE_HAMMER_SCALE_MAX = 2.0;
// Leader settings
-var LEADER_DURATION = 1 * GAME_TICKS;
+var LEADER_DURATION = Math.round(1.25 * GAME_TICKS);
var LEADER_SPAWN_MIN = 2 * GAME_TICKS;
var LEADER_SPAWN_VAR = 1 * GAME_TICKS;
-var LEADER_SPAWN_FACTOR = 0.95;
+var LEADER_SPAWN_FACTOR = 0.96;
var LEADER_SPAWN_TIME = Math.round(0.075 * GAME_TICKS);
+var LEADER_SPAWN_CUTOFF = 1 * GAME_TICKS;
+var LEADER_SPAWN_SNEAKY = 0.2;
+var LEADER_POINTS_TROLL = 1;
+var LEADER_POINTS_GREAT = -2;
// Table settings
var TABLE_WIDTH = 2500;
var TABLE_DEPTH = 1500;
var TABLE_CENTER_Y = GAME_HEIGHT / 2 + 125;
var TABLE_SLICES = 6;
var TABLE_HOLES = [1, 2, 3, 2, 1, 0];
var TABLE_HOLE_WIDTH = 334;
-var TABLE_HOLE_GAP = 778;
+var TABLE_HOLE_DEPTH = 230;
+var TABLE_HOLE_OFFSET = -83;
+var TABLE_HOLE_GAP = 776;
var TABLE_BUTTON_INDEX = 4;
-// Other settings
-var COUNTDOWN_GAME = 60 * GAME_TICKS;
-var HAMMER_RADIUS = 50;
// Messages
-var MESSAGE_REFRESH = 5 * GAME_TICKS;
+var MESSAGE_REFRESH = 9 * GAME_TICKS;
var MESSAGE_INTRO = 'Blue Lizard Entertainment proudly presents: #####Whac-a-Mo...##########\n... Whac-a-##########Politician? Are we T###R###Y###I###N###G### to get sued.########## Again?';
-var MESSAGE_START = 'And off you go... Good luck. You\'ll probably need it for this beta-mess.';
+var MESSAGE_START = 'And off you go... Good luck.##########\nYou\'ll probably need it for this messy beta game.';
var MESSAGE_WRONG = ['Apparently you shouldn\'t bonk the Kiwi.', 'This isn\'t Kiwi Clicker.'];
var MESSAGE_OUTRO = 'Well, that\'s all there is... Good job! Thanks for playing.';
var MESSAGE_EXTRA = 'That\'s a Sneaky one that... Good job! Thanks for playing.';
var MESSAGE_RANDO = [];
-MESSAGE_RANDO.push('Was this a "Bobby-proposal"?');
+MESSAGE_RANDO.push('Was this game a "Bobby-proposal"?');
MESSAGE_RANDO.push('Oh, we are S###O###O###O### getting sued for this.');
MESSAGE_RANDO.push('These people are the pinnacle leaders of humanity, surely not?');
-MESSAGE_RANDO.push('The Europeans leaders seem...########## Okay?########## For once.');
-MESSAGE_RANDO.push('This game must be divine punishment for milking a bad M###M###O### for decades.');
-MESSAGE_RANDO.push('I\'m just here as a distraction to keep you from beating the company highscores.');
-MESSAGE_RANDO.push('Let\'s play spin the bottle on which game company is halving their workforce, again.');
+MESSAGE_RANDO.push('The Europeans politicians seem...########## Okay?########## For once.');
+MESSAGE_RANDO.push('This game must be divine punishment for milking a bad M###M###O### for\nover a decade.');
+MESSAGE_RANDO.push('I\'m just here as a distraction to keep you from beating the company\nhighscores.');
+MESSAGE_RANDO.push('Let\'s play spin the bottle on which game development company is\nhalving their workforce next.');
;
//==============================================================================
// Global variables
//==============================================================================
;
var started = false;
+var ended = false;
var score = 0;
-var countdown = COUNTDOWN_GAME;
+var countdown = GAME_COUNTDOWN;
var spawnTime = LEADER_SPAWN_MIN;
var spawnTimer = spawnTime;
var messageTimer = MESSAGE_REFRESH;
var leaders = [LeaderGreat1, LeaderTroll1, LeaderTroll2, LeaderTroll3, LeaderTroll4, LeaderTroll5, LeaderTroll6];
@@ -661,14 +683,20 @@
});
;
LK.on('tick', function () {
if (started) {
- handleSpawnTimer();
- handleMessageRefresh();
- if (--countdown <= 0) {
- LK.showGameOver();
+ if (ended) {
+ if (--countdown < 0) {
+ LK.showGameOver();
+ }
+ } else {
+ handleSpawnTimer();
+ handleMessageRefresh();
+ countdownText.setText(Math.ceil(countdown / GAME_TICKS));
+ if (--countdown < 0) {
+ handleGameEnd();
+ }
}
- countdownText.setText(Math.ceil(countdown / GAME_TICKS));
for (var i = leaderList.length - 1; i >= 0; i--) {
var leader = leaderList[i];
if (leader.update()) {
table.despawn(leader.slotIndex, leader.className);
@@ -691,9 +719,9 @@
;
// Handlers
;
function handleSpawnTimer() {
- if (--spawnTimer <= 0) {
+ if (--spawnTimer <= 0 && countdown > LEADER_SPAWN_CUTOFF) {
spawnTimer += spawnTime;
spawnTime = spawnTime * LEADER_SPAWN_FACTOR;
LK.setTimeout(table.spawn, Math.random() * LEADER_SPAWN_VAR);
}
@@ -711,13 +739,41 @@
if (pointWithinOval(dx, dy, startButton.width * 0.5, startButton.height * 0.5)) {
started = true;
startButton.destroy();
startButton = undefined;
+ textbox.setText(MESSAGE_START);
+ messageTimer = MESSAGE_REFRESH;
+ particleList.push(midground.addChild(new ImpactParticle({
+ x: x,
+ y: y
+ })));
}
} else {
- // TODO: Check bonk collisions
+ for (var i = leaderList.length - 1; i >= 0; i--) {
+ var leader = leaderList[i];
+ if (leader.tryBonk(x, y)) {
+ score = Math.max(0, LK.getScore() + leader.points);
+ scoreText.setText(score);
+ LK.setScore(score);
+ particleList.push(midground.addChild(new ImpactParticle({
+ x: x,
+ y: y
+ })));
+ break;
+ }
+ }
}
}
+function handleGameEnd() {
+ ended = true;
+ countdown = GAME_COOLDOWN;
+ if (Math.random() <= LEADER_SPAWN_SNEAKY) {
+ LK.setTimeout(table.spawn, 2 * LEADER_SPAWN_VAR);
+ textbox.setText(MESSAGE_EXTRA);
+ } else {
+ textbox.setText(MESSAGE_OUTRO);
+ }
+}
;
// Library
;
function hexToHex(input) {
@@ -727,7 +783,20 @@
return '#' + input.toString(16).padStart(6, '0');
}
return input;
}
+function pointWithinCircle(dx, dy, r) {
+ if (dx >= -r && dx <= r && dy >= -r && dy <= r) {
+ // Quick rectangle-check
+ return dx * dx + dy * dy <= r * r;
+ }
+ return false;
+}
function pointWithinOval(dx, dy, rx, ry) {
- return dx * dx / (rx * rx) + dy * dy / (ry * ry) <= 1;
+ if (dx >= -rx && dx <= rx && dy >= -ry && dy <= ry) {
+ // Quick rectangle-check
+ var rx2 = rx * rx;
+ var ry2 = ry * ry;
+ return ry2 * dx * dx + rx2 * dy * dy <= ry2 * rx2;
+ }
+ return false;
}
\ No newline at end of file
logo for a company called "blue lizard entertainment" using a damaged font and frozen elements.
Pixel art of the bam symbol. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art of bam comic symbol.
pixel art of pow comic symbol.
pixel art of plastic squeaky hammer.
pixel art of a large, round, red start button.