// enum Direction const UP = 0; const RIGHT = 1; const DOWN = 2; const LEFT = 3; // enum State const STATE_START = 0; const STATE_PLAYING = 1; const STATE_GAME_OVER = 2; const STATE_GAME_WIN = 3; let started = false; class Wormle { constructor(view, title, score, opts) { this.view = view; this.title = title; this.score_text = score; // State this.state = STATE_START; this.grid_size = opts.grid_size; this.view_size = opts.view_size; this.tile_size = [ this.view_size[0] / this.grid_size[0], this.view_size[1] / this.grid_size[1] ]; // Apply class to get properties this.view.className = "wormle-view"; this.apples = []; this.state_handle(); this.loop = null; } reset() { // Player this.body = []; this.body_len = 8; this.score = 0; this.level = 0; this.tickspeed = 280; // Controls this.pos = this.spawn_pos = { x: 3, y: 3 }; this.direction = RIGHT; this.direction_queue = []; this.clear_apples(); this.apples = []; this.add_apple(); } clear_apples() { const len = this.apples.length for (let i = 0; i < len; ++i) { this.apples[this.apples.length-1].elem.remove(); this.apples.pop(); } } obj_rand_position() { let x = 0, y = 0; do { x = Math.floor(Math.random() * this.grid_size[0]); y = Math.floor(Math.random() * this.grid_size[1]); } while (this.check_collision(x, y)); return [x, y]; } create_body(name, x, y) { let body = document.createElement("div"); body.className = "wormle-body "+(name ? "wormle-"+name : ""); body.style.left = x * this.tile_size[0] + "px"; body.style.top = y * this.tile_size[1] + "px"; body.style.width = this.tile_size[0] + "px"; body.style.height = this.tile_size[1] + "px"; return body; } worm_grow() { // If anything else, assume we are starting let { x, y } = this.spawn_pos; if (this.body.length) { x = this.body[this.body.length-1].pos.x; y = this.body[this.body.length-1].pos.y; } let body = this.create_body("player", x, y); this.view.appendChild(body); this.body.push({ pos: { x, y }, elem: body, }); } add_apple() { let pos = this.obj_rand_position(); let body = this.create_body("apple", pos[0], pos[1]); this.view.appendChild(body); this.apples.push({ pos: { x: pos[0], y: pos[1], }, elem: body, }); } move(dir) { const DIR_QUEUE_MAX = 4; if (this.direction_queue.length < DIR_QUEUE_MAX) { this.direction_queue.push(dir); } } last_dir() { if (this.direction_queue.length) return this.direction_queue[this.direction_queue-1]; else return this.direction; } worm_update() { // Yeah this is ugly and i don't care its just an easter egg... for (let i = this.body.length-1; i >= 1; --i) { // Shift position forward this.body[i].elem.style.left = this.body[i-1].pos.x * this.tile_size[0] + "px"; this.body[i].elem.style.top = this.body[i-1].pos.y * this.tile_size[1] + "px"; this.body[i].pos.x = this.body[i-1].pos.x; this.body[i].pos.y = this.body[i-1].pos.y; } this.body[0].pos.x = this.pos.x; this.body[0].pos.y = this.pos.y; this.body[0].elem.style.left = this.pos.x * this.tile_size[0] + "px"; this.body[0].elem.style.top = this.pos.y * this.tile_size[1] + "px"; } handle_movement() { // Update queue if (this.direction_queue.length) { this.direction = this.direction_queue[0]; } this.direction_queue.shift(); // Move in direction switch (this.direction) { case LEFT: { this.pos.x--; break; } case RIGHT: { this.pos.x++; break; } case UP: { this.pos.y--; break; } default: case DOWN: { this.pos.y++; } } } game_over() { this.title.innerHTML = `
Press any key...
`; } game_win() { this.title.innerHTML = `Pat yourself on the back...
`; } start() { for (let i of document.querySelectorAll(".wormle-body")) { i.remove(); } this.title.innerHTML = `