diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000000..6f3a2913e1
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "liveServer.settings.port": 5501
+}
\ No newline at end of file
diff --git a/Games/Five_Nights_at_Freddys/README.md b/Games/Five_Nights_at_Freddys/README.md
new file mode 100644
index 0000000000..19020b10f3
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/README.md
@@ -0,0 +1,21 @@
+
+## Installation
+
+First you need to clone this repository
+
+
+
+Then start it using npm or yarn
+
+```
+npm install --legacy-peer-deps
+```
+
+Then start localhost
+
+```
+npm start
+```
+
+
+
diff --git a/Games/Five_Nights_at_Freddys/package.json b/Games/Five_Nights_at_Freddys/package.json
new file mode 100644
index 0000000000..58dd587382
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/package.json
@@ -0,0 +1,41 @@
+{
+ "name": "fnaf",
+ "version": "0.1.0",
+ "private": true,
+ "dependencies": {
+ "@testing-library/jest-dom": "^4.2.4",
+ "@testing-library/react": "^9.3.2",
+ "@testing-library/user-event": "^7.1.2",
+ "gh-pages": "^3.2.3",
+ "global": "^4.4.0",
+ "react": "^16.14.0",
+ "react-dom": "^16.14.0",
+ "react-image-mapper": "^1.0.0",
+ "react-redux": "^7.2.2",
+ "react-scripts": "3.4.1",
+ "redux": "^4.0.5"
+ },
+ "scripts": {
+ "predeploy": "npm run build",
+ "deploy": "gh-pages -d build",
+ "start": "react-scripts --openssl-legacy-provider start",
+ "build": "react-scripts --openssl-legacy-provider build",
+ "test": "react-scripts --openssl-legacy-provider test",
+ "eject": "react-scripts eject"
+ },
+ "eslintConfig": {
+ "extends": "react-app"
+ },
+ "browserslist": {
+ "production": [
+ ">0.2%",
+ "not dead",
+ "not op_mini all"
+ ],
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ]
+ }
+}
diff --git a/Games/Five_Nights_at_Freddys/public/favicon.ico b/Games/Five_Nights_at_Freddys/public/favicon.ico
new file mode 100644
index 0000000000..ff6fe84ae0
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/public/favicon.ico differ
diff --git a/Games/Five_Nights_at_Freddys/public/icon-192x192.png b/Games/Five_Nights_at_Freddys/public/icon-192x192.png
new file mode 100644
index 0000000000..e19126b24f
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/public/icon-192x192.png differ
diff --git a/Games/Five_Nights_at_Freddys/public/icon-256x256.png b/Games/Five_Nights_at_Freddys/public/icon-256x256.png
new file mode 100644
index 0000000000..09c214af4e
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/public/icon-256x256.png differ
diff --git a/Games/Five_Nights_at_Freddys/public/icon-384x384.png b/Games/Five_Nights_at_Freddys/public/icon-384x384.png
new file mode 100644
index 0000000000..66cb397ef3
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/public/icon-384x384.png differ
diff --git a/Games/Five_Nights_at_Freddys/public/icon-512x512.png b/Games/Five_Nights_at_Freddys/public/icon-512x512.png
new file mode 100644
index 0000000000..a6fde2166c
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/public/icon-512x512.png differ
diff --git a/Games/Five_Nights_at_Freddys/public/index.html b/Games/Five_Nights_at_Freddys/public/index.html
new file mode 100644
index 0000000000..cad6906ddc
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/public/index.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Five Nights at Freddy's Web
+
+
+
+
+
+
+
+
+
+
diff --git a/Games/Five_Nights_at_Freddys/public/manifest.json b/Games/Five_Nights_at_Freddys/public/manifest.json
new file mode 100644
index 0000000000..e7f492cebb
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/public/manifest.json
@@ -0,0 +1,37 @@
+{
+ "theme_color": "#000000",
+ "background_color": "#000000",
+ "display": "fullscreen",
+
+ "name": "Five Nights at Freddy's Web",
+ "short_name": "FNAF Web",
+ "description": "A web version of the popular game Five Nights at Freddy's",
+ "orientation": "landscape",
+ "icons": [
+ {
+ "src": "favicon.ico",
+ "sizes": "64x64 32x32 24x24 16x16",
+ "type": "image/x-icon"
+ },
+ {
+ "src": "/icon-192x192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ },
+ {
+ "src": "/icon-256x256.png",
+ "sizes": "256x256",
+ "type": "image/png"
+ },
+ {
+ "src": "/icon-384x384.png",
+ "sizes": "384x384",
+ "type": "image/png"
+ },
+ {
+ "src": "/icon-512x512.png",
+ "sizes": "512x512",
+ "type": "image/png"
+ }
+ ]
+}
diff --git a/Games/Five_Nights_at_Freddys/public/robots.txt b/Games/Five_Nights_at_Freddys/public/robots.txt
new file mode 100644
index 0000000000..e9e57dc4d4
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/public/robots.txt
@@ -0,0 +1,3 @@
+# https://www.robotstxt.org/robotstxt.html
+User-agent: *
+Disallow:
diff --git a/Games/Five_Nights_at_Freddys/src/Controller.js b/Games/Five_Nights_at_Freddys/src/Controller.js
new file mode 100644
index 0000000000..0bf8ac8174
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/Controller.js
@@ -0,0 +1,135 @@
+import React, { useState, useEffect } from "react";
+import BlackoutSound from "./media/Sounds/powerdown.mp3";
+import { connect } from "react-redux";
+import Game from "./Game";
+
+import StaticImage from "./media/Textures/Static-Cam.webp";
+import StaticSound from "./media/Sounds/Dead.mp3";
+import VictoryGIF from "./media/Textures/Victory.gif";
+import VictorySound from "./media/Sounds/Clock.mp3";
+
+///89000
+const TIME_TO_CHANGE_HOUR = 89000;
+
+let gameOverAudio = new Audio(StaticSound);
+let hourInterval = null;
+
+function Controller({
+ isPlaying,
+ hour,
+ time,
+ energy,
+ jumpscare,
+ setStart,
+ dispatch,
+ stages,
+}) {
+ const [gameOver, setGameOver] = useState(false);
+ const [victory, setVictory] = useState(false);
+
+
+ useEffect(() => {
+ dispatch({ type: "CLEAR_DATA" });
+ changeEnergy();
+
+ return () => {
+ // clearInterval(hourInterval);
+ dispatch({ type: "CLEAR_DATA" });
+ gameOverAudio.pause();
+ };
+ }, []);
+
+ useEffect(() => {
+ setTimeout(() => {
+ if (hour === 5 && !gameOver) endGame(true);
+ else changeHour(hour);
+ }, TIME_TO_CHANGE_HOUR);
+ }, [hour])
+
+ useEffect(() => {
+ if (energy <= 0) {
+ setBlackout();
+ } else changeEnergy(energy);
+ }, [energy]);
+
+ async function changeHour(h) {
+ if (isPlaying && !jumpscare && !gameOver && h < 6) {
+ dispatch({ type: "CHANGE_HOUR" });
+ }
+ }
+
+ async function changeEnergy(e) {
+ if (isPlaying && !gameOver && e > 0) {
+ setTimeout(() => {
+ dispatch({ type: "CHANGE_ENERGY" });
+ }, time);
+ }
+ }
+
+ const setBlackout = () => {
+ new Audio(BlackoutSound).play();
+
+ dispatch({ type: "FORCE_CAMERA_CLOSE" });
+ dispatch({ type: "CHANGE_CAMERA_BUTTON" });
+ };
+
+ const endGame = (hasWon) => {
+ if (hasWon) {
+ setVictory(true);
+ let VictoryMusic = new Audio(VictorySound);
+ VictoryMusic.play();
+
+ const victories = JSON.parse(localStorage.getItem("victories")) || {};
+ if(stages.mode !== "CUSTOM") victories[stages.mode] = "★"
+
+ localStorage.setItem("victories", JSON.stringify(victories));
+ } else {
+ setGameOver(true);
+ gameOverAudio.currentTime = 0;
+ gameOverAudio.play();
+ }
+ dispatch({ type: "SET_GAME_OVER" });
+ setTimeout(() => {
+ setStart(false);
+ }, 10000);
+ };
+
+ return (
+ <>
+ {gameOver ? (
+
+ ) : null}
+ {victory ? (
+
+
+
+ ) : null}
+
+ >
+ );
+}
+
+const mapStateToProps = (state) => {
+ return {
+ time: state.configReducer.time,
+ hour: state.configReducer.hour,
+ isPlaying: state.configReducer.isPlaying,
+ jumpscare: state.configReducer.jumpscare,
+ energy: state.configReducer.energy,
+ animatronics: state.animatronicsReducer,
+ };
+};
+
+export default connect(mapStateToProps)(Controller);
diff --git a/Games/Five_Nights_at_Freddys/src/CustomNight.js b/Games/Five_Nights_at_Freddys/src/CustomNight.js
new file mode 100644
index 0000000000..40c2a6be12
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/CustomNight.js
@@ -0,0 +1,161 @@
+import React from 'react';
+import styles from "./css/CustomNight.module.css"
+
+import Freddy from "./media/Textures/CustomNight/freddy.png";
+import Bonnie from "./media/Textures/CustomNight/bonnie.png";
+import Chica from "./media/Textures/CustomNight/chica.png";
+import Foxy from "./media/Textures/CustomNight/foxy.png";
+
+import goldenFreddyJumpscare from "./media/Sounds/golden_freddy.ogg";
+
+const images = {
+ Freddy,
+ Bonnie,
+ Chica,
+ Foxy
+}
+
+const AnimatronicContainer = (props) => {
+ const {range, changeRange, character} = props;
+
+ return (
+
+
+
+
+
+ {range}
+
+
+
+ )
+};
+
+const CustomNight = ({state, setStart}) => {
+ const [goldenFreddy, setGoldenFreddy] = React.useState(false);
+ const changeMode = (value) => {
+
+ let animatronics = {};
+
+ switch(value) {
+ case "EASY":
+ animatronics = {Bonnie: 2, Freddy: 2, Chica: 2, Foxy: 2};
+ break;
+ case "NORMAL":
+ animatronics = {Bonnie: 10, Freddy: 10, Chica: 10, Foxy: 10};
+ break;
+ case "HARD":
+ animatronics = {Bonnie: 15, Freddy: 15, Chica: 15, Foxy: 15};
+ break;
+ case "IMPOSSIBLE":
+ animatronics = {Bonnie: 20, Freddy: 20, Chica: 20, Foxy: 20};
+ break;
+ default:
+ return;
+ }
+
+ state.setStages((stages) => ({...animatronics, mode: value}));
+ };
+
+ const changeRange = (value, character) => {
+ const handleValue = (state, value) =>
+ (state === 0 && value < 0) || (state === 20 && value > 0) ? state : state + value
+
+
+ state.setStages((stages) => ({...stages, mode: "CUSTOM", [character]: handleValue(stages[character], value)}));
+ }
+
+ const hasWon = (mode) => {
+ const victories = JSON.parse(localStorage.getItem("victories")) || {};
+
+ return victories[mode] || " ";
+ }
+
+ const handleStart = () => {
+ if (
+ state.ranges.Freddy === 1 &&
+ state.ranges.Bonnie === 9 &&
+ state.ranges.Chica === 8 &&
+ state.ranges.Foxy === 7
+ ) {
+ const golden = new Audio(goldenFreddyJumpscare);
+ golden.play();
+ return setGoldenFreddy(true);
+ }
+ setStart(true);
+ }
+
+ if(goldenFreddy) return ;
+
+ return (
+
+
+
+
+
+
+
{"Five Nights at Freddy's Web"}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+};
+
+export default CustomNight;
+
+function GoldenFreddy({setGoldenFreddy}) {
+ React.useEffect(() => {
+ setTimeout(() => {
+ window.open("about:blank", "_self");
+ window.close();
+ setGoldenFreddy(false);
+ }, 5000);
+ }, [])
+
+ return
+}
\ No newline at end of file
diff --git a/Games/Five_Nights_at_Freddys/src/Game.js b/Games/Five_Nights_at_Freddys/src/Game.js
new file mode 100644
index 0000000000..10d80d2a5c
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/Game.js
@@ -0,0 +1,125 @@
+import React, { useEffect } from "react";
+import { connect } from "react-redux";
+
+import Animatronic from "./components/Animatronic";
+import Office from "./components/Office";
+import Camera from "./components/Camera";
+import Hud from "./components/Hud";
+import Media from "./components/Media";
+
+let isBlackout = false;
+
+let { Ambience } = Media.Sounds;
+Ambience.loop = true;
+
+let officeProps = { leftDoor: false, rightDoor: false };
+
+const Game = ({
+ office,
+ isCameraOpen,
+ energy,
+ gameOver,
+ stages,
+ endGame,
+ dispatch,
+}) => {
+ useEffect(() => {
+ Ambience.currentTime = 0;
+ Ambience.play();
+ isBlackout = false;
+ officeProps = { leftDoor: false, rightDoor: false };
+ }, []);
+
+ useEffect(() => {
+ if (gameOver) Ambience.pause();
+ }, [gameOver]);
+
+ useEffect(() => {
+ if (energy <= 0) {
+ isBlackout = true;
+ Ambience.pause();
+ }
+ }, [energy]);
+
+ useEffect(() => {
+ let newTime = 6300;
+ if (office.leftDoor) newTime -= 1100;
+ if (office.rightDoor) newTime -= 1100;
+ if (office.leftLight) newTime -= 500;
+ if (office.rightLight) newTime -= 500;
+ if (isCameraOpen) newTime -= 1100;
+
+ dispatch({ type: "CHANGE_TIME", content: newTime });
+ officeProps = {
+ leftDoor: office.leftDoor,
+ rightDoor: office.rightDoor,
+ };
+ }, [
+ office.leftDoor,
+ office.rightDoor,
+ office.leftLight,
+ office.rightLight,
+ isCameraOpen,
+ ]);
+
+ const handleJumpscare = (character) => {
+ if (isBlackout || gameOver) return;
+ dispatch({
+ type: "CHANGE_ANIMATRONIC",
+ animatronic: character,
+ animatronicState: {
+ door: null,
+ camera: null,
+ jumpscare: true,
+ },
+ });
+
+ dispatch({ type: "CHANGE_JUMPSCARE", animatronic: character });
+ if (character === "Foxy" || character === "Freddy")
+ dispatch({ type: "FORCE_CAMERA_CLOSE" });
+ setTimeout(() => {
+ if (!isCameraOpen) dispatch({ type: "FORCE_CAMERA_CLOSE" });
+ }, 10000);
+ };
+
+ async function isThisDoorOpen(door) {
+ const isDoorOpen = await officeProps[door];
+ return isDoorOpen;
+ }
+
+ return (
+ <>
+
+
+ {!gameOver ? (
+ <>
+ {energy <= 0 ? null : }
+
+ {isCameraOpen ? null : (
+
+ )}
+ >
+ ) : null}
+ >
+ );
+};
+
+const mapStateToProps = (state) => {
+ return {
+ animatronics: state.animatronicsReducer,
+ time: state.configReducer.time,
+ hour: state.configReducer.hour,
+ energy: state.configReducer.energy,
+ office: state.officeReducer,
+ camera: state.cameraReducer.camera,
+ isCameraOpen: state.cameraReducer.isCameraOpen,
+ };
+};
+
+export default connect(mapStateToProps)(Game);
diff --git a/Games/Five_Nights_at_Freddys/src/components/Animatronic.js b/Games/Five_Nights_at_Freddys/src/components/Animatronic.js
new file mode 100644
index 0000000000..60378f43cb
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/components/Animatronic.js
@@ -0,0 +1,229 @@
+import React, { useState, useEffect } from "react";
+import Functions from "./Functions";
+import Media from "./Media";
+import { connect } from "react-redux";
+
+let FreddyIterator = Functions.Freddy();
+let BonnieIterator = Functions.Bonnie();
+let ChicaIterator = Functions.Chica();
+let FoxyIterator = Functions.Foxy();
+
+FreddyIterator.next();
+
+let FreddyTime = 10000;
+let BonnieTime = 5000;
+let ChicaTime = 7300;
+let FoxyTime = 13000;
+
+const ranges = {
+ Freddy: 1,
+ Bonnie: 1,
+ Chica: 2,
+ Foxy: 1,
+}
+
+let isBlackout = false;
+let isGameOver = false;
+
+function Animatronic({
+ animatronics,
+ config,
+ handleJumpscare,
+ isThisDoorOpen,
+ dispatch,
+ stages
+}) {
+ const { hour, gameOver, blackout } = config;
+
+ useEffect(() => {
+ ranges["Freddy"] = stages.Freddy;
+ ranges["Bonnie"] = stages.Bonnie;
+ ranges["Chica"] = stages.Chica;
+ ranges["Foxy"] = stages.Foxy;
+
+ if(stages.Bonnie) willMove("Bonnie", BonnieIterator, BonnieTime);
+ if(stages.Chica) willMove("Chica", ChicaIterator, ChicaTime);
+ if(stages.Foxy) willMove("Foxy", FoxyIterator, FoxyTime, true);
+ if(stages.Freddy && stages.Chica && stages.Bonnie)willMove("Freddy", FreddyIterator, FreddyTime, true);
+
+ return () => {
+ FreddyIterator = Functions.Freddy();
+ BonnieIterator = Functions.Bonnie();
+ ChicaIterator = Functions.Chica();
+ FoxyIterator = Functions.Foxy();
+
+ FreddyIterator.next();
+
+ FreddyTime = 10000;
+ BonnieTime = 5000;
+ ChicaTime = 7300;
+ FoxyTime = 13000;
+ ranges["Freddy"] = stages.Freddy;
+ ranges["Bonnie"] = stages.Bonnie;
+ ranges["Chica"] = stages.Chica;
+ ranges["Foxy"] = stages.Foxy;
+
+ isBlackout = false;
+ isGameOver = false;
+ };
+ }, []);
+
+ useEffect(() => {
+ if (hour === 2) {
+ FreddyTime = 9500;
+ BonnieTime = 4700;
+ ChicaTime = 6800;
+ FoxyTime = 10000;
+
+
+ ranges["Bonnie"] = ranges["Bonnie"] + 1;
+ ranges["Chica"] = ranges["Chica"] + 1;
+ } else if (hour === 4) {
+ ranges["Bonnie"] = ranges["Bonnie"] + 2;
+ ranges["Chica"] = ranges["Chica"] + 2;
+ ranges["Freddy"] = ranges["Freddy"] + 1;
+ ranges["Foxy"] = ranges["Foxy"] + 1;
+ } else if (hour === 5) {
+ ranges["Bonnie"] = ranges["Bonnie"] + 2;
+ ranges["Chica"] = ranges["Chica"] + 2;
+ ranges["Freddy"] = ranges["Freddy"] + 2;
+ ranges["Foxy"] = ranges["Foxy"] + 2;
+ }
+ }, [hour]);
+
+ useEffect(() => {
+ if (gameOver) isGameOver = gameOver;
+ }, [gameOver]);
+
+ const changeAnimatronic = (func) => {
+ dispatch({ type: "CHANGE_ANIMATRONICS_MOVING", content: true });
+
+ func();
+
+ setTimeout(() => {
+ dispatch({
+ type: "CHANGE_ANIMATRONICS_MOVING",
+ content: false,
+ });
+ }, 1500);
+ };
+
+ const animatronicFailed = (character) => {
+ changeAnimatronic(() => {
+ dispatch({
+ type: "CHANGE_ANIMATRONIC",
+ animatronic: character,
+ animatronicState: {
+ door: false,
+ camera:
+ character === "Freddy"
+ ? "Stage"
+ : character === "Foxy"
+ ? ""
+ : "Dinning Area",
+ jumpscare: false,
+ },
+ });
+
+ if (character === "Bonnie") {
+ BonnieIterator = Functions.Bonnie();
+ willMove("Bonnie", BonnieIterator, BonnieTime);
+ } else if (character === "Chica") {
+ ChicaIterator = Functions.Chica();
+ willMove("Chica", ChicaIterator, ChicaTime);
+ } else if (character === "Foxy") {
+ FoxyIterator = Functions.Foxy();
+ Media.Sounds.FoxyPunch.play();
+ willMove("Foxy", FoxyIterator, FoxyTime, true);
+ } else if (character === "Freddy") {
+ FreddyIterator = Functions.Freddy();
+ FreddyIterator.next();
+ willMove("Freddy", FreddyIterator, FreddyTime, true);
+ }
+ });
+ };
+
+ const freddyLaugh = () => {
+ if (isBlackout) return;
+ let FreddyNumber = Math.floor(Math.random() * 2);
+ if (FreddyNumber == 0) {
+ Media.Sounds.FreddyLaugh1.play();
+ } else {
+ Media.Sounds.FreddyLaugh2.play();
+ }
+ };
+ useEffect(() => {
+ if (blackout) isBlackout = true;
+ }, [blackout]);
+
+ function willMove (character, iterator, animaTime) {
+ const thisInterval = setInterval(() => {
+ const max = character === "Bonnie" || character === "Chica" ? 22 : 30;
+ let luckyNumber = Math.floor(Math.random() * max);
+
+ let condition = luckyNumber < ranges[character] && !animatronics[character].door;
+
+ let newPlace;
+ if (condition) {
+ changeAnimatronic(() => {
+ newPlace = iterator.next().value;
+
+ const newState = {
+ door: newPlace === "Door" || newPlace === "_3",
+ jumpscare: false,
+ camera: newPlace,
+ };
+ dispatch({
+ type: "CHANGE_ANIMATRONIC",
+ animatronic: character,
+ animatronicState: newState,
+ });
+ });
+
+ if (character === "Freddy") freddyLaugh();
+ }
+
+ if (isBlackout || isGameOver) clearInterval(thisInterval);
+
+ if (newPlace === "Door" || newPlace === "_3") {
+ if (!isBlackout) checkDoors(character);
+ clearInterval(thisInterval);
+ }
+ }, animaTime);
+ };
+
+ async function checkDoors(character) {
+ const door =
+ character === "Bonnie" || character === "Foxy" ? "leftDoor" : "rightDoor";
+
+ setTimeout(async () => {
+ const isDoorOpen = await isThisDoorOpen(door);
+ if (!isDoorOpen) {
+ setTimeout(async () => {
+ const isDoorOpen = await isThisDoorOpen(door);
+ if (!isDoorOpen) {
+ setTimeout(async () => {
+ const isDoorOpen = await isThisDoorOpen(door);
+ if (!isDoorOpen) {
+ handleJumpscare(character);
+ } else animatronicFailed(character);
+ }, 3000);
+ } else animatronicFailed(character);
+ }, 5000);
+ } else animatronicFailed(character);
+ }, 10000);
+ }
+
+ return <>>;
+}
+
+const mapStateToProps = (state) => {
+ return {
+ leftDoor: state.officeReducer.leftDoor,
+ rightDoor: state.officeReducer.rightDoor,
+ animatronics: state.animatronicsReducer,
+ config: state.configReducer,
+ };
+};
+
+export default connect(mapStateToProps)(Animatronic);
diff --git a/Games/Five_Nights_at_Freddys/src/components/Camera.js b/Games/Five_Nights_at_Freddys/src/components/Camera.js
new file mode 100644
index 0000000000..2e2b36457d
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/components/Camera.js
@@ -0,0 +1,175 @@
+import React, { useState, useEffect, useRef } from "react";
+import { connect } from "react-redux";
+import getCam from "./Images";
+
+import AnimatronicsMoving from "../media/Sounds/garble1.mp3";
+import AnimatronicsMoving2 from "../media/Sounds/garble2.mp3";
+import Static from "../media/Textures/Static-Cam.webp";
+import Black from "../media/Textures/black.jpg";
+import Media from "./Media";
+
+import CameraMap from "../components/CameraMap";
+import CameraButton from "../components/CameraButton";
+
+function Camera({
+ animatronics,
+ areAnimatronicsMoving,
+ isCameraOpen,
+ office,
+ camera,
+ cameraButtonDisappear,
+ dispatch,
+}) {
+ const [Image, setImage] = useState(Media.Images.Stage);
+
+ const closeCameraRef = useRef(null);
+ const cameraDivRef = useRef(null);
+
+ const handleCameraButton = () => {
+ dispatch({ type: "SET_IS_OPEN" });
+ };
+
+ const handleCameraChange = (e) => {
+ e.preventDefault();
+ Media.Sounds.CameraChange.play();
+ dispatch({ type: "CHANGE_CAMERA", content: e.target.title });
+ };
+
+ useEffect(() => {
+ if (cameraDivRef.current) {
+ if (isCameraOpen)
+ setTimeout(() => {
+ cameraDivRef.current.style.display = "flex";
+ }, 350);
+ else
+ setTimeout(() => {
+ cameraDivRef.current.style.display = "none";
+ }, 100);
+ }
+ }, [isCameraOpen]);
+
+ useEffect(() => {
+ const { Bonnie, Chica, Freddy, Foxy } = animatronics;
+ let result = "";
+ if (Bonnie.camera === camera) result += "_b";
+ if (Chica.camera === camera) result += "_c";
+ if (Freddy.camera === camera) result += "_f";
+
+ const newCamera = getCam(result, camera, Foxy.camera);
+ setImage(newCamera);
+ }, [camera, animatronics, areAnimatronicsMoving, animatronics.Foxy.camera]);
+
+ useEffect(() => {
+ if (areAnimatronicsMoving && isCameraOpen) {
+ let MusicNumber = Math.floor(Math.random() * 2);
+ let Sound;
+ if (MusicNumber == 1 || MusicNumber == 2) {
+ Sound = new Audio(AnimatronicsMoving);
+ } else {
+ Sound = new Audio(AnimatronicsMoving2);
+ }
+ Sound.play();
+ }
+ }, [areAnimatronicsMoving]);
+
+ return (
+
+ {cameraButtonDisappear ? null : (
+
+ )}
+ {isCameraOpen ? (
+ <>
+
+
+
+ {areAnimatronicsMoving ? (
+
+ ) : (
+
+ )}
+
+
+ >
+ ) : (
+
+ )}
+
+ );
+}
+
+const mapStateToProps = (state) => {
+ return {
+ animatronics: state.animatronicsReducer,
+ camera: state.cameraReducer.camera,
+ office: state.officeReducer,
+ isCameraOpen: state.cameraReducer.isCameraOpen,
+ areAnimatronicsMoving: state.cameraReducer.areAnimatronicsMoving,
+ jumpscare: state.configReducer.jumpscare,
+ cameraButtonDisappear: state.configReducer.cameraButtonDisappear,
+ };
+};
+
+export default connect(mapStateToProps)(Camera);
diff --git a/Games/Five_Nights_at_Freddys/src/components/CameraButton.js b/Games/Five_Nights_at_Freddys/src/components/CameraButton.js
new file mode 100644
index 0000000000..2de25148ab
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/components/CameraButton.js
@@ -0,0 +1,33 @@
+import React from "react";
+import Media from "./Media";
+
+function CameraButton(props) {
+ const { handleCameraButton } = props;
+
+ const handleCamera = ({ target }) => {
+ if (target.dataset.disabled == "true") {
+ target.dataset.disabled = "false";
+ Media.Sounds.OpenCamera.play();
+ handleCameraButton();
+ setTimeout(() => {
+ target.dataset.disabled = "true";
+ }, 700);
+ }
+ };
+ return (
+
+
+
+ );
+}
+
+export default CameraButton;
diff --git a/Games/Five_Nights_at_Freddys/src/components/CameraMap.js b/Games/Five_Nights_at_Freddys/src/components/CameraMap.js
new file mode 100644
index 0000000000..15f33d9743
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/components/CameraMap.js
@@ -0,0 +1,162 @@
+import React from "react";
+import Media from "./Media";
+
+function CameraMap(props) {
+ const { handleCameraChange } = props;
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default CameraMap;
diff --git a/Games/Five_Nights_at_Freddys/src/components/Functions.js b/Games/Five_Nights_at_Freddys/src/components/Functions.js
new file mode 100644
index 0000000000..b10a0eb874
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/components/Functions.js
@@ -0,0 +1,73 @@
+function* Bonnie() {
+ yield* [
+ "Dinning Area",
+ "Backstage",
+ "Supply Closet",
+ "West Hall",
+ "W. Hall Corner",
+ "Door",
+ ];
+}
+
+function* Chica() {
+ yield* [
+ "Dinning Area",
+ "Restrooms",
+ "Kitchen",
+ "East Hall",
+ "E. Hall Corner",
+ "Door",
+ ];
+}
+
+function* Freddy() {
+ yield* [
+ "Stage",
+ "Dinning Area",
+ "Restrooms",
+ "Kitchen",
+ "East Hall",
+ "E. Hall Corner",
+ "Door",
+ ];
+}
+
+function* Foxy() {
+ yield* ["_1", "_2", "_3"];
+}
+
+const changeAnimatronic = (Localization, iterator, setAnimatronics, change) => {
+ Localization = iterator.next().value;
+ setAnimatronics(change);
+};
+
+const checkAnimatronicsPosition = (
+ BonnieLocal,
+ ChicaLocal,
+ FreddyLocal,
+ search
+) => {
+ let res = "";
+ if (BonnieLocal == search) {
+ res += "-b";
+ }
+ if (ChicaLocal == search) {
+ res += "-c";
+ }
+ if (FreddyLocal == search) {
+ res += "-f";
+ }
+
+ return res;
+};
+
+const Functions = {
+ Freddy,
+ Chica,
+ Bonnie,
+ Foxy,
+ changeAnimatronic,
+ checkAnimatronicsPosition,
+};
+
+export default Functions;
diff --git a/Games/Five_Nights_at_Freddys/src/components/Hud.js b/Games/Five_Nights_at_Freddys/src/components/Hud.js
new file mode 100644
index 0000000000..3ae83a0b3b
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/components/Hud.js
@@ -0,0 +1,20 @@
+import React from "react";
+import { connect } from "react-redux";
+
+function Hud({ hour, energy }) {
+ return (
+
+
{hour === 0 ? "12AM" : `${hour}AM`}
+ {energy}%
+
+ );
+}
+
+const mapStateToProps = (state) => {
+ return {
+ hour: state.configReducer.hour,
+ energy: state.configReducer.energy,
+ };
+};
+
+export default connect(mapStateToProps)(Hud);
diff --git a/Games/Five_Nights_at_Freddys/src/components/Images.js b/Games/Five_Nights_at_Freddys/src/components/Images.js
new file mode 100644
index 0000000000..883a63fd4a
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/components/Images.js
@@ -0,0 +1,116 @@
+///SHOW STAGE
+import Stage from "../media/Textures/Cams/Stage.webp";
+import Stage_b_c_f from "../media/Textures/Cams/Stage-b-c-f.webp";
+import Stage_b_f from "../media/Textures/Cams/Stage-b-f.webp";
+import Stage_c_f from "../media/Textures/Cams/Stage-c-f.webp";
+import Stage_f from "../media/Textures/Cams/Stage-f.webp";
+
+///DINNING AREA
+import DinningArea from "../media/Textures/Cams/DinningArea.webp";
+import DinningArea_b from "../media/Textures/Cams/DinningArea-b.webp";
+import DinningArea_c from "../media/Textures/Cams/DinningArea-c.webp";
+import DinningArea_f from "../media/Textures/Cams/DinningArea-f.webp";
+import DinningArea_b_c from "../media/Textures/Cams/DinningArea-b-c.webp";
+import DinningArea_c_f from "../media/Textures/Cams/DinningArea-c-f.webp";
+import DinningArea_b_f from "../media/Textures/Cams/DinningArea-b-f.webp";
+import DinningArea_b_c_f from "../media/Textures/Cams/DinningArea-b-c-f.webp";
+
+///BACKSTAGE
+import Backstage from "../media/Textures/Cams/Backstage.webp";
+import Backstage_b from "../media/Textures/Cams/Backstage-b.webp";
+
+///PIRATE COVE
+import PirateCove from "../media/Textures/Cams/Pirate_Cove.webp";
+import PirateCove_1 from "../media/Textures/Cams/Pirate_Cove-1.webp";
+import PirateCove_2 from "../media/Textures/Cams/Pirate_Cove-2.webp";
+import PirateCove_3 from "../media/Textures/Cams/Pirate_Cove-3.webp";
+
+///SUPPLY ROOM
+import SupplyCloset from "../media/Textures/Cams/SupplyRoom.webp";
+import SupplyCloset_b from "../media/Textures/Cams/SupplyRoom-b.webp";
+
+///WEST HALL
+import WestHall from "../media/Textures/Cams/West_Hall.webp";
+import WestHall_b from "../media/Textures/Cams/West_Hall-b.webp";
+import FoxyHallway from "../media/Textures/Foxy-Hallway.webp";
+
+///WEST HALL CORNER
+import WHallCorner from "../media/Textures/Cams/WHallCorner.webp";
+import WHallCorner_b from "../media/Textures/Cams/WHallCorner-b.webp";
+
+///RESTROOMS
+import Restrooms from "../media/Textures/Cams/Restrooms.webp";
+import Restrooms_c from "../media/Textures/Cams/Restrooms-c.webp";
+import Restrooms_f from "../media/Textures/Cams/Restrooms-f.webp";
+import Restrooms_c_f from "../media/Textures/Cams/Restrooms-c-f.webp";
+
+///EAST HALL
+import EastHall from "../media/Textures/Cams/East_Hall.webp";
+import EastHall_c from "../media/Textures/Cams/East_Hall-c.webp";
+import EastHall_f from "../media/Textures/Cams/East_Hall-f.webp";
+import EastHall_c_f from "../media/Textures/Cams/East_Hall-c-f.webp";
+
+///EAST HALL CORNER
+import EHallCorner from "../media/Textures/Cams/EHallCorner.webp";
+import EHallCorner_c from "../media/Textures/Cams/EHallCorner-c.webp";
+import EHallCorner_f from "../media/Textures/Cams/EHallCorner-f.webp";
+
+import Kitchen from "../media/Textures/black.jpg";
+import Kitchen_c from "../media/Textures/black.jpg";
+import Kitchen_f from "../media/Textures/black.jpg";
+import Kitchen_c_f from "../media/Textures/black.jpg";
+
+const cameraImages = {
+ Stage,
+ Stage_b_c_f,
+ Stage_b_f,
+ Stage_c_f,
+ Stage_f,
+ DinningArea,
+ DinningArea_b_c_f,
+ DinningArea_c_f,
+ DinningArea_b_f,
+ DinningArea_b_c,
+ DinningArea_b,
+ DinningArea_c,
+ DinningArea_f,
+ Backstage,
+ Backstage_b,
+ SupplyCloset,
+ SupplyCloset_b,
+ WestHall,
+ WestHall_b,
+ WHallCorner,
+ WHallCorner_b,
+ Restrooms,
+ Restrooms_c,
+ Restrooms_c_f,
+ Restrooms_f,
+ EastHall,
+ EastHall_c,
+ EastHall_c_f,
+ EastHall_f,
+ EHallCorner,
+ EHallCorner_c,
+ EHallCorner_f,
+ EHallCorner_c_f: EHallCorner_f,
+ PirateCove,
+ PirateCove_1,
+ PirateCove_2,
+ PirateCove_3,
+ Kitchen,
+ Kitchen_c,
+ Kitchen_f,
+ Kitchen_c_f,
+};
+
+export default function getCam(animatronics, camera, foxy = "") {
+ let location = camera.trim().replaceAll(" ", "");
+
+ if (location === "W.HallCorner") location = "WHallCorner";
+ if (location === "E.HallCorner") location = "EHallCorner";
+
+ return cameraImages[
+ `${location}${animatronics}${location === "PirateCove" ? foxy : ""}`
+ ];
+}
diff --git a/Games/Five_Nights_at_Freddys/src/components/Media.js b/Games/Five_Nights_at_Freddys/src/components/Media.js
new file mode 100644
index 0000000000..8a6f970a9d
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/components/Media.js
@@ -0,0 +1,45 @@
+/// AUDIO
+import CameraSound from "../media/Sounds/put down.mp3";
+import CameraChange from "../media/Sounds/blip3.mp3";
+import Ambience from "../media/Sounds/MainAmbience.mp3";
+import FreddyLaugh1 from "../media/Sounds/FreddyLaugh1.mp3";
+import FreddyLaugh2 from "../media/Sounds/FreddyLaugh2.mp3";
+import Door from "../media/Sounds/Door.mp3";
+import FoxyPunch from "../media/Sounds/knock2.mp3";
+import Surprise from "../media/Sounds/windowscare.mp3";
+import Jumpscare from "../media/Sounds/jumpscare.mp3";
+
+/// IMAGES
+import CameraButton from "../media/Textures/CameraButton.png";
+import Up from "../media/Textures/Up.webp";
+import Down from "../media/Textures/Down.webp";
+import Map from "../media/Textures/Cams/Complete_Map.png";
+import Stage from "../media/Textures/Cams/Stage-b-c-f.webp";
+
+const Sounds = {
+ OpenCamera: new Audio(CameraSound),
+ CameraChange: new Audio(CameraChange),
+ Ambience: new Audio(Ambience),
+ FreddyLaugh1: new Audio(FreddyLaugh1),
+ FreddyLaugh2: new Audio(FreddyLaugh2),
+ Door: new Audio(Door),
+ FoxyPunch: new Audio(FoxyPunch),
+ Surprise: new Audio(Surprise),
+ Jumpscare: new Audio(Jumpscare),
+};
+
+const Images = {
+ CameraButton,
+ Up,
+ Down,
+ Map,
+ Stage,
+ Ambience,
+};
+
+const Media = {
+ Sounds,
+ Images,
+};
+
+export default Media;
diff --git a/Games/Five_Nights_at_Freddys/src/components/Office.js b/Games/Five_Nights_at_Freddys/src/components/Office.js
new file mode 100644
index 0000000000..9b1d3c9ee1
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/components/Office.js
@@ -0,0 +1,383 @@
+import React, { useState, useEffect } from "react";
+import { connect } from "react-redux";
+
+import Default from "../media/Textures/Office/Default.webp";
+import Media from "./Media";
+
+import Blackout from "../media/Textures/Office/304.webp";
+import MusicBox from "../media/Sounds/music box.mp3";
+import FreddyBlackout from "../media/Textures/Freddy.webp";
+
+import JumpscareMP3 from "../media/Sounds/jumpscare.mp3";
+import BonnieJumpscare from "../media/Textures/Bonnie-Jumpscare.webp";
+import ChicaJumpscare from "../media/Textures/Chica-Jumpscare.webp";
+import FreddyJumpscare1 from "../media/Textures/Freddy-Jumpscare1.gif";
+import FreddyJumpscare2 from "../media/Textures/Freddy-Jumpscare.webp";
+import FoxyJumpscare from "../media/Textures/Foxy-Jumpscare.gif";
+
+import LD from "../media/Textures/Office/LD.webp";
+import RD from "../media/Textures/Office/RD.webp";
+import RD_LD from "../media/Textures/Office/RD_LD.webp";
+import LD_RL from "../media/Textures/Office/LD_RL.webp";
+import RD_LL from "../media/Textures/Office/RD_LL.webp";
+
+import RD_LL_BONNIE from "../media/Textures/Office/RD_LL_BONNIE.webp";
+import LD_RL_CHICA from "../media/Textures/Office/LD_RL_CHICA.webp";
+import RL from "../media/Textures/Office/RL.webp";
+
+import RL_LL_BONNIE from "../media/Textures/Office/RL_LL_BONNIE.webp";
+import LL from "../media/Textures/Office/LL.webp";
+import LL_BONNIE from "../media/Textures/Office/LL_BONNIE.webp";
+import RL_LL from "../media/Textures/Office/RL_LL.webp";
+import RL_CHICA from "../media/Textures/Office/RL_CHICA.webp";
+import RL_LL_CHICA from "../media/Textures/Office/RL_LL_CHICA.webp";
+import RL_LL_BONNIE_CHICA from "../media/Textures/Office/RL_LL_BONNIE_CHICA.webp";
+
+let canJumpscare = true;
+
+const officeImages = {
+ LD,
+ RD,
+ RD_LD,
+ LD_RL,
+ RD_LL,
+ RD_LL_BONNIE,
+ LD_RL_CHICA,
+ RL,
+ RL_LL_BONNIE,
+ LL,
+ LL_BONNIE,
+ RL_CHICA,
+ RL_LL,
+ RL_LL_CHICA,
+ RL_LL_BONNIE_CHICA,
+};
+
+let musicBox = new Audio(MusicBox);
+let jumpscareSound = new Audio(JumpscareMP3);
+musicBox.loop = "true";
+
+function Office({
+ blackout,
+ animatronics,
+ officeConfig,
+ jumpscare,
+ isCameraOpen,
+ endGame,
+ dispatch,
+}) {
+ const [isJumpscare, setIsJumpscare] = useState(null);
+ const [background, setBackground] = useState(Default);
+ const [blackoutBackground, setBlackoutBackground] = useState(Blackout);
+
+ useEffect(() => {
+ checkBackground();
+ }, [
+ officeConfig.leftDoor,
+ officeConfig.leftLight,
+ officeConfig.rightDoor,
+ officeConfig.rightLight,
+ ]);
+
+ useEffect(() => {
+ if (isCameraOpen) return;
+ checkBackground();
+
+ if (jumpscare) {
+ dispatch({ type: "CHANGE_CAMERA_BUTTON" });
+ setIsJumpscare(jumpscare);
+ jumpscareSound.play();
+ setTimeout(() => {
+ endGame(false);
+ }, 5000);
+ }
+ }, [isCameraOpen]);
+
+ useEffect(() => {
+ if (animatronics.Foxy.jumpscare) {
+ dispatch({ type: "CHANGE_CAMERA_BUTTON" });
+ setIsJumpscare("Foxy");
+ jumpscareSound.play();
+ setTimeout(() => {
+ endGame(false);
+ }, 5000);
+ }
+ }, [animatronics.Foxy.jumpscare]);
+
+ useEffect(() => {
+ if (animatronics.Freddy.jumpscare) {
+ dispatch({ type: "CHANGE_CAMERA_BUTTON" });
+ setIsJumpscare("Freddy");
+ jumpscareSound.play();
+ setTimeout(() => {
+ endGame(false);
+ }, 5000);
+ }
+ }, [animatronics.Freddy.jumpscare]);
+
+ async function checkBackground() {
+ const { leftDoor, rightDoor, leftLight, rightLight } = officeConfig;
+ const { Bonnie, Chica } = animatronics;
+
+ function getBackground() {
+ const result = [];
+
+ if (rightDoor) result.push("RD");
+ if (leftDoor) result.push("LD");
+
+ if (rightLight && !rightDoor) result.push("RL");
+ if (leftLight && !leftDoor) result.push("LL");
+ if (Bonnie.door && leftLight) result.push("BONNIE");
+ if (Chica.door && rightLight) result.push("CHICA");
+
+ return result;
+ }
+
+ const result = await getBackground();
+ if (result.length === 0) setBackground(Default);
+ else setBackground(officeImages[result.join("_")]);
+ }
+
+ const checkDoorSounds = (light) => {
+ const { leftDoor, rightDoor } = officeConfig;
+ const { Bonnie, Chica } = animatronics;
+
+ let condition1 = light === "leftLight" && !leftDoor && Bonnie.door;
+ let condition2 = light === "rightLight" && !rightDoor && Chica.door;
+
+ if (condition1 || condition2) Media.Sounds.Surprise.play();
+ };
+
+ useEffect(() => {
+ if (blackout) FreddyJumpscare();
+ }, [blackout]);
+
+ useEffect(() => {
+ canJumpscare = true;
+ return () => {
+ canJumpscare = false;
+ musicBox.pause();
+ };
+ }, []);
+
+ const FreddyJumpscare = () => {
+ const musicBoxInterval = setInterval(() => {
+ let musicBoxNumber = Math.floor(Math.random() * 9);
+ if (!canJumpscare) clearInterval(musicBoxInterval);
+ if (musicBoxNumber < 3 && canJumpscare) {
+ musicBox.currentTime = 0;
+ musicBox.play();
+ setBlackoutBackground(FreddyBlackout);
+ clearInterval(musicBoxInterval);
+
+ const pauseMusicInterval = setInterval(() => {
+ let pauseNumber = Math.floor(Math.random() * 3);
+ if (!canJumpscare) clearInterval(pauseMusicInterval);
+ if (pauseNumber == 0 && canJumpscare) {
+ setBlackoutBackground(null);
+ musicBox.pause();
+ clearInterval(pauseMusicInterval);
+
+ const freddyInterval = setInterval(() => {
+ let freddyNumber = Math.floor(Math.random() * 9);
+ if (!canJumpscare) clearInterval(freddyInterval);
+ if (freddyNumber == 0 && canJumpscare) {
+ const JumpscareImage = FreddyJumpscare1;
+ setBlackoutBackground(JumpscareImage);
+ jumpscareSound.play();
+ dispatch({
+ type: "CHANGE_JUMPSCARE",
+ animatronic: true,
+ });
+ clearInterval(freddyInterval);
+ setTimeout(() => {
+ endGame(false);
+ setBlackoutBackground(Blackout);
+ }, 5000);
+ }
+ }, 3000);
+ }
+ }, 5000);
+ }
+ }, 3000);
+ };
+
+ if (isJumpscare === "Bonnie" && !isCameraOpen)
+ return (
+
+
+
+ );
+ else if (isJumpscare === "Foxy")
+ return (
+
+
+
+ );
+ else if (isJumpscare === "Freddy")
+ return (
+
+
+
+ );
+ else if (isJumpscare === "Chica" && !isCameraOpen)
+ return (
+
+
+
+ );
+
+ return (
+ <>
+ {!blackout ? (
+
+ ) : (
+
+
+
+ )}
+ >
+ );
+}
+
+const mapStateToProps = (state) => {
+ return {
+ officeConfig: state.officeReducer,
+ animatronics: state.animatronicsReducer,
+ isCameraOpen: state.cameraReducer.isCameraOpen,
+ jumpscare: state.configReducer.jumpscare,
+ };
+};
+
+export default connect(mapStateToProps)(Office);
diff --git a/Games/Five_Nights_at_Freddys/src/css/CustomNight.module.css b/Games/Five_Nights_at_Freddys/src/css/CustomNight.module.css
new file mode 100644
index 0000000000..33660b0897
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/css/CustomNight.module.css
@@ -0,0 +1,208 @@
+.golden_freddy {
+ width: 100vw;
+ height: 100vh;
+ background-image: url("../media/Textures/golden_freddy.webp");
+ background-color: #000;
+ background-size: contain;
+ background-position: center;
+ background-repeat: no-repeat;
+}
+
+.custom_night_container {
+ overflow: auto;
+ font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
+ color: white;
+ backdrop-filter: blur(7px) brightness(0.5);
+
+ display: flex;
+ flex-direction: column;
+ justify-content: space-evenly;
+ height: 100vh;
+}
+
+.github_icon {
+ width: fit-content;
+ height: fit-content;
+ position: absolute;
+ bottom: 2%;
+ right: 2%;
+ cursor: pointer;
+ transition: transform 200ms 50ms;
+}
+
+.github_icon a {
+ width: fit-content;
+ height: fit-content;
+}
+
+.github_icon:hover {
+ transform: scale(1.2);
+ transition: transform 200ms 50ms;
+}
+
+.custom_night_container h1 {
+ font-weight: 400;
+ margin-left: 30px;
+ opacity: 0.8;
+}
+
+.animatronics_container {
+ display: flex;
+ justify-content: space-evenly;
+}
+
+.animatronic {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.animatronic img {
+ max-width: 200px;
+ width: 20vw;
+}
+
+.animatronic > span {
+ font-size: 20pt;
+ margin-bottom: 15px;
+}
+
+.range_buttons {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 25px;
+ font-size: 1.5rem;
+ font-family: "Consolas";
+ width: 100%;
+}
+
+.range_buttons button {
+ border-radius: 5px;
+ width: 50px;
+ outline: none;
+ background-color: var(--button-color);
+ color: inherit;
+ font-weight: bolder;
+ border: none;
+ font-size: inherit;
+ cursor: pointer;
+ transition: transform 200ms 50ms;
+}
+
+.range_buttons button:not(:disabled):hover,
+.range_buttons button:not(:disabled):focus-within {
+ transform: scale(1.15);
+ transition: transform 200ms 50ms;
+}
+
+.range_buttons button:disabled {
+ cursor: default;
+ opacity: 0.8;
+}
+
+.start_screen {
+ font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
+ /* height: 100vh; */
+ display: flex;
+ align-self: center;
+ justify-content: space-evenly;
+ flex-wrap: wrap;
+ align-items: center;
+}
+
+.start_screen span {
+ flex: 100%;
+ margin-bottom: 15px;
+ font-size: 12.5pt;
+}
+
+.ready_button {
+ font-weight: 800;
+ padding: auto 10px;
+
+ font-size: 17pt;
+}
+
+.start_screen button:not(.ready_button) {
+ font-size: 15pt;
+}
+
+.start_screen button:not(.ready_button)[data-selected="false"] {
+ opacity: 0.6;
+}
+
+.start_screen button:not(.ready_button)[data-selected="true"]:before {
+ content: "▶ ";
+}
+
+.start_screen button {
+ border-radius: 6.5px;
+ /* width: 100px; */
+ cursor: pointer;
+ height: 100%;
+ outline: none;
+ color: white;
+ background-color: var(--button-color);
+ border: none;
+}
+
+.footer {
+ opacity: 0.8;
+ height: 50px;
+ text-align: center;
+}
+
+.footer p {
+ margin-top: 0;
+}
+
+@media screen and (min-width: 750px) {
+ .custom_night_container h1 {
+ margin-bottom: 30px;
+ }
+ .start_screen {
+ width: 50%;
+ }
+ .start_screen button {
+ margin-top: 10px;
+ height: 50px;
+ }
+
+ .range_buttons button {
+ height: 50px;
+ }
+
+ .footer {
+ margin-top: 50px;
+ }
+}
+
+@media screen and (max-width: 750px) {
+ .custom_night_container h1 {
+ /* margin-bottom: 2%; */
+ margin-top: 2%;
+ font-size: 15pt;
+ }
+
+ .start_screen {
+ width: 90%;
+ }
+ .ready_button {
+ margin: 1.2% auto 1% auto;
+ }
+
+ .start_screen button {
+ font-size: 10pt !important;
+ height: 35px;
+ }
+
+ .range_buttons {
+ margin-top: 15px;
+ max-height: 30px;
+ }
+
+ .footer {
+ margin: 1% 0px 1% 0px;
+ }
+}
diff --git a/Games/Five_Nights_at_Freddys/src/css/Game.css b/Games/Five_Nights_at_Freddys/src/css/Game.css
new file mode 100644
index 0000000000..59a0766776
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/css/Game.css
@@ -0,0 +1,227 @@
+* {
+ -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, Edge, Opera and Firefox */
+}
+
+:root {
+ --background-color: black;
+ --button-color: rgba(255, 255, 255, 0.2);
+}
+
+body {
+ width: 100vw;
+ height: 100vh;
+}
+
+.custom-night {
+ background-image: url("../media/FNAF.webp");
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+}
+
+.animation {
+ background-size: 100vw;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+
+.animation[data-right-door="false"][data-left-door="false"] {
+ background-image: url("../media/Textures/Office/Default.webp");
+}
+.animation[data-right-door="true"][data-left-door="false"] {
+ background-image: url("../media/Textures/Office/RD.webp");
+}
+.animation[data-right-door="false"][data-left-door="true"] {
+ background-image: url("../media/Textures/Office/LD.webp");
+}
+.animation[data-right-door="true"][data-left-door="true"] {
+ background-image: url("../media/Textures/Office/RD_LD.webp");
+}
+
+@keyframes up {
+ 0% {
+ background-position: 0px;
+ }
+ 85% {
+ background-position: -9500px;
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0;
+ }
+}
+@keyframes down {
+ 0% {
+ background-position: -9500px;
+ opacity: 1;
+ }
+ 100% {
+ background-position: 0px;
+ }
+}
+
+@keyframes disappear {
+ from {
+ display: unset !important;
+ z-index: 1;
+ opacity: 1;
+ }
+ to {
+ display: none !important;
+ opacity: 0;
+ z-index: -10;
+ }
+}
+
+body {
+ margin: 0;
+ overflow: hidden;
+ background-color: var(--background-color);
+}
+
+.camera-button {
+ pointer-events: all !important;
+ margin-left: 26vw;
+ bottom: 0;
+ opacity: 0.5;
+}
+
+.true,
+.false {
+ transform: scale(1.3);
+ animation: up 0.6s steps(8) forwards;
+}
+
+.map {
+ bottom: 0;
+ right: 0;
+ width: fit-content;
+}
+@media only screen and (max-width: 750px) {
+ .map img {
+ width: 250px !important;
+ opacity: 0.7;
+ }
+ .map {
+ margin-bottom: 30px;
+ }
+ .camera-button {
+ width: 100vh !important;
+ }
+}
+
+area {
+ outline: none;
+}
+
+area.hover {
+ cursor: pointer;
+}
+
+.true,
+.false,
+.animatronics-true,
+.static {
+ width: 100vw;
+ height: 100vh;
+}
+.animatronics-true {
+ background-color: var(--background-color);
+}
+
+.static {
+ opacity: 0.9;
+ animation: noise 0.12s infinite alternate-reverse;
+}
+
+.hour,
+.energy {
+ font-weight: lighter;
+ opacity: 0.4;
+ z-index: 1;
+ font-family: "Consolas";
+ color: white;
+ position: "absolute";
+}
+.hour {
+ position: absolute;
+ margin-right: 0;
+ margin-left: 90vw;
+}
+.energy {
+ position: absolute;
+ bottom: 0;
+ margin-left: 3vw;
+ font-size: 15pt;
+}
+
+.opening {
+ z-index: 1;
+ animation: disappear 0.5s steps(1) forwards;
+}
+
+@keyframes opening {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+.open {
+ animation: opening 0.5s steps(1) forwards;
+}
+
+img[data-disabled="false"] {
+ opacity: 0.3;
+}
+
+@media screen and (max-width: 700px) {
+ .camera-img {
+ width: 100vw;
+ height: 90vh;
+ }
+
+ .hour {
+ font-size: 17pt;
+ }
+ .camera-button {
+ margin-left: 22vw;
+ }
+}
+.office-img {
+ margin: auto;
+ width: 100vw;
+}
+
+.office-container {
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+img {
+ pointer-events: none;
+}
+
+* {
+ -moz-user-select: none;
+ -webkit-user-select: none;
+ user-select: none;
+}
+
+.camera-container {
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
diff --git a/Games/Five_Nights_at_Freddys/src/index.js b/Games/Five_Nights_at_Freddys/src/index.js
new file mode 100644
index 0000000000..37e3b1dc06
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/index.js
@@ -0,0 +1,55 @@
+import React, { useState, useEffect } from "react";
+import ReactDOM from "react-dom";
+import Controller from "./Controller";
+import "./css/Game.css";
+import * as serviceWorker from "./serviceWorker";
+import { Provider } from "react-redux";
+import store from "./store/store";
+import CustomNight from "./CustomNight";
+
+const initialState = {
+ mode: "NORMAL",
+ Freddy: 10,
+ Bonnie: 10,
+ Chica: 10,
+ Foxy: 10,
+};
+
+const Start = () => {
+ const [Start, setStart] = useState(false);
+ const [stages, setStages] = useState(initialState);
+
+ useEffect(() => {
+ console.log(window.innerHeight > window.innerWidth);
+ if (window.innerHeight > window.innerWidth) {
+ window.alert(
+ `Para uma melhor experiência, vire seu celular para o modo de paisagem (modo deitado)
+ ~ For a better experience, please rotate your phone to landscape mode`
+ );
+ }
+ }, []);
+
+ return (
+ <>
+ {!Start ? (
+
+
+
+ ) : (
+
+ )}
+ >
+ );
+};
+
+ReactDOM.render(
+
+
+ ,
+ document.getElementById("root")
+);
+
+serviceWorker.register();
diff --git a/Games/Five_Nights_at_Freddys/src/media/FNAF.webp b/Games/Five_Nights_at_Freddys/src/media/FNAF.webp
new file mode 100644
index 0000000000..483ddb8f96
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/FNAF.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/Ambience.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/Ambience.mp3
new file mode 100644
index 0000000000..1404ef982f
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/Ambience.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/CameraIdle 2.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/CameraIdle 2.mp3
new file mode 100644
index 0000000000..2bbcc2473b
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/CameraIdle 2.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/Clock.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/Clock.mp3
new file mode 100644
index 0000000000..712af92409
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/Clock.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/Dead.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/Dead.mp3
new file mode 100644
index 0000000000..0a36517541
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/Dead.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/Door.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/Door.mp3
new file mode 100644
index 0000000000..ef4a82a526
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/Door.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh1.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh1.mp3
new file mode 100644
index 0000000000..4a6ec336f7
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh1.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh2.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh2.mp3
new file mode 100644
index 0000000000..c0688cabfb
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh2.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh3.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh3.mp3
new file mode 100644
index 0000000000..9cae715883
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/FreddyLaugh3.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/MainAmbience.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/MainAmbience.mp3
new file mode 100644
index 0000000000..00f0402b8a
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/MainAmbience.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/blip3.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/blip3.mp3
new file mode 100644
index 0000000000..c6e85da460
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/blip3.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/garble1.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/garble1.mp3
new file mode 100644
index 0000000000..29706fa8c5
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/garble1.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/garble2.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/garble2.mp3
new file mode 100644
index 0000000000..6829647a0f
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/garble2.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/golden_freddy.ogg b/Games/Five_Nights_at_Freddys/src/media/Sounds/golden_freddy.ogg
new file mode 100644
index 0000000000..35ef673b20
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/golden_freddy.ogg differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/jumpscare.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/jumpscare.mp3
new file mode 100644
index 0000000000..f993866c75
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/jumpscare.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/knock2.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/knock2.mp3
new file mode 100644
index 0000000000..6ea586a887
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/knock2.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/music box.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/music box.mp3
new file mode 100644
index 0000000000..abdca5342f
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/music box.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/powerdown.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/powerdown.mp3
new file mode 100644
index 0000000000..0b4db73b12
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/powerdown.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/powerdown2.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/powerdown2.mp3
new file mode 100644
index 0000000000..354625f7a1
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/powerdown2.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/put down.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/put down.mp3
new file mode 100644
index 0000000000..9c4b6f65c1
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/put down.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Sounds/windowscare.mp3 b/Games/Five_Nights_at_Freddys/src/media/Sounds/windowscare.mp3
new file mode 100644
index 0000000000..7a4ac4b9a6
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Sounds/windowscare.mp3 differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Bonnie-Jumpscare.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Bonnie-Jumpscare.webp
new file mode 100644
index 0000000000..06cae0ba00
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Bonnie-Jumpscare.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/CameraButton.png b/Games/Five_Nights_at_Freddys/src/media/Textures/CameraButton.png
new file mode 100644
index 0000000000..7dda7ff099
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/CameraButton.png differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Backstage-b.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Backstage-b.webp
new file mode 100644
index 0000000000..441a2dd198
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Backstage-b.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Backstage.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Backstage.webp
new file mode 100644
index 0000000000..77e87c2e00
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Backstage.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Complete_Map.png b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Complete_Map.png
new file mode 100644
index 0000000000..a6f078049e
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Complete_Map.png differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-c-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-c-f.webp
new file mode 100644
index 0000000000..5575a87290
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-c-f.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-c.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-c.webp
new file mode 100644
index 0000000000..c7f18aa098
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-c.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-f.webp
new file mode 100644
index 0000000000..c53bda41ef
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b-f.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b.webp
new file mode 100644
index 0000000000..28f3782045
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-b.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-c-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-c-f.webp
new file mode 100644
index 0000000000..cbd7de18ef
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-c-f.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-c.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-c.webp
new file mode 100644
index 0000000000..03e2aa4537
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-c.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-f.webp
new file mode 100644
index 0000000000..241653b33e
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea-f.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea.webp
new file mode 100644
index 0000000000..84d236bb9f
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/DinningArea.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner-c.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner-c.webp
new file mode 100644
index 0000000000..673bcbbc10
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner-c.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner-f.webp
new file mode 100644
index 0000000000..0e774eef5a
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner-f.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner.webp
new file mode 100644
index 0000000000..153fb57f2a
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/EHallCorner.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-c-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-c-f.webp
new file mode 100644
index 0000000000..62add29396
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-c-f.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-c.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-c.webp
new file mode 100644
index 0000000000..7c2d237bf0
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-c.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-f.webp
new file mode 100644
index 0000000000..c63eac5dbf
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall-f.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall.webp
new file mode 100644
index 0000000000..f9e7d26bc3
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/East_Hall.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-1.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-1.webp
new file mode 100644
index 0000000000..1453c1c966
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-1.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-2.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-2.webp
new file mode 100644
index 0000000000..82ece70e02
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-2.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-3.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-3.webp
new file mode 100644
index 0000000000..ce9c01f29b
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove-3.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove.webp
new file mode 100644
index 0000000000..ab10b60d82
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Pirate_Cove.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-c-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-c-f.webp
new file mode 100644
index 0000000000..c01a454e07
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-c-f.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-c.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-c.webp
new file mode 100644
index 0000000000..3a87cbe6a6
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-c.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-f.webp
new file mode 100644
index 0000000000..8884eebc63
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms-f.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms.webp
new file mode 100644
index 0000000000..fe2d08cf23
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Restrooms.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-b-c-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-b-c-f.webp
new file mode 100644
index 0000000000..c3ef89ede5
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-b-c-f.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-b-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-b-f.webp
new file mode 100644
index 0000000000..7641c80ad2
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-b-f.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-c-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-c-f.webp
new file mode 100644
index 0000000000..81875cdfaa
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-c-f.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-f.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-f.webp
new file mode 100644
index 0000000000..15e0385866
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage-f.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage.webp
new file mode 100644
index 0000000000..4f6dab81ef
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/Stage.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/SupplyRoom-b.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/SupplyRoom-b.webp
new file mode 100644
index 0000000000..69c559d86b
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/SupplyRoom-b.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/SupplyRoom.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/SupplyRoom.webp
new file mode 100644
index 0000000000..9c07c416fe
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/SupplyRoom.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/WHallCorner-b.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/WHallCorner-b.webp
new file mode 100644
index 0000000000..180a346aa5
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/WHallCorner-b.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/WHallCorner.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/WHallCorner.webp
new file mode 100644
index 0000000000..28c55946d7
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/WHallCorner.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West-Hall-b.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West-Hall-b.webp
new file mode 100644
index 0000000000..ef1026afc3
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West-Hall-b.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West-Hall.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West-Hall.webp
new file mode 100644
index 0000000000..6c374e6221
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West-Hall.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West_Hall-b.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West_Hall-b.webp
new file mode 100644
index 0000000000..aa3a69bd83
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West_Hall-b.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West_Hall.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West_Hall.webp
new file mode 100644
index 0000000000..4d43d1bbd5
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Cams/West_Hall.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Chica-Jumpscare.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Chica-Jumpscare.webp
new file mode 100644
index 0000000000..7e41b75600
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Chica-Jumpscare.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/bonnie.png b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/bonnie.png
new file mode 100644
index 0000000000..b9c1ebfe8b
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/bonnie.png differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/chica.png b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/chica.png
new file mode 100644
index 0000000000..33b343da86
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/chica.png differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/foxy.png b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/foxy.png
new file mode 100644
index 0000000000..87414945a6
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/foxy.png differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/freddy.png b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/freddy.png
new file mode 100644
index 0000000000..8043ec851c
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/CustomNight/freddy.png differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Down.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Down.webp
new file mode 100644
index 0000000000..e583aa3049
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Down.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Foxy-Hallway.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Foxy-Hallway.webp
new file mode 100644
index 0000000000..86e1fb1e88
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Foxy-Hallway.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Foxy-Jumpscare.gif b/Games/Five_Nights_at_Freddys/src/media/Textures/Foxy-Jumpscare.gif
new file mode 100644
index 0000000000..fb41af0621
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Foxy-Jumpscare.gif differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy-Jumpscare.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy-Jumpscare.webp
new file mode 100644
index 0000000000..2d30bc9ba2
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy-Jumpscare.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy-Jumpscare1.gif b/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy-Jumpscare1.gif
new file mode 100644
index 0000000000..94adaf7cef
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy-Jumpscare1.gif differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy.webp
new file mode 100644
index 0000000000..aaec85e93e
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Freddy.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/304.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/304.webp
new file mode 100644
index 0000000000..32c19a8bce
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/304.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/305.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/305.webp
new file mode 100644
index 0000000000..041be5eb6f
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/305.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/Default.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/Default.webp
new file mode 100644
index 0000000000..a6f9532c46
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/Default.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD.webp
new file mode 100644
index 0000000000..4de9fe1afb
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD_RL.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD_RL.webp
new file mode 100644
index 0000000000..6a78ed16f6
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD_RL.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD_RL_CHICA.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD_RL_CHICA.webp
new file mode 100644
index 0000000000..06e6e23d01
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LD_RL_CHICA.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LL.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LL.webp
new file mode 100644
index 0000000000..9b6777773d
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LL.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LL_BONNIE.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LL_BONNIE.webp
new file mode 100644
index 0000000000..7a8df6a2a6
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/LL_BONNIE.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD.webp
new file mode 100644
index 0000000000..c2a5a09233
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LD.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LD.webp
new file mode 100644
index 0000000000..c9b0cd98df
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LD.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LL.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LL.webp
new file mode 100644
index 0000000000..58a9b18946
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LL.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LL_BONNIE.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LL_BONNIE.webp
new file mode 100644
index 0000000000..c76db4fa01
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RD_LL_BONNIE.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL.webp
new file mode 100644
index 0000000000..baa661a62a
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_CHICA.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_CHICA.webp
new file mode 100644
index 0000000000..77e4cdf83b
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_CHICA.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL.webp
new file mode 100644
index 0000000000..5482ad7375
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_BONNIE.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_BONNIE.webp
new file mode 100644
index 0000000000..358a6a4956
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_BONNIE.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_BONNIE_CHICA.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_BONNIE_CHICA.webp
new file mode 100644
index 0000000000..c1b6f2d965
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_BONNIE_CHICA.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_CHICA.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_CHICA.webp
new file mode 100644
index 0000000000..ccb252e9aa
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Office/RL_LL_CHICA.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Static-Cam.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Static-Cam.webp
new file mode 100644
index 0000000000..4d451726eb
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Static-Cam.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Up.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Up.webp
new file mode 100644
index 0000000000..6813603362
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Up.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Victory.gif b/Games/Five_Nights_at_Freddys/src/media/Textures/Victory.gif
new file mode 100644
index 0000000000..3fe570d929
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Victory.gif differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/Victory.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/Victory.webp
new file mode 100644
index 0000000000..49721ccf65
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/Victory.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/black.jpg b/Games/Five_Nights_at_Freddys/src/media/Textures/black.jpg
new file mode 100644
index 0000000000..3320e95c1d
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/black.jpg differ
diff --git a/Games/Five_Nights_at_Freddys/src/media/Textures/golden_freddy.webp b/Games/Five_Nights_at_Freddys/src/media/Textures/golden_freddy.webp
new file mode 100644
index 0000000000..dd6704065e
Binary files /dev/null and b/Games/Five_Nights_at_Freddys/src/media/Textures/golden_freddy.webp differ
diff --git a/Games/Five_Nights_at_Freddys/src/reducers/animatronicsReducer.js b/Games/Five_Nights_at_Freddys/src/reducers/animatronicsReducer.js
new file mode 100644
index 0000000000..581dc73ff2
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/reducers/animatronicsReducer.js
@@ -0,0 +1,48 @@
+const originalState = {
+ Freddy: {
+ camera: "Stage",
+ door: false,
+ jumpscare: false,
+ },
+ Bonnie: {
+ camera: "Stage",
+ door: false,
+ jumpscare: false,
+ },
+ Chica: {
+ camera: "Stage",
+ door: false,
+ jumpscare: false,
+ },
+ Foxy: {
+ camera: "",
+ door: false,
+ jumpscare: false,
+ },
+};
+
+export default function animatronics(state = originalState, action) {
+ switch (action.type) {
+ // case "CHANGE_FREDDY_CAMERA":
+ // return { ...state, Freddy: { ...state.Freddy, camera: action.content } };
+ // case "CHANGE_BONNIE_CAMERA":
+ // return { ...state, Bonnie: { ...state.Bonnie, camera: action.content } };
+ // case "CHANGE_CHICA_CAMERA":
+ // return { ...state, Chica: { ...state.Chica, camera: action.content } };
+ // case "CHANGE_FOXY_CAMERA":
+ // return { ...state, Foxy: { ...state.Foxy, camera: action.content } };
+
+ case "CHANGE_ANIMATRONIC":
+ let animatronicProps = state[action.animatronic];
+
+ animatronicProps = { ...action.animatronicState };
+ state[action.animatronic] = animatronicProps;
+ return state;
+ case "SET_FOXY_NULL":
+ return { ...state, Foxy: { ...state.Foxy, camera: null } };
+ case "CLEAR_DATA":
+ return { ...originalState };
+ default:
+ return state;
+ }
+}
diff --git a/Games/Five_Nights_at_Freddys/src/reducers/cameraReducer.js b/Games/Five_Nights_at_Freddys/src/reducers/cameraReducer.js
new file mode 100644
index 0000000000..e0dd588c59
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/reducers/cameraReducer.js
@@ -0,0 +1,24 @@
+const originalState = {
+ camera: "Stage",
+ isCameraOpen: false,
+ areAnimatronicsMoving: false,
+};
+
+export default function camera(state = originalState, action) {
+ switch (action.type) {
+ case "CHANGE_CAMERA":
+ return { ...state, camera: action.content };
+ case "SET_IS_OPEN":
+ return {
+ ...state,
+ isCameraOpen: state.isCameraOpen ? false : true,
+ };
+ case "FORCE_CAMERA_CLOSE":
+ return { ...state, isCameraOpen: false };
+ case "CHANGE_ANIMATRONICS_MOVING":
+ return { ...state, areAnimatronicsMoving: action.content };
+
+ default:
+ return state;
+ }
+}
diff --git a/Games/Five_Nights_at_Freddys/src/reducers/configReducer.js b/Games/Five_Nights_at_Freddys/src/reducers/configReducer.js
new file mode 100644
index 0000000000..fe6de65a37
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/reducers/configReducer.js
@@ -0,0 +1,35 @@
+const originalState = {
+ hour: 0,
+ isPlaying: true,
+ energy: 100,
+ time: 7000,
+ blackout: false,
+ jumpscare: false,
+ gameOver: false,
+ cameraButtonDisappear: false,
+};
+
+export default function config(state = originalState, action) {
+ switch (action.type) {
+ case "CHANGE_HOUR":
+ if (state.jumpscare || state.gameOver) return state;
+ return { ...state, hour: state.hour + 1 };
+ case "CHANGE_ENERGY":
+ if (state.hour === 6) return state;
+ return { ...state, energy: state.energy - 1 };
+ case "CHANGE_TIME":
+ return { ...state, time: action.content };
+ case "CHANGE_BLACKOUT":
+ return { ...state, blackout: true };
+ case "CHANGE_IS_PLAYING":
+ return { ...state, isPlaying: action.content };
+ case "CHANGE_JUMPSCARE":
+ return { ...state, jumpscare: action.animatronic };
+ case "CHANGE_CAMERA_BUTTON":
+ return { ...state, cameraButtonDisappear: true };
+ case "SET_GAME_OVER":
+ return { ...state, gameOver: true };
+ default:
+ return state;
+ }
+}
diff --git a/Games/Five_Nights_at_Freddys/src/reducers/index.js b/Games/Five_Nights_at_Freddys/src/reducers/index.js
new file mode 100644
index 0000000000..93b06e6e4e
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/reducers/index.js
@@ -0,0 +1,20 @@
+import { combineReducers } from "redux";
+import cameraReducer from "./cameraReducer";
+import configReducer from "./configReducer";
+import officeReducer from "./officeReducer";
+import animatronicsReducer from "./animatronicsReducer";
+
+const appReducer = combineReducers({
+ cameraReducer,
+ configReducer,
+ officeReducer,
+ animatronicsReducer,
+});
+
+export default function rootReducer(state, action) {
+ if (action.type === "CLEAR_DATA") {
+ state = undefined;
+ }
+
+ return appReducer(state, action);
+}
diff --git a/Games/Five_Nights_at_Freddys/src/reducers/officeReducer.js b/Games/Five_Nights_at_Freddys/src/reducers/officeReducer.js
new file mode 100644
index 0000000000..abe1f06e1c
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/reducers/officeReducer.js
@@ -0,0 +1,31 @@
+const originalState = {
+ leftDoor: false,
+ rightDoor: false,
+ leftLight: false,
+ rightLight: false,
+};
+
+export default function office(state = originalState, action) {
+ switch (action.type) {
+ case "CHANGE_OFFICE_CONFIG":
+ if (action.obj === "leftLight" && state.leftDoor) return state;
+ if (action.obj === "rightLight" && state.rightDoor) return state;
+
+ if (action.obj === "leftDoor" && !state.leftDoor && state.leftLight)
+ return { ...state, leftLight: false, leftDoor: true };
+ if (
+ action.obj === "rightDoor" &&
+ !state.rightDoor &&
+ state.rightLight
+ )
+ return { ...state, rightLight: false, rightDoor: true };
+ state[action.obj] = !state[action.obj];
+ return state;
+
+ case "CLEAR_DATA":
+ return { ...originalState };
+
+ default:
+ return state;
+ }
+}
diff --git a/Games/Five_Nights_at_Freddys/src/service-worker.js b/Games/Five_Nights_at_Freddys/src/service-worker.js
new file mode 100644
index 0000000000..93d538ad5a
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/service-worker.js
@@ -0,0 +1,116 @@
+/* eslint-disable no-restricted-globals */
+
+// This service worker can be customized!
+// See https://developers.google.com/web/tools/workbox/modules
+// for the list of available Workbox modules, or add any other
+// code you'd like.
+// You can also remove this file if you'd prefer not to use a
+// service worker, and the Workbox build step will be skipped.
+
+import { clientsClaim } from "workbox-core";
+import { ExpirationPlugin } from "workbox-expiration";
+import { precacheAndRoute, createHandlerBoundToURL } from "workbox-precaching";
+import { registerRoute } from "workbox-routing";
+import {
+ StaleWhileRevalidate,
+ NetworkFirst,
+ CacheFirst,
+} from "workbox-strategies";
+// import { googleFontsCache } from "workbox-recipes";
+
+// googleFontsCache();
+
+clientsClaim();
+
+// Precache all of the assets generated by your build process.
+// Their URLs are injected into the manifest variable below.
+// This variable must be present somewhere in your service worker file,
+// even if you decide not to use precaching. See https://cra.link/PWA
+precacheAndRoute(self.__WB_MANIFEST);
+
+// Set up App Shell-style routing, so that all navigation requests
+// are fulfilled with your index.html shell. Learn more at
+// https://developers.google.com/web/fundamentals/architecture/app-shell
+const fileExtensionRegexp = new RegExp("/[^/?]+\\.[^/]+$");
+registerRoute(
+ // Return false to exempt requests from being fulfilled by index.html.
+ ({ request, url }) => {
+ // If this isn't a navigation, skip.
+ if (request.mode !== "navigate") {
+ return false;
+ } // If this is a URL that starts with /_, skip.
+
+ if (url.pathname.startsWith("/_")) {
+ return false;
+ } // If this looks like a URL for a resource, because it contains // a file extension, skip.
+
+ if (url.pathname.match(fileExtensionRegexp)) {
+ return false;
+ } // Return true to signal that we want to use the handler.
+
+ return true;
+ },
+ createHandlerBoundToURL(process.env.PUBLIC_URL + "/index.html")
+);
+
+// An example runtime caching route for requests that aren't handled by the
+// precache, in this case same-origin .png requests like those from in public/
+registerRoute(
+ // Add in any other file extensions or routing criteria as needed.
+ ({ url }) =>
+ url.origin === self.location.origin &&
+ (url.pathname.endsWith(".webp") || url.pathname.endsWith(".png")), // Customize this strategy as needed, e.g., by changing to CacheFirst.
+ new CacheFirst({
+ cacheName: "images",
+ plugins: [
+ // Ensure that once this runtime cache reaches a maximum size the
+ // least-recently used images are removed.
+ new ExpirationPlugin({
+ maxAgeSeconds: 24 * 60 * 60,
+ }),
+ ],
+ })
+);
+
+registerRoute(
+ // Add in any other file extensions or routing criteria as needed.
+ ({ url }) =>
+ url.origin === self.location.origin && url.pathname.endsWith(".mp3"), // Customize this strategy as needed, e.g., by changing to CacheFirst.
+ new CacheFirst({
+ cacheName: "audios",
+ plugins: [
+ // Ensure that once this runtime cache reaches a maximum size the
+ // least-recently used images are removed.
+ new ExpirationPlugin({
+ maxAgeSeconds: 24 * 60 * 60,
+ }),
+ ],
+ })
+);
+
+registerRoute(
+ ({ request }) => request.destination === "style",
+ new StaleWhileRevalidate({
+ cacheName: "static",
+ plugins: [new ExpirationPlugin({ maxEntries: 50 })],
+ })
+);
+
+registerRoute(
+ ({ request }) =>
+ request.destination === "script" || request.destination === "worker",
+ new NetworkFirst({
+ cacheName: "static-script",
+ plugins: [new ExpirationPlugin({ maxEntries: 50 })],
+ })
+);
+
+// This allows the web app to trigger skipWaiting via
+// registration.waiting.postMessage({type: 'SKIP_WAITING'})
+self.addEventListener("message", (event) => {
+ if (event.data && event.data.type === "SKIP_WAITING") {
+ self.skipWaiting();
+ }
+});
+
+// Any other custom service worker logic can go here.
diff --git a/Games/Five_Nights_at_Freddys/src/serviceWorker.js b/Games/Five_Nights_at_Freddys/src/serviceWorker.js
new file mode 100644
index 0000000000..3eade513cb
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/serviceWorker.js
@@ -0,0 +1,141 @@
+// This optional code is used to register a service worker.
+// register() is not called by default.
+
+// This lets the app load faster on subsequent visits in production, and gives
+// it offline capabilities. However, it also means that developers (and users)
+// will only see deployed updates on subsequent visits to a page, after all the
+// existing tabs open on the page have been closed, since previously cached
+// resources are updated in the background.
+
+// To learn more about the benefits of this model and instructions on how to
+// opt-in, read https://cra.link/PWA
+
+const isLocalhost = Boolean(
+ window.location.hostname === "localhost" ||
+ // [::1] is the IPv6 localhost address.
+ window.location.hostname === "[::1]" ||
+ // 127.0.0.0/8 are considered localhost for IPv4.
+ window.location.hostname.match(
+ /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
+ )
+);
+
+export function register(config) {
+ if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
+ // The URL constructor is available in all browsers that support SW.
+ const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
+ if (publicUrl.origin !== window.location.origin) {
+ // Our service worker won't work if PUBLIC_URL is on a different origin
+ // from what our page is served on. This might happen if a CDN is used to
+
+ return;
+ }
+
+ window.addEventListener("load", () => {
+ const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
+
+ if (isLocalhost) {
+ // This is running on localhost. Let's check if a service worker still exists or not.
+ checkValidServiceWorker(swUrl, config);
+
+ // Add some additional logging to localhost, pointing developers to the
+ // service worker/PWA documentation.
+ navigator.serviceWorker.ready.then(() => {
+ console.log(
+ "This web app is being served cache-first by a service " +
+ "worker. To learn more, visit https://cra.link/PWA"
+ );
+ });
+ } else {
+ // Is not localhost. Just register service worker
+ registerValidSW(swUrl, config);
+ }
+ });
+ }
+}
+
+function registerValidSW(swUrl, config) {
+ navigator.serviceWorker
+ .register(swUrl)
+ .then((registration) => {
+ registration.onupdatefound = () => {
+ const installingWorker = registration.installing;
+ if (installingWorker == null) {
+ return;
+ }
+ installingWorker.onstatechange = () => {
+ if (installingWorker.state === "installed") {
+ if (navigator.serviceWorker.controller) {
+ // At this point, the updated precached content has been fetched,
+ // but the previous service worker will still serve the older
+ // content until all client tabs are closed.
+ console.log(
+ "New content is available and will be used when all " +
+ "tabs for this page are closed. See https://cra.link/PWA."
+ );
+
+ // Execute callback
+ if (config && config.onUpdate) {
+ config.onUpdate(registration);
+ }
+ } else {
+ // At this point, everything has been precached.
+ // It's the perfect time to display a
+ // "Content is cached for offline use." message.
+ console.log("Content is cached for offline use.");
+
+ // Execute callback
+ if (config && config.onSuccess) {
+ config.onSuccess(registration);
+ }
+ }
+ }
+ };
+ };
+ })
+ .catch((error) => {
+ console.error("Error during service worker registration:", error);
+ });
+}
+
+function checkValidServiceWorker(swUrl, config) {
+ // Check if the service worker can be found. If it can't reload the page.
+ fetch(swUrl, {
+ headers: { "Service-Worker": "script" },
+ })
+ .then((response) => {
+ // Ensure service worker exists, and that we really are getting a JS file.
+ const contentType = response.headers.get("content-type");
+ if (
+ response.status === 404 ||
+ (contentType != null && contentType.indexOf("javascript") === -1)
+ ) {
+ // No service worker found. Probably a different app. Reload the page.
+ navigator.serviceWorker.ready.then((registration) => {
+ registration.unregister().then(() => {
+ window.location.reload();
+ });
+ });
+ } else {
+ // Service worker found. Proceed as normal.
+ registerValidSW(swUrl, config);
+ }
+ })
+ .catch(() => {
+ console.log(
+ "No internet connection found. App is running in offline mode."
+ );
+ });
+}
+
+export function unregister() {
+ if ("serviceWorker" in navigator) {
+ navigator.serviceWorker.ready
+ .then((registration) => {
+ registration.unregister();
+ })
+ .catch((error) => {
+ console.error(error.message);
+ });
+ }
+}
diff --git a/Games/Five_Nights_at_Freddys/src/store/store.js b/Games/Five_Nights_at_Freddys/src/store/store.js
new file mode 100644
index 0000000000..bdae8ded07
--- /dev/null
+++ b/Games/Five_Nights_at_Freddys/src/store/store.js
@@ -0,0 +1,6 @@
+import { createStore } from "redux";
+import reducers from "../reducers/index";
+
+const store = createStore(reducers);
+
+export default store;
diff --git a/Games/Hedgehog_Havoc/Hedgehog.png b/Games/Hedgehog_Havoc/Hedgehog.png
new file mode 100644
index 0000000000..c3ffb8b61f
Binary files /dev/null and b/Games/Hedgehog_Havoc/Hedgehog.png differ
diff --git a/Games/Hedgehog_Havoc/index.html b/Games/Hedgehog_Havoc/index.html
new file mode 100644
index 0000000000..e5c6fd573c
--- /dev/null
+++ b/Games/Hedgehog_Havoc/index.html
@@ -0,0 +1,29 @@
+
+
+
+
+ HEDGEHOG HAVOC
+
+
+
+
+
+
+
+
+ Game Over
+
+
+
+Click to jump — Grab the carrots / avoid the hedgehogs
+
+
+
+
+
+
+
+
diff --git a/Games/Hedgehog_Havoc/script.js b/Games/Hedgehog_Havoc/script.js
new file mode 100644
index 0000000000..23783a8a4b
--- /dev/null
+++ b/Games/Hedgehog_Havoc/script.js
@@ -0,0 +1,1374 @@
+//THREEJS RELATED VARIABLES
+
+var scene,
+ camera, fieldOfView, aspectRatio, nearPlane, farPlane,
+ gobalLight, shadowLight, backLight,
+ renderer,
+ container,
+ controls,
+ clock;
+var delta = 0;
+var floorRadius = 200;
+var speed = 6;
+var distance = 0;
+var level = 1;
+var levelInterval;
+var levelUpdateFreq = 3000;
+var initSpeed = 5;
+var maxSpeed = 48;
+var monsterPos = .65;
+var monsterPosTarget = .65;
+var floorRotation = 0;
+var collisionObstacle = 10;
+var collisionBonus = 20;
+var gameStatus = "play";
+var cameraPosGame = 160;
+var cameraPosGameOver = 260;
+var monsterAcceleration = 0.004;
+var malusClearColor = 0xb44b39;
+var malusClearAlpha = 0;
+var audio = new Audio('https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/Antonio-Vivaldi-Summer_01.mp3');
+
+var fieldGameOver, fieldDistance;
+
+//SCREEN & MOUSE VARIABLES
+
+var HEIGHT, WIDTH, windowHalfX, windowHalfY,
+ mousePos = {
+ x: 0,
+ y: 0
+ };
+
+//3D OBJECTS VARIABLES
+
+var hero;
+
+
+// Materials
+var blackMat = new THREE.MeshPhongMaterial({
+ color: 0x100707,
+ shading:THREE.FlatShading,
+ });
+
+var brownMat = new THREE.MeshPhongMaterial({
+ color: 0xb44b39,
+ shininess:0,
+ shading:THREE.FlatShading,
+ });
+
+var greenMat = new THREE.MeshPhongMaterial({
+ color: 0x7abf8e,
+ shininess:0,
+ shading:THREE.FlatShading,
+ });
+
+ var pinkMat = new THREE.MeshPhongMaterial({
+ color: 0xdc5f45,//0xb43b29,//0xff5b49,
+ shininess:0,
+ shading:THREE.FlatShading,
+ });
+
+ var lightBrownMat = new THREE.MeshPhongMaterial({
+ color: 0xe07a57,
+ shading:THREE.FlatShading,
+ });
+
+ var whiteMat = new THREE.MeshPhongMaterial({
+ color: 0xa49789,
+ shading:THREE.FlatShading,
+ });
+ var skinMat = new THREE.MeshPhongMaterial({
+ color: 0xff9ea5,
+ shading:THREE.FlatShading
+ });
+
+
+// OTHER VARIABLES
+
+var PI = Math.PI;
+
+//INIT THREE JS, SCREEN AND MOUSE EVENTS
+
+function initScreenAnd3D() {
+
+ HEIGHT = window.innerHeight;
+ WIDTH = window.innerWidth;
+ windowHalfX = WIDTH / 2;
+ windowHalfY = HEIGHT / 2;
+
+ scene = new THREE.Scene();
+
+ scene.fog = new THREE.Fog(0xd6eae6, 160,350);
+
+ aspectRatio = WIDTH / HEIGHT;
+ fieldOfView = 50;
+ nearPlane = 1;
+ farPlane = 2000;
+ camera = new THREE.PerspectiveCamera(
+ fieldOfView,
+ aspectRatio,
+ nearPlane,
+ farPlane
+ );
+ camera.position.x = 0;
+ camera.position.z = cameraPosGame;
+ camera.position.y = 30;
+ camera.lookAt(new THREE.Vector3(0, 30, 0));
+
+ renderer = new THREE.WebGLRenderer({
+ alpha: true,
+ antialias: true
+ });
+ renderer.setPixelRatio(window.devicePixelRatio);
+ renderer.setClearColor( malusClearColor, malusClearAlpha);
+
+ renderer.setSize(WIDTH, HEIGHT);
+ renderer.shadowMap.enabled = true;
+
+ container = document.getElementById('world');
+ container.appendChild(renderer.domElement);
+
+ window.addEventListener('resize', handleWindowResize, false);
+ document.addEventListener('mousedown', handleMouseDown, false);
+ document.addEventListener("touchend", handleMouseDown, false);
+
+ /*
+ controls = new THREE.OrbitControls(camera, renderer.domElement);
+ //controls.minPolarAngle = -Math.PI / 2;
+ //controls.maxPolarAngle = Math.PI / 2;
+ //controls.noZoom = true;
+ controls.noPan = true;
+ //*/
+
+ clock = new THREE.Clock();
+
+}
+
+function handleWindowResize() {
+ HEIGHT = window.innerHeight;
+ WIDTH = window.innerWidth;
+ windowHalfX = WIDTH / 2;
+ windowHalfY = HEIGHT / 2;
+ renderer.setSize(WIDTH, HEIGHT);
+ camera.aspect = WIDTH / HEIGHT;
+ camera.updateProjectionMatrix();
+}
+
+
+function handleMouseDown(event){
+ if (gameStatus == "play") hero.jump();
+ else if (gameStatus == "readyToReplay"){
+ replay();
+ }
+}
+
+function createLights() {
+ globalLight = new THREE.AmbientLight(0xffffff, .9);
+
+ shadowLight = new THREE.DirectionalLight(0xffffff, 1);
+ shadowLight.position.set(-30, 40, 20);
+ shadowLight.castShadow = true;
+ shadowLight.shadow.camera.left = -400;
+ shadowLight.shadow.camera.right = 400;
+ shadowLight.shadow.camera.top = 400;
+ shadowLight.shadow.camera.bottom = -400;
+ shadowLight.shadow.camera.near = 1;
+ shadowLight.shadow.camera.far = 2000;
+ shadowLight.shadow.mapSize.width = shadowLight.shadow.mapSize.height = 2048;
+
+ scene.add(globalLight);
+ scene.add(shadowLight);
+
+}
+
+function createFloor() {
+
+ floorShadow = new THREE.Mesh(new THREE.SphereGeometry(floorRadius, 50, 50), new THREE.MeshPhongMaterial({
+ color: 0x7abf8e,
+ specular:0x000000,
+ shininess:1,
+ transparent:true,
+ opacity:.5
+ }));
+ //floorShadow.rotation.x = -Math.PI / 2;
+ floorShadow.receiveShadow = true;
+
+ floorGrass = new THREE.Mesh(new THREE.SphereGeometry(floorRadius-.5, 50, 50), new THREE.MeshBasicMaterial({
+ color: 0x7abf8e
+ }));
+ //floor.rotation.x = -Math.PI / 2;
+ floorGrass.receiveShadow = false;
+
+ floor = new THREE.Group();
+ floor.position.y = -floorRadius;
+
+ floor.add(floorShadow);
+ floor.add(floorGrass);
+ scene.add(floor);
+
+}
+
+Hero = function() {
+ this.status = "running";
+ this.runningCycle = 0;
+ this.mesh = new THREE.Group();
+ this.body = new THREE.Group();
+ this.mesh.add(this.body);
+
+ var torsoGeom = new THREE.CubeGeometry(7, 7, 10, 1);
+
+ this.torso = new THREE.Mesh(torsoGeom, brownMat);
+ this.torso.position.z = 0;
+ this.torso.position.y = 7;
+ this.torso.castShadow = true;
+ this.body.add(this.torso);
+
+ var pantsGeom = new THREE.CubeGeometry(9, 9, 5, 1);
+ this.pants = new THREE.Mesh(pantsGeom, whiteMat);
+ this.pants.position.z = -3;
+ this.pants.position.y = 0;
+ this.pants.castShadow = true;
+ this.torso.add(this.pants);
+
+ var tailGeom = new THREE.CubeGeometry(3, 3, 3, 1);
+ tailGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,-2));
+ this.tail = new THREE.Mesh(tailGeom, lightBrownMat);
+ this.tail.position.z = -4;
+ this.tail.position.y = 5;
+ this.tail.castShadow = true;
+ this.torso.add(this.tail);
+
+ this.torso.rotation.x = -Math.PI/8;
+
+ var headGeom = new THREE.CubeGeometry(10, 10, 13, 1);
+
+ headGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,7.5));
+ this.head = new THREE.Mesh(headGeom, brownMat);
+ this.head.position.z = 2;
+ this.head.position.y = 11;
+ this.head.castShadow = true;
+ this.body.add(this.head);
+
+ var cheekGeom = new THREE.CubeGeometry(1, 4, 4, 1);
+ this.cheekR = new THREE.Mesh(cheekGeom, pinkMat);
+ this.cheekR.position.x = -5;
+ this.cheekR.position.z = 7;
+ this.cheekR.position.y = -2.5;
+ this.cheekR.castShadow = true;
+ this.head.add(this.cheekR);
+
+ this.cheekL = this.cheekR.clone();
+ this.cheekL.position.x = - this.cheekR.position.x;
+ this.head.add(this.cheekL);
+
+
+ var noseGeom = new THREE.CubeGeometry(6, 6, 3, 1);
+ this.nose = new THREE.Mesh(noseGeom, lightBrownMat);
+ this.nose.position.z = 13.5;
+ this.nose.position.y = 2.6;
+ this.nose.castShadow = true;
+ this.head.add(this.nose);
+
+ var mouthGeom = new THREE.CubeGeometry(4, 2, 4, 1);
+ mouthGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,0,3));
+ mouthGeom.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI/12));
+ this.mouth = new THREE.Mesh(mouthGeom, brownMat);
+ this.mouth.position.z = 8;
+ this.mouth.position.y = -4;
+ this.mouth.castShadow = true;
+ this.head.add(this.mouth);
+
+
+ var pawFGeom = new THREE.CubeGeometry(3,3,3, 1);
+ this.pawFR = new THREE.Mesh(pawFGeom, lightBrownMat);
+ this.pawFR.position.x = -2;
+ this.pawFR.position.z = 6;
+ this.pawFR.position.y = 1.5;
+ this.pawFR.castShadow = true;
+ this.body.add(this.pawFR);
+
+ this.pawFL = this.pawFR.clone();
+ this.pawFL.position.x = - this.pawFR.position.x;
+ this.pawFL.castShadow = true;
+ this.body.add(this.pawFL);
+
+ var pawBGeom = new THREE.CubeGeometry(3,3,6, 1);
+ this.pawBL = new THREE.Mesh(pawBGeom, lightBrownMat);
+ this.pawBL.position.y = 1.5;
+ this.pawBL.position.z = 0;
+ this.pawBL.position.x = 5;
+ this.pawBL.castShadow = true;
+ this.body.add(this.pawBL);
+
+ this.pawBR = this.pawBL.clone();
+ this.pawBR.position.x = - this.pawBL.position.x;
+ this.pawBR.castShadow = true;
+ this.body.add(this.pawBR);
+
+ var earGeom = new THREE.CubeGeometry(7, 18, 2, 1);
+ earGeom.vertices[6].x+=2;
+ earGeom.vertices[6].z+=.5;
+
+ earGeom.vertices[7].x+=2;
+ earGeom.vertices[7].z-=.5;
+
+ earGeom.vertices[2].x-=2;
+ earGeom.vertices[2].z-=.5;
+
+ earGeom.vertices[3].x-=2;
+ earGeom.vertices[3].z+=.5;
+ earGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,9,0));
+
+ this.earL = new THREE.Mesh(earGeom, brownMat);
+ this.earL.position.x = 2;
+ this.earL.position.z = 2.5;
+ this.earL.position.y = 5;
+ this.earL.rotation.z = -Math.PI/12;
+ this.earL.castShadow = true;
+ this.head.add(this.earL);
+
+ this.earR = this.earL.clone();
+ this.earR.position.x = -this.earL.position.x;
+ this.earR.rotation.z = -this.earL.rotation.z;
+ this.earR.castShadow = true;
+ this.head.add(this.earR);
+
+ var eyeGeom = new THREE.CubeGeometry(2,4,4);
+
+ this.eyeL = new THREE.Mesh(eyeGeom, whiteMat);
+ this.eyeL.position.x = 5;
+ this.eyeL.position.z = 5.5;
+ this.eyeL.position.y = 2.9;
+ this.eyeL.castShadow = true;
+ this.head.add(this.eyeL);
+
+ var irisGeom = new THREE.CubeGeometry(.6,2,2);
+
+ this.iris = new THREE.Mesh(irisGeom, blackMat);
+ this.iris.position.x = 1.2;
+ this.iris.position.y = 1;
+ this.iris.position.z = 1;
+ this.eyeL.add(this.iris);
+
+ this.eyeR = this.eyeL.clone();
+ this.eyeR.children[0].position.x = -this.iris.position.x;
+
+
+ this.eyeR.position.x = -this.eyeL.position.x;
+ this.head.add(this.eyeR);
+
+ this.body.traverse(function(object) {
+ if (object instanceof THREE.Mesh) {
+ object.castShadow = true;
+ object.receiveShadow = true;
+ }
+ });
+}
+
+BonusParticles = function(){
+ this.mesh = new THREE.Group();
+ var bigParticleGeom = new THREE.CubeGeometry(10,10,10,1);
+ var smallParticleGeom = new THREE.CubeGeometry(5,5,5,1);
+ this.parts = [];
+ for (var i=0; i<10; i++){
+ var partPink = new THREE.Mesh(bigParticleGeom, pinkMat);
+ var partGreen = new THREE.Mesh(smallParticleGeom, greenMat);
+ partGreen.scale.set(.5,.5,.5);
+ this.parts.push(partPink);
+ this.parts.push(partGreen);
+ this.mesh.add(partPink);
+ this.mesh.add(partGreen);
+ }
+}
+
+BonusParticles.prototype.explose = function(){
+ var _this = this;
+ var explosionSpeed = .5;
+ for(var i=0; i.2) TweenMax.to([this.eyeR.scale, this.eyeL.scale], sp/8, {y:0, ease:Power1.easeInOut, yoyo:true, repeat:1});
+
+}
+
+Hero.prototype.hang = function(){
+ var _this = this;
+ var sp = 1;
+ var ease = Power4.easeOut;
+
+ TweenMax.killTweensOf(this.eyeL.scale);
+ TweenMax.killTweensOf(this.eyeR.scale);
+
+ this.body.rotation.x = 0;
+ this.torso.rotation.x = 0;
+ this.body.position.y = 0;
+ this.torso.position.y = 7;
+
+ TweenMax.to(this.mesh.rotation, sp, {y:0, ease:ease});
+ TweenMax.to(this.mesh.position, sp, {y:-7, z:6, ease:ease});
+ TweenMax.to(this.head.rotation, sp, {x:Math.PI/6, ease:ease, onComplete:function(){_this.nod();}});
+
+ TweenMax.to(this.earL.rotation, sp, {x:Math.PI/3, ease:ease});
+ TweenMax.to(this.earR.rotation, sp, {x:Math.PI/3, ease:ease});
+
+ TweenMax.to(this.pawFL.position, sp, {y:-1, z:3, ease:ease});
+ TweenMax.to(this.pawFR.position, sp, {y:-1, z:3, ease:ease});
+ TweenMax.to(this.pawBL.position, sp, {y:-2, z:-3, ease:ease});
+ TweenMax.to(this.pawBR.position, sp, {y:-2, z:-3, ease:ease});
+
+ TweenMax.to(this.eyeL.scale, sp, {y:1, ease:ease});
+ TweenMax.to(this.eyeR.scale, sp, {y:1, ease:ease});
+}
+
+Monster.prototype.nod = function(){
+ var _this = this;
+ var sp = 1 + Math.random()*2;
+
+ // HEAD
+ var tHeadRotY = -Math.PI/3 + Math.random()*.5;
+ var tHeadRotX = Math.PI/3 - .2 + Math.random()*.4;
+ TweenMax.to(this.head.rotation, sp, {x:tHeadRotX, y:tHeadRotY, ease:Power4.easeInOut, onComplete:function(){_this.nod()}});
+
+ // TAIL
+
+ var tTailRotY = -Math.PI/4;
+ TweenMax.to(this.tail.rotation, sp/8, {y:tTailRotY, ease:Power1.easeInOut, yoyo:true, repeat:8});
+
+ // EYES
+
+ TweenMax.to([this.eyeR.scale, this.eyeL.scale], sp/20, {y:0, ease:Power1.easeInOut, yoyo:true, repeat:1});
+}
+
+Monster.prototype.sit = function(){
+ var sp = 1.2;
+ var ease = Power4.easeOut;
+ var _this = this;
+ TweenMax.to(this.torso.rotation, sp, {x:-1.3, ease:ease});
+ TweenMax.to(this.torso.position, sp, {y:-5, ease:ease, onComplete:function(){
+ _this.nod();
+ gameStatus = "readyToReplay";
+ }});
+
+ TweenMax.to(this.head.rotation, sp, {x:Math.PI/3, y :-Math.PI/3, ease:ease});
+ TweenMax.to(this.tail.rotation, sp, {x:2, y:Math.PI/4, ease:ease});
+ TweenMax.to(this.pawBL.rotation, sp, {x:-.1, ease:ease});
+ TweenMax.to(this.pawBR.rotation, sp, {x:-.1, ease:ease});
+ TweenMax.to(this.pawFL.rotation, sp, {x:1, ease:ease});
+ TweenMax.to(this.pawFR.rotation, sp, {x:1, ease:ease});
+ TweenMax.to(this.mouth.rotation, sp, {x:.3, ease:ease});
+ TweenMax.to(this.eyeL.scale, sp, {y:1, ease:ease});
+ TweenMax.to(this.eyeR.scale, sp, {y:1, ease:ease});
+
+ //TweenMax.to(this.body.rotation, sp, {y:Math.PI/4});
+
+}
+
+
+Carrot = function() {
+ this.angle = 0;
+ this.mesh = new THREE.Group();
+
+ var bodyGeom = new THREE.CylinderGeometry(5,3, 10, 4,1);
+ bodyGeom.vertices[8].y+=2;
+ bodyGeom.vertices[9].y-=3;
+
+ this.body = new THREE.Mesh(bodyGeom, pinkMat);
+
+ var leafGeom = new THREE.CubeGeometry(5,10,1,1);
+ leafGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,5,0));
+ leafGeom.vertices[2].x-=1;
+ leafGeom.vertices[3].x-=1;
+ leafGeom.vertices[6].x+=1;
+ leafGeom.vertices[7].x+=1;
+
+ this.leaf1 = new THREE.Mesh(leafGeom,greenMat);
+ this.leaf1.position.y = 7;
+ this.leaf1.rotation.z = .3;
+ this.leaf1.rotation.x = .2;
+
+ this.leaf2 = this.leaf1.clone();
+ this.leaf2.scale.set(1,1.3,1);
+ this.leaf2.position.y = 7;
+ this.leaf2.rotation.z = -.3;
+ this.leaf2.rotation.x = -.2;
+
+ this.mesh.add(this.body);
+ this.mesh.add(this.leaf1);
+ this.mesh.add(this.leaf2);
+
+ this.body.traverse(function(object) {
+ if (object instanceof THREE.Mesh) {
+ object.castShadow = true;
+ object.receiveShadow = true;
+ }
+ });
+}
+
+Hedgehog = function() {
+ this.angle = 0;
+ this.status="ready";
+ this.mesh = new THREE.Group();
+ var bodyGeom = new THREE.CubeGeometry(6,6,6,1);
+ this.body = new THREE.Mesh(bodyGeom, blackMat);
+
+ var headGeom = new THREE.CubeGeometry(5,5,7,1);
+ this.head= new THREE.Mesh(headGeom, lightBrownMat);
+ this.head.position.z = 6;
+ this.head.position.y = -.5;
+
+ var noseGeom = new THREE.CubeGeometry(1.5,1.5,1.5,1);
+ this.nose = new THREE.Mesh(noseGeom, blackMat);
+ this.nose.position.z = 4;
+ this.nose.position.y = 2;
+
+ var eyeGeom = new THREE.CubeGeometry(1,3,3);
+
+ this.eyeL = new THREE.Mesh(eyeGeom, whiteMat);
+ this.eyeL.position.x = 2.2;
+ this.eyeL.position.z = -.5;
+ this.eyeL.position.y = .8;
+ this.eyeL.castShadow = true;
+ this.head.add(this.eyeL);
+
+ var irisGeom = new THREE.CubeGeometry(.5,1,1);
+
+ this.iris = new THREE.Mesh(irisGeom, blackMat);
+ this.iris.position.x = .5;
+ this.iris.position.y = .8;
+ this.iris.position.z = .8;
+ this.eyeL.add(this.iris);
+
+ this.eyeR = this.eyeL.clone();
+ this.eyeR.children[0].position.x = -this.iris.position.x;
+ this.eyeR.position.x = -this.eyeL.position.x;
+
+ var spikeGeom = new THREE.CubeGeometry(.5,2,.5,1);
+ spikeGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,1,0));
+
+ for (var i=0; i<9; i++){
+ var row = (i%3);
+ var col = Math.floor(i/3);
+ var sb = new THREE.Mesh(spikeGeom, blackMat);
+ sb.rotation.x =-Math.PI/2 + (Math.PI/12*row) -.5 + Math.random();
+ sb.position.z = -3;
+ sb.position.y = -2 + row*2;
+ sb.position.x = -2 + col*2;
+ this.body.add(sb);
+ var st = new THREE.Mesh(spikeGeom, blackMat);
+ st.position.y = 3;
+ st.position.x = -2 + row*2;
+ st.position.z = -2 + col*2;
+ st.rotation.z = Math.PI/6 - (Math.PI/6*row) -.5 + Math.random();
+ this.body.add(st);
+
+ var sr = new THREE.Mesh(spikeGeom, blackMat);
+ sr.position.x = 3;
+ sr.position.y = -2 + row*2;
+ sr.position.z = -2 + col*2;
+ sr.rotation.z = -Math.PI/2 + (Math.PI/12*row) -.5 + Math.random();
+ this.body.add(sr);
+
+ var sl = new THREE.Mesh(spikeGeom, blackMat);
+ sl.position.x = -3;
+ sl.position.y = -2 + row*2;
+ sl.position.z = -2 + col*2;
+ sl.rotation.z = Math.PI/2 - (Math.PI/12*row) -.5 + Math.random();;
+ this.body.add(sl);
+ }
+
+ this.head.add(this.eyeR);
+ var earGeom = new THREE.CubeGeometry(2, 2, .5, 1);
+ this.earL = new THREE.Mesh(earGeom, lightBrownMat);
+ this.earL.position.x = 2.5;
+ this.earL.position.z = -2.5;
+ this.earL.position.y = 2.5;
+ this.earL.rotation.z = -Math.PI/12;
+ this.earL.castShadow = true;
+ this.head.add(this.earL);
+
+ this.earR = this.earL.clone();
+ this.earR.position.x = -this.earL.position.x;
+ this.earR.rotation.z = -this.earL.rotation.z;
+ this.earR.castShadow = true;
+ this.head.add(this.earR);
+
+ var mouthGeom = new THREE.CubeGeometry( 1, 1,.5, 1);
+ this.mouth = new THREE.Mesh(mouthGeom, blackMat);
+ this.mouth.position.z = 3.5;
+ this.mouth.position.y = -1.5;
+ this.head.add(this.mouth);
+
+
+ this.mesh.add(this.body);
+ this.body.add(this.head);
+ this.head.add(this.nose);
+
+ this.mesh.traverse(function(object) {
+ if (object instanceof THREE.Mesh) {
+ object.castShadow = true;
+ object.receiveShadow = true;
+ }
+ });
+}
+
+Hedgehog.prototype.nod = function(){
+ var _this = this;
+ var speed = .1 + Math.random()*.5;
+ var angle = -Math.PI/4 + Math.random()*Math.PI/2;
+ TweenMax.to(this.head.rotation, speed, {y:angle, onComplete:function(){
+ _this.nod();
+ }});
+}
+
+
+function createHero() {
+ hero = new Hero();
+ hero.mesh.rotation.y = Math.PI/2;
+ scene.add(hero.mesh);
+ hero.nod();
+}
+
+function createMonster() {
+
+ monster = new Monster();
+ monster.mesh.position.z = 20;
+ //monster.mesh.scale.set(1.2,1.2,1.2);
+ scene.add(monster.mesh);
+ updateMonsterPosition();
+
+}
+
+function updateMonsterPosition(){
+ monster.run();
+ monsterPosTarget -= delta*monsterAcceleration;
+ monsterPos += (monsterPosTarget-monsterPos) *delta;
+ if (monsterPos < .56){
+ gameOver();
+ }
+
+ var angle = Math.PI*monsterPos;
+ monster.mesh.position.y = - floorRadius + Math.sin(angle)*(floorRadius + 12);
+ monster.mesh.position.x = Math.cos(angle)*(floorRadius+15);
+ monster.mesh.rotation.z = -Math.PI/2 + angle;
+}
+
+function gameOver(){
+ fieldGameOver.className = "show";
+ gameStatus = "gameOver";
+ monster.sit();
+ hero.hang();
+ monster.heroHolder.add(hero.mesh);
+ TweenMax.to(this, 1, {speed:0});
+ TweenMax.to(camera.position, 3, {z:cameraPosGameOver, y: 60, x:-30});
+ carrot.mesh.visible = false;
+ obstacle.mesh.visible = false;
+ clearInterval(levelInterval);
+}
+
+function replay(){
+
+ gameStatus = "preparingToReplay"
+
+ fieldGameOver.className = "";
+
+ TweenMax.killTweensOf(monster.pawFL.position);
+ TweenMax.killTweensOf(monster.pawFR.position);
+ TweenMax.killTweensOf(monster.pawBL.position);
+ TweenMax.killTweensOf(monster.pawBR.position);
+
+ TweenMax.killTweensOf(monster.pawFL.rotation);
+ TweenMax.killTweensOf(monster.pawFR.rotation);
+ TweenMax.killTweensOf(monster.pawBL.rotation);
+ TweenMax.killTweensOf(monster.pawBR.rotation);
+
+ TweenMax.killTweensOf(monster.tail.rotation);
+ TweenMax.killTweensOf(monster.head.rotation);
+ TweenMax.killTweensOf(monster.eyeL.scale);
+ TweenMax.killTweensOf(monster.eyeR.scale);
+
+ //TweenMax.killTweensOf(hero.head.rotation);
+
+ monster.tail.rotation.y = 0;
+
+ TweenMax.to(camera.position, 3, {z:cameraPosGame, x:0, y:30, ease:Power4.easeInOut});
+ TweenMax.to(monster.torso.rotation,2, {x:0, ease:Power4.easeInOut});
+ TweenMax.to(monster.torso.position,2, {y:0, ease:Power4.easeInOut});
+ TweenMax.to(monster.pawFL.rotation,2, {x:0, ease:Power4.easeInOut});
+ TweenMax.to(monster.pawFR.rotation,2, {x:0, ease:Power4.easeInOut});
+ TweenMax.to(monster.mouth.rotation,2, {x:.5, ease:Power4.easeInOut});
+
+
+ TweenMax.to(monster.head.rotation,2, {y:0, x:-.3, ease:Power4.easeInOut});
+
+ TweenMax.to(hero.mesh.position, 2, { x:20, ease:Power4.easeInOut});
+ TweenMax.to(hero.head.rotation, 2, { x:0, y:0, ease:Power4.easeInOut});
+ TweenMax.to(monster.mouth.rotation, 2, {x:.2, ease:Power4.easeInOut});
+ TweenMax.to(monster.mouth.rotation, 1, {x:.4, ease:Power4.easeIn, delay: 1, onComplete:function(){
+
+ resetGame();
+ }});
+
+}
+
+Fir = function() {
+ var height = 200;
+ var truncGeom = new THREE.CylinderGeometry(2,2,height, 6,1);
+ truncGeom.applyMatrix(new THREE.Matrix4().makeTranslation(0,height/2,0));
+ this.mesh = new THREE.Mesh(truncGeom, greenMat);
+ this.mesh.castShadow = true;
+}
+
+var firs = new THREE.Group();
+
+function createFirs(){
+
+ var nTrees = 100;
+ for(var i=0; i< nTrees; i++){
+ var phi = i*(Math.PI*2)/nTrees;
+ var theta = Math.PI/2;
+ //theta += .25 + Math.random()*.3;
+ theta += (Math.random()>.05)? .25 + Math.random()*.3 : - .35 - Math.random()*.1;
+
+ var fir = new Tree();
+ fir.mesh.position.x = Math.sin(theta)*Math.cos(phi)*floorRadius;
+ fir.mesh.position.y = Math.sin(theta)*Math.sin(phi)*(floorRadius-10);
+ fir.mesh.position.z = Math.cos(theta)*floorRadius;
+
+ var vec = fir.mesh.position.clone();
+ var axis = new THREE.Vector3(0,1,0);
+ fir.mesh.quaternion.setFromUnitVectors(axis, vec.clone().normalize());
+ floor.add(fir.mesh);
+ }
+}
+
+function createCarrot(){
+ carrot = new Carrot();
+ scene.add(carrot.mesh);
+}
+
+function updateCarrotPosition(){
+ carrot.mesh.rotation.y += delta * 6;
+ carrot.mesh.rotation.z = Math.PI/2 - (floorRotation+carrot.angle);
+ carrot.mesh.position.y = -floorRadius + Math.sin(floorRotation+carrot.angle) * (floorRadius+50);
+ carrot.mesh.position.x = Math.cos(floorRotation+carrot.angle) * (floorRadius+50);
+
+}
+
+function updateObstaclePosition(){
+ if (obstacle.status=="flying")return;
+
+ // TODO fix this,
+ if (floorRotation+obstacle.angle > 2.5 ){
+ obstacle.angle = -floorRotation + Math.random()*.3;
+ obstacle.body.rotation.y = Math.random() * Math.PI*2;
+ }
+
+ obstacle.mesh.rotation.z = floorRotation + obstacle.angle - Math.PI/2;
+ obstacle.mesh.position.y = -floorRadius + Math.sin(floorRotation+obstacle.angle) * (floorRadius+3);
+ obstacle.mesh.position.x = Math.cos(floorRotation+obstacle.angle) * (floorRadius+3);
+
+}
+
+function updateFloorRotation(){
+ floorRotation += delta*.03 * speed;
+ floorRotation = floorRotation%(Math.PI*2);
+ floor.rotation.z = floorRotation;
+}
+
+function createObstacle(){
+ obstacle = new Hedgehog();
+ obstacle.body.rotation.y = -Math.PI/2;
+ obstacle.mesh.scale.set(1.1,1.1,1.1);
+ obstacle.mesh.position.y = floorRadius+4;
+ obstacle.nod();
+ scene.add(obstacle.mesh);
+}
+
+function createBonusParticles(){
+ bonusParticles = new BonusParticles();
+ bonusParticles.mesh.visible = false;
+ scene.add(bonusParticles.mesh);
+
+}
+
+
+
+function checkCollision(){
+ var db = hero.mesh.position.clone().sub(carrot.mesh.position.clone());
+ var dm = hero.mesh.position.clone().sub(obstacle.mesh.position.clone());
+
+ if(db.length() < collisionBonus){
+ getBonus();
+ }
+
+ if(dm.length() < collisionObstacle && obstacle.status != "flying"){
+ getMalus();
+ }
+}
+
+function getBonus(){
+ bonusParticles.mesh.position.copy(carrot.mesh.position);
+ bonusParticles.mesh.visible = true;
+ bonusParticles.explose();
+ carrot.angle += Math.PI/2;
+ //speed*=.95;
+ monsterPosTarget += .025;
+
+}
+
+function getMalus(){
+ obstacle.status="flying";
+ var tx = (Math.random()>.5)? -20-Math.random()*10 : 20+Math.random()*5;
+ TweenMax.to(obstacle.mesh.position, 4, {x:tx, y:Math.random()*50, z:350, ease:Power4.easeOut});
+ TweenMax.to(obstacle.mesh.rotation, 4, {x:Math.PI*3, z:Math.PI*3, y:Math.PI*6, ease:Power4.easeOut, onComplete:function(){
+ obstacle.status = "ready";
+ obstacle.body.rotation.y = Math.random() * Math.PI*2;
+ obstacle.angle = -floorRotation - Math.random()*.4;
+
+ obstacle.angle = obstacle.angle%(Math.PI*2);
+ obstacle.mesh.rotation.x = 0;
+ obstacle.mesh.rotation.y = 0;
+ obstacle.mesh.rotation.z = 0;
+ obstacle.mesh.position.z = 0;
+
+ }});
+ //
+ monsterPosTarget -= .04;
+ TweenMax.from(this, .5, {malusClearAlpha:.5, onUpdate:function(){
+ renderer.setClearColor(malusClearColor, malusClearAlpha );
+ }})
+}
+
+function updateDistance(){
+ distance += delta*speed;
+ var d = distance/2;
+ fieldDistance.innerHTML = Math.floor(d);
+}
+
+function updateLevel(){
+ if (speed >= maxSpeed) return;
+ level++;
+ speed += 2;
+}
+
+function loop(){
+ delta = clock.getDelta();
+ updateFloorRotation();
+
+ if (gameStatus == "play"){
+
+ if (hero.status == "running"){
+ hero.run();
+ }
+ updateDistance();
+ updateMonsterPosition();
+ updateCarrotPosition();
+ updateObstaclePosition();
+ checkCollision();
+ }
+
+ render();
+ requestAnimationFrame(loop);
+}
+
+function render(){
+ renderer.render(scene, camera);
+}
+
+window.addEventListener('load', init, false);
+
+function init(event){
+ initScreenAnd3D();
+ createLights();
+ createFloor()
+ createHero();
+ createMonster();
+ createFirs();
+ createCarrot();
+ createBonusParticles();
+ createObstacle();
+ initUI();
+ resetGame();
+ loop();
+
+ //setInterval(hero.blink.bind(hero), 3000);
+}
+
+function resetGame(){
+ scene.add(hero.mesh);
+ hero.mesh.rotation.y = Math.PI/2;
+ hero.mesh.position.y = 0;
+ hero.mesh.position.z = 0;
+ hero.mesh.position.x = 0;
+
+ monsterPos = .56;
+ monsterPosTarget = .65;
+ speed = initSpeed;
+ level = 0;
+ distance = 0;
+ carrot.mesh.visible = true;
+ obstacle.mesh.visible = true;
+ gameStatus = "play";
+ hero.status = "running";
+ hero.nod();
+ audio.play();
+ updateLevel();
+ levelInterval = setInterval(updateLevel, levelUpdateFreq);
+}
+
+function initUI(){
+ fieldDistance = document.getElementById("distValue");
+ fieldGameOver = document.getElementById("gameoverInstructions");
+
+}
+
+
+
+////////////////////////////////////////////////
+// MODELS
+////////////////////////////////////////////////
+
+// TREE
+
+Tree = function(){
+ this.mesh = new THREE.Object3D();
+ this.trunc = new Trunc();
+ this.mesh.add(this.trunc.mesh);
+}
+
+
+Trunc = function(){
+ var truncHeight = 50 + Math.random()*150;
+ var topRadius = 1+Math.random()*5;
+ var bottomRadius = 5+Math.random()*5;
+ var mats = [blackMat, brownMat, pinkMat, whiteMat, greenMat, lightBrownMat, pinkMat];
+ var matTrunc = blackMat;//mats[Math.floor(Math.random()*mats.length)];
+ var nhSegments = 3;//Math.ceil(2 + Math.random()*6);
+ var nvSegments = 3;//Math.ceil(2 + Math.random()*6);
+ var geom = new THREE.CylinderGeometry(topRadius,bottomRadius,truncHeight, nhSegments, nvSegments);
+ geom.applyMatrix(new THREE.Matrix4().makeTranslation(0,truncHeight/2,0));
+
+ this.mesh = new THREE.Mesh(geom, matTrunc);
+
+ for (var i=0; i.7){
+ var size = Math.random()*3;
+ var fruitGeometry = new THREE.CubeGeometry(size,size,size,1);
+ var matFruit = mats[Math.floor(Math.random()*mats.length)];
+ var fruit = new THREE.Mesh(fruitGeometry, matFruit);
+ fruit.position.x = v.x;
+ fruit.position.y = v.y+3;
+ fruit.position.z = v.z;
+ fruit.rotation.x = Math.random()*Math.PI;
+ fruit.rotation.y = Math.random()*Math.PI;
+
+ this.mesh.add(fruit);
+ }
+
+ // BRANCHES
+
+ if (Math.random()>.5 && v.y > 10 && v.y < truncHeight - 10){
+ var h = 3 + Math.random()*5;
+ var thickness = .2 + Math.random();
+
+ var branchGeometry = new THREE.CylinderGeometry(thickness/2, thickness, h, 3, 1);
+ branchGeometry.applyMatrix(new THREE.Matrix4().makeTranslation(0,h/2,0));
+ var branch = new THREE.Mesh(branchGeometry, matTrunc);
+ branch.position.x = v.x;
+ branch.position.y = v.y;
+ branch.position.z = v.z;
+
+ var vec = new THREE.Vector3(v.x, 2, v.z);
+ var axis = new THREE.Vector3(0,1,0);
+ branch.quaternion.setFromUnitVectors(axis, vec.clone().normalize());
+
+
+ this.mesh.add(branch);
+ }
+
+ }
+
+
+ this.mesh.castShadow = true;
+}
\ No newline at end of file
diff --git a/Games/Hedgehog_Havoc/style.css b/Games/Hedgehog_Havoc/style.css
new file mode 100644
index 0000000000..d14dc281fb
--- /dev/null
+++ b/Games/Hedgehog_Havoc/style.css
@@ -0,0 +1,86 @@
+@import url("https://fonts.googleapis.com/css?family=Voltaire");
+#world {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ background-color: #dbe6e6;
+ overflow: hidden;
+}
+
+#gameoverInstructions {
+ position: absolute;
+ font-family: "Voltaire", sans-serif;
+ font-weight: bold;
+ text-transform: uppercase;
+ font-size: 120px;
+ text-align: center;
+ color: #ffc5a2;
+ opacity: 0;
+ left: 50%;
+ top: 50%;
+ width: 100%;
+ transform: translate(-50%, -100%);
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ transition: all 500ms ease-in-out;
+}
+#gameoverInstructions.show {
+ opacity: 1;
+ transform: translate(-50%, -50%);
+ transition: all 500ms ease-in-out;
+}
+
+#dist {
+ position: absolute;
+ left: 50%;
+ top: 50px;
+ transform: translate(-50%, 0%);
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.label {
+ position: relative;
+ font-family: "Voltaire", sans-serif;
+ text-transform: uppercase;
+ color: #ffa873;
+ font-size: 12px;
+ letter-spacing: 2px;
+ text-align: center;
+ margin-bottom: 5px;
+}
+
+#distValue {
+ position: relative;
+ text-transform: uppercase;
+ color: #dc5f45;
+ font-size: 40px;
+ font-family: "Voltaire";
+ text-align: center;
+}
+
+#instructions {
+ position: absolute;
+ width: 100%;
+ bottom: 0;
+ margin: auto;
+ margin-bottom: 50px;
+ font-family: "Voltaire", sans-serif;
+ color: #dc5f45;
+ font-size: 16px;
+ letter-spacing: 1px;
+ text-transform: uppercase;
+ text-align: center;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.lightInstructions {
+ color: #5f9042;
+}
\ No newline at end of file
diff --git a/Games/Idle_miner/README.md b/Games/Idle_miner/README.md
new file mode 100644
index 0000000000..e7198f6002
--- /dev/null
+++ b/Games/Idle_miner/README.md
@@ -0,0 +1,59 @@
+# Idle Miner
+
+---
+
+## **Description 📃**
+
+- Gather resources and upgrade your production by clicking on different items.
+- Automate your resource gathering and expand your mining empire.
+
+
+
+## **functionalities 🎮**
+
+- Clicking to gather resources.
+- Upgrading items to increase resources per click.
+- Automating resource gathering for passive income.
+- Managing and optimizing resource production to grow your mining business.
+
+
+
+## **How to play? 🕹️**
+
+Gather Resources:
+
+- Click on items such as Vadapav, Kulfi, Shawarma, Fish, and Biryani to gather resources.
+
+Upgrade Items:
+
+- Spend resources to upgrade your items, increasing the resources gathered per click.
+
+Automate Gathering:
+
+- Purchase automation upgrades to gather resources passively without clicking.
+
+Optimize and Expand:
+
+- Manage your resources efficiently to maximize production and expand your mining empire.
+
+
+
+## **Screenshots 📸**
+
+![image](./images/game.png)
+
+
+
+## **Working video 📹**
+![image](./images/2024-07-10%2017-14-05.mp4)
+
+
+
+## **Project Done By 👦**
+
+[Manas Deshpande](https://github.com/manasdeshpande)
+
+
+
+### Happy Coding!
+
diff --git a/Games/Idle_miner/idle miner.css b/Games/Idle_miner/idle miner.css
new file mode 100644
index 0000000000..cf1db13ea7
--- /dev/null
+++ b/Games/Idle_miner/idle miner.css
@@ -0,0 +1,73 @@
+body {
+ font-family: Arial, sans-serif;
+ background-color: #f4f4f4;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ margin:0px;
+}
+.hello{
+ margin-top: 150px;
+}
+#game {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.center {
+ display: flex;
+ align-items: center;
+ background-color: #e0e0e0;
+ padding: 10px;
+ width:300px;
+ border-radius: 10px;
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
+}
+
+.icon {
+ font-size: 40px;
+ margin-right: 10px;
+}
+
+.info {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+}
+
+.production-rate {
+ align-items: center;
+ justify-content: center;
+ font-size: 16px;
+ font-weight: bold;
+}
+
+.buy-info {
+ display: flex;
+ align-items: center;
+ margin-top: 5px;
+}
+
+.buy-btn {
+ background-color: #ffcc00;
+ border: none;
+ padding: 5px 10px;
+ cursor: pointer;
+ border-radius: 5px;
+ margin-right: 10px;
+}
+
+.buy-btn:hover {
+ background-color: #ffbb00;
+}
+
+.cost {
+ font-size: 14px;
+}
+
+.timer {
+ font-size: 14px;
+ margin-top: 5px;
+}
diff --git a/Games/Idle_miner/idle miner.html b/Games/Idle_miner/idle miner.html
new file mode 100644
index 0000000000..2f204e50b6
--- /dev/null
+++ b/Games/Idle_miner/idle miner.html
@@ -0,0 +1,93 @@
+
+
+
+
+
+ Idle Miner Clicker Game
+
+
+
+
+
RS:00/sec
+
+
+
+
1 /click 0/sec
+
+
+
+
100
+
+
+
+
+
+
+
+
1 /click 0/sec
+
+
+
+
100
+
+
+
+
+
+
+
+
1 /click 0/sec
+
+
+
+
100
+
+
+
+
+
+
+
+
1 /click 0/sec
+
+
+
+
100
+
+
+
+
+
+
+
+
1 /click 0/sec
+
+
+
+
100
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Games/Idle_miner/idle miner.js b/Games/Idle_miner/idle miner.js
new file mode 100644
index 0000000000..b621ab538c
--- /dev/null
+++ b/Games/Idle_miner/idle miner.js
@@ -0,0 +1,243 @@
+
+let resources = 0;
+let Cost = {
+ "upgrade": {
+ "vadapav": 10,
+ "kulfi": 100,
+ "shawrma": 1000,
+ "Fish": 10000,
+ "Biryani": 100000,
+ },
+ automation: {
+ "vadapav": 100,
+ "kulfi": 1000,
+ "shawrma": 10000,
+ "Fish": 100000,
+ "Biryani": 1000000,
+ },
+ resourcesPerClick: {
+ "vadapav": 1,
+ "kulfi": 0,
+ "shawrma": 0,
+ "Fish": 0,
+ "Biryani": 0,
+ },
+ AutomationPerSec: {
+ "vadapav": 0,
+ "kulfi": 0,
+ "shawrma": 0,
+ "Fish": 0,
+ "Biryani": 0,
+ },
+ Value: {
+ "vadapav": 1,
+ "kulfi": 5,
+ "shawrma": 15,
+ "Fish": 50,
+ "Biryani": 100,
+ }
+};
+let resourcesPerSecond = 0;
+
+//clicking on product
+{
+ document.getElementById('vadapav').addEventListener('click', () => {
+ resources += Cost.resourcesPerClick.vadapav;
+ updateResources();
+ }
+ );
+ document.getElementById('kulfi').addEventListener('click', () => {
+ resources += Cost.resourcesPerClick.kulfi;
+ updateResources();
+ }
+ );
+ document.getElementById('shawrma').addEventListener('click', () => {
+ resources += Cost.resourcesPerClick.shawrma;
+ updateResources();
+ }
+ );
+ document.getElementById('fish').addEventListener('click', () => {
+ resources += Cost.resourcesPerClick.Fish;
+ updateResources();
+ }
+ );
+ document.getElementById('biryani').addEventListener('click', () => {
+ resources += Cost.resourcesPerClick.Biryani;
+ updateResources();
+ }
+ );
+}
+//buying single product
+{
+ document.getElementById('buy-vadapav').addEventListener('click', () => {
+ console.log(resources, Cost.upgrade.vadapav, Cost.resourcesPerClick.vadapav);
+ if (resources >= Cost.upgrade.vadapav) {
+ resources -= Cost.upgrade.vadapav;
+ Cost.resourcesPerClick.vadapav += 1;
+ Cost.upgrade.vadapav *= 2;
+ updateResourcesPerClick()
+ updateResources();
+ updateUpgradeCost();
+ }
+ }
+ );
+ document.getElementById('buy-kulfi').addEventListener('click', () => {
+ console.log(resources, Cost.upgrade.kulfi, Cost.resourcesPerClick.kulfi);
+ if (resources >= Cost.upgrade.kulfi) {
+ resources -= Cost.upgrade.kulfi;
+ Cost.resourcesPerClick.kulfi += 5;
+ Cost.upgrade.kulfi *= 2;
+ updateResourcesPerClick()
+ updateResources();
+ updateUpgradeCost();
+ }
+ }
+ );
+ document.getElementById('buy-shawrma').addEventListener('click', () => {
+ if (resources >= Cost.upgrade.shawrma) {
+ resources -= Cost.upgrade.shawrma;
+ Cost.resourcesPerClick.shawrma += 10;
+ Cost.upgrade.shawrma *= 2;
+ updateResourcesPerClick()
+ updateResources();
+ updateUpgradeCost();
+ }
+ }
+ );
+ document.getElementById('buy-fish').addEventListener('click', () => {
+ if (resources >= Cost.upgrade.Fish) {
+ resources -= Cost.upgrade.Fish;
+ Cost.resourcesPerClick.Fish += 50;
+ Cost.upgrade.Fish *= 2;
+ updateResourcesPerClick()
+ updateResources();
+ updateUpgradeCost();
+ }
+ }
+ );
+ document.getElementById('buy-biryani').addEventListener('click', () => {
+ if (resources >= Cost.upgrade.Biryani) {
+ resources -= Cost.upgrade.Biryani;
+ Cost.resourcesPerClick.Biryani += 100;
+ Cost.upgrade.Biryani *= 2;
+ updateResourcesPerClick()
+ updateResources();
+ updateUpgradeCost();
+ }
+ }
+ );
+}
+
+//buying single automation
+{
+ document.getElementById('auto-vadapav').addEventListener('click', () => {
+ console.log(resources, Cost.upgrade.vadapav, Cost.resourcesPerClick.vadapav);
+ if (resources >= Cost.automation.vadapav) {
+ resources -= Cost.automation.vadapav;
+ resourcesPerSecond += Cost.Value.vadapav;
+ Cost.automation.vadapav *= 2;
+ Cost.AutomationPerSec.vadapav += Cost.Value.vadapav;
+ updateAutomationPerSec();
+ updateResources();
+ updateAutomationCost();
+ }
+ }
+ );
+ document.getElementById('auto-kulfi').addEventListener('click', () => {
+ if (resources >= Cost.automation.kulfi) {
+ resources -= Cost.automation.kulfi;
+ resourcesPerSecond += Cost.Value.kulfi;
+ Cost.automation.kulfi *= 2;
+ Cost.AutomationPerSec.kulfi += Cost.Value.kulfi;
+ updateAutomationPerSec();
+ updateResources();
+ updateAutomationCost();
+ }
+ }
+ );
+ document.getElementById('auto-shawrma').addEventListener('click', () => {
+ if (resources >= Cost.automation.shawrma) {
+ resources -= Cost.automation.shawrma;
+ resourcesPerSecond += Cost.Value.shawrma;
+ Cost.automation.shawrma *= 2;
+ Cost.AutomationPerSec.shawrma += Cost.Value.shawrma;
+ updateAutomationPerSec();
+ updateResources();
+ updateAutomationCost();
+ }
+ }
+ );
+ document.getElementById('auto-fish').addEventListener('click', () => {
+ if (resources >= Cost.automation.Fish) {
+ resources -= Cost.automation.Fish;
+ resourcesPerSecond += Cost.Value.Fish;
+ Cost.automation.Fish *= 2;
+ Cost.AutomationPerSec.Fish += Cost.Value.Fish;
+ updateAutomationPerSec();
+ updateResources();
+ updateAutomationCost();
+ }
+ }
+ );
+ document.getElementById('auto-biryani').addEventListener('click', () => {
+ if (resources >= Cost.automation.Biryani) {
+ resources -= Cost.automation.Biryani;
+ resourcesPerSecond += Cost.Value.Biryani;
+ Cost.automation.Biryani *= 2;
+ Cost.AutomationPerSec.Biryani += Cost.Value.Biryani;
+ updateAutomationPerSec();
+ updateResources();
+ updateAutomationCost();
+ }
+ }
+ );
+}
+function updateResources() {
+ document.getElementById('resource').textContent = resources;
+ document.getElementById('automation-').textContent = " "+resourcesPerSecond;
+}
+
+function updateUpgradeCost() {
+ document.getElementById('vadapav-cost').textContent = Cost.upgrade.vadapav;
+ document.getElementById('kulfi-cost').textContent = Cost.upgrade.kulfi;
+ document.getElementById('shawrma-cost').textContent = Cost.upgrade.shawrma;
+ document.getElementById('fish-cost').textContent = Cost.upgrade.Fish;
+ document.getElementById('biryani-cost').textContent = Cost.upgrade.Biryani;
+}
+
+function updateAutomationCost() {
+ document.getElementById('vadapav-auto').textContent = Cost.automation.vadapav;
+ document.getElementById('kulfi-auto').textContent = Cost.automation.kulfi;
+ document.getElementById('shawrma-auto').textContent = Cost.automation.shawrma;
+ document.getElementById('fish-auto').textContent = Cost.automation.Fish;
+ document.getElementById('biryani-auto').textContent = Cost.automation.Biryani;
+}
+
+function updateResourcesPerClick() {
+ document.getElementById('vadapav-click').textContent = Cost.resourcesPerClick.vadapav;
+ document.getElementById('kulfi-click').textContent = Cost.resourcesPerClick.kulfi;
+ document.getElementById('shawrma-click').textContent = Cost.resourcesPerClick.shawrma;
+ document.getElementById('fish-click').textContent = Cost.resourcesPerClick.Fish;
+ document.getElementById('biryani-click').textContent = Cost.resourcesPerClick.Biryani;
+}
+
+function updateAutomationPerSec() {
+ document.getElementById('vadapav-autom').textContent = Cost.AutomationPerSec.vadapav;
+ document.getElementById('kulfi-autom').textContent = Cost.AutomationPerSec.kulfi;
+ document.getElementById('shawrma-autom').textContent = Cost.AutomationPerSec.shawrma;
+ document.getElementById('fish-autom').textContent = Cost.AutomationPerSec.Fish;
+ document.getElementById('biryani-autom').textContent = Cost.AutomationPerSec.Biryani;
+}
+
+setInterval(() => {
+ resources += resourcesPerSecond;
+ updateResources();
+}, 1000);
+
+document.addEventListener("DOMContentLoaded", function() {
+ updateResources();
+ updateUpgradeCost();
+ updateAutomationCost();
+ updateResourcesPerClick();
+ updateAutomationPerSec();
+});
diff --git a/Games/Idle_miner/images/2024-07-10 17-14-05.mp4 b/Games/Idle_miner/images/2024-07-10 17-14-05.mp4
new file mode 100644
index 0000000000..146f49b359
Binary files /dev/null and b/Games/Idle_miner/images/2024-07-10 17-14-05.mp4 differ
diff --git a/Games/Idle_miner/images/biryani.png b/Games/Idle_miner/images/biryani.png
new file mode 100644
index 0000000000..0705ce9e2b
Binary files /dev/null and b/Games/Idle_miner/images/biryani.png differ
diff --git a/Games/Idle_miner/images/fish.png b/Games/Idle_miner/images/fish.png
new file mode 100644
index 0000000000..b14479c43d
Binary files /dev/null and b/Games/Idle_miner/images/fish.png differ
diff --git a/Games/Idle_miner/images/game.png b/Games/Idle_miner/images/game.png
new file mode 100644
index 0000000000..3a8f5c1179
Binary files /dev/null and b/Games/Idle_miner/images/game.png differ
diff --git a/Games/Idle_miner/images/kulfi.png b/Games/Idle_miner/images/kulfi.png
new file mode 100644
index 0000000000..ac287733ed
Binary files /dev/null and b/Games/Idle_miner/images/kulfi.png differ
diff --git a/Games/Idle_miner/images/shawrma.png b/Games/Idle_miner/images/shawrma.png
new file mode 100644
index 0000000000..21a833d582
Binary files /dev/null and b/Games/Idle_miner/images/shawrma.png differ
diff --git a/Games/Idle_miner/images/vadapav.png b/Games/Idle_miner/images/vadapav.png
new file mode 100644
index 0000000000..a728ad60ec
Binary files /dev/null and b/Games/Idle_miner/images/vadapav.png differ
diff --git a/Games/King_Of_Pirates_Quiz/README.md b/Games/King_Of_Pirates_Quiz/README.md
new file mode 100644
index 0000000000..e239f34954
--- /dev/null
+++ b/Games/King_Of_Pirates_Quiz/README.md
@@ -0,0 +1,48 @@
+# One Piece Quiz
+
+This is a simple quiz application based on the popular anime and manga series, One Piece. The quiz tests your knowledge of the series with a set of questions. The application is built using HTML, CSS, and JavaScript.
+
+## Table of Contents
+
+- [Project Overview](#project-overview)
+- [Features](#features)
+- [Technologies Used](#technologies-used)
+- [Usage](#usage)
+- [Contributing](#contributing)
+
+
+## Project Overview
+
+The One Piece Quiz is a web application that presents the user with a series of questions related to One Piece. Each question has multiple choice answers, and the user can select the correct answer to proceed to the next question. At the end of the quiz, the user receives a score based on their answers.
+
+## Features
+
+- A series of multiple choice questions related to One Piece
+- Next question button to proceed through the quiz
+- Score calculation and display at the end of the quiz
+- Responsive design for various screen sizes
+
+## Technologies Used
+
+- HTML
+- CSS
+- JavaScript
+- Google Fonts
+
+
+
+## Usage
+
+1. Open the `index.html` file in your web browser.
+2. Click the "Next Question" button to proceed through the quiz.
+3. Select the correct answer for each question.
+4. At the end of the quiz, view your score.
+
+
+
+## Contributing
+
+Contributions are welcome! If you would like to contribute to this project, please fork the repository and submit a pull request with your changes. Ensure that your code follows the existing code style and includes tests where applicable.
+
+
+
diff --git a/Games/King_Of_Pirates_Quiz/background.jpg b/Games/King_Of_Pirates_Quiz/background.jpg
new file mode 100644
index 0000000000..d02228d699
Binary files /dev/null and b/Games/King_Of_Pirates_Quiz/background.jpg differ
diff --git a/Games/King_Of_Pirates_Quiz/index.html b/Games/King_Of_Pirates_Quiz/index.html
new file mode 100644
index 0000000000..f1a00d71dd
--- /dev/null
+++ b/Games/King_Of_Pirates_Quiz/index.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+One Piece Quiz
+
+
+
+
+
+
+
+
One Piece Quiz
+
+
+
+
+
+
+