/****
* 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.slotIndex = config.slotIndex;
self.className = config.className;
self.leaderAsset = leaderAsset;
self.censorAsset = censorAsset;
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() {
if (!self.bonked) {
// TODO: Check if collision before performing
scoreText.setText(++score);
self.countdown = 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);
;
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);
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;
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;
;
// 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 = 1 * 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_TIME = Math.round(0.075 * GAME_TICKS);
// 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_BUTTON_INDEX = 4;
// Other settings
var COUNTDOWN_GAME = 60 * GAME_TICKS;
var HAMMER_RADIUS = 50;
// Messages
var MESSAGE_REFRESH = 5 * 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_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('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.');
;
//==============================================================================
// Global variables
//==============================================================================
;
var started = false;
var score = 0;
var countdown = COUNTDOWN_GAME;
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) {
handleSpawnTimer();
handleMessageRefresh();
if (--countdown <= 0) {
LK.showGameOver();
}
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);
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) {
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;
}
} else {
// TODO: Check bonk collisions
}
}
;
// 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 pointWithinOval(dx, dy, rx, ry) {
return dx * dx / (rx * rx) + dy * dy / (ry * ry) <= 1;
}
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.