mirror of
https://github.com/zyllian/zyllian.github.io.git
synced 2025-01-17 19:22:30 -08:00
add very basic clicker game
This commit is contained in:
parent
3ccd5b0df8
commit
19ffac4a90
9 changed files with 335 additions and 17 deletions
|
@ -1,7 +1,7 @@
|
|||
base_url: "https://zyl.gay"
|
||||
title: zyl is gay
|
||||
description: "zyl's website."
|
||||
sass_styles: [index.scss, "pet.scss"]
|
||||
sass_styles: [index.scss, pet.scss, click.scss]
|
||||
images_per_page: 10
|
||||
blog_posts_per_page: 20
|
||||
cdn_url: "https://i.zyl.gay"
|
||||
|
|
10
site/pages/click.md
Normal file
10
site/pages/click.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: click
|
||||
scripts: ["js/click.js"]
|
||||
styles: ["click.css"]
|
||||
embed:
|
||||
title: click
|
||||
site_name: zyl.gay
|
||||
description: click click click
|
||||
extra: click
|
||||
---
|
11
site/pages/games.md
Normal file
11
site/pages/games.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
title: games!
|
||||
---
|
||||
|
||||
# games
|
||||
|
||||
little games i've made on here :3
|
||||
|
||||
<h2><a href="/pet">pet game</a></h2>
|
||||
|
||||
<h2><a href="/click">clicker game</a></h2>
|
222
site/root/js/click.js
Normal file
222
site/root/js/click.js
Normal file
|
@ -0,0 +1,222 @@
|
|||
(function () {
|
||||
"use strict";
|
||||
|
||||
const click = document.querySelector("#click");
|
||||
const petsCounter = click.querySelector("#pets");
|
||||
const petsPerSecondCounter = click.querySelector("#pets-per-second");
|
||||
const barksCounter = click.querySelector("#barks");
|
||||
const barksPerSecondCounter = click.querySelector("#barks-per-second");
|
||||
const kissesCounter = click.querySelector("#kisses");
|
||||
const kissesPerSecondCounter = click.querySelector("#kisses-per-second");
|
||||
const barker = click.querySelector("#barker");
|
||||
const toolsEl = click.querySelector(".tools");
|
||||
|
||||
const toolPriceFactor = 0.1;
|
||||
const upgradePriceFactor = 0.2;
|
||||
const upgradeProductionFactor = 1.1;
|
||||
|
||||
const toolData = {
|
||||
hand: {
|
||||
priceIn: "barks",
|
||||
basePrice: 10,
|
||||
petsPerSecond: 0.5,
|
||||
},
|
||||
puppy: {
|
||||
priceIn: "pets",
|
||||
basePrice: 5,
|
||||
barksPerSecond: 0.5,
|
||||
},
|
||||
foodBowl: {
|
||||
priceIn: "barks",
|
||||
basePrice: 50,
|
||||
barksPerSecond: 1.3,
|
||||
},
|
||||
kisser: {
|
||||
priceIn: "pets",
|
||||
basePrice: 500,
|
||||
kissesPerSecond: 0.25,
|
||||
},
|
||||
};
|
||||
|
||||
let barks = 0;
|
||||
let pets = 0;
|
||||
let kisses = 0;
|
||||
let tools = {};
|
||||
|
||||
let petsPerSecond = 0;
|
||||
let barksPerSecond = 0;
|
||||
let kissesPerSecond = 0;
|
||||
|
||||
function calcPrice(base, count) {
|
||||
return Math.floor(base ** (1 + toolPriceFactor * count));
|
||||
}
|
||||
|
||||
function calcUpgradePrice(base, count) {
|
||||
return Math.floor((base * 2) ** (1 + upgradePriceFactor * count));
|
||||
}
|
||||
|
||||
const getValue = (name) => {
|
||||
if (name === "pets") {
|
||||
return pets;
|
||||
} else if (name === "barks") {
|
||||
return barks;
|
||||
} else if (name === "kisses") {
|
||||
return kisses;
|
||||
} else if (name === "petsPerSecond") {
|
||||
return petsPerSecond;
|
||||
} else if (name === "barksPerSecond") {
|
||||
return barksPerSecond;
|
||||
} else if (name === "kissesPerSecond") {
|
||||
return kissesPerSecond;
|
||||
}
|
||||
};
|
||||
|
||||
const setValue = (name, value) => {
|
||||
if (name === "pets") {
|
||||
pets = value;
|
||||
} else if (name === "barks") {
|
||||
barks = value;
|
||||
} else if (name === "kisses") {
|
||||
kisses = value;
|
||||
} else if (name === "petsPerSecond") {
|
||||
petsPerSecond = value;
|
||||
} else if (name === "barksPerSecond") {
|
||||
barksPerSecond = value;
|
||||
} else if (name === "kissesPerSecond") {
|
||||
kissesPerSecond = value;
|
||||
}
|
||||
};
|
||||
|
||||
const updatePerSecondValues = () => {
|
||||
let pets = 0;
|
||||
let barks = 0;
|
||||
let kisses = 0;
|
||||
|
||||
for (const [id, tool] of Object.entries(tools)) {
|
||||
pets +=
|
||||
(toolData[id].petsPerSecond || 0) *
|
||||
tool.count *
|
||||
tool.upgrades *
|
||||
upgradeProductionFactor;
|
||||
barks +=
|
||||
(toolData[id].barksPerSecond || 0) *
|
||||
tool.count *
|
||||
tool.upgrades *
|
||||
upgradeProductionFactor;
|
||||
kisses +=
|
||||
(toolData[id].kissesPerSecond || 0) *
|
||||
tool.count *
|
||||
tool.upgrades *
|
||||
upgradeProductionFactor;
|
||||
}
|
||||
|
||||
petsPerSecond = pets;
|
||||
barksPerSecond = barks;
|
||||
kissesPerSecond = kisses;
|
||||
};
|
||||
|
||||
const updateDisplay = () => {
|
||||
petsCounter.innerText = pets;
|
||||
petsPerSecondCounter.innerText = petsPerSecond.toFixed(2);
|
||||
barksCounter.innerText = barks;
|
||||
barksPerSecondCounter.innerText = barksPerSecond.toFixed(2);
|
||||
kissesCounter.innerText = kisses;
|
||||
kissesPerSecondCounter.innerText = kissesPerSecond.toFixed(2);
|
||||
};
|
||||
|
||||
for (const el of toolsEl.querySelectorAll(".tool")) {
|
||||
const id = el.getAttribute("data-tool");
|
||||
if (id) {
|
||||
const data = toolData[id];
|
||||
if (data) {
|
||||
const toolInfo = {
|
||||
count: 0,
|
||||
upgrades: 1,
|
||||
};
|
||||
tools[id] = toolInfo;
|
||||
|
||||
const count = el.querySelector(".count");
|
||||
const level = el.querySelector(".level");
|
||||
const buy = el.querySelector(".buy");
|
||||
const upgrade = el.querySelector(".upgrade");
|
||||
|
||||
const updateText = () => {
|
||||
count.innerText = toolInfo.count;
|
||||
level.innerText = toolInfo.upgrades;
|
||||
const price = calcPrice(data.basePrice, toolInfo.count);
|
||||
const upgradePrice = calcUpgradePrice(
|
||||
data.basePrice,
|
||||
toolInfo.upgrades
|
||||
);
|
||||
buy.innerText = `buy - ${price} ${data.priceIn}`;
|
||||
upgrade.innerText = `upgrade - ${upgradePrice} kisses`;
|
||||
};
|
||||
updateText();
|
||||
|
||||
buy.addEventListener("click", () => {
|
||||
const price = calcPrice(data.basePrice, toolInfo.count);
|
||||
const v = getValue(data.priceIn);
|
||||
if (v >= price) {
|
||||
setValue(data.priceIn, v - price);
|
||||
toolInfo.count += 1;
|
||||
updatePerSecondValues();
|
||||
updateText();
|
||||
updateDisplay();
|
||||
}
|
||||
});
|
||||
|
||||
upgrade.addEventListener("click", () => {
|
||||
const price = calcUpgradePrice(data.basePrice, toolInfo.upgrades);
|
||||
if (kisses >= price) {
|
||||
kisses -= price;
|
||||
toolInfo.upgrades += 1;
|
||||
updatePerSecondValues();
|
||||
updateText();
|
||||
updateDisplay();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
barker.addEventListener("click", () => {
|
||||
barks += 1;
|
||||
updateDisplay();
|
||||
});
|
||||
|
||||
let lastUpdate = 0;
|
||||
let petsQueued = 0;
|
||||
let barksQueued = 0;
|
||||
let kissesQueued = 0;
|
||||
|
||||
const checkQueue = (name, queued) => {
|
||||
const perSecond = getValue(`${name}PerSecond`);
|
||||
if (perSecond > 0) {
|
||||
const amount = 1000 / perSecond;
|
||||
const toAdd = Math.floor(queued / amount);
|
||||
setValue(name, getValue(name) + toAdd);
|
||||
updateDisplay();
|
||||
queued -= toAdd * amount;
|
||||
} else {
|
||||
queued = 0;
|
||||
}
|
||||
return queued;
|
||||
};
|
||||
|
||||
const update = (ts) => {
|
||||
requestAnimationFrame(update);
|
||||
|
||||
const diff = ts - lastUpdate;
|
||||
petsQueued += diff;
|
||||
barksQueued += diff;
|
||||
kissesQueued += diff;
|
||||
|
||||
petsQueued = checkQueue("pets", petsQueued);
|
||||
barksQueued = checkQueue("barks", barksQueued);
|
||||
kissesQueued = checkQueue("kisses", kissesQueued);
|
||||
|
||||
lastUpdate = ts;
|
||||
};
|
||||
|
||||
requestAnimationFrame(update);
|
||||
})();
|
27
site/sass/click.scss
Normal file
27
site/sass/click.scss
Normal file
|
@ -0,0 +1,27 @@
|
|||
#click {
|
||||
.resources {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 0fr);
|
||||
grid-auto-flow: row;
|
||||
|
||||
& > span {
|
||||
margin-right: 5px;
|
||||
width: max-content;
|
||||
|
||||
&.resource {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#barker {
|
||||
font-size: 2rem;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.tools {
|
||||
.name {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@
|
|||
<span class="pronouns">it/puppy(/she)</span>
|
||||
</span>
|
||||
<span class="spacer"></span>
|
||||
<a href="/pet">creature</a> |
|
||||
<a href="/games">games</a> |
|
||||
<a href="/projects">my projects</a> |
|
||||
<a href="/blog/">blog</a> |
|
||||
<a href="/images/">images</a> |
|
||||
|
|
30
site/templates/extras/click.hbs
Normal file
30
site/templates/extras/click.hbs
Normal file
|
@ -0,0 +1,30 @@
|
|||
<div id="click">
|
||||
<p>WARNING: no save mechanic is implemented yet!!</p>
|
||||
<h1>click</h1>
|
||||
<noscript>
|
||||
<h1>javascript is required for the clicker game!!</h1>
|
||||
</noscript>
|
||||
<div class="resources">
|
||||
{{#*inline "resource"}}
|
||||
<span class="resource">{{name}}</span><span id={{id}}>0</span> <span>(<span
|
||||
id="{{id}}-per-second">0</span>/s)</span>
|
||||
{{/inline}}
|
||||
{{> resource id="pets" name="pets"}}
|
||||
{{> resource id="barks" name="barks"}}
|
||||
{{> resource id="kisses" name="kisses"}}
|
||||
</div>
|
||||
<button id="barker">bark</button>
|
||||
<div class="tools">
|
||||
{{#*inline "tool"}}
|
||||
<div class="tool" data-tool={{id}}>
|
||||
<p class="name">{{name}} (<span class="count">0</span>, lvl <span class="level">1</span>)</p>
|
||||
<p class="description">{{description}}</p>
|
||||
<button class="buy">buy</button> <button class="upgrade">upgrade</button>
|
||||
</div>
|
||||
{{/inline}}
|
||||
{{> tool id="hand" name="hand" description="don't bite the hand that pets you"}}
|
||||
{{> tool id="puppy" name="puppy" description="arf arf wruff :3"}}
|
||||
{{> tool id="foodBowl" name="food bowl" description="more food for more barking"}}
|
||||
{{> tool id="kisser" name="kisser wow" description="someone to kiss all those poor puppies,,"}}
|
||||
</div>
|
||||
</div>
|
|
@ -10,9 +10,7 @@ use pulldown_cmark::{Options, Parser};
|
|||
use serde::Serialize;
|
||||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
extras::Extra, resource::ResourceBuilder, util, PageMetadata, Site, ROOT_PATH, SASS_PATH,
|
||||
};
|
||||
use crate::{resource::ResourceBuilder, util, PageMetadata, Site, ROOT_PATH, SASS_PATH};
|
||||
|
||||
/// Struct containing data to be sent to templates when rendering them.
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -283,8 +281,8 @@ impl<'a> SiteBuilder<'a> {
|
|||
// Modify HTML output
|
||||
let mut out = self.rewrite_html(out)?;
|
||||
|
||||
if let Some(Extra::HtmlModification(f)) = extra {
|
||||
out = f(out, self)?;
|
||||
if let Some(extra) = extra {
|
||||
out = extra.handle(out, self)?;
|
||||
}
|
||||
|
||||
if !self.serving {
|
||||
|
|
|
@ -5,17 +5,46 @@ use crate::{blog::BlogPostMetadata, builder::SiteBuilder, resource::ResourceTemp
|
|||
|
||||
#[derive(Debug)]
|
||||
pub enum Extra {
|
||||
Basic(&'static str),
|
||||
HtmlModification(fn(page: String, builder: &SiteBuilder) -> eyre::Result<String>),
|
||||
}
|
||||
|
||||
impl Extra {
|
||||
/// runs the handler for the extra
|
||||
pub fn handle(&self, page: String, builder: &SiteBuilder) -> eyre::Result<String> {
|
||||
match self {
|
||||
Self::Basic(template) => {
|
||||
println!("{template}");
|
||||
let content = builder.reg.render(template, &())?;
|
||||
append_to(&page, &content, "main.page")
|
||||
}
|
||||
Self::HtmlModification(f) => (f)(page, builder),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the extra for the given value.
|
||||
pub fn get_extra(extra: &str) -> Option<Extra> {
|
||||
match extra {
|
||||
"index" => Some(Extra::HtmlModification(index)),
|
||||
"click" => Some(Extra::Basic("extras/click")),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn append_to(page: &str, content: &str, selector: &str) -> eyre::Result<String> {
|
||||
Ok(lol_html::rewrite_str(
|
||||
page,
|
||||
RewriteStrSettings {
|
||||
element_content_handlers: vec![element!(selector, move |el| {
|
||||
el.append(content, lol_html::html_content::ContentType::Html);
|
||||
Ok(())
|
||||
})],
|
||||
..Default::default()
|
||||
},
|
||||
)?)
|
||||
}
|
||||
|
||||
/// Extra to add a sidebar to the index page with recent blog posts on it.
|
||||
fn index(page: String, builder: &SiteBuilder) -> eyre::Result<String> {
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -42,14 +71,5 @@ fn index(page: String, builder: &SiteBuilder) -> eyre::Result<String> {
|
|||
},
|
||||
)?;
|
||||
|
||||
Ok(lol_html::rewrite_str(
|
||||
&page,
|
||||
RewriteStrSettings {
|
||||
element_content_handlers: vec![element!("#content", move |el| {
|
||||
el.append(&sidebar, lol_html::html_content::ContentType::Html);
|
||||
Ok(())
|
||||
})],
|
||||
..Default::default()
|
||||
},
|
||||
)?)
|
||||
append_to(&page, &sidebar, "#content")
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue