Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

draw bg graphics and add mouse events for scrolling, panning, and sho…

…oting
  • Loading branch information...
commit 493b7187483e4c86f6cd04f985a72416bd7ffeb1 1 parent 1f5afd4
authored June 22, 2011
296  public/client.js
@@ -8,7 +8,7 @@ $(document).ready(function() {
8 8
 	var viewport = {
9 9
 		height: 600,
10 10
 		width: 800,
11  
-		zoom: .5,
  11
+		zoom: 0.5,
12 12
 		x0: 0, 
13 13
 		x1: 800,
14 14
 		y0: 0,
@@ -43,15 +43,29 @@ $(document).ready(function() {
43 43
 //speed that viewport is moved
44 44
 	var incr;
45 45
 	//whether or not we are in motion;
46  
-	var moving = false;
  46
+	var moving = false
  47
+	//whether we are shooting
  48
+	var shooting = false;
  49
+	//global var so that we can always stop motion if we want
  50
+	var interval;
  51
+
  52
+	//At full size, offset from the slingshot to the rubber band attachment points
  53
+	const ssOffset = {
  54
+		front: { x: 15, y: 15 },
  55
+		back: { x: 15, y: 25}
  56
+	};
  57
+	//height of the slingshot;
  58
+	const ssHeight = 199;
  59
+	//max size of rubber band
  60
+	const bandSize = 450;
47 61
 
48 62
 //load all the images and store them, then call redraw()
49 63
 	function init() {
50 64
 		var bg1TileSrcs = {'BLUE_GRASS_FG_1.png': {height: 187, width: 332, defaultY: viewport.height - viewport.groundY, index: 1},
51 65
 									 'BLUE_GRASS_FG_2.png': {height: 33, width: 332, defaultY: viewport.height - viewport.groundY - 33, index: 2}, 
52 66
 		};
53  
-		var bg1ImgSrcs = {'SLINGSHOT_01_BACK.png': {height: 199, width: 38, defaultY: viewport.height - viewport.groundY - 124, defaultX: 40},
54  
-									 		'SLINGSHOT_01_FRONT.png': {height: 124, width: 43, defaultY: viewport.height - viewport.groundY - 124, defaultX: 40},
  67
+		var bg1ImgSrcs = {'SLINGSHOT_01_BACK.png': {height: 199, width: 38, defaultY: viewport.height - viewport.groundY - 124, defaultX: 250, index: 1},
  68
+									 		'SLINGSHOT_01_FRONT.png': {height: 124, width: 43, defaultY: viewport.height - viewport.groundY - 124, defaultX: 220, index: 2},
55 69
 		};
56 70
 		var fgImgSrcs = {
57 71
 									 'INGAME_BIRDS_PIGS.png': {height: 920, width: 859},
@@ -97,6 +111,7 @@ $(document).ready(function() {
97 111
 			img.height = data.height;
98 112
 			img.defaultY = data.defaultY;
99 113
 			img.defaultX = data.defaultX;
  114
+			img.index = data.index;
100 115
 
101 116
 			bgImages[key] = img;
102 117
 			//when all images are loaded, draw;
@@ -133,48 +148,224 @@ $(document).ready(function() {
133 148
 
134 149
 //called whenever some change to the viewport is occurring.	
135 150
 	function modifyViewport(zoom, x) {
  151
+		if(moving) {
  152
+			return;
  153
+		}
136 154
 		moving = true;
137 155
 		if(x > viewport.x0) {
138 156
 			incr = 4;
  157
+		} else if(x < viewport.x0){
  158
+			incr = -4;
139 159
 		} else {
140  
-			incr = -4
  160
+			zoom - viewport.zoom > 0 ? incr = -4 : incr = 4;
141 161
 		}
142 162
 		if(zoom != viewport.zoom) {
  163
+			var zoomDiff;
143 164
 			if(viewport.x0 != x) {
144  
-				var zoomDiff = ((zoom - viewport.zoom) / Math.abs((viewport.x0 - x))) * incr;
  165
+				zoomDiff = ((zoom - viewport.zoom) / (x - viewport.x0 )) * incr;
145 166
 			} else {
146  
-				var zoomDiff = (2.0 / 400);
  167
+				var steps = (viewport.height / zoom - viewport.height / viewport.zoom) / incr;
  168
+				zoomDiff = (zoom - viewport.zoom) / steps;
  169
+
147 170
 			}
148 171
 		}
  172
+
149 173
 		//set the redraw interval
150  
-		var interval = setInterval(function() {
  174
+		interval = setInterval(function() {
151 175
 			if(! transitionView(x, zoom, zoomDiff)) {
152 176
 				clearInterval(interval);
  177
+				moving = false;
153 178
 			}
154 179
 		}, 10);
155 180
 	}
156 181
 	
157 182
 //handles a single frame of animation by adjusting image size and position and redrawing the canvas.
158 183
 	function transitionView(goalX, goalZoom, zoomDiff) {
159  
-		if(Math.abs(viewport.x0 - goalX) < 2 && (zoomDiff == undefined || Math.abs(viewport.zoom - goalZoom) < .01)) {
160  
-			return false;
  184
+		//console.log(Math.abs(viewport.x0 - goalX) < 2 && (zoomDiff == undefined || Math.abs(viewport.zoom - goalZoom) < .01));
  185
+		if(Math.abs(viewport.x0 - goalX) < 2) {
  186
+			 if (zoomDiff == undefined || Math.abs(viewport.zoom - goalZoom) < .01) {
  187
+/*				viewport.x0 = goalX;
  188
+				viewport.zoom = goalZoom;
  189
+				redraw();*/
  190
+				return false;
  191
+			} else {
  192
+				viewport.zoom += zoomDiff;
  193
+				//viewport.x1 += incr;
  194
+			}
161 195
 		} else {
162  
-
163 196
 			viewport.x0 += incr;
164  
-			viewport.x1 += incr;
  197
+			//viewport.x1 += incr;
165 198
 			if(goalZoom != undefined) {
166 199
 				viewport.zoom += zoomDiff;
167 200
 			}
168  
-			redraw();
169  
-			return true;
170 201
 		}
  202
+		redraw();
  203
+		return true;
171 204
 	}
172 205
 	
173 206
 	//redraw the entire canvas with updated positions.
174 207
 	function redraw() {
175 208
 		bgContext.clearRect(0, 0, viewport.width, viewport.height);
  209
+		placeBgTiles();
  210
+		placeBgImages();
  211
+	}
  212
+
  213
+/*
  214
+* event handlers
  215
+*/
  216
+//this is set on mousedown, then used to prevent action on long clicks.
  217
+var mouseDownTime;
  218
+
  219
+//click handler
  220
+	var panner = function(e) {
  221
+		//if the click was a long click, don't do anything
  222
+		if(e.timeStamp - mouseDownTime > 200) {
  223
+			return;
  224
+		}
  225
+		//click event gets triggered on mouseup. This adds a delay so that we won't do anything on the intial mouseup.
  226
+		if(shooting) {
  227
+			shooting = false;
  228
+			return;
  229
+		}
  230
+		if(getLeftBound() + viewport.x0 > viewport.width) {
  231
+			modifyViewport(defaultLeft.zoom, defaultLeft.x0);
  232
+		} else {
  233
+			modifyViewport(defaultRight.zoom, defaultRight.x0);
  234
+		}
  235
+	};
  236
+
  237
+//toggle zoom and panning
  238
+	$('canvas').click(function(e) {
  239
+		panner(e)
  240
+	})
  241
+//zoom in and out with mousewheel
  242
+	.mousewheel(function() {
  243
+		if(!moving) {
  244
+			if(viewport.zoom > .75) {
  245
+				//since we're going to the fully zoomed out pos, set viewport x to 0 so we're seeing the whole world.
  246
+				modifyViewport(0.5, 0);
  247
+			} else {
  248
+				modifyViewport(1.0, viewport.x0);
  249
+			}
  250
+		}
  251
+	})
  252
+	//rubber band animations
  253
+ .mousedown(function(e) {
  254
+	 mouseDownTime = e.timeStamp;
  255
+	 console.log('zoom: ' + viewport.zoom);
176 256
 		
177  
-		//tile images	
  257
+		var canvasCoords = $('canvas').offset();
  258
+		var relX = e.pageX - canvasCoords.left;
  259
+		var relY = e.pageY - canvasCoords.top;
  260
+		var rad = getBandSize(relX, relY);
  261
+		console.log('rad: ' + rad);
  262
+		//If cursor is outside of the range of the rubber band, return
  263
+		if(rad > bandSize) {
  264
+			return;
  265
+		}
  266
+		//If we're not in a position to shoot, return.
  267
+	 if(moving || viewport.x0 != 0){
  268
+		return;
  269
+	 }
  270
+	 moving = true;
  271
+	 shooting = true;
  272
+
  273
+		prepareShot(relX, relY);
  274
+		$(this).mousemove(function(e2) {
  275
+			prepareShot(e2.pageX - canvasCoords.left, e2.pageY - canvasCoords.top);
  276
+		});
  277
+		$(this).unbind('click');
  278
+	})
  279
+ .mouseup(function(e) {
  280
+	 //clear the slingshot graphics
  281
+	clearShot();
  282
+	//unbind mousemove handler
  283
+	$(this).unbind('mousemove');
  284
+	//rebind the click handler
  285
+	$(this).click(panner);
  286
+	 moving = false;
  287
+ });
  288
+
  289
+
  290
+
  291
+	init();
  292
+
  293
+	//helper functions
  294
+	function prepareShot(mouseX, mouseY) {
  295
+		fgContext.clearRect(0, 0, viewport.width, viewport.height);
  296
+		
  297
+		var img = fgImages['SLINGSHOT_RUBBERBAND.png'];
  298
+		var width = Math.ceil(img.width * viewport.zoom * .5);
  299
+		var height = Math.ceil(img.height * viewport.zoom * .5);
  300
+
  301
+
  302
+		var ss = getSS();
  303
+		var y = Math.round(viewport.height - viewport.groundY - ssHeight * viewport.zoom);
  304
+		for(var i in ss) {
  305
+			var ssComponent = ss[i];
  306
+			x = Math.ceil((ssComponent.defaultX - viewport.x0) * viewport.zoom);
  307
+			if(ssComponent.index == 1) {
  308
+				x += ssOffset.front.x;
  309
+				y += ssOffset.front.y;
  310
+			} else {
  311
+				x += ssOffset.back.x;
  312
+				y += ssOffset.back.y;
  313
+			}
  314
+			
  315
+			var delX = x - mouseX;
  316
+			var delY = y - mouseY;
  317
+			var angle = Math.atan(1.0 * delY / delX);
  318
+			if(delX < 0) {
  319
+				angle += Math.PI;
  320
+			}
  321
+
  322
+			fgContext.save();
  323
+			fgContext.translate(mouseX, mouseY);
  324
+			fgContext.rotate(angle);
  325
+			var rotHor = 0;
  326
+
  327
+			while(rotHor < Math.sqrt(delX * delX + delY * delY)) {
  328
+				fgContext.drawImage(img, rotHor, 0, width, height);//Math.ceil(img.width * viewport.zoom), Math.ceil(img.height * viewport.zoom));
  329
+				rotHor += width;
  330
+			}
  331
+			fgContext.restore();
  332
+
  333
+		}
  334
+	}
  335
+
  336
+	function clearShot() {
  337
+		fgContext.clearRect(0, 0, viewport.width, viewport.height);
  338
+	}
  339
+
  340
+	function getLeftBound() {
  341
+		return viewport.x0 + (1 / (2 * viewport.zoom)) * viewport.width;
  342
+	}
  343
+	
  344
+	//place non-tile background images	
  345
+	function placeBgImages() {
  346
+		for(var i in bgImages) {
  347
+			var img = bgImages[i];
  348
+
  349
+			var height = Math.round(img.height * viewport.zoom);
  350
+			var width = img.width * viewport.zoom;
  351
+			var y = Math.round(viewport.height - viewport.groundY - ssHeight * viewport.zoom);
  352
+			var x;
  353
+
  354
+			if(img.defaultX < viewport.x0 && img.defaultX + img.width > viewport.x0) {
  355
+				var crop = viewport.x0 - img.defaultX;
  356
+					
  357
+				x = Math.floor((img.width - crop) * viewport.zoom);
  358
+				//console.log([img, crop, 0, img.width - crop, img.height, x, y, Math.floor(crop * viewport.zoom), height]);
  359
+				bgContext.drawImage(img, crop, 0, img.width - crop, img.height, 0, y, width - crop * viewport.zoom, height);
  360
+			} else if(img.defaultX >= viewport.x0) {
  361
+				x = Math.floor((img.defaultX - viewport.x0) * viewport.zoom);
  362
+				bgContext.drawImage(img, x, y, width, height);
  363
+			}
  364
+		}
  365
+	}
  366
+
  367
+		//place tile images	
  368
+	function placeBgTiles() {
178 369
 		for(var i in bgTiles) {
179 370
 			var img = bgTiles[i] 
180 371
 			//scaled dimensions of the image to account for zoom
@@ -186,44 +377,87 @@ $(document).ready(function() {
186 377
 			while(initialWidth < 0) {
187 378
 				initialWidth += adjustedWidth;
188 379
 			}
189  
-			initialWidth = Math.ceil(initialWidth);
190 380
 
191 381
 			//offset of the first image, in terms of the images original size.
192 382
 			var initialOffset = img.width - (initialWidth / viewport.zoom);
  383
+			initialWidth = Math.round(initialWidth);
193 384
 			var horzPos = 0;
194 385
 			
  386
+			//specific positioning for each image
195 387
 			var y;	
196 388
 			switch(img.index){
197  
-				case 1: y = viewport.height - viewport.groundY;
198  
-								break;
199  
-				case 2: y = viewport.height - viewport.groundY - img.height * viewport.zoom;
  389
+				case 1: 
  390
+					y = viewport.height - viewport.groundY;
  391
+					break;
  392
+				case 2: 
  393
+					y = viewport.height - viewport.groundY - img.height * viewport.zoom;
  394
+					break;
200 395
 			}
  396
+			//turn floating points back to integers.
  397
+			y = Math.round(y)
  398
+			initialOffset = Math.round(initialOffset);
  399
+			adjustedHeight = Math.round(adjustedHeight);
  400
+			var crop = Math.floor(initialWidth / viewport.zoom);
201 401
 
202 402
 			//first tile
203  
-			bgContext.drawImage(img, initialOffset, 0, initialWidth / viewport.zoom, img.height, 0, y, initialWidth, adjustedHeight);
  403
+			bgContext.drawImage(img, initialOffset, 0, crop, img.height, 0, y, initialWidth, adjustedHeight);
204 404
 
205 405
 			horzPos += initialWidth;
206 406
 
207 407
 			//filler tiles
208  
-			adjustedWidth = Math.ceil(adjustedWidth);
209  
-			while(horzPos + adjustedWidth <= viewport.x1 - viewport.x0) {
  408
+			adjustedWidth = Math.round(adjustedWidth);
  409
+			while(horzPos + adjustedWidth <= viewport.width){
  410
+
210 411
 				bgContext.drawImage(img, horzPos, y, adjustedWidth, adjustedHeight);
211 412
 				horzPos += adjustedWidth;
212 413
 			}
213 414
 	
214 415
 			//last tile
215  
-			var finalWidth = (viewport.x1 - viewport.x0) - horzPos;
216  
-			bgContext.drawImage(img, 0, 0, finalWidth / viewport.zoom, img.height, horzPos, y, finalWidth, adjustedHeight);
  416
+			var finalWidth = viewport.width - horzPos;
  417
+			while(finalWidth <= 0) {
  418
+				finalWidth += adjustedWidth;
  419
+			}
  420
+			//console.log([viewport.x0, viewport.x1, finalWidth, horzPos]);
  421
+			bgContext.drawImage(img, 0, 0, Math.floor(finalWidth / viewport.zoom), img.height, horzPos, y, finalWidth, adjustedHeight);
217 422
 		}
218 423
 	}
219  
-
220  
-	$('canvas').click(function() {
221  
-		if(!moving) {
222  
-			modifyViewport(defaultRight.zoom, defaultRight.x0);
  424
+	
  425
+	//returns an object that contains both slingshot images
  426
+	function getSS() {
  427
+		return bgImages;
  428
+	}
  429
+	
  430
+	function getBandSize(mouseX, mouseY) {
  431
+		var sec1, sec2;
  432
+		var coords = getViewportCoords(mouseX, mouseY);
  433
+		var ss = getSS();
  434
+		for(var i in ss) {
  435
+			img = ss[i];
  436
+			if(img.index == 1) {
  437
+				var y = viewport.height - viewport.groundY  - ssHeight + ssOffset.front.y;
  438
+				var x = img.defaultX + ssOffset.front.x;
  439
+				sec1 = Math.sqrt((coords.x - x) * (coords.x - x) + (coords.y - y) * (coords.y - y));
  440
+			} else {
  441
+				var y = viewport.height - viewport.groundY  - ssHeight + ssOffset.back.y;
  442
+				var x = img.defaultX + ssOffset.back.x;
  443
+				sec2 = Math.sqrt((coords.x - x) * (coords.x - x) + (coords.y - y) * (coords.y - y));
  444
+			}
  445
+			
223 446
 		}
224  
-	});
225  
-
  447
+		return sec1 + sec2;
  448
+	}
226 449
 
  450
+//converts pixels on the canvas to units on the viewport
  451
+	function getViewportCoords(canX, canY) {
  452
+		console.log('canX: ' + canX);
  453
+		var vpX = Math.round(canX / (2 * viewport.zoom) + viewport.x0);
  454
+		console.log('vpx: ' + vpX);
  455
+		var vpY = Math.round((canY - viewport.height + viewport.groundY) / (2 * viewport.zoom) + viewport.height - viewport.groundY);
  456
+		//var vpY = Math.round(canY / (2 * viewport.zoom));
  457
+		console.log('canY: ' + canY);
  458
+		console.log('vpY: ' + vpY);
  459
+		console.log('');
  460
+		return {x: vpX, y: vpY};
  461
+	}
227 462
 
228  
-	init();
229 463
 });
11  public/jquery.mousewheel.min.js
... ...
@@ -0,0 +1,11 @@
  1
+/* Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
  2
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
  3
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
  4
+ * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
  5
+ * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
  6
+ *
  7
+ * Version: 3.0.2
  8
+ * 
  9
+ * Requires: 1.2.2+
  10
+ */
  11
+(function(c){var a=["DOMMouseScroll","mousewheel"];c.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var d=a.length;d;){this.addEventListener(a[--d],b,false)}}else{this.onmousewheel=b}},teardown:function(){if(this.removeEventListener){for(var d=a.length;d;){this.removeEventListener(a[--d],b,false)}}else{this.onmousewheel=null}}};c.fn.extend({mousewheel:function(d){return d?this.bind("mousewheel",d):this.trigger("mousewheel")},unmousewheel:function(d){return this.unbind("mousewheel",d)}});function b(f){var d=[].slice.call(arguments,1),g=0,e=true;f=c.event.fix(f||window.event);f.type="mousewheel";if(f.wheelDelta){g=f.wheelDelta/120}if(f.detail){g=-f.detail/3}d.unshift(f,g);return c.event.handle.apply(this,d)}})(jQuery);
1  views/index.ejs
@@ -2,6 +2,7 @@
2 2
 <html>
3 3
 <head>
4 4
 	<script type="text/javascript" src="/jquery.js"></script>
  5
+	<script type="text/javascript" src="/jquery.mousewheel.min.js"></script>
5 6
 	<script type="text/javascript" src="/client.js"></script>
6 7
 	<link href="style.css" rel="stylesheet" type="text/css">
7 8
 </head>

0 notes on commit 493b718

Please sign in to comment.
Something went wrong with that request. Please try again.