diff options
author | Joris | 2021-02-14 20:25:55 +0100 |
---|---|---|
committer | Joris | 2021-02-14 20:25:55 +0100 |
commit | f47b2e3f68e69238b731d6183e739805db20ae5b (patch) | |
tree | 2eaa3937cdec3dccf4e751f9b519833740e69aca /src/view/ship.ts | |
parent | 0b60fd8c2cf5746a45cea137d2eac918ca7a8307 (diff) |
Control a ship that can fire missiles
Diffstat (limited to 'src/view/ship.ts')
-rw-r--r-- | src/view/ship.ts | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/view/ship.ts b/src/view/ship.ts new file mode 100644 index 0000000..92590d3 --- /dev/null +++ b/src/view/ship.ts @@ -0,0 +1,94 @@ +import * as Controls from 'controls' +import * as Vec2 from 'model/vec2' +import * as Number from 'util/number' +import * as Screen from 'screen' +import * as Colors from 'view/colors' + +export const radius: number = 30 +export const fireDelay: number = 200 +export const missileWidth: number = 10 +export const missileHeight: number = 5 + +export interface State { + pos: Vec2.Vec2, + missiles: Array<Vec2.Vec2>, + lastFired: number, +} + +export function init(): State { + return { + pos: { + x: Screen.width / 6, + y: Screen.height / 2, + }, + missiles: [], + lastFired: 0, + } +} + +export function update(state: State, timestamp: number, delta: number) { + move(state, delta) + updateMissiles(state, timestamp, delta) +} + +function move(state: State, delta: number) { + let 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 + } + + state.pos.x = Number.clamp(state.pos.x, radius, Screen.width - radius) + state.pos.y = Number.clamp(state.pos.y, radius, Screen.height - radius) +} + +function controlsDir(c: Controls.Controls): Vec2.Vec2 { + let dir = Vec2.zero() + + if (c.up && !c.down) + dir.y = -1 + else if (c.down && !c.up) + dir.y = 1 + + if (c.right && !c.left) + dir.x = 1 + else if (c.left && !c.right) + dir.x = -1 + + return 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 + } + + state.missiles = state.missiles + .map(missile => ({ ...missile, x: missile.x + delta})) + .filter(missile => missile.x < Screen.width) +} + +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.closePath() + context.fill() + + state.missiles.forEach(({x, y}) => { + context.fillStyle = Colors.colors.red + context.beginPath() + context.rect( + x - missileWidth / 2, + y - missileHeight / 2, + missileWidth, + missileHeight + ) + context.fill() + }) +} |