Upload files to "/"

This commit is contained in:
2026-06-30 22:11:27 +00:00
parent 198d9cf477
commit 1c9a3c06fe

174
index.html Normal file
View File

@@ -0,0 +1,174 @@
<!doctype html>
<html lang="pl">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Symulacja minigierki z rzucaniem zaklęć z Reksio i Czarodzieje</title>
<style>
body { margin: 0; display:flex; height:100vh; align-items:center; justify-content:center; background:#f0f0f0; }
canvas { background: #ffffff; border:1px solid #ccc; }
#coords { position:fixed; left:10px; top:10px; background:rgba(0,0,0,0.6); color:#fff; padding:6px 8px; border-radius:4px; font-family:monospace; }
</style>
</head>
<body>
<div id="coords">x: -, y: - | down: false</div>
<canvas id="canvas" width="800" height="600"></canvas>
<script>
const canvas = document.getElementById('canvas');
const rect = canvas.getBoundingClientRect();
const coordsEl = document.getElementById('coords');
const ctx = canvas.getContext('2d');
const spellDirections = {
'Sen': [270,45,315,90],
'Zamiana w żabę': [90,0,270,180,45,135],
'Plaga much': [90,225,0,225],
'Kula budyniu': [180,90,0,90,180],
'Koła i wiry': [270,45,270,135,0],
'Ciemność': [0,225,315,180],
'Obrona przed Snem': [0,90,180,270,0],
'Obrona przed Zamianą w żabę': [280,0,90,0,270,135], // nope, that 280 is not a typo, that was in the original code
'Obrona przed Plagą much': [225,135,45,315,180],
'Obrona przed Kulą budyniu': [270,180,90,180,270],
'Obrona przed Kołami i wirami': [45,180,315,180],
'Obrona przed Ciemnością': [180,45,135,0]
};
const ANGLE_TOLERANCE = 35.5; // used in shape comparison, not in point probing
const POINT_DISTANCE_THRESHOLD = 30;
let lastPoint = null;
let drawnAngles = [];
clearCanvas();
let isDown = false;
function updateDisplay(x, y) {
coordsEl.textContent = `x: ${x}, y: ${y} | down: ${isDown}`;
}
function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
function getPos(evt) {
const r = canvas.getBoundingClientRect();
return {
x: Math.round(evt.clientX - r.left),
y: Math.round(evt.clientY - r.top)
};
}
function compareAngle(a, b) {
return (a - b + 540.0) % 360.0 - 180.0;
}
function angleNear(angle, target, margin) {
return Math.abs(compareAngle(angle, target)) <= margin;
}
function probePoint(p) {
// probing by >= 30 pixels
if (lastPoint) {
const dx = p.x - lastPoint.x;
const dy = p.y - lastPoint.y;
const distance = Math.hypot(dx, dy);
if (distance >= POINT_DISTANCE_THRESHOLD) {
const angle = Math.atan2(dy, dx) * 180 / Math.PI;
// normalize angle to [0, 360) (ATAN2 in Piklib was normalized)
const normalizedAngle = (angle + 360) % 360;
// calculate the difference between the last angle and the current angle
if (drawnAngles.length > 0) {
const lastAngle = drawnAngles[drawnAngles.length - 1];
const angleDifference = Math.abs(compareAngle(normalizedAngle, lastAngle));
if (angleDifference > 45) {
drawnAngles.push(normalizedAngle);
}
} else {
// technically game scripts force the first angle to have difference of 46 degrees, so it pushes the first angle regardless of the tolerance
drawnAngles.push(normalizedAngle);
}
// draw a line from lastPoint to current point
ctx.beginPath();
ctx.moveTo(lastPoint.x, lastPoint.y);
ctx.lineTo(p.x, p.y);
ctx.strokeStyle = '#ff0000';
ctx.lineWidth = 2;
ctx.stroke();
// override last point
lastPoint = p;
}
}
}
canvas.addEventListener('mousedown', (e) => {
// left button is a 0
if (e.button === 0) {
isDown = true;
const p = getPos(e);
lastPoint = p;
drawnAngles = [];
clearCanvas();
updateDisplay(p.x, p.y);
}
});
window.addEventListener('mouseup', (e) => {
if (e.button === 0) {
isDown = false;
const p = getPos(e);
probePoint(p);
console.log('Drawn angles:', drawnAngles);
// break a spell and compare with the known spell directions
const spellName = Object.keys(spellDirections).find(name => {
const directions = spellDirections[name];
// when lengths of array are different, it cancels the comparison
if (directions.length !== drawnAngles.length) {
console.log(`Spell "${name}" rejected due to length mismatch: expected ${directions.length}, got ${drawnAngles.length}`);
return false;
}
// compare each angle with the corresponding drawn angle with angle tolerance
for (let i = 0; i < directions.length; i++) {
const expectedAngle = directions[i];
const drawnAngle = drawnAngles[i];
if (!angleNear(drawnAngle, expectedAngle, ANGLE_TOLERANCE)) {
console.log(`Spell "${name}" rejected due to angle mismatch at index ${i}: expected ${expectedAngle}, got ${drawnAngle}`);
return false;
}
}
return true;
});
console.log(spellName);
if (spellName) {
console.log(`Spell cast: ${spellName}`);
}
updateDisplay(p.x, p.y);
}
});
canvas.addEventListener('mousemove', (e) => {
const p = getPos(e);
updateDisplay(p.x, p.y);
if (isDown) {
probePoint(p);
}
});
// zapobiegaj zaznaczaniu tekstu/dragowaniu
canvas.addEventListener('dragstart', e => e.preventDefault());
</script>
</body>
</html>