entityjs 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/.gitignore +7 -0
  2. data/Gemfile +4 -0
  3. data/README.md +49 -0
  4. data/Rakefile +1 -0
  5. data/bin/entityjs +14 -0
  6. data/build/build_debug.bat +1 -0
  7. data/build/build_min.bat +1 -0
  8. data/build/config.php +64 -0
  9. data/build/debug.php +48 -0
  10. data/build/files.php +74 -0
  11. data/build/jsmin.php +376 -0
  12. data/build/min.php +50 -0
  13. data/changelog.txt +53 -0
  14. data/entityjs.gemspec +25 -0
  15. data/examples/keys/arrow.png +0 -0
  16. data/examples/keys/keys.html +59 -0
  17. data/examples/keys/keys.js +148 -0
  18. data/examples/mouse/mouse.html +58 -0
  19. data/examples/mouse/mouse.js +60 -0
  20. data/examples/scenes/home.png +0 -0
  21. data/examples/scenes/scenes.html +55 -0
  22. data/examples/scenes/scenes.js +134 -0
  23. data/examples/scenes/win.png +0 -0
  24. data/examples/sounds/sound1.mp3 +0 -0
  25. data/examples/sounds/sound1.ogg +0 -0
  26. data/examples/sounds/sounds.html +56 -0
  27. data/examples/sounds/sounds.js +44 -0
  28. data/examples/style/background.png +0 -0
  29. data/examples/style/sheet.css +762 -0
  30. data/examples/tiles/tiles.html +56 -0
  31. data/examples/tiles/tiles.js +85 -0
  32. data/examples/tiles/tiles.png +0 -0
  33. data/lib/blank/config.js +4 -0
  34. data/lib/blank/config.yml +21 -0
  35. data/lib/blank/home.js +11 -0
  36. data/lib/blank/init.js +7 -0
  37. data/lib/blank/load.js +21 -0
  38. data/lib/blank/play.html +29 -0
  39. data/lib/entity.debug.js +52 -0
  40. data/lib/entity.min.js +184 -0
  41. data/lib/entityjs/command.rb +37 -0
  42. data/lib/entityjs/comp.rb +11 -0
  43. data/lib/entityjs/game.rb +93 -0
  44. data/lib/entityjs/min.rb +11 -0
  45. data/lib/entityjs/refresh.rb +14 -0
  46. data/lib/entityjs/version.rb +3 -0
  47. data/lib/entityjs.rb +6 -0
  48. data/license.txt +1 -0
  49. data/spec/lib/entityjs/game_spec.rb +11 -0
  50. data/spec/spec_helper.rb +3 -0
  51. data/src/entityjs/core/component.js +306 -0
  52. data/src/entityjs/core/entity.js +516 -0
  53. data/src/entityjs/core/load.js +224 -0
  54. data/src/entityjs/core/query.js +410 -0
  55. data/src/entityjs/core/re.js +70 -0
  56. data/src/entityjs/core/system.js +125 -0
  57. data/src/entityjs/cycle/draw.js +185 -0
  58. data/src/entityjs/cycle/ticker.js +27 -0
  59. data/src/entityjs/cycle/tween.js +61 -0
  60. data/src/entityjs/cycle/update.js +86 -0
  61. data/src/entityjs/cycle/wait.js +22 -0
  62. data/src/entityjs/cycle/worker.js +9 -0
  63. data/src/entityjs/display/anchor.js +53 -0
  64. data/src/entityjs/display/bitfont.js +93 -0
  65. data/src/entityjs/display/bitmap.js +37 -0
  66. data/src/entityjs/display/circle.js +30 -0
  67. data/src/entityjs/display/font.js +41 -0
  68. data/src/entityjs/display/group.js +63 -0
  69. data/src/entityjs/display/rect.js +19 -0
  70. data/src/entityjs/display/screen.js +46 -0
  71. data/src/entityjs/display/sprite.js +37 -0
  72. data/src/entityjs/input/keyboard.js +150 -0
  73. data/src/entityjs/input/mouse.js +123 -0
  74. data/src/entityjs/input/pressed.js +81 -0
  75. data/src/entityjs/input/touch.js +28 -0
  76. data/src/entityjs/math/bind.js +76 -0
  77. data/src/entityjs/math/bisect.js +69 -0
  78. data/src/entityjs/math/body.js +39 -0
  79. data/src/entityjs/math/drag.js +39 -0
  80. data/src/entityjs/math/hitmap.js +165 -0
  81. data/src/entityjs/math/hittest.js +26 -0
  82. data/src/entityjs/math/physics.js +142 -0
  83. data/src/entityjs/math/point.js +57 -0
  84. data/src/entityjs/math/tile.js +91 -0
  85. data/src/entityjs/media/channel.js +93 -0
  86. data/src/entityjs/media/playlist.js +5 -0
  87. data/src/entityjs/media/sound.js +110 -0
  88. data/src/entityjs/net/socket.js +52 -0
  89. data/src/entityjs/pattern/arraymap.js +89 -0
  90. data/src/entityjs/pattern/flicker.js +214 -0
  91. data/src/entityjs/pattern/timestep.js +34 -0
  92. data/src/entityjs/save/database.js +7 -0
  93. data/src/entityjs/save/storage.js +57 -0
  94. data/src/entityjs/util/log.js +25 -0
  95. data/src/entityjs/util/polyfill.js +25 -0
  96. data/src/entityjs/util/random.js +38 -0
  97. data/src/entityjs/util/scene.js +101 -0
  98. data/src/entityjs/util/sheet.js +51 -0
  99. data/src/entityjs/util/support.js +132 -0
  100. metadata +156 -0
@@ -0,0 +1,19 @@
1
+ /*
2
+ The rect component draws a rectangle on screen.
3
+ */
4
+ re.c('rect')
5
+ .require('draw')
6
+ .inherit({
7
+ color:'#82d5f4'
8
+ })
9
+ .extend({
10
+
11
+ draw:function(c){
12
+
13
+ c.fillStyle = this.color;
14
+
15
+ c.fillRect(-this.regX, -this.regY, this.sizeX, this.sizeY);
16
+
17
+ }
18
+
19
+ });
@@ -0,0 +1,46 @@
1
+ /*
2
+ The screen component is used for scrolling or shaking all visible objects.
3
+ It simply offsets pos values upon rendering.
4
+
5
+ This is useful for setting up a tile-based game.
6
+ */
7
+ re.c('screen')
8
+ .require('hittest')
9
+ .extend({
10
+
11
+ setPos:function(x, y){
12
+ if(arguments.length == 1){
13
+ y = x.posY;
14
+ x = x.posX;
15
+ }
16
+
17
+ this.posX = x - this.regX;
18
+ this.posY = y - this.regY;
19
+
20
+ return this;
21
+ },
22
+
23
+ toScreenX:function(x){
24
+ return x + this.posX + this.offX;
25
+ },
26
+
27
+ toScreenY:function(y){
28
+ return y + this.posY + this.offY;
29
+ }
30
+
31
+ })
32
+ .inherit({
33
+
34
+ posX:0,
35
+ posY:0,
36
+
37
+ regX:0,
38
+ regY:0,
39
+
40
+ sizeX:0,
41
+ sizeY:0,
42
+
43
+ offX:0,
44
+ offY:0
45
+
46
+ });
@@ -0,0 +1,37 @@
1
+ /*
2
+ The sprite object extends a drawable image for an entity.
3
+ */
4
+
5
+ re.c('sprite')
6
+ .require('bitmap bisect')
7
+ .inherit({
8
+
9
+ frameX:0,
10
+ frameY:0
11
+
12
+ })
13
+ .extend({
14
+
15
+ setFrameId:function(id){
16
+ this.frameX = this.biToXt(id);
17
+ this.frameY = this.biToYt(id);
18
+
19
+ return this;
20
+ },
21
+
22
+ getFrameId:function(){
23
+ return this.toBi(this.frameX, this.frameY);
24
+ },
25
+
26
+ draw:function(c){
27
+ c.drawImage(this.bitmap, this.frameX * this.sizeX, this.frameY * this.sizeY, this.sizeX, this.sizeY, -this.regX, -this.regY, this.sizeX, this.sizeY);
28
+
29
+ return this;
30
+ },
31
+
32
+ //implement for flicker
33
+ flick:function(c){
34
+ this.setFrameId(c);
35
+ }
36
+
37
+ });
@@ -0,0 +1,150 @@
1
+ re.c('keyboard')
2
+ .global({
3
+ listeners:[],
4
+
5
+ keyCodes: {
6
+ /* start the a-z keys */
7
+ 65 : 'a',
8
+ 66:'b',
9
+ 67:'c',
10
+ 68:'d',
11
+ 69:'e',
12
+ 70:'f',
13
+ 71:'g',
14
+ 72:'h',
15
+ 73:'i',
16
+ 74:'j',
17
+ 75:'k',
18
+ 76:'l',
19
+ 77:'m',
20
+ 78:'n',
21
+ 79:'o',
22
+ 80:'p',
23
+ 81:'q',
24
+ 82:'r',
25
+ 83:'s',
26
+ 84:'t',
27
+ 85:'u',
28
+ 86:'v',
29
+ 87:'w',
30
+ 88:'x',
31
+ 89:'y',
32
+ 90:'z',
33
+ /* start number keys */
34
+ 48:'0',
35
+ 49:'1',
36
+ 50:'2',
37
+ 51:'3',
38
+ 52:'4',
39
+ 53:'5',
40
+ 54:'6',
41
+ 55:'7',
42
+ 56:'8',
43
+ 57:'9',
44
+ /* start the f keys */
45
+ 112:'f1',
46
+ 113:'f2',
47
+ 114:'f3',
48
+ 115:'f4',
49
+ 116:'f5',
50
+ 117:'f6',
51
+ 118:'f7',
52
+ 119:'f8',
53
+ 120:'f9',
54
+ 121:'f10',
55
+ 122:'f11',
56
+ 123:'f12',
57
+ /* start the modifier keys */
58
+ 16:'shift',
59
+ 17:'ctrl', //mac os - control
60
+ 18:'alt',//mac os key - option opt
61
+ 24:'cmd', //Mac OS key - also command
62
+ 255:'fn',//lenovo - function
63
+ /* Misc. Keys */
64
+ 8:'backspace',
65
+ 13:'enter', //max os - return
66
+ 32:'space',
67
+ 27:'esc',
68
+ 9:'tab',
69
+ 20:'capslock',
70
+ 91:'windows',//mac os - super
71
+ 46:'delete', //NOT THE OS X DELETE KEY!
72
+ 36:'home',
73
+ 35:'end',
74
+ 33:'pageup',
75
+ 34:'pagedown',
76
+ /* Arrow keys */
77
+ 37:'left',
78
+ 38:'up',
79
+ 39:'right',
80
+ 40:'down',
81
+ /* Special char keys */
82
+ 96:'`',
83
+ 45:'-',//also insert on mac?
84
+ 187:'=',
85
+ 219:'[',
86
+ 221:']',
87
+ 220:'\\', //it's actually a \ but there's two to escape
88
+ 59:';',
89
+ 222:"'",
90
+ 188:',',
91
+ 190:'.',
92
+ 191:'/'
93
+ },
94
+
95
+ /*
96
+ Add modifiers, shift, alt, ctrl.
97
+ .signal('ctrl+k')
98
+ */
99
+ keyboardEvent: function(e){
100
+ var that = re.c('keyboard');
101
+
102
+ if(that.body != document.activeElement){
103
+ return;
104
+ }
105
+
106
+ var c = e.keyCode || e.which;
107
+
108
+ var key = that.keyCodes[c];
109
+
110
+ if(re.c('pressed').preventDefault && re.c('pressed').preventDefault[key]){
111
+ if(e.preventDefault)
112
+ e.preventDefault();
113
+ else
114
+ e.returnValue = false;
115
+
116
+ }
117
+
118
+ if(re.c('pressed')._pressed){
119
+ re.c('pressed')._pressed[key] = (e.type == 'keydown');
120
+ }
121
+
122
+ for(var k=0; k<that.listeners.length; k++){
123
+ that.listeners[k]
124
+ .signal(e.type, key, e)
125
+ .signal(e.type+':'+key, key, e);
126
+ }
127
+
128
+ },
129
+
130
+ active:false,
131
+
132
+ initListeners:function(){
133
+ if(!this.active){
134
+ this.active = true;
135
+ re.listener('keydown', this.keyboardEvent, false);
136
+ re.listener('keyup', this.keyboardEvent, false);
137
+ this.body = re.$('body')[0];
138
+ }
139
+ }
140
+
141
+ })
142
+ .init(function(c){
143
+ c.initListeners();
144
+ //add to global key array
145
+ c.listeners.push(this);
146
+ })
147
+ .dispose(function(c){
148
+ //remove from global key array
149
+ c.listeners.splice(c.listeners.indexOf(this), 1);
150
+ });
@@ -0,0 +1,123 @@
1
+ re.c('mouse')
2
+ .global({
3
+ listeners:[],
4
+
5
+ mouseAction:function(e){
6
+ var b;
7
+
8
+ //find which key
9
+ if(e.which == null){
10
+ //IE
11
+ if(e.button < 2){
12
+ b = 'left';
13
+ } else if(e.button == 4){
14
+ b = 'middle';
15
+ } else {
16
+ b = 'right';
17
+ }
18
+ } else {
19
+ if(e.which < 2){
20
+ b = 'left';
21
+ } else if(e.which == 2){
22
+ b = 'middle';
23
+ } else {
24
+ b = 'right';
25
+ }
26
+ }
27
+
28
+ b = 'mouse:'+b;
29
+
30
+ //register mouse action
31
+ if(re.c('pressed')._pressed){
32
+ re.c('pressed')._pressed[b] = (e.type == 'mousedown');
33
+ }
34
+
35
+ var c = false;
36
+
37
+ if(re.c('pressed').preventDefault){
38
+ if(re.c('pressed').preventDefault[b]){
39
+ if(e.preventDefault)
40
+ e.preventDefault();
41
+ else
42
+ e.returnValue = false;
43
+
44
+ c = true;
45
+ }
46
+ }
47
+
48
+ re.c('mouse').mouseEvent(e);
49
+
50
+ if(c) return false;
51
+ },
52
+
53
+ mouseEvent:function(e){
54
+
55
+ //calculate mouse coordinate
56
+ var x;
57
+ var y;
58
+
59
+ if(e.pageX || e.pageY){
60
+ x = e.pageX;
61
+ y = e.pageY;
62
+ } else {
63
+ x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
64
+ y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
65
+ }
66
+
67
+ //FUTURE fix, does not support multiple canvases
68
+ if(re.sys.canvas){
69
+ x -= re.sys.canvas.offsetLeft;
70
+ y -= re.sys.canvas.offsetTop;
71
+ }
72
+
73
+ //ignore if off canvas
74
+ if(x < 0 || y < 0 || y > re.sys.sizeY || x > re.sys.sizeX){
75
+ return;
76
+ }
77
+
78
+ var that = re.c('mouse');
79
+
80
+ //FUTURE automatically transform screen coordinates?
81
+ var c, t, sx, sy;
82
+ for(var i=0, l = that.listeners.length; i<l; i++){
83
+ t = that.listeners[i];
84
+ if(t.toScreen && t.screen){
85
+ sx = t.screen.toScreenX(x);
86
+ sy = t.screen.toScreenY(y);
87
+ } else {
88
+ sx = x;
89
+ sy = y;
90
+ }
91
+ t.signal(e.type, sx, sy, e);
92
+ }
93
+
94
+ },
95
+
96
+ active:false,
97
+ initListeners:function(){
98
+ if(!this.active){
99
+ this.active = true;
100
+
101
+ re.listener('mousedown', this.mouseAction, false);
102
+ re.listener('mouseup', this.mouseAction, false);
103
+ re.listener('mousemove', this.mouseEvent, false);
104
+ re.listener('click', this.mouseEvent, false);
105
+ re.listener('dblclick', this.mouseEvent, false);
106
+ re.listener('contextmenu', this.mouseEvent, false);
107
+ }
108
+ }
109
+
110
+ })
111
+ .inherit({
112
+ toScreen:false
113
+ })
114
+ .init(function(c){
115
+ //add to listener array
116
+ c.initListeners();
117
+ c.listeners.push(this);
118
+ })
119
+ .dispose(function(c){
120
+ //remove from listener array
121
+
122
+ c.listeners.splice(c.listeners.indexOf(this), 1);
123
+ });
@@ -0,0 +1,81 @@
1
+ re.c('pressed')
2
+ .global({
3
+ //contains pressed keys and mouse clicks
4
+ _pressed:{},
5
+ preventDefault:{}
6
+
7
+ })
8
+ .extend({
9
+
10
+ /*
11
+ This function is usually used in conjunction with mousemove or update for controls.
12
+
13
+ //if either one is true
14
+ if(this.pressed('w', 'up')){
15
+ this.posY--;
16
+ }
17
+
18
+ //or
19
+ if(this.pressed(['w', 'up']){
20
+
21
+ }
22
+
23
+ */
24
+ pressed:function(){
25
+ return re.pressed.apply(this, arguments);
26
+ },
27
+
28
+ /*
29
+ Stops inputs default value.
30
+
31
+ FUTURE
32
+ -be able to remove prevents
33
+ */
34
+ preventDefault:function(){
35
+ re.preventDefault.apply(this, arguments);
36
+ return this;
37
+ }
38
+
39
+ })
40
+ .init(function(){
41
+
42
+ //int mouse and keyboard
43
+ re._c.keyboard.initListeners();
44
+ re._c.mouse.initListeners();
45
+ re._c.touch.initListeners();
46
+
47
+ });
48
+
49
+ re.pressed = function(key){
50
+ var that = re.c('pressed');
51
+
52
+ var c = arguments;
53
+
54
+ if(typeof key == 'object') c = key;
55
+
56
+ for(var i=0; i<c.length; i++){
57
+ if(that._pressed[c[i]]){
58
+ return true;
59
+ }
60
+ }
61
+
62
+ return false;
63
+ };
64
+
65
+ re.preventDefault = function(key){
66
+
67
+ var p = key.split(' ');
68
+
69
+ if(p.length > 1){
70
+
71
+ for(var k in p){
72
+ this.preventDefault(p[k]);
73
+ }
74
+
75
+ return this;
76
+ }
77
+
78
+ re.c('pressed').preventDefault[key] = true;
79
+
80
+ return this;
81
+ };
@@ -0,0 +1,28 @@
1
+ /*
2
+ The touch component handles touch events and dispatches signals.
3
+ */
4
+ re.c('touch')
5
+ .global({
6
+
7
+ touchEvent:function(e){
8
+
9
+ },
10
+
11
+ active:false,
12
+
13
+ initListeners:function(){
14
+ if(!this.active){
15
+ this.active = true;
16
+
17
+ re.listener('touchstart', this.touchEvent, false);
18
+ re.listener('touchmove', this.touchEvent, false);
19
+ re.listener('touchend', this.touchEvent, false);
20
+
21
+ }
22
+ }
23
+
24
+ })
25
+ .init(function(c){
26
+ c.initListeners();
27
+
28
+ });
@@ -0,0 +1,76 @@
1
+ /*
2
+ The bind component prevents points from going outside of the set parameters.
3
+
4
+ This can be useful for maps, characters, enemies, boxes etc..
5
+
6
+ re.e('bind bitmap char.png')
7
+ .bind = {min:{x:0, y:0}, max:{x:100, y: 10}};
8
+
9
+ */
10
+
11
+ re.c('bind')
12
+ .require('update')
13
+ .namespace({
14
+
15
+ update:function(){
16
+ if(!this.bind) return;
17
+
18
+ if(this.posX < this.bindMinX){
19
+
20
+ this.posX = this.bindMinX;
21
+
22
+ } else if(this.posX > this.bindMaxX){
23
+
24
+ this.posX = this.bindMaxX;
25
+ }
26
+
27
+ if(this.posY < this.bindMinY){
28
+
29
+ this.posY = this.bindMinY;
30
+
31
+ } else if(this.posY > this.bindMaxY){
32
+
33
+ this.posY = this.bindMaxY;
34
+ }
35
+
36
+ }
37
+
38
+ })
39
+ .inherit({
40
+
41
+ posX:0,
42
+ posY:0,
43
+
44
+ bindMinX:0,
45
+ bindMinY:0,
46
+
47
+ bindMaxX:10,
48
+ bindMaxY:10,
49
+
50
+ bind:true
51
+
52
+ })
53
+ .extend({
54
+
55
+ setBind:function(minx, miny, maxx, maxy){
56
+
57
+ this.bindMinX = minx;
58
+ this.bindMinY = miny;
59
+
60
+ this.bindMaxX = maxx;
61
+ this.bindMaxY = maxy;
62
+
63
+ return this;
64
+ }
65
+
66
+ })
67
+ .init(function(){
68
+
69
+ this.addSignal('update', this.bind_update);
70
+
71
+ })
72
+ .dispose(function(){
73
+
74
+ this.removeSignal('update', this.bind_update);
75
+
76
+ });
@@ -0,0 +1,69 @@
1
+ /*
2
+ The bisect component cuts an object into equal sections. It supplies helper functions
3
+ for converting to a section and from a section. Useful for sprites and animation.
4
+ */
5
+ re.bisect = re.c('bisect')
6
+ .global({
7
+
8
+ biToX:function(bi, width, size){
9
+
10
+ return this.biToXt(bi, width) * size;
11
+ },
12
+
13
+ biToY:function(bi, width, size){
14
+
15
+ return this.biToYt(bi, width) * size;
16
+ },
17
+
18
+ biToXt:function(bi, width, size){
19
+
20
+ return Math.floor(bi % (width / size) );
21
+ },
22
+
23
+ biToYt:function(bi, width, size){
24
+ return Math.floor((bi * size) / (width - 0.1));
25
+ },
26
+
27
+ toBi:function(xt, yt, w, s){
28
+
29
+ return (xt + (yt * (w / s))) / s;
30
+ }
31
+
32
+ })
33
+ .extend({
34
+
35
+
36
+ biToX:function(bi){
37
+
38
+ return this.biToXt(bi, this.bisect) * this.sizeX;
39
+ },
40
+
41
+ biToY:function(bi){
42
+
43
+ return this.biToYt(bi, this.bisect) * this.sizeY;
44
+ },
45
+
46
+ biToXt:function(bi){
47
+
48
+ return Math.floor(bi % (this.bisect / this.sizeX) );
49
+ },
50
+
51
+ biToYt:function(bi){
52
+ return Math.floor((bi * this.sizeY) / (this.bisect - 0.1));
53
+ },
54
+
55
+ toBi:function(xt, yt){
56
+
57
+ return (xt + (yt * (this.bisect / this.sizeX))) / this.sizeX;
58
+ }
59
+
60
+ })
61
+ .inherit({
62
+
63
+ //spliting width
64
+ bisect:1,
65
+
66
+ sizeX:1,
67
+ sizeY:1
68
+
69
+ });
@@ -0,0 +1,39 @@
1
+ /*
2
+ The body component replaces the hittest component for
3
+ a more precise touch checking.
4
+
5
+ */
6
+ re.c('body')
7
+ .extend({
8
+
9
+ touches:function(x, y, w, h){
10
+ return !
11
+ (
12
+ x > this.posX + this.bodX - this.padX ||
13
+ x + w < this.posX + this.padX ||
14
+ y > this.posY + this.bodY - this.padY||
15
+ y + h < this.posY + this.padY
16
+ );
17
+ },
18
+
19
+ touchesBody:function(x, y, bx, by, px, py){
20
+ return !
21
+ (
22
+ x + px > this.posX + this.bodX + this.padX ||
23
+ x + bx - px < this.posX + this.padX ||
24
+ y + py > this.posY + this.bodY - this.padY ||
25
+ y + by - py < this.posY + this.padY
26
+ );
27
+ }
28
+
29
+
30
+ })
31
+ .inherit({
32
+
33
+ padX:0,
34
+ padY:0,
35
+
36
+ bodX:1,
37
+ bodY:1
38
+
39
+ });
@@ -0,0 +1,39 @@
1
+ /*
2
+ The drag component adds functions to move points
3
+ in relation to its starting postion.
4
+ */
5
+ re.c('drag')
6
+ .inherit({
7
+ posX:0,
8
+ posY:0,
9
+
10
+ dragX:0,
11
+ dragY:0,
12
+
13
+ dragging:false
14
+ })
15
+ .extend({
16
+
17
+ startDrag:function(x, y){
18
+ if(!this.dragging){
19
+ this.dragging = true;
20
+ this.dragX = x;
21
+ this.dragY = y;
22
+ }
23
+ },
24
+
25
+ endDrag:function(){
26
+ this.dragging = false;
27
+ },
28
+
29
+ updateDrag:function(x, y){
30
+ if(this.dragging){
31
+ this.posX += x - this.dragX;
32
+ this.posY += y - this.dragY;
33
+
34
+ this.dragX = x;
35
+ this.dragY = y;
36
+ }
37
+ }
38
+
39
+ });