From e42ebae867dc441fbeacf8d44291c50ac0a4e5c4 Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Wed, 16 Jun 2010 22:56:48 +0000 Subject: [PATCH] It's not drawing the real tile/art assets yet, but handles enough of the model correctly to draw boxes for each base/object tile. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@928 ed5b42cb-e716-0410-a449-f6a68f950b19 --- etc/libs-incl.xml | 1 + .../miso/client/BaseTileIsoSprite.as | 22 ++++ .../miso/client/MisoMetricsTransformation.as | 46 +++++++ .../threerings/miso/client/MisoScenePanel.as | 118 ++++++++++++++++++ .../miso/client/ObjectTileIsoSprite.as | 20 +++ .../threerings/miso/data/MisoSceneModel.as | 6 +- .../miso/data/SparseMisoSceneModel.as | 7 +- .../threerings/miso/util/MisoSceneMetrics.as | 107 ++++++++++++++++ src/as/com/threerings/miso/util/ObjectSet.as | 2 +- 9 files changed, 322 insertions(+), 7 deletions(-) create mode 100644 src/as/com/threerings/miso/client/BaseTileIsoSprite.as create mode 100644 src/as/com/threerings/miso/client/MisoMetricsTransformation.as create mode 100644 src/as/com/threerings/miso/client/MisoScenePanel.as create mode 100644 src/as/com/threerings/miso/client/ObjectTileIsoSprite.as create mode 100644 src/as/com/threerings/miso/util/MisoSceneMetrics.as diff --git a/etc/libs-incl.xml b/etc/libs-incl.xml index 1229a2c9..926b2e0a 100644 --- a/etc/libs-incl.xml +++ b/etc/libs-incl.xml @@ -36,5 +36,6 @@ + diff --git a/src/as/com/threerings/miso/client/BaseTileIsoSprite.as b/src/as/com/threerings/miso/client/BaseTileIsoSprite.as new file mode 100644 index 00000000..1a078b51 --- /dev/null +++ b/src/as/com/threerings/miso/client/BaseTileIsoSprite.as @@ -0,0 +1,22 @@ +package com.threerings.miso.client { + +import as3isolib.display.primitive.IsoBox; +import as3isolib.graphics.SolidColorFill; + +public class BaseTileIsoSprite extends IsoBox +{ + public function BaseTileIsoSprite (x :int, y :int, tileId :int) + { + width = 1; + height = VERT_OFFSET; + length = 1; + + moveTo(x, y, -VERT_OFFSET); + + // TEMP + fill = new SolidColorFill(tileId * 1000, 1.0); + } + + protected static const VERT_OFFSET :Number = 0.01; +} +} diff --git a/src/as/com/threerings/miso/client/MisoMetricsTransformation.as b/src/as/com/threerings/miso/client/MisoMetricsTransformation.as new file mode 100644 index 00000000..10130ea6 --- /dev/null +++ b/src/as/com/threerings/miso/client/MisoMetricsTransformation.as @@ -0,0 +1,46 @@ +package com.threerings.miso.client { + +import as3isolib.geom.Pt; +import as3isolib.geom.transformations.IAxonometricTransformation; + +import com.threerings.miso.util.MisoSceneMetrics; + +public class MisoMetricsTransformation implements IAxonometricTransformation +{ + public function MisoMetricsTransformation (metrics :MisoSceneMetrics, zFact :Number) + { + _metrics = metrics; + _zFact = zFact; + } + + public function screenToSpace (screenPt :Pt) :Pt + { + var tpos :Pt = new Pt(); + + // determine the upper-left of the quadrant that contains our point + var zx :int = int(Math.floor(screenPt.x / _metrics.tilewid)); + var zy :int = int(Math.floor(screenPt.y / _metrics.tilehei)); + + // these are the tile coordinates + tpos.x = zy + zx; + tpos.y = zy - zx; + tpos.z = 0; + + return tpos; + } + + public function spaceToScreen (spacePt :Pt) :Pt + { + var spos :Pt = new Pt(); + spos.x = (spacePt.x - spacePt.y) * _metrics.tilehwid; + spos.y = (spacePt.x + spacePt.y) * _metrics.tilehhei - spacePt.z * _zFact; + spos.z = 0; + return spos; + } + + protected var _metrics :MisoSceneMetrics; + + /** Handles any vertical transformations. */ + protected var _zFact :Number; +} +} diff --git a/src/as/com/threerings/miso/client/MisoScenePanel.as b/src/as/com/threerings/miso/client/MisoScenePanel.as new file mode 100644 index 00000000..67a18800 --- /dev/null +++ b/src/as/com/threerings/miso/client/MisoScenePanel.as @@ -0,0 +1,118 @@ +package com.threerings.miso.client { + +import flash.utils.getTimer; + +import flash.display.Sprite; + +import flash.geom.Point; +import flash.geom.Rectangle; + +import flash.events.MouseEvent; + +import com.threerings.crowd.client.PlaceView; +import com.threerings.crowd.data.PlaceObject; +import com.threerings.miso.client.MisoMetricsTransformation; +import com.threerings.miso.data.MisoSceneModel; +import com.threerings.miso.data.ObjectInfo; +import com.threerings.miso.util.MisoContext; +import com.threerings.miso.util.ObjectSet; +import com.threerings.miso.util.MisoSceneMetrics; + +import as3isolib.display.primitive.IsoBox; +import as3isolib.geom.Pt; +import as3isolib.geom.IsoMath; +import as3isolib.display.scene.IsoGrid; +import as3isolib.display.scene.IsoScene; +import as3isolib.display.IsoView; + +public class MisoScenePanel extends Sprite + implements PlaceView +{ + public function MisoScenePanel (ctx :MisoContext, metrics :MisoSceneMetrics) + { + // Excitingly, we get to override this globally for as3isolib... + IsoMath.transformationObject = new MisoMetricsTransformation(metrics, + metrics.tilehei * 3 / 4); + + _isoView = new IsoView(); + _isoView.setSize(DEF_WIDTH, DEF_HEIGHT); + + _isoView.addEventListener(MouseEvent.CLICK, onClick); + + addChild(_isoView); + } + + public function setSize (width :int, height :int) :void + { + _isoView.setSize(width, height); + } + + public function onClick (event :MouseEvent) :void + { + var viewPt :Point = _isoView.globalToLocal(new Point(event.stageX, event.stageY)); + _isoView.centerOnPt(new Pt(viewPt.x - _isoView.width / 2 + _isoView.currentX, + viewPt.y - _isoView.height / 2 + _isoView.currentY), false); + } + + public function setSceneModel (model :MisoSceneModel) :void + { + _model = model; + refreshScene(); + } + + public function willEnterPlace (plobj :PlaceObject) :void + { + } + + public function didLeavePlace (plobj :PlaceObject) :void + { + } + + protected function refreshScene () :void + { + // Clear it out... + _isoView.removeAllScenes(); + + var scene :IsoScene = new IsoScene(); + + var time :int = getTimer(); + var baseArr :Array = []; + + for (var si :int = -10; si < 3; si++) { + for (var sj :int = -8; sj < 4; sj++) { + var baseScene :IsoScene = new IsoScene(); + for (var ii :int = 10*si; ii < 10*si + 10; ii++) { + for (var jj :int = 10*sj; jj < 10*sj + 10; jj++) { + baseScene.addChild( + new BaseTileIsoSprite(ii, jj, _model.getBaseTileId(ii, jj))); + } + } + baseScene.render(); + _isoView.addScene(baseScene); + } + } + + var set :ObjectSet = new ObjectSet(); + _model.getObjects(new Rectangle(-100, -100, 200, 200), set); + time = getTimer(); + for (ii = 0; ii < set.size(); ii++) { + var objInfo :ObjectInfo = set.get(ii); + if (objInfo.priority == 0) { + scene.addChild(new ObjectTileIsoSprite(objInfo.x, objInfo.y, objInfo.tileId)); + } + } + + time = getTimer(); + scene.render(); + + _isoView.addScene(scene); + } + + protected var _model :MisoSceneModel; + + protected var _isoView :IsoView; + + protected const DEF_WIDTH :int = 985; + protected const DEF_HEIGHT :int = 560; +} +} diff --git a/src/as/com/threerings/miso/client/ObjectTileIsoSprite.as b/src/as/com/threerings/miso/client/ObjectTileIsoSprite.as new file mode 100644 index 00000000..5820d31e --- /dev/null +++ b/src/as/com/threerings/miso/client/ObjectTileIsoSprite.as @@ -0,0 +1,20 @@ +package com.threerings.miso.client { + +import as3isolib.display.primitive.IsoBox; +import as3isolib.graphics.SolidColorFill; + +public class ObjectTileIsoSprite extends IsoBox +{ + public function ObjectTileIsoSprite (x :int, y :int, tileId :int) + { + width = 1; + height = 1; + length = 1; + + moveTo(x, y, 0); + + // TEMP + fill = new SolidColorFill(tileId * 1000, 1.0); + } +} +} diff --git a/src/as/com/threerings/miso/data/MisoSceneModel.as b/src/as/com/threerings/miso/data/MisoSceneModel.as index 54879f26..aa4e0998 100644 --- a/src/as/com/threerings/miso/data/MisoSceneModel.as +++ b/src/as/com/threerings/miso/data/MisoSceneModel.as @@ -49,17 +49,17 @@ public /*abstract*/ class MisoSceneModel extends SimpleStreamableObject * specified coordinates. -1 will be returned if there is * no tile at the specified coordinate. */ - public function getBaseTileId (arg1 :int, arg2 :int) :int + public function getBaseTileId (x :int, y :int) :int { throw new Error("abstract"); } - public function setBaseTile (arg1 :int, arg2 :int, arg3 :int) :Boolean + public function setBaseTile (x :int, y :int, tileId :int) :Boolean { throw new Error("abstract"); } - public function setDefaultBaseTileSet (arg1 :int) :void + public function setDefaultBaseTileSet (tileSetId :int) :void { // nothing doing } diff --git a/src/as/com/threerings/miso/data/SparseMisoSceneModel.as b/src/as/com/threerings/miso/data/SparseMisoSceneModel.as index 400d9add..1c9feade 100644 --- a/src/as/com/threerings/miso/data/SparseMisoSceneModel.as +++ b/src/as/com/threerings/miso/data/SparseMisoSceneModel.as @@ -29,6 +29,7 @@ import com.threerings.io.ObjectOutputStream; import com.threerings.util.ArrayIterator; import com.threerings.util.ClassUtil; +import com.threerings.util.Integer; import com.threerings.util.Iterator; import com.threerings.util.Joiner; import com.threerings.util.MathUtil; @@ -221,17 +222,17 @@ public class SparseMisoSceneModel extends MisoSceneModel /** * Returns the key for the specified section. */ - protected function key (x :int, y :int) :int + protected function key (x :int, y :int) :Integer { var sx :int = MathUtil.floorDiv(x, swidth); var sy :int = MathUtil.floorDiv(y, sheight); - return (sx << 16) | (sy & 0xFFFF); + return Integer.valueOf((sx << 16) | (sy & 0xFFFF)); } /** Returns the section for the specified tile coordinate. */ protected function getSection (x :int, y :int, create :Boolean) :SparseMisoSceneModel_Section { - var key :int = key(x, y); + var key :Integer = key(x, y); var sect :SparseMisoSceneModel_Section = _sections.get(key); if (sect == null && create) { var sx :int = MathUtil.floorDiv(x, swidth)*swidth; diff --git a/src/as/com/threerings/miso/util/MisoSceneMetrics.as b/src/as/com/threerings/miso/util/MisoSceneMetrics.as new file mode 100644 index 00000000..fcc32ec0 --- /dev/null +++ b/src/as/com/threerings/miso/util/MisoSceneMetrics.as @@ -0,0 +1,107 @@ +// +// Nenya library - tools for developing networked games +// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/nenya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.miso.util { + +public class MisoSceneMetrics +{ + /** Tile dimensions and half-dimensions in the view. */ + public var tilewid :int; + public var tilehei :int; + public var tilehwid :int; + public var tilehhei :int; + + /** Fine coordinate dimensions. */ + public var finehwid :int; + public var finehhei :int; + + /** Number of fine coordinates on each axis within a tile. */ + public var finegran :int; + + /** Dimensions of our scene blocks in tile count. */ + public var blockwid :int = 4; + public var blockhei :int = 4; + + /** The length of a tile edge in pixels. */ + public var tilelen :Number; + + /** The slope of the x- and y-axis lines. */ + public var slopeX :Number; + public var slopeY :Number; + + /** The length between fine coordinates in pixels. */ + public var finelen :Number; + + /** The y-intercept of the x-axis line within a tile. */ + public var fineBX :Number; + + /** The slope of the x- and y-axis lines within a tile. */ + public var fineSlopeX :Number; + public var fineSlopeY :Number; + + /** + * Constructs scene metrics by directly specifying the desired config + * parameters. + * + * @param tilewid the width in pixels of the tiles. + * @param tilehei the height in pixels of the tiles. + * @param finegran the number of sub-tile divisions to use for fine + * coordinates. + */ + public function MisoSceneMetrics (tilewid :int = DEF_TILE_WIDTH, tilehei :int = DEF_TILE_HEIGHT, + finegran :int = DEF_FINE_GRAN) + { + // keep track of this stuff + this.tilewid = tilewid; + this.tilehei = tilehei; + this.finegran = finegran; + + // halve the dimensions + tilehwid = (tilewid / 2); + tilehhei = (tilehei / 2); + + // calculate the length of a tile edge in pixels + tilelen = Math.sqrt( + (tilehwid * tilehwid) + (tilehhei * tilehhei)); + + // calculate the slope of the x- and y-axis lines + slopeX = Number(tilehei) / Number(tilewid); + slopeY = -slopeX; + + // calculate the edge length separating each fine coordinate + finelen = tilelen / finegran; + + // calculate the fine-coordinate x-axis line + fineSlopeX = Number(tilehei) / Number(tilewid); + fineBX = -(fineSlopeX * tilehwid); + fineSlopeY = -fineSlopeX; + + // calculate the fine coordinate dimensions + finehwid = int(Number(tilehwid) / Number(finegran)); + finehhei = int(Number(tilehhei) / Number(finegran)); + } + + /** Default scene view parameters. */ + protected static const DEF_TILE_WIDTH :int = 64; + protected static const DEF_TILE_HEIGHT :int = 48; + protected static const DEF_FINE_GRAN :int = 4; + +} +} + diff --git a/src/as/com/threerings/miso/util/ObjectSet.as b/src/as/com/threerings/miso/util/ObjectSet.as index f6faeac3..35fc2629 100644 --- a/src/as/com/threerings/miso/util/ObjectSet.as +++ b/src/as/com/threerings/miso/util/ObjectSet.as @@ -50,7 +50,7 @@ public class ObjectSet // otherwise insert it ipos = -(ipos+1); - _objs = _objs.splice(ipos, 0, info); + _objs.splice(ipos, 0, info); return true; }