@@ 19,6 19,7 @@ import {
} from "./protocol/message_c2s";
import {encode} from "./serde";
import {InputType} from "./protocol/input";
+import {createParticle, tickAndDrawParticles} from "./particle";
logSetup();
const logger = new Logger("client");
@@ 290,7 291,14 @@ async function client_main(server: string, username: string, texture_quality: st
global.client?.socket.send(encode(MessageC2SInput_packetInfo.type, msg));
}
- let render = () => {
+ let t = performance.now();
+ let delta = 0.0;
+
+ let render = (newT: DOMHighResTimeStamp) => {
+
+ delta = newT - t;
+ t = newT;
+
let viewer_size_x = global.canvas.width;
let viewer_size_y = global.canvas.height;
@@ 494,6 502,206 @@ async function client_main(server: string, username: string, texture_quality: st
}
}
+ function calculateRotated(x: number, y: number, rotation: number): [number, number] {
+ let x2 = x * Math.cos(rotation) - y * Math.sin(rotation);
+ let y2 = x * Math.sin(rotation) + y * Math.cos(rotation);
+ return [x2, y2];
+ }
+
+ const thruster_r = 52;
+ const thruster_g = 189;
+ const thruster_b = 235;
+
+ let thruster_counter = 0;
+
+ if (global.me !== null) {
+ console.log(thruster_counter);
+ thruster_counter += 1;
+ if (thruster_counter > 200) {
+ console.log("resetting counter");
+ thruster_counter = 0;
+ } else if (thruster_counter == 1) {
+ console.log("drawing particle");
+ if (global.keys.up) {
+ // two backward thrusters
+ // this one is blue
+ createParticle({
+ x: global.me.x + calculateRotated(-25, 25, global.me.rotation)[0],
+ y: global.me.y + calculateRotated(-25, 25, global.me.rotation)[1],
+ lifetime: 500,
+ timer: 0,
+ startSize: 10,
+ finalSize: 50,
+ startRotation: 0,
+ finalRotation: 180,
+ startOpacity: 40,
+ endOpacity: 0,
+ startR: thruster_r,
+ startG: thruster_g,
+ startB: thruster_b,
+ endR: thruster_r,
+ endG: thruster_g,
+ endB: thruster_b
+ });
+
+ // two backward thrusters
+ // this one is pink
+ createParticle({
+ x: global.me.x + calculateRotated(25, -25, global.me.rotation + Math.PI/2)[0],
+ y: global.me.y + calculateRotated(25, -25, global.me.rotation + Math.PI/2)[1],
+ lifetime: 500,
+ timer: 0,
+ startSize: 10,
+ finalSize: 50,
+ startRotation: 0,
+ finalRotation: 180,
+ startOpacity: 40,
+ endOpacity: 0,
+ startR: thruster_r,
+ startG: thruster_g,
+ startB: thruster_b,
+ endR: thruster_r,
+ endG: thruster_g,
+ endB: thruster_b
+ });
+ }
+
+ if (global.keys.down) {
+ // two backward thrusters
+ // this one is blue
+ createParticle({
+ x: global.me.x + calculateRotated(25, -25, global.me.rotation)[0],
+ y: global.me.y + calculateRotated(25, -25, global.me.rotation)[1],
+ lifetime: 500,
+ timer: 0,
+ startSize: 10,
+ finalSize: 50,
+ startRotation: 0,
+ finalRotation: 180,
+ startOpacity: 40,
+ endOpacity: 0,
+ startR: thruster_r,
+ startG: thruster_g,
+ startB: thruster_b,
+ endR: thruster_r,
+ endG: thruster_g,
+ endB: thruster_b
+ });
+
+ // two backward thrusters
+ // this one is pink
+ createParticle({
+ x: global.me.x + calculateRotated(-25, 25, global.me.rotation + Math.PI/2)[0],
+ y: global.me.y + calculateRotated(-25, 25, global.me.rotation + Math.PI/2)[1],
+ lifetime: 500,
+ timer: 0,
+ startSize: 10,
+ finalSize: 50,
+ startRotation: 0,
+ finalRotation: 180,
+ startOpacity: 40,
+ endOpacity: 0,
+ startR: thruster_r,
+ startG: thruster_g,
+ startB: thruster_b,
+ endR: thruster_r,
+ endG: thruster_g,
+ endB: thruster_b
+ });
+ }
+
+ if (global.keys.left) {
+ // two backward thrusters
+ // this one is blue
+ createParticle({
+ x: global.me.x + calculateRotated(25, 25, global.me.rotation)[0],
+ y: global.me.y + calculateRotated(25, 25, global.me.rotation)[1],
+ lifetime: 500,
+ timer: 0,
+ startSize: 10,
+ finalSize: 50,
+ startRotation: 0,
+ finalRotation: 180,
+ startOpacity: 40,
+ endOpacity: 0,
+ startR: thruster_r,
+ startG: thruster_g,
+ startB: thruster_b,
+ endR: thruster_r,
+ endG: thruster_g,
+ endB: thruster_b
+ });
+
+ // two backward thrusters
+ // this one is pink
+ createParticle({
+ x: global.me.x + calculateRotated(-25, 25, global.me.rotation + Math.PI/2)[0],
+ y: global.me.y + calculateRotated(-25, 25, global.me.rotation + Math.PI/2)[1],
+ lifetime: 500,
+ timer: 0,
+ startSize: 10,
+ finalSize: 50,
+ startRotation: 0,
+ finalRotation: 180,
+ startOpacity: 40,
+ endOpacity: 0,
+ startR: thruster_r,
+ startG: thruster_g,
+ startB: thruster_b,
+ endR: thruster_r,
+ endG: thruster_g,
+ endB: thruster_b
+ });
+ }
+
+ if (global.keys.right) {
+ // two backward thrusters
+ // this one is blue
+ createParticle({
+ x: global.me.x + calculateRotated(-25, 25, global.me.rotation)[0],
+ y: global.me.y + calculateRotated(-25, 25, global.me.rotation)[1],
+ lifetime: 500,
+ timer: 0,
+ startSize: 10,
+ finalSize: 50,
+ startRotation: 0,
+ finalRotation: 180,
+ startOpacity: 40,
+ endOpacity: 0,
+ startR: thruster_r,
+ startG: thruster_g,
+ startB: thruster_b,
+ endR: thruster_r,
+ endG: thruster_g,
+ endB: thruster_b
+ });
+
+ // two backward thrusters
+ // this one is pink
+ createParticle({
+ x: global.me.x + calculateRotated(-25, -25, global.me.rotation + Math.PI/2)[0],
+ y: global.me.y + calculateRotated(-25, -25, global.me.rotation + Math.PI/2)[1],
+ lifetime: 500,
+ timer: 0,
+ startSize: 10,
+ finalSize: 50,
+ startRotation: 0,
+ finalRotation: 180,
+ startOpacity: 40,
+ endOpacity: 0,
+ startR: thruster_r,
+ startG: thruster_g,
+ startB: thruster_b,
+ endR: thruster_r,
+ endG: thruster_g,
+ endB: thruster_b
+ });
+ }
+ }
+
+ tickAndDrawParticles(delta);
+ }
+
requestAnimationFrame(render);
}
requestAnimationFrame(render);
@@ 0,0 1,76 @@
+import {global} from "./index";
+
+export interface Particle {
+ x: number,
+ y: number,
+ lifetime: number,
+ timer: number,
+ startSize: number,
+ finalSize: number,
+ startRotation: number,
+ finalRotation: number,
+ startOpacity: number,
+ endOpacity: number,
+ startR: number,
+ endR: number,
+ startG: number,
+ endG: number,
+ startB: number,
+ endB: number
+}
+
+let particles: Particle[] = [];
+
+export function createParticle(particle: Particle) {
+ particles.push(particle);
+}
+
+function lerp(start: number, end: number, time: number): number {
+ return start + time * (end - start);
+}
+
+export function drawParticle(particle: Particle) {
+ let t = particle.timer / particle.lifetime;
+ let size = lerp(particle.startSize, particle.finalSize, t);
+ let rotation = lerp(particle.startRotation, particle.finalRotation, t);
+
+ global.context.save();
+
+ global.context.translate(particle.x - global.me!.x, particle.y - global.me!.y);
+
+ global.context.rotate(rotation);
+
+ let opacity = Math.trunc(lerp(particle.startOpacity, particle.endOpacity, t));
+ let r = Math.trunc(lerp(particle.startR, particle.endR, t));
+ let g = Math.trunc(lerp(particle.startG, particle.endG, t));
+ let b = Math.trunc(lerp(particle.startB, particle.endB, t));
+
+ global.context.fillStyle = `rgb(${r} ${g} ${b} / ${opacity}%)`;
+ global.context.fillRect(-size/2, -size/2, size, size);
+
+ global.context.restore();
+}
+
+export function drawParticles() {
+ for (let i = 0; i < particles.length; i++) {
+ drawParticle(particles[i]);
+ }
+}
+
+export function tickParticles(delta: number) {
+ let keptParticles = []
+ for (let i = 0; i < particles.length; i++) {
+ particles[i].timer += delta;
+ if (!(particles[i].timer > particles[i].lifetime)) {
+ keptParticles.push(particles[i]);
+ } else {
+ console.log("dropping particle");
+ }
+ }
+ particles = keptParticles;
+}
+
+export function tickAndDrawParticles(delta: number) {
+ tickParticles(delta);
+ drawParticles();
+}<
\ No newline at end of file