junkerstock
 vrx-test7x 

<!DOCTYPE html>
<html>
<head>
<title>A-Frame - 3D巨大迷路 (HTML一括生成・最終FIX版)</title>
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/c-frame/aframe-physics-system@v4.0.1/dist/aframe-physics-system.min.js"></script>
<script src="https://unpkg.com/aframe-look-at-component@0.8.0/dist/aframe-look-at-component.min.js"></script>
<script src="https://unpkg.com/aframe-troika-text/dist/aframe-troika-text.min.js"></script>
</head>
<body>

<a-scene id="myScene" vr-mode-ui="enabled: true" background="color: #87CEEB" physics="debug: true; gravity: -9.8;">

<a-entity id="rig">
<a-entity id="player"
camera="userHeight: 1.6; far: 20000;"
look-controls="pointerLockEnabled: false; touchEnabled: false"
wasd-controls="acceleration: 80;"
dynamic-body="shape: capsule; mass: 5; height: 1.6; radius: 0.4; linearDamping: 0.97; angularDamping: 1; fixedRotation: true;">

<a-entity id="mouseCursor" cursor="rayOrigin: mouse" raycaster="objects: .maze-wall, a-sphere" position="0 0 -1" geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03" material="color: black; shader: flat; opacity: 0.7"></a-entity>
<a-entity id="leftHand" oculus-touch-controls="hand: left;"></a-entity>
<a-entity id="rightHand" oculus-touch-controls="hand: right;" laser-controls="hand: right" raycaster="objects: .maze-wall, a-sphere;"></a-entity>
</a-entity>
</a-entity>


<a-entity light="type: ambient; color: #888"></a-entity>
<a-entity light="type: directional; color: #FFF; intensity: 0.8; castShadow: true" position="-100 200 100"></a-entity>

<a-box id="ground"
position="0 -0.05 0"
width="500"
height="0.1"
depth="500"
color="#7BC8A4"
shadow="receive: true"
static-body>
</a-box>

<a-entity id="maze-container"></a-entity>


<script>
// --- SCRIPT BLOCK 2: Main Scene Logic ---
document.addEventListener('DOMContentLoaded', function () {
const sceneEl = document.querySelector('a-scene');
if (sceneEl.hasLoaded) { initializeWorld(); } else { sceneEl.addEventListener('loaded', initializeWorld, {once: true}); }
const MAZE_GRID_SIZE = 99;
const MAZE_CELL_SIZE = 4;
const WALL_HEIGHT = 8;
function initializeWorld() {
console.log("Generating maze data...");
const mazeData = generateMazeData(MAZE_GRID_SIZE);
console.log("Creating 3D maze from data...");
create3DMaze(mazeData); // この関数の中身を全面的に変更
setPlayerStartPosition();
createSpheres();
}
function generateMazeData(gridSize) {
let ary = Array.from({ length: gridSize }, () => Array(gridSize).fill(0));
for (let i = 0; i < gridSize; i++) { ary[i][0] = 1; ary[i][gridSize - 1] = 1; ary[0][i] = 1; ary[gridSize - 1][i] = 1; }
for (let i = 1; i < (gridSize - 1) / 2; i++) {
for (let j = 1; j < (gridSize - 1) / 2; j++) {
const x = i * 2; const y = j * 2; ary[x][y] = 1;
const isStartArea = (i === 1 && j === 1);
let ranten;
if (isStartArea) { ranten = Math.random() < 0.5 ? 0 : 2; } else { ranten = Math.floor(Math.random() * 4); }
if (ranten === 0) { ary[x + 1][y] = 1; } else if (ranten === 1) { ary[x - 1][y] = 1; } else if (ranten === 2) { ary[x][y + 1] = 1; } else if (ranten === 3) { ary[x][y - 1] = 1; }
}
}
return ary;
}

// ▼▼▼ 変更点2: 壁の生成方法をHTML文字列の一括挿入に変更 ▼▼▼
function create3DMaze(mazeData) {
const container = document.getElementById('maze-container');
if (!container) {
console.error('Maze container not found!');
return;
}

const wallFragments = []; // HTML文字列を格納する配列
const gridSize = mazeData.length;
const offset = (gridSize - 1) / 2;

for (let i = 0; i < gridSize; i++) {
for (let j = 0; j < gridSize; j++) {
if (mazeData[i][j] === 1) {
const x = (i - offset) * MAZE_CELL_SIZE;
const y = WALL_HEIGHT / 2;
const z = (j - offset) * MAZE_CELL_SIZE;

// 壁一つ一つのHTMLコードを文字列として生成
const wallHtml = `
<a-box class="maze-wall"
position="${x} ${y} ${z}"
width="${MAZE_CELL_SIZE}"
height="${WALL_HEIGHT}"
depth="${MAZE_CELL_SIZE}"
color="#A0522D"
shadow="cast: true; receive: false"
static-body>
</a-box>
`;
// 配列に追加
wallFragments.push(wallHtml);
}
}
}

console.log(`Generated ${wallFragments.length} wall fragments. Injecting into scene...`);
// 全ての壁のHTML文字列を結合し、コンテナに一度に挿入
container.innerHTML = wallFragments.join('');
console.log("3D maze created via innerHTML.");
}

function setPlayerStartPosition() {
const rigEl = document.getElementById('rig');
const gridSize = MAZE_GRID_SIZE;
const offset = (gridSize - 1) / 2;
const startGridX = 1;
const startGridZ = 1;
const startWorldX = (startGridX - offset) * MAZE_CELL_SIZE;
const startWorldZ = (startGridZ - offset) * MAZE_CELL_SIZE;
rigEl.setAttribute('position', `${startWorldX} 1.6 ${startWorldZ}`);
}

function createSpheres() {
const numberOfSpheres = 30; const spawnRadius = MAZE_GRID_SIZE / 2 * MAZE_CELL_SIZE * 1.1;
for (let i = 0; i < numberOfSpheres; i++) {
const sphereEl = document.createElement('a-sphere');
const radius = Math.random() * 3 + 0.5;
const angle = Math.random() * Math.PI * 2; const distance = spawnRadius + Math.random() * 50;
const x = Math.cos(angle) * distance; const z = Math.sin(angle) * distance; const y = radius;
const color = `hsl(${Math.random() * 360}, 70%, 50%)`;
sphereEl.setAttribute('position', {x: x, y: y, z: z});
sphereEl.setAttribute('radius', radius); sphereEl.setAttribute('color', color); sphereEl.setAttribute('shadow', 'cast: true');
sceneEl.appendChild(sphereEl);
}
}
});
</script>
</a-scene>
</body>
</html>


使用変数

-------( Function )
angle
ary
background
body
camera
class
color
container
controls
create3DMaze -------( Function )
createSpheres -------( Function )
cursor
depth
distance
generateMazeData -------( Function )
geometry
gridSize
height
i
id
initializeWorld -------( Function )
innerHTML
isStartArea
j
light
material
mazeData
MAZE_CELL_SIZE
MAZE_GRID_SIZE
numberOfSpheres
offset
physics
position
radius
ranten
raycaster
rigEl
sceneEl
setPlayerStartPosition -------( Function )
shadow
spawnRadius
sphereEl
src
startGridX
startGridZ
startWorldX
startWorldZ
ui
wallFragments
wallHtml
WALL_HEIGHT
width
x
y
z