Home » Demos » Move demo

Move demo



About this demo


This demo shows how APE can handles massive multi-user moving on a web page in real-time. This demo does not use APE as a middleware. A libape-setcord server-side module has been created to handle the coordinates of the users.

Which features this demo is using?

  • nickname.js
  • move.js
  • Sessions
  • ServerSide JavaScript



A simple chat demo, multi-user and private messages.

APE real time chat

A simple chat demo, multi-user and private messages.

Demo of multi-user moving and chating in real time.

Move demo

Demo of multi-user moving and chating in real time.

Live tweets from Twitter trends, in real time!

Live tweets

Live tweets from Twitter trends, in real time!


Gateway to IRC using the TCPSocket feature. Come chat with us ;)

TCPSocket Demo (IRC)

Gateway to IRC using the TCPSocket feature. Come chat with us ;)

A demo of a small massive multiplayer role playing game!

MMORPG

A demo of a small massive multiplayer role playing game!

Draw with everyone in real time!

Pixelbox

Draw with everyone in real time!


Homepage demo

Homepage demo

This is the demo from the home page of APE, but you've probably already seen it ;-)


Study the source code


Check out the Client JavaScript, HTML and ServerSide JavaScript source code of this demo by reading the following :


  1. <script type="text/javascript" src="http://static.weelya.com/weelya_ape/includes/tpl/js/APE_JSF/Demos/Move/move.js"></script>
  2. <link type="text/css" rel="stylesheet" href="http://static.weelya.com/weelya_ape/includes/tpl/js/APE_JSF/Demos/Move/demo.css" title="APE Stylesheet" />
  3. <script type="text/javascript">
  4.         window.addEvent('domready', function() {
  5.                 var move = new APE.Move({'container':$('ape_master_container')});
  6.                 move.load({
  7.                                 'identifier': 'movedemo',
  8.                                 'channel': 'move',
  9.                                 'connectOptions': {'name': rand_chars()}
  10.                 });
  11.         });
  12. </script>
  13.  
  1. APE.Move = new Class({
  2.         Implements: [APE.Client, Options],
  3.  
  4.         options: {
  5.                 container: document.body
  6.         },
  7.  
  8.         initialize: function(core,options){
  9.                 this.core = core;
  10.                 this.setOptions(options);
  11.                 this.addEvent('init', this.initPlayground);
  12.                 this.addEvent('userJoin', this.createUser);
  13.                 this.addEvent('pipeCreate', function(type, pipe, options){
  14.                         if(type=='multi') this.pipe = pipe;
  15.                 });
  16.                 this.onRaw('positions',this.rawPositions);
  17.                 this.onRaw('data',this.rawData);
  18.                 this.onCmd('send', this.cmdSend);
  19.                 this.addEvent('userLeft', this.deleteUser);
  20.                 this.onError('004',this.reset);
  21.                 if (this.options.name) this.core.start(this.options.name);
  22.         },
  23.        
  24.         deleteUser: function(user, pipe){
  25.                 user.element.dispose();
  26.         },
  27.  
  28.         cmdSend: function(pipe,sessid,pubid,message){
  29.                 this.writeMessage(pipe,message,this.core.user);
  30.         },
  31.         rawData: function(raw,pipe){
  32.                 this.writeMessage(pipe,raw.datas.msg,raw.datas.sender);
  33.         },
  34.         rawPositions: function(raw, pipe){
  35.                 this.movePoint(raw.datas.sender,raw.datas.sender.properties.x,raw.datas.sender.properties.y);
  36.         },
  37.         parseMessage: function(message){
  38.                 return unescape(message);
  39.         },
  40.         writeMessage: function(pipe,message,sender){
  41.                 //Define sender
  42.                 sender = this.pipe.getUser(sender.pubid);
  43.  
  44.                 //destory old message
  45.                 sender.element.getElements('.ape_message_container').destroy();
  46.  
  47.                 //Create message container
  48.                 var msg = new Element('div',{'opacity':'0','class':'ape_message_container'});
  49.                 var cnt = new Element('div',{'class':'msg_top'}).inject(msg);
  50.  
  51.                 //Add message
  52.                 new Element('div',{
  53.                                         'text':this.parseMessage(message),
  54.                                         'class':'ape_message'
  55.                                 }).inject(cnt);
  56.                 new Element('div',{'class':'msg_bot'}).inject(cnt);
  57.  
  58.                 //Inject message
  59.                 msg.inject(sender.element);
  60.  
  61.                 //Show message
  62.                 var fx = msg.morph({'opacity':'1'});
  63.  
  64.                 //Delete old message
  65.                 (function(el){
  66.                         $(el).morph({'opacity':'0'});
  67.                         (function(){
  68.                                 $(this).dispose();
  69.                         }).delay(300,el);
  70.                  }).delay(3000,this,msg);
  71.         },
  72.         createUser: function(user, pipe){
  73.                 if(user.properties.x){
  74.                         var x = user.properties.x;
  75.                         var y = user.properties.y;
  76.                 }else{
  77.                         var x = 8;
  78.                         var y = 8;
  79.                 }
  80.                 var pos = this.element.getCoordinates();
  81.                 x = x.toInt()+pos.left;
  82.                 y = y.toInt()+pos.top;
  83.                 user.element = new Element('div',{
  84.                                 'class':'demo_box_container',
  85.                                 'styles':{
  86.                                         'left':x+'px',
  87.                                         'top':y+'px'
  88.                                 }
  89.                         }).inject(this.element,'inside');
  90.                 new Element('div',{
  91.                                 'class':'user',
  92.                                 'styles':{
  93.                                         'background-color':'rgb('+this.userColor(user.properties.name)+')'
  94.                                 }
  95.                                 }).inject(user.element,'inside');
  96.                 new Element('span',{
  97.                                 'text':user.properties.name
  98.                         }).inject(user.element,'inside');
  99.         },
  100.         userColor: function(nickname){
  101.                 var color = new Array(0,0,0);
  102.                 var i=0;
  103.                 while(i<3 && i<nickname.length){
  104.                         //Transformation du code ascii du caractère en code couleur
  105.                         color[i] = Math.abs(Math.round(((nickname.charCodeAt(i)-97)/26)*200+10));                      
  106.                         i++;
  107.                 }
  108.                 return color.join(',');
  109.         },
  110.         sendpos: function(x,y){
  111.                 var pos=this.posToRelative(x,y);
  112.                 this.core.request('SETPOS',[this.pipe.getPubid(),pos.x,pos.y]);
  113.                 this.movePoint(this.core.user,pos.x,pos.y);    
  114.         },
  115.         posToRelative:function(x,y){
  116.                 var pos = this.element.getCoordinates();
  117.                 x = x-pos.left-36;
  118.                 y = y-pos.top-46;
  119.                 if(x<0) x = 10;
  120.                 if(x>pos.width)  x=pos.width-10;
  121.                 if(y<0) y = 10;
  122.                 if(y>pos.height) y = pos.height-10;
  123.                 return {'x':x,'y':y};
  124.         },
  125.         movePoint:function(user,x,y){
  126.                 var user = this.pipe.getUser(user.pubid);
  127.                 var el = user.element;
  128.                 var fx = el.retrieve('fx');
  129.  
  130.                 if(!fx){
  131.                         fx = new Fx.Morph(el,{'duration':300,'fps':100});
  132.                         el.store('fx',fx);
  133.                 }
  134.                 el.retrieve('fx').cancel();
  135.  
  136.                 pos = this.element.getCoordinates();
  137.  
  138.                 x = x.toInt();
  139.                 y = y.toInt()
  140.                 //Save position in user properties
  141.                 user.properties.x = x;
  142.                 user.properties.y = y;
  143.  
  144.                 fx.start({'left':pos.left+x,'top':pos.top+y});
  145.         },
  146.         initPlayground: function(){
  147.                 this.element = this.options.container;
  148.                 this.els = {};
  149.                 this.els.move_box = new Element('div',{'class':'move_box'}).inject(this.element);
  150.                 this.els.move_box.addEvent('click',function(ev){
  151.                         this.sendpos(ev.page.x,ev.page.y);
  152.                 }.bindWithEvent(this));
  153.                 this.els.more = new Element('div',{'id':'more'}).inject(this.element,'inside');
  154.  
  155.                 this.els.sendboxContainer = new Element('div',{'id':'ape_sendbox_container'}).inject(this.els.more);
  156.  
  157.                 this.els.sendBox = new Element('div',{'text':'Say : ','id':'ape_sendbox'}).inject(this.els.sendboxContainer,'bottom');
  158.                 this.els.sendbox = new Element('input',{
  159.                                                         'type':'text',
  160.                                                         'id':'sendbox_input',
  161.                                                         'autocomplete':'off',
  162.                                                         'events':{
  163.                                                                 'keypress':function(ev){
  164.                                                                                 if(ev.code == 13){
  165.                                                                                         var val = this.els.sendbox.get('value');
  166.                                                                                         if(val!=''){
  167.                                                                                                 this.pipe.send(val);
  168.                                                                                                 $(ev.target).set('value','');
  169.                                                                                         }
  170.                                                                                 }
  171.                                                                         }.bind(this)
  172.                                                         }
  173.                                                 }).inject(this.els.sendBox);
  174.                 this.els.sendButton = new Element('input',{
  175.                                                         'type':'button',
  176.                                                         'id':'sendbox_button',
  177.                                                         'value':'Send',
  178.                                                         'events': {
  179.  
  180.                                                                 'click': function(){
  181.                                                                         var val = this.els.sendbox.get('value');
  182.                                                                         if(val!=''){
  183.                                                                                 this.pipe.send(val);
  184.                                                                                 $(ev.target).set('value','');
  185.                                                                         }
  186.                                                                 }.bind(this)
  187.                                                         }
  188.                                                 }).inject(this.els.sendBox);
  189.         },
  190.         reset: function(){
  191.                 this.core.clearSession();
  192.                 if (this.element) {
  193.                         this.element.empty();
  194.                 }
  195.                 this.core.initialize(this.core.options);
  196.         }
  197. });
  1. //
  2. // move.js
  3. //
  4.  
  5. Ape.registerCmd('setpos', true, function(params, infos) {
  6.         if ((!$defined(params.x) || !$defined(params.y)) && (!isFinite(params.x) || !isFinite(params.y))) return 0;
  7.  
  8.         infos.user.setProperty('x', params.x); 
  9.         infos.user.setProperty('y', params.y); 
  10.        
  11.         var chan = Ape.getChannelByPubid(params.pipe);
  12.  
  13.         if (chan) {
  14.                 chan.pipe.sendRaw('positions', {'x': params.x, 'y': params.y}, {'from': infos.user.pipe, 'restrict': infos.subuser});
  15.         } else {
  16.                 return ['109', 'UNKNOWN_PIPE'];
  17.         }
  18.  
  19.         return 1;
  20. });
  21.  
  22. //
  23. // nickname.js
  24. //
  25.  
  26. var userlist = new $H;
  27.  
  28. Ape.registerHookCmd("connect", function(params, cmd) {
  29.  
  30.         if (!$defined(params.name)) return 0;
  31.         if (userlist.has(params.name.toLowerCase())) return ["005", "NICK_USED"];
  32.         if (params.name.length > 16 || params.name.test('[^a-zA-Z0-9]', 'i')) return ["006", "BAD_NICK"];
  33.  
  34.        
  35.         cmd.user.setProperty('name', params.name);
  36.        
  37.         return 1;
  38. });
  39.  
  40. Ape.addEvent('adduser', function(user) {
  41.         userlist.set(user.getProperty('name').toLowerCase(), true);    
  42. });
  43.  
  44. Ape.addEvent('deluser', function(user) {
  45.         userlist.erase(user.getProperty('name').toLowerCase());
  46. });