Add rotating gun
This commit is contained in:
@@ -52,9 +52,9 @@
|
|||||||
<rect id="bg" x="-200" y="-150" width="400" height="300"/>
|
<rect id="bg" x="-200" y="-150" width="400" height="300"/>
|
||||||
<g class="hitbox">
|
<g class="hitbox">
|
||||||
<g class="tank">
|
<g class="tank">
|
||||||
<!-- <line x1="0" y1="0" x2="0" y2="10" stroke="black"/> -->
|
|
||||||
<!-- <rect width="15" height="10"/> -->
|
<!-- <rect width="15" height="10"/> -->
|
||||||
<circle cx="0" cy="0" r="5"/>
|
<circle cx="0" cy="0" r="5"/>
|
||||||
|
<line x1="0" y1="0" x2="0" y2="8" stroke="black"/>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<!-- <g id="crosshair"> -->
|
<!-- <g id="crosshair"> -->
|
||||||
@@ -72,21 +72,31 @@
|
|||||||
<button id="move-backward" xmlns="http://www.w3.org/1999/xhtml">Up</button>
|
<button id="move-backward" xmlns="http://www.w3.org/1999/xhtml">Up</button>
|
||||||
<button id="move-forward" xmlns="http://www.w3.org/1999/xhtml">Down</button>
|
<button id="move-forward" xmlns="http://www.w3.org/1999/xhtml">Down</button>
|
||||||
<button id="turn-right" xmlns="http://www.w3.org/1999/xhtml">Right</button>
|
<button id="turn-right" xmlns="http://www.w3.org/1999/xhtml">Right</button>
|
||||||
|
<button id="rotate-ccw" xmlns="http://www.w3.org/1999/xhtml">Rotate CCW</button>
|
||||||
|
<button id="rotate-cw" xmlns="http://www.w3.org/1999/xhtml">Rotate CW</button>
|
||||||
</foreignObject>
|
</foreignObject>
|
||||||
|
|
||||||
<script type="text/javascript">//<![CDATA[
|
<script type="text/javascript">//<![CDATA[
|
||||||
const rules = document.styleSheets[0].cssRules;
|
const rules = document.styleSheets[0].cssRules;
|
||||||
const tank = document.querySelector(".tank");
|
const tank = document.querySelector(".tank");
|
||||||
|
const gun = tank.querySelector('line');
|
||||||
const hitbox = document.querySelector(".hitbox");
|
const hitbox = document.querySelector(".hitbox");
|
||||||
const leftTurnButton = document.querySelector("#turn-left");
|
const leftTurnButton = document.querySelector("#turn-left");
|
||||||
const rightTurnButton = document.querySelector("#turn-right");
|
const rightTurnButton = document.querySelector("#turn-right");
|
||||||
const reverseMoveButton = document.querySelector("#move-backward");
|
const reverseMoveButton = document.querySelector("#move-backward");
|
||||||
const forwardMoveButton = document.querySelector("#move-forward");
|
const forwardMoveButton = document.querySelector("#move-forward");
|
||||||
|
|
||||||
|
const rotateCWButton = document.querySelector("#rotate-cw");
|
||||||
|
const rotateCCWButton = document.querySelector("#rotate-ccw");
|
||||||
|
|
||||||
const fps = document.querySelector("#fps");
|
const fps = document.querySelector("#fps");
|
||||||
let velocity = [0, 0]; // meters per second
|
let velocity = [0, 0]; // meters per second
|
||||||
let acceleration = [0, 0]; // meters per second per second
|
let acceleration = [0, 0]; // meters per second per second
|
||||||
let previous, zero, frameCount = 0;
|
let previous, zero, frameCount = 0;
|
||||||
let friction = 7.5;
|
let friction = 7.5;
|
||||||
|
let rotate = 0;
|
||||||
|
let rotationSpeed = 0.25;
|
||||||
|
gun.style.transform = "rotate(0deg)";
|
||||||
|
|
||||||
requestAnimationFrame(firstFrame);
|
requestAnimationFrame(firstFrame);
|
||||||
|
|
||||||
@@ -109,6 +119,13 @@
|
|||||||
frameCount++;
|
frameCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const degsRegex = /(-?\d*\.{0,1}\d+)deg/g;
|
||||||
|
|
||||||
|
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 [velocityX, velocityY] = velocity;
|
||||||
let [accelerationX, accelerationY] = acceleration;
|
let [accelerationX, accelerationY] = acceleration;
|
||||||
|
|
||||||
@@ -155,226 +172,58 @@
|
|||||||
// if (velocity[1] < 0)
|
// if (velocity[1] < 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveTank(el) {
|
|
||||||
const tankMove = el.animate(
|
|
||||||
[
|
|
||||||
{ transform: `translate(0, -10px)`},
|
|
||||||
{ transform: `translate(0, 10px)`}
|
|
||||||
], {
|
|
||||||
duration: 1000,
|
|
||||||
fill: 'both'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
tankMove.pause();
|
|
||||||
tankMove.currentTime = tankMove.effect.getComputedTiming().activeDuration / 2;
|
|
||||||
|
|
||||||
return tankMove;
|
|
||||||
}
|
|
||||||
|
|
||||||
function turnTank(el) {
|
|
||||||
const tankTurn = el.animate(
|
|
||||||
[
|
|
||||||
{ transform: 'rotate(180deg)' },
|
|
||||||
{ transform: 'rotate(-180deg)' }
|
|
||||||
], {
|
|
||||||
duration: 2000,
|
|
||||||
easint: 'ease-in-out',
|
|
||||||
fill: 'both'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
tankTurn.pause();
|
|
||||||
tankTurn.currentTime = tankTurn.effect.getComputedTiming().activeDuration / 2;
|
|
||||||
|
|
||||||
return tankTurn;
|
|
||||||
}
|
|
||||||
|
|
||||||
// const tankTurn = turnTank(tank);
|
|
||||||
// const tankMove = moveTank(hitbox);
|
|
||||||
|
|
||||||
function degsToRads(degrees) {
|
|
||||||
return degrees * Math.PI / 180;
|
|
||||||
}
|
|
||||||
|
|
||||||
function afterTurn() {
|
|
||||||
const totalDegrees = 180;
|
|
||||||
const current = tankTurn.currentTime;
|
|
||||||
const duration = tankTurn.effect.getComputedTiming().activeDuration / 2;
|
|
||||||
const diff = current - duration;
|
|
||||||
const degrees = diff / duration * totalDegrees;
|
|
||||||
const radians = degsToRads(degrees);
|
|
||||||
// https://stackoverflow.com/a/3644302
|
|
||||||
const y = 10 * +Math.cos(radians).toFixed(15);
|
|
||||||
const x = 10 * +Math.sin(radians).toFixed(15);
|
|
||||||
|
|
||||||
console.log("diff", diff, "current", current, "duration", duration, diff / duration * Math.PI);
|
|
||||||
|
|
||||||
console.log("degrees", degrees, "radians", radians, "x", x == 0, "y", y);
|
|
||||||
|
|
||||||
const regex = /(-?\d*\.{0,1}\d+)px/g;
|
|
||||||
const [past, future] = tankMove.effect.getKeyframes()
|
|
||||||
|
|
||||||
const def = ["0px", "0"];
|
|
||||||
const [[, px], [, py] = def] = [...past.transform.matchAll(regex)];
|
|
||||||
const [[, fx], [, fy] = def] = [...future.transform.matchAll(regex)];
|
|
||||||
|
|
||||||
const position = { x: (+fx + +px) / 2, y: (+fy + +py) / 2 };
|
|
||||||
|
|
||||||
tankMove.effect.setKeyframes(
|
|
||||||
[
|
|
||||||
{ transform: `translate(${-x + position.x}px, ${-y + position.y}px)`},
|
|
||||||
{ transform: `translate(${x + position.x}px, ${y + position.y}px)`}
|
|
||||||
], {
|
|
||||||
duration: 5000,
|
|
||||||
fill: 'both'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const [pkf, fkf] = tankMove.effect.getKeyframes();
|
|
||||||
console.log(pkf.transform, fkf.transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
function afterMove() {
|
|
||||||
const totalDistance = 10;
|
|
||||||
const current = tankMove.currentTime;
|
|
||||||
const duration = tankMove.effect.getComputedTiming().activeDuration / 2;
|
|
||||||
const regex = /(-?\d*\.{0,1}\d+)px/g;
|
|
||||||
const [past, future] = tankMove.effect.getKeyframes()
|
|
||||||
|
|
||||||
const totalDegrees = 180;
|
|
||||||
const turnCurrent = tankTurn.currentTime;
|
|
||||||
const turnDuration = tankTurn.effect.getComputedTiming().activeDuration / 2;
|
|
||||||
// const diff = turnDuration - turnCurrent;
|
|
||||||
const diff = turnCurrent - turnDuration;
|
|
||||||
const degrees = diff / turnDuration * totalDegrees;
|
|
||||||
const radians = degsToRads(degrees);
|
|
||||||
|
|
||||||
const def = ["0px", "0"];
|
|
||||||
const [[, px], [, py] = def] = [...past.transform.matchAll(regex)];
|
|
||||||
const [[, fx], [, fy] = def] = [...future.transform.matchAll(regex)];
|
|
||||||
|
|
||||||
const timeSpan = Math.abs(duration - current);
|
|
||||||
// const timeSpan = duration - current;
|
|
||||||
const distanceTraveled = timeSpan / duration * totalDistance;
|
|
||||||
let y = distanceTraveled * +Math.cos(radians).toFixed(15) * tankMove.playbackRate;
|
|
||||||
let x = distanceTraveled * +Math.sin(radians).toFixed(15) * tankMove.playbackRate;
|
|
||||||
|
|
||||||
// console.log("distanceTraveled", distanceTraveled);
|
|
||||||
|
|
||||||
if (degrees > 0 && degrees < 90) {
|
|
||||||
// quadrant 1
|
|
||||||
console.log("quadrant 1");
|
|
||||||
x = -x;
|
|
||||||
y = -y;
|
|
||||||
} else if (degrees > 90 && degrees < 180) {
|
|
||||||
// quadrant 2
|
|
||||||
console.log("quadrant 2");
|
|
||||||
x = -x;
|
|
||||||
y = -y;
|
|
||||||
} else if (degrees < -90 && degrees > -180) {
|
|
||||||
// quadrant 3
|
|
||||||
console.log("quadrant 3");
|
|
||||||
x = -x;
|
|
||||||
y = -y;
|
|
||||||
} else if (degrees < 0 && degrees > -90) {
|
|
||||||
// quadrant 4
|
|
||||||
console.log("quadrant 4");
|
|
||||||
x = -x;
|
|
||||||
y = -y;
|
|
||||||
} else if (degrees === 0) {
|
|
||||||
x = +x;
|
|
||||||
y = -y;
|
|
||||||
} else if (degrees === 90) {
|
|
||||||
x = +x;
|
|
||||||
y = +y;
|
|
||||||
} else if (degrees === -90) {
|
|
||||||
x = -x;
|
|
||||||
y = +y;
|
|
||||||
} else {
|
|
||||||
x = +x;
|
|
||||||
y = -y;
|
|
||||||
}
|
|
||||||
|
|
||||||
const position = { x: (+fx + +px) / 2, y: (+fy + +py) / 2};
|
|
||||||
const [turnPast, turnFuture] = tankTurn.effect.getKeyframes()
|
|
||||||
|
|
||||||
// console.log("playbackRate", tankMove.playbackRate);
|
|
||||||
// console.log("before", past.transform, future.transform);
|
|
||||||
// console.log("position", position, "degrees", degrees, "x", x, "y", y);
|
|
||||||
|
|
||||||
// can get transformation matrix
|
|
||||||
// getComputedStyle(hitbox).transform
|
|
||||||
|
|
||||||
tankMove.effect.setKeyframes(
|
|
||||||
[
|
|
||||||
{ transform: `translate(${-x + +px}px, ${-y + +py}px)`},
|
|
||||||
{ transform: `translate(${-x + +fx}px, ${-y + +fy}px)`}
|
|
||||||
], {
|
|
||||||
duration: 5000,
|
|
||||||
fill: 'both'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
tankMove.currentTime = duration;
|
|
||||||
|
|
||||||
const [pkf, fkf] = tankMove.effect.getKeyframes()
|
|
||||||
// console.log("after", pkf.transform, fkf.transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
let force = 10;
|
let force = 10;
|
||||||
|
|
||||||
leftTurnButton.addEventListener("mousedown", function (e) {
|
leftTurnButton.addEventListener("mousedown", function (e) {
|
||||||
acceleration[0] = -force;
|
acceleration[0] = -force;
|
||||||
// tankTurn.playbackRate = 1;
|
|
||||||
// tankTurn.play();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
leftTurnButton.addEventListener("mouseup", function (e) {
|
leftTurnButton.addEventListener("mouseup", function (e) {
|
||||||
acceleration[0] = 0;
|
acceleration[0] = 0;
|
||||||
|
|
||||||
// tankTurn.pause();
|
|
||||||
// afterTurn();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
rightTurnButton.addEventListener("mousedown", function (e) {
|
rightTurnButton.addEventListener("mousedown", function (e) {
|
||||||
acceleration[0] = force;
|
acceleration[0] = force;
|
||||||
|
|
||||||
// tankTurn.playbackRate = -1;
|
|
||||||
// tankTurn.play();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
rightTurnButton.addEventListener("mouseup", function (e) {
|
rightTurnButton.addEventListener("mouseup", function (e) {
|
||||||
acceleration[0] = 0;
|
acceleration[0] = 0;
|
||||||
|
|
||||||
// tankTurn.pause();
|
|
||||||
// afterTurn();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
reverseMoveButton.addEventListener("mousedown", function (e) {
|
reverseMoveButton.addEventListener("mousedown", function (e) {
|
||||||
acceleration[1] = -force; // meters per second per second
|
acceleration[1] = -force;
|
||||||
|
|
||||||
// tankMove.playbackRate = -1;
|
|
||||||
// tankMove.play();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
reverseMoveButton.addEventListener("mouseup", function (e) {
|
reverseMoveButton.addEventListener("mouseup", function (e) {
|
||||||
acceleration[1] = 0; // meters per second per second
|
acceleration[1] = 0;
|
||||||
|
|
||||||
// tankMove.pause();
|
|
||||||
// afterMove();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
forwardMoveButton.addEventListener("mousedown", function (e) {
|
forwardMoveButton.addEventListener("mousedown", function (e) {
|
||||||
// tankMove.playbackRate = 1;
|
acceleration[1] = force;
|
||||||
// tankMove.play();
|
|
||||||
acceleration[1] = force; // meters per second per second
|
|
||||||
});
|
});
|
||||||
|
|
||||||
forwardMoveButton.addEventListener("mouseup", function (e) {
|
forwardMoveButton.addEventListener("mouseup", function (e) {
|
||||||
// tankMove.pause();
|
acceleration[1] = 0;
|
||||||
// afterMove();
|
|
||||||
acceleration[1] = 0; // meters per second per second
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// tankTurn.addEventListener("finish", function (e) {
|
// tankTurn.addEventListener("finish", function (e) {
|
||||||
// const duration = tankTurn.effect.getComputedTiming().activeDuration;
|
// const duration = tankTurn.effect.getComputedTiming().activeDuration;
|
||||||
// tankTurn.currentTime = tankTurn.currentTime > 0 ? 0 : duration;
|
// tankTurn.currentTime = tankTurn.currentTime > 0 ? 0 : duration;
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 6.8 KiB |
Reference in New Issue
Block a user