From 97adc4bb943b7c72784b2f76bb1f6652912e42fe Mon Sep 17 00:00:00 2001 From: dsc Date: Sat, 11 Dec 2010 23:27:57 -0800 Subject: [PATCH] Position refactor complete, I think. --- src/ezl/layer.cjs | 64 ++++++++++++++++++++++++++++++++++----- src/ezl/loc/boundingbox.cjs | 30 ++++++++++++------ src/ezl/math/vec.cjs | 4 ++ src/ezl/shape/circle.cjs | 7 +++- src/ezl/shape/rect.cjs | 6 ++-- src/tanks/config.cjs | 2 +- src/tanks/game.cjs | 4 +- src/tanks/map/pathmap.cjs | 24 +++++++++------ src/tanks/map/trajectory.cjs | 4 +- src/tanks/thing/player.cjs | 2 +- src/tanks/thing/tank.cjs | 36 ++++------------------ src/tanks/thing/thing.cjs | 47 ++++++++++++++++------------- src/tanks/ui/grid.cjs | 14 ++++---- src/tanks/ui/main.cjs | 3 ++ www/test/shapes/test-shapes.js | 15 +++++++++- 15 files changed, 164 insertions(+), 98 deletions(-) diff --git a/src/ezl/layer.cjs b/src/ezl/layer.cjs index dfc5aad..19d5396 100644 --- a/src/ezl/layer.cjs +++ b/src/ezl/layer.cjs @@ -43,6 +43,12 @@ Y.subclass('Layer', { transform : null, // Object useCanvasScaling : false, // default to CSS3 scaling + /// Defaults /// + + originX : 0, + originY : 0, + + /// Setup /// @@ -53,7 +59,7 @@ Y.subclass('Layer', { this.negBleed = new Loc(0,0); this.posBleed = new Loc(0,0); - this.boundingBox = new BoundingBox(0,0, 0,0); + this.boundingBox = new BoundingBox(0,0, 0,0, this.originX,this.originY); this._origin = this.boundingBox.origin; this.transform = { @@ -139,6 +145,36 @@ Y.subclass('Layer', { attr : Y.attr.methodize(), + size : function size(w,h){ + if (w === undefined && h === undefined) + return new Vec(this.layerWidth,this.layerHeight); + + this.layerWidth = w; + this.layerHeight = h; + + var bb = this.boundingBox.resize(w,h) + , nb = this.negBleed, pb = this.posBleed + + // HTMLCanvas.{width,height} is a long + , cw = this.canvasWidth = Math.ceil(w + nb.x + pb.x) + , ch = this.canvasHeight = Math.ceil(h + nb.y + pb.y) + ; + + this.layer.css({ + 'width' : w, 'height' : h, + 'left' : bb.x1, 'top' : bb.y1 + }); + this.canvas.css({ + 'width' : cw, 'height' : ch, + 'margin-left' : -nb.x, 'top' : -nb.y + }); + var el = this.canvas[0]; + el.width = cw; + el.height = ch; + + return this; + }, + /** * Changes the layer's width and then updates the canvas. */ @@ -149,14 +185,14 @@ Y.subclass('Layer', { this.layerWidth = w; var bb = this.boundingBox.resize(w, this.layerHeight) - , ro = bb.relOrigin + // , ro = bb.relOrigin , nb = this.negBleed , cw = this.canvasWidth = Math.ceil(w + nb.x + this.posBleed.x); // HTMLCanvas.width is a long this.layer.css({ 'width' : w, 'left' : bb.x1, - 'margin-left' : -ro.x + // 'margin-left' : -ro.x }); this.canvas.css({ @@ -175,14 +211,14 @@ Y.subclass('Layer', { this.layerHeight = h; var bb = this.boundingBox.resize(this.layerWidth, h) - , ro = bb.relOrigin + // , ro = bb.relOrigin , nb = this.negBleed , ch = this.canvasHeight = Math.ceil(h + nb.y + this.posBleed.y); // HTMLCanvas.height is a long this.layer.css({ 'height' : h, 'top' : bb.y1, - 'margin-top' : -ro.y + // 'margin-top' : -ro.y }); this.canvas.css({ @@ -256,7 +292,7 @@ Y.subclass('Layer', { css : makeDelegate('css'), /** Position relative to document. */ - // offset : makeDelegate('offset'), + offset : makeDelegate('offset'), @@ -464,6 +500,12 @@ Y.subclass('Layer', { return this; }, + animate : function animate(props, options) { + + }, + + /// Debuggging /// + // for debugging point : function point(x,y, color){ var ctx = this.ctx; @@ -480,16 +522,20 @@ Y.subclass('Layer', { return this; }, - animate : function animate(props, options) { + title : function title(val){ + if (val === undefined) + return this.layer.attr('title'); + this.layer.attr('title', val); + return this; }, /// Misc /// toString : function toString(){ - var pos = (this.layer ? this.position() : {y:NaN, x:NaN}); - return this.className+'['+pos.x+','+pos.y+']( children='+this.children.size()+' )'; + var pos = (this.layer ? this.position() : {top:NaN, left:NaN}); + return this.className+'['+pos.left+','+pos.top+']( children='+this.children.size()+' )'; } }); diff --git a/src/ezl/loc/boundingbox.cjs b/src/ezl/loc/boundingbox.cjs index 3145a81..5de767d 100644 --- a/src/ezl/loc/boundingbox.cjs +++ b/src/ezl/loc/boundingbox.cjs @@ -27,15 +27,15 @@ Rect.subclass('BoundingBox', { * Use relocate() to change the position by moving the origin. */ set originX(v){ this._origin.x = v; return v; }, - get originX(){ return this._origin.absolute(this.width,this.height, this.x1,this.x2).x; }, + get originX(){ return this._origin.absolute(this.width,this.height, this.x1,this.y1).x; }, set originY(v){ this._origin.y = v; return v; }, - get originY(){ return this._origin.absolute(this.width,this.height, this.x1,this.x2).y; }, + get originY(){ return this._origin.absolute(this.width,this.height, this.x1,this.y1).y; }, /** * Accessor for the realized numeric origin. */ - get absOrigin() { return this._origin.absolute(this.width,this.height, this.x1,this.x2); }, + get absOrigin() { return this._origin.absolute(this.width,this.height, this.x1,this.y1); }, get relOrigin() { return this._origin.absolute(this.width,this.height); }, get origin(){ return this._origin; }, @@ -44,7 +44,7 @@ Rect.subclass('BoundingBox', { var _x1 = this[X1], _y1 = this[Y1] , _x2 = this[X2], _y2 = this[Y2] - , abs = this._origin.absolute(_x1-_x1, _y2-_y1, _x1,_y1) + , abs = this._origin.absolute(_x2-_x1, _y2-_y1, _x1,_y1) , dx1 = _x1 - abs.x, dy1 = _y1 - abs.y , dx2 = _x2 - abs.x, dy2 = _y2 - abs.y @@ -54,6 +54,11 @@ Rect.subclass('BoundingBox', { return this.set4(x1,y1, x2,y2); }, + relocated : function relocated(x,y){ + var bb = this.clone(); + return bb.relocate(x,y); + }, + resize : function resize(w,h){ var x1 = this[X1], y1 = this[Y1] , x2 = this[X2], y2 = this[Y2] @@ -63,24 +68,29 @@ Rect.subclass('BoundingBox', { , xp = o.xPercentage, yp = o.yPercentage ; if ( xp !== null ) { - diff = w - wOld; + // diff = w - wOld; abs = x1 + xp*wOld; - x1 = abs - xp*diff; - x2 = abs + (1-xp)*diff; + x1 = abs - xp*w; + x2 = abs + (1-xp)*w; } else x2 = x1 + w; if ( yp !== null ) { - diff = h - hOld; + // diff = h - hOld; abs = y1 + yp*hOld; - y1 = abs - yp*diff; - y2 = abs + (1-yp)*diff; + y1 = abs - yp*h; + y2 = abs + (1-yp)*h; } else y2 = y1 + h; return this.set4(x1,y1, x2,y2); }, + resized : function resized(w,h){ + var bb = this.clone(); + return bb.resize(w,h); + }, + clone : function clone(){ var o = this._origin; return new BoundingBox(this[X1],this[Y1], this[X2],this[Y2], o[X1], o[Y1]); diff --git a/src/ezl/math/vec.cjs b/src/ezl/math/vec.cjs index 19cf627..1bc3c08 100644 --- a/src/ezl/math/vec.cjs +++ b/src/ezl/math/vec.cjs @@ -91,6 +91,10 @@ new Y.Class('Vec', [], { return this.setXY(x*cos - y*sin, x*sin + y*cos); }, + clone : function clone(){ + return new this.__class__(this[_X],this[_Y]); + }, + toString : function toString(){ var p = 2, x = this[_X], y = this[_Y]; x = ((x % 1 !== 0) ? x.toFixed(p) : x); diff --git a/src/ezl/shape/circle.cjs b/src/ezl/shape/circle.cjs index 00acd8b..e02eab7 100644 --- a/src/ezl/shape/circle.cjs +++ b/src/ezl/shape/circle.cjs @@ -6,6 +6,8 @@ Circle = exports['Circle'] = Shape.subclass('Circle', { _cssClasses : 'ezl layer shape circle', + originX : '50%', + originY : '50%', init : function initCircle(radius){ Shape.init.call(this); @@ -19,12 +21,13 @@ Shape.subclass('Circle', { var d = r * 2; this.dirty = true; this._radius = r; - this.width(d).height(d); + this.size(d,d); return this; }, drawShape : function drawShape(ctx){ - ctx.arc(0,0, this._radius, 0, Math.PI*2, false); + var r = this._radius; + ctx.arc(r,r, r, 0, Math.PI*2, false); ctx.fill(); ctx.stroke(); } diff --git a/src/ezl/shape/rect.cjs b/src/ezl/shape/rect.cjs index 563a441..845688d 100644 --- a/src/ezl/shape/rect.cjs +++ b/src/ezl/shape/rect.cjs @@ -5,12 +5,12 @@ Rect = exports['Rect'] = Shape.subclass('Rect', { _cssClasses : 'ezl layer shape rect', + originX : 0, + originY : 0, init : function initRect(w,h){ Shape.init.call(this); - this.origin(0,0) - .width(w) - .height(h); + this.size(w,h); }, drawShape : function drawShape(ctx){ diff --git a/src/tanks/config.cjs b/src/tanks/config.cjs index dc05997..9178463 100644 --- a/src/tanks/config.cjs +++ b/src/tanks/config.cjs @@ -5,7 +5,7 @@ var Y = require('Y').Y exports['defaults'] = { ui : { showGridCoords : false, - showCountdown : true + showCountdown : false }, pathing : { overlayAIPaths : false, diff --git a/src/tanks/game.cjs b/src/tanks/game.cjs index b4a260f..d21ef32 100644 --- a/src/tanks/game.cjs +++ b/src/tanks/game.cjs @@ -119,8 +119,8 @@ Y.subclass('Game', { // Center unit in square var sqX = (col || 0) * REF_SIZE , sqY = (row || 0) * REF_SIZE - , x = sqX + (REF_SIZE-unit.width) /2 - , y = sqY + (REF_SIZE-unit.height)/2 ; + , x = sqX + REF_SIZE/2 + , y = sqY + REF_SIZE/2 ; unit.position(x,y); unit.render( this.level ); diff --git a/src/tanks/map/pathmap.cjs b/src/tanks/map/pathmap.cjs index f80bda9..c107629 100644 --- a/src/tanks/map/pathmap.cjs +++ b/src/tanks/map/pathmap.cjs @@ -1,6 +1,8 @@ // -*- mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*- var Y = require('Y').Y -, Vec = require('ezl/math/vec').Vec +, math = require('ezl/math') +, Vec = math.Vec +, Line = math.Line , QuadTree = require('ezl/util/tree/quadtree').QuadTree , Bullet = require('tanks/thing/bullet').Bullet , astar = require('ezl/util/astar') @@ -74,14 +76,16 @@ QuadTree.subclass('PathMap', { bb = bb || agent.boundingBox; var blockers, blocker, msg , side = null - - , bw = bb.width, bh = bb.height + , tobb = bb.relocated(to.x,to.y) + , x1 = tobb.x1, y1 = tobb.y1 + , x2 = tobb.x2, y2 = tobb.y2 , ro = bb.relOrigin - , offX = ro.x, offY = ro.y + , bw = bb.width, bh = bb.height + , offX = bw - ro.x, offY = bh = ro.y - , x1 = to.x+offX, y1 = to.y+offY - , x2 = x1+bw, y2 = y1+bh + // , x1 = to.x+offX, y1 = to.y+offY + // , x2 = x1+bw, y2 = y1+bh ; blockers = this.get(x1,y1, x2,y2).remove(agent).end(); @@ -104,22 +108,22 @@ QuadTree.subclass('PathMap', { if (bb.x2 <= B.x1 && x2 >= B.x1) { msg += 'left'; side = new Line(B.x1,B.y1, B.x1,B.y2); - to = trj.pointAtX(B.x1-bw-offX-1); + to = trj.pointAtX(B.x1-offX-1); } else if (bb.x1 >= B.x2 && x1 <= B.x2) { msg += 'right'; side = new Line(B.x2,B.y1, B.x2,B.y2); - to = trj.pointAtX(B.x2-offX+1); + to = trj.pointAtX(B.x2+ro.x+1); } else if (bb.y2 <= B.y1 && y2 >= B.y1) { msg += 'top'; side = new Line(B.x1,B.y1, B.x2,B.y1); - to = trj.pointAtY(B.y1-bh-offY-1); + to = trj.pointAtY(B.y1-offY-1); } else if (bb.y1 >= B.y2 && y1 <= B.y2) { msg += 'bottom'; side = new Line(B.x1,B.y2, B.x2,B.y2); - to = trj.pointAtY(B.y2-offY+1); + to = trj.pointAtY(B.y2+ro.y+1); } msg += ' side'; diff --git a/src/tanks/map/trajectory.cjs b/src/tanks/map/trajectory.cjs index f406acc..edace1b 100644 --- a/src/tanks/map/trajectory.cjs +++ b/src/tanks/map/trajectory.cjs @@ -3,6 +3,7 @@ var Y = require('Y').Y , Vec = math.Vec , Line = math.Line , Rect = math.Rect +, BoundingBox = require('ezl/loc').BoundingBox , Thing = require('tanks/thing/thing').Thing , @@ -172,8 +173,7 @@ Line.subclass('Trajectory', { to = this.stepTo(t, bb); if (this.halt) break; - // FIXME: bb.add? - bb = new Rect(to.x,to.y, to.x+bw,to.y+bh); + bb = new BoundingBox(to.x,to.y, to.x+bw,to.y+bh); } while (dt > 0); diff --git a/src/tanks/thing/player.cjs b/src/tanks/thing/player.cjs index 64f9125..ab5215a 100644 --- a/src/tanks/thing/player.cjs +++ b/src/tanks/thing/player.cjs @@ -90,7 +90,7 @@ Tank.subclass('PlayerTank', { var toLoc = this.loc.moveByDir(dir, (this.stats.move * SQUARETH)) , x = toLoc.x, y = toLoc.y - , bb = this.boundingBox.reloacte(x,y) + , bb = this.boundingBox.relocate(x,y) , blockers = this.game.pathmap.get(bb.x1,bb.y1, bb.x2,bb.y2).remove(this) ; diff --git a/src/tanks/thing/tank.cjs b/src/tanks/thing/tank.cjs index 4c142f1..1d81dbe 100644 --- a/src/tanks/thing/tank.cjs +++ b/src/tanks/thing/tank.cjs @@ -25,7 +25,6 @@ Thing.subclass('Tank', function(Tank){ turretColor : '#1C625B', barrelColor : '#D43B24', - // Bounding box size width : REF_SIZE*0.55, height : REF_SIZE*0.55, @@ -297,7 +296,7 @@ Thing.subclass('Tank', function(Tank){ function moveByAngle(theta, targetX,targetY){ var abs = Math.abs , bb = this.boundingBox, w2 = bb.width/2, h2 = bb.height/2 - , loc = this.loc, mid = bb.midpoint() + , loc = this.loc, mid = bb.midpoint , to = loc.moveByAngle(theta, this.stats.move * SQUARETH) ; @@ -308,7 +307,7 @@ Thing.subclass('Tank', function(Tank){ if ( targetY !== undefined && abs(loc.y-to.y) > abs(loc.y-targetY) ) to.setXY(to.x, targetY); - var nbb = bb.add(to.x,to.y) + var nbb = bb.relocated(to.x,to.y) , blockers = this.game.pathmap.get(nbb.x1,nbb.y1, nbb.x2,nbb.y2).remove(this) ; @@ -353,29 +352,6 @@ Thing.subclass('Tank', function(Tank){ , path = this.lastPath = pm.path(start, end, this.id) , to = this.currentMove = path.shift() ; - - // VVV We only really need this code if we're going to recalculate before we reach the currentMove - - // we may need to move closer to start if we occupy multiple grid-squares - // var tosq = pm.vec2Square(to), manhattan = Vec.manhattan - // , bb = this.boundingBox - // , tl = pm.vec2Square(bb.x1,bb.y1), tr = pm.vec2Square(bb.x2,bb.y1) - // , bl = pm.vec2Square(bb.x1,bb.y2), br = pm.vec2Square(bb.x2,bb.y2) - // , straddles = [tl, tr, bl, br] - // ; - // - // - // if ( !tl.equals(br) ) { - // tl.to = pm.vec2Square(bb.x1,bb.y1); tr.to = pm.vec2Square(mid.x,bb.y1); - // bl.to = pm.vec2Square(bb.x1,mid.y); br.to = pm.vec2Square(mid.x,mid.y); - // straddles.sort(function(a,b){ - // return Y.op.cmp(manhattan(a,tosq), manhattan(b,tosq)); - // }); - // to = pm.square2Vec(straddles[0].to).add(pm.gridSquareMidPt); - // path.unshift(to); - // } - - // console.log('start:', start, 'straddles:', straddles.map(pm.square2Vec.bind(pm)), 'end:', end, 'next:', to); }; @@ -386,17 +362,18 @@ Thing.subclass('Tank', function(Tank){ this['getTurretLoc'] = function getTurretLoc(){ - var loc = this.loc, mid = this.midpoint + var WIGGLE = 8 + , loc = this.loc, mid = this.midpoint , barrel = this.barrel , theta = barrel.transform.rotate , sin = Math.sin(theta), cos = Math.cos(theta) - , len = barrel.boundingBox.width + , len = barrel.boundingBox.width + WIGGLE , x = mid.x + len*cos , y = mid.y + len*sin ; - // console.log('getTurretLoc()', 'loc:', loc, 'bbb.(x2,y2):', [bbb.x2,bbb.y2], '(x,y):', [x,y]); + // console.log('getTurretLoc()', 'loc:', loc, '(x,y):', [x,y]); return new Vec(x,y); }; @@ -423,6 +400,7 @@ Thing.subclass('Tank', function(Tank){ this.shape = new Rect(w,h) + .origin(this.originX,this.originY) .position(this.loc.x, this.loc.y) .fill(this.bodyColor) .appendTo( parent ) ; diff --git a/src/tanks/thing/thing.cjs b/src/tanks/thing/thing.cjs index 4c5eeb5..8c29cf9 100644 --- a/src/tanks/thing/thing.cjs +++ b/src/tanks/thing/thing.cjs @@ -13,15 +13,6 @@ Thing = exports['Thing'] = new evt.Class('Thing', { - init : function init(align){ - this.id = Thing.THING_ID++; - this.align = align || 0; - this.boundingBox = new BoundingBox(0,0, this.width,this.height, this.originX,this.originY); - - this.fillStats(); - this.createCooldowns(); - }, - // Attributes stats: { hp : 1, // health @@ -59,24 +50,28 @@ new evt.Class('Thing', { width : REF_SIZE, height : REF_SIZE, - set : Y.op.set.methodize(), - attr : Y.op.attr.methodize(), - - dealDamage : function dealDamage(d, source){ - this.stats.hp -= d; - - if (this.stats.hp <= 0) - this.destroy(); + init : function init(align){ + this.id = Thing.THING_ID++; + this.align = align || 0; + this.boundingBox = new BoundingBox(0,0, this.width,this.height, this.originX,this.originY); - return this; + this.fillStats(); + this.createCooldowns(); }, + set : Y.op.set.methodize(), + attr : Y.op.attr.methodize(), + + position : function position(x,y){ - var bb = this.boundingBox.relocate(x,y); - this.loc = bb.absOrigin; + if (x === undefined && y === undefined) + return this.loc; + + var bb = this.boundingBox.relocate(x,y) + , loc = this.loc = bb.absOrigin; this.midpoint = bb.midpoint; - if (this.shape) this.shape.position(x,y); + if (this.shape) this.shape.position(loc.x,loc.y); return this; }, @@ -114,6 +109,16 @@ new evt.Class('Thing', { return this; }, + dealDamage : function dealDamage(d, source){ + this.stats.hp -= d; + + if (this.stats.hp <= 0) + this.destroy(); + + return this; + }, + + /** * Calculates the location of the bullet-spawning point on this Thing. */ diff --git a/src/tanks/ui/grid.cjs b/src/tanks/ui/grid.cjs index 5183abf..f3fb59c 100644 --- a/src/tanks/ui/grid.cjs +++ b/src/tanks/ui/grid.cjs @@ -13,11 +13,11 @@ Rect.subclass('Grid', { createCanvasGrid : true, - init : function init(cols,rows, size){ + init : function init(cols,rows, side){ this.cols = cols; this.rows = rows; - this.size = size; - Rect.init.call(this, cols*size, rows*size); + this.side = side; + Rect.init.call(this, cols*side, rows*side); }, drawShape : function drawShape(ctx){ @@ -25,7 +25,7 @@ Rect.subclass('Grid', { // if (this.canvas) this.canvas.remove(); var cols = this.cols, rows = this.rows - , size = this.size + , side = this.side , w = this.canvasWidth , h = this.canvasHeight ; @@ -36,7 +36,7 @@ Rect.subclass('Grid', { var row = $('').appendTo(tbody); Y(0, cols).forEach(function(x){ $(''+x+','+y+'') - .width(size).height(size) + .width(side).height(side) .appendTo(row); }, this); }, this); @@ -55,12 +55,12 @@ Rect.subclass('Grid', { ctx.lineWidth = this.lineWidth; ctx.strokeStyle = this.strokeStyle; - for (var row=0, y=0; row<=rows; y = (++row) * size){ + for (var row=0, y=0; row<=rows; y = (++row) * side){ ctx.moveTo(0, y); ctx.lineTo(w, y); } - for (var col=0, x=0; col<=cols; x = (++col) * size){ + for (var col=0, x=0; col<=cols; x = (++col) * side){ ctx.moveTo(x, 0); ctx.lineTo(x, h); } diff --git a/src/tanks/ui/main.cjs b/src/tanks/ui/main.cjs index 134e339..1e6f086 100644 --- a/src/tanks/ui/main.cjs +++ b/src/tanks/ui/main.cjs @@ -73,6 +73,9 @@ function main(){ setupGame(); setupUI(); + + // $('#welcome').hide(); + // $('#overlay').hide(); } function gameExists(){ return !!tanks.currentGame; } diff --git a/www/test/shapes/test-shapes.js b/www/test/shapes/test-shapes.js index 0fa526b..261302e 100644 --- a/www/test/shapes/test-shapes.js +++ b/www/test/shapes/test-shapes.js @@ -2,7 +2,10 @@ REF_SIZE = 50; Y = require('Y').Y; ezl = require('ezl'); +math = require('ezl/math'); +loc = require('ezl/loc'); shape = require('ezl/shape'); + Grid = require('tanks/ui/grid').Grid; @@ -19,7 +22,6 @@ $(function(){ grid.createTableGrid = false; grid.lineWidth = 1.0; grid.strokeStyle = '#E0E0E0'; //'#EEEEEE'; // - grid.draw(); // Draw axes shape.Line // X Axis @@ -35,6 +37,17 @@ $(function(){ .width(w).height(h) .appendTo(grid); + R = shape.Rect + .fromPoints(100,100, 150,150) + .fill('#E73075') + .appendTo(plot); + R.title(R.boundingBox+''); + C = new shape.Circle(25) + .position(150,150) + .fill('#2E62C9') + .appendTo(plot); + C.title(C.boundingBox+''); + grid.draw(); }); -- 1.7.0.4