Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Commit

Permalink
visual improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
CodyAdam committed Jan 30, 2024
1 parent b259e2d commit b744c98
Show file tree
Hide file tree
Showing 21 changed files with 142 additions and 167 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"explorer.excludeGitIgnore": false
"explorer.excludeGitIgnore": true
}
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/client/public/pattern.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/client/src/app/canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,5 @@ export function Canvas(params: Params) {
game.setScene(api.scene);
}, [api.scene, game]);

return <canvas ref={canvasRef} className='w-full h-full dustBackground' height={screen.height} width={screen.width} />;
return <canvas ref={canvasRef} className='w-full h-full grid-bg' height={screen.height} width={screen.width} />;
}
32 changes: 0 additions & 32 deletions packages/client/src/lib/Food.ts

This file was deleted.

49 changes: 14 additions & 35 deletions packages/client/src/lib/Game.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { screenToWorld, worldToScreen } from "@/utils/position";
import { type SceneDTO, type Position } from "@viper-vortex/shared";
import { type Api } from "@/hooks/useApi";
import { Food } from "./Food";
import { Player } from "./Player";
import { TimeManager } from "./TimeManager";
import { screenToWorld, worldToScreen } from "@/utils/position";
import { type Position, type SceneDTO } from "@viper-vortex/shared";
import { MyPlayer } from "./MyPlayer";
import { Orb } from "./Orb";
import { Player } from "./Player";
import { TimeManager } from "./TimeManager";

export type Params = {
centered: boolean;
Expand All @@ -21,16 +20,15 @@ export type Camera = {

export class Game {
private players: Record<string, Player> = {};
private foods: Record<string, Food> = {};
private orbs: Record<string, Food> = {};
private orbs: Record<string, Orb> = {};
private mapSize = { width: 0, height: 0 };
private me: MyPlayer | undefined;
private params: Params = { centered: true };
private api: Api | undefined;
private time: TimeManager;
private isSprinting = false;
private angle = 0;
private canvas: HTMLCanvasElement | null = null;
time: TimeManager;
isSprinting = false;
camera: Camera = { offset: { x: 0, y: 0 }, zoom: 2 };
cursor: Position = { x: 0, y: 0 };
screen = { width: 0, height: 0 };
Expand Down Expand Up @@ -73,17 +71,6 @@ export class Game {
});
notSeen.forEach((id) => delete this.players[id]);

const notSeenFood = new Set(Object.keys(this.foods));
scene.food.forEach((food) => {
notSeenFood.delete(food.id); // seen
if (!this.foods[food.id]) {
this.foods[food.id] = new Food(food, this);
} else {
this.foods[food.id]!.update(food);
}
});
notSeenFood.forEach((id) => delete this.foods[id]);

const notSeenOrbs = new Set(Object.keys(this.orbs));
scene.orbs.forEach((orb) => {
notSeenOrbs.delete(orb.id); // seen
Expand Down Expand Up @@ -175,15 +162,15 @@ export class Game {
const c = this.c;
if (!c) return;
const screenOrigin = worldToScreen({ x: 0, y: 0 }, this.camera);
c.lineWidth = 2;
c.lineWidth = 4;
c.fillStyle = "transparent";
c.rect(
screenOrigin.x,
screenOrigin.y,
this.mapSize.width * this.camera.zoom,
this.mapSize.height * this.camera.zoom,
);
c.strokeStyle = "black";
c.strokeStyle = "hsl(0, 0%, 30%)";
c.stroke();
}

Expand All @@ -195,9 +182,6 @@ export class Game {

if (this.params.centered) this.centerCamera();

Object.values(this.foods).forEach((food) => {
food.draw();
});
Object.values(this.players).forEach((player) => {
player.draw();
});
Expand All @@ -211,22 +195,17 @@ export class Game {

// show fps top right
this.c.fillStyle = "white";
this.c.font = "20px Arial";
this.c.font = "16px Arial";
this.c.textAlign = "right";
this.c.fillText(
`FPS: ${Math.round(this.time.fps).toString()}`,
this.screen.width - 32,
32,
this.screen.width - 10,
20,
);
this.c.fillText(
`TPS: ${Math.round(this.time.tps).toString()}`,
this.screen.width - 32,
64,
);
this.c.fillText(
`Sprinting: ${this.isSprinting ? "Yes" : "No"}`,
this.screen.width - 32,
128,
this.screen.width - 10,
40,
);
}

Expand Down
14 changes: 0 additions & 14 deletions packages/client/src/lib/MyPlayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,5 @@ import { Player } from "./Player";
export class MyPlayer extends Player {
draw(): void {
super.draw();
const c = this.game.c;
if (!c) return;
const playerHead = this.getHead();
if (playerHead) {
const screenHead = worldToScreen(playerHead, this.game.camera);
const screenCurPos = worldToScreen(this.game.cursor, this.game.camera);
c.beginPath();
c.moveTo(screenHead.x, screenHead.y);
c.lineTo(screenCurPos.x, screenCurPos.y);
c.fillStyle = "red";
c.strokeStyle = "red";
c.lineWidth = 2;
c.stroke();
}
}
}
32 changes: 22 additions & 10 deletions packages/client/src/lib/Orb.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,47 @@
import { worldToScreen } from "@/utils/position";
import { type OrbDTO } from "@viper-vortex/shared";
import { Food } from "./Food";
import { getOrbSizeFromPoints, type OrbDTO, type Position } from "@viper-vortex/shared";
import { Entity } from './Entity';
import { type Game } from "./Game";

export class Orb extends Food {
export class Orb extends Entity{
private size: number;
private points: number;
private readonly color: string;
private position: Position;

constructor(orb: OrbDTO, game: Game) {
super(orb, game);
this.size = orb.size;
super(orb.id, game);
this.points = orb.points;
this.size = getOrbSizeFromPoints(orb.points);
this.color = orb.color;
this.position = orb.position;
}

update(orb: OrbDTO) {
super.update(orb);
this.size = orb.size;
this.position = orb.position;
this.points = orb.points;
this.size = getOrbSizeFromPoints(orb.points);
}

draw(): void {
const c = this.game.c;
if (!c) return;
const screenFood = worldToScreen(this.position, this.game.camera);
const screenPos = worldToScreen(this.position, this.game.camera);
c.beginPath();
c.arc(
screenFood.x,
screenFood.y,
screenPos.x,
screenPos.y,
this.size * 5 * this.game.camera.zoom,
0,
2 * Math.PI,
);
c.fillStyle = this.color;
// lower opacity
c.globalAlpha = 0.4;
c.shadowBlur = 6;
c.shadowColor = "rgba(255, 255, 255, 0.4)";
c.fill();
c.shadowBlur = 0;
c.globalAlpha = 1;
}
}
40 changes: 31 additions & 9 deletions packages/client/src/lib/Player.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { worldToScreen } from "@/utils/position";
import { type PlayerDTO, type Position } from "@viper-vortex/shared";
import {
getPlayerRadiusFromScore,
type PlayerDTO,
type Position,
} from "@viper-vortex/shared";
import { Entity } from "./Entity";
import { type Game } from "./Game";

Expand All @@ -8,19 +12,22 @@ export class Player extends Entity {
rawBody: Position[]; // raw data from server
name: string;
color: string;
score: number;

constructor(p: PlayerDTO, game: Game) {
super(p.id, game);
this.body = p.body;
this.rawBody = p.body;
this.name = p.name;
this.color = p.color;
this.score = p.score;
}

update(p: PlayerDTO) {
this.rawBody = p.body;
this.name = p.name;
this.color = p.color;
this.score = p.score;
}

draw(): void {
Expand All @@ -30,10 +37,8 @@ export class Player extends Entity {
this.interpolate();

c.beginPath();

let prevScreenBodyPart = worldToScreen(this.body[0]!, this.game.camera);
c.moveTo(prevScreenBodyPart.x, prevScreenBodyPart.y);

this.body.forEach((bodyPart, index) => {
if (index === 0) return;
const screenBodyPart = worldToScreen(bodyPart, this.game.camera);
Expand All @@ -45,21 +50,38 @@ export class Player extends Entity {
c.lineTo(prevScreenBodyPart.x, prevScreenBodyPart.y);
}

c.lineWidth = 30 * this.game.camera.zoom
c.lineWidth = getPlayerRadiusFromScore(this.score) * this.game.camera.zoom;
c.strokeStyle = this.color;
c.lineCap = "round";
c.lineJoin = "round";

c.globalAlpha = 1;
// add an outline if sprinting
if (this.game.isSprinting) {
c.shadowBlur = 10;
// change alpha based on time
const t = this.game.time.fixedTickCount;
c.shadowColor = `rgba(255, 255, 255, ${Math.sin(t / 2) * 0.4 + 0.6})`;
}
c.stroke();
c.shadowBlur = 0;


// draw names
const head = this.getHead();
if (!head) return;
const screenHead = worldToScreen(head, this.game.camera);
c.font = "20px Arial";
c.fillStyle = "white";
c.textAlign = "center";
c.fillText(this.name + this.body.length, screenHead.x, screenHead.y - 20);
}

interpolate() {
let { body } = this;
const { rawBody } = this;

// remove extra body parts
if (body.length > rawBody.length)
body = body.slice(0, rawBody.length);
if (body.length > rawBody.length) body = body.slice(0, rawBody.length);

// add missing body parts
if (body.length < rawBody.length)
Expand All @@ -73,8 +95,8 @@ export class Player extends Entity {
const bodyPart = body[i]!;
const rawBodyPart = rawBody[i]!;

bodyPart.x += (rawBodyPart.x - bodyPart.x) * 0.1;
bodyPart.y += (rawBodyPart.y - bodyPart.y) * 0.1;
bodyPart.x += (rawBodyPart.x - bodyPart.x) * 0.2;
bodyPart.y += (rawBodyPart.y - bodyPart.y) * 0.2;
}
this.body = body;
this.rawBody = rawBody;
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/lib/TimeManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ export class TimeManager {
private lastUpdate = performance.now();
private lastFixedUpdate = performance.now();
private tickCount = 0;
private fixedTickCount = 0;
private deltaTime = 1;
private fixedDeltaTime = 1;
private updateCallbacks: Array<(deltaTime: number) => void> = [];
private fixedUpdateCallbacks: Array<(deltaTime: number) => void> = [];
fixedTickCount = 0;
isPaused = true;
fps = 0;
tps = 0;
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/lib/shared-state.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { type SceneDTO, ScoresDTO } from "@viper-vortex/shared";
import { type SceneDTO, type ScoresDTO } from "@viper-vortex/shared";
import { createContext, useContext, useState } from "react";
import { type Socket } from "socket.io-client";

Expand Down
4 changes: 2 additions & 2 deletions packages/client/src/styles/globals.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@viper-vortex/server",
"type": "module",
"scripts": {
"dev": "tsx src/index.ts",
"dev": "tsx watch ./src/index.ts",
"watch": "tsx watch ./src/index.ts",
"build": "tsc",
"start": "node ./dist/index.js"
Expand Down
Loading

0 comments on commit b744c98

Please sign in to comment.