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, 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() }) }