first commit

This commit is contained in:
2024-04-27 14:46:59 -07:00
commit 98f57d50bd
6 changed files with 445 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
# What is this?
This is a procedurally-generated game that can run right in your browser!
Created by ION606
+17
View File
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ProcGen Mark I</title>
<link rel="stylesheet" type="text/css" href="/styles/style.css">
<script src="/scripts/init.js"></script>
<script src="/scripts/player.js"></script>
</head>
<body>
<button class="hidebtn" onclick="reset()">🗑</button>
<main class="dispGrid">
</main>
</body>
</html>
+93
View File
@@ -0,0 +1,93 @@
const MACROS = {
TILE_SIZE: 80,
COLORS: ['red', 'orange', 'yellow', 'green', 'blue', 'purple', 'white',' black'],
}
class Coordinates {
/**
* @param {Number} x
* @param {Number} y
*/
constructor(x, y) {this.x = x; this.y = y;}
}
const getRandInRange = (boundUpper, boundLower = 0, asFloat = true) => {
const ogNum = (Math.random() * (boundUpper - boundLower)) + boundLower;
return (asFloat) ? ogNum : Math.floor(ogNum);
}
const inRange = (x, min, max) => (x >= min && x <= max);
window.addEventListener("DOMContentLoaded", () => {
if (!localStorage.getItem('seed')) localStorage.setItem('seed', Math.round(Date.now() * Math.random()));
MACROS.seed = Number(localStorage.getItem('seed'));
MACROS.numTiles = [Math.floor((window.innerWidth) / MACROS.TILE_SIZE),Math.floor((window.innerHeight) / MACROS.TILE_SIZE)];
// create the grid
for (let i = 0; i < MACROS.numTiles[1]; i++) {
const row = document.createElement('div');
row.className = 'gridRow';
row.style.columnCount = MACROS.numTiles[0];
for (let j = 0; j < MACROS.numTiles[0]; j++) {
// const bkcol = MACROS.COLORS[getRandInRange(MACROS.COLORS.length, 0, false)];
const colBox = document.createElement('div');
colBox.className = "colBox";
// colBox.innerText = bkcol;
colBox.style.backgroundColor = 'black';
colBox.style.width = `${MACROS.TILE_SIZE}px`;
colBox.style.height = `${MACROS.TILE_SIZE}px`;
row.appendChild(colBox);
}
document.getElementsByTagName('main')[0].appendChild(row);
}
// setInterval(() => {
// const x = genRandInRange(0, window.screenX),
// y = genRandInRange(0, window.screenY);
// console.log(x, y)
// }, 1000)
});
/**
* RANDOM, NOT OPTIMIZED
* @param {[Number, Number]} startCoords
* @param {[Number, Number]} endCoords
*/
function makePath(startCoords, endCoords) {
const main = document.getElementsByTagName('main')[0];
const w = main.children.length,
h = main.children[0].children.length;
let [x, y] = startCoords;
let [ex, ey] = endCoords;
while (x != ex && y != ey) {
const dir = Math.floor(Math.random() * 4);
if (dir == 0 && y - 1 >= 0) y -= 1;
else if (dir == 1 && y + 1 < MACROS.numTiles[1]) y += 1;
else if (dir == 2 && x - 1 >= 0) x -= 1;
else if (dir == 3 && x + 1 < MACROS.numTiles[0]) x += 1;
const currentTile = main.children[y].children[x];
currentTile.style.backgroundColor = 'white';
}
}
function putTrees() {
const main = document.getElementsByTagName('main')[0];
const numTreesOnScreen = Math.round(getRandInRange(MACROS.numTiles[1])/1.5);
for (let i = 0; i < numTreesOnScreen; i++) {
const [x, y] = Math.floor(MACROS.numTiles * Math.random())
const currentTile = main.children[y].children[x];
currentTile.style.backgroundColor = 'white';
}
}
+225
View File
@@ -0,0 +1,225 @@
const MACROS = {
TILE_SIZE: 30,
COLORS: ['red', 'orange', 'yellow', 'green', 'blue', 'purple', 'white', 'black'],
ROOM_MIN_SIZE: 3,
ROOM_MAX_SIZE: 6,
HALLWAY_WIDTH: 1
};
const inRange = (x, min, max) => (x >= min && x <= max);
window.addEventListener("DOMContentLoaded", () => {
if (!localStorage.getItem('seed')) {
localStorage.setItem('seed', Math.round(Date.now() * Math.random()));
}
MACROS.seed = Number(localStorage.getItem('seed'));
MACROS.numTiles = [Math.floor(window.innerWidth / MACROS.TILE_SIZE), Math.floor(window.innerHeight / MACROS.TILE_SIZE)];
const r = loadMap();
if (r) return;
const main = document.querySelector('main.dispGrid');
// create the grid
for (let i = 0; i < MACROS.numTiles[1]; i++) {
const row = document.createElement('div');
row.className = 'gridRow';
row.style.columnCount = MACROS.numTiles[0];
for (let j = 0; j < MACROS.numTiles[0]; j++) {
// const bkcol = MACROS.COLORS[getRandInRange(MACROS.COLORS.length, 0, false)];
const colBox = document.createElement('div');
colBox.className = "colBox";
// colBox.innerText = bkcol;
colBox.style.width = `${MACROS.TILE_SIZE}px`;
colBox.style.height = `${MACROS.TILE_SIZE}px`;
row.appendChild(colBox);
}
main.appendChild(row);
}
generateMap(); // Call the map generation after grid initialization
});
function generateRooms() {
const main = document.querySelector('main.dispGrid');
// idk make one for every 20 tiles
const numRoomsRaw = (MACROS.numTiles[0] / 20) > 1 ? Math.round((MACROS.numTiles[0] / 10)) : 2;
const numRooms = getRandInRange(numRoomsRaw, 2, false);
let rooms = [];
for (let i = 0; i < numRooms; i++) {
const roomWidth = getRandInRange(MACROS.ROOM_MAX_SIZE, MACROS.ROOM_MIN_SIZE, false),
roomHeight = getRandInRange(MACROS.ROOM_MAX_SIZE, MACROS.ROOM_MIN_SIZE, false),
x = getRandInRange(MACROS.numTiles[0] - roomWidth, 0, false),
y = getRandInRange(MACROS.numTiles[1] - roomHeight, 0, false);
rooms.push({ x, y, width: roomWidth, height: roomHeight });
for (let ry = y; ry < y + roomHeight; ry++) {
for (let rx = x; rx < x + roomWidth; rx++) {
main.children[ry].children[rx].classList.add('room');
}
}
}
return rooms;
}
/** will return the coords of the end of the path */
function drawLineToRoom(x1, y1, x2, y2) {
let xret = x1, yret = y1;
const main = document.querySelector('main.dispGrid');
// Connect horizontally from room1 to room2
while (x1 !== x2) {
if (main.children[y1]?.children[x1]) {
main.children[y1].children[x1].classList.add('path');
xret = x1;
}
x1 += (x2 > x1) ? 1 : -1; // Increment or decrement to move towards x2
}
// Once x1 is aligned with x2, connect vertically
while (y1 !== y2) {
if (main.children[y1]?.children[x1]) {
main.children[y1].children[x1].classList.add('path');
yret = y1;
}
y1 += (y2 > y1) ? 1 : -1; // Increment or decrement to move towards y2
}
return {x: xret, y: yret};
}
function getRandomEdgePoint() {
const width = window.innerWidth;
const height = window.innerHeight;
let x, y;
// Choose a random edge: 0 = top, 1 = right, 2 = bottom, 3 = left
const edge = Math.floor(Math.random() * 4);
console.log(edge);
switch (edge) {
case 0: // Top edge
x = Math.random() * width;
y = 0;
break;
case 1: // Right edge
x = width;
y = Math.random() * height;
break;
case 2: // Bottom edge
x = Math.random() * width;
y = height;
break;
case 3: // Left edge
x = 0;
y = Math.random() * height;
break;
}
return { x: Math.round(x), y: Math.round(y) };
}
const calculateDistance = (point1, point2) => Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
function findClosestRoom(edgePoint, rooms) {
let closestRoom = null;
let minDistance = Infinity;
rooms.forEach(room => {
const roomCenter = {
x: room.x + room.width / 2,
y: room.y + room.height / 2
};
const distance = calculateDistance(edgePoint, roomCenter);
if (distance < minDistance) {
minDistance = distance;
closestRoom = room;
}
});
return closestRoom;
}
function connectRooms(room1, room2) {
let x1 = room1.x + Math.floor(room1.width / 2);
let y1 = room1.y + Math.floor(room1.height / 2);
let x2 = room2.x + Math.floor(room2.width / 2);
let y2 = room2.y + Math.floor(room2.height / 2);
drawLineToRoom(x1, y1, x2, y2);
}
const saveMap = () => {
localStorage.setItem('savedMap', document.querySelector('main.dispGrid').innerHTML);
}
const loadMap = () => {
const htmlToLoad = localStorage.getItem('savedMap');
if (htmlToLoad) {
document.querySelector('main.dispGrid').innerHTML = htmlToLoad;
return true;
}
return false;
}
function reset(player = false) {
localStorage.clear();
if (player) player.save();
window.location.reload();
}
function generateMap() {
const rooms = generateRooms();
for (let i = 0; i < rooms.length - 1; i++) {
connectRooms(rooms[i], rooms[i + 1]);
}
if (!localStorage.getItem('outerEdges')) {
const outerEdges = [];
const rToEMax = Math.round(Math.random() * rooms.length);
for (let i = 0; i < getRandInRange(rToEMax > 2 ? rToEMax : 2, 2, false); i++) {
const {x, y} = getRandomEdgePoint();
// Find the closest room to this edge point
const closestRoom = findClosestRoom({x, y}, rooms);
// Draw a line from the edge point to the center of the closest room
outerEdges.push(drawLineToRoom(closestRoom.x, closestRoom.y, x, y));
}
localStorage.setItem('outerEdges', JSON.stringify(outerEdges));
}
const edges = JSON.parse(localStorage.getItem('outerEdges'));
const main = document.querySelector('main.dispGrid');
for (const edge of edges) {
main.children[edge.y].children[edge.x].classList.add('edgePath');
}
const edge = edges[getRandInRange(edges.length - 1, 0, false)];
const player = new Player(edge.x, edge.y);
player.save();
saveMap();
}
function getRandInRange(upper, lower = 0, asFloat = true) {
const num = Math.random() * (upper - lower) + lower;
return asFloat ? num : Math.floor(num);
}
+44
View File
@@ -0,0 +1,44 @@
class Player {
constructor(startx, starty) {
this.mainEl = document.querySelector('main.dispGrid');
this.x = startx;
this.y = starty;
this.mainEl.children[this.y].children[this.x].classList.add("player");
this.setupEventListeners();
}
save() {
const {...object} = this;
delete object['x'];
delete object['y'];
localStorage.setItem('player', JSON.stringify(object));
}
moveTo(newX, newY) {
const square = this.mainEl.children[newY]?.children[newX];
if (square?.classList?.contains('room')) {
// for now, just move through it
this.mainEl.children[this.y].children[this.x].classList.remove('player');
square.classList.add('player');
this.x = newX;
this.y = newY;
}
else if (square?.classList?.contains('edgePath')) reset(this);
else if (square?.classList?.contains('path')) {
this.mainEl.children[this.y].children[this.x].classList.remove('player');
square.classList.add('player');
this.x = newX;
this.y = newY;
}
}
setupEventListeners() {
document.addEventListener('keydown', (e) => {
if (e.key === 'w') this.moveTo(this.x, this.y - 1);
else if (e.key === 'a') this.moveTo(this.x - 1, this.y);
else if (e.key === 's') this.moveTo(this.x, this.y + 1);
else if (e.key === 'd') this.moveTo(this.x + 1, this.y);
});
}
}
+62
View File
@@ -0,0 +1,62 @@
body {
background-color: black;
margin: 0;
}
main {
margin: 0;
text-align: center;
}
.gridRow {
display: flex;
}
.colBox {
background-color: black;
}
.dispGrid {
display: grid;
gap: 0px;
padding: 0;
margin: 0;
}
.room {
background-color: white !important;
}
.path {
background-color: grey;
}
.edgePath {
background-color: blue;
}
.player {
background-color: red !important;
}
.hidebtn {
opacity: 0;
position: absolute;
top: 10px;
left: 10px;
z-index: 999;
font-size: 30px;
width: 35px;
height: 35px;
background-color: transparent;
color: red;
border: none;
padding: auto;
text-align: center;
cursor: pointer;
}
.hidebtn:hover {
opacity: 1;
}