Skip to content

Instantly share code, notes, and snippets.

@primaryobjects
Last active December 9, 2023 02:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save primaryobjects/8fb9214ade94704a46057c4b8ba542e9 to your computer and use it in GitHub Desktop.
Save primaryobjects/8fb9214ade94704a46057c4b8ba542e9 to your computer and use it in GitHub Desktop.
Creating a random 3D maze with WebGL and three.js along with ChatGPT4 on Bing https://3D-Maze.primaryobjects.repl.co
<!DOCTYPE html>
<html>
<head>
<title>3D Maze with GPT4</title>
<link rel="stylesheet" href="style.css">
<script src="https://code.jquery.com/jquery-3.6.4.slim.min.js" integrity="sha256-a2yjHM4jnF9f54xUQakjZGaqYs/V1CYvWpoqZzC2/Bw=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>
<script src="script.js"></script>
</head>
<body>
<canvas id="canvas" width="100%" height="100%"></canvas>
<div id="controls">
<button id="up-arrow">Up</button>
<br>
<button id="left-arrow">Left</button>
<button id="right-arrow">Right</button>
<br>
<button id="down-arrow">Down</button>
</div>
</body>
</html>
//create a scene
const scene = new THREE.Scene();
//create a camera
const camera = new THREE.PerspectiveCamera(
90,
window.innerWidth / window.innerHeight,
0.1,
500
);
camera.position.z = 5;
//create the first object
const geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({
color: 0xfffff,
wireframe: false,
});
var cube = new THREE.Mesh(geometry, material);
//add the first object to scene
scene.add(cube);
//create the second object
const geometry2 = new THREE.BoxGeometry(1, 1, 1);
var material2 = new THREE.MeshBasicMaterial({
color: 'red',
wireframe: false,
});
var cube2 = new THREE.Mesh(geometry2, material2);
cube2.position.x = 2;
//add the second object to scene
scene.add(cube2);
//create the maze
const mazeGeometry = new THREE.BoxGeometry(0.5, 0.5, 0.5);
// Load texture for maze blocks
const loader = new THREE.TextureLoader();
const textures = [
loader.load('block1.jpg'),
loader.load('block2.jpg'),
loader.load('block3.jpg')
];
// Maze generation using depth-first search algorithm
const mazeSize = 10;
let maze = new Array(mazeSize);
for (let i = 0; i < mazeSize; i++) {
maze[i] = new Array(mazeSize).fill(1);
}
let stack = [];
let visitedCells = 1;
let totalCells = ((mazeSize - 1) / 2) ** 2;
let currentCell = [1,1];
while (visitedCells < totalCells) {
let possibleDirections = [];
if (currentCell[0] + 2 < mazeSize - 1 && maze[currentCell[0] + 2][currentCell[1]] === 1) {
possibleDirections.push('S');
}
if (currentCell[0] - 2 > 0 && maze[currentCell[0] - 2][currentCell[1]] === 1) {
possibleDirections.push('N');
}
if (currentCell[1] + 2 < mazeSize - 1 && maze[currentCell[0]][currentCell[1] + 2] === 1) {
possibleDirections.push('E');
}
if (currentCell[1] - 2 > 0 && maze[currentCell[0]][currentCell[1] - 2] === 1) {
possibleDirections.push('W');
}
if (possibleDirections.length > 0) {
let direction = possibleDirections[Math.floor(Math.random() * possibleDirections.length)];
switch(direction) {
case 'N':
maze[currentCell[0] - 2][currentCell[1]] = 0;
maze[currentCell[0] - 1][currentCell[1]] = 0;
currentCell[0] -= 2;
break;
case 'S':
maze[currentCell[0] + 2][currentCell[1]] = 0;
maze[currentCell[0] + 1][currentCell[1]] = 0;
currentCell[0] += 2;
break;
case 'W':
maze[currentCell[0]][currentCell[1] - 2] = 0;
maze[currentCell[0]][currentCell[1] - 1] = 0;
currentCell[1] -= 2;
break;
case 'E':
maze[currentCell[0]][currentCell[1] + 2] = 0;
maze[currentCell[0]][currentCell[1] + 1] = 0;
currentCell[1] += 2;
break;
}
visitedCells++;
stack.push(currentCell.slice());
} else {
if (stack.length < 1) {
break;
}
else {
currentCell = stack.pop();
}
}
}
/*maze = [
[1,1,1,1,1],
[1,0,0,0,1],
[1,0,1,0,1],
[1,0,0,0,1],
[1,1,1,1,1]
];*/
const mazeBlocks = [];
for (let i = 0; i < maze.length; i++) {
for (let j = 0; j < maze[i].length; j++) {
if (maze[i][j] === 1) {
const r = Math.floor(Math.random() * 3);
const mazeMaterial = new THREE.MeshBasicMaterial({
map: textures[r],
});
const block = new THREE.Mesh(mazeGeometry, mazeMaterial);
block.position.set(i - 2.5 , j - 2.5 , -2);
mazeBlocks.push(block);
scene.add(block);
}
}
}
//create renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
// Create an object to keep track of which keys are pressed
const keysPressed = {
ArrowLeft: false,
ArrowRight: false,
ArrowUp: false,
ArrowDown: false
};
//animation loop
const animate = () => {
requestAnimationFrame(animate);
cube.rotation.y += 0.01;
cube.rotation.x += 0.02;
cube2.rotation.y += 0.01;
cube2.rotation.x += 0.02;
// Move the maze blocks
for (let block of mazeBlocks) {
block.position.z += 0.01;
if (block.position.z > 5) {
block.position.z = -5;
}
}
// Update camera position based on keys pressed
if (keysPressed.ArrowLeft) {
camera.position.x -= 0.1;
}
if (keysPressed.ArrowRight) {
camera.position.x += 0.1;
}
if (keysPressed.ArrowUp) {
camera.position.y += 0.1;
}
if (keysPressed.ArrowDown) {
camera.position.y -= 0.1;
}
renderer.render(scene, camera);
};
animate();
$(function() {
$('body').append(renderer.domElement);
// Add event listeners for keydown and keyup events
document.addEventListener('keydown', (event) => {
if (event.key in keysPressed) {
keysPressed[event.key] = true;
}
});
document.addEventListener('keyup', (event) => {
if (event.key in keysPressed) {
keysPressed[event.key] = false;
}
});
window.addEventListener("keydown", function(e) {
if(["Space","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].indexOf(e.code) > -1) {
e.preventDefault();
}
}, false);
const leftArrow = document.getElementById('left-arrow');
const rightArrow = document.getElementById('right-arrow');
const upArrow = document.getElementById('up-arrow');
const downArrow = document.getElementById('down-arrow');
leftArrow.addEventListener('touchstart', () => {
keysPressed.ArrowLeft = true;
});
leftArrow.addEventListener('touchend', () => {
keysPressed.ArrowLeft = false;
});
leftArrow.addEventListener('mousedown', () => {
keysPressed.ArrowLeft = true;
});
leftArrow.addEventListener('mouseup', () => {
keysPressed.ArrowLeft = false;
});
rightArrow.addEventListener('touchstart', () => {
keysPressed.ArrowRight = true;
});
rightArrow.addEventListener('touchend', () => {
keysPressed.ArrowRight = false;
});
rightArrow.addEventListener('mousedown', () => {
keysPressed.ArrowRight = true;
});
rightArrow.addEventListener('mouseup', () => {
keysPressed.ArrowRight = false;
});
upArrow.addEventListener('touchstart', () => {
keysPressed.ArrowUp = true;
});
upArrow.addEventListener('touchend', () => {
keysPressed.ArrowUp = false;
});
upArrow.addEventListener('mousedown', () => {
keysPressed.ArrowUp = true;
});
upArrow.addEventListener('mouseup', () => {
keysPressed.ArrowUp = false;
});
downArrow.addEventListener('touchstart', () => {
keysPressed.ArrowDown = true;
});
downArrow.addEventListener('touchend', () => {
keysPressed.ArrowDown = false;
});
downArrow.addEventListener('mousedown', () => {
keysPressed.ArrowDown = true;
});
downArrow.addEventListener('mouseup', () => {
keysPressed.ArrowDown = false;
});
});
body {
overflow: hidden;
position: relative;
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Old versions of Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently supported by Chrome, Opera and Firefox */
}
#controls {
position: absolute;
bottom: 15%;
left: 15%;
z-index: 1;
}
button {
width: 150px;
height: 150px;
background-color: rgba(255, 255, 255, 0.1); /* change the color and opacity as desired */
color: white;
font-size: 30px;
}
#up-arrow, #down-arrow {
margin-left: 70px;
}
#container {
position: relative;
}
@primaryobjects
Copy link
Author

cap

@Kelvinlinus7
Copy link

Why is the report

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment