oggata commited on
Commit
e4cffa4
·
verified ·
1 Parent(s): 4c5cd5c

Create js/three_map.js

Browse files
Files changed (1) hide show
  1. static/js/three_map.js +123 -0
static/js/three_map.js ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Three.jsを使用した3Dマップの実装
2
+ let scene, camera, renderer, buildings = {}, residents = {};
3
+
4
+ function init() {
5
+ // シーンの作成
6
+ scene = new THREE.Scene();
7
+ scene.background = new THREE.Color(0x87CEEB); // 空色の背景
8
+
9
+ // カメラの設定
10
+ camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
11
+ camera.position.set(50, 50, 50);
12
+ camera.lookAt(0, 0, 0);
13
+
14
+ // レンダラーの設定
15
+ renderer = new THREE.WebGLRenderer({ antialias: true });
16
+ renderer.setSize(window.innerWidth, window.innerHeight);
17
+ document.getElementById('three-container').appendChild(renderer.domElement);
18
+
19
+ // 光源の追加
20
+ const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
21
+ scene.add(ambientLight);
22
+ const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
23
+ directionalLight.position.set(50, 50, 50);
24
+ scene.add(directionalLight);
25
+
26
+ // 地面の作成
27
+ const groundGeometry = new THREE.PlaneGeometry(100, 100);
28
+ const groundMaterial = new THREE.MeshStandardMaterial({
29
+ color: 0x90EE90,
30
+ side: THREE.DoubleSide
31
+ });
32
+ const ground = new THREE.Mesh(groundGeometry, groundMaterial);
33
+ ground.rotation.x = -Math.PI / 2;
34
+ scene.add(ground);
35
+
36
+ // アニメーションループの開始
37
+ animate();
38
+
39
+ // ウィンドウリサイズのハンドリング
40
+ window.addEventListener('resize', onWindowResize, false);
41
+ }
42
+
43
+ function createBuilding(name, position, color = 0x808080) {
44
+ const geometry = new THREE.BoxGeometry(10, 10, 10);
45
+ const material = new THREE.MeshStandardMaterial({ color: color });
46
+ const building = new THREE.Mesh(geometry, material);
47
+ building.position.set(position.x, 5, position.z);
48
+ scene.add(building);
49
+ buildings[name] = building;
50
+
51
+ // 建物名のラベル
52
+ const canvas = document.createElement('canvas');
53
+ const context = canvas.getContext('2d');
54
+ canvas.width = 256;
55
+ canvas.height = 64;
56
+ context.fillStyle = '#ffffff';
57
+ context.font = '24px Arial';
58
+ context.fillText(name, 10, 32);
59
+ const texture = new THREE.CanvasTexture(canvas);
60
+ const labelMaterial = new THREE.SpriteMaterial({ map: texture });
61
+ const label = new THREE.Sprite(labelMaterial);
62
+ label.position.set(position.x, 15, position.z);
63
+ scene.add(label);
64
+ }
65
+
66
+ function createResident(name, position, color = 0xff0000) {
67
+ const geometry = new THREE.SphereGeometry(1, 32, 32);
68
+ const material = new THREE.MeshStandardMaterial({ color: color });
69
+ const resident = new THREE.Mesh(geometry, material);
70
+ resident.position.set(position.x, 1, position.z);
71
+ scene.add(resident);
72
+ residents[name] = resident;
73
+
74
+ // 住民名のラベル
75
+ const canvas = document.createElement('canvas');
76
+ const context = canvas.getContext('2d');
77
+ canvas.width = 256;
78
+ canvas.height = 64;
79
+ context.fillStyle = '#ffffff';
80
+ context.font = '24px Arial';
81
+ context.fillText(name, 10, 32);
82
+ const texture = new THREE.CanvasTexture(canvas);
83
+ const labelMaterial = new THREE.SpriteMaterial({ map: texture });
84
+ const label = new THREE.Sprite(labelMaterial);
85
+ label.position.set(position.x, 3, position.z);
86
+ scene.add(label);
87
+ }
88
+
89
+ function updatePositions(state) {
90
+ // 建物の位置を更新
91
+ state.locations.forEach(location => {
92
+ if (!buildings[location.name]) {
93
+ createBuilding(location.name, location.position);
94
+ }
95
+ });
96
+
97
+ // 住民の位置を更新
98
+ state.residents.forEach(resident => {
99
+ if (!residents[resident.name]) {
100
+ createResident(resident.name, resident.position);
101
+ } else {
102
+ residents[resident.name].position.set(
103
+ resident.position.x,
104
+ 1,
105
+ resident.position.z
106
+ );
107
+ }
108
+ });
109
+ }
110
+
111
+ function onWindowResize() {
112
+ camera.aspect = window.innerWidth / window.innerHeight;
113
+ camera.updateProjectionMatrix();
114
+ renderer.setSize(window.innerWidth, window.innerHeight);
115
+ }
116
+
117
+ function animate() {
118
+ requestAnimationFrame(animate);
119
+ renderer.render(scene, camera);
120
+ }
121
+
122
+ // 初期化
123
+ init();