From 8c1ab4c5756ac43d52bc8773f5e72dde90f79e77 Mon Sep 17 00:00:00 2001 From: Joris Date: Tue, 5 Jul 2022 22:11:00 +0200 Subject: WIP --- src/view/colors.ts | 2 +- src/view/scene.ts | 32 ++++++++++++++++++----- src/view/ship.ts | 76 +++++++++++++++++++++++++++++++++--------------------- 3 files changed, 73 insertions(+), 37 deletions(-) (limited to 'src/view') diff --git a/src/view/colors.ts b/src/view/colors.ts index c663d25..725e981 100644 --- a/src/view/colors.ts +++ b/src/view/colors.ts @@ -1,4 +1,4 @@ -export let colors = { +export const colors = { blue: "#333388", red: "#CC3333", } diff --git a/src/view/scene.ts b/src/view/scene.ts index fe88c12..6d35edc 100644 --- a/src/view/scene.ts +++ b/src/view/scene.ts @@ -1,35 +1,53 @@ import * as Ship from 'view/ship' import * as Colors from 'view/colors' -import * as Screen from 'screen' +import * as Vec2 from 'model/vec2' +import * as Size from 'model/size' export interface State { + canvas: HTMLCanvasElement, context: CanvasRenderingContext2D, timestamp: number, ship: Ship.State, + windowSize: Size.Size, } export function init(): State { - let canvas = document.querySelector('canvas') as HTMLCanvasElement - let context = canvas.getContext("2d") as CanvasRenderingContext2D + const canvas = document.querySelector('canvas') as HTMLCanvasElement + const context = canvas.getContext("2d") as CanvasRenderingContext2D + const windowSize = { + width: window.innerWidth, + height: window.innerHeight + } + canvas.width = windowSize.width + canvas.height = windowSize.height return { + canvas, context, timestamp: 0, - ship: Ship.init(), + ship: Ship.init(windowSize), + windowSize } } export function update(state: State, timestamp: number) { - let delta = timestamp - state.timestamp + const dt = timestamp - state.timestamp state.timestamp = timestamp - Ship.update(state.ship, state.timestamp, delta) + Ship.update(state.ship, dt, state.windowSize) +} + +export function resize(state: State, size: Size.Size) { + Ship.project(state.ship, state.windowSize, size) + state.windowSize = size + state.canvas.width = size.width + state.canvas.height = size.height } export function view(state: State) { // Clear state.context.fillStyle = Colors.colors.blue - state.context.fillRect(0, 0, Screen.width, Screen.height) + state.context.fillRect(0, 0, state.windowSize.width, state.windowSize.height) Ship.view(state.context, state.ship) } diff --git a/src/view/ship.ts b/src/view/ship.ts index 92590d3..5a8b86f 100644 --- a/src/view/ship.ts +++ b/src/view/ship.ts @@ -1,51 +1,64 @@ import * as Controls from 'controls' import * as Vec2 from 'model/vec2' +import * as Size from 'model/size' import * as Number from 'util/number' -import * as Screen from 'screen' import * as Colors from 'view/colors' +import * as Physics from 'util/physics' -export const radius: number = 30 -export const fireDelay: number = 200 export const missileWidth: number = 10 export const missileHeight: number = 5 export interface State { + speed: Vec2.Vec2, pos: Vec2.Vec2, + radius: number, missiles: Array, lastFired: number, } -export function init(): State { +export function init(windowSize: Size.Size): State { return { + speed: { x: 0, y: 0 }, pos: { - x: Screen.width / 6, - y: Screen.height / 2, + x: windowSize.width / 6, + y: windowSize.height / 2, }, + radius: Size.diagonal(windowSize) / 30, missiles: [], lastFired: 0, } } -export function update(state: State, timestamp: number, delta: number) { - move(state, delta) - updateMissiles(state, timestamp, delta) +export function update( + state: State, + dt: number, + windowSize: Size.Size +) { + move(state, dt, windowSize) + updateMissiles(state, dt, windowSize) } -function move(state: State, delta: number) { - let dir = controlsDir(Controls.current) +function move(state: State, dt: number, windowSize: Size.Size) { + const dir = controlsDir(Controls.current) - if (!Vec2.equals(dir, Vec2.zero())) { - let teta = Math.atan2(dir.y, dir.x) - state.pos.x += Math.cos(teta) * delta / 3 - state.pos.y += Math.sin(teta) * delta / 3 - } + const unitDt = 0.5 + const steps = Math.round(dt / unitDt) + + const acc = Physics.acc({ dt, speed: state.speed, dir }) + Array(steps).fill(1).forEach(_ => { + state.speed = Physics.speed({ dt: unitDt, acc, speed: state.speed }) + state.pos = Physics.pos({ dt: unitDt, acc, speed: state.speed, pos: state.pos }) + }) - state.pos.x = Number.clamp(state.pos.x, radius, Screen.width - radius) - state.pos.y = Number.clamp(state.pos.y, radius, Screen.height - radius) + state.pos = Vec2.clamp( + state.pos, + { x: state.radius, y: state.radius }, + { x: windowSize.width - state.radius, y: windowSize.height - state.radius } + ) } function controlsDir(c: Controls.Controls): Vec2.Vec2 { - let dir = Vec2.zero() + let dir = { x: 0, y: 0 } if (c.up && !c.down) dir.y = -1 @@ -57,26 +70,31 @@ function controlsDir(c: Controls.Controls): Vec2.Vec2 { else if (c.left && !c.right) dir.x = -1 - return dir + return Vec2.normalize(dir) } -function updateMissiles(state: State, timestamp: number, delta: number) { - if (Controls.current.space && state.lastFired + fireDelay < timestamp) { - state.missiles.push({x: state.pos.x + radius, y: state.pos.y}) - state.lastFired = timestamp +function updateMissiles(state: State, dt: number, windowSize: Size.Size) { + if (Controls.current.spaceCount > state.lastFired) { + state.missiles.push({x: state.pos.x + state.radius, y: state.pos.y}) + state.lastFired = Controls.current.spaceCount } state.missiles = state.missiles - .map(missile => ({ ...missile, x: missile.x + delta})) - .filter(missile => missile.x < Screen.width) + .map(missile => ({ ...missile, x: missile.x + dt})) + .filter(missile => missile.x < windowSize.width) +} + +export function project(state: State, from: Size.Size, to: Size.Size) { + state.pos = Vec2.project(from, to, state.pos) + state.radius = state.radius / Size.diagonal(from) * Size.diagonal(to) } export function view(context: CanvasRenderingContext2D, state: State) { context.fillStyle = Colors.colors.red context.beginPath() - context.moveTo(state.pos.x - radius, state.pos.y - radius) - context.lineTo(state.pos.x + radius, state.pos.y) - context.lineTo(state.pos.x - radius, state.pos.y + radius) + context.moveTo(state.pos.x - state.radius, state.pos.y - state.radius) + context.lineTo(state.pos.x + state.radius, state.pos.y) + context.lineTo(state.pos.x - state.radius, state.pos.y + state.radius) context.closePath() context.fill() -- cgit v1.2.3