FossilOrigin-Name: 2590ac1110487535856c4eed5c0780cf7af169bad5ea97245dfea54a60d69f6a
This commit is contained in:
nekobit 2022-06-15 08:08:08 +00:00
parent 0cc4efb2a3
commit 1616c5f6f0
3 changed files with 335 additions and 0 deletions

273
dist/js/worm.js vendored Normal file
View file

@ -0,0 +1,273 @@
// 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;
class Wormle
{
constructor(view, title, score, opts)
{
this.view = view;
this.title = title;
this.score_text = score;
// State
this.state = STATE_START;
// Reset to blank game state
this.reset();
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.state_handle();
}
reset()
{
// Player
this.body = [];
this.body_len = 8;
this.score = 0;
this.food_sum = 4;
this.level = 0;
this.tickspeed = 400;
// Controls
this.pos = this.spawn_pos = { x: 3, y: 3 };
this.direction = RIGHT;
this.direction_queue = [];
}
worm_grow()
{
// If anything else, assume we are starting
let { x, y } = this.pos;
let body = document.createElement("div");
body.className = "wormle-body wormle-body-" + this.body.length;
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";
this.view.appendChild(body);
this.body.unshift({
pos: { x, y },
elem: body,
});
}
move(dir)
{
const DIR_QUEUE_MAX = 4;
if (this.direction_queue.length < DIR_QUEUE_MAX)
this.direction_queue.push(dir);
}
worm_update()
{
if (this.body.length === this.body_len)
{
// 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";
// // First head is profile picture
// if (!this.body.length)
// body.style.background = "url('" + document.querySelector(".account-sidebar .acct-info .acct-pfp").src + "')";
}
}
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 = `<h1>You lost! Score: ${this.score}</h1>
<p>Press any key...</p>`;
}
start()
{
this.title.innerHTML = `<h1>Wormle</h1>
<p>Press any key...</p>`;
this.reset();
for (let i of document.querySelectorAll(".wormle-body"))
{
i.remove();
}
}
next_state()
{
this.state++;
if (this.state > STATE_GAME_OVER)
this.state = 0;
this.state_handle();
}
state_handle()
{
switch (this.state)
{
case STATE_START:
this.start();
break;
case STATE_GAME_OVER:
this.game_over();
break;
default:
this.score_text.innerHTML = this.score;
this.title.innerHTML = '';
break;
}
}
check_collision()
{
for (let i = 1; i < this.body.length; ++i)
{
if (this.body[0].pos.x === this.body[i].pos.x &&
this.body[0].pos.y === this.body[i].pos.y)
{
this.state = STATE_GAME_OVER;
this.state_handle();
}
}
}
update()
{
if (this.state == STATE_PLAYING)
{
if (this.body.length < this.body_len)
this.worm_grow();
this.handle_movement();
this.check_collision();
this.worm_update();
}
}
}
function start_wormle()
{
let wormle_view = document.createElement("div");
wormle_view.tabIndex = 1;
let title = document.createElement("span");
title.className = "wormle-title";
let score = document.createElement("span");
score.className = "wormle-score";
wormle_view.appendChild(score);
wormle_view.appendChild(title);
let game = new Wormle(wormle_view, title, score, {
grid_size: [16, 16], // Tiles
view_size: [400, 400], // Px
});
setInterval(() => {
game.update();
}, game.tickspeed);
document.addEventListener("keydown", (e) => {
// Fallback incase
e = e || window.event;
if (e.target.classList.contains("wormle-view"))
{
if (game.state !== STATE_PLAYING)
game.next_state();
else switch (e.keyCode)
{
// Left
case 37: {
game.move(LEFT);
break;
}
// Up
case 38: {
game.move(UP);
break;
}
// Right
case 39: {
game.move(RIGHT);
break;
}
// Down
case 40: {
game.move(DOWN);
break;
}
}
e.preventDefault();
return false;
}
});
let view_place = document.querySelector(".about-content");
document.querySelector(".simple-page").insertBefore(wormle_view, view_place);
}
(function() {
document.getElementById("about-icon").addEventListener("click", start_wormle);
})();

59
dist/treebird20.css vendored
View file

@ -1858,6 +1858,13 @@ ul.large-list li a.edit-list-btn
display: inline;
margin-right: 16px;
vertical-align: middle;
border-radius: 100%;
cursor: pointer;
}
#about-icon:hover
{
box-shadow: 0px 2px 5px red;
}
.about-header h1
@ -1948,3 +1955,55 @@ ul.large-list li a.edit-list-btn
70% { transform: rotate(-0deg) skew(-30deg); }
100% { transform: rotate(-35deg) skew(-30deg); }
}
/* Wormle stuff - If you're a theme dev just ignore this honestly */
.wormle-view
{
position: relative;
border: 1px solid #505050;
border-radius: 4px;
background-color: #fff;
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2);
width: 400px;
height: 400px;
margin: auto;
}
.wormle-view h1
{
border: 0;
padding: 0;
margin: 0;
}
.wormle-body
{
z-index: 3;
position: absolute;
background-color: #dd0000;
border: 1px solid #aa0000;
border-radius: 4px;
}
.wormle-view .wormle-body:last-child
{
transition: left .2s linear, top .2s linear;
}
.wormle-score
{
z-index: 9;
position: absolute;
right: 5px;
font-size: 18px;
color: black;
}
.wormle-title
{
z-index: 9;
margin-top: 140px;
text-align: center;
display: block;
}

View file

@ -23,3 +23,6 @@
<a class="btn btn-single" href="https://fossil.nekobit.net/treebird/home">View the Fossil Repository</a> <a class="btn btn-single" href="/about/license">View the License</a>
</div>
</div>
<!-- Scripts -->
<script src="/js/worm.js"></script>