Rename file
This commit is contained in:
402
html/images/space.svg
Normal file
402
html/images/space.svg
Normal file
@@ -0,0 +1,402 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg viewBox="-200 -150 400 300" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>
|
||||
#frames {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
p {
|
||||
border: 1px solid black;
|
||||
box-size: border-box;
|
||||
}
|
||||
|
||||
rect#bg {
|
||||
fill: gray;
|
||||
}
|
||||
|
||||
.tank rect {
|
||||
fill: green;
|
||||
transform: translate(-7.5px, -5px);
|
||||
}
|
||||
|
||||
.tank circle {
|
||||
fill: white;
|
||||
}
|
||||
|
||||
#crosshair {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
circle.bullet {
|
||||
fill: yellow;
|
||||
}
|
||||
</style>
|
||||
|
||||
<g>
|
||||
<rect id="bg" x="-200" y="-150" width="400" height="300"/>
|
||||
|
||||
<g class="hitbox">
|
||||
<g class="tank">
|
||||
<circle cx="0" cy="0" r="5"/>
|
||||
<line x1="0" y1="0" x2="0" y2="8" stroke="black"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<g id="bullets"></g>
|
||||
</g>
|
||||
|
||||
<foreignObject x="-200" y="-150" width="100%" height="100%">
|
||||
<div id="frames" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<span id="fps" xmlns="http://www.w3.org/1999/xhtml">0</span> fps
|
||||
</div>
|
||||
|
||||
<button id="turn-left" xmlns="http://www.w3.org/1999/xhtml">🡐</button>
|
||||
<button id="move-backward" xmlns="http://www.w3.org/1999/xhtml">🡑</button>
|
||||
<button id="move-forward" xmlns="http://www.w3.org/1999/xhtml">🡓</button>
|
||||
<button id="turn-right" xmlns="http://www.w3.org/1999/xhtml">🡒</button>
|
||||
<button id="rotate-ccw" xmlns="http://www.w3.org/1999/xhtml">⟲</button>
|
||||
<button id="rotate-cw" xmlns="http://www.w3.org/1999/xhtml">⟳</button>
|
||||
<button id="fire" xmlns="http://www.w3.org/1999/xhtml">Fire</button>
|
||||
</foreignObject>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
const namespaceURIsvg = 'http://www.w3.org/2000/svg';
|
||||
const degsRegex = /(-?\d*\.{0,1}\d+)deg/g;
|
||||
const regex = /(-?\d*\.{0,1}\d+)px/g;
|
||||
const def = ["0px", "0"];
|
||||
let bullets = [];
|
||||
|
||||
let position = [0, 0]; // meters
|
||||
let velocity = [0, 0]; // meters per second
|
||||
let acceleration = [0, 0]; // meters per second per second
|
||||
let previous, zero, frameCount = 0;
|
||||
// let friction = 7.5;
|
||||
let friction = 0;
|
||||
let rotate = 0;
|
||||
let rotationSpeed = 0.25;
|
||||
|
||||
const rules = document.styleSheets[0].cssRules;
|
||||
|
||||
const fps = document.querySelector("#fps");
|
||||
const tank = document.querySelector(".tank");
|
||||
const gun = tank.querySelector('line');
|
||||
const hitbox = document.querySelector(".hitbox");
|
||||
const bulletsContainer = document.querySelector("#bullets");
|
||||
|
||||
const leftTurnButton = document.querySelector("#turn-left");
|
||||
const rightTurnButton = document.querySelector("#turn-right");
|
||||
const reverseMoveButton = document.querySelector("#move-backward");
|
||||
const forwardMoveButton = document.querySelector("#move-forward");
|
||||
|
||||
const rotateCWButton = document.querySelector("#rotate-cw");
|
||||
const rotateCCWButton = document.querySelector("#rotate-ccw");
|
||||
|
||||
const fireButton = document.querySelector("#fire");
|
||||
|
||||
gun.style.transform = "rotate(0deg)";
|
||||
|
||||
function wrapPos(positionX, positionY) {
|
||||
let x, y;
|
||||
|
||||
if (positionY > 150) y = positionY - 300;
|
||||
else if (positionY < -150) y = positionY + 300;
|
||||
else y = positionY;
|
||||
|
||||
if (positionX > 200) x = positionX - 400;
|
||||
else if (positionX < -200) x = positionX + 400;
|
||||
else x = positionX;
|
||||
|
||||
return [x, y];
|
||||
}
|
||||
|
||||
function fireBullet(x, y) {
|
||||
const degrees = getRotate(gun);
|
||||
const radians = degrees * Math.PI / 180; // toFixed(15)?
|
||||
const vx = -Math.sin(radians);
|
||||
const vy = Math.cos(radians);
|
||||
const bulletTimeout = 5000; // miliseconds
|
||||
const cannonLength = 8;
|
||||
|
||||
const el = document.createElementNS(namespaceURIsvg, 'circle');
|
||||
el.classList.add('bullet');
|
||||
el.setAttribute('r', 1);
|
||||
el.setAttribute('cx', 0);
|
||||
el.setAttribute('cy', 0);
|
||||
|
||||
const bullet = {
|
||||
x: x + vx * cannonLength,
|
||||
y: y + vy * cannonLength,
|
||||
vx: vx,
|
||||
vy: vy,
|
||||
time: bulletTimeout,
|
||||
node: bulletsContainer.appendChild(el)
|
||||
}
|
||||
|
||||
bullets.push(bullet);
|
||||
}
|
||||
|
||||
function getTranslate(el) {
|
||||
let x, y;
|
||||
|
||||
if (el.style.transform.length === 0) {
|
||||
x = 0;
|
||||
y = 0;
|
||||
} else {
|
||||
[[, x], [, y] = def] = [...el.style.transform.matchAll(regex)];
|
||||
}
|
||||
|
||||
return [+x, +y];
|
||||
}
|
||||
|
||||
function getRotate(el) {
|
||||
let [[, degrees]] = [...el.style.transform.matchAll(degsRegex)];
|
||||
return +degrees;
|
||||
}
|
||||
|
||||
requestAnimationFrame(firstFrame);
|
||||
|
||||
function firstFrame(timestamp) {
|
||||
zero = timestamp;
|
||||
previous = timestamp;
|
||||
animate(timestamp);
|
||||
}
|
||||
|
||||
function animate(timestamp) {
|
||||
const delta = timestamp - zero;
|
||||
const elapsed = timestamp - previous;
|
||||
previous = timestamp;
|
||||
|
||||
if (delta >= 1000) {
|
||||
fps.innerText = frameCount;
|
||||
zero = timestamp;
|
||||
frameCount = 0;
|
||||
} else {
|
||||
frameCount++;
|
||||
}
|
||||
|
||||
let [[, degrees]] = [...gun.style.transform.matchAll(degsRegex)];
|
||||
|
||||
if (rotate > 0) gun.style.transform = `rotate(${(+degrees + rotationSpeed * elapsed) % 360}deg)`;
|
||||
else if (rotate < 0) gun.style.transform = `rotate(${(+degrees - rotationSpeed * elapsed) % 360}deg)`;
|
||||
|
||||
let [velocityX, velocityY] = velocity;
|
||||
let [accelerationX, accelerationY] = acceleration;
|
||||
|
||||
if (velocityX > 0) accelerationX += -friction;
|
||||
else if (velocityX < 0) accelerationX += friction;
|
||||
|
||||
if (velocityY > 0) accelerationY += -friction;
|
||||
else if (velocityY < 0) accelerationY += friction;
|
||||
|
||||
velocityX = velocityX > 0 && velocityX + accelerationX < 0 ? 0 : velocityX + accelerationX;
|
||||
velocityY = velocityY > 0 && velocityY + accelerationY < 0 ? 0 : velocityY + accelerationY;
|
||||
velocity = [velocityX, velocityY];
|
||||
|
||||
const changeX = 0.001 * elapsed * velocityX;
|
||||
const changeY = 0.001 * elapsed * velocityY;
|
||||
|
||||
bullets.forEach((bullet, index) => {
|
||||
const deleteCount = 1;
|
||||
bullets[index].time -= elapsed;
|
||||
|
||||
if (bullets[index].time > 0) {
|
||||
bullets[index].y += 0.1 * elapsed * bullets[index].vy;
|
||||
bullets[index].x += 0.1 * elapsed * bullets[index].vx;
|
||||
|
||||
let [bx, by] = wrapPos(bullets[index].x, bullets[index].y)
|
||||
bullets[index].x = bx;
|
||||
bullets[index].y = by;
|
||||
bullet.node.style.transform = `translate(${bx}px, ${by}px)`;
|
||||
} else {
|
||||
bullet.node.remove();
|
||||
bullets.splice(index, deleteCount);
|
||||
}
|
||||
});
|
||||
|
||||
let [x, y] = getTranslate(hitbox);
|
||||
let positionX = changeX + +x;
|
||||
let positionY = changeY + +y;
|
||||
|
||||
if (positionY > 150) positionY += -300;
|
||||
else if (positionY < -150) positionY += 300;
|
||||
|
||||
if (positionX > 200) positionX += -400;
|
||||
else if (positionX < -200) positionX += 400;
|
||||
|
||||
hitbox.style.transform = `translate(${positionX}px, ${positionY}px)`;
|
||||
|
||||
// if (+y < 200)
|
||||
// if (timestamp < 10000)
|
||||
requestAnimationFrame(t => animate(t));
|
||||
}
|
||||
|
||||
let force = 1;
|
||||
|
||||
let spacePressed = false;
|
||||
let upPressed = false;
|
||||
let downPressed = false;
|
||||
let leftPressed = false;
|
||||
let rightPressed = false;
|
||||
let rotateCWPressed = false;
|
||||
let rotateCCWPressed = false;
|
||||
|
||||
document.addEventListener("keydown", function(e) {
|
||||
switch (e.code) {
|
||||
case "Space":
|
||||
if (!spacePressed) {
|
||||
spacePressed = true;
|
||||
const [x, y] = getTranslate(hitbox);
|
||||
fireBullet(x, y);
|
||||
}
|
||||
break;
|
||||
case "KeyW":
|
||||
case "ArrowUp":
|
||||
if (!upPressed) {
|
||||
upPressed = true;
|
||||
acceleration[1] += -force;
|
||||
}
|
||||
break;
|
||||
case "KeyS":
|
||||
case "ArrowDown":
|
||||
if (!downPressed) {
|
||||
downPressed = true;
|
||||
acceleration[1] += force;
|
||||
}
|
||||
break;
|
||||
case "KeyA":
|
||||
case "ArrowLeft":
|
||||
if (!leftPressed) {
|
||||
leftPressed = true;
|
||||
acceleration[0] += -force;
|
||||
}
|
||||
break;
|
||||
case "KeyD":
|
||||
case "ArrowRight":
|
||||
if (!rightPressed) {
|
||||
rightPressed = true;
|
||||
acceleration[0] += force;
|
||||
}
|
||||
break;
|
||||
case "KeyQ":
|
||||
case "Comma":
|
||||
if (!rotateCCWPressed) {
|
||||
rotateCCWPressed = true;
|
||||
rotate += -1;
|
||||
}
|
||||
break;
|
||||
case "KeyE":
|
||||
case "Period":
|
||||
if (!rotateCWPressed) {
|
||||
rotateCWPressed = true;
|
||||
rotate += 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener("keyup", function(e) {
|
||||
switch (e.code) {
|
||||
case "Space":
|
||||
spacePressed = false;
|
||||
break;
|
||||
case "KeyW":
|
||||
case "ArrowUp":
|
||||
if (upPressed) {
|
||||
upPressed = false;
|
||||
acceleration[1] -= -force;
|
||||
}
|
||||
break;
|
||||
case "KeyS":
|
||||
case "ArrowDown":
|
||||
if (downPressed) {
|
||||
downPressed = false;
|
||||
acceleration[1] -= force;
|
||||
}
|
||||
break;
|
||||
case "KeyA":
|
||||
case "ArrowLeft":
|
||||
if (leftPressed) {
|
||||
leftPressed = false;
|
||||
acceleration[0] -= -force;
|
||||
}
|
||||
break;
|
||||
case "KeyD":
|
||||
case "ArrowRight":
|
||||
if (rightPressed) {
|
||||
rightPressed = false;
|
||||
acceleration[0] -= force;
|
||||
}
|
||||
break;
|
||||
case "KeyQ":
|
||||
case "Comma":
|
||||
if (rotateCCWPressed) {
|
||||
rotateCCWPressed = false;
|
||||
rotate -= -1;
|
||||
}
|
||||
break;
|
||||
case "KeyE":
|
||||
case "Period":
|
||||
if (rotateCWPressed) {
|
||||
rotateCWPressed = false;
|
||||
rotate -= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
leftTurnButton.addEventListener("mousedown", function (e) {
|
||||
acceleration[0] = -force;
|
||||
});
|
||||
|
||||
leftTurnButton.addEventListener("mouseup", function (e) {
|
||||
acceleration[0] = 0;
|
||||
});
|
||||
|
||||
rightTurnButton.addEventListener("mousedown", function (e) {
|
||||
acceleration[0] = force;
|
||||
});
|
||||
|
||||
rightTurnButton.addEventListener("mouseup", function (e) {
|
||||
acceleration[0] = 0;
|
||||
});
|
||||
|
||||
reverseMoveButton.addEventListener("mousedown", function (e) {
|
||||
acceleration[1] = -force;
|
||||
});
|
||||
|
||||
reverseMoveButton.addEventListener("mouseup", function (e) {
|
||||
acceleration[1] = 0;
|
||||
});
|
||||
|
||||
forwardMoveButton.addEventListener("mousedown", function (e) {
|
||||
acceleration[1] = force;
|
||||
});
|
||||
|
||||
forwardMoveButton.addEventListener("mouseup", function (e) {
|
||||
acceleration[1] = 0;
|
||||
});
|
||||
|
||||
rotateCWButton.addEventListener("mousedown", function (e) {
|
||||
rotate = 1;
|
||||
});
|
||||
|
||||
rotateCWButton.addEventListener("mouseup", function (e) {
|
||||
rotate = 0;
|
||||
});
|
||||
|
||||
rotateCCWButton.addEventListener("mousedown", function (e) {
|
||||
rotate = -1;
|
||||
});
|
||||
|
||||
rotateCCWButton.addEventListener("mouseup", function (e) {
|
||||
rotate = 0;
|
||||
});
|
||||
|
||||
fireButton.addEventListener("click", function (e) {
|
||||
const [x, y] = getTranslate(hitbox);
|
||||
fireBullet(x, y);
|
||||
});
|
||||
//]]></script>
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 11 KiB |
Reference in New Issue
Block a user