junkerstock
 vrx-test5 

<!DOCTYPE html>
<html>
<head>
<title>A-Frame - 3D巨大迷路 (移動修正版)</title>
<script src="https://aframe.io/releases/1.7.0/aframe.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/c-frame/aframe-physics-system@v4.2.2/dist/aframe-physics-system.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/aframe-extras@7.2.0/dist/aframe-extras.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>

<script>
// movement-controls を使用するため、このブロックは不要です
</script>
</head>
<body>

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

<a-entity id="rig"
movement-controls="speed: 0.3; fly: true;"
dynamic-body="shape: cylinder; mass: 2; height: 1.6; radius: 0.5; linearDamping: 0.05; angularDamping: 0.05;">
<a-entity id="camera" camera="far: 20000;" look-controls="pointerLockEnabled: false; touchEnabled: false" position="0 1.6 0">
<a-entity id="mouseCursor" cursor="rayOrigin: mouse; fuse: false;" 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>
<a-entity id="leftHand" oculus-touch-controls="hand: left; model: true;"></a-entity>
<a-entity id="rightHand" oculus-touch-controls="hand: right; model: true;" raycaster="objects: .maze-wall, a-sphere;" laser-controls="hand: right; model: false; lineColor: white; lineOpacity: 0.75" ></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-plane id="ground" position="0 0 0" rotation="-90 0 0" width="500" height="500" color="#7BC8A4" shadow="receive: true"
static-body>
</a-plane>


<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(mazeData);
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;
}
function create3DMaze(mazeData) {
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 wall = document.createElement('a-box');
const x = (i - offset) * MAZE_CELL_SIZE; const y = WALL_HEIGHT / 2; const z = (j - offset) * MAZE_CELL_SIZE;
wall.setAttribute('position', {x: x, y: y, z: z});
wall.setAttribute('width', MAZE_CELL_SIZE); wall.setAttribute('height', WALL_HEIGHT); wall.setAttribute('depth', MAZE_CELL_SIZE);
wall.setAttribute('color', '#A0522D'); wall.setAttribute('material', { roughness: 0.8 });
wall.setAttribute('shadow', 'cast: true; receive: false'); wall.classList.add('maze-wall');
wall.setAttribute('static-body', '');
sceneEl.appendChild(wall);
}
}
}
console.log("3D maze created.");
}
function setPlayerStartPosition(mazeData) {
const rigEl = document.getElementById('rig');
const gridSize = mazeData.length; 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.object3D.position.set(startWorldX, 0, startWorldZ);
console.log(`Player start position set to: X=${startWorldX}, Z=${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);
}
console.log(`${numberOfSpheres} spheres created around the maze.`);
}
});
</script>
</a-scene>
</body>
</html>


使用変数

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