-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
115 lines (110 loc) · 3.64 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { fromEvent,interval,Observable } from 'rxjs';
import { map,filter,flatMap,takeUntil,merge,scan } from 'rxjs/operators';
class Tick {
constructor(public readonly elapsed:number) {}
}
class Rotate {
constructor(public readonly angle:number) {}
}
enum KeyCode { LeftKey=37, UpKey=38, RightKey=39 }
interface State {
readonly x:number,readonly y:number,
readonly angle:number,readonly rotation:number,
readonly torque:number
}
function asteroidsObservable2() {
interface State {
readonly x: number;
readonly y: number;
readonly angle: number;
}
const initialState: State = { x: 100, y: 100, angle: 0};
function rotate(s:State, angleDelta:number): State {
return { ...s,
angle: s.angle + angleDelta
}
}
function updateView(state:State): void {
const ship = document.getElementById("ship")!;
ship.setAttribute('transform',
`translate(${state.x},${state.y}) rotate(${state.angle})`)
}
fromEvent<KeyboardEvent>(document, 'keydown')
.pipe(
filter(({key})=>key === 'ArrowLeft' || key === 'ArrowRight'),
filter(({repeat})=>!repeat),
flatMap(d=>interval(10).pipe(
takeUntil(fromEvent<KeyboardEvent>(document, 'keyup').pipe(
filter(({key})=>key === d.key)
)),
map(_=>d))
),
map(d=>d.key==='ArrowLeft'?-1:1),
scan(rotate, initialState))
.subscribe(updateView)
}
function asteroids() {
const ship = document.getElementById("ship")!;
const leftThruster = document.getElementById("leftThrust")!;
const rightThruster = document.getElementById("rightThrust")!;
const state:State = {
x:50,y:50,angle:0,
rotation:0,
torque:0
}
function keyEvent<T>(eventName:string,keyCode:number,result:()=>T):Observable<T> {
return fromEvent<KeyboardEvent>(document,eventName)
.pipe(
filter(e=>e.keyCode===keyCode),
map(result))
}
const
startLeftRotate = keyEvent('keydown',KeyCode.LeftKey,()=>new Rotate(-.1)),
startRightRotate = keyEvent('keydown',KeyCode.RightKey,()=>new Rotate(.1)),
stopLeftRotate = keyEvent('keyup',KeyCode.LeftKey,()=>new Rotate(0)),
stopRightRotate = keyEvent('keyup',KeyCode.RightKey,()=>new Rotate(0))
interval(10).pipe(
map(elapsed=>new Tick(elapsed)),
merge(startLeftRotate,startRightRotate,stopLeftRotate,stopRightRotate),
scan((s:State,e:Tick|Rotate)=>
e instanceof Rotate ? {...s,
torque:e.angle
} : {...s,
angle:s.angle+s.rotation,
rotation:s.rotation+s.torque
}, state)
)
.subscribe({next:s=>{
ship.setAttribute('transform',
`translate(${s.x},${s.y}) rotate(${s.angle})`)
if(s.torque < 0)
leftThruster.classList.remove('hidden');
else if(s.torque > 0)
rightThruster.classList.remove('hidden');
else {
leftThruster.classList.add('hidden');
rightThruster.classList.add('hidden');
}
}})
}
setTimeout(asteroidsObservable2, 0)
//window.onload = asteroids
function showKeys() {
function showKey(elementId,keyCode) {
fromEvent<KeyboardEvent>(document,'keydown')
.pipe(filter(e=>e.keyCode === keyCode))
.subscribe(e=>{
const arrowKey = document.getElementById(elementId)!;
arrowKey.classList.add("highlight");
})
fromEvent<KeyboardEvent>(document,'keyup')
.pipe(filter(e=>e.keyCode === keyCode))
.subscribe(e=>{
const arrowKey = document.getElementById(elementId)!;
arrowKey.classList.remove("highlight");
})
}
showKey("leftarrow",37);
showKey("rightarrow",39);
}
setTimeout(showKeys, 0)