diff --git a/src/as/com/threerings/stage/client/PortalIsoSprite.as b/src/as/com/threerings/stage/client/PortalIsoSprite.as new file mode 100644 index 00000000..8b270ca3 --- /dev/null +++ b/src/as/com/threerings/stage/client/PortalIsoSprite.as @@ -0,0 +1,72 @@ +// +// Vilya library - tools for developing networked games +// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/vilya/ +// +// 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.stage.client { + +import flash.display.Bitmap; +import flash.display.BitmapData; +import flash.display.DisplayObject; + +import flash.geom.Point; + +import as3isolib.display.IsoSprite; + +import com.threerings.miso.client.PriorityIsoDisplayObject; + +public class PortalIsoSprite extends IsoSprite + implements PriorityIsoDisplayObject +{ + public function PortalIsoSprite (img :DisplayObject, x :int, y :int) + { + sprites = [img]; + setSize(1, 1, 1); + moveTo(x, y, 0); + setRaised(false); + } + + public function getPriority () :int + { + return 0; + } + + public function hitTest (stageX :int, stageY :int) :Boolean + { + if (sprites == null || sprites.length == 0) { + return false; + } + + if (sprites[0] is Bitmap) { + if (!sprites[0].hitTestPoint(stageX, stageY, true)) { + // Doesn't even hit the bounds... + return false; + } + // Check the actual pixels... + var pt :Point = sprites[0].globalToLocal(new Point(stageX, stageY)); + return Bitmap(sprites[0]).bitmapData.hitTest(new Point(0, 0), 0, pt); + } else { + return sprites[0].hitTestPoint(stageX, stageY, true); + } + } + + public function setRaised (raised :Boolean) :void + { + sprites[0].alpha = (raised ? 1.0 : 0.5); + } +} +} \ No newline at end of file diff --git a/src/as/com/threerings/stage/client/StageSceneBlock.as b/src/as/com/threerings/stage/client/StageSceneBlock.as index a68f9dc3..29040411 100644 --- a/src/as/com/threerings/stage/client/StageSceneBlock.as +++ b/src/as/com/threerings/stage/client/StageSceneBlock.as @@ -61,7 +61,7 @@ public class StageSceneBlock extends SceneBlock var portal :Portal = Portal(iter.next()); var x :int = MisoUtil.fullToTile(StageLocation(portal.loc).x); var y :int = MisoUtil.fullToTile(StageLocation(portal.loc).y); - if (x < bx || x > bx + BLOCK_SIZE || y < by || y > by + BLOCK_SIZE) { + if (x < bx || x >= bx + BLOCK_SIZE || y < by || y >= by + BLOCK_SIZE) { continue; } @@ -69,15 +69,11 @@ public class StageSceneBlock extends SceneBlock var fineY :int = MisoUtil.fullToFine(StageLocation(portal.loc).y); // Grab the portal image, and center it. - var portalSprite :IsoSprite = new IsoSprite(); var img :DisplayObject = StageScenePanel(panel).getPortalImage(StageLocation(portal.loc).orient); img.x = -img.width/2 + int(_metrics.finehwid * (fineX - fineY)); img.y = -img.height/2 + int(_metrics.finehhei * (fineX + fineY)); - - portalSprite.sprites = [img]; - portalSprite.setSize(1, 1, 1); - portalSprite.moveTo(x, y, 0); + var portalSprite :PortalIsoSprite = new PortalIsoSprite(img, x, y); if (_portSprites == null) { _portSprites = []; diff --git a/src/as/com/threerings/stage/client/StageScenePanel.as b/src/as/com/threerings/stage/client/StageScenePanel.as index 4d25a3de..25156b74 100644 --- a/src/as/com/threerings/stage/client/StageScenePanel.as +++ b/src/as/com/threerings/stage/client/StageScenePanel.as @@ -30,13 +30,16 @@ import com.threerings.whirled.spot.data.Portal; import com.threerings.media.tile.Colorizer; import com.threerings.media.tile.Tile; import com.threerings.miso.client.MisoScenePanel; +import com.threerings.miso.client.PriorityIsoDisplayObject; import com.threerings.miso.client.SceneBlock; +import com.threerings.miso.client.TileIsoSprite; import com.threerings.miso.data.ObjectInfo; import com.threerings.miso.util.MisoSceneMetrics; import com.threerings.stage.data.StageMisoSceneModel; import com.threerings.stage.data.StageScene; import com.threerings.stage.util.StageContext; +import as3isolib.display.IsoSprite; import as3isolib.display.scene.IsoScene; /** @@ -50,9 +53,6 @@ public class StageScenePanel extends MisoScenePanel { super(ctx, metrics); _sCtx = ctx; - - _portalScene = new IsoScene(); - _isoView.addScene(_portalScene); } public function setScene (scene :StageScene) :void @@ -74,12 +74,81 @@ public class StageScenePanel extends MisoScenePanel // TODO } - override protected function resolutionComplete () :void + override protected function computeOverHover (mx :int, my :int) :Object { - super.resolutionComplete(); - _portalScene.render(); + var hits :Array = + _overPortalScene.displayListChildren.filter( + function(val :Object, idx :int, arr :Array) :Boolean { + if (val is PriorityIsoDisplayObject) { + return PriorityIsoDisplayObject(val).hitTest(mx, my); + } else { + return false; + } + }); + + if (hits.length > 0) { + return hits[0]; + } else { + hits = _portalScene.displayListChildren.filter( + function(val :Object, idx :int, arr :Array) :Boolean { + if (val is PriorityIsoDisplayObject) { + return PriorityIsoDisplayObject(val).hitTest(mx, my); + } else { + return false; + } + }); + if (hits.length > 0) { + return hits[0]; + } else { + return null; + } + } } + override protected function hoverObjectChanged (oldHover :Object, newHover :Object) :void + { + super.hoverObjectChanged(oldHover, newHover); + + if (oldHover is PortalIsoSprite) { + var oldPortal :PortalIsoSprite = PortalIsoSprite(oldHover); + oldPortal.setRaised(false); + + if (_overPortalScene.removeChild(oldPortal) != null) { + _portalScene.addChild(oldPortal); + } + + _portalScene.render(); + _overPortalScene.render(); + } + + if (newHover is PortalIsoSprite) { + var newPortal :PortalIsoSprite = PortalIsoSprite(newHover); + newPortal.setRaised(true); + + if (_portalScene.removeChild(newPortal) != null) { + _overPortalScene.addChild(newPortal); + } + + _portalScene.render(); + _overPortalScene.render(); + } + } + + override protected function renderObjectScenes () :void + { + super.renderObjectScenes(); + _portalScene.render(); + _overPortalScene.render(); + } + + override protected function addObjectScenes () :void + { + _portalScene = new IsoScene(); + _isoView.addScene(_portalScene); + super.addObjectScenes(); + _overPortalScene = new IsoScene(); + _isoView.addScene(_overPortalScene); + } override protected function createSceneBlock (blockKey :int) :SceneBlock { @@ -103,7 +172,8 @@ public class StageScenePanel extends MisoScenePanel } - protected var _portalScene :IsoScene + protected var _portalScene :IsoScene; + protected var _overPortalScene :IsoScene; /** The scene we're presenting in our panel. */ protected var _scene :StageScene;