JSFiddle - React, Tailwind, and code Playground

by dmihaelkonjevic

HTML

<script src="http://canjs.us/release/latest/can.jquery.js"></script>
<script src="http://canjs.us/release/latest/can.model.queue.js"></script>
<script src="http://canjs.us/release/latest/can.fixture.js"></script>
<script src="http://canjs.us/release/latest/can.view.mustache.js"></script>
<strong>Move around with the arrow keys, and click replay after you're done.</strong>
    <div class="rpg">
      
    </div>
    

    <script type="text/mustache" id="avatar">
  <div class="map">
    <div class="character {{ position.direction }}" style="left: {{ position.left }}px; top: {{ position.top}}px"></div>
    <div class="fire-pit"></div> 
  </div>
  <span>{{#hasQueuedRequests}}Saving!{{/hasQueuedRequests}}</span>
  <button class="replay" {{#hasQueuedRequests}}disabled="disabled"{{/hasQueuedRequests}}>Replay!</button>
  
</script>

CSS

body {
        font-family: Arial, sans-serif;
      }
      .character {
        width: 24px;
        height: 32px;
        position: absolute;
        z-index: 1000;
        /* created with http://charas-project.net/charas2/index.php */
        background-image: url(http://i.imgur.com/axPRWA3.gif);
      }
      .fire-pit {
        width: 24px;
        height: 24px;
        background: url(http://i.imgur.com/otMEOq6.gif);
        position: absolute;
        top: 100px;
        left: 80px;
      }
      .up {
        background-position: 0 0;
      }
      .down {
        background-position: 0 -64px;
      }
      .right {
        background-position: 0 -32px;
      }
      .left {
        background-position: 0 -96px;
      }
      .moving {
        background-image: url(http://i.imgur.com/8ar9p7B.gif);
      }
      .map {
        width: 300px;
        height: 300px;
        position: relative;
        margin: 10px 0;
        /* Texture from http://zooboingreview.blogspot.com/2009/11/seamless-texture-more-nice-grass.html */
        background-image: url(http://i.imgur.com/YiyLRvu.jpg);
      }

JavaScript

$(document).ready(function(){

/* SERVER EMULATION */

        var getRandomInt = function(min, max) {
          return Math.floor(Math.random() * (max - min + 1)) + min;
        }

        var positions = [];

        can.fixture('POST /players', function(req){
          var attrs = req.data || {};
          positions.push(attrs.position); // Save current position
          attrs.id  = 1;
          return attrs;
        })

        can.fixture('PUT /players/{id}', function(req, respondWith){
          var attrs    = req.data || {},
              position = attrs.position;

          if(position.top > 80 && position.top < 100 && position.left > 60 && position.left < 100){ // you stepped on the fire, you die
            return respondWith(406);
          }

          positions.push(attrs.position); // Save current position
          can.fixture.delay = getRandomInt(10, 300); // change delay to simulate slow and spotty connection
          return attrs;
        })

        can.fixture('GET /game', function(req){
          return positions;
        })

        var directions = {
          37 : 'LEFT',
          38 : 'UP',
          39 : 'RIGHT',
          40 : 'DOWN'
        },
        max = function(val, max){
          return val > max ? max : val;
        },
        min = function(val, min){
          return val < min ? min : val;
        };

        var Player = can.Model({
          create : "POST /players",
          update : "PUT /players/{id}"
        }, {});

        var Replay = can.Model({
          findAll : "GET /game"
        }, {})


        var RPG = can.Control({
          init : function(){
            this.player = new Player({
              position: {
                top  : 0,
                left : 0,
                direction: "down"
              }
            });
            this.element.html(can.view('avatar', this.player));
            this.character = this.element.find('.character');
            // save starting position
           ...