aboutsummaryrefslogtreecommitdiff
path: root/src/view
diff options
context:
space:
mode:
authorJoris2021-02-14 20:25:55 +0100
committerJoris2021-02-14 20:25:55 +0100
commitf47b2e3f68e69238b731d6183e739805db20ae5b (patch)
tree2eaa3937cdec3dccf4e751f9b519833740e69aca /src/view
parent0b60fd8c2cf5746a45cea137d2eac918ca7a8307 (diff)
Control a ship that can fire missiles
Diffstat (limited to 'src/view')
-rw-r--r--src/view/colors.ts4
-rw-r--r--src/view/scene.ts35
-rw-r--r--src/view/ship.ts94
3 files changed, 133 insertions, 0 deletions
diff --git a/src/view/colors.ts b/src/view/colors.ts
new file mode 100644
index 0000000..c663d25
--- /dev/null
+++ b/src/view/colors.ts
@@ -0,0 +1,4 @@
+export let colors = {
+ blue: "#333388",
+ red: "#CC3333",
+}
diff --git a/src/view/scene.ts b/src/view/scene.ts
new file mode 100644
index 0000000..fe88c12
--- /dev/null
+++ b/src/view/scene.ts
@@ -0,0 +1,35 @@
+import * as Ship from 'view/ship'
+import * as Colors from 'view/colors'
+import * as Screen from 'screen'
+
+export interface State {
+ context: CanvasRenderingContext2D,
+ timestamp: number,
+ ship: Ship.State,
+}
+
+export function init(): State {
+ let canvas = document.querySelector('canvas') as HTMLCanvasElement
+ let context = canvas.getContext("2d") as CanvasRenderingContext2D
+
+ return {
+ context,
+ timestamp: 0,
+ ship: Ship.init(),
+ }
+}
+
+export function update(state: State, timestamp: number) {
+ let delta = timestamp - state.timestamp
+ state.timestamp = timestamp
+
+ Ship.update(state.ship, state.timestamp, delta)
+}
+
+export function view(state: State) {
+ // Clear
+ state.context.fillStyle = Colors.colors.blue
+ state.context.fillRect(0, 0, Screen.width, Screen.height)
+
+ Ship.view(state.context, state.ship)
+}
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()
+ })
+}