Why I’m making a game before my next project

Quick link to the game I made


Primary Technology is a good place to work, the main reason being is that I have a lot of freedom to be creative. The ability to be creative means I get to work with a lot of different platforms and technologies. The next project I have been asked to do is a “web based really real time light-weight open source collaborative sticky note tool” AKA PrimaryWall. o_O

So let’s break that down… Web based, easy.. Really real time, not so easy when using conventions… light-weight, easy-ish.. open source, sort of easy.. collaborative, not so easy…

I could go ahead and make something with AJAX & Apache but it wouldn’t be as really real time as a lot of genuine really-real time so I’m going to be better off using NodeJS and Web Sockets. I did an example using Socket and Node a week or so ago that really got me thinking about how I can/could apply what I had learned to the projects I work on at Primary Technology.

The biggest problem I face is my lack of experience with Javascript. If I went straight into building PrimaryWall I would probably build it in a linear fashion and that would suck for an open source project because it wouldn’t feel appropriately structured.. Sure I “could” structure it all out based on what I know so far but I feel like I should do a test first and that test is to build a game using the same structure and hopefully at the same time build my knowledge of NodeJS, WebSocket + Javascript.

So I have 4 weeks to build a game then 4 weeks to build PrimaryWall (It is due at the end of March). The game will be called either “Tag” or “You’re it” and will be a simple multi-mouse game where moving the mouse is all that is required to play.

Any developers that read this think that I’m wasting my time and should just go for it?

I think this post is mostly me justifying spending the next month building a game that has been ultimately funded by the public sector.. I know this may seem a little strange but NodeJS is relatively new and so is Javascript and I really need to learn before I create as to create something that is worthwhile for other people to contribute towards….

Quick link to the game I made

Real time mouse activity w/ NodeJS & Sockets

Quick link to the NodeJS/websocket game I made — includes source

Thanks to Reddit for helping me test this.

Steps:
Get NodeJS
Get npm
Get SocketIO

Create server.js
Paste in:

// Simple Node & Socket server

var http = require('http')
  , url = require('url')
  , fs = require('fs')
  , io = require('../')
  , sys = require('sys')
  , server;

server = http.createServer(function(req, res){
  var path = url.parse(req.url).pathname;
  switch (path){
    case '/':
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.write('<h1>Welcome. Try the <a href="/chat.html">chat</a> example.</h1>');
      res.end();
      break;
      
    case '/json.js':
    case '/test.html':
      fs.readFile(__dirname + path, function(err, data){
        if (err) return send404(res);
        res.writeHead(200, {'Content-Type': path == 'json.js' ? 'text/javascript' : 'text/html'})
        res.write(data, 'utf8');
        res.end();
      });
      break;
    default: send404(res);
  }
}),

send404 = function(res){
  res.writeHead(404);
  res.write('404');
  res.end();
};
server.listen(8080);

// socket.io, I choose you
var io = io.listen(server)
  , buffer = [];
  
io.on('connection', function(client){
  client.send({ buffer: buffer });
  client.broadcast({ announcement: client.sessionId + ' connected' });
  
  client.on('message', function(message){
    var msg = { message: [client.sessionId, message] };
    buffer.push(msg);
    if (buffer.length > 15) buffer.shift();
    client.broadcast(msg);
//    console.log(msg);
});
  client.on('disconnect', function(){
    client.broadcast({ announcement: client.sessionId + ' disconnected' });
  });
});

Create test.html
Paste in:

<!doctype html>
<html>
  <head>
    <title>Multi Mouse - How many mice can I mouse eater eat?</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script> <!-- jquery -->        
    <script src="/json.js"></script> <!-- for ie -->
    <script src="socket.io/socket.io.js"></script> <!-- sockets -->
  </head>
  <body>
<h1> You can see my mouse!! ZOMG - <a href="http://www.youtube.com/watch?v=aFLcbBvTGns">Video explaining why I'm doign this</a></h1>    

    <script>

// some random color 
function randc(){
colors = new Array('#FF0000','#00FF00','#0000FF','#00FFFF','#FF00FF','#C0C0C0');
var color = colors[Math.floor(Math.random()*colors.length)]
return color;
}

// When a new message arrives..
      function message(obj){
	var data = obj.message[1].split(':');
	var x = data[0];
	var y = data[1];
        var userid = obj.message[0];

  if($('#mouse_'+userid).length == 0 && userid != 'you') {
	var randcolor = randc();
	$('body').append('<div class="dot" style="background-color:'+randcolor+'" id="mouse_'+userid+'"/>'
    );
  }

// stops a dot being drawn for local user
if (userid != 'you'){
   $('#mouse_'+userid).css({
    'left' : x + 'px',
    'top' : y + 'px'
  })
}
        var el = document.createElement('p');
        if ('announcement' in obj) el.innerHTML = '<em>' + esc(obj.announcement) + '</em>';
        else if ('message' in obj) el.innerHTML = '<b>' + esc(obj.message[0]) + ':</b> ' + esc(obj.message[1]);
        document.getElementById('chat').appendChild(el);
        document.getElementById('chat').scrollTop = 1000000;
      }
      
// A function to define how we send data
      function send(){
        var val = document.getElementById('text').value;
        socket.send(val);
        message({ message: ['you', val] });
        document.getElementById('text').value = '';
      }
      
// When a mouse is moved
      window.onmousemove = function(event){
	 message({ message: ['you', event.clientX+':'+event.clientY] });
         socket.send(event.clientX+':'+event.clientY);
      };

// replace <&> w/ &lt&&gt
      function esc(msg){
        return msg.replace(/</g, '&lt;').replace(/>/g, '&gt;');
      };

// establish the socket connection      
      var socket = new io.Socket(null, {port: 8080, rememberTransport: false});
      socket.connect();
      socket.on('message', function(obj){
        if ('buffer' in obj){
          document.getElementById('form').style.display='none';
          document.getElementById('chat').innerHTML = '';
          
          for (var i in obj.buffer) message(obj.buffer[i]);
        } else message(obj);
      });
    </script>
    
    <div id="chat"><p>Connecting...</p></div>
    <form id="form" onsubmit="send(); return false">
      <input type="text" autocomplete="off" id="text"><input type="submit" value="Send">
    </form>
    
    <style>
      .dot { height: 10px; width: 10px; background-color:#000000;position:absolute;left:0;top:0;}
    </style>
    
  </body>
</html>

Run it with

node server.js

Test it by visiting http://whatever:8080

Quick link to the NodeJS/websocket game I made — includes source

Profanity filtering in AjaxChat

AjaxChat provide a Client side profanity filter but this is not cool because:

a) Big arrays of profanities on your client is going to kill javascript
b) You are going to be passing your users an array of profanities.

Fix? Do it server side. giggidy. Jump into /ajaxchat/lib/class/AJAXChat.php

Just above the insertCustomMessage function add

 function filterMessageText($text){
    $prof = array("badword1","badword2"); // extend this with your bad words..
    $replace = array();
    foreach ($prof as $word){
       $replace[] = str_repeat('*', strlen($word));
    }
    return str_ireplace($prof, $replace, $text);
  }

Go to line 1498 and add:

// Copies the original text to a value we can store in a separate table if we want to.
   $original_text = $text;
// Pass the text through the filter.
          $text = $this->filterMessageText($text);

npm install ReferenceError: console is not defined

Trying to install npm with:

curl http://npmjs.org/install.sh | sh

Returns:

ReferenceError: console is not defined:

Cause:
NodeJS not properly installed.

Solution:
Goto NodeJS download and get the latest tar package and install it yourself. Usual install procedure:

tar -zxvf node-whatever.tar.gz
cd node-whatever
./configure
make
make install

Now try again and it should work 🙂

Getting and Setting timeline position in JWPlayer

Getting the position is easy:

<script type="text/javscript">

var player   =  null;
  var playlist =  null;
  var time     =  null;

  function playerReady(obj)
  {
    player = gid(obj.id);
    addListeners();
  };


  function addListeners()
  {
    try
    {
      playlist = player.getPlaylist();
    }
    catch(e)
    {
      setTimeout("addListeners()", 100);
    }

    player.addModelListener('TIME', 'timeMonitor');
  };

  function timeMonitor(obj)
  {
    time = obj.position;
  };

  function gid(name)
  {
    return document.getElementById(name);
  };

</script>

You now have the current timeslider time as the variable named “time”.

Test it out by doing an alert(time); attached to a button. This also gives us the time(according to the timeslider) that you clicked the alert and saves it as a variable named “savetime”.

<a href="#" onClick="savetime = time;alert(time);">Alert the current timeline position</a>

Now to push the savetime back to the video object. This will allow us to go back to a saved value, you can manipulate this by adding or removing an integer to fast forward / rewind.

<a href="#" onClick="setTimeout("player.sendEvent('SEEK',savetime)",2000);
">Go to the stored timeline position</a>

Why the setTimeout? Well if you are hiding your jwplayer so you can work around the rest of the screen and you want to bring it back at the same timeline position this will allow the DOM time to reload the element back in. Ideally I would of used a listener here and pushed the value back on “state ready”. Feel free to adjust the code so it does that and leave a copy in the comments 🙂