%%js
// GAME_RUNNER: Cookie Clicker challenge mode with smaller target | hide_edit: true, panel: cookie_hack_game, slot: right, layout: row, ratio: 20-80, gap: 1rem, height: 520px, width: 100%
import GameControl from '@assets/js/GameEnginev1.1/essentials/GameControl.js';
import Clicker from '@assets/js/GameEnginev1.1/essentials/Clicker.js'
class CookieClicker {
constructor(gameEnv) {
const path = gameEnv.path;
const width = gameEnv.innerWidth;
const height = gameEnv.innerHeight;
const cookie_src = path + "/hacks/cookie-clicker/assets/baseCookie.png";
const grandma_src = path + "/hacks/cookie-clicker/assets/grandma.png";
// Shared score map for all spawned clickers in this runner instance.
window.cookieHackCounters = window.cookieHackCounters || {};
// Function to render the counters
const renderCounters = () => {
const entries = Object.entries(window.cookieHackCounters);
const total = entries.reduce((sum, pair) => sum + pair[1], 0);
// Update total clicks
const totalEl = document.getElementById('cookie-hack-panel-clicks');
if (totalEl) totalEl.textContent = "Total Clicks: " + total;
// Also keep the game-runner metric aligned with the same total.
const runnerMetric = document.getElementById('gamerunner-cookie-1-metric');
if (runnerMetric) runnerMetric.textContent = "Total Clicks: " + total;
// Breakdown clicks by spawned objects
const listEl = document.getElementById('cookie-hack-panel-counter-list');
if (!listEl) return;
if (entries.length === 0) {
listEl.innerHTML = "<em>No clicks yet.</em>";
return;
}
const rows = entries
.sort((a, b) => a[0].localeCompare(b[0]))
.map(function(pair) {
const id = pair[0];
const count = pair[1];
return '<li><code>' + id + '</code>: ' + count + '</li>';
})
.join('');
listEl.innerHTML = '<strong>Per Object:</strong><ul>' + rows + '</ul>';
};
// Same object-literal pattern as Runner 1, now tuned for more challenging play.
const cookie_clicker = {
id: 'Cookie Clicker',
greeting: "Click or collide with me to earn points!",
src: cookie_src,
SCALE_FACTOR: 8, // Higher value means smaller cookie, division of original size
pixels: {height: 512, width: 512},
INIT_POSITION: { x: 0, y: 0},
orientation: {rows: 1, columns: 1 },
down: {row: 0, start: 0, columns: 1, wiggle: 0.10 },
up: {row: 0, start: 0, columns: 1, wiggle: 0.10 },
left: {row: 0, start: 0, columns: 1, wiggle: 0.10 },
right: {row: 0, start: 0, columns: 1, wiggle: 0.10 },
hitbox: { widthPercentage: 0.15, heightPercentage: 0.15 },
// Walking area uses full container, so motion bounces off all four walls.
walkingArea: {
xMin: 0,
xMax: width,
yMin: 0,
yMax: height
},
speed: 3,
direction: { x: 1, y: 1 },
interact: function(clicks, objectId) {
// on callback, get objectId
const id = objectId || (this && this.spriteData && this.spriteData.id) || 'unknown';
window.cookieHackCounters[id] = clicks; // update map with object count
renderCounters();
},
};
// Associate Template with Clicker Class, define to spawn multiple instances
this.classes = [
{ class: Clicker, data: cookie_clicker,
spawn: {
count: 3, // object count
ranges: { // random value from range
INIT_POSITION: {
x: [0, Math.max(0, width - 128)],
y: [0, Math.max(0, height - 128)]
},
speed: [1, 5]
},
pickOne: { // random pick
src: [
cookie_src,
grandma_src
]
}
}
}
];
renderCounters();
}
}
export const gameLevelClasses = [CookieClicker];
export { GameControl };