From 6f549dfefe32d237919d7269456add47f602f50f Mon Sep 17 00:00:00 2001 From: Stefan Stefanov Date: Sat, 27 Oct 2012 22:38:11 +0300 Subject: [PATCH 1/6] wip perspective --- client/collections/PlayersCollection.js | 3 + client/game-index.js | 45 ++--- client/models/Player.js | 12 ++ client/views/PlayerView.js | 25 +++ client/views/WorldView.js | 210 ++++++++++++++++++++++++ public/js/backbone-min.js | 38 +++++ public/js/jquery-1.7.2.min.js | 4 + public/js/jquery.ba-resize.min.js | 9 + public/js/jquery.mousewheel.min.js | 12 ++ public/js/underscore-min.js | 32 ++++ public/stylesheets/style.css | 2 +- views/layout.jade | 4 + 12 files changed, 367 insertions(+), 29 deletions(-) create mode 100644 client/collections/PlayersCollection.js create mode 100644 client/models/Player.js create mode 100644 client/views/PlayerView.js create mode 100644 client/views/WorldView.js create mode 100644 public/js/backbone-min.js create mode 100644 public/js/jquery-1.7.2.min.js create mode 100644 public/js/jquery.ba-resize.min.js create mode 100644 public/js/jquery.mousewheel.min.js create mode 100644 public/js/underscore-min.js diff --git a/client/collections/PlayersCollection.js b/client/collections/PlayersCollection.js new file mode 100644 index 0000000..547d943 --- /dev/null +++ b/client/collections/PlayersCollection.js @@ -0,0 +1,3 @@ +module.exports = Backbone.Collection.extend({ + model:require("../models/Player"), +}); \ No newline at end of file diff --git a/client/game-index.js b/client/game-index.js index b2f1382..95ed82d 100644 --- a/client/game-index.js +++ b/client/game-index.js @@ -4,23 +4,14 @@ var socket = io.connect(); var Player = require("./views/Player"); var players = []; -var getPlayerByUsername = function(username){ - for(var i = 0; i")); + else + this.$(".coin").remove(); + return this; + }, + + remove:function(){ + this.model.unbind(); + this.$el.remove(); + //this.trigger("removed"); + return this; + } +}); \ No newline at end of file diff --git a/client/views/WorldView.js b/client/views/WorldView.js new file mode 100644 index 0000000..e24b3be --- /dev/null +++ b/client/views/WorldView.js @@ -0,0 +1,210 @@ +module.exports = WorldView = Backbone.View.extend({ + + PlayerView:require("./PlayerView"), + //TerrainView: require("./TerrainView"), + + collection:null, + //terrainCollection + + width: null, + height: null, + zoom: 12, + min_zoom:10, + max_zoom:20, + + drag_mode: "navigate", //"selection", "select_area", "drag_object" + offset:{ + left:null, + top:null + }, + + events:{ + "mousedown" : "drag", + "mousewheel" : "changeZoom", + "resize": "resize" + }, + + initialize: function(options){ + this.views = []; + this.focus ={x:0,y:0}; + this.$el.css({'z-indx':'-10000'}); + this.updateDimensions(); + + //Initializing the views + //this.terrain = []; + //this.terrain.push(new this.Terra) + + var self = this; + this.collection.each(function(model){ + self.createView(model); + }); + + this.collection.on("add", function(model){ + self.createView(model); + }); + + this.collection.on("reset", this.reset, this); + }, + + reset: function(){ + this.views.forEach(function(view){ + view.remove(); + }); + this.views = []; + this.$el.empty(); + }, + + bindView:function(view){ + view.on("change", this.updateOne, this); + }, + + createView:function(model){ + var view = new this.PlayerView({ + model:model + }).render(); + this.views.push(view); + this.$el.append(view.$el); + this.bindView(view); + this.updateOne(view); + }, + + render: function(options){ + this.updateAll(); + return this; + }, + + updateAll: function(){ + var self = this; + this.views.forEach(function(view){self.updateOne(view)}); + //this.terreain.forEach(function(item){ + + //}); + }, + + updateOne:function(view){ + view.$el.css(this.modelPointToScreen(view.model)); + }, + + modelPointToScreen: function (model){ + width = 10*(model.get('width')/(this.zoom - model.get('z'))); + height = 10*(model.get('height')/(this.zoom - model.get('z'))); + + var result = { + "left": (this.focus.x - model.get('x')) / (model.get('z') - this.zoom) + this.width/2 - width / 2, + "top": (this.focus.y - model.get('y')) / (model.get('z') - this.zoom) + this.height/2 - height / 2, + "width": width, + "height": height + }; + return result; + }, + + changeZoom: function(event, delta){ + event.stopPropagation(); + this.zoom-=(delta*this.zoom/50); + if(this.zoomthis.max_zoom) this.zoom = this.max_zoom; + this.updateAll(); + }, + + drag: function(event){ + switch(this.drag_mode){ + case "navigate": + this.navigate(event); break; + case "selection": + this.selection(event); break; + case "select_area": + this.select_area(event); break; + case "drag_object": + this.drag_object(event); break; + } + }, + + navigate : function(e){ + var that = this; + var prevx = this.focus.x; + var prevy = this.focus.y; + WorldView.disableSelection(); + var x = e.pageX; + var y = e.pageY; + $("*").mousemove(function(e){ + //Drag arround + var posx = x - e.pageX; + var posy = y - e.pageY; + that.focus.x = prevx+posx; + that.focus.y = prevy+posy; + that.updateAll(); + }) + .mouseup(function(){ + WorldView.enableSelection(); + //Disable mousemove and mouseup event from all elements + $("*").unbind("mousemove"); + $("*").unbind("mouseup"); + }); + }, + + resize: function(event){ + var oldSize = {width:this.width, height:this.height}; + var newSize = {width:this.$el.width(), height:this.$el.height()}; + var diff = {width:newSize.width/oldSize.width, height:newSize.height/oldSize.height}; + this.width = newSize.width; + this.height = newSize.height; + this.zoom /= newSize.width < newSize.height ? diff.width : diff.height; + this.updateAll(); + }, + + updateDimensions: function(){ + this.width = parseInt(this.$el.css("width").slice(0,-2)); + this.height = parseInt(this.$el.css("height").slice(0,-2)); + this.offset = this.$el.offset(); + }, + + }, + + //Static methods + { + + //Translation from screen to model and from model to screen + + modelAreaToScreen: function(map, modelPoints){ + var result = []; + modelPoints.forEach(function(point){ + result.push(Map.modelPointToScreen( map, point)); }); + return result; + }, + + screenPointToModel: function (map, screenPoint){ + return { + x: screenPoint.x * map.zoom - map.width / 2 + map.focus.x, + y: screenPoint.y * map.zoom + map.height / 2 + map.focus.y}; + }, + + screenAreaToModel: function (map, screenPoint){ + var result = []; + screenPoints.forEach(function(point){ + result.push(screenPointToModel(map, point)); }); + return redult; + }, + + disableSelection: function(){ + $("*").css({ + '-moz-user-select':'none', + '-webkit-user-select':'none', + 'user-select':'none', + '-ms-user-select':'none'}) + .attr('unselectable', 'on') + .onselectstart = function(){return false;}; + }, + + enableSelection: function(){ + $("*").css({ + '-moz-user-select':'auto', + '-webkit-user-select':'auto', + 'user-select':'auto', + '-ms-user-select':'auto' + }) + .attr('unselectable', 'off') + .onselectstart = function(){}; + } + + } +); diff --git a/public/js/backbone-min.js b/public/js/backbone-min.js new file mode 100644 index 0000000..c1c0d4f --- /dev/null +++ b/public/js/backbone-min.js @@ -0,0 +1,38 @@ +// Backbone.js 0.9.2 + +// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. +// Backbone may be freely distributed under the MIT license. +// For all details and documentation: +// http://backbonejs.org +(function(){var l=this,y=l.Backbone,z=Array.prototype.slice,A=Array.prototype.splice,g;g="undefined"!==typeof exports?exports:l.Backbone={};g.VERSION="0.9.2";var f=l._;!f&&"undefined"!==typeof require&&(f=require("underscore"));var i=l.jQuery||l.Zepto||l.ender;g.setDomLibrary=function(a){i=a};g.noConflict=function(){l.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var p=/\s+/,k=g.Events={on:function(a,b,c){var d,e,f,g,j;if(!b)return this;a=a.split(p);for(d=this._callbacks||(this._callbacks= +{});e=a.shift();)f=(j=d[e])?j.tail:{},f.next=g={},f.context=c,f.callback=b,d[e]={tail:g,next:j?j.next:f};return this},off:function(a,b,c){var d,e,h,g,j,q;if(e=this._callbacks){if(!a&&!b&&!c)return delete this._callbacks,this;for(a=a?a.split(p):f.keys(e);d=a.shift();)if(h=e[d],delete e[d],h&&(b||c))for(g=h.tail;(h=h.next)!==g;)if(j=h.callback,q=h.context,b&&j!==b||c&&q!==c)this.on(d,j,q);return this}},trigger:function(a){var b,c,d,e,f,g;if(!(d=this._callbacks))return this;f=d.all;a=a.split(p);for(g= +z.call(arguments,1);b=a.shift();){if(c=d[b])for(e=c.tail;(c=c.next)!==e;)c.callback.apply(c.context||this,g);if(c=f){e=c.tail;for(b=[b].concat(g);(c=c.next)!==e;)c.callback.apply(c.context||this,b)}}return this}};k.bind=k.on;k.unbind=k.off;var o=g.Model=function(a,b){var c;a||(a={});b&&b.parse&&(a=this.parse(a));if(c=n(this,"defaults"))a=f.extend({},c,a);b&&b.collection&&(this.collection=b.collection);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.changed={};this._silent= +{};this._pending={};this.set(a,{silent:!0});this.changed={};this._silent={};this._pending={};this._previousAttributes=f.clone(this.attributes);this.initialize.apply(this,arguments)};f.extend(o.prototype,k,{changed:null,_silent:null,_pending:null,idAttribute:"id",initialize:function(){},toJSON:function(){return f.clone(this.attributes)},get:function(a){return this.attributes[a]},escape:function(a){var b;if(b=this._escapedAttributes[a])return b;b=this.get(a);return this._escapedAttributes[a]=f.escape(null== +b?"":""+b)},has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c||(c={});if(!d)return this;d instanceof o&&(d=d.attributes);if(c.unset)for(e in d)d[e]=void 0;if(!this._validate(d,c))return!1;this.idAttribute in d&&(this.id=d[this.idAttribute]);var b=c.changes={},h=this.attributes,g=this._escapedAttributes,j=this._previousAttributes||{};for(e in d){a=d[e];if(!f.isEqual(h[e],a)||c.unset&&f.has(h,e))delete g[e],(c.silent?this._silent: +b)[e]=!0;c.unset?delete h[e]:h[e]=a;!f.isEqual(j[e],a)||f.has(h,e)!=f.has(j,e)?(this.changed[e]=a,c.silent||(this._pending[e]=!0)):(delete this.changed[e],delete this._pending[e])}c.silent||this.change(c);return this},unset:function(a,b){(b||(b={})).unset=!0;return this.set(a,null,b)},clear:function(a){(a||(a={})).unset=!0;return this.set(f.clone(this.attributes),a)},fetch:function(a){var a=a?f.clone(a):{},b=this,c=a.success;a.success=function(d,e,f){if(!b.set(b.parse(d,f),a))return!1;c&&c(b,d)}; +a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},save:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c=c?f.clone(c):{};if(c.wait){if(!this._validate(d,c))return!1;e=f.clone(this.attributes)}a=f.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c))return!1;var h=this,i=c.success;c.success=function(a,b,e){b=h.parse(a,e);if(c.wait){delete c.wait;b=f.extend(d||{},b)}if(!h.set(b,c))return false;i?i(h,a):h.trigger("sync",h,a,c)};c.error=g.wrapError(c.error, +h,c);b=this.isNew()?"create":"update";b=(this.sync||g.sync).call(this,b,this,c);c.wait&&this.set(e,a);return b},destroy:function(a){var a=a?f.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};if(this.isNew())return d(),!1;a.success=function(e){a.wait&&d();c?c(b,e):b.trigger("sync",b,e,a)};a.error=g.wrapError(a.error,b,a);var e=(this.sync||g.sync).call(this,"delete",this,a);a.wait||d();return e},url:function(){var a=n(this,"urlRoot")||n(this.collection,"url")||t(); +return this.isNew()?a:a+("/"==a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return null==this.id},change:function(a){a||(a={});var b=this._changing;this._changing=!0;for(var c in this._silent)this._pending[c]=!0;var d=f.extend({},a.changes,this._silent);this._silent={};for(c in d)this.trigger("change:"+c,this,this.get(c),a);if(b)return this;for(;!f.isEmpty(this._pending);){this._pending= +{};this.trigger("change",this,a);for(c in this.changed)!this._pending[c]&&!this._silent[c]&&delete this.changed[c];this._previousAttributes=f.clone(this.attributes)}this._changing=!1;return this},hasChanged:function(a){return!arguments.length?!f.isEmpty(this.changed):f.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?f.clone(this.changed):!1;var b,c=!1,d=this._previousAttributes,e;for(e in a)if(!f.isEqual(d[e],b=a[e]))(c||(c={}))[e]=b;return c},previous:function(a){return!arguments.length|| +!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},isValid:function(){return!this.validate(this.attributes)},_validate:function(a,b){if(b.silent||!this.validate)return!0;var a=f.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error?b.error(this,c,b):this.trigger("error",this,c,b);return!1}});var r=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);b.comparator&&(this.comparator=b.comparator); +this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,{silent:!0,parse:b.parse})};f.extend(r.prototype,k,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},add:function(a,b){var c,d,e,g,i,j={},k={},l=[];b||(b={});a=f.isArray(a)?a.slice():[a];c=0;for(d=a.length;c=b))this.iframe=i('