Permalink
Browse files

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

…oting
  • Loading branch information...
1 parent 1f5afd4 commit 493b7187483e4c86f6cd04f985a72416bd7ffeb1 @zachwe zachwe committed Jun 23, 2011
Showing with 277 additions and 31 deletions.
  1. +265 −31 public/client.js
  2. +11 −0 public/jquery.mousewheel.min.js
  3. +1 −0 views/index.ejs
View
@@ -8,7 +8,7 @@ $(document).ready(function() {
var viewport = {
height: 600,
width: 800,
- zoom: .5,
+ zoom: 0.5,
x0: 0,
x1: 800,
y0: 0,
@@ -43,15 +43,29 @@ $(document).ready(function() {
//speed that viewport is moved
var incr;
//whether or not we are in motion;
- var moving = false;
+ var moving = false
+ //whether we are shooting
+ var shooting = false;
+ //global var so that we can always stop motion if we want
+ var interval;
+
+ //At full size, offset from the slingshot to the rubber band attachment points
+ const ssOffset = {
+ front: { x: 15, y: 15 },
+ back: { x: 15, y: 25}
+ };
+ //height of the slingshot;
+ const ssHeight = 199;
+ //max size of rubber band
+ const bandSize = 450;
//load all the images and store them, then call redraw()
function init() {
var bg1TileSrcs = {'BLUE_GRASS_FG_1.png': {height: 187, width: 332, defaultY: viewport.height - viewport.groundY, index: 1},
'BLUE_GRASS_FG_2.png': {height: 33, width: 332, defaultY: viewport.height - viewport.groundY - 33, index: 2},
};
- var bg1ImgSrcs = {'SLINGSHOT_01_BACK.png': {height: 199, width: 38, defaultY: viewport.height - viewport.groundY - 124, defaultX: 40},
- 'SLINGSHOT_01_FRONT.png': {height: 124, width: 43, defaultY: viewport.height - viewport.groundY - 124, defaultX: 40},
+ var bg1ImgSrcs = {'SLINGSHOT_01_BACK.png': {height: 199, width: 38, defaultY: viewport.height - viewport.groundY - 124, defaultX: 250, index: 1},
+ 'SLINGSHOT_01_FRONT.png': {height: 124, width: 43, defaultY: viewport.height - viewport.groundY - 124, defaultX: 220, index: 2},
};
var fgImgSrcs = {
'INGAME_BIRDS_PIGS.png': {height: 920, width: 859},
@@ -97,6 +111,7 @@ $(document).ready(function() {
img.height = data.height;
img.defaultY = data.defaultY;
img.defaultX = data.defaultX;
+ img.index = data.index;
bgImages[key] = img;
//when all images are loaded, draw;
@@ -133,48 +148,224 @@ $(document).ready(function() {
//called whenever some change to the viewport is occurring.
function modifyViewport(zoom, x) {
+ if(moving) {
+ return;
+ }
moving = true;
if(x > viewport.x0) {
incr = 4;
+ } else if(x < viewport.x0){
+ incr = -4;
} else {
- incr = -4
+ zoom - viewport.zoom > 0 ? incr = -4 : incr = 4;
}
if(zoom != viewport.zoom) {
+ var zoomDiff;
if(viewport.x0 != x) {
- var zoomDiff = ((zoom - viewport.zoom) / Math.abs((viewport.x0 - x))) * incr;
+ zoomDiff = ((zoom - viewport.zoom) / (x - viewport.x0 )) * incr;
} else {
- var zoomDiff = (2.0 / 400);
+ var steps = (viewport.height / zoom - viewport.height / viewport.zoom) / incr;
+ zoomDiff = (zoom - viewport.zoom) / steps;
+
}
}
+
//set the redraw interval
- var interval = setInterval(function() {
+ interval = setInterval(function() {
if(! transitionView(x, zoom, zoomDiff)) {
clearInterval(interval);
+ moving = false;
}
}, 10);
}
//handles a single frame of animation by adjusting image size and position and redrawing the canvas.
function transitionView(goalX, goalZoom, zoomDiff) {
- if(Math.abs(viewport.x0 - goalX) < 2 && (zoomDiff == undefined || Math.abs(viewport.zoom - goalZoom) < .01)) {
- return false;
+ //console.log(Math.abs(viewport.x0 - goalX) < 2 && (zoomDiff == undefined || Math.abs(viewport.zoom - goalZoom) < .01));
+ if(Math.abs(viewport.x0 - goalX) < 2) {
+ if (zoomDiff == undefined || Math.abs(viewport.zoom - goalZoom) < .01) {
+/* viewport.x0 = goalX;
+ viewport.zoom = goalZoom;
+ redraw();*/
+ return false;
+ } else {
+ viewport.zoom += zoomDiff;
+ //viewport.x1 += incr;
+ }
} else {
-
viewport.x0 += incr;
- viewport.x1 += incr;
+ //viewport.x1 += incr;
if(goalZoom != undefined) {
viewport.zoom += zoomDiff;
}
- redraw();
- return true;
}
+ redraw();
+ return true;
}
//redraw the entire canvas with updated positions.
function redraw() {
bgContext.clearRect(0, 0, viewport.width, viewport.height);
+ placeBgTiles();
+ placeBgImages();
+ }
+
+/*
+* event handlers
+*/
+//this is set on mousedown, then used to prevent action on long clicks.
+var mouseDownTime;
+
+//click handler
+ var panner = function(e) {
+ //if the click was a long click, don't do anything
+ if(e.timeStamp - mouseDownTime > 200) {
+ return;
+ }
+ //click event gets triggered on mouseup. This adds a delay so that we won't do anything on the intial mouseup.
+ if(shooting) {
+ shooting = false;
+ return;
+ }
+ if(getLeftBound() + viewport.x0 > viewport.width) {
+ modifyViewport(defaultLeft.zoom, defaultLeft.x0);
+ } else {
+ modifyViewport(defaultRight.zoom, defaultRight.x0);
+ }
+ };
+
+//toggle zoom and panning
+ $('canvas').click(function(e) {
+ panner(e)
+ })
+//zoom in and out with mousewheel
+ .mousewheel(function() {
+ if(!moving) {
+ if(viewport.zoom > .75) {
+ //since we're going to the fully zoomed out pos, set viewport x to 0 so we're seeing the whole world.
+ modifyViewport(0.5, 0);
+ } else {
+ modifyViewport(1.0, viewport.x0);
+ }
+ }
+ })
+ //rubber band animations
+ .mousedown(function(e) {
+ mouseDownTime = e.timeStamp;
+ console.log('zoom: ' + viewport.zoom);
- //tile images
+ var canvasCoords = $('canvas').offset();
+ var relX = e.pageX - canvasCoords.left;
+ var relY = e.pageY - canvasCoords.top;
+ var rad = getBandSize(relX, relY);
+ console.log('rad: ' + rad);
+ //If cursor is outside of the range of the rubber band, return
+ if(rad > bandSize) {
+ return;
+ }
+ //If we're not in a position to shoot, return.
+ if(moving || viewport.x0 != 0){
+ return;
+ }
+ moving = true;
+ shooting = true;
+
+ prepareShot(relX, relY);
+ $(this).mousemove(function(e2) {
+ prepareShot(e2.pageX - canvasCoords.left, e2.pageY - canvasCoords.top);
+ });
+ $(this).unbind('click');
+ })
+ .mouseup(function(e) {
+ //clear the slingshot graphics
+ clearShot();
+ //unbind mousemove handler
+ $(this).unbind('mousemove');
+ //rebind the click handler
+ $(this).click(panner);
+ moving = false;
+ });
+
+
+
+ init();
+
+ //helper functions
+ function prepareShot(mouseX, mouseY) {
+ fgContext.clearRect(0, 0, viewport.width, viewport.height);
+
+ var img = fgImages['SLINGSHOT_RUBBERBAND.png'];
+ var width = Math.ceil(img.width * viewport.zoom * .5);
+ var height = Math.ceil(img.height * viewport.zoom * .5);
+
+
+ var ss = getSS();
+ var y = Math.round(viewport.height - viewport.groundY - ssHeight * viewport.zoom);
+ for(var i in ss) {
+ var ssComponent = ss[i];
+ x = Math.ceil((ssComponent.defaultX - viewport.x0) * viewport.zoom);
+ if(ssComponent.index == 1) {
+ x += ssOffset.front.x;
+ y += ssOffset.front.y;
+ } else {
+ x += ssOffset.back.x;
+ y += ssOffset.back.y;
+ }
+
+ var delX = x - mouseX;
+ var delY = y - mouseY;
+ var angle = Math.atan(1.0 * delY / delX);
+ if(delX < 0) {
+ angle += Math.PI;
+ }
+
+ fgContext.save();
+ fgContext.translate(mouseX, mouseY);
+ fgContext.rotate(angle);
+ var rotHor = 0;
+
+ while(rotHor < Math.sqrt(delX * delX + delY * delY)) {
+ fgContext.drawImage(img, rotHor, 0, width, height);//Math.ceil(img.width * viewport.zoom), Math.ceil(img.height * viewport.zoom));
+ rotHor += width;
+ }
+ fgContext.restore();
+
+ }
+ }
+
+ function clearShot() {
+ fgContext.clearRect(0, 0, viewport.width, viewport.height);
+ }
+
+ function getLeftBound() {
+ return viewport.x0 + (1 / (2 * viewport.zoom)) * viewport.width;
+ }
+
+ //place non-tile background images
+ function placeBgImages() {
+ for(var i in bgImages) {
+ var img = bgImages[i];
+
+ var height = Math.round(img.height * viewport.zoom);
+ var width = img.width * viewport.zoom;
+ var y = Math.round(viewport.height - viewport.groundY - ssHeight * viewport.zoom);
+ var x;
+
+ if(img.defaultX < viewport.x0 && img.defaultX + img.width > viewport.x0) {
+ var crop = viewport.x0 - img.defaultX;
+
+ x = Math.floor((img.width - crop) * viewport.zoom);
+ //console.log([img, crop, 0, img.width - crop, img.height, x, y, Math.floor(crop * viewport.zoom), height]);
+ bgContext.drawImage(img, crop, 0, img.width - crop, img.height, 0, y, width - crop * viewport.zoom, height);
+ } else if(img.defaultX >= viewport.x0) {
+ x = Math.floor((img.defaultX - viewport.x0) * viewport.zoom);
+ bgContext.drawImage(img, x, y, width, height);
+ }
+ }
+ }
+
+ //place tile images
+ function placeBgTiles() {
for(var i in bgTiles) {
var img = bgTiles[i]
//scaled dimensions of the image to account for zoom
@@ -186,44 +377,87 @@ $(document).ready(function() {
while(initialWidth < 0) {
initialWidth += adjustedWidth;
}
- initialWidth = Math.ceil(initialWidth);
//offset of the first image, in terms of the images original size.
var initialOffset = img.width - (initialWidth / viewport.zoom);
+ initialWidth = Math.round(initialWidth);
var horzPos = 0;
+ //specific positioning for each image
var y;
switch(img.index){
- case 1: y = viewport.height - viewport.groundY;
- break;
- case 2: y = viewport.height - viewport.groundY - img.height * viewport.zoom;
+ case 1:
+ y = viewport.height - viewport.groundY;
+ break;
+ case 2:
+ y = viewport.height - viewport.groundY - img.height * viewport.zoom;
+ break;
}
+ //turn floating points back to integers.
+ y = Math.round(y)
+ initialOffset = Math.round(initialOffset);
+ adjustedHeight = Math.round(adjustedHeight);
+ var crop = Math.floor(initialWidth / viewport.zoom);
//first tile
- bgContext.drawImage(img, initialOffset, 0, initialWidth / viewport.zoom, img.height, 0, y, initialWidth, adjustedHeight);
+ bgContext.drawImage(img, initialOffset, 0, crop, img.height, 0, y, initialWidth, adjustedHeight);
horzPos += initialWidth;
//filler tiles
- adjustedWidth = Math.ceil(adjustedWidth);
- while(horzPos + adjustedWidth <= viewport.x1 - viewport.x0) {
+ adjustedWidth = Math.round(adjustedWidth);
+ while(horzPos + adjustedWidth <= viewport.width){
+
bgContext.drawImage(img, horzPos, y, adjustedWidth, adjustedHeight);
horzPos += adjustedWidth;
}
//last tile
- var finalWidth = (viewport.x1 - viewport.x0) - horzPos;
- bgContext.drawImage(img, 0, 0, finalWidth / viewport.zoom, img.height, horzPos, y, finalWidth, adjustedHeight);
+ var finalWidth = viewport.width - horzPos;
+ while(finalWidth <= 0) {
+ finalWidth += adjustedWidth;
+ }
+ //console.log([viewport.x0, viewport.x1, finalWidth, horzPos]);
+ bgContext.drawImage(img, 0, 0, Math.floor(finalWidth / viewport.zoom), img.height, horzPos, y, finalWidth, adjustedHeight);
}
}
-
- $('canvas').click(function() {
- if(!moving) {
- modifyViewport(defaultRight.zoom, defaultRight.x0);
+
+ //returns an object that contains both slingshot images
+ function getSS() {
+ return bgImages;
+ }
+
+ function getBandSize(mouseX, mouseY) {
+ var sec1, sec2;
+ var coords = getViewportCoords(mouseX, mouseY);
+ var ss = getSS();
+ for(var i in ss) {
+ img = ss[i];
+ if(img.index == 1) {
+ var y = viewport.height - viewport.groundY - ssHeight + ssOffset.front.y;
+ var x = img.defaultX + ssOffset.front.x;
+ sec1 = Math.sqrt((coords.x - x) * (coords.x - x) + (coords.y - y) * (coords.y - y));
+ } else {
+ var y = viewport.height - viewport.groundY - ssHeight + ssOffset.back.y;
+ var x = img.defaultX + ssOffset.back.x;
+ sec2 = Math.sqrt((coords.x - x) * (coords.x - x) + (coords.y - y) * (coords.y - y));
+ }
+
}
- });
-
+ return sec1 + sec2;
+ }
+//converts pixels on the canvas to units on the viewport
+ function getViewportCoords(canX, canY) {
+ console.log('canX: ' + canX);
+ var vpX = Math.round(canX / (2 * viewport.zoom) + viewport.x0);
+ console.log('vpx: ' + vpX);
+ var vpY = Math.round((canY - viewport.height + viewport.groundY) / (2 * viewport.zoom) + viewport.height - viewport.groundY);
+ //var vpY = Math.round(canY / (2 * viewport.zoom));
+ console.log('canY: ' + canY);
+ console.log('vpY: ' + vpY);
+ console.log('');
+ return {x: vpX, y: vpY};
+ }
- init();
});
Oops, something went wrong.

0 comments on commit 493b718

Please sign in to comment.