Skip to content

Commit

Permalink
feat: ✨ Added automatic generation of obstacles using Perlin Noise.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmnorheim committed Aug 9, 2024
1 parent 2a65967 commit fb678ff
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 6 deletions.
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@fremtind/jkl-tooltip-react": "^4.2.21",
"@preact/signals-react": "^1.3.6",
"axios": "^1.6.3",
"noisejs": "^2.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/components/mapGrid/MapGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ import { signal } from "@preact/signals-react";
export const tiles = signal<Node[]>([]);

const MapGrid = () => {
const maxNumOfColumns = 80; // Maximum number of columns
const maxHeight = 45;
const numOfColumns = mapSizeSliderSignal.value; // Get the current size of the grid
const height = Math.round(numOfColumns * (9 / 16)); // Set aspect ratio of grid to 16:9
console.log("Height = ", height);
const tileWidth = 80 / numOfColumns; // 80 is the width of the grid container
const tileHeight = 80 / height; // 80 is the height of the grid container

Expand All @@ -33,8 +36,8 @@ const MapGrid = () => {
if (tiles.value.length === 0) {
// Initialize the tiles array with all possible tiles
const newTiles: Node[] = [];
for (let row = 0; row < height; row++) {
for (let col = 0; col < numOfColumns; col++) {
for (let row = 0; row < maxHeight; row++) {
for (let col = 0; col < maxNumOfColumns; col++) {
newTiles.push({ x: row, y: col, weight: 0 });
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.generate-obstacles-buttons-container {
display: flex;
flex-direction: column;
margin-top: 24px;
gap: 16px;
}
50 changes: 50 additions & 0 deletions frontend/src/generateObstacleButtons/GenerateObstacleButtons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */
import React from "react";
import DefaultButton from "../components/defaultButton/DefaultButton";
import { Noise } from "noisejs";
import "./GenerateObstacleButtons.css";
import { tiles } from "../components/mapGrid/MapGrid";
import { mapSizeSliderSignal } from "../pages/homePage/HomePage";

type NoiseType = {
perlin2(x: number, y: number): number;
};

const GenerateObstacleButtons: React.FC = () => {
const handleGenerateObstacles = () => {
const noise = new Noise(Math.random()) as NoiseType;

const numOfColumns = mapSizeSliderSignal.value; // Get the current number of columns from the slider
const height = Math.round(numOfColumns * (9 / 16)); // Set aspect ratio of grid to 16:9

const scale = 0.2; // Adjust the scale to control the frequency of obstacles

// Only modify the tiles that are within the viewable grid (based on the current mapSizeSliderSignal-value)
tiles.value = tiles.value.map((tile) => {
if (tile.x < height && tile.y < numOfColumns) {
const noiseValue = noise.perlin2(tile.x * scale, tile.y * scale);
const isObstacle = noiseValue > 0.1 ? 1 : 0; // Adjust threshold as needed
return { ...tile, weight: isObstacle };
}
return tile; // Leave tiles outside the viewable area unchanged
});

console.log("Generated obstacles");
};

const handleGenerateMaze = () => {
console.log("Generated maze");
};

return (
<div className="generate-obstacles-buttons-container">
<DefaultButton
text={"Generate obstacles"}
onClick={handleGenerateObstacles}
/>
<DefaultButton text={"Generate maze"} onClick={handleGenerateMaze} />
</div>
);
};

export default GenerateObstacleButtons;
4 changes: 2 additions & 2 deletions frontend/src/pages/homePage/HomePage.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@
margin-top: 16px;
}

.generate-obstacles-buttons-container {
/* .generate-obstacles-buttons-container {
display: flex;
flex-direction: column;
margin-top: 24px;
gap: 16px;
}
} */

.text-fields-container-homepage {
width: 268px;
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/pages/homePage/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import "./HomePage.css";
import DefaultButton from "../../components/defaultButton/DefaultButton";
import StartButton from "../../components/startButton/StartButton";
import AlgorithmStepSlider from "../../components/algorithmStepSlider/AlgorithmStepSlider";
import GenerateObstacleButtons from "../../generateObstacleButtons/GenerateObstacleButtons";

export const mapSizeSliderSignal = signal<number>(50);
export const algorithmStepSliderSignal = signal<number>(0);
Expand Down Expand Up @@ -64,13 +65,14 @@ const HomePage = () => {
<div className="map-size-slider-container-homepage">
<MapSizeSlider />
</div>
<div className="generate-obstacles-buttons-container">
{/* <div className="generate-obstacles-buttons-container">
<DefaultButton
text={"Generate obstacles"}
onClick={handleGenerateObstacles}
/>
<DefaultButton text={"Generate maze"} onClick={handleGenerateMaze} />
</div>
</div> */}
<GenerateObstacleButtons />
<div className="text-fields-container-homepage">
<TextFieldAndButton text={"Place obstacles"} />
<TextFieldAndButton text={"Select animation speed"} />
Expand Down

0 comments on commit fb678ff

Please sign in to comment.