2009-11-24 19:43
lufy
用FLASH制作RPG-初级
自学flash,属初级阶段,会用flash的清自动绕行:P
目录
4楼:简单的地图显示
5楼:解决"跳移"和添加障碍移动
8楼:实现滚屏移动
13楼:地图跳转
14楼:npc人物添加
15楼:对话添加
16楼:A*算法寻路
18楼:就代码改动
19楼:战场画面-人物动作控制
20楼:战场画面
21楼:滚动条的研究
22楼:地图编辑器
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/fight01.jpg?t=1274089175[/img]
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/fight02.jpg?t=1274089195[/img]
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/fight03.jpg?t=1274089212[/img]
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/makemap.gif?t=1274090079[/img]
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/talk03.gif?t=1259668109[/img]
[color=Silver][[i] 本帖最后由 lufy 于 2010-5-18 08:22 编辑 [/i]][/color]
2009-11-24 22:35
岱瀛
从长期来讲,建议楼主要把代码分离出来,看到上面的帖子,发现不少代码写在动画贞里,这对于后期工程大了后,根本就没办法维护。
从现在开始就努力把as代码和界面分离。
2009-11-25 09:25
司徒苍月
貌似现在流行flash+xml方式,代码不一定要放在flash里,否则像楼上所说的,日后会很麻烦的
2009-11-25 18:01
lufy
多谢两位关注,:q555+
做这个本来也是无聊,考虑了一下,前面的作废了,:)
准备听取意见,重新规划,重新开始制作
考虑到代码与界面的分离,actionscript3.0比较容易,
这次,开发语言选择actionscript3.0,工具CS3不变
首先,建立结构包,如下
FlashProject
∟__com
∟data
∟images__map
∟player
以上各文件夹,com用来存放as文件,date用来存放xml等外部data文件,images下的map用来存放地图图片,player用来存放人物图片
好,下面,先建立新工程
选择Flash工程as3.0,名字随意
然后,CTRL + J打开属性框,将大小改为480*480
首先,先来写一个xml文件,命名为map001.xml,放到FlashProject/data/下,用来生成地图
我还用上次的数组了,但是写到xml文件里,如下:
<data>
<imageMap>
<list>3,3,3,3,3,3,3,3,3,3</list>
<list>3,1,0,0,0,0,3,0,0,3</list>
<list>3,0,0,0,0,0,3,3,0,3</list>
<list>3,0,3,3,3,3,3,3,0,3</list>
<list>3,0,0,3,0,0,0,3,0,3</list>
<list>3,3,0,3,0,3,3,3,0,3</list>
<list>3,0,0,3,0,0,0,0,0,3</list>
<list>3,0,3,3,0,3,0,3,3,3</list>
<list>3,0,0,0,0,3,0,0,2,3</list>
<list>3,3,3,3,3,3,3,3,3,3</list>
</imageMap>
</data>
接着,准备一张图片stage.jpg,放到FlashProject/images/map/备用
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/stage.jpg?t=1259142770[/img]
下面先不急着生成地图,先来建立一个处理图片的类,
因为刚刚准备的图片需要分解成小的位图才可以用
在com文件夹下,新建ImageCtrl.as
里面代码如下:
package com{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Matrix;
import flash.geom.Rectangle;
public class ImageCtrl {
public function ImageCtrl() {
}
//参数依次为原图片,图片列数,图片行数
public static function divide(source:Bitmap,row:int,col:int,total:* = null):Array {
//计算出每个小位图对象的宽度
var w:uint=source.width/row;
//计算出每个小位图对象的高度
var h:uint=source.height/col;
//计算有效位图总数
total=total==null?col*row:total;
//定义结果数组
var result:Array= new Array();
//定义矩阵
var matrix:Matrix = new Matrix();
//定义矩形
var rect:Rectangle=new Rectangle(0,0,w,h);
out:for (var j:int = 0; j < col; j++) {
var tempArr:Array = new Array();
for (var i:int = 0; i < row; i++) {
if (total<=0) {
break out;
}
//新建小位图对象
var bmp:BitmapData=new BitmapData(w,h,true,0x00000000);
//定义矩阵的焦点
matrix.tx=- i*w;
matrix.ty=- j*h;
//将矩阵内的数据按定义好的矩形大小和相应位置,画出小位图对象像素
bmp.draw(source,matrix,null,null,rect,true);
tempArr.push(bmp);
total--;
}
result.push(tempArr);
}
return result;
}
}
}
好了,上面这个类,可以把需要的大图片,按照需要分解成小的位图装进数组里
下面,该做地图了,在FlashProject/com/里新建Map001.as文件
内容如下:
package com{
import flash.net.URLLoader;
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.geom.Point;
public class Map001 extends MovieClip {
//声明载入图片类
private var _loader:Loader = new Loader( );
//声明Bitmap
private var _image:Bitmap;
//装载地图小位图用
private var _mapList:Array= new Array();
private var _mapXmlSrc:String;
//地图图片数组
private var _map:Array= new Array();
public function Map001() {
//获取地图xml文件
_mapXmlSrc = "data/map001.xml";
var loader:URLLoader = new URLLoader(new URLRequest(_mapXmlSrc));
loader.addEventListener(Event.COMPLETE,initMap);
}
public function initMap(evet:Event):void{
var mapXml:XML = new XML(evet.target.data);
//根据xml内容,得到地图图片数组
for each ( var element:XML in mapXml.imageMap.elements( ) ) {
var words:Array = ("" + element).split( ",");
_map.push(words);
}
//加载地图
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.load(new URLRequest("images/map/stage.jpg"));
}
public function onComplete(event:Event):void {
_image = Bitmap(_loader.content);
//将地图文件分解成数组
_mapList = ImageCtrl.divide(_image,4,1);
for(var i:int=0;i<10;i++){
for(var j:int=0;j<10;j++){
var index:int = _map[i][j];
var __image = new Bitmap(_mapList[0][index]);
__image.x = j*48;
__image.y = i*48;
addChild(__image);
}
}
}
}
}
这样地图就已经生成了,下面该把地图显示出来了
在FlashProject/com/里新建GameStart.as
代码如下:
package com{
import flash.display.MovieClip;
public class GameStart extends MovieClip {
public function GameStart() {
var map_001:Map001 = new Map001();
addChild(map_001);
}
}
}
然后,打开flash工程主场景,鼠标点击第一贞,F9打开代码框,写下:
import com.GameStart;
var myStart:GameStart = new GameStart();
addChild(myStart);
stop();
然后,CTRL+回车,生成flash
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/flash17.gif?t=1259142819[/img]
可以看到,一幅简单的地图就这样轻松的生成了
按照上次的步骤,下面加载人物
首先准备一张图片liubei.gif,放到FlashProject/images/player/下,备用
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/liubei.gif?t=1259143347[/img]
然后,在FlashProject/com/里新建PeopleClass.as
添加代码如下:
package com{
import flash.net.URLLoader;
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.events.KeyboardEvent;
import flash.geom.Point;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class PeopleClass extends MovieClip {
//声明time函数
private var _timer:Timer;
//位图数据数组
protected var _bitmapArr:Array;
//播放的顺序 0为上 1为下 2为左 3为右
private var _playDirection:int = 1;
//当前帧显示的位图数据的索引
private var _bitmapIndex:int=0;
//图片列数
private var _row:int;
//图片行数
private var _col:int;
private var _pointer:int;
//加载图片用
private var _loader:Loader;
//读取图片用
private var _image:Bitmap;
//用以显示的bitMap对象
private var _peopleBitmap:Bitmap;
//当前地图类
private var _mapBack:Object;
private var _isKeyDown:Boolean = false;
//人物坐标
private var _point: Point;
//构造器 mapBack:当前地图 player:人物图片 row:图片列数 col:图片行数
public function PeopleClass(mapBack:Object,player:String,row:int,col:int,point: Point = null) {
_point = new Point(point.x*48,point.y*48);
_mapBack = mapBack;
_row = row;
_col = col;
//初始化time;
_timer = new Timer(100);
_timer.addEventListener(TimerEvent.TIMER, timerHandler);
//图片加载对象;
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.load(new URLRequest(player));
//用来添加侦听器,侦听键盘
_mapBack.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
_mapBack.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
}
public function onComplete(event:Event):void {
_image = Bitmap(_loader.content);
//将传入的位图数据拆分成小块,装入bitmapArr
_bitmapArr=ImageCtrl.divide(_image,_row,_col);
//角色动作开始;
_timer.start();
}
//键盘事件,通过方向键更改角色移动方向;
private function keyDownHandler(event:KeyboardEvent):void {
_isKeyDown = true;
switch (event.keyCode) {
case 40 :
_playDirection = 1;
break;
case 38 :
_playDirection = 0;
break;
case 37 :
_playDirection = 2;
break;
case 39 :
_playDirection = 3;
break;
}
}
//键盘事件,
private function keyUpHandler(event:KeyboardEvent):void {
_isKeyDown = false;
}
//定时器运行事件;
private function timerHandler(event:Event):void {
//删除旧的角色动作图像;
if (_peopleBitmap != null) {
_mapBack.removeChild(_peopleBitmap);
}
//显示新的角色动作图像;
_peopleBitmap = new Bitmap(_bitmapArr[_playDirection][_pointer]);
//角色坐标
_peopleBitmap.x = _point.x;
_peopleBitmap.y = _point.y;
_mapBack.addChild(_peopleBitmap);
//角色动作循环处理;
if (_pointer < _row - 1) {
_pointer ++;
} else {
_pointer = 0;
}
//移动控制
toMove();
}
//移动控制
private function toMove():void{
if(_isKeyDown){
switch (_playDirection) {
case 0 :
_point.y -= 48;
break;
case 1 :
_point.y += 48;
break;
case 2 :
_point.x -= 48;
break;
case 3 :
_point.x += 48;
break;
}
}
}
}
}
Map001.as中添加两行代码
//加载人物
_player = new PeopleClass(this,"images/player/liubei.gif",2,4,new Point(2,1));
//设定光标
stage.focus = this;
变为:
package com{
import flash.net.URLLoader;
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.geom.Point;
public class Map001 extends MovieClip {
//声明载入图片类
private var _loader:Loader = new Loader( );
//声明Bitmap
private var _image:Bitmap;
//装载地图小位图用
private var _mapList:Array= new Array();
private var _mapXmlSrc:String;
//地图图片数组
private var _map:Array= new Array();
//人物
private var _player: PeopleClass;
public function Map001() {
//获取地图xml文件
_mapXmlSrc = "data/map001.xml";
var loader:URLLoader = new URLLoader(new URLRequest(_mapXmlSrc));
loader.addEventListener(Event.COMPLETE,initMap);
}
public function initMap(evet:Event):void{
var mapXml:XML = new XML(evet.target.data);
//根据xml内容,得到地图图片数组
for each ( var element:XML in mapXml.imageMap.elements( ) ) {
var words:Array = ("" + element).split( ",");
_map.push(words);
}
//加载地图
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.load(new URLRequest("images/map/stage.jpg"));
}
public function onComplete(event:Event):void {
_image = Bitmap(_loader.content);
//将地图文件分解成数组
_mapList = ImageCtrl.divide(_image,4,1);
for(var i:int=0;i<10;i++){
for(var j:int=0;j<10;j++){
var index:int = _map[i][j];
var __image = new Bitmap(_mapList[0][index]);
__image.x = j*48;
__image.y = i*48;
addChild(__image);
}
}
[color=Red] //加载人物
_player = new PeopleClass(this,"images/player/liubei.gif",2,4,new Point(2,1));
//设定光标
stage.focus = this;[/color]
}
}
}
CTRL+回车运行,
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/flash16-1.gif?t=1259142893[/img]
可以看到,人物已经添加上去了,
但是情况,依然是“跳移”,且上天入地,畅通无阻
至此,已经和上次完成了相同的内容
[color=Silver][[i] 本帖最后由 lufy 于 2009-11-25 18:09 编辑 [/i]][/color]
2009-11-25 18:01
lufy
接下来,解决跳格“跳移”和添加障碍
先来解决“跳移”,
首先PeopleClass.as里增加两个变量
//移动步数控制
private var _moveCtrl:int = 0;
//移动步长
private var _moveLong:int = 12;
keyDownHandler方法中添加
if(_moveCtrl > 0){
return;
}
toMove方法变为
//移动控制
private function toMove():void{
if(_moveCtrl >= 4){
_moveCtrl =0;
}
if(!_isKeyDown){
keyUpCheck();
}else{
keyDownCheck();
}
}
private function keyUpCheck(){
if(_moveCtrl == 0){
return;
}else{
switch (_playDirection) {
case 0 :
_point.y -= _moveLong;
break;
case 1 :
_point.y += _moveLong;
break;
case 2 :
_point.x -= _moveLong;
break;
case 3 :
_point.x += _moveLong;
break;
}
_moveCtrl += 1;
}
}
private function keyDownCheck(){
switch (_playDirection) {
case 0 :
_point.y -= _moveLong;
break;
case 1 :
_point.y += _moveLong;
break;
case 2 :
_point.x -= _moveLong;
break;
case 3 :
_point.x += _moveLong;
break;
}
_moveCtrl += 1;
}
CTRL+回车,再次运行,跳格问题已经解决了,接下来,
为了不让人物飞檐走壁,必须添加障碍
那么地图,就必须要有相对应得地形
首先,先来建立地形数组,map001.xml文件修改为
<data>
<imageMap>
<list>3,3,3,3,3,3,3,3,3,3</list>
<list>3,1,0,0,0,0,3,0,0,3</list>
<list>3,0,0,0,0,0,3,3,0,3</list>
<list>3,0,3,3,3,3,3,3,0,3</list>
<list>3,0,0,3,0,0,0,3,0,3</list>
<list>3,3,0,3,0,3,3,3,0,3</list>
<list>3,0,0,3,0,0,0,0,0,3</list>
<list>3,0,3,3,0,3,0,3,3,3</list>
<list>3,0,0,0,0,3,0,0,2,3</list>
<list>3,3,3,3,3,3,3,3,3,3</list>
</imageMap>
<dataMap>
<list>1,1,1,1,1,1,1,1,1,1</list>
<list>1,0,0,0,0,0,1,0,0,1</list>
<list>1,0,0,0,0,0,1,1,0,1</list>
<list>1,0,1,1,1,1,1,1,0,1</list>
<list>1,0,0,1,0,0,0,1,0,1</list>
<list>1,1,0,1,0,1,1,1,0,1</list>
<list>1,0,0,1,0,0,0,0,0,1</list>
<list>1,0,1,1,0,1,0,1,1,1</list>
<list>1,0,0,0,0,1,0,0,0,1</list>
<list>1,1,1,1,1,1,1,1,1,1</list>
</dataMap>
</data>
地形中,0为可移动,1为障碍
Map001.as文件中,添加地形数组,更改如下:
package com{
import flash.net.URLLoader;
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.geom.Point;
public class Map001 extends MovieClip {
//声明载入图片类
private var _loader:Loader = new Loader( );
//声明Bitmap
private var _image:Bitmap;
//装载地图小位图用
private var _mapList:Array= new Array();
private var _mapXmlSrc:String;
//地图图片数组
private var _map:Array= new Array();
//地形数组
private var _mapDate:Array= new Array();
//人物
private var _player: PeopleClass;
public function Map001() {
//获取地图xml文件
_mapXmlSrc = "data/map001.xml";
var loader:URLLoader = new URLLoader(new URLRequest(_mapXmlSrc));
loader.addEventListener(Event.COMPLETE,initMap);
}
public function initMap(evet:Event):void{
var mapXml:XML = new XML(evet.target.data);
//根据xml内容,得到地图图片数组
for each ( var element:XML in mapXml.imageMap.elements( ) ) {
var words:Array = ("" + element).split( ",");
_map.push(words);
}
//根据xml内容,得到地形数组
for each ( var datement:XML in mapXml.dataMap.elements( ) ) {
var dates:Array = ("" + datement).split( ",");
_mapDate.push(dates);
}
//加载地图
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.load(new URLRequest("images/map/stage.jpg"));
}
public function onComplete(event:Event):void {
_image = Bitmap(_loader.content);
//将地图文件分解成数组
_mapList = ImageCtrl.divide(_image,4,1);
for(var i:int=0;i<10;i++){
for(var j:int=0;j<10;j++){
var index:int = _map[i][j];
var __image = new Bitmap(_mapList[0][index]);
__image.x = j*48;
__image.y = i*48;
addChild(__image);
}
}
//加载人物
_player = new PeopleClass(this,"images/player/liubei.gif",2,4,new Point(2,1));
//设定光标
stage.focus = this;
}
//取得地形数组
public function getMapDate():Array{
return _mapDate;
}
}
}
PeopleClass.as中,人物行走前,添加地形判断
package com{
import flash.net.URLLoader;
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.events.KeyboardEvent;
import flash.geom.Point;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class PeopleClass extends MovieClip {
//声明time函数
private var _timer:Timer;
//位图数据数组
protected var _bitmapArr:Array;
//播放的顺序 0为上 1为下 2为左 3为右
private var _playDirection:int = 1;
//当前帧显示的位图数据的索引
private var _bitmapIndex:int=0;
//图片列数
private var _row:int;
//图片行数
private var _col:int;
private var _pointer:int;
//加载图片用
private var _loader:Loader;
//读取图片用
private var _image:Bitmap;
//用以显示的bitMap对象
private var _peopleBitmap:Bitmap;
//当前地图类
private var _mapBack:Object;
//移动步数控制
private var _moveCtrl:int = 0;
//移动步长
private var _moveLong:int = 12;
private var _isKeyDown:Boolean = false;
//人物坐标
private var _point: Point;
private var _mapPoint: Point;
//构造器 mapBack:当前地图 player:人物图片 row:图片列数 col:图片行数
public function PeopleClass(mapBack:Object,player:String,row:int,col:int,point:
Point = null) {
if(point == null){
_point = new Point(0,0);
_mapPoint = new Point(0,0);
}else{
_point = new Point(point.x*48,point.y*48);
_mapPoint = point;
}
_mapBack = mapBack;
_row = row;
_col = col;
//初始化time;
_timer = new Timer(100);
_timer.addEventListener(TimerEvent.TIMER, timerHandler);
//图片加载对象;
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.load(new URLRequest(player));
//用来添加侦听器,侦听键盘
_mapBack.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
_mapBack.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
}
public function onComplete(event:Event):void {
_image = Bitmap(_loader.content);
//将传入的位图数据拆分成小块,装入bitmapArr
_bitmapArr=ImageCtrl.divide(_image,_row,_col);
//角色动作开始;
_timer.start();
}
//键盘事件,通过方向键更改角色移动方向;
private function keyDownHandler(event:KeyboardEvent):void {
if(_moveCtrl > 0){
return;
}
_isKeyDown = true;
switch (event.keyCode) {
case 40 :
_playDirection = 1;
break;
case 38 :
_playDirection = 0;
break;
case 37 :
_playDirection = 2;
break;
case 39 :
_playDirection = 3;
break;
}
}
//键盘事件,
private function keyUpHandler(event:KeyboardEvent):void {
_isKeyDown = false;
}
//定时器运行事件;
private function timerHandler(event:Event):void {
//删除旧的角色动作图像;
if (_peopleBitmap != null) {
_mapBack.removeChild(_peopleBitmap);
}
//显示新的角色动作图像;
_peopleBitmap = new Bitmap(_bitmapArr[_playDirection][_pointer]);
//角色坐标
_peopleBitmap.x = _point.x;
_peopleBitmap.y = _point.y;
_mapBack.addChild(_peopleBitmap);
//角色动作循环处理;
if (_pointer < _row - 1) {
_pointer ++;
} else {
_pointer = 0;
}
//移动控制
toMove();
}
private function keyUpCheck(){
if(_moveCtrl == 0){
return;
}else{
switch (_playDirection) {
case 0 :
_point.y -= _moveLong;
break;
case 1 :
_point.y += _moveLong;
break;
case 2 :
_point.x -= _moveLong;
break;
case 3 :
_point.x += _moveLong;
break;
}
_moveCtrl += 1;
}
}
private function keyDownCheck(){
if(_moveCtrl == 0){
switch (_playDirection) {
case 0 :
checkUp();
break;
case 1 :
checkDown();
break;
case 2 :
checkLeft();
break;
case 3 :
checkRight();
break;
}
}else{
switch (_playDirection) {
case 0 :
_point.y -= _moveLong;
break;
case 1 :
_point.y += _moveLong;
break;
case 2 :
_point.x -= _moveLong;
break;
case 3 :
_point.x += _moveLong;
break;
}
_moveCtrl += 1;
}
}
//移动控制
private function toMove():void{
if(_moveCtrl >= 4){
_moveCtrl =0;
}
if(!_isKeyDown){
keyUpCheck();
}else{
keyDownCheck();
}
}
private function checkRight():void{
if(checkMap(_mapPoint.x + 1,_mapPoint.y)){
_mapPoint.x += 1;
_point.x += _moveLong;
_moveCtrl += 1;
}
}
private function checkLeft():void{
if(checkMap(_mapPoint.x - 1,_mapPoint.y)){
_mapPoint.x -= 1;
_point.x -= _moveLong;
_moveCtrl += 1;
}
}
private function checkDown():void{
if(checkMap(_mapPoint.x, _mapPoint.y + 1)){
_mapPoint.y += 1;
_point.y += _moveLong;
_moveCtrl += 1;
}
}
private function checkUp():void{
if(checkMap(_mapPoint.x,_mapPoint.y - 1)){
_mapPoint.y -= 1;
_point.y -= _moveLong;
_moveCtrl += 1;
}
}
//障碍判断
private function checkMap(mapX:int,mapY:int):Boolean{
var mapDate:Array = _mapBack.getMapDate();
if(mapDate[mapY][mapX] == 0){
return true;
}else{
return false;
}
}
public function getPeoplePoint(): Point{
return new Point(_point.x/48,_point.y/48);
}
}
}
好了,再来运行一下吧,超人终于变正常了:lol:
不过,一个RPG,地图也不能就这么点阿,
[size=3]下次准备把地图弄大,加上滚屏[/size]:wink:
[color=Silver][[i] 本帖最后由 lufy 于 2009-11-25 18:10 编辑 [/i]][/color]
2009-11-26 07:38
花言乔语
希望楼主能做一个flash版的曹操传
2009-11-26 07:39
花言乔语
希望楼主能做一个flash版的曹操传
2009-11-26 18:50
lufy
这次将地图扩大,实现滚屏
首先,将map001.xml内容修改为:
<data>
<imageMap>
<list>3,3,3,3,3,3,3,3,3,3,3,3,3,3,3</list>
<list>3,1,0,0,0,0,3,0,0,0,0,0,0,0,3</list>
<list>3,0,0,0,0,0,3,3,0,0,0,0,0,0,3</list>
<list>3,0,3,3,3,3,3,0,0,0,0,0,3,0,3</list>
<list>3,0,0,3,0,0,0,0,0,0,0,0,3,0,3</list>
<list>3,3,0,3,0,3,3,3,0,0,0,0,0,0,3</list>
<list>3,0,0,3,0,0,0,0,0,0,0,0,0,0,3</list>
<list>3,0,3,3,0,3,0,3,3,0,0,0,0,0,3</list>
<list>3,0,0,0,0,3,0,0,0,0,0,0,0,0,3</list>
<list>3,0,0,0,0,3,0,0,0,0,0,0,0,0,3</list>
<list>3,0,0,0,0,3,0,0,0,0,0,0,0,0,3</list>
<list>3,0,0,0,0,3,0,0,0,0,0,0,0,0,3</list>
<list>3,0,0,0,0,3,0,0,0,0,0,0,0,2,3</list>
<list>3,0,0,0,0,3,0,0,0,0,0,0,0,0,3</list>
<list>3,3,3,3,3,3,3,3,3,3,3,3,3,3,3</list>
</imageMap>
<dataMap maxX="15" maxY="15">
<list>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</list>
<list>1,0,0,0,0,0,1,0,0,0,0,0,0,0,1</list>
<list>1,0,0,0,0,0,1,1,0,0,0,0,0,0,1</list>
<list>1,0,1,1,1,1,1,0,0,0,0,0,1,0,1</list>
<list>1,0,0,1,0,0,0,0,0,0,0,0,1,0,1</list>
<list>1,1,0,1,0,1,1,1,0,0,0,0,0,0,1</list>
<list>1,0,0,1,0,0,0,0,0,0,0,0,0,0,1</list>
<list>1,0,1,1,0,1,0,1,1,0,0,0,0,0,1</list>
<list>1,0,0,0,0,1,0,0,0,0,0,0,0,0,1</list>
<list>1,0,0,0,0,1,0,0,0,0,0,0,0,0,1</list>
<list>1,0,0,0,0,1,0,0,0,0,0,0,0,0,1</list>
<list>1,0,0,0,0,1,0,0,0,0,0,0,0,0,1</list>
<list>1,0,0,0,0,1,0,0,0,0,0,0,0,0,1</list>
<list>1,0,0,0,0,1,0,0,0,0,0,0,0,0,1</list>
<list>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</list>
</dataMap>
</data>
然后,下面的工作,主要是Map001.as和PeopleClass.as的修改,下面给出修改后代码,加了详细的注释,就不多说了:P
Map001.as:
package com{
import flash.net.URLLoader;
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.geom.Point;
import flash.events.MouseEvent;
public class Map001 extends MovieClip {
//声明载入图片类
private var _loader:Loader = new Loader( );
//声明Bitmap
private var _image:Bitmap;
private var __image:Bitmap;
//装载地图小位图用
private var _mapList:Array= new Array();
private var _mapXmlSrc:String;
//地图图片数组
private var _map:Array= new Array();
//地形数组
private var _mapDate:Array= new Array();
//人物
private var _player: PeopleClass;
//滚屏用变量
private var _mapStartX:int = 0;
private var _mapEndX:int = 0;
private var _mapStartY:int = 0;
private var _mapEndY:int = 0;
//地图显示的起始坐标
public var _mPoint: Point;
//地图最大坐标
public var _maxX:int;
public var _maxY:int;
public var _mapFrame:MovieClip = new MovieClip();
public function Map001() {
addChild(_mapFrame);
_mPoint = new Point(0,0);
//获取地图xml文件
_mapXmlSrc = "data/map001.xml";
var loader:URLLoader = new URLLoader(new URLRequest(_mapXmlSrc));
loader.addEventListener(Event.COMPLETE,initMap);
addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
public function mouseDownHandler(evet:MouseEvent):void{
//设定光标
stage.focus = this;
}
public function initMap(evet:Event):void{
var mapXml:XML = new XML(evet.target.data);
_maxX = mapXml.dataMap.@maxX;;
_maxY = mapXml.dataMap.@maxY;
//根据xml内容,得到地图图片数组
for each ( var element:XML in mapXml.imageMap.elements( ) ) {
var words:Array = ("" + element).split( ",");
_map.push(words);
}
//根据xml内容,得到地形数组
for each ( var datement:XML in mapXml.dataMap.elements( ) ) {
var dates:Array = ("" + datement).split( ",");
_mapDate.push(dates);
}
//加载地图
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.load(new URLRequest("images/map/stage.jpg"));
}
public function onComplete(event:Event):void {
_image = Bitmap(_loader.content);
//将地图文件分解成数组
_mapList = ImageCtrl.divide(_image,4,1);
//加载人物
_player = new PeopleClass(this,"images/player/liubei.gif",2,4,new Point(4,4));
//绘制地图
drowMap();
//设定光标
stage.focus = this;
}
public function drowMap():void{
[color=Red][size=3][b] //地图清空
BaseRemove.removeAllChildren(_mapFrame);[/b][/size][/color]
//地图重绘
for(var i:int= _mPoint.y + _mapStartY;i<_mPoint.y + _mapEndY + 10;i++){
for(var j:int=_mPoint.x + _mapStartX;j<_mPoint.x + _mapEndX + 10;j++){
var index:int = _map[i][j];
__image = new Bitmap(_mapList[0][index]);
__image.x = (j - _mPoint.x)*48;
__image.y = (i - _mPoint.y)*48;
_mapFrame.addChild(__image);
}
}
}
//取得地形数组
public function getMapDate():Array{
return _mapDate;
}
//设定偏移
public function setCoordinate(intStartX:int = 0,intEndX:int = 0,intStartY:int = 0,intEndY:int = 0):void{
_mapStartX = intStartX;
_mapEndX = intEndX;
_mapStartY = intStartY;
_mapEndY = intEndY;
}
}
}
PeopleClass.as:
package com{
import flash.net.URLLoader;
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.events.KeyboardEvent;
import flash.geom.Point;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class PeopleClass extends MovieClip {
//声明time函数
private var _timer:Timer;
//位图数据数组
protected var _bitmapArr:Array;
//播放的顺序 0为上 1为下 2为左 3为右
private var _playDirection:int = 1;
//当前帧显示的位图数据的索引
private var _bitmapIndex:int=0;
//图片列数
private var _row:int;
//图片行数
private var _col:int;
private var _pointer:int;
//加载图片用
private var _loader:Loader;
//读取图片用
private var _image:Bitmap;
//用以显示的bitMap对象
private var _peopleBitmap:Bitmap;
//当前地图类
private var _mapBack:Object;
//移动步数控制
public var _moveCtrl:int = 0;
//移动步长
public var _moveLong:int = 12;
private var _isKeyDown:Boolean = false;
//人物在画面中坐标
private var _point: Point;
//人物在地图中坐标
private var _mapPoint: Point;
//滚屏控制
private var _mapIsRoll = false;
//构造器 mapBack:当前地图 player:人物图片 row:图片列数 col:图片行数
public function PeopleClass(mapBack:Object,player:String,row:int,col:int,point: Point = null) {
if(point == null){
_point = new Point(0,0);
_mapPoint = new Point(0,0);
}else{
_point = new Point(point.x*48,point.y*48);
_mapPoint = point;
}
_mapBack = mapBack;
_row = row;
_col = col;
//初始化time;
_timer = new Timer(100);
_timer.addEventListener(TimerEvent.TIMER, timerHandler);
//图片加载对象;
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.load(new URLRequest(player));
//用来添加侦听器,侦听键盘
_mapBack.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
_mapBack.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
}
public function onComplete(event:Event):void {
_image = Bitmap(_loader.content);
//将传入的位图数据拆分成小块,装入bitmapArr
_bitmapArr=ImageCtrl.divide(_image,_row,_col);
//角色动作开始;
_timer.start();
}
//键盘事件,通过方向键更改角色移动方向;
private function keyDownHandler(event:KeyboardEvent):void {
//人物移动不够一个坐标,则返回
if(_moveCtrl > 0){
return;
}
_isKeyDown = true;
switch (event.keyCode) {
case 40 :
_playDirection = 1;
break;
case 38 :
_playDirection = 0;
break;
case 37 :
_playDirection = 2;
break;
case 39 :
_playDirection = 3;
break;
}
}
//键盘事件,
private function keyUpHandler(event:KeyboardEvent):void {
_isKeyDown = false;
}
//定时器运行事件;
private function timerHandler(event:Event):void {
//删除旧的角色动作图像;
if (_peopleBitmap != null) {
_mapBack.removeChild(_peopleBitmap);
}
//显示新的角色动作图像;
_peopleBitmap = new Bitmap(_bitmapArr[_playDirection][_pointer]);
//角色坐标
_peopleBitmap.x = _point.x;
_peopleBitmap.y = _point.y;
_mapBack.addChild(_peopleBitmap);
//角色动作循环处理;
if (_pointer < _row - 1) {
_pointer ++;
} else {
_pointer = 0;
}
//移动控制
toMove();
}
private function keyUpCheck(){
//人物移动达到一个坐标,则停止,否则继续移动
if(_moveCtrl == 0){
_mapIsRoll = false;
return;
}else{
coordinateChange();
}
}
private function keyDownCheck(){
//人物移动达到一个坐标,则进行下一个坐标的判断,否则继续移动
if(_moveCtrl == 0){
switch (_playDirection) {
case 0 :
checkUp();
break;
case 1 :
checkDown();
break;
case 2 :
checkLeft();
break;
case 3 :
checkRight();
break;
}
}else{
coordinateChange();
}
}
//移动执行
private function coordinateChange():void{
//人物移动
if(!_mapIsRoll){
switch (_playDirection) {
case 0 :
_point.y -= _moveLong;
break;
case 1 :
_point.y += _moveLong;
break;
case 2 :
_point.x -= _moveLong;
break;
case 3 :
_point.x += _moveLong;
break;
}
}else{
//滚屏移动
switch (_playDirection) {
case 0 :
_mapBack._mapFrame.y += _moveLong;
break;
case 1 :
_mapBack._mapFrame.y -= _moveLong;
break;
case 2 :
_mapBack._mapFrame.x += _moveLong;
break;
case 3 :
_mapBack._mapFrame.x -= _moveLong;
break;
}
//地图重绘
_mapBack.drowMap();
}
_moveCtrl += 1;
}
//移动控制
private function toMove():void{
//移动达到一个坐标判断
if(_moveCtrl >= 4){
_moveCtrl =0;
//如果滚屏移动,则重绘地图
if(_mapIsRoll){
_mapBack._mapFrame.x = 0;
_mapBack._mapFrame.y = 0;
_mapBack.setCoordinate();
switch (_playDirection) {
case 0 :
_mapBack._mPoint.y -= 1;
break;
case 1 :
_mapBack._mPoint.y += 1;
break;
case 2 :
_mapBack._mPoint.x -= 1;
break;
case 3 :
_mapBack._mPoint.x += 1;
break;
}
_mapBack.drowMap();
}
}
if(!_isKeyDown){
//键盘弹起状态处理
keyUpCheck();
}else{
//键盘按下状态处理
keyDownCheck();
}
}
//右移判断
private function checkRight():void{
if(checkMap(_mapPoint.x + 1,_mapPoint.y)){
//是否滚屏移动
if(_point.x >= 240 && _mapBack._mPoint.x < _mapBack._maxX - 10){
_mapBack.setCoordinate(0,1);
_mapBack._mapFrame.x -= _moveLong;
_mapBack.drowMap();
_mapIsRoll = true;
}else{;
_mapIsRoll = false;
_point.x += _moveLong;
}
_moveCtrl += 1;
_mapPoint.x += 1
}
}
//左移判断
private function checkLeft():void{
if(checkMap(_mapPoint.x - 1,_mapPoint.y)){
//是否滚屏移动
if(_point.x <= 192 && _mapBack._mPoint.x > 0){
_mapBack.setCoordinate(-1,0);
_mapBack._mapFrame.x += _moveLong;
_mapBack.drowMap();
_mapIsRoll = true;
}else{
_mapIsRoll = false;
_point.x -= _moveLong;
}
_mapPoint.x -= 1;
_moveCtrl += 1;
}
}
//下移判断
private function checkDown():void{
if(checkMap(_mapPoint.x, _mapPoint.y + 1)){
//是否滚屏移动
if(_point.y >= 240 && _mapBack._mPoint.y< _mapBack._maxY - 10){
_mapBack.setCoordinate(0,0,0,1);
_mapBack._mapFrame.y -= _moveLong;
_mapBack.drowMap();
_mapIsRoll = true;
}else{
_mapIsRoll = false;
_point.y += _moveLong;
}
_mapPoint.y += 1;
_moveCtrl += 1;
}
}
//上移判断
private function checkUp():void{
if(checkMap(_mapPoint.x,_mapPoint.y - 1)){
//是否滚屏移动
if(_point.y <= 192 && _mapBack._mPoint.y > 0){
_mapBack.setCoordinate(0,0,-1,0);
_mapBack._mapFrame.y += _moveLong;
_mapBack.drowMap();
_mapIsRoll = true;
}else{
_mapIsRoll = false;
_point.y -= _moveLong;
}
_mapPoint.y -= 1;
_moveCtrl += 1;
}
}
//障碍判断
private function checkMap(mapX:int,mapY:int):Boolean{
var mapDate:Array = _mapBack.getMapDate();
if(mapDate[mapY][mapX] == 0){
return true;
}else{
return false;
}
}
}
}
以上,红色字体部分必须有,是用来清除旧的地图,否则new的越来越多,速度也就越来越慢了......
当然,需要在com包下添加一个新类,
BaseRemove.as:
package com
{
import flash.display.*;
public class BaseRemove{
public static function removeAllChildren(
container:DisplayObjectContainer ):void {
var count:int = container.numChildren;
for ( var i:int = 0; i < count; i++ ) {
container.removeChildAt( 0 );
}
}
}
}
好了,CTRL+回车运行,滚屏移动就实现了:victory:
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/flash18.gif?t=1259230228[/img]
游戏中总不能只有一张地图阿,所以,下次准备弄一下地图切换:)
[color=Silver][[i] 本帖最后由 lufy 于 2009-11-26 19:04 编辑 [/i]][/color]
2009-11-26 18:58
赵辉
请lz编辑一下楼上的帖子,选一下左边的“禁用Smiles”吧(见附图),有几处程序符号错显示成表情了:lol:
[color=Silver][[i] 本帖最后由 赵辉 于 2009-11-26 19:02 编辑 [/i]][/color]
2009-11-26 19:03
狂煞∑小星
好东西,做成flash的曹操传就好了
2009-11-26 19:06
lufy
[quote]原帖由 [i]赵辉[/i] 于 2009-11-26 18:58 发表
请lz编辑一下楼上的帖子,选一下左边的“禁用Smiles”吧(见附图),有几处程序符号错显示成表情了:lol: [/quote]
:lol:原来如此,改了
2009-11-26 23:19
岱瀛
[quote]原帖由 [i]司徒苍月[/i] 于 2009-11-25 09:25 发表
貌似现在流行flash+xml方式,代码不一定要放在flash里,否则像楼上所说的,日后会很麻烦的 [/quote]
这个应该是flex, 用的AS 3.0的了,看楼主主要还是用 as 2.0.
其实我是不建议盲目追捧新技术的,关键还是个人的编程思想和编程习惯的培养。
像Flash中代码写入帧,几乎是企业级代码编写的首忌。 要在公司里有新人这样写,基本打回去重新写。
2009-11-28 14:36
lufy
下面实现地图跳转
首先,先把地图图片扩展一下
将stage.jpg替换如下
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/stage-1.jpg?t=1259389286[/img]
然后,Map001.as中读取地图小位图的时候,需要变更一下:
public function drowMap():void{
//地图清空
BaseRemove.removeAllChildren(_mapFrame);
//地图重绘
for(var i:int= _mPoint.y + _mapStartY;i<_mPoint.y + _mapEndY + 10;i++){
for(var j:int=_mPoint.x + _mapStartX;j<_mPoint.x + _mapEndX + 10;j++){
var index:int = _map[i][j];
var indexX:int = Math.floor(index /10);
var indexY:int = index - indexX*10;
__image = new Bitmap(_mapList[indexX][indexY]);
__image.x = (j - _mPoint.x)*48;
__image.y = (i - _mPoint.y)*48;
_mapFrame.addChild(__image);
}
}
}
接下来,准备就是画两个地图了,为了以后添加地图和人物方便,不用改程序,将xml改进一下
FlashProject\data下,先建立一个maps.xml文件,内容如下
<data>
<list>map001</list>
<list>map002</list>
</data>
封装所有地图名称,这次暂时用到两个map001.xml和map002.xml
map001.xml内容:
<data>
<imageMap>
<list>18,18,18,18,18,18,18,18,18,18,18,18,55,55,18</list>
<list>18,18,18,17,17,17,17,17,17,17,17,17,55,55,18</list>
<list>18,18,17,17,17,17,18,18,17,17,17,17,55,55,18</list>
<list>18,17,17,17,18,18,18,18,18,17,17,55,55,17,18</list>
<list>18,17,17,18,22,23,23,23,24,18,17,55,55,17,18</list>
<list>18,17,17,18,25,28,26,79,27,18,55,55,17,17,18</list>
<list>18,17,17,17,17,10,11,12,18,18,55,55,17,17,18</list>
<list>18,17,17,17,17,77,16,78,18,18,55,55,17,17,18</list>
<list>18,17,17,17,17,77,16,78,17,55,55,17,17,17,18</list>
<list>18,18,17,17,10,16,16,16,11,55,55,17,17,17,18</list>
<list>18,18,17,17,77,16,16,16,16,21,21,17,17,17,18</list>
<list>18,18,17,17,13,14,14,14,15,55,55,17,17,17,18</list>
<list>18,18,17,17,55,55,55,55,55,55,55,17,17,18,18</list>
<list>18,18,17,17,55,55,55,55,55,55,55,17,18,18,18</list>
<list>18,18,55,55,55,55,55,55,55,55,55,18,18,18,18</list>
</imageMap>
<dataMap maxX="15" maxY="15">
<list>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</list>
<list>1,1,1,0,0,0,0,0,0,0,0,0,1,1,1</list>
<list>1,1,0,0,0,0,1,1,0,0,0,0,1,1,1</list>
<list>1,0,0,0,1,1,1,1,1,0,0,1,1,0,1</list>
<list>1,0,0,1,1,1,1,1,1,1,0,1,1,0,1</list>
<list>1,0,0,1,1,1,0,1,1,1,1,1,0,0,1</list>
<list>1,0,0,0,0,0,0,0,1,1,1,1,0,0,1</list>
<list>1,0,0,0,0,0,0,0,1,1,1,1,0,0,1</list>
<list>1,0,0,0,0,0,0,0,0,1,1,0,0,0,1</list>
<list>1,1,0,0,0,0,0,0,0,1,1,0,0,0,1</list>
<list>1,1,0,0,0,0,0,0,0,0,0,0,0,0,1</list>
<list>1,1,0,0,0,0,0,0,0,1,1,0,0,0,1</list>
<list>1,1,0,0,1,1,1,1,1,1,1,0,0,1,1</list>
<list>1,1,0,0,1,1,1,1,1,1,1,0,1,1,1</list>
<list>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</list>
</dataMap>
<hero>
<Image>images/player/liubei.gif</Image>
<Coordinate>12,12</Coordinate>
</hero>
<changeMap>
<list name="map002" coordinate="5,9">6,5</list>
</changeMap>
</data>
map002.xml内容:
<data>
<imageMap>
<list>1,2,2,2,2,2,2,2,2,1</list>
<list>1,3,5,5,1,5,5,5,5,1</list>
<list>1,80,4,4,1,80,4,4,4,1</list>
<list>1,80,4,4,1,80,8,7,8,1</list>
<list>1,80,4,4,5,81,4,4,4,1</list>
<list>1,2,2,2,6,4,4,4,4,1</list>
<list>1,3,5,5,81,4,4,4,4,1</list>
<list>1,80,4,4,4,4,4,4,4,1</list>
<list>1,80,4,4,4,4,4,4,9,1</list>
<list>1,2,2,2,2,6,2,2,2,1</list>
</imageMap>
<dataMap maxX="10" maxY="10">
<list>1,1,1,1,1,1,1,1,1,1</list>
<list>1,0,0,0,1,0,0,0,0,1</list>
<list>1,0,0,0,1,0,0,0,0,1</list>
<list>1,0,0,0,1,0,0,1,0,1</list>
<list>1,0,0,0,0,0,0,0,0,1</list>
<list>1,1,1,1,0,0,0,0,0,1</list>
<list>1,0,0,0,0,0,0,0,0,1</list>
<list>1,0,0,0,0,0,0,0,0,1</list>
<list>1,0,0,0,0,0,0,0,1,1</list>
<list>1,1,1,1,1,0,1,1,1,1</list>
</dataMap>
<hero>
<Image>images/player/liubei.gif</Image>
<Coordinate>5,9</Coordinate>
</hero>
<changeMap>
<list name="map001" coordinate="6,5">5,9</list>
</changeMap>
</data>
地图xml中,第一个节点,是地图图片信息,第二个节点是地形信息,
第三个节点是人物信息,Image为人物图片,Coordinate为人物出现的默认坐标
第四个节点是地图跳转信息,list中的(5,9)是人物到达指定的跳转位置坐标,name指跳转后的地图名称,coordinate是人物出现在跳转后地图的坐标。
以后如果想另添加一个新的场景,只需要添加一个map003.xml,然后在maps.xml添加相应的节点就行了
GameStart.as中,将相应地图名称封装,变更如下:
package com{
import flash.display.MovieClip;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.geom.Point;
public class GameStart extends MovieClip {
private var _mapList:HashMap = new HashMap();
private var _mapName:String = "map001";
//人物跳转坐标
private var _mapPoint:Point;
public function GameStart() {
var loader:URLLoader = new URLLoader(new URLRequest("data/maps.xml"));
loader.addEventListener(Event.COMPLETE,initMap);
}
public function initMap(evet:Event):void{
//得到xml信息
var mapXml:XML = new XML(evet.target.data);
//装载所有地图信息
for each ( var datement:XML in mapXml.elements( ) ) {
var strDate:String = ("" + datement);
_mapList.put(strDate,"data/" + strDate + ".xml");
}
selectMap();
}
//地图跳转
public function selectMap():void{
BaseRemove.removeAllChildren(this);
//通过名称显示相应地图
var mapValue:String = "" +_mapList.getValue(_mapName);
var map_001:Map001 = new Map001(mapValue,this);
addChild(map_001);
}
//设定地图名称
public function setMapName(mapName:String):void{
_mapName = mapName;
}
//设定人物跳转坐标
public function setPoint(mapPoint:Point = null):void{
_mapPoint = mapPoint;
}
//得到人物跳转坐标
public function getPoint():Point{
return _mapPoint;
}
}
}
Map001.as 中,增加响应解析xml的代码,
public function initMap(evet:Event):void{
//得到xml信息
var mapXml:XML = new XML(evet.target.data);
//得到人物图片
_propleImage = mapXml.hero.Image;
//取得地图最大size
_maxX = mapXml.dataMap.@maxX;;
_maxY = mapXml.dataMap.@maxY;
//得到人物坐标信息
var peoplePoint:Point = _gameMap.getPoint();
if(peoplePoint == null){
var strPoint:String = mapXml.hero.Coordinate;
var pointArray:Array = strPoint.split( ",");
_peoplePoint = new Point(pointArray[0],pointArray[1]);
}else{
_peoplePoint = peoplePoint;
}[color=Red]
//计算人物坐标和显示位置
var mPointX:int = 0;
var mPointY:int = 0;
if(_peoplePoint.x > 5){
if(_peoplePoint.x + 5 <= _maxX){
mPointX = _peoplePoint.x - 5;
_peoplePoint.x = 5;
}else{
mPointX = _maxX - 10;
if(mPointX > 0){
_peoplePoint.x = _peoplePoint.x - mPointX;
}
}
}
if(_peoplePoint.y > 5){
if(_peoplePoint.y + 5 <= _maxY){
mPointY = _peoplePoint.y - 5;
_peoplePoint.y = 5;
}else{
mPointY = _maxY - 10;
if(mPointY > 0 ){
_peoplePoint.y = _peoplePoint.y - mPointY;
}
}
}
_mPoint = new Point(mPointX,mPointY);[/color]
//根据xml内容,得到地图图片数组
for each ( var element:XML in mapXml.imageMap.elements( ) ) {
var words:Array = ("" + element).split( ",");
_map.push(words);
}
//根据xml内容,得到地形数组
for each ( var datement:XML in mapXml.dataMap.elements( ) ) {
var dates:Array = ("" + datement).split( ",");
_mapDate.push(dates);
}[color=Red]
//根据xml内容,得到地图跳转信息
for each ( var changement:XML in mapXml.changeMap.elements( ) ) {
var changeList:Array = new Array();
changeList.push(changement.@name);
if(("" + changement.@coordinate).length > 0){
var thisPointArray:Array = ("" + changement.@coordinate).split( ",");
var thisPoint1:Point = new Point(thisPointArray[0],thisPointArray[1]);
changeList.push(thisPoint1);
}else{
changeList.push(null);
}
_changeList.put("" + changement,changeList);
}[/color]
//加载地图
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.load(new URLRequest("images/map/stage.jpg"));
}
最终代码如下:
package com{
import flash.net.URLLoader;
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.geom.Point;
import flash.events.MouseEvent;
public class Map001 extends MovieClip {
//声明载入图片类
private var _loader:Loader = new Loader( );
//声明Bitmap
private var _image:Bitmap;
private var __image:Bitmap;
//装载地图小位图用
private var _mapList:Array= new Array();
private var _mapXmlSrc:String;
//地图图片数组
private var _map:Array= new Array();
//地形数组
private var _mapDate:Array= new Array();
//人物
private var _player:PeopleClass;
//滚屏用变量
private var _mapStartX:int = 0;
private var _mapEndX:int = 0;
private var _mapStartY:int = 0;
private var _mapEndY:int = 0;
//地图显示的起始坐标
public var _mPoint:Point;
//地图最大坐标
public var _maxX:int;
public var _maxY:int;
//人物主角图片
private var _propleImage:String;
//人物初始坐标
public var _peoplePoint:Point;
//地图画板
public var _mapFrame:MovieClip = new MovieClip();
//地图跳转信息
public var _changeList:HashMap = new HashMap();
public var _gameMap:GameStart;
public function Map001(mapXmlSrc:String,gameMap:GameStart) {
addChild(_mapFrame);
_gameMap = gameMap;
//获取地图xml文件
_mapXmlSrc = mapXmlSrc;
var loader:URLLoader = new URLLoader(new URLRequest(_mapXmlSrc));
loader.addEventListener(Event.COMPLETE,initMap);
addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
public function mouseDownHandler(evet:MouseEvent):void{
//设定光标
stage.focus = this;
}
public function initMap(evet:Event):void{
//得到xml信息
var mapXml:XML = new XML(evet.target.data);
//得到人物图片
_propleImage = mapXml.hero.Image;
//取得地图最大size
_maxX = mapXml.dataMap.@maxX;;
_maxY = mapXml.dataMap.@maxY;
//得到人物坐标信息
var peoplePoint:Point = _gameMap.getPoint();
if(peoplePoint == null){
var strPoint:String = mapXml.hero.Coordinate;
var pointArray:Array = strPoint.split( ",");
_peoplePoint = new Point(pointArray[0],pointArray[1]);
}else{
_peoplePoint = peoplePoint;
}
//计算人物坐标和显示位置
var mPointX:int = 0;
var mPointY:int = 0;
if(_peoplePoint.x > 5){
if(_peoplePoint.x + 5 <= _maxX){
mPointX = _peoplePoint.x - 5;
_peoplePoint.x = 5;
}else{
mPointX = _maxX - 10;
if(mPointX > 0){
_peoplePoint.x = _peoplePoint.x - mPointX;
}
}
}
if(_peoplePoint.y > 5){
if(_peoplePoint.y + 5 <= _maxY){
mPointY = _peoplePoint.y - 5;
_peoplePoint.y = 5;
}else{
mPointY = _maxY - 10;
if(mPointY > 0 ){
_peoplePoint.y = _peoplePoint.y - mPointY;
}
}
}
_mPoint = new Point(mPointX,mPointY);
//根据xml内容,得到地图图片数组
for each ( var element:XML in mapXml.imageMap.elements( ) ) {
var words:Array = ("" + element).split( ",");
_map.push(words);
}
//根据xml内容,得到地形数组
for each ( var datement:XML in mapXml.dataMap.elements( ) ) {
var dates:Array = ("" + datement).split( ",");
_mapDate.push(dates);
}
//根据xml内容,得到地图跳转信息
for each ( var changement:XML in mapXml.changeMap.elements( ) ) {
var changeList:Array = new Array();
changeList.push(changement.@name);
if(("" + changement.@coordinate).length > 0){
var thisPointArray:Array = ("" + changement.@coordinate).split( ",");
var thisPoint1:Point = new Point(thisPointArray[0],thisPointArray[1]);
changeList.push(thisPoint1);
}else{
changeList.push(null);
}
_changeList.put("" + changement,changeList);
}
//加载地图
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.load(new URLRequest("images/map/stage.jpg"));
}
public function onComplete(event:Event):void {
_image = Bitmap(_loader.content);
//将地图文件分解成数组
_mapList = ImageCtrl.divide(_image,10,10);
//加载人物
_player = new PeopleClass(this,_propleImage,2,4,_peoplePoint);
//绘制地图
drowMap();
//设定光标
stage.focus = this;
}
public function drowMap():void{
//地图清空
BaseRemove.removeAllChildren(_mapFrame);
//地图重绘
for(var i:int= _mPoint.y + _mapStartY;i<_mPoint.y + _mapEndY + 10;i++){
for(var j:int=_mPoint.x + _mapStartX;j<_mPoint.x + _mapEndX + 10;j++){
var index:int = _map[i][j];
var indexX:int = Math.floor(index /10);
var indexY:int = index - indexX*10;
__image = new Bitmap(_mapList[indexX][indexY]);
__image.x = (j - _mPoint.x)*48;
__image.y = (i - _mPoint.y)*48;
_mapFrame.addChild(__image);
}
}
}
//取得地形数组
public function getMapDate():Array{
return _mapDate;
}
//设定偏移
public function setCoordinate(intStartX:int = 0,intEndX:int = 0,intStartY:int = 0,intEndY:int = 0):void{
_mapStartX = intStartX;
_mapEndX = intEndX;
_mapStartY = intStartY;
_mapEndY = intEndY;
}
public function removeSelf():void{
BaseRemove.removeAllChildren(_mapFrame);
}
}
}
最后是PeopleClass.as中,在人物移动中添加跳转判断
//移动控制
private function toMove():void{
//移动达到一个坐标判断
if(_moveCtrl >= 4){
_moveCtrl =0;
//如果滚屏移动,则重绘地图
if(_mapIsRoll){
_mapBack._mapFrame.x = 0;
_mapBack._mapFrame.y = 0;
_mapBack.setCoordinate();
switch (_playDirection) {
case 0 :
_mapBack._mPoint.y -= 1;
break;
case 1 :
_mapBack._mPoint.y += 1;
break;
case 2 :
_mapBack._mPoint.x -= 1;
break;
case 3 :
_mapBack._mPoint.x += 1;
break;
}
_mapBack.drowMap();
}[color=Red]
//检测跳转
if(_mapBack._changeList.getValue(_mapPoint.x + "," + _mapPoint.y) != null){
var changeList:Object = _mapBack._changeList.getValue(_mapPoint.x + "," + _mapPoint.y);
_mapBack._gameMap.setMapName(changeList[0]);
_mapBack._gameMap.setPoint(changeList[1]);
_mapBack.removeSelf();
BaseRemove.removeAllChildren(this);
_mapBack._gameMap.selectMap();
return;
}[/color]
}
if(!_isKeyDown){
//键盘弹起状态处理
keyUpCheck();
}else{
//键盘按下状态处理
keyDownCheck();
}
}
最终代码如下:
package com{
import flash.net.URLLoader;
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.events.KeyboardEvent;
import flash.geom.Point;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class PeopleClass extends MovieClip {
//声明time函数
private var _timer:Timer;
//位图数据数组
protected var _bitmapArr:Array;
//播放的顺序 0为上 1为下 2为左 3为右
private var _playDirection:int = 1;
//当前帧显示的位图数据的索引
private var _bitmapIndex:int=0;
//图片列数
private var _row:int;
//图片行数
private var _col:int;
private var _pointer:int;
//加载图片用
private var _loader:Loader;
//读取图片用
private var _image:Bitmap;
//用以显示的bitMap对象
private var _peopleBitmap:Bitmap;
//当前地图类
private var _mapBack:Map001;
//移动步数控制
public var _moveCtrl:int = 0;
//移动步长
public var _moveLong:int = 12;
private var _isKeyDown:Boolean = false;
//人物在画面中坐标
private var _point:Point;
//人物在地图中坐标
private var _mapPoint:Point;
//滚屏控制
private var _mapIsRoll = false;
//构造器 mapBack:当前地图 player:人物图片 row:图片列数 col:图片行数
public function PeopleClass(mapBack:Map001,player:String,row:int,col:int,point:Point = null) {
_mapBack = mapBack;
_row = row;
_col = col;
if(point == null){
_point = new Point(5,5);
_mapPoint = new Point(5,5);
}else{
_point = new Point(point.x*48,point.y*48);
_mapPoint = new Point(_mapBack._mPoint.x + point.x,_mapBack._mPoint.y + point.y);
}
//初始化time;
_timer = new Timer(100);
_timer.addEventListener(TimerEvent.TIMER, timerHandler);
//图片加载对象;
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.load(new URLRequest(player));
//用来添加侦听器,侦听键盘
_mapBack.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
_mapBack.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
}
public function onComplete(event:Event):void {
_image = Bitmap(_loader.content);
//将传入的位图数据拆分成小块,装入bitmapArr
_bitmapArr=ImageCtrl.divide(_image,_row,_col);
//角色动作开始;
_timer.start();
}
//键盘事件,通过方向键更改角色移动方向;
private function keyDownHandler(event:KeyboardEvent):void {
//人物移动不够一个坐标,则返回
if(_moveCtrl > 0){
return;
}
_isKeyDown = true;
switch (event.keyCode) {
case 40 :
_playDirection = 1;
break;
case 38 :
_playDirection = 0;
break;
case 37 :
_playDirection = 2;
break;
case 39 :
_playDirection = 3;
break;
}
}
//键盘事件,
private function keyUpHandler(event:KeyboardEvent):void {
_isKeyDown = false;
}
//定时器运行事件;
private function timerHandler(event:Event):void {
//删除旧的角色动作图像;
if (_peopleBitmap != null) {
_mapBack.removeChild(_peopleBitmap);
}
//显示新的角色动作图像;
_peopleBitmap = new Bitmap(_bitmapArr[_playDirection][_pointer]);
//角色坐标
_peopleBitmap.x = _point.x;
_peopleBitmap.y = _point.y;
_mapBack.addChild(_peopleBitmap);
//角色动作循环处理;
if (_pointer < _row - 1) {
_pointer ++;
} else {
_pointer = 0;
}
//移动控制
toMove();
}
private function keyUpCheck(){
//人物移动达到一个坐标,则停止,否则继续移动
if(_moveCtrl == 0){
_mapIsRoll = false;
return;
}else{
coordinateChange();
}
}
private function keyDownCheck(){
//人物移动达到一个坐标,则进行下一个坐标的判断,否则继续移动
if(_moveCtrl == 0){
switch (_playDirection) {
case 0 :
checkUp();
break;
case 1 :
checkDown();
break;
case 2 :
checkLeft();
break;
case 3 :
checkRight();
break;
}
}else{
coordinateChange();
}
}
//移动执行
private function coordinateChange():void{
//人物移动
if(!_mapIsRoll){
switch (_playDirection) {
case 0 :
_point.y -= _moveLong;
break;
case 1 :
_point.y += _moveLong;
break;
case 2 :
_point.x -= _moveLong;
break;
case 3 :
_point.x += _moveLong;
break;
}
}else{
//滚屏移动
switch (_playDirection) {
case 0 :
_mapBack._mapFrame.y += _moveLong;
break;
case 1 :
_mapBack._mapFrame.y -= _moveLong;
break;
case 2 :
_mapBack._mapFrame.x += _moveLong;
break;
case 3 :
_mapBack._mapFrame.x -= _moveLong;
break;
}
//地图重绘
_mapBack.drowMap();
}
_moveCtrl += 1;
}
//移动控制
private function toMove():void{
//移动达到一个坐标判断
if(_moveCtrl >= 4){
_moveCtrl =0;
//如果滚屏移动,则重绘地图
if(_mapIsRoll){
_mapBack._mapFrame.x = 0;
_mapBack._mapFrame.y = 0;
_mapBack.setCoordinate();
switch (_playDirection) {
case 0 :
_mapBack._mPoint.y -= 1;
break;
case 1 :
_mapBack._mPoint.y += 1;
break;
case 2 :
_mapBack._mPoint.x -= 1;
break;
case 3 :
_mapBack._mPoint.x += 1;
break;
}
_mapBack.drowMap();
}
//检测跳转
if(_mapBack._changeList.getValue(_mapPoint.x + "," + _mapPoint.y) != null){
var changeList:Object = _mapBack._changeList.getValue(_mapPoint.x + "," + _mapPoint.y);
_mapBack._gameMap.setMapName(changeList[0]);
_mapBack._gameMap.setPoint(changeList[1]);
_mapBack.removeSelf();
BaseRemove.removeAllChildren(this);
_mapBack._gameMap.selectMap();
return;
}
}
if(!_isKeyDown){
//键盘弹起状态处理
keyUpCheck();
}else{
//键盘按下状态处理
keyDownCheck();
}
}
//右移判断
private function checkRight():void{
if(checkMap(_mapPoint.x + 1,_mapPoint.y)){
//是否滚屏移动
if(_point.x >= 240 && _mapBack._mPoint.x < _mapBack._maxX - 10){
_mapBack.setCoordinate(0,1);
_mapBack._mapFrame.x -= _moveLong;
_mapBack.drowMap();
_mapIsRoll = true;
}else{;
_mapIsRoll = false;
_point.x += _moveLong;
}
_moveCtrl += 1;
_mapPoint.x += 1
}
}
//左移判断
private function checkLeft():void{
if(checkMap(_mapPoint.x - 1,_mapPoint.y)){
//是否滚屏移动
if(_point.x <= 192 && _mapBack._mPoint.x > 0){
_mapBack.setCoordinate(-1,0);
_mapBack._mapFrame.x += _moveLong;
_mapBack.drowMap();
_mapIsRoll = true;
}else{
_mapIsRoll = false;
_point.x -= _moveLong;
}
_mapPoint.x -= 1;
_moveCtrl += 1;
}
}
//下移判断
private function checkDown():void{
if(checkMap(_mapPoint.x, _mapPoint.y + 1)){
//是否滚屏移动
if(_point.y >= 240 && _mapBack._mPoint.y< _mapBack._maxY - 10){
_mapBack.setCoordinate(0,0,0,1);
_mapBack._mapFrame.y -= _moveLong;
_mapBack.drowMap();
_mapIsRoll = true;
}else{
_mapIsRoll = false;
_point.y += _moveLong;
}
_mapPoint.y += 1;
_moveCtrl += 1;
}
}
//上移判断
private function checkUp():void{
if(checkMap(_mapPoint.x,_mapPoint.y - 1)){
//是否滚屏移动
if(_point.y <= 192 && _mapBack._mPoint.y > 0){
_mapBack.setCoordinate(0,0,-1,0);
_mapBack._mapFrame.y += _moveLong;
_mapBack.drowMap();
_mapIsRoll = true;
}else{
_mapIsRoll = false;
_point.y -= _moveLong;
}
_mapPoint.y -= 1;
_moveCtrl += 1;
}
}
//障碍判断
private function checkMap(mapX:int,mapY:int):Boolean{
var mapDate:Array = _mapBack.getMapDate();
if(mapDate[mapY][mapX] == 0){
return true;
}else{
return false;
}
}
}
}
最后,做一个仿HashMap类,HashMap.as
package com
{
import flash.utils.Dictionary;
public class HashMap
{
private var _keys:Array=null;
private var props:Dictionary=null;
public function HashMap() {
this.clear();
}
public function clear():void {
this.props=new Dictionary ;
this._keys=new Array ;
}
public function containsKey(key:Object):Boolean {
return this.props[key]!=null;
}
public function containsValue(value:Object):Boolean {
var result:Boolean=false;
var len:uint=this.size();
if (len>0) {
for (var i:uint=0; i<len; i++) {
if (this.props[this._keys[i]]==value) {
result = true;
break;
}
}
}
return result;
}
public function getValue(key:Object):Object {
return this.props[key];
}
public function put(key:Object,value:Object):Object {
var result:Object=null;
if (this.containsKey(key)) {
result=this.getValue(key);
this.props[key]=value;
} else {
this.props[key]=value;
this._keys.push(key);
}
return result;
}
public function remove(key:Object):Object {
var result:Object=null;
if (this.containsKey(key)) {
delete this.props[key];
var index:int=this._keys.indexOf(key);
if (index>-1) {
this._keys.splice(index,1);
}
}
return result;
}
public function putAll(map:HashMap):void {
this.clear();
var len:uint=map.size();
if (len>0) {
var arr:Array=map.keys();
for (var i:uint=0; i<len; i++) {
this.put(arr[i],map.getValue(arr[i]));
}
}
}
public function size():uint {
return this._keys.length;
}
public function isEmpty():Boolean {
return this.size() <1;
}
public function values():Array {
var result:Array=new Array ;
var len:uint=this.size();
if (len>0) {
for (var i:uint=0; i<len; i++) {
result.push(this.props[this._keys[i]]);
}
}
return result;
}
public function keys():Array {
return this._keys;
}
}
}
然后,Ctrl + 回车,看下运行结果
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/flash1-1.jpg?t=1259390104[/img]
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/flash2-2.jpg?t=1259390131[/img]
这样,就实现了地图的跳转了,
下次,该让NPC人物出场了,哈
[color=Silver][[i] 本帖最后由 lufy 于 2009-11-28 15:14 编辑 [/i]][/color]
2009-12-1 19:37
lufy
轮到npc的添加了,
先来做准备工作
在xml中添加NPC的相应节点
<?xml version="1.0" encoding="GB2312"?>
<data>
<imageMap>
<list>18,18,18,18,18,18,18,18,18,18,18,18,55,55,18</list>
<list>18,18,18,17,17,17,17,17,17,17,17,17,55,55,18</list>
<list>18,18,17,17,17,17,18,18,17,17,17,17,55,55,18</list>
<list>18,17,17,17,18,18,18,18,18,17,17,55,55,17,18</list>
<list>18,17,17,18,22,23,23,23,24,18,17,55,55,17,18</list>
<list>18,17,17,18,25,28,26,79,27,18,55,55,17,17,18</list>
<list>18,17,17,17,17,10,11,12,18,18,55,55,17,17,18</list>
<list>18,17,17,17,17,77,16,78,18,18,55,55,17,17,18</list>
<list>18,17,17,17,17,77,16,78,17,55,55,17,17,17,18</list>
<list>18,18,17,17,10,16,16,16,11,55,55,17,17,17,18</list>
<list>18,18,17,17,77,16,16,16,16,21,21,17,17,17,18</list>
<list>18,18,17,17,13,14,14,14,15,55,55,17,17,17,18</list>
<list>18,18,17,17,55,55,55,55,55,55,55,17,17,18,18</list>
<list>18,18,17,17,55,55,55,55,55,55,55,17,18,18,18</list>
<list>18,18,55,55,55,55,55,55,55,55,55,18,18,18,18</list>
</imageMap>
<dataMap maxX="15" maxY="15">
<list>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</list>
<list>1,1,1,0,0,0,0,0,0,0,0,0,1,1,1</list>
<list>1,1,0,0,0,0,1,1,0,0,0,0,1,1,1</list>
<list>1,0,0,0,1,1,1,1,1,0,0,1,1,0,1</list>
<list>1,0,0,1,1,1,1,1,1,1,0,1,1,0,1</list>
<list>1,0,0,1,1,1,0,1,1,1,1,1,0,0,1</list>
<list>1,0,0,0,0,0,0,0,1,1,1,1,0,0,1</list>
<list>1,0,0,0,0,0,0,0,1,1,1,1,0,0,1</list>
<list>1,0,0,0,0,0,0,0,0,1,1,0,0,0,1</list>
<list>1,1,0,0,0,0,0,0,0,1,1,0,0,0,1</list>
<list>1,1,0,0,0,0,0,0,0,0,0,0,0,0,1</list>
<list>1,1,0,0,0,0,0,0,0,1,1,0,0,0,1</list>
<list>1,1,0,0,1,1,1,1,1,1,1,0,0,1,1</list>
<list>1,1,0,0,1,1,1,1,1,1,1,0,1,1,1</list>
<list>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</list>
</dataMap>
<hero>
<Name>刘备</Name>
<Image>images/player/liubei.gif</Image>
<Coordinate>11,10</Coordinate>
</hero>[color=Red]
<npc>
<list name="zhangfei" coordinate="4,6" move="true">images/player/zhangfei.gif</list>
<list name="guanyu" coordinate="11,9" move="true">images/player/guanyu.gif</list>
</npc>[/color]
<changeMap>
<list name="map002" coordinate="5,9">6,5</list>
</changeMap>
</data>
npc节点中,name关联着对话,这个后面说,coordinate是npc出现的坐标,move代表是否可在地图中随意移动。
好了,下面把PeopleClass.as代码copy一下,建立一个NpcClass.as,共同代码比较多,所以应该做一个父类的,这个后面再整理
NpcClass.as代码如下,
package com{
import flash.net.URLLoader;
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.events.KeyboardEvent;
import flash.geom.Point;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class NpcClass extends MovieClip {
//声明time函数
private var _timer:Timer;
//位图数据数组
protected var _bitmapArr:Array;
//播放的顺序 0为上 1为下 2为左 3为右
private var _playDirection:int = 1;
//当前帧显示的位图数据的索引
private var _bitmapIndex:int=0;
//图片列数
private var _row:int;
//图片行数
private var _col:int;
private var _pointer:int;
//加载图片用
private var _loader:Loader;
//读取图片用
private var _image:Bitmap;
//用以显示的bitMap对象
private var _peopleBitmap:Bitmap;
//当前地图类
private var _mapBack:Map001;
//移动步数控制
public var _moveCtrl:int = 0;
//移动步长
public var _moveLong:int = 12;
private var _isKeyDown:Boolean = false;
//NPC在地图中坐标
private var _mapPoint:Point;
//滚屏控制
private var _mapIsRoll = false;
//NPC是否可移动
private var _canMove:Boolean = false;
//NPC是否已显示
private var _isAdd = false;
public var _npcName:String;
//构造器 mapBack:当前地图 player:NPC图片 npcName:NPC名称 row:图片列数 col:图片行数
public function NpcClass(mapBack:Map001,player:String,npcName:String,row:int,col:int,point:Point = null,timer:Timer=null,canMove:Boolean = false) {
//初始化
_mapBack = mapBack;
_npcName = npcName;
_row = row;
_col = col;
_canMove = canMove;
_mapPoint = point;
_timer = timer;
_timer.addEventListener(TimerEvent.TIMER, timerHandler);
//图片加载对象;
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.load(new URLRequest(player));
}
public function onComplete(event:Event):void {
_image = Bitmap(_loader.content);
//将传入的位图数据拆分成小块,装入bitmapArr
_bitmapArr=ImageCtrl.divide(_image,_row,_col);
//NPC动作开始;
_timer.start();
}
//获得NPC名称
public function getName():String{
return _npcName;
}
public function drowNpc():void{
//删除旧的NPC动作图像;
if (_peopleBitmap != null && _isAdd) {
_mapBack._npcFrame.removeChild(_peopleBitmap);
}
//显示新的NPC动作图像;
_peopleBitmap = new Bitmap(_bitmapArr[_playDirection][_pointer]);
//NPC坐标计算
_peopleBitmap.x = (_mapPoint.x - _mapBack._mPoint.x)*48;
_peopleBitmap.y = (_mapPoint.y - _mapBack._mPoint.y)*48;
if(_moveCtrl > 0){
switch (_playDirection) {
case 0 :
_peopleBitmap.y = _peopleBitmap.y + 48 - _moveCtrl*12;
break;
case 1 :
_peopleBitmap.y = _peopleBitmap.y - 48 + _moveCtrl*12;
break;
case 2 :
_peopleBitmap.x = _peopleBitmap.x + 48 - _moveCtrl*12;
break;
case 3 :
_peopleBitmap.x = _peopleBitmap.x - 48 + _moveCtrl*12;
break;
}
}
if(_mapPoint.x - _mapBack._mPoint.x >= 0 && _mapPoint.x - _mapBack._mPoint.x < 11
&& _mapPoint.y - _mapBack._mPoint.y >= 0 && _mapPoint.y - _mapBack._mPoint.y < 11){
_mapBack._npcFrame.addChild(_peopleBitmap);
_isAdd = true;
}else{
_isAdd = false;
}
//NPC动作循环处理;
if (_pointer < _row - 1) {
_pointer ++;
} else {
_pointer = 0;
}
}
//定时器运行事件;
private function timerHandler(event:Event):void {
drowNpc();
//移动控制
toMove();
}
//移动
private function toMove():void{
if(!_canMove){
return;
}
//移动达到一个坐标判断
if(_moveCtrl >= 4 || _moveCtrl == 0){
_moveCtrl =0;
toCheckMove();
}else{
_moveCtrl += 1;
}
}
//键盘事件,通过方向键更改角色移动方向;
private function toCheckMove():void {
var intRand:int = Math.floor(Math.random()*15);
if(intRand < 4){
_playDirection = intRand;
switch (_playDirection) {
case 0 :
checkUp();
break;
case 1 :
checkDown();
break;
case 2 :
checkLeft();
break;
case 3 :
checkRight();
break;
}
}
}
//坐标随NPC移动
private function npcChange(npcX:int,npcY:int):void{
_mapBack._npcList.remove(_mapPoint.x + "," + _mapPoint.y);
_mapBack._npcList.put((_mapPoint.x + npcX )+ "," + (_mapPoint.y + npcY),this);
}
//右移判断
private function checkRight():void{
if(checkMap(_mapPoint.x + 1,_mapPoint.y)){
npcChange(1,0);
_mapPoint.x += 1
_moveCtrl += 1;
}
}
//左移判断
private function checkLeft():void{
if(checkMap(_mapPoint.x - 1,_mapPoint.y)){
npcChange(-1,0);
_mapPoint.x -= 1;
_moveCtrl += 1;
}
}
//下移判断
private function checkDown():void{
if(checkMap(_mapPoint.x, _mapPoint.y + 1)){
npcChange(0,1);
_mapPoint.y += 1;
_moveCtrl += 1;
}
}
//上移判断
private function checkUp():void{
if(checkMap(_mapPoint.x,_mapPoint.y - 1)){
npcChange(0,-1);
_mapPoint.y -= 1;
_moveCtrl += 1;
}
}
//障碍判断
private function checkMap(mapX:int,mapY:int):Boolean{
var mapDate:Array = _mapBack.getMapDate();
if(mapDate[ mapY][mapX] == 0){
if(_mapBack._npcList.getValue(mapX + "," + mapY) == null && !_mapBack.isPlayer(mapX,mapY)){
return true;
}else{
return false;
}
}else{
return false;
}
}
}
}
当然,Map001.as中,npc是必须要添加的:
//根据xml内容,得到NPC人物
for each ( var npcment:XML in mapXml.npc.elements( ) ) {
var npcPoint:Array = ("" + npcment.@coordinate).split( ",");
var npcMove:Boolean = ("" + npcment.@move) == "true"?true:false;
var npc:NpcClass = new NpcClass(this,"" + npcment,"" + npcment.@name,2,4,new Point(npcPoint[0],npcPoint[1]),_timer,npcMove);
_npcList.put(npcPoint[0] + "," + npcPoint[1],npc);
}
PeopleClass.as中,在滚屏的时候,必须得处理一下,否则,npc乱跳
//移动控制
private function toMove():void{
//移动达到一个坐标判断
if(_moveCtrl >= 4){
_moveCtrl =0;
//如果滚屏移动,则重绘地图
if(_mapIsRoll){
_mapBack._mapFrame.x = 0;
_mapBack._mapFrame.y = 0;
_mapBack.setCoordinate();
switch (_playDirection) {
case 0 :
_mapBack._mPoint.y -= 1;
break;
case 1 :
_mapBack._mPoint.y += 1;
break;
case 2 :
_mapBack._mPoint.x -= 1;
break;
case 3 :
_mapBack._mPoint.x += 1;
break;
}
_mapBack._npcFrame.x = 0;
_mapBack._npcFrame.y = 0;
for each ( var npc:NpcClass in _mapBack._npcList.values() ) {
npc.drowNpc();
}
_mapBack.drowMap();
}
//检测跳转
if(_mapBack._changeList.getValue(_mapPoint.x + "," + _mapPoint.y) != null){
var changeList:Object = _mapBack._changeList.getValue(_mapPoint.x + "," + _mapPoint.y);
_mapBack._gameMap.setMapName(changeList[0]);
_mapBack._gameMap.setPoint(changeList[1]);
_mapBack.removeSelf();
BaseRemove.removeAllChildren(this);
_mapBack._gameMap.selectMap();
return;
}
}
if(!_isKeyDown){
//键盘弹起状态处理
keyUpCheck();
}else{
//键盘按下状态处理
keyDownCheck();
}
}
看吧,npc就这么加进去了,想多加几个的话,只需要在xml中添加几个节点就好了
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/npc.gif?t=1259667401[/img]
下面,来添加对话..
[color=Silver][[i] 本帖最后由 lufy 于 2009-12-1 19:38 编辑 [/i]][/color]
2009-12-1 19:55
lufy
添加对话的准备工作,
首先,还是xml
xml名称对应上次npc节点中的name
zhangfei.xml
<?xml version="1.0" encoding="GB2312"?>
<data>
<talk rand="false">
<list image="images/face/zhangfei.gif" name="张飞">某姓张名飞,字翼德。世居涿郡,颇有庄田,卖酒屠猪,专好结交天下豪杰。恰才见公看榜而叹,故此相问。</list>
<list image="images/face/liubei.gif" name="刘备">我本汉室宗亲,姓刘,名备。今闻黄巾倡乱,有志欲破贼安民,恨力不能,故长叹耳。</list>
<list image="images/face/zhangfei.gif" name="张飞">吾颇有资财,当招募乡勇,与公同举大事,如何?</list>
</talk>
</data>
在flash中添加三个场景MC,其实也可以做一个类,我比较懒,就用懒人的方法了
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/s01.gif?t=1259667639[/img]
然后,将里面的face和talk_background,托拽到talk_mc当中
修改相应属性,并添加两个text框,来显示姓名和对话内容
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/s02.gif?t=1259667749[/img]
然后准备自己需要的头像,放在images/face/文件夹下
准备工作结束,下面新建一个Talk.as类
代码如下
package com{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.KeyboardEvent;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
public class Talk extends MovieClip {
private var _tar:MovieClip;
private var _talkStr:String;
private var _temp_str:String;
private var _my_talk:MovieClip;
private var _down_fun:Object;
private var _now_index:uint;
private var _total_index:uint;
private var _my_timer:Timer;
private var _loader:Loader = new Loader( );
private var _image:Bitmap;
private var _bitmap:BitmapData;
private var _array:Array;
public function Talk(tar:MovieClip) {
_tar=tar;
}
public function newTalk(array:Array) {
_array = array;
_down_fun=array[3];
_my_talk=new talk_mc();
_my_talk.name_txt.text=array[1];
if(_tar.getPlayer()._peopleName == array[1]){
_my_talk.x=0;
_my_talk.y=300;
}else{
_my_talk.x=0;
_my_talk.y=30;
}
_talkStr=array[2];
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.load(new URLRequest(array[0]));
_my_timer=new Timer(50);
_now_index=0;
_total_index=_talkStr.length;
_my_timer.addEventListener(TimerEvent.TIMER,_my_timer_fun);
_tar.addEventListener(KeyboardEvent.KEY_DOWN, my_md_key);
_my_timer.start();
return _my_talk;
}
public function onComplete(event:Event):void {
_image = Bitmap(_loader.content);
_bitmap = _image.bitmapData;
_my_talk.face.addChild(_image);
_tar.addChild(_my_talk);
}
private function my_md_key(eve:KeyboardEvent) {
if (_now_index<_total_index) {
_now_index=_total_index;
_my_talk.show_txt.text=_talkStr;
} else {
_tar.removeChild(_my_talk);
_loader = new Loader( );
_my_talk=null;
_my_timer.stop();
_down_fun();
}
}
public function removeKeyDown():void{
_tar.removeEventListener(KeyboardEvent.KEY_DOWN, my_md_key);
}
private function _my_timer_fun(eve:TimerEvent) {
if (_now_index<_total_index) {
_now_index++;
_temp_str=_talkStr.substr(0,_now_index);
_my_talk.show_txt.text=_temp_str;
} else {
_my_timer.stop();
}
}
public function getTar(){
return _tar;
}
}
}
然后,主要是修改PeopleClass.as中的代码
现在把工程上传,里面都写了详细的注释,很容易明白,有兴趣的朋友可以下载看一下,
代码没多少,主要是几张图片占地方
效果如图
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/talk01.gif?t=1259668061[/img]
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/talk02.gif?t=1259668081[/img]
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/talk03.gif?t=1259668109[/img]
暂时告一段落了,有时间了再慢慢研究战斗系统B)
[color=Silver][[i] 本帖最后由 lufy 于 2009-12-1 20:00 编辑 [/i]][/color]
2009-12-3 16:31
lufy
看到赵辉的帖子里的寻路,自己也手痒了起来,记得以前在网上看过一个A*算法,根据记忆,依葫芦画瓢了
A*算法寻路代码如下
RoadQuery.as
package com
{
import flash.geom.Point;
public class RoadQuery
{
private var _map:Array;//地图
private var _w:int;//地图的宽
private var _h:int;//地图的高
private var _open:Array;//开放列表
private var _aveOpen:Number;//开放列表平均值
private var _starPoint:Object;
private var _endPoint:Object;
private var _path:Array = [];//计算出的路径
public function RoadQuery(map:Array) {
_map = [];
_w = map[0].length;
_h = map.length;
for (var y:int=0; y<_h; y++) {
if (_map[y]==undefined) {
_map[y] = [];
}
for (var x:int=0; x<_w; x++) {
_map[y][x] = {x:x, y:y, value:map[y][x], isChecked:false, open:false, value_g:0, value_h:0, value_f:0, nodeparent:null, index:-1};
}
}
}
//寻路
public function path4(star:Point, end:Point):Array {
_path = [];
_starPoint = _map[star.y][star.x];
_endPoint = _map[end.y][end.x];
var isOver:Boolean = false;
setStart();
var thisPoint:Object = _starPoint;
while (!isOver) {
thisPoint.isChecked = true;
var checkList:Array = [];
//获取周围四个点
if (thisPoint.y>0) {
checkList.push(_map[(thisPoint.y-1)][thisPoint.x]);
}
if (thisPoint.x>0) {
checkList.push(_map[thisPoint.y][(thisPoint.x-1)]);
}
if (thisPoint.x<_w-1) {
checkList.push(_map[thisPoint.y][(thisPoint.x+1)]);
}
if (thisPoint.y<_h-1) {
checkList.push(_map[(thisPoint.y+1)][thisPoint.x]);
}
//检测开始
var startIndex:int = checkList.length;
for (var i:int = 0; i<startIndex; i++) {
//周围的每一个节点
var checkPoint:Object = checkList[i];
if(_map[checkPoint.y][checkPoint.x].value==0){
//如果可通过,则先判断是否是指定地点,否则开始计算
if (checkPoint == _endPoint) {
checkPoint.nodeparent = thisPoint;
isOver = true;
break;
}
count(checkPoint, thisPoint);
}
}
if (!isOver) {
//如果未到达指定地点则取出f值最小的点作为循环点
if (_open.length>0) {
thisPoint = getOpen();
} else {
//开发列表为空,寻路失败
return [];
}
}
}
//画路径
var pathPoint:Object = _endPoint;
while (pathPoint != _starPoint) {
_path.unshift(new Point(pathPoint.x, pathPoint.y));
pathPoint = pathPoint.nodeparent;
}
_path.unshift(new Point(pathPoint.x, pathPoint.y));
return _path;
}
//寻路前的初始化
private function setStart():void {
for (var y:int=0; y<_h; y++) {
for (var x:int=0; x<_w; x++) {
_map[y][x].open = false;
_map[y][x].isChecked = false;
_map[y][x].value_g = 0;
_map[y][x].value_h = 0;
_map[y][x].value_f = 0;
_map[y][x].nodeparent = null;
_map[y][x].index = -1;
}
}
_open = [];
_aveOpen = 0;
}
//计算每个节点
private function count(neighboringNode:Object, centerNode:Object):void {
//是否已经检测过
if (!neighboringNode.isChecked) {
//不在关闭列表里才开始判断
var g:Number= centerNode.value_g+10;
if (neighboringNode.open) {
//如果该节点已经在开放列表里
if (neighboringNode.value_g>=g) {
//如果新G值小于或者等于旧值,则表明该路更优,更新其值
_aveOpen += (_aveOpen-neighboringNode.value_f)/_open.length;
var thisIndex:int = _open.indexOf(neighboringNode);
_open.splice(thisIndex,1);
neighboringNode.value_g = g;
ghf(neighboringNode);
neighboringNode.nodeparent = centerNode;
setOpen(neighboringNode);
}
} else {
//如果该节点未在开放列表里
//计算GHF值
neighboringNode.value_g = g;
ghf(neighboringNode);
neighboringNode.nodeparent = centerNode;
//添加至列表
setOpen(neighboringNode);
}
}
}
//计算ghf各值
private function ghf(node:Object):void {
var dx:Number = Math.abs(node.x-_endPoint.x);
var dy:Number = Math.abs(node.y-_endPoint.y);
node.value_h = 10*(dx+dy);
node.value_f = node.value_g+node.value_h;
}
//加入开放列表
private function setOpen(newNode:Object):void {
newNode.open = true;
var startIndex:int = _open.length;
if (startIndex==0) {
_open.push(newNode);
_aveOpen = newNode.value_f;
} else {
if (newNode.value_f<_aveOpen) {
for (var i:int=0; i<startIndex; i++) {
if (newNode.value_f<=_open[i].value_f) {
_open.splice(i, 0, newNode);
break;
}
}
} else {
for (var j:int=startIndex; j>0; j--) {
if (newNode.value_f>=_open[(j-1)].value_f) {
_open.splice(j, 0, newNode);
break;
}
}
}
_aveOpen += (newNode.value_f-_aveOpen)/_open.length;
}
}
//取开放列表里
private function getOpen():Object {
var __next:Object = _open.splice(0,1)[0];
_aveOpen += (_aveOpen-__next.value_f)/_open.length;
return __next;
}
public function value(px:int, py:int):int
{
return _map[py][px].value;
}
}
}
既然用了鼠标寻路,我目前的游戏的走路方式等就需要修改了,但是为了省事,直接添加几行代码暂且了事!
地图:
<?xml version="1.0" encoding="GB2312"?>
<data>
<imageMap>
<list>18,18,18,18,18,18,18,18,18,18</list>
<list>18,17,17,17,17,17,17,17,17,18</list>
<list>18,17,17,18,18,18,18,18,17,18</list>
<list>18,17,17,18,17,17,17,18,17,18</list>
<list>18,17,17,18,17,18,18,18,17,18</list>
<list>18,17,17,18,17,17,17,18,17,18</list>
<list>18,17,17,18,18,18,17,18,17,18</list>
<list>18,17,17,17,17,17,17,17,17,18</list>
<list>18,17,17,17,17,17,17,17,17,18</list>
<list>18,18,18,18,18,18,18,18,18,18</list>
</imageMap>
<dataMap maxX="10" maxY="10">
<list>1,1,1,1,1,1,1,1,1,1</list>
<list>1,0,0,0,0,0,0,0,0,1</list>
<list>1,0,0,1,1,1,1,1,0,1</list>
<list>1,0,0,1,0,0,0,1,0,1</list>
<list>1,0,0,1,0,1,1,1,0,1</list>
<list>1,0,0,1,0,0,0,1,0,1</list>
<list>1,0,0,1,1,1,0,1,0,1</list>
<list>1,0,0,0,0,0,0,0,0,1</list>
<list>1,0,0,0,0,0,0,0,0,1</list>
<list>1,1,1,1,1,1,1,1,1,1</list>
</dataMap>
<hero>
<Name>刘备</Name>
<Image>images/player/liubei.gif</Image>
<Coordinate>1,1</Coordinate>
</hero>
<npc />
<changeMap />
</data>
Map001.as中添加鼠标事件
//鼠标点击事件
addEventListener(MouseEvent.CLICK,onClick);
public function onClick(event:Event):void{
var __mouseX:int = event.currentTarget.mouseX;
var __mouseY:int = event.currentTarget.mouseY;
_player._moveToX = _mPoint.x + Math.floor(__mouseX/48);
_player._moveToY = _mPoint.y + Math.floor(__mouseY/48);
_player.getRoad();
}
PeopleClass.as中添加
public function getRoad(){
_roadArray = _mapBack._roadQuery.path4(_mapPoint,new Point(_moveToX,_moveToY));
}
定时器运行事件中添加
//定时器运行事件;
private function timerHandler(event:Event):void {
//删除旧的角色动作图像;
if (_peopleBitmap != null) {
_mapBack.removeChild(_peopleBitmap);
} [color=Magenta]
if(_roadArray != null){
_isKeyDown = true;
if(_moveCtrl == 0 || _moveCtrl >= 4){
if(_roadArray[0].x == _roadArray[1].x){
if(_roadArray[0].y > _roadArray[1].y){
_playDirection =0;
}else{
_playDirection = 1;
}
}else{
if(_roadArray[0].x > _roadArray[1].x){
_playDirection =2;
}else{
_playDirection = 3;
}
}
_roadArray.splice(0,1);
}
}[/color]
//显示新的角色动作图像;
_peopleBitmap = new Bitmap(_bitmapArr[_playDirection][_pointer]);
//角色坐标
_peopleBitmap.x = _point.x;
_peopleBitmap.y = _point.y;
_mapBack.addChild(_peopleBitmap);
//角色动作循环处理;
if (_pointer < _row - 1) {
_pointer ++;
} else {
_pointer = 0;
}
//移动控制
toMove();
}
下面运行,看效果:
2009-12-22 10:00
Maxwell
进来支持一下楼主的普及帖。希望楼主继续发帖,多介绍一些flash开发方面的内容。
2010-5-17 18:17
lufy
最近在公司干活又有些无聊了,然后就继续研究flash游戏制作了,接着以前的代码,继续制作战场画面
首先,先来个几个大改动,为了使得代码更方便修改和阅读,将各个类文件分类,如图所视
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/flashview.jpg?t=1274087755[/img]
然后,对地图显示和滚屏稍作修改,显示更流畅化,具体修改Map001中如下两个方法
public function onComplete(event:Event):void {
_image = Bitmap(_loader.content);
//_mapFrame.addChild(_image);
//将地图文件分解成数组
_mapList = ImageCtrl.divide(_image,10,10);
//加载人物
_player = new PeopleClass(this,_propleImage,_peopleName,2,4,_peoplePoint,_timer);
//绘制地图
//在_listBitmap数组中装载12x12个图片Bitmap,用来滚动显示地图
for(var i:int= -1;i<11;i++){
var listChild:Array = new Array();
for(var j:int=-1;j<11;j++){
if(_mPoint.y + i < 0 || _mPoint.y + i >= _map.length || _mPoint.x + j < 0 || _mPoint.x + j >= _map[0].length){
__image = new Bitmap();
__image.x = j*48;
__image.y = i*48;
_mapFloor.addChild(__image);
}else{
var index:int = _map[ _mPoint.y + i][_mPoint.x + j];
var indexX:int = Math.floor(index /10);
var indexY:int = index - indexX*10;
__image = new Bitmap(_mapList[indexX][indexY]);
__image.x = j*48;
__image.y = i*48;
_mapFloor.addChild(__image);
}
listChild.push(__image);
}
_listBitmap.push(listChild);
}
//设定光标
stage.focus = this;
}
//重载bitmapData来滚动显示地图
public function drowMap(playDirection:int):void{
var listChild:Array;
var i:int;
var index:int;
var indexX:int;
var indexY:int;
switch (playDirection) {
case 0 :
//向下滚动地图
listChild = _listBitmap[11];
_listBitmap.pop();
for(i= -1;i<11;i++){
listChild[i + 1].y -= 576;
if(_mPoint.y - 1< 0 || _mPoint.x + i < 0 || _mPoint.x + i >= _map[0].length){
listChild[i + 1].bitmapData = null;
}else{
index = _map[ _mPoint.y - 1][_mPoint.x + i];
indexX = Math.floor(index /10);
indexY = index - indexX*10;
listChild[i + 1].bitmapData = _mapList[indexX][indexY];
}
}
_listBitmap.unshift(listChild);
break;
case 1 :
//向上滚动地图
listChild = _listBitmap[0];
_listBitmap.shift();
for(i= -1;i<11;i++){
listChild[i + 1].y += 576;
if(_mPoint.y + 10 >= _map.length || _mPoint.x + i < 0 || _mPoint.x + i >= _map[0].length){
listChild[i + 1].bitmapData = null;
}else{
index = _map[ _mPoint.y + 10][_mPoint.x + i];
indexX = Math.floor(index /10);
indexY = index - indexX*10;
listChild[i + 1].bitmapData = _mapList[indexX][indexY];
}
}
_listBitmap.push(listChild);
break;
case 2 :
//向右滚动地图
for(i= -1;i<11;i++){
__image = _listBitmap[i + 1][11];
_listBitmap[i + 1].pop();
__image.x -= 576;
if(_mPoint.y + i< 0 || _mPoint.y + i >= _map.length || _mPoint.x - 1 < 0){
__image.bitmapData = null;
}else{
index = _map[ _mPoint.y + i][_mPoint.x - 1];
indexX = Math.floor(index /10);
indexY = index - indexX*10;
__image.bitmapData = _mapList[indexX][indexY];
}
_listBitmap[i + 1].unshift(__image);
}
break;
case 3 :
//向左滚动地图
for(i= -1;i<11;i++){
__image = _listBitmap[i + 1][0];
_listBitmap[i + 1].shift();
__image.x += 576;
if(_mPoint.y + i< 0 || _mPoint.y + i >= _map.length || _mPoint.x - 1 < 0){
__image.bitmapData = null;
}else{
index = _map[ _mPoint.y + i][_mPoint.x + 10];
indexX = Math.floor(index /10);
indexY = index - indexX*10;
__image.bitmapData = _mapList[indexX][indexY];
}
_listBitmap[i + 1].push(__image);
}
break;
}
}
主角显示类中解析游戏脚本文件(算是简单的游戏脚本吧)
目前只做了对话事件,战斗事件,设定变量事件,条件事件四个事件的解析
分别对应脚本文件中的talk,att,set,if
具体看下面代码,每个时间结束后,都继续执行剩下的事件,直到事件为空,则停止
//获取事件
private function getXml(xml:XML):void{
var xmlarr:Array = new Array();
for each ( var element:XML in xml.elements( ) ) {
xmlarr.push(element);
}
setEvent(xmlarr);
}
/*
*游戏脚本解析*
每个游戏,或者有自己特定的脚本,或者用共同的脚本
这里的xml处理或许可以称作一个简单的游戏脚本吧
获取事件类型,进入事件 目前只有对话,战斗,设定变量和选择四种事件
若要添加更多的事件解析,如行走,动作等,则在此添加,然后修改事件xml
*/
private function setEvent(xmlarr:Array):void{
if(xmlarr.length == 0){
return;
}
var index:int;
var varlable_name:String;
var varlable_value:int;
var ele:XML = xmlarr[0];
if(ele.name() == "talk"){
//对话事件
xmlarr.shift();
getTalkXml(ele,xmlarr);
}else if(ele.name() == "att"){
//战斗事件
xmlarr.shift();
getAttXml(ele,xmlarr);
}else if(ele.name() == "set"){
//设定变量事件
varlable_name = "save" + ele.@varlable_name;
varlable_value = int(ele.@varlable_value);
Sav.gamedata[varlable_name] = varlable_value;
xmlarr.shift();
setEvent(xmlarr);
}else if(ele.name() == "if"){
//条件事件
index = 0;
var eleif:XML;
varlable_name = "save" + ele.@varlable_name;
varlable_value = int(ele.@varlable_value);
if(Sav.gamedata[varlable_name] == varlable_value){
xmlarr.shift();
for each ( eleif in ele["true"].elements( ) ) {
xmlarr.splice(index++, 0,eleif);
}
setEvent(xmlarr);
}else{
xmlarr.shift();
for each ( eleif in ele["false"].elements( ) ) {
xmlarr.splice(index++, 0,eleif);
}
setEvent(xmlarr);
}
}
}
//战斗事件运行
private function getAttXml(xml:XML,xmlarr:Array):void{
var fun:Function = function(){
setEvent(xmlarr);
}
_mapBack._gameMap.fightStart(xml.toString(),fun);
}
//对话事件运行
private function getTalkXml(xml:XML,xmlarr:Array):void{
//根据xml内容,得到地图图片数组
var talkArray:Array = new Array();
for each ( var elementTalk:XML in xml.elements( ) ) {
var thisTalk = [elementTalk.@image,elementTalk.@name," "+elementTalk];
talkArray.push(thisTalk);
}
if(("" + xml.@rand) == "false"){
//顺序对话
setTalk(talkArray);
(talkArray[talkArray.length - 1])[3]=function (){
_mapBack._is_talked=false;
_my_talk.removeKeyDown();
setEvent(xmlarr);
};
if (!_mapBack._is_talked) {
_mapBack._is_talked=true;
_my_talk.newTalk(talkArray[0]);
}
}else{
//随即对话
var _talk_npc_random=talkArray[int(Math.random()*talkArray.length)];
_talk_npc_random[3]=function(){
_mapBack._is_talked=false;
_my_talk.removeKeyDown();
setEvent(xmlarr);
};
if (!_mapBack._is_talked) {
_mapBack._is_talked=true;
_my_talk.newTalk(_talk_npc_random);
}
}
}
//对话显示处理
private function setTalk(talkArray:Array):void{
if(talkArray.length > 0){
(talkArray[0])[3]=function (){
_my_talk.newTalk(talkArray[1]);
};
}else{
return;
}
if(talkArray.length > 1){
(talkArray[1])[3]=function (){
_my_talk.newTalk(talkArray[2]);
};
}else{
return;
}
if(talkArray.length > 2){
(talkArray[2])[3]=function (){
_my_talk.newTalk(talkArray[3]);
};
}else{
return;
}
}
另外,NPC显示类和其他几个文件都有些小改动,具体看源文件,就不罗嗦了
2010-5-17 18:18
lufy
好了,下面开始添加战场画面
首先准备各个人物的攻击图片,和战斗背景图片等
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/guanyuatt.gif?t=1274088828[/img]
然后,添加人物动作控制类CharacterMC,用来控制人物的攻击,受攻击等动作,还有HP的显示等等
package com.npc {
import com.ot.ImageCtrl;
import com.ot.FightMap;
import flash.events.Event;
import flash.display.Sprite;
import flash.display.Loader;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.net.URLRequest;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.*;
public class CharacterMC extends Sprite{
//位图数据数组
protected var _bitmapArr:Array;
//加载图片用
private var _loader:Loader;
//读取图片用Bitmap
private var _image:Bitmap;
//头像Bitmap
public var _imageFace:Bitmap;
//用以显示的bitMap对象
private var _peopleBitmap:Bitmap;
//图片列数
private var _row:int;
//图片行数
private var _col:int;
//图片列数
private var _rowatt:int;
//图片行数
private var _colatt:int;
//图片显示控制
public var _keys:Object;
//目前显示图片列号
private var _pointer:int = 0;
//图片显示速度控制
private var _count:Number = 0;
//图片显示速度
private var _speed:Number;
//攻击图片地址
private var _attImage:String;
//行走图片地址
private var _strImage:String;
//HP显示
public var _hp:TextField = new TextField();
//HP值
public var _hpValue:int = 100;
//函数1
public var _fun:Function;
//函数2
public var _fun2:Function;
//战斗类Class
private var _fightMap:FightMap;
//HP伤害显示
public var _hpHert:TextField = new TextField();
//人物名称
public var _nameTxt:String;
//Class参数依次为:战斗类Class,头像地址,行走图片地址,攻击图片地址,图片显示控制,行走图片行数,行走图片列数,攻击图片行数,攻击图片列数,显示速度
public function CharacterMC(fightMap:FightMap = null,faceImage:String = "",strImage:String = "",attImage:String = "",keys:Object = null,row:int = 2,col:int = 4,rowatt:int = 1,colatt:int= 5,speed:Number = 0.15) {
_fightMap = fightMap;
_keys = keys;
_row = row;
_col = col;
_rowatt = rowatt;
_colatt = colatt;
_speed = speed;
_strImage = strImage;
_attImage = attImage;
//头像图片加载对象;
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.load(new URLRequest(faceImage));
}
//头像加载完成
public function onComplete(event:Event):void {
_imageFace = Bitmap(_loader.content);
_imageFace.width = 120;
_imageFace.height = 120;
//行走图片加载对象;
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteMov);
_loader.load(new URLRequest(_strImage));
}
//HP伤害
public function setHp(hert:int):void{
_hpHert.htmlText = "<font color='#FF0000'>-" + hert + "</font>";
_hpHert.height = 20;
_hpHert.y = 0;
//伤害图片显示
var hertDir:int;
if(int(_keys["playDirection"]) == 2){
setDir(5);
}else{
setDir(7);
}
//HP伤害显示
addEventListener(Event.ENTER_FRAME, hertFrame);
//HP值计算与显示
_hpValue -= hert;
_hp.htmlText = "<font color='#FF0000'>" + _hpValue + " / 100</font>";
//HP值为0时,显示撤退信息
if(_hpValue == 0){
_fightMap._characterShow.show_txt.appendText( _nameTxt + "撤退\n");
}
}
//行走图片加载完成
public function onCompleteMov(event:Event):void {
_image = Bitmap(_loader.content);
//将传入的位图数据拆分成小块,装入bitmapArr
_bitmapArr=ImageCtrl.divide(_image,_row,_col);
_peopleBitmap = new Bitmap();
addChild(_peopleBitmap);
//HP初始化
_hp.x = 0;
_hp.y = 48;
_hp.width = 48;
_hp.height = 20;
_hp.htmlText = "<font color='#FF0000'>" + _hpValue + " / 100</font>";
addChild(_hp);
addChild(_hpHert);
_hpHert.y = -50;
//攻击图片加载对象;
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteAtt);
_loader.load(new URLRequest(_attImage));
}
//图片水平翻转处理
private function imageTurn(loaderBmp:Bitmap):Bitmap{
var w:Number = loaderBmp.width / 96;
var imagebit:BitmapData = new BitmapData(loaderBmp.width,loaderBmp.height,true, 0xffffffff);
for(var i:int = 0; i < 96; i++) {
imagebit.copyPixels(loaderBmp.bitmapData,
new Rectangle( i * w, 0,w, loaderBmp.height),
new Point((95 - i) * w , 0));
}
var __image:Bitmap = new Bitmap(imagebit);
return __image;
}
//攻击图片加载完成,将图片按照 [0-3上下左右 4左攻击5左倒6右攻击7右倒]的顺序装入数组
public function onCompleteAtt(event:Event):void {
_image = Bitmap(_loader.content);
//将传入的位图数据拆分成小块,装入bitmapArr
var bitmapArr:Array=ImageCtrl.divide(_image,_rowatt,_colatt);
var bitArr:Array;
var i:int = 0;
bitArr = new Array();
for(i = 0;i<bitmapArr.length - 1;i++){
bitArr.push(bitmapArr[i][0]);
}
_bitmapArr.push(bitArr);
bitArr = new Array();
bitArr.push(bitmapArr[bitmapArr.length - 1][0]);
_bitmapArr.push(bitArr);
//攻击图片翻转
_image = imageTurn(_image);
bitmapArr=ImageCtrl.divide(_image,_rowatt,_colatt);
bitArr = new Array();
for(i = 0;i<bitmapArr.length - 1;i++){
bitArr.push(bitmapArr[i][0]);
}
_bitmapArr.push(bitArr);
bitArr = new Array();
bitArr.push(bitmapArr[bitmapArr.length - 1][0]);
_bitmapArr.push(bitArr);
var dir:int = int(_keys["playDirection"]);
_peopleBitmap.bitmapData = _bitmapArr[dir][0];
}
public function startFrame():void{
//角色动作开始;
addEventListener(Event.ENTER_FRAME, onFrame);
}
public function endFrame():void{
//角色动作停止;
removeEventListener(Event.ENTER_FRAME, onFrame);
}
//角色动作改变
public function setDir(dir:int):void{
_keys["playDirection"] = dir;
_pointer = 0;
_count = 0;
startFrame();
}
//_keys["playDirection"] 0-3上下左右 4左攻击5左倒6右攻击7右倒
public function onFrame(event:Event):void {
var dir:int = int(_keys["playDirection"]);
_peopleBitmap.bitmapData = _bitmapArr[dir][_pointer];
_count += _speed;
_pointer += int(_count) ;
_count=_count%1;
if(_pointer >= _bitmapArr[dir].length){
endFrame();
_pointer = 0;
_count = 0;
switch(dir){
case 4:
setDir(2);
_fun();
_fun = null;
break;
case 6:
setDir(3);
_fun();
_fun = null;
break;
case 5:
setDir(2);
break;
case 7:
setDir(3);
break;
default:
break;
}
}
}
//伤害显示
public function hertFrame(event:Event):void {
if(_hpHert.y > -50){
_hpHert.y -= 2;
}else{
removeEventListener(Event.ENTER_FRAME, hertFrame);
_hpHert.text = "";
_fun2();
_fun2 = null;
}
}
}
}
2010-5-17 18:18
lufy
人物控制类添加完了之后,就可以做战场了,添加战场类FightMap
package com.ot{
import com.mains.GameStart;
import com.npc.PeopleClass;
import com.npc.NpcClass;
import com.npc.CharacterMC;
import com.npc.XMLLoader;
import flash.net.URLLoader;
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.geom.Point;
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.KeyboardEvent;
public class FightMap extends Sprite {
private const BTN_ATTACK:String = "攻击";
private const BTN_DETECT:String = "侦查";
private const BTN_DEFENSE:String = "防御";
private const BTN_RETREAT:String = "撤退";
private const SELECT:String = "SELECT";//战斗状态:选择
private const FIGHT:String = "FIGHT";//战斗状态:战斗开始
private const FIGHTVIEW:String = "FIGHTVIEW";//战斗状态:侦查
private const MOVE_ADVANCE:String = "MOVE_ADVANCE";//前进
private const MOVE_RETREAT:String = "MOVE_RETREAT";//后退
private const GAMEOVER:String = "GAMEOVER";//战斗状态:结束
//声明time函数
private var _timer:Timer;
//声明载入图片类
private var _loader:Loader = new Loader( );
//声明Bitmap
private var _image:Bitmap;
private var __image:Bitmap;
//装载地图小位图用
private var _mapList:Array= new Array();
private var _mapXmlSrc:String;
//地图图片数组
private var _map:Array= new Array();
//地形数组
private var _mapDate:Array= new Array();
//人物
private var _player:PeopleClass;
//滚屏用变量
private var _mapStartX:int = 0;
private var _mapEndX:int = 0;
private var _mapStartY:int = 0;
private var _mapEndY:int = 0;
//地图显示的起始坐标
public var _mPoint:Point;
//地图最大坐标
public var _maxX:int;
public var _maxY:int;
//人物主角图片
private var _propleImage:String;
//人物初始坐标
public var _peoplePoint:Point;
//地图画板
public var _mapFrame:Sprite = new Sprite();
public var _mapFloor:Sprite = new Sprite();
//地图画板
public var _npcFrame:Sprite = new Sprite();
public var _npcPoint:Point = new Point(0,0);
//地图跳转信息
public var _changeList:HashMap = new HashMap();
//主地图
public var _gameMap:GameStart;
//装载NPC数组
public var _npcList:HashMap = new HashMap();
//人物名称
private var _peopleName:String;
//是否对话中
public var _is_talked:Boolean = false;
//我方人物数组
private var _listOur:Array = new Array();
//敌方人物数组
private var _listEnemy:Array = new Array();
//当前数组(敌方或我方)
public var _ctrlArr:Array;
//当前人物序号
public var _ctrlIndex:int;
//选项显示用和信息显示用MC
public var _characterShow:CharacterShow;
//当前选择选项
private var _btnCtrl:String;
//战斗状态
private var _fightShow:String;
//移动状态
private var _moveCtrl:String;
//符号显示用Bitmap
private var _sign:Bitmap = new Bitmap();
//符号图片储存数组
private var _signArr:Array;
//人物属性储存用Xml
private var _peopleXml:XML;
//xml载入类
private var loader:XMLLoader;
//符号显示用序号
private var _signIndex:int = 0;
//人物属性用MC
private var _view:VIEW = new VIEW();
//人物属性显示时,头像图片装载用Bitmap
private var _view_face:Bitmap = new Bitmap();
//战斗时我方人物数组
private var _pkOurArr:Array;
//战斗时敌方人物数组
private var _pkEnemyArr:Array;
//信息显示时,头像图片装载用Bitmap
private var _face:Bitmap = new Bitmap();
private var _fun:Function;
public function FightMap(mapXmlSrc:String,fun:Function,gameMap:GameStart) {
//添加地图画板
addChild(_mapFrame);
_mapFrame.addChild(_mapFloor);
//添加NPC画板
_mapFrame.addChild(_npcFrame);
_view.face.addChild(_view_face);
_gameMap = gameMap;
_fun = fun;
//获取地图xml文件
_mapXmlSrc = mapXmlSrc;
//选项显示用和信息显示用MC初始化
_characterShow = new CharacterShow();
_characterShow.ctrl.visible = false;
_characterShow.y = 360;
_characterShow.face.addChild(_face);
this.addChild(_characterShow);
//鼠标点击时候,光标设定
addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
//载入人物属性Xml
loader = new XMLLoader();
loader.onLoadComplete = initPeople;
loader.load("data/people.xml", XMLLoader.GB2312);
}
public function mouseDownHandler(evet:MouseEvent):void{
//设定光标
stage.focus = _characterShow.ctrl;
}
public function initPeople(peopleXml:XML):void{
_peopleXml = peopleXml;
//载入战场用xml
loader = new XMLLoader();
loader.onLoadComplete = initStage;
loader.load(_mapXmlSrc, XMLLoader.GB2312);
}
//得到战场xml信息
public function initStage(mapXml:XML):void{
var obj:Object;
var chara:CharacterMC;
var keys:Object;
var indexY:int = 10;
//获得我方人物
for each ( var elementOur:XML in mapXml.our.elements( ) ) {
obj = new Object();
obj["id"] = _peopleXml[elementOur.toString()].id;
obj["name"] = _peopleXml[elementOur.toString()].name;
obj["face"] = _peopleXml[elementOur.toString()].face;
obj["moveimage"] = _peopleXml[elementOur.toString()].moveimage;
obj["attimage"] = _peopleXml[elementOur.toString()].attimage;
obj["att"] = _peopleXml[elementOur.toString()].att;
obj["def"] = _peopleXml[elementOur.toString()].def;
obj["speed"] = _peopleXml[elementOur.toString()].speed;
obj["comment"] = _peopleXml[elementOur.toString()].comment;
_listOur.push(obj);
}
indexY = 10;
//获得敌方人物
for each ( var elementEnemy:XML in mapXml.enemy.elements( ) ) {
obj = new Object();
obj["id"] = _peopleXml[elementEnemy.toString()].id;
obj["name"] = _peopleXml[elementEnemy.toString()].name;
obj["face"] = _peopleXml[elementEnemy.toString()].face;
obj["moveimage"] = _peopleXml[elementEnemy.toString()].moveimage;
obj["attimage"] = _peopleXml[elementEnemy.toString()].attimage;
obj["att"] = _peopleXml[elementEnemy.toString()].att;
obj["def"] = _peopleXml[elementEnemy.toString()].def;
obj["speed"] = _peopleXml[elementEnemy.toString()].speed;
obj["comment"] = _peopleXml[elementEnemy.toString()].comment;
_listEnemy.push(obj);
}
//加载地图
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
_loader.load(new URLRequest("images/map/" + mapXml.map));
}
public function onComplete(event:Event):void {
_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onComplete);
_image = Bitmap(_loader.content);
_mapFloor.addChild(_image);
//加载箭头图标
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteSign);
_loader.load(new URLRequest("images/system/sign.gif"));
}
public function onCompleteSign(event:Event):void {
_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onCompleteSign);
_image = Bitmap(_loader.content);
_signArr = ImageCtrl.divide(_image,2,1);
_mapFrame.addChild(_sign);
//战场人物初始化
var obj:Object;
var chara:CharacterMC;
var keys:Object;
var i:int = 0;
//初始化我方人物
for(i=0;i<_listOur.length;i++){
obj = _listOur[i];
keys = new Object();
keys["playDirection"] = 3;
chara = new CharacterMC(this,obj["face"],obj["moveimage"],obj["attimage"],keys);
chara.x = 50;
chara.y = i * 70 + 20;
chara._nameTxt = obj["name"];
obj["chara"] = chara;
obj["move"] = 0;
_npcFrame.addChild(chara);
}
//初始化敌方人物
for(i=0;i<_listEnemy.length;i++){
obj = _listEnemy[i];
keys = new Object();
keys["playDirection"] = 2;
chara = new CharacterMC(this,obj["face"],obj["moveimage"],obj["attimage"],keys);
chara.x = 380;
chara.y = i * 70 + 20;
chara._nameTxt = obj["name"];
obj["chara"] = chara;
obj["move"] = 0;
_npcFrame.addChild(chara);
}
_ctrlIndex = 0;
_ctrlArr = _listOur;
//开始检测我方图片是否全部加载完成
this.addEventListener(Event.ENTER_FRAME,faceFrameOur);
}
//战斗结束测试
public function memberCheck():int{
var hp:int = 0;
var i:int;
var obj:Object;
for(i=0;i<_listOur.length;i++){
obj = _listOur[i];
hp += obj["chara"]._hpValue;
if(obj["chara"]._hpValue == 0){
_listOur.splice(i,1);
i --;
}
}
//我方全灭测试
if(hp == 0){
return 1;
}
hp = 0;
for(i=0;i<_listEnemy.length;i++){
obj = _listEnemy[i];
hp += obj["chara"]._hpValue;
if(obj["chara"]._hpValue == 0){
_listEnemy.splice(i,1);
i --;
}
}
//敌方全灭测试
if(hp == 0){
return 2;
}
return 0;
}
//检测我方图片是否全部加载完成
private function faceFrameOur(e:Event):void{
var obj:Object = _ctrlArr[_ctrlIndex];
if(obj["chara"]._imageFace != null){
_ctrlIndex ++;
if(_ctrlIndex >= _ctrlArr.length){
this.removeEventListener(Event.ENTER_FRAME,faceFrameOur);
_ctrlIndex = 0;
_ctrlArr = _listEnemy;
//检测敌方图片是否加载完成
this.addEventListener(Event.ENTER_FRAME,faceFrameEnemy);
}
};
}
//检测敌方图片是否全部加载完成
private function faceFrameEnemy(e:Event):void{
var obj:Object = _ctrlArr[_ctrlIndex];
if(obj["chara"]._imageFace != null){
_ctrlIndex ++;
if(_ctrlIndex >= _ctrlArr.length){
this.removeEventListener(Event.ENTER_FRAME,faceFrameEnemy);
_ctrlArr = _listOur;
_ctrlIndex = 0;
this.addEventListener(Event.ENTER_FRAME, renderHandler);
//用来添加侦听器,侦听键盘
_characterShow.ctrl.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.focus = _characterShow.ctrl;
//开始选择战斗选项
_fightShow = SELECT;
_moveCtrl = MOVE_ADVANCE;
_mapFrame.addEventListener(Event.ENTER_FRAME,moveFrame);
}
};
}
//战斗开始
private function toPK():void{
//获取战斗结果
var intCheck = memberCheck();
if(intCheck == 1){
_face.bitmapData = _listOur[0]["chara"]._imageFace.bitmapData;
_characterShow.show_txt.appendText("战斗失败了\n");
_ctrlIndex = 0;
_fightShow = GAMEOVER;
this.addEventListener(Event.ENTER_FRAME, keyDownOver);
return;
}else if(intCheck == 2){
_face.bitmapData = _listOur[0]["chara"]._imageFace.bitmapData;
_characterShow.show_txt.appendText("战斗胜利了\n");
_ctrlIndex = 0;
_fightShow = GAMEOVER;
this.addEventListener(Event.ENTER_FRAME, keyDownOver);
return;
}
//战斗本回合结束测试
if(_pkOurArr.length + _pkEnemyArr.length == 0){
_ctrlArr = _listOur;
_ctrlIndex = 0;
//回合结束,进入选择战斗菜单选项
_fightShow = SELECT;
_moveCtrl = MOVE_ADVANCE;
_mapFrame.addEventListener(Event.ENTER_FRAME,moveFrame);
return;
}
//找出未行动的人中速度最快的人,速度采用随机浮动
var obj:Object;
_ctrlIndex = 0;
if(_pkOurArr.length > 0){
_ctrlArr = _pkOurArr;
}else{
_ctrlArr = _pkEnemyArr;
}
var i:int;
for(i = 0;i<_pkOurArr.length;i++){
obj = _pkOurArr[i];
if(obj["chara"]._hpValue >0 && int(_ctrlArr[_ctrlIndex]["speed"]) <( int(obj["speed"]) + 5 - Math.random() * 10)){
_ctrlArr = _pkOurArr;
_ctrlIndex = i;
}
}
for(i = 0;i<_pkEnemyArr.length;i++){
obj = _pkEnemyArr[i];
if(obj["chara"]._hpValue >0 && int(_ctrlArr[_ctrlIndex]["speed"]) < int(obj["speed"]) + 5 - Math.random()* 10){
_ctrlArr = _pkEnemyArr;
_ctrlIndex = i;
}
}
_moveCtrl = MOVE_ADVANCE;
_mapFrame.addEventListener(Event.ENTER_FRAME,moveFrame);
}
//人物移动
private function moveFrame(e:Event):void{
var obj:Object;
var i:int;
//战斗状态判断
if(_fightShow == SELECT){
//战斗菜单状态
obj = _ctrlArr[_ctrlIndex];
if(_moveCtrl == MOVE_ADVANCE){
//前移
if(obj["chara"].x == 50){
obj["chara"].startFrame();
}
if(obj["chara"].x < 178){
obj["chara"].x += 12;
}else{
obj["chara"].x = 178;
_mapFrame.removeEventListener(Event.ENTER_FRAME,moveFrame);
setCtrlBtn();
}
}else if(_moveCtrl == MOVE_RETREAT){
//后移
if(obj["chara"].x == 178){
obj["chara"].startFrame();
}
if(obj["chara"].x > 50){
obj["chara"].x -= 12;
}else{
obj["chara"].x = 50;
_ctrlIndex++;
if(_ctrlIndex >= _ctrlArr.length){
_fightShow = FIGHT;
_mapFrame.removeEventListener(Event.ENTER_FRAME,moveFrame);
_pkOurArr = new Array();
_pkEnemyArr = new Array();
for(i=0;i<_listOur.length;i++){
_pkOurArr.push(_listOur[i]);
}
for(i=0;i<_listEnemy.length;i++){
_pkEnemyArr.push(_listEnemy[i]);
}
toPK();
}else{
_moveCtrl = MOVE_ADVANCE;
}
}
}
}else if(_fightShow == FIGHT){
//战斗状态
obj = _ctrlArr[_ctrlIndex];
if(_moveCtrl == MOVE_ADVANCE){
if(obj["chara"]._hpValue == 0){
_ctrlArr.splice(_ctrlIndex,1);
_mapFrame.removeEventListener(Event.ENTER_FRAME,moveFrame);
toPK();
return;
}
//前移
if(_ctrlArr == _pkOurArr){
if(obj["chara"].x == 50){
obj["chara"].startFrame();
}
if(obj["chara"].x < 178){
obj["chara"].x += 12;
}else{
obj["chara"].x = 178;
setAtt();
}
}else{
if(obj["chara"].x == 380){
obj["chara"].startFrame();
}
if(obj["chara"].x > 316){
obj["chara"].x -= 12;
}else{
obj["chara"].x = 316;
setAtt();
}
}
}else if(_moveCtrl == MOVE_RETREAT){
//后移
if(_ctrlArr == _pkOurArr){
if(obj["chara"].x == 178){
obj["chara"].startFrame();
}
if(obj["chara"].x > 50){
obj["chara"].x -= 12;
}else{
obj["chara"].x = 50;
_ctrlArr.splice(_ctrlIndex,1);
_mapFrame.removeEventListener(Event.ENTER_FRAME,moveFrame);
toPK();
}
}else{
if(obj["chara"].x == 316){
obj["chara"].startFrame();
}
if(obj["chara"].x < 380){
obj["chara"].x += 12;
}else{
obj["chara"].x = 380;
_ctrlArr.splice(_ctrlIndex,1);
_mapFrame.removeEventListener(Event.ENTER_FRAME,moveFrame);
toPK();
}
}
}
}
}
//判断战斗选项,开始战斗
private function setAtt():void{
_mapFrame.removeEventListener(Event.ENTER_FRAME,moveFrame);
var obj:Object = _ctrlArr[_ctrlIndex];
_face.bitmapData = obj["chara"]._imageFace.bitmapData;
var hertObj:Object;
var randIndex:int;
var hert:int;
var selfDir:int;
var hertDir:int;
//随机获取受攻击武将
if(_ctrlArr == _pkOurArr){
randIndex = Math.random()*_listEnemy.length;
hertObj = _listEnemy[randIndex];
selfDir = 6;
hertDir = 5;
}else{
randIndex = Math.random()*_listOur.length;
hertObj = _listOur[randIndex];
selfDir = 4;
hertDir = 7;
}
//如果战斗选项是撤退,则随机判断撤退是否成功
if(obj["ctrl"] == BTN_RETREAT && Math.random()*100 < 20){
_characterShow.show_txt.appendText("撤退成功!\n");
_ctrlIndex = 0;
_fightShow = GAMEOVER;
this.addEventListener(Event.ENTER_FRAME, keyDownOver);
return;
}
//选择防御
if(obj["ctrl"] == BTN_DEFENSE){
_face.bitmapData = obj["chara"]._imageFace.bitmapData;
_characterShow.show_txt.appendText(obj["name"] + "防御中\n");
_moveCtrl = MOVE_RETREAT;
_mapFrame.addEventListener(Event.ENTER_FRAME,moveFrame);
return;
}
//选择战斗
var hertDef:int = int(hertObj["def"]);
if(hertObj["ctrl"] == BTN_DEFENSE){
hertDef = hertDef*1.5;
}
//攻击力随机浮动,计算伤害值
hert = Math.floor((110 + int(obj["att"]) - Math.random()*20 - hertDef)/5);
obj["chara"]._fun = function (){
//攻击动作结束后,处理函数
hertObj["chara"]._fun2 = function (){
//受伤害动作结束后,处理函数
_moveCtrl = MOVE_RETREAT;
_mapFrame.addEventListener(Event.ENTER_FRAME,moveFrame);
}
if(hert >= hertObj["chara"]._hpValue){
hert = hertObj["chara"]._hpValue;
}
_characterShow.show_txt.appendText(obj["name"] + "攻击\n杀死" + hertObj["name"] + hert + "个士兵\n");
hertObj["chara"].setHp(hert);
}
//开始攻击
obj["chara"].setDir(selfDir);
}
//选项菜单设定
private function setCtrlBtn():void{
_btnCtrl = BTN_ATTACK;
_face.bitmapData = _ctrlArr[_ctrlIndex]["chara"]._imageFace.bitmapData;
_face.width = 120;
_face.height = 120;
_characterShow.ctrl.btn1.show.htmlText = getBtnText(BTN_ATTACK,true);
_characterShow.ctrl.btn2.show.htmlText = getBtnText(BTN_DETECT,false);
_characterShow.ctrl.btn3.show.htmlText = getBtnText(BTN_DEFENSE,false);
_characterShow.ctrl.btn4.show.htmlText = getBtnText(BTN_RETREAT,false);
_characterShow.ctrl.visible = true;
stage.focus = _characterShow.ctrl;
}
//战斗结束,
private function keyDownOver(event:Event):void {
_ctrlIndex ++;
if(_ctrlIndex > 20){
this.removeEventListener(Event.ENTER_FRAME, keyDownOver);
_gameMap.fightEnd(_fun);
}
}
//键盘事件,
private function keyDownHandler(event:KeyboardEvent):void {
if(_fightShow == SELECT){
//战斗菜单键盘事件
switch (event.keyCode) {
case 40 :
btnUpDown();
break;
case 38 :
btnUpDown();
break;
case 37 :
btnLeftRight();
break;
case 39 :
btnLeftRight();
break;
case 32 :
btnOk();
break;
case 13 :
btnOk();
break;
default:
break;
}
}else if(_fightShow == BTN_DETECT){
//侦查选择键盘事件
switch (event.keyCode) {
case 40 :
signDown();
break;
case 38 :
signUp();
break;
case 37 :
signLeftRight();
break;
case 39 :
signLeftRight();
break;
default:
signOk();
break;
}
}else if(_fightShow == FIGHTVIEW){
//侦查显示状态下键盘状态
_mapFrame.removeChild(_view);
_fightShow = SELECT;
}
}
//侦查显示
private function signOk():void{
_sign.bitmapData = null;
var obj:Object;
if(_sign.x == _listEnemy[0]["chara"].x - 30){
obj = _listEnemy[_signIndex];
}else{
obj = _listOur[_signIndex];
}
_view_face.bitmapData = obj["chara"]._imageFace.bitmapData;
_view_face.width = 120;
_view_face.height = 120;
_view.name_txt.text = obj["name"];
_view.att.text = obj["att"];
_view.def.text = obj["def"];
_view.speed.text = obj["speed"];
_view.comment.text = obj["comment"];
_mapFrame.addChild(_view);
_fightShow = FIGHTVIEW;
}
//侦查选择键盘事件 : 上
private function signUp():void{
_signIndex --;
if(_sign.x == _listEnemy[0]["chara"].x - 30){
if(_signIndex< 0){
_signIndex = _listEnemy.length - 1;
}
_sign.x = _listEnemy[_signIndex]["chara"].x - 30;
_sign.y = _listEnemy[_signIndex]["chara"].y + 10;
}else{
if(_signIndex < 0){
_signIndex = _listOur.length - 1;
}
_sign.x = _listOur[_signIndex]["chara"].x + 48;
_sign.y = _listOur[_signIndex]["chara"].y + 10;
}
}
//侦查选择键盘事件 : 下
private function signDown():void{
_signIndex ++;
if(_sign.x == _listEnemy[0]["chara"].x - 30){
if(_signIndex >= _listEnemy.length){
_signIndex = 0;
}
_sign.x = _listEnemy[_signIndex]["chara"].x - 30;
_sign.y = _listEnemy[_signIndex]["chara"].y + 10;
}else{
if(_signIndex >= _listOur.length){
_signIndex = 0;
}
_sign.x = _listOur[_signIndex]["chara"].x + 48;
_sign.y = _listOur[_signIndex]["chara"].y + 10;
}
}
//侦查选择键盘事件 : 左右
private function signLeftRight():void{
if(_sign.x == _listEnemy[0]["chara"].x - 30){
if(_signIndex >= _listEnemy.length || _signIndex < 0){
_signIndex = 0;
}else{
_sign.bitmapData = _signArr[0][0];
_sign.x = _listOur[0]["chara"].x + 48;
_sign.y = _listOur[0]["chara"].y + 10;
}
}else{
if(_signIndex >= _signArr.length || _signIndex < 0){
_signIndex = 0;
}else{
_sign.bitmapData = _signArr[0][1];
_sign.x = _listEnemy[0]["chara"].x - 30;
_sign.y = _listEnemy[0]["chara"].y + 10;
}
}
}
//战斗菜单键盘事件 : 确定
private function btnOk():void{
if(_btnCtrl == BTN_DETECT){
_sign.bitmapData = _signArr[0][1];
_sign.x = _listEnemy[0]["chara"].x - 30;
_sign.y = _listEnemy[0]["chara"].y + 10;
//记录选择事件
_fightShow = BTN_DETECT;
_signIndex = 0;
return;
}
var obj:Object = _ctrlArr[_ctrlIndex];
obj["ctrl"] = _btnCtrl;
_moveCtrl = MOVE_RETREAT
_characterShow.ctrl.visible = false;
_mapFrame.addEventListener(Event.ENTER_FRAME,moveFrame);
}
//战斗菜单键盘事件 : 上下
private function btnUpDown():void{
if(_btnCtrl == BTN_ATTACK){
_btnCtrl = BTN_DEFENSE;
_characterShow.ctrl.btn1.show.htmlText = getBtnText(BTN_ATTACK,false);
_characterShow.ctrl.btn3.show.htmlText = getBtnText(BTN_DEFENSE,true);
}else if(_btnCtrl == BTN_DEFENSE){
_btnCtrl = BTN_ATTACK;
_characterShow.ctrl.btn1.show.htmlText = getBtnText(BTN_ATTACK,true);
_characterShow.ctrl.btn3.show.htmlText = getBtnText(BTN_DEFENSE,false);
}else if(_btnCtrl == BTN_DETECT){
_btnCtrl = BTN_RETREAT;
_characterShow.ctrl.btn2.show.htmlText = getBtnText(BTN_DETECT,false);
_characterShow.ctrl.btn4.show.htmlText = getBtnText(BTN_RETREAT,true);
}else if(_btnCtrl == BTN_RETREAT){
_btnCtrl = BTN_DETECT;
_characterShow.ctrl.btn2.show.htmlText = getBtnText(BTN_DETECT,true);
_characterShow.ctrl.btn4.show.htmlText = getBtnText(BTN_RETREAT,false);
}
}
//战斗菜单键盘事件 : 左右
private function btnLeftRight():void{
if(_btnCtrl == BTN_ATTACK){
_btnCtrl = BTN_DETECT;
_characterShow.ctrl.btn1.show.htmlText = getBtnText(BTN_ATTACK,false);
_characterShow.ctrl.btn2.show.htmlText = getBtnText(BTN_DETECT,true);
}else if(_btnCtrl == BTN_DETECT){
_btnCtrl = BTN_ATTACK;
_characterShow.ctrl.btn1.show.htmlText = getBtnText(BTN_ATTACK,true);
_characterShow.ctrl.btn2.show.htmlText = getBtnText(BTN_DETECT,false);
}else if(_btnCtrl == BTN_DEFENSE){
_btnCtrl = BTN_RETREAT;
_characterShow.ctrl.btn3.show.htmlText = getBtnText(BTN_DEFENSE,false);
_characterShow.ctrl.btn4.show.htmlText = getBtnText(BTN_RETREAT,true);
}else if(_btnCtrl == BTN_RETREAT){
_btnCtrl = BTN_DEFENSE;
_characterShow.ctrl.btn3.show.htmlText = getBtnText(BTN_DEFENSE,true);
_characterShow.ctrl.btn4.show.htmlText = getBtnText(BTN_RETREAT,false);
}
}
//战斗菜单显示设定
private function getBtnText(txt:String,isOn:Boolean):String{
var colStr:String = "#CCCCCC";
if(isOn){
colStr = "#FF0000";
}
return "<font color='" + colStr + "'><b>" + txt + "</b></font>";
}
//滚动显示文本信息,让文本始终向上滚动,显示最后一行
private function renderHandler(e:Event):void
{
_characterShow.show_txt.scrollV = _characterShow.show_txt.maxScrollV;
}
}
}
然后,利用事件脚本的xml,添加战斗事件att,运行游戏并触发事件,就可以看到如下画面了
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/fight01.jpg?t=1274089175[/img]
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/fight02.jpg?t=1274089195[/img]
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/fight03.jpg?t=1274089212[/img]
接下来,研究地图编辑器^0^!
2010-5-17 18:19
lufy
打算为游戏做一个地图编辑器,地图大的时候需要用到滚动条,
而Flash自带的滚动条不太会用,于是自己弄了个简单的滚动条来控制图片的显示,
想想以后需要新功能的话,自己还可以修改添加,应该会很方便
首先利用CS4,建立一个竖向的MC
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/bar.jpg?t=1272674778[/img]
里面向上的箭头(up),向下的箭头(down),滚动条(ctrl),背景(bak),都分别是一个MC,然后同样方法建立一个横向的MC,里面的四个MC分别是left,right,ctrl,bak
接下来,建立图片显示板MapFloor,画一个480X480的遮罩mask,然后将两个滚动条分别拖到左,下,名称设定为barC,barR,遮罩下面建立一个MC(名称:floorImage)
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/mapfloor.jpg?t=1272675200[/img]
下面就可以用这些MC来控制图片显示了
首先找一个稍微大一点的图片,
利用_loader 读取图片,
_map = new MapFloor();
addChild(_map);
_loader = new Loader( );
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, setJpgOver);
_loader.load(new URLRequest("images/test.jpg"));
读取完之后,设定滚动条状态:
_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, setJpgOver);
_image = Bitmap(_loader.content);
_map.floorImage.addChild(_image);
if(_map.floorImage.width > 480){
_map.barR.bak.width = 480;
_map.barR.right.x = 466;
_map.barR.addEventListener(MouseEvent.MOUSE_DOWN,barRMouseDown);
_map.barR.addEventListener(MouseEvent.MOUSE_UP,barRMouseUp);
_map.barR.left.addEventListener(MouseEvent.MOUSE_DOWN,barRUp);
_map.barR.right.addEventListener(MouseEvent.MOUSE_DOWN,barRDown);
}else{
_map.barR.visible = false;
}
if(_map.floorImage.height > 480){
_map.barC.bak.height = 480;
_map.barC.down.y = 466;
_map.barC.addEventListener(MouseEvent.MOUSE_DOWN,barCMouseDown);
_map.barC.addEventListener(MouseEvent.MOUSE_UP,barCMouseUp);
_map.barC.up.addEventListener(MouseEvent.MOUSE_DOWN,barCUp);
_map.barC.down.addEventListener(MouseEvent.MOUSE_DOWN,barCDown);
}else{
_map.barC.visible = false;
}
private function barCUp(event:MouseEvent):void{
_map.barC.ctrl.y -= 10;
if(_map.barC.ctrl.y < 14){
_map.barC.ctrl.y = 14;
}
mapToY();
}
private function barCDown(event:MouseEvent):void{
_map.barC.ctrl.y += 10;
if(_map.barC.ctrl.y > 416){
_map.barC.ctrl.y = 416;
}
mapToY();
}
private function barRUp(event:MouseEvent):void{
_map.barR.ctrl.x -= 10;
if(_map.barR.ctrl.x < 14){
_map.barR.ctrl.x = 14;
}
mapToX();
}
private function barRDown(event:MouseEvent):void{
_map.barR.ctrl.x += 10;
if(_map.barR.ctrl.x > 416){
_map.barR.ctrl.x = 416;
}
mapToX();
}
private function barCMouseDown(event:MouseEvent):void{
barCToMouse(event);
_map.barC.addEventListener(MouseEvent.MOUSE_MOVE,barCMouseMove);
}
private function barCMouseUp(event:MouseEvent):void{
_map.barC.removeEventListener(MouseEvent.MOUSE_MOVE,barCMouseMove);
}
private function barCMouseMove(event:MouseEvent):void{
barCToMouse(event);
}
private function barRMouseDown(event:MouseEvent):void{
barRToMouse(event);
_map.barR.addEventListener(MouseEvent.MOUSE_MOVE,barRMouseMove);
}
private function barRMouseUp(event:MouseEvent):void{
_map.barR.removeEventListener(MouseEvent.MOUSE_MOVE,barRMouseMove);
}
private function barRMouseMove(event:MouseEvent):void{
barRToMouse(event);
}
private function barRToMouse(event:MouseEvent):void{
if(event.currentTarget.mouseX < 14 || event.currentTarget.mouseX > 466){
return;
}
_map.barR.ctrl.x = event.currentTarget.mouseX - 11;
if(_map.barR.ctrl.x < 14){
_map.barR.ctrl.x = 14;
}else if(_map.barR.ctrl.x > 416){
_map.barR.ctrl.x = 416;
}
mapToX();
}
private function mapToX():void{
_map.floorImage.x = -1 * (_map.barR.ctrl.x - 14) * (_map.floorImage.width - 480) /402;
}
private function barCToMouse(event:MouseEvent):void{
if(event.currentTarget.mouseY < 14 || event.currentTarget.mouseY > 466){
return;
}
_map.barC.ctrl.y = event.currentTarget.mouseY - 11;
if(_map.barC.ctrl.y < 14){
_map.barC.ctrl.y = 14;
}else if(_map.barC.ctrl.y > 416){
_map.barC.ctrl.y = 416;
}
mapToY();
}
private function mapToY():void{
_map.floorImage.y = -1 * (_map.barC.ctrl.y - 14) * (_map.floorImage.height - 480) /402;
}
然后CTRL+回车,测试一下,可以看到滚动条已经可以很好的控制图片了
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/gundong.jpg?t=1272676474[/img]
2010-5-17 18:20
lufy
好了,有了上面的基础,要做一个地图编辑器,就不难了
修改上面的代码,做成MapImage类
如下
package rpg_map4.map {
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.events.Event;
import flash.events.MouseEvent;
import rpg_map4.mains.Main;
import rpg_map4.other.GridLayer;
import rpg_map4.other.ChildFloor;
public class MapImage extends Sprite{
// Constants:
// Public Properties:
// Private Properties:
private var _map:MapFloor;
private var _main:Main;
private var _bakMc:Sprite;
private var _gridMc:Sprite;
private var _gridLayer:GridLayer;
public var _floorList:Array = new Array();
// Initialization:
public function MapImage(main) {
_main = main;
_map = new MapFloor();
addChild(_map);
}
public function setFloor(mapwidth:int,mapheight:int):void{
_bakMc = new Sprite();
_gridMc = new Sprite();
_map.floorImage.addChild(_bakMc);
_map.floorImage.addChild(_gridMc);
for(var i:int = 0;i<(mapwidth);i++){
var floorChild:Array = new Array();
for(var j:int = 0;j<(mapheight);j++){
var bit:ChildFloor = new ChildFloor();
bit.bitmapData = _main._mapList[0][0];
bit.x = i*48;
bit.y = j*48;
_bakMc.addChild(bit);
floorChild.push(bit);
}
_floorList.push(floorChild);
}
_gridLayer = new GridLayer();
_gridLayer.drawGrid(_map.floorImage.width,_map.floorImage.height,48,48);
_gridMc.addChild(_gridLayer);
_map.floorImage.addEventListener(MouseEvent.CLICK,floorClick);
init();
}
private function floorClick(event:MouseEvent):void{
if(_main._imageMouse.bitmapData == null){
return;
}
var intX:int = int(event.currentTarget.mouseX/48);
var intY:int = int(event.currentTarget.mouseY/48);
_floorList[intX][intY].bitmapData = _main._imageMouse.bitmapData;
_floorList[intX][intY].valueX = _main._imageMouse.valueX;
_floorList[intX][intY].valueY = _main._imageMouse.valueY;
}
public function init():void{
if(_map.floorImage.width > 480){
_map.barR.bak.width = 480;
_map.barR.right.x = 466;
_map.barR.addEventListener(MouseEvent.MOUSE_DOWN,barRMouseDown);
_map.barR.addEventListener(MouseEvent.MOUSE_UP,barRMouseUp);
_map.barR.left.addEventListener(MouseEvent.MOUSE_DOWN,barRUp);
_map.barR.right.addEventListener(MouseEvent.MOUSE_DOWN,barRDown);
}else{
_map.barR.visible = false;
}
if(_map.floorImage.height > 480){
_map.barC.bak.height = 480;
_map.barC.down.y = 466;
_map.barC.addEventListener(MouseEvent.MOUSE_DOWN,barCMouseDown);
_map.barC.addEventListener(MouseEvent.MOUSE_UP,barCMouseUp);
_map.barC.up.addEventListener(MouseEvent.MOUSE_DOWN,barCUp);
_map.barC.down.addEventListener(MouseEvent.MOUSE_DOWN,barCDown);
}else{
_map.barC.visible = false;
}
}
private function barCUp(event:MouseEvent):void{
_map.barC.ctrl.y -= 10;
if(_map.barC.ctrl.y < 14){
_map.barC.ctrl.y = 14;
}
mapToY();
}
private function barCDown(event:MouseEvent):void{
_map.barC.ctrl.y += 10;
if(_map.barC.ctrl.y > 416){
_map.barC.ctrl.y = 416;
}
mapToY();
}
private function barRUp(event:MouseEvent):void{
_map.barR.ctrl.x -= 10;
if(_map.barR.ctrl.x < 14){
_map.barR.ctrl.x = 14;
}
mapToX();
}
private function barRDown(event:MouseEvent):void{
_map.barR.ctrl.x += 10;
if(_map.barR.ctrl.x > 416){
_map.barR.ctrl.x = 416;
}
mapToX();
}
private function barCMouseDown(event:MouseEvent):void{
barCToMouse(event);
_map.barC.addEventListener(MouseEvent.MOUSE_MOVE,barCMouseMove);
}
private function barCMouseUp(event:MouseEvent):void{
_map.barC.removeEventListener(MouseEvent.MOUSE_MOVE,barCMouseMove);
}
private function barCMouseMove(event:MouseEvent):void{
barCToMouse(event);
}
private function barRMouseDown(event:MouseEvent):void{
barRToMouse(event);
_map.barR.addEventListener(MouseEvent.MOUSE_MOVE,barRMouseMove);
}
private function barRMouseUp(event:MouseEvent):void{
_map.barR.removeEventListener(MouseEvent.MOUSE_MOVE,barRMouseMove);
}
private function barRMouseMove(event:MouseEvent):void{
barRToMouse(event);
}
private function barRToMouse(event:MouseEvent):void{
if(event.currentTarget.mouseX < 14 || event.currentTarget.mouseX > 466){
return;
}
_map.barR.ctrl.x = event.currentTarget.mouseX - 11;
if(_map.barR.ctrl.x < 14){
_map.barR.ctrl.x = 14;
}else if(_map.barR.ctrl.x > 416){
_map.barR.ctrl.x = 416;
}
mapToX();
}
private function mapToX():void{
_map.floorImage.x = -1 * (_map.barR.ctrl.x - 14) * (_map.floorImage.width - 480) /402;
}
private function barCToMouse(event:MouseEvent):void{
if(event.currentTarget.mouseY < 14 || event.currentTarget.mouseY > 466){
return;
}
_map.barC.ctrl.y = event.currentTarget.mouseY - 11;
if(_map.barC.ctrl.y < 14){
_map.barC.ctrl.y = 14;
}else if(_map.barC.ctrl.y > 416){
_map.barC.ctrl.y = 416;
}
mapToY();
}
private function mapToY():void{
_map.floorImage.y = -1 * (_map.barC.ctrl.y - 14) * (_map.floorImage.height - 480) /402;
}
}
}
然后,建立分块儿显示的小图片类ChildFloor
package rpg_map4.other {
import flash.display.Bitmap;
public class ChildFloor extends Bitmap{
// Constants:
// Public Properties:
// Private Properties:
public var valueX:int;
public var valueY:int;
// Initialization:
public function ChildFloor() { }
// Public Methods:
// Protected Methods:
}
}
然后就是主类Main.as了
package rpg_map4.mains {
import flash.display.Bitmap;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.ui.Mouse;
import rpg_map4.map.MapImage;
import rpg_map4.other.Covert;
import rpg_map4.other.ChildFloor;
import com.ot.BaseRemove;
import com.npc.XMLLoader;
import fl.controls.Button;
import fl.controls.Label;
import fl.controls.TextInput;
import flash.net.FileReference;
import flash.net.FileFilter;
public class Main extends Sprite{
//地图画板
private var _mapImage:MapImage;
//小图片数组
public var _mapList:Array= new Array();
//地形数组
public var _mapTypeList:Array= new Array();
private var _loader:Loader;
private var _image:Bitmap;
private var _mc:Sprite;
//地图画板表示用MC
private var _mcMap:Sprite;
//小图片表示用MC
private var _mcStage:Sprite;
//地形表示用MC
private var _mcMapType:Sprite;
//鼠标Icon用
private var _mcMouse:Sprite;
//按钮表示用MC
private var _backMC:Sprite;
//新建地图按钮
private var _newBtn:Button;
//取消所选按钮
private var _canBtn:Button;
//保存地图按钮
private var _saveBtn:Button;
//载入地图按钮
private var _openBtn:Button;
//修改地形/地图按钮
private var _mapTypeBtn:Button;
//保存地形按钮
private var _typeSaveBtn:Button;
public var _imageMouse:ChildFloor = new ChildFloor();
private var _xleng:TextInput = new TextInput();
private var _yleng:TextInput = new TextInput();
//新建地图后确定按钮
private var _makeBtn:Button = new Button();
//新建地图后取消按钮
private var _canselBtn:Button = new Button();
//新建地图页面表示用MC
private var _mcMake:Sprite;
//XML载入器
private var _xmlloader:XMLLoader;
//文件操作用
private var _file:FileReference;
public function Main() {
_mc = new Sprite();
addChild(_mc);
_mcMouse = new Sprite();
addChild(_mcMouse);
_mcMouse.addChild(_imageMouse);
this..addEventListener(MouseEvent.MOUSE_MOVE,moveMouse);
//载入属性Xml
_xmlloader = new XMLLoader();
_xmlloader.onLoadComplete = initMapType;
_xmlloader.load("mapType.xml", XMLLoader.GB2312);
}
//初始化地形数组
private function initMapType(xml:XML):void{
_mcMapType = new Sprite();
var floor:FLOOR = new FLOOR();
var _lblType:Label;
_mcMapType.addChild(floor);
var i:int;
//根据xml内容,得到地形数组
for each ( var datement:XML in xml.elements( ) ) {
var dates:Array = ("" + datement).split( ",");
var mapTypeChild:Array = new Array();
for(var j=0;j<dates.length;j++){
_lblType = new Label();
_lblType.width = 24;
_lblType.height = 24;
_lblType.htmlText = '<font color="#FF0000" size="20"><b>' + dates[j] + "</b></font>";
_lblType.x = j*24;
_lblType.y = i*24;
mapTypeChild.push(_lblType);
_mcMapType.addChild(_lblType);
}
_mapTypeList.push(mapTypeChild);
i++;
}
floor.width = _mapTypeList.length * 24;
floor.height = _mapTypeList[0].length * 24;
floor.alpha = 0.5;
_loader = new Loader( );
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, setStageOver);
_loader.load(new URLRequest("images/map/stage.jpg"));
}
//初始化小图片数组
//加载按钮和事件
private function setStageOver(evt:Event):void{
_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, setStageOver);
_image = Bitmap(_loader.content);
_mapList = Covert.divide(_image,10,10);
var floor:FLOOR = new FLOOR();
_mcStage = new Sprite();
var i:int;
var j:int;
for(i = 0;i<_mapList.length;i++){
var mapChild:Array = _mapList[i];
for(j = 0;j<mapChild.length;j++){
_image = new Bitmap(mapChild[j]);
_image.scaleX = 0.5;
_image.scaleY = 0.5;
_image.x = j*24;
_image.y = i*24;
_mcStage.addChild(_image);
}
}
_mcStage.x = 540;
_mcStage.y = 20;
_mc.addChild(_mcStage);
_mcMapType.x = 540;
_mcMapType.y = 20;
_mc.addChild(_mcMapType);
_mcMapType.addEventListener(MouseEvent.CLICK,setMapType);
_mcMapType.visible = false;
_mcStage.addEventListener(MouseEvent.CLICK,selectImage);
_backMC = new Sprite();
floor = new FLOOR();
floor.width = 240;
floor.height = 260;
_backMC.x = 540;
_backMC.y = 300;
_backMC.addChild(floor);
_mc.addChild(_backMC);
_canBtn = new Button();
_canBtn.label = "取消所选";
_canBtn.x = 70;
_canBtn.y = 20;
_backMC.addChild(_canBtn);
_canBtn.addEventListener(MouseEvent.CLICK,canImage);
_canBtn.addEventListener(MouseEvent.MOUSE_MOVE,deImage);
_canBtn.addEventListener(MouseEvent.MOUSE_OUT,adImage);
_newBtn = new Button();
_newBtn.label = "新建地图";
_newBtn.x = 70;
_newBtn.y = 60;
_backMC.addChild(_newBtn);
_newBtn.addEventListener(MouseEvent.CLICK,newMap);
_newBtn.addEventListener(MouseEvent.MOUSE_MOVE,deImage);
_newBtn.addEventListener(MouseEvent.MOUSE_OUT,adImage);
_openBtn = new Button();
_openBtn.label = "载入文件";
_openBtn.x = 70;
_openBtn.y = 100;
_backMC.addChild(_openBtn);
_openBtn.addEventListener(MouseEvent.CLICK,opnFile);
_openBtn.addEventListener(MouseEvent.MOUSE_MOVE,deImage);
_openBtn.addEventListener(MouseEvent.MOUSE_OUT,adImage);
_saveBtn = new Button();
_saveBtn.label = "保存地图";
_saveBtn.x = 70;
_saveBtn.y = 140;
_backMC.addChild(_saveBtn);
_saveBtn.addEventListener(MouseEvent.CLICK,saveMap);
_saveBtn.addEventListener(MouseEvent.MOUSE_MOVE,deImage);
_saveBtn.addEventListener(MouseEvent.MOUSE_OUT,adImage);
_mapTypeBtn = new Button();
_mapTypeBtn.label = "修改地形";
_mapTypeBtn.x = 70;
_mapTypeBtn.y = 180;
_backMC.addChild(_mapTypeBtn);
_mapTypeBtn.addEventListener(MouseEvent.CLICK,changeMapType);
_saveBtn.addEventListener(MouseEvent.MOUSE_MOVE,deImage);
_saveBtn.addEventListener(MouseEvent.MOUSE_OUT,adImage);
_typeSaveBtn = new Button();
_typeSaveBtn.label = "保存地形";
_typeSaveBtn.x = 70;
_typeSaveBtn.y = 220;
_backMC.addChild(_typeSaveBtn);
_mcMap = new Sprite();
_mc.addChild(_mcMap);
_mcMake = new Sprite();
floor = new FLOOR();
floor.width = 800;
floor.height = 600;
_mcMake.addChild(floor);
var xMsg:Label = new Label();
var yMsg:Label = new Label();
xMsg.width = 200;
xMsg.text = "列数 X 行数";
xMsg.x = 300;
xMsg.y = 200;
yMsg.text = "X";
yMsg.x = 358;
yMsg.y = 250;
_xleng.x = 300;
_xleng.y = 250;
_xleng.width = 50;
_yleng.x = 375;
_yleng.y = 250;
_yleng.width = 50;
_makeBtn.label = "确定";
_makeBtn.x = 260;
_makeBtn.y = 300;
_canselBtn.label = "取消";
_canselBtn.x = 370;
_canselBtn.y = 300;
_mcMake.addChild(xMsg);
_mcMake.addChild(yMsg);
_mcMake.addChild(_xleng);
_mcMake.addChild(_yleng);
_mcMake.addChild(_makeBtn);
_mcMake.addChild(_canselBtn);
_mc.addChild(_mcMake);
_makeBtn.addEventListener(MouseEvent.CLICK,makeMap);
_canselBtn.addEventListener(MouseEvent.CLICK,canselMap);
_mcMake.visible = false;
}
//弹出载入文件框
private function opnFile(event:MouseEvent):void{
_file = new FileReference();
_file.browse([new FileFilter("XML", "*.xml") ] );
_file.addEventListener(Event.SELECT,loadMapXml);
}
//选择文件
private function loadMapXml(event:Event):void{
_file.removeEventListener(Event.SELECT,loadMapXml);
_file.load();
_file.addEventListener("complete",setLoadXml);
}
//载入所选文件
private function setLoadXml(e:Event) {
_file.removeEventListener("complete",setLoadXml);
setMapFromXml(XML(e.currentTarget.data));
}
//根据载入文件,显示地图
private function setMapFromXml(xml:XML):void{
var wMap:int = 0;
var hMap:int = 0;
var mapArr:Array = new Array();
//根据xml内容,得到地图图片数组
for each ( var element:XML in xml.imageMap.elements( ) ) {
var words:Array = ("" + element).split( ",");
wMap = words.length;
mapArr.push(words);
}
hMap = mapArr.length;
BaseRemove.removeAllChildren(_mcMap);
_mapImage = new MapImage(this);
_mapImage.x = 20;
_mapImage.y = 20;
_mcMap.addChild(_mapImage);
_mapImage.setFloor(wMap,hMap);
for(var i:int = 0;i<mapArr.length;i++){
for(var j:int = 0;j<mapArr[0].length;j++){
var childFloor:ChildFloor = _mapImage._floorList[i][j];
childFloor.valueX = mapArr[j][i]%10;
childFloor.valueY = Math.floor(mapArr[j][i]/10);
childFloor.bitmapData = _mapList[childFloor.valueY][childFloor.valueX];
}
}
}
//取消新建地图
private function canselMap(event:MouseEvent):void{
_mcMake.visible = false;
}
//保存修改地图
private function saveMap(event:MouseEvent):void{
var str:String = '<?xml version="1.0" encoding="GB2312"?>\n<data>\n';
str += '<imageMap>\n';
var strDataMap:String = "<dataMap>\n";
var floorArr:Array = _mapImage._floorList;
for(var i:int = 0;i<floorArr.length;i++){
str += '<list>';
strDataMap += '<list>';
var strAdd:String = "";
for(var j:int = 0;j<floorArr[0].length;j++){
var childFloor:ChildFloor = floorArr[j][i];
var num:int =childFloor.valueY*10 + childFloor.valueX;
str += strAdd + num;
strDataMap += strAdd + _mapTypeList[childFloor.valueY][childFloor.valueX].text;
strAdd = ",";
}
str += '</list>\n';
strDataMap += '</list>\n';
}
str += '</imageMap>\n';
strDataMap += "</dataMap>\n";
str += strDataMap;
str += '</data>';
_file = new FileReference();
_file.save(str,"newMap.xml");
}
//保存修改地形文件/*必须跟地图编辑器在同一文件夹下*/
private function saveMapType(event:MouseEvent):void{
var str:String = '<?xml version="1.0" encoding="GB2312"?>\n<data>\n';
for(var i:int = 0;i<_mapTypeList.length;i++){
var mapTypeChild:Array = _mapTypeList[i];
var stri:String = "";
var strjAdd:String = "";
for(var j:int = 0;j<mapTypeChild.length;j++){
var strj:String = mapTypeChild[j].text;
stri += strjAdd + strj;
strjAdd = ",";
}
str += '<list>' + stri + '</list>\n';
}
str += '</data>';
_file = new FileReference();
_file.save(str,"mapType.xml");
}
//修改地图与修改地形切换
private function changeMapType(event:MouseEvent):void{
if(!_mcMapType.visible){
_mcMapType.visible = true;
_mapTypeBtn.label = "修改地图";
_typeSaveBtn.addEventListener(MouseEvent.CLICK,saveMapType);
}else{
_mcMapType.visible = false;
_mapTypeBtn.label = "修改地形";
_typeSaveBtn.removeEventListener(MouseEvent.CLICK,saveMapType);
}
}
//地形编辑
private function setMapType(event:MouseEvent):void{
var intX:int = int(event.currentTarget.mouseX/24);
var intY:int = int(event.currentTarget.mouseY/24);
var lblType:Label = _mapTypeList[intY][intX];
if(lblType.text == "1"){
lblType.htmlText = '<font color="#FF0000" size="20"><b>0</b></font>';
}else{
lblType.htmlText = '<font color="#FF0000" size="20"><b>1</b></font>';
}
}
//新建地图
private function newMap(event:MouseEvent):void{
_mcMake.visible = true;
_xleng.text = "";
_yleng.text = "";
}
//鼠标显示
private function deImage(event:MouseEvent):void{
_imageMouse.visible = false;
Mouse.show();
}
//鼠标隐藏
private function adImage(event:MouseEvent):void{
_imageMouse.visible = true;
if(_imageMouse.bitmapData != null){
Mouse.hide();
}
}
//选择小图片并跟随鼠标移动,隐藏鼠标
private function selectImage(event:MouseEvent):void{
var intX:int = int(event.currentTarget.mouseX/24);
var intY:int = int(event.currentTarget.mouseY/24);
_imageMouse.bitmapData = _mapList[intY][intX];
_imageMouse.valueX = intX;
_imageMouse.valueY = intY;
Mouse.hide();
}
//取消选择小图片,显示鼠标
private function canImage(event:MouseEvent):void{
_imageMouse.bitmapData = null;
Mouse.show();
}
//小图片跟随鼠标移动
private function moveMouse(event:MouseEvent):void{
_imageMouse.x = event.currentTarget.mouseX ;
_imageMouse.y = event.currentTarget.mouseY;
}
//新建地图
private function makeMap(event:MouseEvent):void{
if(_xleng.text == "" || _yleng.text == ""){
return;
}
_mcMake.visible = false;
BaseRemove.removeAllChildren(_mcMap);
_mapImage = new MapImage(this);
_mapImage.x = 20;
_mapImage.y = 20;
_mcMap.addChild(_mapImage);
_mapImage.setFloor(int(_xleng.text),int(_yleng.text));
}
}
}
运行代码,就可以开始轻松的编辑地图了
[img]http://i818.photobucket.com/albums/zz104/lufy_photo/makemap.gif?t=1274090079[/img]
这样配合我的那个简单的RPG,也可以算是一个简单的游戏引擎了,哈哈
所有源代码,请看一楼附件
[color=Silver][[i] 本帖最后由 lufy 于 2010-5-17 18:41 编辑 [/i]][/color]
2010-5-17 19:36
司徒苍月
如果是rpg那还好点,如果是srpg(rpg+slg),光是AI算法就很让人头疼了,我想问一下,如果你是楼主你,你打算怎么实现AI算法
ps bug还不少,例如刘备上来和关羽对话就死机了:hz1031:
[color=Silver][[i] 本帖最后由 司徒苍月 于 2010-5-17 19:38 编辑 [/i]][/color]
2010-5-18 08:30
lufy
bug是在关羽对话的文件中,我多加了一个战场fight002的跳转,而我上传的时候,把这个战场文件删除了,我直接把对话文件中的att事件删除,就正常了,现在重新上传了下
现在这个是一个简单的RPG,貌似现在这样倒像是一个吞食天地简化版,如果是SLG,确实要麻烦些,打算下次有时间了,研究下用flash试着实现一个简单版的曹操传,再具体研究SLG的AI
2010-6-8 18:29
小妖在城市
&quot;9RIA天地会&quot;官方合作
2012-9-26 16:56
wam0277
好东西啊,正是需要的
2012-9-30 21:10
yjr3426619
拜读了一下,不明白最开始那个分割地图的时候为什么要将矩阵的焦点设为负数?求解
2012-10-13 12:22
凯旋JK
受教了,但F完有时候就会有错位现象,再重新编辑地址才回复状态:hz1013:
2013-8-11 20:56
xggzga117
好东西,收藏了慢慢学习。
2013-8-11 22:13
董家小四
用RPGVA就可以做出游戏,有人用这个软件做出了dnf单机版
2013-9-4 20:03
xggzga117
RM本来就简单,何况是最近出的VA。
能写代码才是真正的高手。
页:
[1]
Powered by Discuz! Archiver 5.0.0
© 2001-2006 Comsenz Inc.