css Audio - Active file-generic CSS - Active Generic - Active HTML - Active JS - Active SVG - Active Text - Active file-generic Video - Active header Love html icon-new-collection icon-person icon-team numbered-list123 pop-out spinner split-screen star tv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              <div class="root">
  
</div>
            
          
!
            
              body { 
background-color: #37474F;
  color: white;
  font-family: 'Slabo 27px', serif;
}

button a{
  text-decoration: none;
  color: black;
}

.result {
/*   min-width: 800px; */
/*   max-width: 800px; */
  margin-left: auto;
  margin-right: auto;
/*   margin-top: 50px; */
  text-align: center;
/*   display: flex; */
}
table {
  margin-left: auto;
  margin-right: auto;
  border: 2px white ridge;
  border-spacing: 0;
border-collapse: collapse;
}


td {
  width:15px;
  height: 15px;
  padding: 0;
}

.dude{
  background-color: white;
}
.road{
  background-color: #90CAF9;
}
.wall{
  background-color: #E65100;
}
.health{
  background-color: #FF80AB;
}
.gun{
  background-color: #90A4AE;
}
.enemy{
  background-color: purple;
}
.door{
  background-color: black;
}

.doorOpener{
  background-color: #9C27B0;
}
.darkness {
  background-color: black;
}

.float *{
  display: inline-block;
}


.dashboard{
/*   border: 1px black solid; */
  /*background-color: #FF8A80;*/
  margin-left: auto;
  margin-right: auto;
}

.dashboard span{
  padding-left: 20px;
  padding-right: 20px;
  border: 2px #1B5E20 dotted;
  background-color: black;
  border-radius: 2px;
}

.fa-heart{
  color: red;
}
            
          
!
            
              //TODO
/*
-make settings work
-improve performance
*/



const boardWidth_Height = Math.floor(window.innerHeight/15) - 4;

const {
	Provider, connect
} = ReactRedux;

const {
	createStore, bindActionCreators
} = Redux;

const {
  Router, Route, Link, HashRouter, Switch, withRouter
} = ReactRouterDOM;
//////////////////////////////////
// REDUX CODE
//////////////////////////////////



//////////////////////////////////
// REDUX CODE ENDS HERE
//////////////////////////////////






//////////////////////////////////
// REACT and REDUX CODE
//////////////////////////////////

// 
class GameOver extends React.Component {
  render(){
    return (
    <div>
        <h1>
          YOU
        {this.props.win === true ? " WON! :)" : " LOST! :("}
        </h1>
      </div>
    );
  }
}

class SquareOnGameBoard extends React.Component {
  render(){
    return(
      <td name={this.props.index}className={this.props.type}></td>
    );
  }
}
// 
// health, new guns, enemy and doors
// 
class GameBoard extends React.Component {
  state = {
    dudePosition: 0,
    table: [],
    roadArr: [],
    maxTunnels: 130,
    maxLength: 30,
    healthPosition: null,
    gunPosition: -1,
    enemyPosition: [],
    enemyHealth: [30, 30, 30],
    doorPosition: -1,
    health: 100,
    energy: 5000,
    weaponArr: ['stick', 'gun','programming joke', 'Grumpy Cat meme', 'Rickroll Song', 'Deadliest weapon ever'],
    weapon: 0,
    level: 1,
    gameover: false,
    win: false 
    
  }


componentWillMount(){
  this.createMapOfRectangles();
  
}
  
  componentDidMount(){
   // console.log("GAMEBOARD props",this.props);
    document.addEventListener("keydown",this.handleKeyDown);

   this.setEverything();

  }

setEverything(){
  this.setState({
    dudePosition: null,
    healthPosition: null,
    gunPosition: null,
    enemyPosition: [],
    enemyHealth: [30, 30, 30],
    doorPosition: null
  }, ()=> {
  let dudePoz = this.dudePosition();
  this.setState({dudePosition: dudePoz});
    let healthPoz = this.healthPosition();
    this.setState({healthPosition: healthPoz}, ()=>{
      let gunPoz = this.gunPosition();
    this.setState({gunPosition: gunPoz}, () => {
      let enemyPoz = [];
      for(let i = 0; i<3; i++){
        enemyPoz.push(this.enemyPosition());
      }
      this.setState({enemyPosition: enemyPoz},()=>{
        let doorPoz = this.doorPosition();
        this.setState({doorPosition: doorPoz}, () => {
          this.setObjectsPositions();
        });
      });
    });
    });
     });
}

checkSquare(val){
  if([this.state.dudePosition,this.state.healthPosition,this.state.gunPosition,...this.state.enemyPosition,this.state.doorPosition].indexOf(val) === -1){
    return true;
  }
  return false;
}

dudePosition(){
  return this.state.roadArr[Math.floor(Math.random() * this.state.roadArr.length)];
}
// Health
healthPosition(){
  while(true){
    let healthPoz = this.state.roadArr[Math.floor(Math.random() * this.state.roadArr.length)];
    if(this.checkSquare(healthPoz)){
     return healthPoz;
    }
  }
  
}
// 
// Gun
gunPosition(){
  while(true){
    let gunPoz = this.state.roadArr[Math.floor(Math.random() * this.state.roadArr.length)];
    if(this.checkSquare(gunPoz)){
     return gunPoz;
    }
  }
}

// Enemy
enemyPosition(){
  while(true){
    enemyPoz = this.state.roadArr[Math.floor(Math.random() * this.state.roadArr.length)];
    if(this.checkSquare(enemyPoz)){
     return enemyPoz;
    }
  }
}

// Door
doorPosition(){
  while(true){
    doorPoz = this.state.roadArr[Math.floor(Math.random() * this.state.roadArr.length)];
    if(this.checkSquare(doorPoz)){
     return doorPoz;
    }
  }
}
 



componentWillUnmount(){
  document.removeEventListener("keydown",this.handleKeyDown);
}

handleKeyDown = e =>{
  
  e.preventDefault();
  let x = 0,
      y = 0,
      previousPoz = this.state.dudePosition;
  let nextPosition;
  if(e.key === "ArrowUp")
  {
        nextPosition = this.state.dudePosition - boardWidth_Height;
    y = -1;

  }
  else if(e.key === "ArrowDown")
  {
        nextPosition = this.state.dudePosition + boardWidth_Height;
    y = 1;
  }
  else if(e.key === "ArrowLeft")
  {
        nextPosition = this.state.dudePosition - 1;
    x = -1;
  }
  else if(e.key === "ArrowRight")
  {
        nextPosition = this.state.dudePosition + 1;
    x = 1;
  } 
  else
  {
    console.log("wrong key");
  }
//   health detection
  if(nextPosition === this.state.healthPosition){
          
          this.setState({healthPosition: null, health: this.state.health+50}, () => this.setObjectsPositions()); 
        }
//   weapon detection
         else if(nextPosition === this.state.gunPosition)
        {
                
          this.setState({gunPosition: null, weapon: this.state.weapon + 1}, () => this.setObjectsPositions());
        }
  
  // Enemy detection
  // CLEAN UP CODE BELOW
         else if(nextPosition === this.state.enemyPosition[0]){
          if(this.state.enemyHealth[0] === 0){
            this.setState({enemyPosition: [null, this.state.enemyPosition[1], this.state.enemyPosition[2]],energy: this.state.energy + 100}, () => {this.setObjectsPositions()});
          } else {
            if(this.state.health === 0){
              this.setState({gameover: true, win: false})
            }
             this.setState({health: this.state.health - 10, enemyHealth: [this.state.enemyHealth[0] - 10, this.state.enemyHealth[1], this.state.enemyHealth[2]], energy: this.state.energy - 100}, () => {console.log(this.state.enemyHealth)});
          }
           
          
         }
          else if(nextPosition === this.state.enemyPosition[1]){
          if(this.state.enemyHealth[1] === 0){
            this.setState({enemyPosition: [this.state.enemyPosition[0],null, this.state.enemyPosition[2]], energy: this.state.energy + 100}, () => {this.setObjectsPositions()});
          } else {
            if(this.state.health === 0){
              this.setState({gameover: true, win: false})
            }
           this.setState({health: this.state.health - 10, enemyHealth: [this.state.enemyHealth[0], this.state.enemyHealth[1] - 10, this.state.enemyHealth[2]],energy: this.state.energy - 100}, () => {console.log(this.state.enemyHealth)});
            }
         }
            else if(nextPosition === this.state.enemyPosition[2]){
              if(this.state.enemyHealth[2] === 0){
            this.setState({enemyPosition: [this.state.enemyPosition[0], this.state.enemyPosition[1], null], energy: this.state.energy + 100}, () => {this.setObjectsPositions()});
          } else {
            if(this.state.health === 0){
              this.setState({gameover: true, win: false})
            }
           this.setState({health: this.state.health - 10, enemyHealth: [this.state.enemyHealth[0], this.state.enemyHealth[1], this.state.enemyHealth[2] - 10],energy: this.state.energy - 100}, () => {console.log(this.state.enemyHealth)});
          }
         }
  
  
//   door detection - next level
  
  else if(nextPosition === this.state.doorPosition){
if(this.state.level === 6){
   this.setState({gameover: true, win: true})
   } else{
       document.getElementsByName(this.state.dudePosition)[0].classList.remove('dude');
    document.getElementsByName(this.state.dudePosition)[0].classList.add('road');
    this.createMapOfRectangles();
    
    this.setEverything();
   this.setState({level: this.state.level + 1}, () => {console.log(this.state.level)})
    // .classList.remove('dude');
   // document.getElementsByTagName('td')[nextPosition - 1].classList.add('road');
    
    
    
    console.log(this.state.dudePosition);
   }
  }
  
  
//   Wall detection//
        else if(this.state.roadArr.indexOf(nextPosition) !== -1){
           this.setState({
    dudePosition: (y * boardWidth_Height) + x + this.state.dudePosition
  }, () => {
    this.renderDude(previousPoz); 
  });
           }
  
  
  
    
}

createArray = (num, dimensions) => {
    var array = [];
    for (var i = 0; i < dimensions; i++) {
      array.push([]);
      for (var j = 0; j < dimensions; j++) {
        array[i].push(num);
      }
    }
    return array;
  }

// algorithm for creating tunnels is not mine, source is down below
// https://gist.github.com/ahmadabdolsaheb/0b2df13fc6834ef3acd3d699ee21e748
createMapOfRectangles = () => {
  
  let index = 0;
  let arr = [];
  let dimensions = boardWidth_Height,
      maxTunnels = this.state.maxTunnels, // max number of tunnels possible
      maxLength = this.state.maxLength, // max length each tunnel can have
      map = this.createArray(1, dimensions), // create a 2d array full of 1's
      currentRow = Math.floor(Math.random() * dimensions), // our current row - start at a random spot
      currentColumn = Math.floor(Math.random() * dimensions), // our current column - start at a random spot
      directions = [[-1, 0], [1, 0], [0, -1], [0, 1]], // array to get a random direction from (left,right,up,down)
      lastDirection = [], // save the last direction we went
      randomDirection; // next turn/direction - holds a value from directions
  
  while (maxTunnels && dimensions && maxLength) {

      // lets get a random direction - until it is a perpendicular to our lastDirection
      // if the last direction = left or right,
      // then our new direction has to be up or down,
      // and vice versa
      do {
         randomDirection = directions[Math.floor(Math.random() * directions.length)];
      } while ((randomDirection[0] === -lastDirection[0] && randomDirection[1] === -lastDirection[1]) || (randomDirection[0] === lastDirection[0] && randomDirection[1] === lastDirection[1]));

      var randomLength = Math.ceil(Math.random() * maxLength), //length the next tunnel will be (max of maxLength)
        tunnelLength = 0; //current length of tunnel being created

		// lets loop until our tunnel is long enough or until we hit an edge
      while (tunnelLength < randomLength) {

        //break the loop if it is going out of the map
        if (((currentRow === 0) && (randomDirection[0] === -1)) ||
            ((currentColumn === 0) && (randomDirection[1] === -1)) ||
            ((currentRow === dimensions - 1) && (randomDirection[0] === 1)) ||
            ((currentColumn === dimensions - 1) && (randomDirection[1] === 1))) {
          break;
        } else {
          map[currentRow][currentColumn] = 0; //set the value of the index in map to 0 (a tunnel, making it one longer)
          currentRow += randomDirection[0]; //add the value from randomDirection to row and col (-1, 0, or 1) to update our location
          currentColumn += randomDirection[1];
          tunnelLength++; //the tunnel is now one longer, so lets increment that variable
        }
      }

      if (tunnelLength) { // update our variables unless our last loop broke before we made any part of a tunnel
        lastDirection = randomDirection; //set lastDirection, so we can remember what way we went
        maxTunnels--; // we created a whole tunnel so lets decrement how many we have left to create
      }
    }
  let roadArr = [];
  for(let i = 0; i < map.length; i++){
    for(let j = 0; j < map[i].length; j++){
      if(map[i][j] === 0){
        roadArr.push(i * dimensions + j);
      }
    }
  }
  this.setState({roadArr: roadArr})
}

renderDude = (prevIndex) =>{
 
  let td = document.getElementsByTagName("td");
td[prevIndex].classList.remove("dude");
  td[prevIndex].classList.add("road");
  td[this.state.dudePosition].classList.remove("road");
  td[this.state.dudePosition].classList.add("dude");
  // change this to this.props.darkness
  if(true){
    this.renderDarkness();
  }
}

renderDarkness = () => {
  let td = document.getElementsByTagName("td");
  let dudePoz = this.state.dudePosition;
  for(let i = 0; i < td.length; i++){
    
      td[i].classList.remove("darkness");
    
  }
  for(let i = 0; i < td.length; i++){
    if(
      // i + 54 < dudePoz
       // || dudePoz + 54  < i
       i + (4 * boardWidth_Height) - 3  < dudePoz
      ||(i + (3 * boardWidth_Height) + 2 < dudePoz && i + (4 * boardWidth_Height) - 2> dudePoz)
      ||(i + (2 * boardWidth_Height) + 3 < dudePoz && i + (3 * boardWidth_Height) - 2 > dudePoz)
      ||(i + boardWidth_Height + 4 < dudePoz && i + (2  * boardWidth_Height) - 3 > dudePoz)
      ||(i + 4 < dudePoz && i + boardWidth_Height - 4 > dudePoz)
      
       || (dudePoz + 4 < i && dudePoz + boardWidth_Height - 4 > i)
      || (dudePoz + boardWidth_Height + 4 < i && dudePoz + (2  * boardWidth_Height) - 3 > i)
      || (dudePoz + (2 * boardWidth_Height) + 3 < i  && dudePoz + (3 * boardWidth_Height) - 2 > i)
      || (dudePoz + (3 * boardWidth_Height) + 2 < i && dudePoz + (4 * boardWidth_Height) - 2 > i)
      || (dudePoz + (4 * boardWidth_Height) - 3 < i)
        ) {
      td[i].classList.add("darkness");
    } 
  }
}

setObjectsPositions = () =>{
  
     let table = [],
        bufor = [],
        index = 0;
  
  
    for(let i = 0; i<boardWidth_Height;i++){
      for(let j = 0; j < boardWidth_Height; j++){
        if(index === this.state.dudePosition){
          bufor.push(<SquareOnGameBoard index={index}key={"td"+j}type="dude"/>);
           }
        else if(index === this.state.healthPosition){
                bufor.push(<SquareOnGameBoard index={index}key={"td"+j}type="health"/>);
                }
        else if(index === this.state.gunPosition){
                bufor.push(<SquareOnGameBoard index={index}key={"td"+j}type="gun"/>);
                }
         else if(this.state.enemyPosition.indexOf(index) !== -1){
                bufor.push(<SquareOnGameBoard index={index}key={"td"+j}type="enemy"/>);
                }
        else if(index === this.state.doorPosition){
                bufor.push(<SquareOnGameBoard index={index}key={"td"+j}type="door"/>);
                }
       
        else if(this.state.roadArr.indexOf(index) !== -1){
           bufor.push(<SquareOnGameBoard index={index} key={"td"+j}type="road"/>);
           }
        
         
                 else {
          bufor.push(<SquareOnGameBoard index={index} key={"td"+j}type="wall"/>);
        }
        
        index++;
        
      }
      table.push(<tr key={"tr"+i}>{bufor}</tr>);
      bufor = [];
      
    }
  
  
  this.setState({table: table}, () => {
//     change this to this.props.darkness
    if(true){
      this.renderDarkness();
    }
  });
}




  render(){
    if(this.state.gameover){
      if(this.state.win){

        return <GameOver win={true}/>;
        
      } else{
 
        return <GameOver win={false}/>;
      }
    } else {
    return(
      <div>
        <DashBoard health={this.state.health} energy={this.state.energy} weapon={this.state.weaponArr[this.state.weapon]} level={this.state.level}  />
        <table> 
          <tbody>
      {this.state.table}
          </tbody>
        </table>
          </div>
    
    );
      }
  }
}
class Settings extends React.Component {
  handleDarkness = () =>{
    console.log("SETTINGS props",this.props);
  }
  render(){
    return(
    <div>
        <Header />
        <div>Darkness |ON|</div>
      <button onClick={this.handleDarkness}>Toggle Darkness</button>
        <hr />
        <div>Difficulty</div>
        <button>E A S Y</button>
        <hr />
      </div>
    
    );
  }
}

const Header = () => {
       return(
       <div>
          <h1>Dungeon Crawl</h1>
        <hr />
         </div>);
}

// const DashBoard = () => {
  
//     return(
    
//     );
// }

class DashBoard extends React.Component {
  render(){
    return(
    <div className="dashboard">
        <span> Health: &nbsp;
        {this.props.health}
        </span>
         <span> Energy: {this.props.energy} </span>
         <span> Weapon: {this.props.weapon} </span>
         <span> LEVEL: {this.props.level} </span>
      </div>
    );
  }
}



const Main = withRouter(({location}) => (
  
  <main>
    {(location.pathname == "/" && <Header />)}
    <Switch>
      <Route path='/game' component={GameBoard}/>
      <Route path='/settings' component={Settings}/>
    </Switch>
  </main>
))


const Menu = () => {
 
  
   return(
     
    <div>
      <button id="playButton"><Link to='/game'>PLAY</Link></button>
       <button id="settingsButton"><Link to='/'>Main Menu</Link></button>
        <button id="settingsButton"><Link to='/settings'>Settings</Link></button>
    
     
     </div>
   );
  
    
}

const App = () => (
   <div className="result">
    
    <Main />
    <Menu />
  </div>
)



//////////////////////////////////
// REACT CODE ENDS HERE
//////////////////////////////////


ReactDOM.render(
  
   <HashRouter>
     <App />
    </HashRouter>

  , document.querySelector('.root'));
            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console