The Crystal Maze
How do I make an the crystal maze?
Roguelike Dungeon Crawler made with React for freecodecamp data visualisation course. Based on the 90's British TV show 'The Crystal Maze'.. What is a the crystal maze? How do you make a the crystal maze? This script and codes were developed by Adam on 28 November 2022, Monday.
The Crystal Maze - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>The Crystal Maze</title> <link href="https://fonts.googleapis.com/css?family=VT323" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css"> <link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="app"></div> <script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.min.js'></script> <script src="js/index.js"></script>
</body>
</html>
The Crystal Maze - Script Codes CSS Codes
body { background: #000; text-align: center; font-family: 'VT323', monospace;
}
h2 { padding: 0.2em 0.2em 0.5em; font-size: 3rem;
}
button { margin: 0.3em 0 0.6em; padding: 0.1em; background: inherit; color: inherit; font-family: inherit; font-size: inherit; border: 0.1em solid #000; border-color: inherit; border-radius: 0.3em; cursor: pointer;
}
.container { display: flex; width: 100%;
}
.info { width: 20%; height: 100%; margin: 1em 0.4em; background: #000; color: #F5BE33; font-size: 2rem; border: 0.2em solid #F5BE33; border-radius: 0.5em;
}
.info-2 { color: #518CC7; border-color: #518CC7;
}
.info-3 { color: #195B1B; border-color: #195B1B;
}
.info-4 { color: #A258A8; border-color: #A258A8;
}
.info-5 { color: #F8F4EB; border-color: #F8F4EB;
}
.log { padding: 0.5em 0.2em;
}
.hp-good { color: green;
}
.hp-warn { color: yellow;
}
.hp-danger { color: red;
}
.modal { position: absolute; top: 40%; left: 30%; width: 400px; height: 200px; background: rgba(0, 0, 0, 0.8); color: #F8F4EB; font-size: 2rem; border: 0.2em solid #F8F4EB; border-radius: 0.3em;
}
.modal h3 { padding: 0.3em; font-size: 3rem;
}
.defeated { color: red; border-color: red;
}
.game { width: 80%; margin: 1em;
}
.hp-bar { position: relative; top: -4px; left: 1px; width: 30px; height: 5px; background: red;
}
.hp-life { position: relative; height: 5px; background: green;
}
.row { line-height: 0px;
}
.tile { display: inline-block; height: 2em; width: 2em;
}
@media (max-width: 1300px) { .tile { height: 1.5em; width: 1.5em; }
}
@media (max-width: 1000px) { .tile { height: 1em; width: 1em; }
}
.wall-1 { background: #F5BE33; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") 0 0;
}
.wall-2 { background: #518CC7; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") 0 -32px;
}
.wall-3 { background: #195B1B; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") 0 -64px;
}
.wall-4 { background: #A258A8; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") 0 -96px;
}
.wall-5 { background: #F8F4EB; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") 0 -128px;
}
.floor-1 { background: #f7cd64; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -32px 0;
}
.floor-2 { background: #78a6d3; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -32px -32px;
}
.floor-3 { background: #248327; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -32px -64px;
}
.floor-4 { background: #b57ab9; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -32px -96px;
}
.floor-5 { background: white; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -32px -128px;
}
.player-1 { background: blue; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -64px 0;
}
.player-2 { background: blue; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -64px -32px;
}
.player-3 { background: blue; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -64px -64px;
}
.player-4 { background: blue; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -64px -96px;
}
.player-5 { background: blue; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -64px -128px;
}
.enemy-1 { background: red; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -96px 0;
}
.enemy-2 { background: red; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -96px -32px;
}
.enemy-3 { background: red; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -96px -64px;
}
.enemy-4 { background: red; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -96px -96px;
}
.boss { background: red; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -96px -128px;
}
.chest-1, .chest-3, .chest-4 { background: brown; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -128px 0;
}
.chest-2 { background: brown; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -128px -32px;
}
.hp-1 { background: green; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -160px 0;
}
.hp-2 { background: green; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -160px -32px;
}
.hp-3 { background: green; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -160px -64px;
}
.hp-4 { background: green; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -160px -96px;
}
.hp-5 { background: green; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -160px -128px;
}
.weapon-1 { background: orange; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -192px 0;
}
.weapon-2 { background: orange; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -192px -32px;
}
.weapon-3 { background: orange; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -192px -64px;
}
.weapon-4 { background: orange; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -192px -96px;
}
.armour-1 { background: #bbb; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -224px 0;
}
.armour-2 { background: #bbb; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -224px -32px;
}
.armour-3 { background: #bbb; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -224px -64px;
}
.armour-4 { background: #bbb; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -224px -96px;
}
.crystal-1 { background: purple; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -256px 0;
}
.crystal-2 { background: purple; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -256px -32px;
}
.crystal-3 { background: purple; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -256px -64px;
}
.crystal-4 { background: purple; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") -256px -96px;
}
.door-1 { background: pink; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") 32px 0;
}
.door-2 { background: pink; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") 32px -32px;
}
.door-3 { background: pink; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") 32px -64px;
}
.door-4 { background: pink; background: url("https://s2.postimg.org/4jw9ig9m1/sprite-map.png") 32px -96px;
}
The Crystal Maze - Script Codes JS Codes
"use strict";
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/*====================================== THE CRYSTAL MAZE A ROGUELIKE DUNGEON CRAWLER
========================================
TO DO: animation? mobile? !DESKTOP ONLY Tested on Firefox, Chrome, Edge - I may try to add mobile compatability in the future
Dungeon crawler game based on the UK 90's TV game show 'The Crystal Maze'.
Made for the final free code camp data visualisation course.
Made with React and Sass.
Use arrow or WASD keys to move
Best played on full screen.
Most sprites created by David Gervais from http://pousse.rapiere.free.fr/tome/ I created a few myself
Tip - Get the weapon and armour for each level before attacking the enemies.
Spaces Key 0 = Wall 1 = Space 2 = Player 3 = (Was Enemy however enemies are now objects) 4 = Chests 5 = Hp 6 = Weapon 7 = Armour 8 = Crystal 9 = Stairs
Procedurally generated room system developed from this tutorial https://gamedevelopment.tutsplus.com/tutorials/create-a-procedurally-generated-dungeon-cave-system--gamedev-10099
*/
//Game Constants
var dungeonWidth = 30;
var dungeonHeight = 18;
var expArray = [0, 50, 100, 200, 400, 600, 900, 1200, 1500, 1800];
var weaponArray = ["Fists", "Axe", "Sword", "Excalibur", "Holy Hand Grenade"];
var armourArray = ["None", "Leather", "Chain Mail", "Plate Mail", "Dragon Scale"];
var enemyNames = ["Snake", "Alien", "Knight", "Mutant", "Dome Dragon"];
var zones = ["Aztec", "Futuristic", "Medieval", "Industrial", "Crystal Dome"];
//Utility Functions
function randomVal(val) { return Math.floor(Math.random() * val);
}
//Check if space in dungeon is free or used
function checkFreeSpace(y, x) { return dungeon[y][x] != 1;
}
//Dungeon board array
var dungeon = [];
var dungeonRooms = [];
//Create a blank dungeon area
function createDungeon() { dungeon = []; for (var i = 0; i < dungeonHeight; i++) { var row = []; for (var j = 0; j < dungeonWidth; j++) { row.push(0); } dungeon.push(row); } return dungeon;
};
//New room constructor
var Room = function Room(x, y, w, h) { this.w = w; this.h = h; this.x = x; this.x1 = x; this.x2 = x + w; this.y = y; this.y1 = y; this.y2 = y + h; //Find center of room this.center = { 'x': Math.floor((x * 2 + w) / 2), 'y': Math.floor((y * 2 + h) / 2) };
};
//Check if newly created room overlaps with other rooms
Room.prototype.overlaps = function (room) { return this.x1 <= room.x2 && this.x2 >= room.x1 && this.y1 <= room.y2 && this.y2 >= room.y1;
};
//Adds Vertical corridor into dungeon
function vertCorridor(y1, y2, x) { var startPath = Math.min(y1, y2); var endPath = Math.max(y1, y2); for (var i = startPath; i < endPath + 1; i++) { dungeon[i][x] = 1; }
}
//Adds horizontal corridor into dungeon
function hozCorridor(x1, x2, y) { var startPath = Math.min(x1, x2); var endPath = Math.max(x1, x2); for (var i = startPath; i < endPath + 1; i++) { dungeon[y][i] = 1; }
}
//Produce randomly sized rooms and attempt to add to dungeon in a free space. Then connect room with previous room
function placeRooms() { dungeonRooms = []; //Constants for max/min room sizes var maxRooms = dungeonWidth * dungeonHeight; var minSize = 3; var maxSize = 8; //Attempt to create and add a new room to the dungeon for (var i = 0; i < maxRooms; i++) { //Give random dimensions within limits to new room var w = Math.floor(Math.random() * (maxSize - minSize + 1) + minSize); var h = Math.floor(Math.random() * (maxSize - minSize + 1) + minSize); var x = Math.floor(Math.random() * (dungeonWidth - w - 1) + 1); var y = Math.floor(Math.random() * (dungeonHeight - h - 1) + 1); // Create new room var room = new Room(x, y, w, h); var fail = false; //Check if room overlaps other rooms. If it does break out of loop and attempt a new room for (var j = 0; j < dungeonRooms.length; j++) { if (room.overlaps(dungeonRooms[j])) { fail = true; break; } } //If passes, Add room to free space in dungeon if (!fail) { for (var _i = room.y1; _i < room.y2; _i++) { for (var j = room.x1; j < room.x2; j++) { dungeon[_i][j] = 1; } } //Store center values to allow corridor creation between rooms if (dungeonRooms.length !== 0) { var center = room.center; var prevCenter = dungeonRooms[dungeonRooms.length - 1].center; vertCorridor(prevCenter.y, center.y, center.x); hozCorridor(prevCenter.x, center.x, prevCenter.y); } dungeonRooms.push(room); } }
}
//Place items into dungeon
function placeItems(num, type) { for (var i = 0; i < num; i++) { //Set an initial room to attempt to add item var room = dungeonRooms[Math.floor(Math.random() * dungeonRooms.length)]; var yPos = Math.floor(Math.random() * room.h); var xPos = Math.floor(Math.random() * room.w); while (checkFreeSpace(room.y1 + yPos, room.x1 + xPos)) { //Try random room and positions to attempt to add item room = dungeonRooms[Math.floor(Math.random() * dungeonRooms.length)]; var _yPos = Math.floor(Math.random() * room.h); var _xPos = Math.floor(Math.random() * room.w); } dungeon[room.y1 + yPos][room.x1 + xPos] = type; }
}
//Player and Enemies
//New player constructor
function Player(pos) { this.x = pos[1]; this.y = pos[0]; this.hp = 100; this.maxHp = 100; this.armour = 1; this.armourName = "None"; this.weapon = 10; this.weaponName = "Fists"; this.crystals = 0; this.exp = 0; this.level = 0; this.name = "Richard";
}
//Place player in random dungeon loaction
function playerStart() { var start = dungeonRooms[Math.floor(Math.random() * dungeonRooms.length)]; dungeon[start.center.y][start.center.x] = 2; return [start.center.y, start.center.x];
}
//Enemy constructor
var Enemy = function Enemy(name, level) { this.name = name; this.health = level * 50 + randomVal(50); this.maxHealth = this.health; this.weapon = level * 10 + randomVal(10);
};
//Create final boss
var _boss = { name: "Dome Dragon", health: 1000, maxHealth: 1000, weapon: 70
};
//Create number of enemies
function createEnemies(num, level) { var enemiesArray = []; for (var i = 1; i <= num; i++) { var enemy = new Enemy(i, level); enemiesArray['enemy' + i] = enemy; placeItems(1, enemy); } return enemiesArray;
}
//Create boss level
var dome = [, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0], [0, 5, 1, 1, 1, 1, _boss, 1, 1, 1, 1, 5, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 1, 1, 2, 1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]];
//Create initial dungeon
function init(chestNum) { createDungeon(); placeRooms(); placeItems(chestNum, 4); //Place Initial Chests placeItems(1, 9); //Place initial door
}
init(8);
//Main game component
var App = function (_React$Component) { _inherits(App, _React$Component); function App(props) { _classCallCheck(this, App); var _this = _possibleConstructorReturn(this, _React$Component.call(this, props)); _this.state = { dungeon: dungeon, player: new Player(playerStart()), enemies: createEnemies(6, 1), level: 1, log: "Welcome to the Crystal Maze. Use the arrow keys or WASD to move", light: false, gotWeapon: false, gotArmour: false, gameOver: false }; _this.move = _this.move.bind(_this); _this.handleKeydown = _this.handleKeydown.bind(_this); _this.boss = _this.boss.bind(_this); _this.win = _this.win.bind(_this); _this.reset = _this.reset.bind(_this); _this.light = _this.light.bind(_this); return _this; } //Handle player move App.prototype.move = function move(oldPos, newPos) { var player = this.state.player; var dungeon = this.state.dungeon; var tile = dungeon[newPos.y][newPos.x]; //Check if enemy if ((typeof tile === "undefined" ? "undefined" : _typeof(tile)) === 'object') { return this.fight(tile, newPos); } switch (tile) { case 0: return; case 4: return this.openChest(newPos); case 5: this.hp(); break; case 6: this.weapon(); break; case 7: this.armour(); break; case 8: this.crystal(); break; case 9: return this.nextDungeon(); break; } //Change new position to player and prev to floor player.x = newPos.x; player.y = newPos.y; dungeon[newPos.y][newPos.x] = 2; dungeon[oldPos.y][oldPos.x] = 1; this.setState({ player: player, dungeon: dungeon }); }; //Handle combat App.prototype.fight = function fight(enemy, newPos) { var player = this.state.player; var dungeon = this.state.dungeon; var array = this.state.enemies; var enemyDamage = Math.floor(player.weapon / 2 + randomVal(player.weapon / 2)); enemy.health -= enemyDamage; var log = "You did " + enemyDamage + " damage to " + enemyNames[this.state.level - 1] + "\n"; var enemyIndex = this.state.enemies['enemy' + enemy.name]; array[enemyIndex] = enemy; if (enemy.health < 1) { if (enemy.name === "Dome Dragon") { return this.win(); } else { var index = array.indexOf(enemyIndex); array.splice(enemyIndex, 1); dungeon[newPos.y][newPos.x] = 8; var exp = randomVal(this.state.level * 15) + this.state.level * 15; player.exp += exp; log = "You defeated " + enemyNames[this.state.level - 1] + " and gained " + exp + "EXP"; } } else { var playerDamage = Math.floor(enemy.weapon / 2 / player.armour + randomVal(enemy.weapon / player.armour)); player.hp -= playerDamage; log += "You received " + playerDamage + " damage\n"; if (player.hp < 1) { return this.gameOver(); } } this.checkLevelUp(player); this.setState({ player: player, dungeon: dungeon, enemies: array, log: log }); }; //Handle opening treasure chests App.prototype.openChest = function openChest(newPos) { var tile = undefined; var player = this.state.player; var weapon = this.state.gotWeapon; var armour = this.state.gotArmour; var rand = Math.random(); if (rand < 0.5 && !weapon) { tile = 6; weapon = true; } else if (rand < 0.8 && !armour) { tile = 7; armour = true; } else { tile = 5; } var exp = randomVal(this.state.level * 10); player.exp += exp; this.checkLevelUp(player); var dungeon = this.state.dungeon; dungeon[newPos.y][newPos.x] = tile; this.setState({ player: player, dungeon: dungeon, log: "You gained " + exp + "exp from opening the chest", gotWeapon: weapon, gotArmour: armour }); }; //Handle adding health App.prototype.hp = function hp() { var player = this.state.player; player.hp += this.state.level * 50 + 50; if (player.hp > player.maxHp) { player.hp = player.maxHp; } this.setState({ player: player, log: "Potion gave you " + (this.state.level * 50 + 50) + "HP" }); }; //handle weapon pickup App.prototype.weapon = function weapon() { var player = this.state.player; player.weapon += this.state.level * 5; player.weaponName = weaponArray[this.state.level]; this.setState({ player: player, log: "You found the " + weaponArray[this.state.level] }); }; //handle armour pickup App.prototype.armour = function armour() { var player = this.state.player; player.armour += 0.2; player.armourName = armourArray[this.state.level]; this.setState({ player: player, log: "You found " + armourArray[this.state.level] + " armour" }); }; //handle crystal pickup App.prototype.crystal = function crystal() { var player = this.state.player; player.crystals += 1; this.setState({ player: player, log: "You found a Crystal!" }); }; //handle lava App.prototype.lava = function lava() {}; //handle entering next dungeon App.prototype.nextDungeon = function nextDungeon() { var player = this.state.player; if (player.crystals < this.state.level * 5 + this.state.level) { return this.setState({ log: "You need " + (this.state.level * 5 + this.state.level) + " total Crystals to enter the next zone" }); } if (this.state.level === 4) { return this.boss(); } init(8); var start = playerStart(); player.x = start[1]; player.y = start[0]; player.hp = player.maxHp; this.setState({ player: player, dungeon: dungeon, enemies: createEnemies(this.state.level + 5, this.state.level + 1), level: this.state.level + 1, gotWeapon: false, gotArmour: false, light: false, log: "You entered the " + zones[this.state.level] + " Zone!" }); }; //Check if enough exp to level up App.prototype.checkLevelUp = function checkLevelUp(player) { var oldLevel = player.level; for (var i = 0; i < expArray.length; i++) { if (player.exp < expArray[i]) { player.level = i; if (player.level > oldLevel) { player.maxHp += Math.floor(randomVal(15) + 15); } return player; } } }; //handle final boss level App.prototype.boss = function boss() { var player = this.state.player; player.x = 6; player.y = 10; this.setState({ player: player, dungeon: dome, enemies: _boss, level: 5, log: "You entered the Crystal Dome.\nDefeat the final boss!" }); }; //handle win scenario App.prototype.win = function win() { window.removeEventListener('keydown', this.handleKeydown); this.setState({ log: "You Win!", win: true }); }; //handle gameover scenario App.prototype.gameOver = function gameOver() { window.removeEventListener('keydown', this.handleKeydown); var player = this.state.player; player.hp = 0; this.setState({ player: player, gameOver: true, log: "You were defeated!" }); }; App.prototype.reset = function reset() { init(9); window.addEventListener('keydown', this.handleKeydown); this.setState({ player: new Player(playerStart()), dungeon: dungeon, enemies: createEnemies(6, 1), level: 1, gotWeapon: false, gotArmour: false, log: "Welcome to the Crystal Maze. Use the arrow keys or WASD to move", light: false, gameOver: false, win: false }); }; App.prototype.light = function light() { this.setState({ light: !this.state.light }); }; App.prototype.handleKeydown = function handleKeydown(e) { e.preventDefault(); var newPos = {}; var player = this.state.player; var oldPos = { x: player.x, y: player.y }; switch (e.keyCode) { //Up arrow + w case 38: case 87: newPos = { x: player.x, y: player.y - 1 }; break; //Down arrow + s case 40: case 83: newPos = { x: player.x, y: player.y + 1 }; break; //Left arrow + a case 37: case 65: newPos = { x: player.x - 1, y: player.y }; break; //Right arrow + d case 39: case 68: // right newPos = { x: player.x + 1, y: player.y }; break; default: return; } this.move(oldPos, newPos); }; App.prototype.componentDidMount = function componentDidMount() { window.addEventListener('keydown', this.handleKeydown); }; App.prototype.componentWillUnmount = function componentWillUnmount() { window.removeEventListener('keydown', this.handleKeydown); }; App.prototype.render = function render() { return React.createElement( "div", { className: "container" }, React.createElement(RenderGame, { dungeon: this.state.dungeon, player: this.state.player, level: this.state.level, light: this.state.light }), this.state.gameOver || this.state.win ? React.createElement(Modal, { gameOver: this.state.gameOver, reset: this.reset }) : "", React.createElement(Info, { player: this.state.player, level: this.state.level, log: this.state.log, light: this.light }) ); }; return App;
}(React.Component);
//Game render function
function RenderGame(props) { //return how far player can see function lightDistance(y1, x1, y2, x2, distance) { var xDistance = Math.abs(x2 - x1); var yDistance = Math.abs(y2 - y1); var distanceFromTile = Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2)); if (distance > distanceFromTile) { return true; } } return React.createElement( "div", { className: "game" }, props.dungeon.map(function (row, i) { return React.createElement( "div", { className: "row" }, row.map(function (tile, j) { if (lightDistance(props.player.y, props.player.x, i, j, 7) || props.light) { var hp = undefined; var style = undefined; if (tile.name) { hp = (tile.health / tile.maxHealth * 30).toString(); style = { width: hp + "px" }; } if (tile === 2) { hp = (props.player.hp / props.player.maxHp * 30).toString(); style = { width: hp + "px" }; } switch (tile) { case 0: return React.createElement("div", { className: "tile wall-" + props.level }); break; case 1: return React.createElement("div", { className: "tile floor-" + props.level }); break; case 2: return React.createElement( "div", { className: "tile player-" + props.level }, React.createElement( "div", { className: "hp-bar" }, React.createElement("div", { className: "hp-life", style: style }) ) ); break; case 4: return React.createElement("div", { className: "tile chest-" + props.level }); break; case 5: return React.createElement("div", { className: "tile hp-" + props.level }); break; case 6: return React.createElement("div", { className: "tile weapon-" + props.level }); break; case 7: return React.createElement("div", { className: "tile armour-" + props.level }); break; case 8: return React.createElement("div", { className: "tile crystal-" + props.level }); break; case 9: return React.createElement("div", { className: "tile door-" + props.level }); case _boss: return React.createElement( "div", { className: "tile boss" }, tile.health < tile.maxHealth ? React.createElement( "div", { className: "hp-bar" }, React.createElement("div", { className: "hp-life", style: style }) ) : "" ); default: return React.createElement( "div", { className: "tile enemy-" + props.level }, tile.health < tile.maxHealth ? React.createElement( "div", { className: "hp-bar" }, React.createElement("div", { className: "hp-life", style: style }) ) : "" ); } } else { return React.createElement("div", { className: "tile" }); } }) ); }) );
}
//Info panel component
var Info = function (_React$Component2) { _inherits(Info, _React$Component2); function Info(props) { _classCallCheck(this, Info); return _possibleConstructorReturn(this, _React$Component2.call(this, props)); } //Disply correct warning Info.prototype.checkHealth = function checkHealth() { var hp = this.props.player.hp / this.props.player.maxHp; if (hp < 0.25) { return "hp-danger"; } else if (hp < 0.5) { return "hp-warn"; } else { return "hp-good"; } }; Info.prototype.render = function render() { var _this3 = this; return React.createElement( "div", { className: "info info-" + this.props.level }, React.createElement( "h2", null, zones[this.props.level - 1], " ", this.props.level === 5 ? "" : "Zone" ), React.createElement( "div", { className: this.checkHealth() }, "Health: ", this.props.player.hp, "/", this.props.player.maxHp ), React.createElement( "div", null, "Level: ", this.props.player.level ), React.createElement( "div", null, "Exp: ", this.props.player.exp ), React.createElement( "div", null, "Crystals: ", this.props.player.crystals ), React.createElement( "div", null, "Weapon: ", this.props.player.weaponName ), React.createElement( "div", null, "Armour: ", this.props.player.armourName ), React.createElement( "div", { className: "log" }, this.props.log ), React.createElement( "button", { onClick: function onClick() { _this3.props.light(); } }, "Toggle Lights" ) ); }; return Info;
}(React.Component);
//Modal compoent
function Modal(props) { return React.createElement( "div", { className: "modal " + (props.gameOver ? "defeated" : "") }, React.createElement( "h3", null, props.gameOver ? "You were Defeated!" : "You Cracked the Crystal Maze!" ), React.createElement( "button", { onClick: function onClick() { props.reset(); } }, "Play Again" ) );
}
//Render
ReactDOM.render(React.createElement(App, null), document.querySelector('.app'));
Developer | Adam |
Username | rzencoder |
Uploaded | November 28, 2022 |
Rating | 3 |
Size | 16,117 Kb |
Views | 10,120 |
Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!
Name | Size |
HTML Canvas Paint App | 3,477 Kb |
Scrolling Effects Practice | 6,441 Kb |
Whack-a-Mole and Simon Game | 10,604 Kb |
Scatterplot Graph D3 | 5,762 Kb |
Calculator | 4,572 Kb |
Markdown Previewer | 3,929 Kb |
Countdown Anagram Game | 7,625 Kb |
Random Movie Quote Generator | 3,861 Kb |
React Leaderboard | 4,333 Kb |
CSS World Flags | 8,782 Kb |
Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!
Name | Username | Size |
Obligatory CSS3 UI Nav | Romandiaz | 9,017 Kb |
Brent Burns Tribute Page | Nevada48 | 2,569 Kb |
Parallax.js | Zmeeey5 | 2,330 Kb |
Get third wednesday | Wojtek1150 | 2,691 Kb |
Css Rotating 3d cubes different speed | Dghez | 2,364 Kb |
Wip elementary os navbar | Nickcolley | 2,993 Kb |
Light Switch | Bartuc | 4,933 Kb |
My three.js practice | Esambino | 3,203 Kb |
Mobile Sub Menu Concept | Berdejitendra | 2,790 Kb |
CSS eye follow | Pedrocampos | 2,592 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!