iteye的博客太难编辑了,改天要换个地方了。
最近在研究45度地图,写了一个demo,
主要的类有两个,第一个,人物控制的类
第二个,主程序的类
源代码在附件中
最近在研究45度地图,写了一个demo,
主要的类有两个,第一个,人物控制的类
package view { import com.friendsofed.isometric.IsoObject; import constVars.Directions; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.DisplayObject; import flash.display.Sprite; import flash.events.Event; import flash.geom.Point; import flash.geom.Rectangle; import flash.utils.Dictionary; import flash.utils.getTimer; public class SpriteSheet extends IsoObject { //源图片 protected var _source:BitmapData; //每小格图片的宽 protected var _frameWidth:Number; //每小格图片的高 protected var _frameHeight:Number; //接受拷贝图片的bitmap private var _frameBitmap:Bitmap; //拷贝源图片的范围 private var _frameRect:Rectangle; //当前人物的方向 protected var _direction:String; //图片所在的行 protected var _rowNum:int; //图片所在列 private var _col:int = 0; //每间隔多少毫秒,图片拷贝一次 public static const RENDER_INTERVAL:Number = 64; //render timer protected var _oldTime:Number = 0; //每间隔多少毫秒,图片拷贝一次 protected var _renderInterval:Number; //最大图片的列 protected var _maxCol:int; //最大图片的行 protected var _maxRow:int = 8;//8个方向 //存放拷贝各个小格图片所占用的rectangle protected var _rects:Dictionary; //是否静止 private var _isIdle:Boolean; public function SpriteSheet(source:BitmapData,frameWidth:Number, frameHeight:Number,renderInterval:Number = RENDER_INTERVAL) { super(size); _source = source; _frameWidth = frameWidth; _frameHeight = frameHeight; _maxCol = Math.floor(_source.width/_frameWidth); _renderInterval = renderInterval; _frameRect = new Rectangle(0, 0, frameWidth, frameHeight); _rects = new Dictionary(); for(var i:int = 0; i < _maxRow; i++) for(var j:int = 0; j < _maxCol; j++) { var rect:Rectangle = new Rectangle(j*_frameWidth, i*_frameHeight, _frameWidth, _frameHeight); _rects[j+","+i] = rect;//将各个小格所需的rectangle存在dictrony里面 } _oldTime = getTimer(); render(); } /** * 把状态设为静止 */ public function idle():void { _isIdle = true; }; /** * 把状态设为运动 * */ public function action():void { _isIdle = false; startRender(); }; //监听函数,如果过了_renderInterval秒,那么渲染一次 protected function onEnterFrame(event:Event):void { var elapsed:Number = getTimer() - _oldTime; if (elapsed >= _renderInterval) { render(); _oldTime = getTimer(); } } //停止渲染 private function stopRender():void { removeEventListener(Event.ENTER_FRAME,onEnterFrame); } //开始渲染 private function startRender():void { if(!hasEventListener(Event.ENTER_FRAME)) { addEventListener(Event.ENTER_FRAME,onEnterFrame); } } public function render():void { if (_frameBitmap == null) { //创建bitmap存储从源图片拷贝的bitmapData _frameBitmap = new Bitmap(new BitmapData(_frameWidth, _frameHeight, true, 0x00000000)); addChild(_frameBitmap); //图片的片源量 _frameBitmap.x = -39; _frameBitmap.y = -115; } _frameBitmap.bitmapData.lock(); if(_isIdle)//如果静止,那么拷贝每一行的第一张图片 { _frameRect = _rects[0 +","+_rowNum] as Rectangle; _frameBitmap.bitmapData.copyPixels(_source, _frameRect, new Point(0, 0), null, null, false); stopRender(); } else { if(_col < _maxCol) { //从_rects取出rectangle _frameRect = _rects[_col+","+_rowNum] as Rectangle; } else { _col = 0; } _col++;//每一次渲染图片的列数依次加1 _frameBitmap.bitmapData.copyPixels(_source, _frameRect, new Point(0, 0), null, null, false); } _frameBitmap.bitmapData.unlock(); } //改变人物行走的方向 public function setDirection(direction:String):void { _direction = direction; switch (direction) { case Directions.S: _rowNum = 0; break; case Directions.W: _rowNum = 1; break; case Directions.E: _rowNum = 2; break; case Directions.N: _rowNum = 3; break; case Directions.SW: _rowNum = 4; break; case Directions.SE: _rowNum = 5; break; case Directions.NW: _rowNum = 6; break; case Directions.NE: _rowNum = 7; break; default: _rowNum = 0; } } } }
第二个,主程序的类
package { import com.friendsofed.isometric.DrawnIsoTile; import com.friendsofed.isometric.IsoUtils; import com.friendsofed.isometric.IsoWorld; import com.friendsofed.isometric.Point3D; import constVars.Directions; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Point; import path.AStar; import path.Grid; import path.Node; import view.PathNode; import view.SpriteSheet; [SWF(width="1000",height="600",frameRate="30")] public class PlayerTest extends Sprite { [Embed(source='0001.png')] public const SHEET:Class; //图片每一小格占用的宽和高 public const SHEET_FRAME_WIDTH:Number = 79; public const SHEET_FRAME_HEIGHT:Number = 108; private var _ss:SpriteSheet; private var _world:IsoWorld; //地图每一个tile的大小 private static const SIZE:int = 40; private static const GIRD_SIZE:int = 20; //网格 private var _grid:Grid; //寻路路径,节点数组 private var _path:Array; //寻路路径下标 private var _index:int; //行走速度 private var _speed:int = 2; public function PlayerTest() { createWorld(); _ss = new SpriteSheet(new SHEET().bitmapData, SHEET_FRAME_WIDTH, SHEET_FRAME_HEIGHT); _world.addChildToWorld(_ss); //初始化人物位置 _ss.position = new Point3D(SIZE/2, 0, SIZE/2); _world.addEventListener(MouseEvent.CLICK,onClick); makeGrid(); } //创建网格 private function makeGrid():void { // TODO Auto Generated method stub _grid = new Grid(GIRD_SIZE, GIRD_SIZE); for(var i:int = 0; i < GIRD_SIZE; i++) { for(var j:int = 0; j < GIRD_SIZE; j++) { _grid.setWalkable(i,j,true); } } } //创建地图 private function createWorld():void { _world = new IsoWorld(); _world.x = stage.stageWidth / 2; _world.y = 100; addChild(_world); for(var i:int = 0; i < GIRD_SIZE; i++) { for(var j:int = 0; j < GIRD_SIZE; j++) { var tile:DrawnIsoTile = new DrawnIsoTile(SIZE, 0xcccccc); tile.position = new Point3D(i * SIZE, 0, j * SIZE); _world.addChildToFloor(tile); } } } private function onClick(event:MouseEvent):void { var pos:Point3D = IsoUtils.screenToIso(new Point(_world.mouseX, _world.mouseY)); var col:int = Math.round(pos.x/SIZE); var row:int = Math.round(pos.z/SIZE); //设置起始的node _grid.setStartNode(Math.round(_ss.x/SIZE),Math.round(_ss.z/SIZE)); //设置目的地的node _grid.setEndNode(col,row);//取得网格地图的终点 //寻路 findPath(); //人物开始行走 _ss.action(); } private function findPath():void { //A*寻路 var astar:AStar = new AStar(); if(astar.findPath(_grid)) { _path = astar.path; _index = 0; showPath();//显示路径提示 addEventListener(Event.ENTER_FRAME, onEnterFrame); } } private function showPath():void { _world.clearPathTip();//清除之前的提示 var node:Node; for(var i:int = 0; i< _path.length; i++) { node = _path[i] as Node; var pathNode:PathNode = new PathNode(); //显示人物行走的路线 pathNode.position = new Point3D(node.x*SIZE,0,node.y*SIZE); _world.addChildToPathTip(pathNode); } } protected function onEnterFrame(event:Event):void { var node:Node = _path[_index]; var targetPoint:Point = IsoUtils.isoToScreen(new Point3D(node.x*SIZE+SIZE/2,0,node.y*SIZE+SIZE/2)); var playPoint:Point = IsoUtils.isoToScreen(_ss.position); var dx:Number = targetPoint.x - playPoint.x; var dy:Number = targetPoint.y - playPoint.y; var dist:Number = Math.sqrt(dx * dx + dy * dy); if(dist < _speed) { _index++; if(_index >= _path.length)//已经到达目的地 { _ss.idle(); removeEventListener(Event.ENTER_FRAME, onEnterFrame); } } else { var angle:Number = Math.atan2( dy, dx );//弧度 var speedX:Number = _speed * Math.cos( angle ); var speedY:Number = _speed * Math.sin( angle ); var ang:Number=angle*180/Math.PI; //判断行走方向,切换不同方向的行走动画 if(ang > -22.5 && ang <= 22.5) { _ss.setDirection(Directions.E); } else if(ang > 22.5 && ang <= 67.5) { _ss.setDirection(Directions.SE); } else if(ang > 67.5 && ang <= 112.5) { _ss.setDirection(Directions.S); } else if(ang > 112.5 && ang <= 157.5) { _ss.setDirection(Directions.SW); } else if(ang > -157.5 && ang <= -112.5) { _ss.setDirection(Directions.NW); } else if(ang > -67.5 && ang <= -22.5) { _ss.setDirection(Directions.NE); } else if(ang > -112.5 && ang <= -67.5) { _ss.setDirection(Directions.N); } else { _ss.setDirection(Directions.W); } var newX:Number=_ss.screenX+speedX; var newY:Number=_ss.screenY+speedY; var newPos:Point3D=IsoUtils.screenToIso(new Point(newX,newY)); _ss.position=newPos;//更新位置 } } } }
源代码在附件中
- PlayerTest.rar (789.2 KB)
- 下载次数: 42
发表评论
-
[AS3] Serializing Bitmaps (Storing BitmapData As Raw Binary/ByteArray)
2013-01-07 15:46 874转 [AS3] Serializing Bitmaps (S ... -
xml to binary
2013-01-07 15:44 730转两篇不错的关于xml压缩成binary的文章 http:/ ... -
puremvc,bulkload在线文档
2012-12-22 10:31 760pureMVC在线api http://puremvc.or ... -
发现一套不错的as3数据结构库
2012-12-21 14:34 881AS3 Data Structures For Game De ... -
地图滚动
2012-12-18 18:54 777http://www.emanueleferonato.com ... -
AS3 经典的代码库(转载)
2012-12-15 10:53 38743D引擎 Papervision3Dhttp://blog.p ...
相关推荐
为了更好地实现这一案例,我们可以编写一个简单的事件驱动程序,当用户点击地图上的某个位置时,启动寻路算法计算路径,并开始播放人物行走动画。此外,为了提高用户体验,还可以添加暂停、重置和调整行走速度等功能...
FLASH+php WEBGame 45度地图切换 多人游戏社区 FLASH人物行走 FLASH人物8方向寻路 在线聊天 (源码+fms服务端)开源项目 游戏截图: http://www.365tt1.com/ads/RGP/001.jpg http://www.365tt1.com/ads/RGP/002.jpg...
本资源包含一个Flex游戏人物行走的源代码,这对于理解游戏开发中的角色移动逻辑和碰撞检测至关重要。 源代码的核心部分可能涉及以下几个关键知识点: 1. **ActionScript**:ActionScript是Flash和Flex中的主要编程...
5. **导航网格**:用于AI路径规划,生成一个表示可行走区域的网格,以便游戏角色自动寻路。 6. **场景编排**:可以设置触发器、动画、事件等,使地图具备交互性和动态性。 对于初学者来说,3D地图编辑器的教程极具...
在这些游戏中,通过鼠标指定行走目的地,人物或者NPC就会自动行走到目标地点,这就是通过路径搜索或者称为寻路算法来实现的。通俗地说,就是在一张地图中,如何让主角自动行走到指定的地点,如图6-21所示,假设主角...
SLG(策略游戏)中的人物可达范围计算,主要是确定角色能够在地图上的哪些区域自由移动。这涉及到对地图障碍物的分析,以及角色移动规则的设定,例如限制只能在特定地形上行走。通过计算每个节点的可达性,可以生成...
使用three.js基于已有的路径和节点数据 使用d算法实现室内地图点选路径规划 具体效果参见我的博客:https://blog.csdn.net/u014529917/article/details/100424812
a星算法1、A星寻路; 2、支持连续点击,行走动画需要流畅过度; 3、地图不足以一屏显示时,能够自动滚动,到达边界时,不再滚动(人物并不总是在正中); 4、地图需要有障碍层,寻路时跳过;
1. 地图设计:迷宫地图通常由一系列可行走和不可行走的格子组成。在Unity3D中,我们可以使用Box Collider或者Custom Collider来定义可行走区域。迷宫的墙壁可以通过导入3D模型或者使用Plane GameObject并调整尺寸来...
在这些游戏中,通过路径指定目的地,人物或者 NPC 就会自动行走到目的地,这就是通过路径搜索或者称为寻路算法来实现的。 路径搜索算法的基本思想是,给定一个起点和终点,找到从起点到终点的一条路径,使得人物...