cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

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.

            
              <body>
  <div id="App" class="container"></div>
</body>
            
          
!
            
              $bg-black: black
$bg-white: white
$tile-wall: gray
$tile-free: white
$tile-user: blue
$tile-health: green
$tile-weapon: gold
$tile-enemies: red
$tile-boss: crimson
$tile-fog: black

body
  background-color: $bg-black
  color: $bg-white
#App
  margin-top: 30px
  
.GameMap
  display: flex
  flex-wrap: wrap
  // width: 500px
  margin: 0 auto
  border: solid
  border-color: blue
  border-width: 2px
.tile
  height: 10px
  width: 10px
.tile-free
  background-color: $tile-free
.tile-wall
  background-color: $tile-wall
.tile-user
  background-color: $tile-user
.tile-health
  background-color: $tile-health
.tile-weapon
  background-color: $tile-weapon
.tile-enemies
  background-color: $tile-enemies
.tile-boss
  background-color: $tile-boss
.tile-fog 
  background-color: $tile-fog // 5
  
  
  
            
          
!
            
              const { combineReducers, createStore, bindActionCreators} = Redux;
const { connect, Provider } = ReactRedux;
const rawMap = [
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ,
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ];
var constMap = rawMap[0]  // newmap has row = y
for (var y=0;y<constMap.length;y++){ // expand each item in y into a row
  var newrow = []
  for (var x=0;x<rawMap.length;x++){ // for each x, pick data from y
    newrow.push(rawMap[x][y])
  }
  constMap[y] = newrow // expand each item in y into a row
}
constMap = JSON.stringify(constMap)
humane.timeout = 1000;
var randXstore=[]
var randYstore=[]
function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
function placeInRandomFreeSpace(){
  const cm = JSON.parse(constMap)
  var randX = Math.floor(Math.random() * cm.length)
  var randY = Math.floor(Math.random() * cm[0].length)
  if (cm[randX][randY] && randXstore.indexOf(randX) < 0 && randYstore.indexOf(randY) < 0) {
    randXstore.push(randX)
    randYstore.push(randY)
    return {y: randX, x: randY}
  } else {
    //iterate until expression is not 0
    return placeInRandomFreeSpace() 
  }
}
function generateCircle(viewedMap, loc){
  for (var xi=-3; xi<=3; xi++){
    for (var yi=-3; yi<=3; yi++){
      if (Math.abs(xi) + Math.abs(yi) < 4) { viewedMap.push({x: loc.y + xi,y:loc.x + yi})}
    }
  }
  return viewedMap
}
////////////////////////////////////////////
////////////////////// REDUCERS
////////////////////////////////////////////
const initState = {viewedMap: []
                   , user:{hp:30, level:0, weaponName:"hands", dmgLo:3, dmgHi:5, xp:0, jloc: placeInRandomFreeSpace()}
                   , item:[
                     {id:"H-1",hpOrDMG:20,name:"carrot", jloc: placeInRandomFreeSpace()},
                     {id:"H-2",hpOrDMG:70,name:"potato", jloc: placeInRandomFreeSpace()},
                     {id:"W-1",hpOrDMG:6,name:"paper cutter", jloc: placeInRandomFreeSpace()},
                     {id:"W-2",hpOrDMG:12,name:"shitty sword", jloc: placeInRandomFreeSpace()},
                     {id:"W-3",hpOrDMG:30,name:"gatling gun", jloc: placeInRandomFreeSpace()}
                   ]
                   , enemy:[
                     {id:"E-1",dmgLo:3,dmgHi:6,hp:10,xp:10,name:"grunt", jloc: placeInRandomFreeSpace()},
                     {id:"E-2",dmgLo:7,dmgHi:14,hp:30,xp:30,name:"orc", jloc: placeInRandomFreeSpace()},
                     {id:"B-1",dmgLo:14,dmgHi:28,hp:100,xp:80,name:"bossman", jloc: placeInRandomFreeSpace()}
                   ]}
function renderMap(map, state) {
  state.item.forEach((x) => {
    x.id[0] == "H" ? map[x.jloc.y][x.jloc.x] = 3 : map[x.jloc.y][x.jloc.x] = 4
  })
  state.enemy.forEach((x) => {
    x.id[0] == "E" ? map[x.jloc.y][x.jloc.x] = 7 : map[x.jloc.y][x.jloc.x] = 8
  })
  const viewdmaps = state.viewedMap.map((x) => JSON.stringify(x))
  // console.log('viewdmaps',viewdmaps)
  var occludedmap = []
  for (var i=0;i<map.length;i++){
    var occludedmaprow = []
    for (var j=0;j<map[0].length;j++){
      if (viewdmaps.indexOf(JSON.stringify({x:i,y:j})) < 0) {
        // console.log('occluded',JSON.stringify({x:i,y:j}))
        occludedmaprow.push(5) //fog
      } else {
        // console.log('viewable',JSON.stringify({x:i,y:j}))
        occludedmaprow.push(map[i][j]) //viewable
      }
    }
    occludedmap.push(occludedmaprow)
  }
  console.log('occludedmap',occludedmap)
  return occludedmap
}
function calcMap(state = initState, action){
  console.log('calcMap')
  if (action.type == "KEYPRESS") {
    console.log('state',state)
    var coreMap = JSON.parse(constMap)
    var newstate = JSON.parse(JSON.stringify(state))
    console.log(coreMap[action.payload.y][action.payload.x])
    if (!coreMap[action.payload.y][action.payload.x]) {
      // console.log(newstate)
      return newstate // new spot is wall, break early
    }
    var newitems = [] // to prepare the new itemlist
    newstate.item.forEach((x) => {
      // console.log('x: ', x.jloc)
      // console.log('action.payload: ', action.payload)
      if (action.payload.y == x.jloc.y && action.payload.x == x.jloc.x) {
        console.log('matched')
        console.log('user ', newstate.user)
        if (x.id[0] == "H") {
          newstate.user.hp += x.hpOrDMG
          humane.log("Ate a " + x.name + "!")
        } else {
          newstate.user.dmgLo += x.hpOrDMG + 1
          newstate.user.dmgHi += x.hpOrDMG + 3
          newstate.user.weaponName = x.name
          humane.log("Picked up a " + x.name + "!")
        } 
        console.log('user ', newstate.user)
      } else {
          console.log('added')
          newitems.push(x)
      }
    })
    newstate.item = newitems
    var newenemy = [] // to prepare the new itemlist
    console.log('newstate.user',newstate.user)
    newstate.enemy.forEach((x) => {
      if (action.payload.y == x.jloc.y && action.payload.x == x.jloc.x) {
        //generate user damage
        var udmg = getRandomInt(newstate.user.dmgLo,newstate.user.dmgHi)
        //generate enemy damage
        var edmg = getRandomInt(x.dmgLo,x.dmgHi)
        humane.log("Did " + udmg + " damage to " + x.name + "!<br />" + x.name + " did " + edmg + " damage to you!")
        //subtract enemy damage from user hp
        newstate.user.hp -= edmg
        //subtract user damage from enemy hp
        x.hp -= udmg
        //if user dead, end game
        if (newstate.user.hp < 1) newstate.user.jloc = "hell"
        //if enemy dead, dont add enemy, add xp, add level
        if (x.hp > 0) {
          // console.log('added')
          // console.log('user ', newstate.user, 'edmg', edmg)
          // console.log('enemy ', x, 'udmg', udmg)
          newenemy.push(x) //damaged but not dead
        } else {
          newstate.user.xp += x.xp
          
          humane.log("Killed " + x.name + "! Gained " + x.xp + "xp!")
          if (newstate.user.xp >= 30) newstate.user.level = 1
          if (newstate.user.xp >= 100) newstate.user.level = 2
          //if boss dead, end game 
          if (x.id[0] == "B") newstate.user.jloc = "heaven"
          humane.log("Defeated bossman! you have won!")
        }
      } 
      else {
          newenemy.push(x)
      }
    }) 
    console.log("user after enemy: ", newstate.user)
    newstate.enemy = newenemy
    console.log('action.payload',action.payload)
    coreMap = renderMap(coreMap,newstate)
    console.log('newloc',coreMap[action.payload.y][action.payload.x])
    switch (coreMap[action.payload.y][action.payload.x]){
      case 1: // new spot is free space
        console.log('moving')
        newstate.user.jloc = action.payload
        newstate.viewedMap = generateCircle(newstate.viewedMap, newstate.user.jloc)
        return newstate
      default: // new spot is not free space and we render it
        newstate.viewedMap = generateCircle(newstate.viewedMap, newstate.user.jloc)
        return newstate
      }
    } 
  else {
      state.viewedMap = generateCircle(state.viewedMap, state.user.jloc)
      return state
    }
}
//reducer
const rootReducer = combineReducers({
  game: calcMap
});
////////////////////////////////////////////
////////////////////// containers
////////////////////////////////////////////
class GameMap extends React.Component{
  renderMap(){
    console.log('renderMap')
    // console.log(this.props)
    return this.props.gamemap.map((tilerow) => {
      const tr = tilerow.map((td) => {
        switch(td){
          case 1:
            td = "tile-free"
            break;
          case 3:
            td = "tile-health"
            break;
          case 4:
            td = "tile-weapon"
            break;
          case 5:
            td = "tile-fog"
            break;
          case 7:
            td = "tile-enemies"
            break;
          case 8:
            td = "tile-boss"
            break;
          case 9:
            td = "tile-user"
            break;
          default:    
            td = "tile-wall"
            break;
                 }
        return <div className={"tile " + td}></div>
      })
      return <div>{tr}</div>
    })
  }
  render() {
    console.log('GameMap.render()')
    return (
      <div className="GameMap">
        {this.renderMap()}
      </div>)
  } 
  componentDidMount() {
    console.log("componentDidMount")
    console.log(this)
    // the following line won't be bound to the store here...
    document.addEventListener("keydown", this.props.keyPress );
  }
}
function GMmapStateToProps(state){
  //from here goes into this.props
  console.log('GMmapStateToProps')
  console.log(state)
  var coreMap = JSON.parse(constMap)
  if (state.game.user.jloc == "hell") {
    humane.log("you have lost!")
  } else if (state.game.user.jloc == "heaven") {
    humane.log("you have won!")
  } else {
    coreMap[state.game.user.jloc.y][state.game.user.jloc.x] = 9    
  }
  coreMap = renderMap(coreMap, state.game)
  return{
    gamemap: coreMap
  }
}
function GMmapDispatchToProps(dispatch){
  //when selectbook called, pass result to all reducers
  console.log('GMmapDispatchToProps')
  return bindActionCreators({keyPress: keyPress}, dispatch)
}
const VGameMap = connect(GMmapStateToProps, GMmapDispatchToProps)(GameMap)

class GameStatus extends React.Component{
  render() {
    console.log('GameStatus.render()')
    return (
      <div className="GameStatus">
        Level: {this.props.user.level} |
        XP: {this.props.user.xp}  |
        HP: {this.props.user.hp}  |
        Weapon: {this.props.user.weaponName}  |
        Damage: {this.props.user.dmgLo}-{this.props.user.dmgHi} |
        Location: {JSON.stringify(this.props.user.jloc)}
      </div>)
  } 
}
function GSmapStateToProps(state){
  //from here goes into this.props
  console.log('GSmapStateToProps')
  console.log(state)
  return{
    user: state.game.user
  }
}
//const VGameStatus = connect(GSmapStateToProps, GMmapDispatchToProps, undefined,{ pure: false })(GameStatus)
const VGameStatus = connect(GSmapStateToProps)(GameStatus)


////////////////////////////////////////////
////////////////////// actions
////////////////////////////////////////////
// actions/index.js action creator
function keyPress(key) {
  console.log('keyPress: ', key)
  // console.log(this)
  var game = store.getState().game
  console.log(game)
  var newlocation = ""
  switch(key.key){
    case "w":
    case "ArrowUp":
      newlocation = {y:game.user.jloc.y,x:game.user.jloc.x-1};break;
      // newlocation = {y:game.user.jloc.y-1,x:game.user.jloc.x};break;
    case "s":
    case "ArrowDown":
      newlocation = {y:game.user.jloc.y,x:game.user.jloc.x+1};break;
      // newlocation = {y:game.user.jloc.y+1,x:game.user.jloc.x};break;
    case "a":
    case "ArrowLeft":
      newlocation = {y:game.user.jloc.y-1,x:game.user.jloc.x};break;
      // newlocation = {y:game.user.jloc.y,x:game.user.jloc.x-1};break;
    case "d":
    case "ArrowRight":
      newlocation = {y:game.user.jloc.y+1,x:game.user.jloc.x};break;
      // newlocation = {y:game.user.jloc.y,x:game.user.jloc.x+1};break;
            }
  return {
    type: "KEYPRESS",
    payload: newlocation
  } // this is an action created
}


////////////////////////////////////////////
////////////////////// APP
////////////////////////////////////////////
const store = createStore(rootReducer)
class App extends React.Component {
  render() {
    console.log('app.render')
    return (
        <Provider store={store}>
          <div>
            <VGameStatus />
          <VGameMap />
        </div>
        </Provider>
)
  }
}

ReactDOM.render(<App />,document.getElementById('App'))
            
          
!
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