git @ Cat's Eye Technologies yoob.js / cb0c05f
Refactor SpriteManager. (x, y)=centre. init takes cfg, chainable. Chris Pressey 10 years ago
2 changed file(s) with 186 addition(s) and 167 deletion(s). Raw diff Collapse all Expand all
1818 <script type="text/javascript">
1919 var c = document.getElementById('canvas');
2020 var manager = new yoob.SpriteManager();
21 manager.init(c);
21 manager.init({
22 canvas: c
23 });
2224
23 var drawDraggable = function(ctx) {
24 ctx.shadowOffsetX = 10;
25 ctx.shadowOffsetY = 10;
26 ctx.shadowBlur = 15;
27 ctx.shadowColor = "black";
25 var addDraggable = function(x, y, w, h, style) {
26 var d = new yoob.Sprite();
27 d.init({
28 x: x,
29 y: y,
30 width: w,
31 height: h,
32 isDraggable: true
33 });
34 d.draw = function(ctx) {
35 ctx.shadowOffsetX = 10;
36 ctx.shadowOffsetY = 10;
37 ctx.shadowBlur = 15;
38 ctx.shadowColor = "black";
2839
29 var x = this.getX();
30 var y = this.getY();
31 var w = this.getWidth();
32 var h = this.getHeight();
33 if (this.selected) {
34 var max = w > h ? w : h;
35 var gradient = ctx.createLinearGradient(x, y, x + max, y + max);
36 gradient.addColorStop(0, this.style);
37 gradient.addColorStop(0.5, "white");
38 gradient.addColorStop(1, this.style);
39 ctx.fillStyle = gradient;
40 } else {
41 ctx.fillStyle = this.style;
42 }
43 ctx.fillRect(x, y, w, h);
40 var x = this.getLeftX();
41 var y = this.getTopY();
42 var w = this.getWidth();
43 var h = this.getHeight();
44 if (this.selected) {
45 var max = w > h ? w : h;
46 var gradient = ctx.createLinearGradient(x, y, x + max, y + max);
47 gradient.addColorStop(0, this.style);
48 gradient.addColorStop(0.5, "white");
49 gradient.addColorStop(1, this.style);
50 ctx.fillStyle = gradient;
51 } else {
52 ctx.fillStyle = this.style;
53 }
54 ctx.fillRect(x, y, w, h);
4455
45 ctx.lineWidth = "1";
46 ctx.strokeStyle = "black";
47 ctx.shadowColor = "transparent";
48 ctx.strokeRect(x, y, w, h);
49 };
50
51 var addDraggable = function(x, y, w, h, style) {
52 var d = new yoob.Sprite();
53 d.init(x, y, w, h);
54 d.isDraggable = true;
55 d.draw = drawDraggable;
56 d.style = style;
57 d.ongrab = function() {
58 manager.moveToFront(this);
59 };
60 d.ondrop = function() {
61 //alert("Dropped at (" + this.getX() + ", " + this.getY() + ")");
62 if (this.getX() > canvas.width - this.getWidth()) {
63 manager.removeSprite(this);
64 }
65 };
66 manager.addSprite(d);
56 ctx.lineWidth = 1;
57 ctx.strokeStyle = "black";
58 ctx.shadowColor = "transparent";
59 ctx.strokeRect(x, y, w, h);
60 };
61 d.style = style;
62 d.ongrab = function() {
63 manager.moveToFront(this);
64 };
65 d.ondrop = function() {
66 if (this.getX() > canvas.width - this.getWidth()) {
67 manager.removeSprite(this);
68 }
69 };
70 manager.addSprite(d);
6771 };
6872
6973 var addClickable = function(x, y, w, h, text) {
70 var d = new yoob.Sprite();
71 d.init(x, y, w, h);
72 d.isClickable = true;
73 d.draw = function(ctx) {
74 ctx.fillStyle = "blue";
75 ctx.beginPath();
76 ctx.arc(
77 this.getX() + this.getWidth() / 2,
78 this.getY() + this.getHeight() / 2,
79 this.getWidth() / 2,
80 0, 2 * Math.PI,
81 false
82 );
83 ctx.fill();
84 ctx.strokeStyle = "black";
85 ctx.lineWidth = 2;
86 ctx.stroke();
87 };
88 d.containsPoint = function(x, y) {
89 var r = this.getWidth() / 2;
90 var dx = x - (this.getX() + r);
91 var dy = y - (this.getY() + this.getHeight() / 2);
92 var dist = dx * dx + dy * dy;
93 return dist < r * r;
94 };
95 d.onclick = function() {
96 alert("You clicked " + text);
97 };
98 manager.addSprite(d);
74 var d = new yoob.Sprite();
75 d.init({
76 x: x,
77 y: y,
78 width: w,
79 height: h,
80 isClickable: true
81 });
82 d.draw = function(ctx) {
83 ctx.fillStyle = "blue";
84 ctx.beginPath();
85 ctx.arc(
86 this.getX(), this.getY(), this.getWidth() / 2,
87 0, 2 * Math.PI, false
88 );
89 ctx.fill();
90 ctx.strokeStyle = "black";
91 ctx.lineWidth = 2;
92 ctx.stroke();
93 };
94 d.containsPoint = function(x, y) {
95 var r = this.getWidth() / 2;
96 var dx = x - this.getX();
97 var dy = y - this.getY();
98 var dist = dx * dx + dy * dy;
99 return dist < r * r;
100 };
101 d.onclick = function() {
102 alert("You clicked " + text);
103 };
104 manager.addSprite(d);
99105 };
100106
101107 addDraggable(100, 100, 60, 60, "green");
105111 addClickable(200, 200, 80, 80, "blue circle");
106112
107113 interval_id = setInterval(function() {
108 var ctx = canvas.getContext("2d");
109 ctx.clearRect(0, 0, c.width, c.height);
110 manager.draw(ctx);
114 var ctx = canvas.getContext("2d");
115 ctx.clearRect(0, 0, c.width, c.height);
116 manager.draw(ctx);
111117 }, 20);
112118 </script>
1010 * methods.
1111 */
1212 yoob.Sprite = function() {
13 this.isDraggable = false;
14 this.isClickable = false;
15
16 this.init = function(x, y, w, h) {
13
14 /*
15 * x and y always represent the CENTRE of the Sprite().
16 */
17 this.init = function(cfg) {
18 this.x = cfg.x;
19 this.y = cfg.y;
20 this.width = cfg.width;
21 this.height = cfg.height;
22 this.dx = cfg.dx || 0;
23 this.dy = cfg.dy || 0;
24 this.isDraggable = cfg.isDraggable || false;
25 this.isClickable = cfg.isClickable || false;
26 this.selected = false;
27 return this;
28 };
29
30 this.getX = function() {
31 return this.x;
32 };
33
34 this.getLeftX = function() {
35 return this.x - this.width / 2;
36 };
37
38 this.getRightX = function() {
39 return this.x + this.width / 2;
40 };
41
42 this.getY = function() {
43 return this.y;
44 };
45
46 this.getTopY = function() {
47 return this.y - this.height / 2;
48 };
49
50 this.getBottomY = function() {
51 return this.y + this.height / 2;
52 };
53
54 this.getWidth = function() {
55 return this.width;
56 };
57
58 this.getHeight = function() {
59 return this.height;
60 };
61
62 this.setPosition = function(x, y) {
1763 this.x = x;
1864 this.y = y;
19 this.w = w;
20 this.h = h;
21 this.dx = 0;
22 this.dy = 0;
23 this.selected = false;
24 };
25
26 this.getX = function() {
27 return this.x;
28 };
29
30 this.getY = function() {
31 return this.y;
32 };
33
34 this.getCenterX = function() {
35 return this.x + this.w / 2;
36 };
37
38 this.getCenterY = function() {
39 return this.y + this.h / 2;
40 };
41
42 this.getWidth = function() {
43 return this.w;
44 };
45
46 this.getHeight = function() {
47 return this.h;
65 };
66
67 this.setDimensions = function(width, height) {
68 this.width = width;
69 this.height = height;
4870 };
4971
5072 this.setVelocity = function(dx, dy) {
5577 this.setDestination = function(x, y, ticks) {
5678 this.destX = x;
5779 this.destY = y;
58 this.dx = (this.destX - this.getX()) / ticks;
59 this.dy = (this.destY - this.getY()) / ticks;
80 this.setVelocity((this.destX - this.getX()) / ticks, (this.destY - this.getY()) / ticks);
6081 this.destCounter = ticks;
6182 };
6283
6889 this.destCounter--;
6990 if (this.destCounter <= 0) {
7091 this.destCounter = undefined;
71 this.x = this.destX;
72 this.y = this.destY;
92 this.setPosition(this.destX, this.destY);
7393 this.onreachdestination();
7494 }
7595 }
7696 };
7797
78 this.moveTo = function(x, y) {
79 this.x = x;
80 this.y = y;
81 };
82
83 this.moveCenterTo = function(x, y) {
84 this.x = x - this.getWidth() / 2;
85 this.y = y - this.getHeight() / 2;
86 };
87
8898 this.containsPoint = function(x, y) {
89 return (x >= this.getX() && x <= this.getX() + this.getWidth() &&
90 y >= this.getY() && y <= this.getY() + this.getHeight());
99 return (x >= this.getLeftX() && x <= this.getRightX() &&
100 y >= this.getTopY() && y <= this.getBottomY());
91101 };
92102
93103 // you will probably want to override this
94104 this.draw = function(ctx) {
95105 ctx.fillStyle = this.fillStyle || "green";
96 ctx.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());
106 ctx.fillRect(this.getLeftX(), this.getTopY(), this.getWidth(), this.getHeight());
97107 };
98108
99109 // event handlers. override to detect these events.
117127 * This still has a few shortcomings at the moment.
118128 */
119129 yoob.SpriteManager = function() {
120 this.canvas = undefined;
121 this.canvasX = undefined;
122 this.canvasY = undefined;
123 this.offsetX = undefined;
124 this.offsetY = undefined;
125 this.dragging = undefined;
126 this.sprites = [];
130 /*
131 * Attach this SpriteManager to a canvas.
132 */
133 this.init = function(cfg) {
134 this.canvasX = undefined;
135 this.canvasY = undefined;
136 this.offsetX = undefined;
137 this.offsetY = undefined;
138 this.dragging = undefined;
139 this.sprites = [];
140
141 this.canvas = cfg.canvas;
142
143 var $this = this;
144 this.canvas.addEventListener('mousedown', function(e) {
145 return $this.onmousedown(e, e);
146 });
147 this.canvas.addEventListener('touchstart', function(e) {
148 return $this.onmousedown(e, e.touches[0]);
149 });
150
151 this.canvas.addEventListener('mousemove', function(e) {
152 return $this.onmousemove(e, e);
153 });
154 this.canvas.addEventListener('touchmove', function(e) {
155 return $this.onmousemove(e, e.touches[0]);
156 });
157
158 this.canvas.addEventListener('mouseup', function(e) {
159 return $this.onmouseup(e, e);
160 });
161 this.canvas.addEventListener('touchend', function(e) {
162 return $this.onmouseup(e, e.touches[0]);
163 });
164
165 return this;
166 };
127167
128168 /*
129169 * Common handling of mouse and touch events
154194 this.canvasX = touch.pageX - this.canvas.offsetLeft;
155195 this.canvasY = touch.pageY - this.canvas.offsetTop;
156196
157 this.dragging.moveTo(this.canvasX + this.offsetX,
158 this.canvasY + this.offsetY);
197 this.dragging.setPosition(this.canvasX + this.offsetX,
198 this.canvasY + this.offsetY);
159199 };
160200
161201 this.onmouseup = function(e, touch) {
172212 this.dragging = undefined;
173213 this.canvas.style.cursor = "auto";
174214 };
175
176 /*
177 * Attach this SpriteManager to a canvas.
178 */
179 this.init = function(canvas) {
180 this.canvas = canvas;
181
182 var self = this;
183 this.canvas.addEventListener('mousedown', function(e) {
184 return self.onmousedown(e, e);
185 });
186 this.canvas.addEventListener('touchstart', function(e) {
187 return self.onmousedown(e, e.touches[0]);
188 });
189
190 this.canvas.addEventListener('mousemove', function(e) {
191 return self.onmousemove(e, e);
192 });
193 this.canvas.addEventListener('touchmove', function(e) {
194 return self.onmousemove(e, e.touches[0]);
195 });
196
197 this.canvas.addEventListener('mouseup', function(e) {
198 return self.onmouseup(e, e);
199 });
200 this.canvas.addEventListener('touchend', function(e) {
201 return self.onmouseup(e, e.touches[0]);
202 });
203 };
204215
205216 this.move = function() {
206 this.foreach(function(sprite) { sprite.move(); });
217 this.foreach(function(sprite) {
218 sprite.move();
219 });
207220 };
208221
209222 this.draw = function(ctx) {
210223 if (ctx === undefined) {
211224 ctx = this.canvas.getContext('2d');
212225 }
213 for (var i = 0; i < this.sprites.length; i++) {
214 this.sprites[i].draw(ctx);
215 }
226 this.foreach(function(sprite) {
227 sprite.draw(ctx);
228 });
216229 };
217230
218231 this.addSprite = function(sprite) {