Skip to content

Commit 5116858

Browse files
committed
Add control. (down only)
1 parent 809e1f5 commit 5116858

File tree

2 files changed

+91
-13
lines changed

2 files changed

+91
-13
lines changed

src/main.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,68 @@ function startApp() {
77
const canvas = document.getElementById('game') as HTMLCanvasElement;
88
const space = new Space(canvas);
99

10+
let prevTimeStamp = performance.now();
11+
let deltaTimeSec = 0.001;
12+
13+
let rotateYaw = 0;
14+
let rotatePitch = 0;
15+
const rotateMax = Math.PI / 3;
16+
const rotateAmount = Math.PI / 4;
17+
let rotateYawPushed = false;
18+
let pitchUpPushed = false;
19+
let pitchDownPushed = false;
20+
21+
function checkRotateDown(x: number, y: number, pushOrNot: boolean) {
22+
if (y > canvas.height * 0.8 &&
23+
x > canvas.width * 0.2 &&
24+
x < canvas.width * 0.8) {
25+
pitchDownPushed = pushOrNot;
26+
}
27+
}
28+
29+
canvas.addEventListener('touchstart', (e) => {
30+
// if touch on canvas bottom?
31+
if (e.touches.length > 0) {
32+
const touch = e.touches[0];
33+
checkRotateDown(touch.clientX, touch.clientY, true);
34+
}
35+
});
36+
canvas.addEventListener('mousedown', (e) => {
37+
checkRotateDown(e.clientX, e.clientY, true);
38+
});
39+
40+
canvas.addEventListener('touchmove', (e) => {
41+
});
42+
43+
canvas.addEventListener('touchend', (e) => {
44+
if (e.touches.length > 0) {
45+
const touch = e.touches[0];
46+
checkRotateDown(touch.clientX, touch.clientY, false);
47+
}
48+
});
49+
50+
canvas.addEventListener('mouseup', (e) => {
51+
checkRotateDown(e.clientX, e.clientY, false);
52+
});
53+
1054
space.start();
1155
// loop to render the game
1256
function gameLoop() {
57+
const nowTimeStamp = performance.now();
58+
deltaTimeSec = (nowTimeStamp - prevTimeStamp) * 0.001;
59+
prevTimeStamp = nowTimeStamp;
60+
61+
if (pitchUpPushed) {
62+
rotatePitch = Math.min(rotatePitch + rotateAmount * deltaTimeSec, rotateMax);
63+
} else if (pitchDownPushed) {
64+
rotatePitch = Math.max(rotatePitch - rotateAmount * deltaTimeSec, -rotateMax);
65+
} else {
66+
rotatePitch *= 0.5 * deltaTimeSec;
67+
}
68+
69+
space.setFlowDirection(rotateYaw, rotatePitch);
70+
space.flowStars(deltaTimeSec);
71+
1372
space.render();
1473
requestAnimationFrame(gameLoop);
1574
}

src/space.ts

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ export class Space {
6868
// webgl default is x(right), y(up), z(out of screen = towards the viewer) = right-handed coordinate system.
6969
cameraPosition: Vector3 = { x: 0, y: 0, z: 0 };
7070
cameraDirection: Vector3 = { x: 0, y: 0, z: -1 };
71+
originalFlowDirection: Vector3 = { x: 0, y: 0, z: 1 };
72+
flowDirection: Vector3 = { x: 0, y: 0, z: 1 };
7173
stars: Star[] = [];
7274

73-
prevTimeStamp: number = 0;
74-
7575
shaderProgram: WebGLProgram;
7676
vertexBuffer: WebGLBuffer;
7777

@@ -83,7 +83,6 @@ export class Space {
8383
this.canvas.height = this.canvas.clientHeight;
8484
this.context = this.canvas.getContext('webgl')!;
8585
this.context.viewport(0, 0, this.canvas.width, this.canvas.height);
86-
this.prevTimeStamp = performance.now();
8786
this.shaderProgram = this.context.createProgram()!;
8887
this.vertexBuffer = this.context.createBuffer()!;
8988
}
@@ -145,7 +144,6 @@ void main() {
145144

146145
initiateStars() {
147146
this.alpha = 0.0;
148-
this.prevTimeStamp = performance.now();
149147
this.stars = [];
150148
this.stars.push({ // default test star.
151149
position: { x: 0, y: 0, z: -5 },
@@ -204,11 +202,13 @@ void main() {
204202
this.stars.forEach(star => {
205203
let position = star.position;
206204
// move the star against the camera direction.
207-
position = vectorSubtract(position, vectorMultiplyScalar(this.cameraDirection, flowAmount * star.speedRatio));
205+
position = vectorAdd(position, vectorMultiplyScalar(this.flowDirection, flowAmount * star.speedRatio));
208206
star.alpha = clampValue(star.alpha + dt * star.speedRatio, 0.0, 1.0);
209-
if (Math.abs(position.z) > STAR_VISUAL_RANGE ||
207+
const outOfVisualRange = Math.abs(position.z) > STAR_VISUAL_RANGE ||
210208
Math.abs(position.x) > STAR_VISUAL_RANGE ||
211-
Math.abs(position.y) > STAR_VISUAL_RANGE) {
209+
Math.abs(position.y) > STAR_VISUAL_RANGE;
210+
const outOfScreen = dotProduct(position, this.cameraDirection) < 0;
211+
if (outOfVisualRange || outOfScreen) {
212212
position.x = rangedRandom(-1, 1) * STAR_VISUAL_RANGE;
213213
position.y = rangedRandom(-1, 1) * STAR_VISUAL_RANGE;
214214
position.z = rangedRandom(-1, 1) * STAR_VISUAL_RANGE;
@@ -298,12 +298,6 @@ void main() {
298298
}
299299

300300
render() {
301-
const nowTimeStamp = performance.now();
302-
const deltaTimeSec = (nowTimeStamp - this.prevTimeStamp) * 0.001;
303-
this.prevTimeStamp = nowTimeStamp;
304-
305-
this.flowStars(deltaTimeSec);
306-
307301
this.updateVertexBuffer();
308302

309303
// clear black.
@@ -351,4 +345,29 @@ void main() {
351345
// Draw points
352346
gl.drawArrays(gl.POINTS, 0, this.stars.length);
353347
}
348+
349+
setFlowDirection(yaw: number, pitch: number) {
350+
// rotate only cameraDirection vector.
351+
const flowDirection = this.originalFlowDirection;
352+
353+
// rotate around y-axis.
354+
const cosYaw = Math.cos(yaw);
355+
const sinYaw = Math.sin(yaw);
356+
const newCameraDirection = {
357+
x: flowDirection.x * cosYaw - flowDirection.z * sinYaw,
358+
y: flowDirection.y,
359+
z: flowDirection.x * sinYaw + flowDirection.z * cosYaw
360+
};
361+
362+
// rotate around x-axis.
363+
const cosPitch = Math.cos(pitch);
364+
const sinPitch = Math.sin(pitch);
365+
const newCameraDirection2 = {
366+
x: newCameraDirection.x,
367+
y: newCameraDirection.y * cosPitch - newCameraDirection.z * sinPitch,
368+
z: newCameraDirection.y * sinPitch + newCameraDirection.z * cosPitch
369+
};
370+
371+
this.flowDirection = newCameraDirection2;
372+
}
354373
}

0 commit comments

Comments
 (0)