标题: 用AS3.0开发flash版曹操传-初级, 撤退,反击,双击,致命一击,源代码
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


用AS3.0开发flash版曹操传-初级

以前也曾因为研究曹操传MOD而废寖忘食,却没想到曹操传MOD已经发展到现在这种地步,但是,修改永远是修改,总会遇到各种限制,想要突破,当然要自己动手,开发自己的引擎。
但是,在这里,我研究flash版的曹操传,目的并不是想要有任何突破,只是单纯的为了研究一下,熟悉一下用flash完成各种游戏的制作而已。
那下面就开始了。

2楼:建立战场
3楼:人物显示
4楼:控制人物移动和菜单的显示
5楼:2,3,4楼的源代码
7楼:显示一下地形
8楼:多地形下的寻路
9楼:加入敌军,攻击范围的显示
10楼:敌军行动
11楼:在战场上显示人物属性
12楼:我军攻击
15楼:敌军攻击
19楼:伤害显示
21楼:撤退
22楼:反击
23楼:双击和致命一击
24楼:23楼之前的源代码















[ 本帖最后由 lufy 于 2010-6-2 08:53 编辑 ]


顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


首先,先建立一个战场,显示一张地图吧,
导出一张曹操传第一关颖川的地图,把它转化成gif格式,命名为1.gif待用
然后,建立1S.xml,作为S剧本,内容
<?xml version="1.0" encoding="GB2312"?>
<data>
    <Map>1</Map>
</data>
里面的1就是地图的代号,对应的地图就是1.gif了
要显示它,就很简单了
建立两个Sprite,
//最底层Sprite
private var _bakSprite:Sprite;
//地图Sprite
private var _mapSprite:Sprite;
将地图建立在底层的Sprite,方便之后操作
_bakSprite.addChild(_mapSprite);

//加载地图
_pic_loader = new Loader();
_pic_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteMap);
var mapName:String = "Images/HM/" + _fightXml.Map + ".gif";
_pic_loader.load(new URLRequest(mapName));

//加载地图完毕
private function onCompleteMap(event:Event):void {
    _pic_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onCompleteMap);
    _image = Bitmap(_pic_loader.content);
    _mapSprite.addChild(_image);
}
然后,一张地图,就可以显示出来了
当然,光显示出来还不行,因为地图很大,窗口显示不了全部的地图,这样,就要像曹操传中的那样,当鼠标移动到边界的时候,地图就发生移动,看到自己想看的位置
所以,需要加入鼠标移动事件
                        //鼠标移动事件
                        this.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);

                //鼠标移动事件
                private function mouseMoveHandler(event:MouseEvent):void{
                        var intX:int = event.currentTarget.mouseX;
                        var intY:int = event.currentTarget.mouseY;
                        if(intX < 48){
                                 _mapXadd = 48;
                        }else        if(intX > Sav.gamedata["stageWidth"] - 48){
                                _mapXadd = -48;
                        }else{
                                _mapXadd = 0;
                        }
                        if(intY < 48){
                                _mapYadd = 48;
                        }else        if(intY > Sav.gamedata["stageHeight"] - 48){
                                _mapYadd = -48;
                        }else{
                                _mapYadd = 0;
                        }
                }
Sav.gamedata["stageWidth"] 是flash窗口的宽度,我把它存在了静态变量里了,方便用的时候取出来
这样,根据鼠标和地图位置,先来确定地图移动的x,y的方向和步长
然后,加入一个贞事件,来控制地图的移动
                        //贞事件
                        this.addEventListener(Event.ENTER_FRAME, mapMoveHandler);
                //贞事件
                private function mapMoveHandler(event:Event):void{
                        if(_mapMoveCtrl > 5){
                                //根据地图移动用xy步长移动地图
                                _bakSprite.x += _mapXadd;
                                _bakSprite.y += _mapYadd;
                                _mapMoveCtrl = 0;
                        }
                        //控制地图不移出指定范围
                        if(_bakSprite.x > 0){
                                _bakSprite.x = 0;
                        }else if( _bakSprite.x < Sav.gamedata["stageWidth"] - _bakSprite.width){
                                _bakSprite.x = Sav.gamedata["stageWidth"] - _bakSprite.width;
                        }
                        if(_bakSprite.y > 0){
                                _bakSprite.y = 0;
                        }else if( _bakSprite.y < Sav.gamedata["stageHeight"] - _bakSprite.height){
                                _bakSprite.y = Sav.gamedata["stageHeight"] - _bakSprite.height;
                        }
                        _mapMoveCtrl ++;
                }
_mapMoveCtrl 用来控制地图移动的速度,然后只要控制地图不移出指定的范围就可以了
这样,运行一下,就可以让地图自由的移动位置了


顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


接下来,让地图上显示一个人物
导出曹操传中曹操的三个图片,去除背景,并保存为gif格式,就像下面这样

首先,在1S.xml中加入
    <Our>
        <List>Caocao</List>
    </Our>
建立一个用来显示人物动作的类CharacterMC,
在类里面,读取完图片之后,将其按照规律拆分成数组,和之前我在做flashRPG游戏的时候一样,用的同样的方法,
                //Unit_mov图片加载完成
                public function onCompleteUnit_mov(event:Event):void {
                        _image = Bitmap(_loader.content);
                        //初始化显示数组
                        _bitShowArr = new Array();
                        //将位图数据拆分成小块,装入bitmapArr
                        _bitmapArr=ImageCtrl.divide(_image,1,11);
                        var newArr:Array;
                        //得到向上行走数组
                        newArr = new Array(_bitmapArr[2][0],_bitmapArr[3][0]);
                        //将向上行走数组加入到显示数组 编号:0
                        _bitShowArr.push(newArr);
                        //得到向下行走数组
                        newArr = new Array(_bitmapArr[0][0],_bitmapArr[1][0]);
                        //将向下行走数组加入到显示数组 编号:1
                        _bitShowArr.push(newArr);
                        //得到向左行走数组
                        newArr = new Array(_bitmapArr[4][0],_bitmapArr[5][0]);
                        //将向左行走数组加入到显示数组 编号:2
                        _bitShowArr.push(newArr);
                        //得到向右行走数组
                        newArr = new Array(ImageCtrl.bitHorizontal(_bitmapArr[4][0]),ImageCtrl.bitHorizontal(_bitmapArr[5][0]));
                        //将向右行走数组加入到显示数组 编号:3
                        _bitShowArr.push(newArr);
                       
                        startFrame();
                }
然后显示的时候,只需要调用不同的编号,就可以显示不同的动作了
新建一个人物属性类,Character ,存放人物的属性
        public class Character {
                //人物显示控制类
                private var _characterMC:CharacterMC;
                //人物移动力
                private var _moveLong:int;
                //人物编号
                private var _charaIndex:int;

然后在战场上,再另建一个Sprite,用来显示人物
                //人物Sprite
                private var _characterSprite:Sprite;
然后,在读取S剧本完成时,把人物加入
                        //我军人物添加
                        _ourArr = new Array();
                        //根据xml内容,得到我军人物,添加至战场
                        for each ( var ourment:XML in _fightXml.Our.elements( ) ) {
                                var ourName:String = ourment.toString();
                                var ourchara:XML = XML(_pXml[ourName]);
                                _characterMC = new CharacterMC(int(ourchara.Id));
                                _character = new Character(_characterMC,int(ourchara.Move),int(ourchara.Id));
                                _characterSprite.addChild(_characterMC);
                                _ourArr.push(_character);
                        }
运行就可以看到曹操出现在战场上了

下面,开始控制曹操移动
顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


首先,先在CS4里,建立一个MC,加入三个按钮,如图


我暂时把地形全都设定成为可移动,且地形全都消耗1,1S.xml中
    <DataMap>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
        <list>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</list>
    </DataMap>

加入鼠标点击事件
                        //鼠标点击事件
                        addEventListener(MouseEvent.CLICK,onClick);

                //鼠标点击事件
                private function onClick(event:Event):void{
                        var __mouseX:Number = event.currentTarget.mouseX;
                        var __mouseY:Number = event.currentTarget.mouseY;
                        var i:int;
                        if(_clickCtrl == "NULL"){
                                for(i=0;i<_ourArr.length;i++){
                                        _character = _ourArr as Character;
                                        _characterMC = _character.characterMC;
                                        if(Math.floor(_characterMC.x/48) == Math.floor(__mouseX/48) && Math.floor(_characterMC.y/48) == Math.floor(__mouseY/48)){
                                                _nowChatacter = _character;
                                                setRoad(_nowChatacter);
                                                _clickCtrl = "ROAD_SHOW";
                                                removeEventListener(MouseEvent.CLICK,onClick);
                                                _roadSprite.addEventListener(MouseEvent.CLICK,onClick);
                                                break;
                                        }
                                }
                        }else if(_clickCtrl == "ROAD_SHOW"){
                                _characterMC = _nowChatacter.characterMC;
                                for(i=0;i<_roadShowArray.length;i++){
                                                _nowPoint = new Point(Math.floor(_characterMC.x/48),Math.floor(_characterMC.y/48));
                                                _nowDirection = _characterMC.getDir();
                                                _toPoint = new Point(Math.floor(__mouseX/48),Math.floor(__mouseY/48));
                                                _roadArray = _roadQuery.path4(_nowPoint,_toPoint,_roadShowArray);
                                                if(_roadArray != null && _roadArray.length > 0){
                                                        addEventListener(Event.ENTER_FRAME, onFrame);
                                                        _clickCtrl == "MOVE_NOW"
                                                        SpriteRemove.removeAllChildren(_roadSprite);
                                                        _roadSprite.removeEventListener(MouseEvent.CLICK,onClick);
                                                }
                                }
                        }
                       
                       
                }
_clickCtrl 用来控制点击鼠标时,战场上的状态,当为NULL的时候,寻找点击的人物,然后开始寻找最大可移动的范围
                                //循环搜寻可到达的点
                                public function loopPath(thisPoint:Object):void{
                                        if(thisPoint.moveLong <= 0){
                                                return;
                                        }
                                       
                                         if(! thisPoint.isChecked){
                                                _path.push(thisPoint);
                                                 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]);
                    }
                                        for(var i=0;i<checkList.length;i++){
                                                if(!checkList.isChecked || checkList.moveLong < thisPoint.moveLong){
                                                        checkList.moveLong = thisPoint.moveLong - 1;
                                                        loopPath(checkList);
                                                }
                                        }       
                                }
                                //搜寻最大路径
                public function makePath(star:Point, moveLong:int):Array {
                    _path = [];
                    var isOver:Boolean = false;
                    setStart();
                    _starPoint = _map[star.y][star.x];
                                        _starPoint.moveLong = moveLong;
                                        loopPath(_starPoint);
                                        return _path;
                                }

最大路径找好后,点击目标点,利用A*算法,走到目标点
_clickCtrl 用来控制点击鼠标时,战场上的状态,当为ROAD_SHOW的时候,查找路径,并走到目标点
A*算法,比较麻烦,就不多解释了,想了解的,可以看源代码
然后,行走完毕后,要显示出选择菜单,
                //人物移动事件贞控制
                private function onFrame(event:Event):void {
                        _characterMC = _nowChatacter.characterMC;
                        if(_roadArray != null && _roadArray.length > 1){
                                if(_characterMC.x % 48 == 0 && _characterMC.y % 48 == 0){
                                         if(_roadArray[0].x == _roadArray[1].x){
                                                if(_roadArray[0].y > _roadArray[1].y){
                                                        _characterMC.setDir(0);
                                                        _xadd = 0;
                                                        _yadd = -_addLeng;
                                                }else{
                                                        _characterMC.setDir(1);
                                                        _xadd = 0;
                                                        _yadd = _addLeng;
                                                }
                                        }else{
                                                if(_roadArray[0].x > _roadArray[1].x){
                                                        _characterMC.setDir(2);
                                                        _xadd = -_addLeng;
                                                        _yadd = 0;
                                                }else{
                                                        _characterMC.setDir(3);
                                                        _xadd = _addLeng;
                                                        _yadd = 0;
                                                }
                                        }                                       

                                        _roadArray.splice(0,1);
                                       
                                }
                                _characterMC.x += _xadd;
                                _characterMC.y += _yadd;
                                
                        }else if(_characterMC.x % 48 == 0 && _characterMC.y % 48 == 0){
                                removeEventListener(Event.ENTER_FRAME, onFrame);
                                _selectBox.visible = true;
                                _selectBox.x = _characterMC.x + 48;
                                _selectBox.y = _characterMC.y;
                        }else{
                       
                                _characterMC.x += _xadd;
                                _characterMC.y += _yadd;
                        }
                }
所以在战场初始化的时候,加入菜单按钮等事件
                       
                        //点击停止事件
                        _selectBox.btnStop.addEventListener(MouseEvent.CLICK, charaStopHandler);
                        //点击取消事件
                        _selectBox.btnCan.addEventListener(MouseEvent.CLICK, charaCanHandler);
                        //菜单隐藏
                        _selectBox.visible = false;
效果如下图


[ 本帖最后由 lufy 于 2010-5-19 22:54 编辑 ]
顶部
性别:男-离线 moyanxiawei123
(默言)


Rank: 12Rank: 12Rank: 12
轩辕春秋年度最佳(轩辕工作室)
组别 羽林都尉
级别 征南将军
功绩 86
帖子 4569
编号 271179
注册 2008-3-15
来自 浙江
家族 默家派学院


发表于 2010-5-19 22:43 资料 个人空间 短消息 只看该作者
又有一位高人出现了,又有一种新形式的曹操传MOD出现了,又有一场新浪潮要被挂起来了,又有..
顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


这是以上的源代码,有兴趣的一起研究下


附件: [源代码] CaoCao.rar (2010-5-19 22:47, 641.83 K)
该附件被下载次数 630
顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


接下来,显示一下地形,
准备一个Terrain.xml
<?xml version="1.0" encoding="GB2312"?>
<data>
    <Terrain0>
        <Name>平原</Name>
        <Image></Image>
    </Terrain0>
    <Terrain1>
        <Name>草原</Name>
        <Image></Image>
    </Terrain1>
    <Terrain2>
        <Name>树林</Name>
        <Image></Image>
    </Terrain2>
</data>
暂时添加这三个地形,等有时间了之后,再慢慢加
然后,在CS4里,建立一个MC,如下,用来显示地形



剩下的就简单了,
在战场的鼠标点击事件中,当状态为NULL的时候,
                        if(_clickCtrl == "NULL"){
                                var queryPeople:Boolean = false;
                                //点击我军人物判断
                                for(i=0;i<_ourArr.length;i++){
                                        _character = _ourArr as Character;
                                        _characterMC = _character.characterMC;
                                        if(Math.floor(_characterMC.x/48) == Math.floor(__mouseX/48) && Math.floor(_characterMC.y/48) == Math.floor(__mouseY/48)){
                                                _nowChatacter = _character;
                                                setRoad(_nowChatacter);
                                                _clickCtrl = "ROAD_SHOW";
                                                removeEventListener(MouseEvent.CLICK,onClick);
                                                _roadSprite.addEventListener(MouseEvent.CLICK,onClick);
                                                queryPeople = true;
                                                break;
                                        }
                                }
                                //点击敌军人物判断
                                for(i=0;i<_enemyArr.length;i++){
                                        //点击敌军人物动作
                                }
                                if(!queryPeople){
                                        //点击地图,显示地形
                                        _clickCtrl = "TERRAIN_SHOW";
                                        var mapX:int = Math.floor((__mouseX - _bakSprite.x)/48);
                                        var mapY:int = Math.floor((__mouseY - _bakSprite.y)/48);
                                        var showX:int = Math.floor(__mouseX/48);
                                        var showY:int = Math.floor(__mouseY/48);
                                        var terrainId:int = _mapDate[mapX][mapY];
                                        var terrainName:String = "Terrain" + terrainId;
                                        _terrainBox.x = showX*48 - 48;
                                        _terrainBox.y = showY*48 - 48;
                                        if(_terrainBox.x < 0){
                                                _terrainBox.x = 0;
                                        }else if(_terrainBox.x > Sav.gamedata["stageWidth"] - 144){
                                                _terrainBox.x = Sav.gamedata["stageWidth"] - 144;
                                        }
                                        if(_terrainBox.y < 0){
                                                _terrainBox.y = 0;
                                        }else if(_terrainBox.y > Sav.gamedata["stageHeight"] - 144){
                                                _terrainBox.y = Sav.gamedata["stageHeight"] - 144;
                                        }
                                        _terrainBox.TerrainName.text = _terrain[terrainName].Name;
                                        SpriteRemove.removeAllChildren(_terrainBox.TerrainShow);
                                        _terrainBox.TerrainShow.addChild(ImageCtrl.getImage(_bmapimage,mapX*48,mapY*48,48,48));
                                        removeEventListener(MouseEvent.CLICK,onClick);
                                        _terrainBox.visible = true;
                                }
                        }else if(_clickCtrl == "ROAD_SHOW"){
就是说,点击的地方如果没有人,则显示地形框
然后,在鼠标移动的时候,把地形框隐藏掉
                //鼠标移动事件
                private function mouseMoveHandler(event:MouseEvent):void{
                        var intX:int = event.currentTarget.mouseX;
                        var intY:int = event.currentTarget.mouseY;
                        if(intX < 48){
                                 _mapXadd = 48;
                        }else        if(intX > Sav.gamedata["stageWidth"] - 48 && intX <= Sav.gamedata["stageWidth"]){
                                _mapXadd = -48;
                        }else{
                                _mapXadd = 0;
                        }
                        if(intY < 48){
                                _mapYadd = 48;
                        }else        if(intY > Sav.gamedata["stageHeight"] - 48 && intY <= Sav.gamedata["stageHeight"]){
                                _mapYadd = -48;
                        }else{
                                _mapYadd = 0;
                        }
                        if(_terrainBox.visible){
                                _clickCtrl = "NULL";
                                _terrainBox.visible = false;
                                addEventListener(MouseEvent.CLICK,onClick);
                        }
                }
看吧,效果如下图


因为地形我全都设定成了0,所以现在点哪里都是平原

剩下的就是把1S.xml的地形好好设定下了

下次,研究在各种地形下行走的范围^0^!
顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


下面,来继续在不同地形下的寻路问题
首先,准备好兵种数据Arms.xml
<?xml version="1.0" encoding="GB2312"?>
<data>
    <Arms1>
        <Name>英雄</Name>
        <Property>
            <Attack>A</Attack>
            <Spirit>A</Spirit>
            <Defense>A</Defense>
            <Breakout>A</Breakout>
            <Morale>A</Morale>
        </Property>
        <Terrain>
            <Terrain0>1</Terrain0>
            <Terrain1>1</Terrain1>
            <Terrain2>2</Terrain2>
            <Terrain3>100</Terrain3>
            <Terrain4>100</Terrain4>
            <Terrain5>1</Terrain5>
            <Terrain6>1</Terrain6>
            <Terrain7>1</Terrain7>
        </Terrain>
    </Arms1>
</data>
地形数据Terrain.xml
<?xml version="1.0" encoding="GB2312"?>
<data>
    <Terrain0>平原</Terrain0>
    <Terrain1>草原</Terrain1>
    <Terrain2>树林</Terrain2>
    <Terrain3>大河</Terrain3>
    <Terrain4>栅栏</Terrain4>
    <Terrain5>城池</Terrain5>
    <Terrain6>村庄</Terrain6>
    <Terrain7>帐篷</Terrain7>
</data>
人物属性上当然要对应好兵种
<?xml version="1.0" encoding="GB2312"?>
<data>
    <Caocao>
        <Id>1</Id>
        <Name>曹操</Name>
        <Arms>1</Arms>
        <Lv>1</Lv>
        <Exp>0</Exp>
        <HP>100</HP>
        <MP>50</MP>
        <Move>5</Move>
    </Caocao>
</data>
其中,Arms是兵种ID,Move是移动力
最后,设定下战场文件1S.xml
<?xml version="1.0" encoding="GB2312"?>
<data>
    <Map>1</Map>
    <DataMap>
        <list>1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1</list>
        <list>3,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1</list>
        <list>3,3,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1</list>
        <list>3,3,3,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,3,3</list>
        <list>3,3,3,3,1,1,1,0,0,0,0,1,1,1,1,1,1,3,3,3</list>
        <list>3,3,3,3,3,1,1,0,0,0,0,0,1,1,1,1,1,3,3,3</list>
        <list>3,3,3,3,3,4,4,4,4,0,0,4,4,4,4,1,1,3,3,3</list>
        <list>3,3,3,3,3,4,6,0,0,0,0,0,0,6,4,1,3,3,3,3</list>
        <list>3,3,3,3,3,4,6,0,0,0,0,0,0,6,4,1,3,3,3,3</list>
        <list>3,3,3,3,0,4,6,0,0,0,0,0,0,0,4,1,3,3,3,3</list>
        <list>3,3,3,0,0,0,0,0,0,4,4,0,0,0,4,3,3,3,3,3</list>
        <list>3,3,0,0,0,0,0,0,0,5,7,0,0,0,4,3,3,3,3,3</list>
        <list>3,0,0,0,0,4,0,0,0,0,0,0,0,0,4,3,3,3,3,3</list>
        <list>0,0,0,0,0,4,6,6,0,0,0,0,0,7,4,0,3,3,3,3</list>
        <list>0,0,0,0,0,4,4,4,4,0,0,4,4,4,4,0,1,1,3,3</list>
        <list>0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,3</list>
        <list>1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1</list>
        <list>1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1</list>
        <list>1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1</list>
        <list>1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1</list>
    </DataMap>
    <Our>
        <List x="10" y="5">Caocao</List>
    </Our>
    <Enemy />
</data>

然后开始利用这些数据,完成寻路
首先在添加战场人物的时候,要把相应的兵种和移动力都得到
                        //我军人物添加
                        _ourArr = new Array();
                        //根据xml内容,得到我军人物,添加至战场
                        for each ( var ourment:XML in _fightXml.Our.elements( ) ) {
                                var ourName:String = ourment.toString();
                                var ourchara:XML = XML(_pXml[ourName]);
                                _characterMC = new CharacterMC(int(ourchara.Id));
                                _characterMC.x = int(ourment.@x)*48;
                                _characterMC.y = int(ourment.@y)*48;
                                _character = new Character(_characterMC,int(ourchara.Move),int(ourchara.Id),int(ourchara.Arms));
                                _characterSprite.addChild(_characterMC);
                                _ourArr.push(_character);
                        }
Character类中,加入兵种ID属性就可以了

然后,寻路的时候,把当前人物传到makePath方法中

                //寻找最大移动范围
                private function setRoad(chara:Character){
                        _roadShowArray = _roadQuery.makePath(chara);
                       
                        if(_roadShowArray != null && _roadShowArray.length > 0){
                                var sign:Sign;
                                for(var i:int = 0;i<_roadShowArray.length;i++){
                                        sign = new Sign();
                                        sign.x = _roadShowArray.x * 48;
                                        sign.y = _roadShowArray.y * 48;
                                        _roadSprite.addChild(sign);
                                }
                        }
                }

_roadQuery方法中,移动力和起始坐标都根据当前人物得到
                public function makePath(chara:Character):Array {
                                        _chara = chara;
                    _path = [];
                    var isOver:Boolean = false;
                    setStart();
                    _starPoint = _map[Math.floor(chara.characterMC.y/48)][Math.floor(chara.characterMC.x/48)];
                                        _starPoint.moveLong = chara.moveLong;
                                        loopPath(_starPoint);
                                        return _path;
                                }
然后,在loopPath方法中,做最后的修改
checkPoint.moveLong = thisPoint.moveLong - 1;是用来计算下一个点的剩余移动力的,
之前,所有点的移动力都是由当前点的移动力-1
把它改为
var cost:int = int(XML(Sav.gamedata["Arms"])["Arms" + _chara.armsIndex]["Terrain"]["Terrain" + _map[checkPoint.y][checkPoint.x].value]);
                                                        checkPoint.moveLong = thisPoint.moveLong - cost;
就是减去下一个点的消耗移动力,这个消耗移动力在兵种数据文件中已经设定好了,直接读取就可以了
运行代码,效果如下


下次,该研究一下,加入敌军的人物问题了

[ 本帖最后由 lufy 于 2010-5-21 13:04 编辑 ]
顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


其实,加入敌军人物,只需要在1S.xml中加入几个人物就可以了
    <Our>
        <List x="10" y="4">1</List>
        <List x="10" y="5">98</List>
    </Our>
    <Enemy>
        <List x="12" y="5">100</List>
        <List x="16" y="5">103</List>
    </Enemy>
然后配置好,相应的兵种数据和人物数据,就可以在战场上显示了
剩下的还要改动一下寻路的方法,把战场上有人物的地方,改为消耗移动力100

                public function makePath(chara:Character):Array {
                                        _chara = chara;
                    _path = [];
                    var isOver:Boolean = false;
                    setStart();
                                        _enemyCost = new Object();
                                        var i:int = 0;
                                        var objarr:Array;
                                        objarr = _fightMap.enemyArr;
                                        for(i=0;i<objarr.length;i++){
                                                _enemyCost[objarr.locationX + "-" +objarr.locationY] = 100;
                                        }
                                        objarr = _fightMap.ourArr;
                                        for(i=0;i<objarr.length;i++){
                                                _enemyCost[objarr.locationX + "-" +objarr.locationY] = 100;
                                        }
                    _starPoint = _map[Math.floor(chara.character.y/48)][Math.floor(chara.character.x/48)];
                                        _starPoint.moveLong = chara.moveLong;
                                        loopPath(_starPoint);
                                       
                                        return _path;
                                }

                                public function loopPath(thisPoint:Object):void{
                                        if(thisPoint.moveLong <= 0){
                                                return;
                                        }
                                       
                                         if(! thisPoint.isChecked){
                                                _path.push(thisPoint);
                                                 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]);
                    }
                                        for(var i=0;i<checkList.length;i++){
                         var checkPoint:Object = checkList;
                                                if(!checkPoint.isChecked || checkPoint.moveLong < thisPoint.moveLong){
                                                        var cost:int = int(XML(Sav.gamedata["Arms"])["Arms" + _chara.armsIndex]["Terrain"]["Terrain" + _map[checkPoint.y][checkPoint.x].value]);
                                                        cost += _enemyCost[checkPoint.x + "-" + checkPoint.y] == null ? 0:_enemyCost[checkPoint.x + "-" + checkPoint.y];
                                                        checkPoint.moveLong = thisPoint.moveLong - cost;
                                                        loopPath(checkPoint);
                                                }
                                        }       
                                }
这样战场上有人的地方就移动不过去了

接下来,来给每个人加上攻击范围的光标
准备好攻击范围显示的光标MC

然后,在相应的兵种数据中加上攻击范围的控制
如英雄
    <Arms1>
        <Name>英雄</Name>
        <Property>
            <Attack>A</Attack>
            <Spirit>A</Spirit>
            <Defense>A</Defense>
            <Breakout>A</Breakout>
            <Morale>A</Morale>
        </Property>
        <Terrain>
            <Terrain0>1</Terrain0>
            <Terrain1>1</Terrain1>
            <Terrain2>2</Terrain2>
            <Terrain3>100</Terrain3>
            <Terrain4>100</Terrain4>
            <Terrain5>1</Terrain5>
            <Terrain6>1</Terrain6>
            <Terrain7>1</Terrain7>
        </Terrain>
        <RangeAttack>
            <List>0,-1</List>
            <List>0,1</List>
            <List>-1,0</List>
            <List>1,0</List>
        </RangeAttack>
    </Arms1>
其中RangeAttack代表以当前人物为坐标的相对攻击范围
然后在战场类中加一个函数
                //攻击范围显示
                private function setAttRound(armIndex:int):void{
                        var attRoundArr:Array;
                        var attRound:AttBox;
                        for each ( var roundment:XML in _arms["Arms" + armIndex]["RangeAttack"].elements( ) ) {
                                attRound = new AttBox();
                                attRoundArr = roundment.toString().split(",");
                                attRound.x = (int(attRoundArr[0]) + _nowChatacter.locationX )*48;
                                attRound.y = (int(attRoundArr[1]) + _nowChatacter.locationY) *48;
                                _roadSprite.addChild(attRound);
                        }
                       
                }
其中AttBox是预先准备好的攻击范围显示的光标MC
然后,在寻找最大行动范围的时候,调用这个函数
就可以显示攻击范围了,效果如图


接下来,研究一下回合控制,和敌军回合的时候,敌军的行动:wink:

[ 本帖最后由 lufy 于 2010-5-23 15:51 编辑 ]
顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


这次除了添加一些东西外,改动也比较大
具体改了哪里,也忘了做记录了
最后成形的战场类代码如下FightMap .as

package Caocao.Mains{
        import Lufy.Images.ImageCtrl;
        import Lufy.Sprite.SpriteRemove;
        import Caocao.Character.CharacterMC;
        import Caocao.Character.Character;
        import Caocao.ot.RoadQuery;
        import Lufy.Xml.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;
        import flash.text.*;
       
        public class FightMap extends Sprite {
                //最底层Sprite
                private var _bakSprite:Sprite;
                //地图Sprite
                private var _mapSprite:Sprite;
                //人物Sprite
                private var _characterSprite:Sprite;
                //通路Sprite
                private var _roadSprite:Sprite;
                //战场Xml
                private var _fightXml:XML;
                //地形数组
                private var _mapData:Array;
                //图片载入器
                private var _pic_loader:Loader;
                //xml载入器
                private var _xml_loader:XMLLoader;
                //声明Bitmap
                private var _image:Bitmap;
                //大地图Bitmap
                private var _bmapimage:Bitmap;
                //人物类
                private var _character:Character;
                private var _characterMC:CharacterMC;
                private var _nowChatacter:Character;
                //我军数组
                private var _ourArr:Array;
                //敌军数组
                private var _enemyArr:Array;
                //寻路类
                private var _roadQuery:RoadQuery;
                //储存路径数组
                private var _roadArray:Array;
                //表示路径数组
                private var _roadShowArray:Array;
                //人物移动控制
                private var _xadd:int = 0;
                private var _yadd:int = 0;
                //人物移动步长
                private var _addLeng:int = 4;
                //移动起始坐标
                private var _nowPoint:Point;
                //移动起始方向
                private var _nowDirection:int;
                //移动目的地坐标
                private var _toPoint:Point;
                //点击动作控制
                private var _clickCtrl:String = "NULL";
                //人物数据
                private var _pXml:XML;
                //地形数据
                private var _terrain:XML;
                //兵种数据
                private var _arms:XML;
                //选择菜单
                private var _selectBox:SelectBox;
                //地图移动速度控制
                private var _mapMoveCtrl:int = 0;
                //地图移动用xy步长
                private var _mapXadd:int = 0;
                private var _mapYadd:int = 0;
                //地形框
                private var _terrainBox:TerrainShowBox;
                //回合控制
                private var _roundCtrl:String = "我方回合";
                //回合数
                private var _roundIndex:int = 1;
                //鼠标框
                private var _mouseBox:MouseBox;
                //敌方行动控制用
                private var _enemyActionCtrl:int = 0;
                //回合显示信息
                private var _roundShow:TextField ;
                //回合显示信息控制用
                private var _roundShowCtrl:int = 0;
                public function FightMap(mapXmlSrc:String,fun:Function,gameMap:GameStart) {
                        //添加显示Sprite
                        _bakSprite = new Sprite();
                        addChild(_bakSprite);
                        _mapSprite = new Sprite();
                        _bakSprite.addChild(_mapSprite);
                        _characterSprite = new Sprite();
                        _bakSprite.addChild(_characterSprite);
                        _roadSprite = new Sprite();
                        _bakSprite.addChild(_roadSprite);
                       
                        _mouseBox = new MouseBox();
                        _bakSprite.addChild(_mouseBox);
                       
                        _selectBox = new SelectBox();
                        _bakSprite.addChild(_selectBox);
                       
                        _terrainBox = new TerrainShowBox();
                        addChild(_terrainBox);
                       
                        textInit();
                       
                        //菜单事件
                        //点击停止事件
                        _selectBox.btnStop.addEventListener(MouseEvent.CLICK, charaStopHandler);
                        //点击取消事件
                        _selectBox.btnCan.addEventListener(MouseEvent.CLICK, charaCanHandler);
                        //菜单隐藏
                        _selectBox.visible = false;
                       
                       
                        //地形显示框隐藏
                        _terrainBox.visible = false;
                       
                        //得到所有人物数据
                        _pXml = Sav.gamedata["people"] as XML;
                        //得到所有地形数据
                        _terrain = Sav.gamedata["Terrain"] as XML;
                        //得到所有兵种数据
                        _arms = Sav.gamedata["Arms"] as XML;
                       
                        //鼠标点击事件
                        _bakSprite.addEventListener(MouseEvent.CLICK,onClick);
                        //贞事件
                        this.addEventListener(Event.ENTER_FRAME, mapMoveHandler);
                       
                        //鼠标移动事件
                        addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
                        //鼠标移动事件
                        _bakSprite.addEventListener(MouseEvent.MOUSE_MOVE, mouseBakMoveHandler);
                       
                        //载入人物属性Xml
                        _xml_loader = new XMLLoader();
                        _xml_loader.onLoadComplete      = initStage;
                        _xml_loader.load(mapXmlSrc, XMLLoader.GB2312);
                }
                //文本格式
                private function textInit():void{
               
                        _roundShow = new TextField();
                        _roundShow.autoSize = TextFieldAutoSize.LEFT;
                        var formatter:TextFormat = new TextFormat( );
                        formatter.color = 0xCCCCCC;
                        formatter.size = 60;
                        formatter.bold = true;
                        _roundShow.defaultTextFormat = formatter;
                        _roundShow.text = "";
                        addChild(_roundShow);
                }
                //贞事件
                private function mapMoveHandler(event:Event):void{
                        if(_mapMoveCtrl > 5){
                                //根据地图移动用xy步长移动地图
                                _bakSprite.x += _mapXadd;
                                _bakSprite.y += _mapYadd;
                                _mapMoveCtrl = 0;
                        }
                        //控制地图不移出指定范围
                        if(_bakSprite.x > 0){
                                _bakSprite.x = 0;
                        }else if( _bakSprite.x < Sav.gamedata["stageWidth"] - _bakSprite.width){
                                _bakSprite.x = Sav.gamedata["stageWidth"] - _bakSprite.width;
                        }
                        if(_bakSprite.y > 0){
                                _bakSprite.y = 0;
                        }else if( _bakSprite.y < Sav.gamedata["stageHeight"] - _bakSprite.height){
                                _bakSprite.y = Sav.gamedata["stageHeight"] - _bakSprite.height;
                        }
                        if(_roundShowCtrl == 0){
                                _roundShow.text = "第" + _roundIndex + "回合\n";
                                _roundShow.x = (Sav.gamedata["stageWidth"] - _roundShow.width)/2;
                                _roundShow.y = (Sav.gamedata["stageHeight"] - _roundShow.height)/2;
                        }else if(_roundShowCtrl == 40){
                                _roundShow.text = "\n" + _roundCtrl;
                                _roundShow.x = (Sav.gamedata["stageWidth"] - _roundShow.width)/2;
                                _roundShow.y = (Sav.gamedata["stageHeight"] - _roundShow.height)/2;
                        }else if(_roundShowCtrl == 80){
                                _roundShow.text = "";
                                if(_roundCtrl == "我方回合"){
                                        _bakSprite.addEventListener(MouseEvent.CLICK,onClick);
                                }else        if(_roundCtrl == "敌方回合"){
                                        addEventListener(Event.ENTER_FRAME, onEnemyFrame);
                                }
                        }
                        _roundShowCtrl++;
                        _mapMoveCtrl ++;
                }
                //鼠标移动事件
                private function mouseBakMoveHandler(event:MouseEvent):void{
                        var intX:int = event.currentTarget.mouseX;
                        var intY:int = event.currentTarget.mouseY;
                        _mouseBox.x = Math.floor(intX/48)*48;
                        _mouseBox.y = Math.floor(intY/48)*48;
                }
                //鼠标移动事件
                private function mouseMoveHandler(event:MouseEvent):void{
                        var intX:int = event.currentTarget.mouseX;
                        var intY:int = event.currentTarget.mouseY;
                        if(intX < 48){
                                 _mapXadd = 48;
                        }else        if(intX > Sav.gamedata["stageWidth"] - 48 && intX <= Sav.gamedata["stageWidth"]){
                                _mapXadd = -48;
                        }else{
                                _mapXadd = 0;
                        }
                        if(intY < 48){
                                _mapYadd = 48;
                        }else        if(intY > Sav.gamedata["stageHeight"] - 48 && intY <= Sav.gamedata["stageHeight"]){
                                _mapYadd = -48;
                        }else{
                                _mapYadd = 0;
                        }
                        if(_terrainBox.visible){
                                _clickCtrl = "NULL";
                                _terrainBox.visible = false;
                                _bakSprite.addEventListener(MouseEvent.CLICK,onClick);
                        }
                        if(_clickCtrl == "ENEMY_ROUND_SHOW"){
                                _clickCtrl = "NULL";
                                SpriteRemove.removeAllChildren(_roadSprite);
                                _bakSprite.addEventListener(MouseEvent.CLICK,onClick);
                        }
                }
               
                //用来重新载入点击事件
                private function onClickFrame(event:Event):void {
                        removeEventListener(Event.ENTER_FRAME, onClickFrame);
                        var ctrl:Boolean = false;
                        var i:int;
                        for(i = 0;i<_ourArr.length;i++){
                                if(!_ourArr.actionCtrl){
                                        ctrl = true;
                                        break;
                                }
                        }
                        if(!ctrl){
                                _roundCtrl = "敌方回合";
                                for(i=0;i<_enemyArr.length;i++){
                                        _enemyArr.actionCtrl = false;
                                }
                                _enemyActionCtrl = 0;
                                //addEventListener(Event.ENTER_FRAME, onEnemyFrame);
                                _roundShowCtrl  = 40;
                        }else{
                                _bakSprite.addEventListener(MouseEvent.CLICK,onClick);
                        }
                }
               
                //控制敌军行动事件
                private function onEnemyFrame(event:Event):void {
                        var i:int;
                        var toDistance:int;
                        var checkDistance:int;
                        if(_clickCtrl == "NULL"){
                                _nowChatacter = null;
                                //寻找未行动人员
                                for(i=0;i<_enemyArr.length;i++){
                                        if(!_enemyArr.actionCtrl){
                                                _nowChatacter = _enemyArr;
                                                break;
                                        }
                                }
                                //如果全部行动完毕,则进入我军回合
                                if(_nowChatacter == null){
                                        _roundCtrl = "我方回合";
                                        for(i=0;i<_ourArr.length;i++){
                                                _ourArr.actionCtrl = false;
                                        }
                                        removeEventListener(Event.ENTER_FRAME, onEnemyFrame);
                                        _roundIndex ++;
                                        _roundShowCtrl  = 0;
                                        return;
                                }
                                if(_enemyActionCtrl == 0){
                                        //得到为行动人员,开始寻路显示
                                        _clickCtrl = "ROAD_SHOW";
                                        setRoad(_nowChatacter);
                                }
                        }
                        if(_clickCtrl == "ROAD_SHOW" && _enemyActionCtrl == 10){
                                //开始行动
                                _toPoint = new Point(_roadShowArray[0].x,_roadShowArray[0].y);
                                i = Math.random() * _ourArr.length;
                                _character = _ourArr;
                                toDistance = Math.abs(_character.locationX - _toPoint.x) + Math.abs(_character.locationY - _toPoint.y) ;
                                for(i=1;i<_roadShowArray.length;i++){
                                        checkDistance = Math.abs(_character.locationX - _roadShowArray.x) + Math.abs(_character.locationY - _roadShowArray.y) ;
                                        if(checkDistance < toDistance){
                                                toDistance = checkDistance;
                                                _toPoint.x = _roadShowArray.x;
                                                _toPoint.y = _roadShowArray.y;
                                        }
                                }
                                _nowPoint = new Point( _nowChatacter.locationX, _nowChatacter.locationY);
                                _nowDirection = _characterMC.getDir();
                                charaToMove();
                        }
                        _enemyActionCtrl ++;
                       
                }
                //点击停止事件
                private function charaStopHandler(event:MouseEvent):void{
                        _clickCtrl = "NULL";
                        _nowChatacter.actionCtrl = true;
                        _selectBox.visible = false;
                        addEventListener(Event.ENTER_FRAME, onClickFrame);
                }
                //点击取消事件
                private function charaCanHandler(event:MouseEvent):void{
                        _clickCtrl = "NULL";
                        _selectBox.visible = false;
                        _characterMC = _nowChatacter.character;
                        _characterMC.x = _nowPoint.x * 48;
                        _characterMC.y = _nowPoint.y * 48;
                        _characterMC.setDir(_nowDirection);
                        addEventListener(Event.ENTER_FRAME, onClickFrame);
                }
               
                //寻找最大移动范围
                private function setRoad(chara:Character){
                        _roadShowArray = _roadQuery.makePath(chara);
                       
                        if(_roadShowArray != null && _roadShowArray.length > 0){
                                var sign:Sign;
                                for(var i:int = 0;i<_roadShowArray.length;i++){
                                        sign = new Sign();
                                        sign.x = _roadShowArray.x * 48;
                                        sign.y = _roadShowArray.y * 48;
                                        _roadSprite.addChild(sign);
                                }
                                setAttRound(_pXml["peo" + _nowChatacter.charaIndex].Arms);
                        }
                }
                //攻击范围显示
                private function setAttRound(armIndex:int):void{
                        var attRoundArr:Array;
                        var attRound:AttBox;
                        for each ( var roundment:XML in _arms["Arms" + armIndex]["RangeAttack"].elements( ) ) {
                                attRound = new AttBox();
                                attRoundArr = roundment.toString().split(",");
                                attRound.x = (int(attRoundArr[0]) + _nowChatacter.locationX )*48;
                                attRound.y = (int(attRoundArr[1]) + _nowChatacter.locationY) *48;
                                _roadSprite.addChild(attRound);
                        }
                       
                }
                //鼠标点击事件
                private function onClick(event:Event):void{
                        var __mouseX:Number = event.currentTarget.mouseX;
                        var __mouseY:Number = event.currentTarget.mouseY;
                        var i:int;
                        if(_clickCtrl == "NULL"){
                                var queryPeople:Boolean = false;
                                //点击我军人物判断
                                for(i=0;i<_ourArr.length;i++){
                                        _character = _ourArr as Character;
                                        _characterMC = _character.character;
                                        if(Math.floor(_characterMC.x/48) == Math.floor(__mouseX/48) && Math.floor(_characterMC.y/48) == Math.floor(__mouseY/48)){
                                                _nowChatacter = _character;
                                                setRoad(_nowChatacter);
                                                _clickCtrl = "ROAD_SHOW";
                                                _bakSprite.removeEventListener(MouseEvent.CLICK,onClick);
                                                _roadSprite.addEventListener(MouseEvent.CLICK,onClick);
                                                queryPeople = true;
                                                break;
                                        }
                                }
                                //点击敌军人物判断
                                for(i=0;i<_enemyArr.length && !queryPeople;i++){
                                        _character = _enemyArr as Character;
                                        _characterMC = _character.character;
                                        if(Math.floor(_characterMC.x/48) == Math.floor(__mouseX/48) && Math.floor(_characterMC.y/48) == Math.floor(__mouseY/48)){
                                                _nowChatacter = _character;
                                                setRoad(_nowChatacter);
                                                _clickCtrl = "ENEMY_ROUND_SHOW";
                                                _bakSprite.removeEventListener(MouseEvent.CLICK,onClick);
                                                queryPeople = true;
                                                break;
                                        }
                                }
                                if(!queryPeople){
                                        //点击地图,显示地形
                                        _clickCtrl = "TERRAIN_SHOW";
                                        var mapX:int = Math.floor(__mouseX/48);
                                        var mapY:int = Math.floor(__mouseY/48);
                                        var terrainId:int = _mapData[mapY][mapX];
                                        var terrainName:String = "Terrain" + terrainId;
                                        _terrainBox.x = mapX *48 - 48 + _bakSprite.x;
                                        _terrainBox.y = mapY*48 - 48 + _bakSprite.y;
                                        if(_terrainBox.x < 0){
                                                _terrainBox.x = 0;
                                        }else if(_terrainBox.x > Sav.gamedata["stageWidth"] - 144){
                                                _terrainBox.x = Sav.gamedata["stageWidth"] - 144;
                                        }
                                        if(_terrainBox.y < 0){
                                                _terrainBox.y = 0;
                                        }else if(_terrainBox.y > Sav.gamedata["stageHeight"] - 144){
                                                _terrainBox.y = Sav.gamedata["stageHeight"] - 144;
                                        }
                                        _terrainBox.TerrainName.text = _terrain[terrainName];
                                        SpriteRemove.removeAllChildren(_terrainBox.TerrainShow);
                                        _terrainBox.TerrainShow.addChild(ImageCtrl.getImage(_bmapimage,mapX*48,mapY*48,48,48));
                                        _bakSprite.removeEventListener(MouseEvent.CLICK,onClick);
                                        _terrainBox.visible = true;
                                }
                        }else if(_clickCtrl == "ROAD_SHOW"){
                                _characterMC = _nowChatacter.character;
                                for(i=0;i<_roadShowArray.length;i++){
                                                _nowPoint = new Point(_nowChatacter.locationX,_nowChatacter.locationY);
                                                _nowDirection = _characterMC.getDir();
                                                _toPoint = new Point(Math.floor(__mouseX/48),Math.floor(__mouseY/48));
                                                charaToMove();
                                }
                        }
                       
                       
                }
                //当前人物开始移动
                private function charaToMove():void{
                        _roadArray = _roadQuery.path4(_nowPoint,_toPoint,_roadShowArray);
                        if(_roadArray != null && _roadArray.length > 0){
                                addEventListener(Event.ENTER_FRAME, onFrame);
                                _clickCtrl == "MOVE_NOW"
                                SpriteRemove.removeAllChildren(_roadSprite);
                                if(_roundCtrl == "我方回合"){
                                        _roadSprite.removeEventListener(MouseEvent.CLICK,onClick);
                                }
                        }
                }
                //人物移动事件贞控制
                private function onFrame(event:Event):void {
                        _characterMC = _nowChatacter.character;
                        if(_roadArray != null && _roadArray.length > 1){
                                if(_characterMC.x % 48 == 0 && _characterMC.y % 48 == 0){
                                         if(_roadArray[0].x == _roadArray[1].x){
                                                if(_roadArray[0].y > _roadArray[1].y){
                                                        _characterMC.setDir(0);
                                                        _xadd = 0;
                                                        _yadd = -_addLeng;
                                                }else{
                                                        _characterMC.setDir(1);
                                                        _xadd = 0;
                                                        _yadd = _addLeng;
                                                }
                                        }else{
                                                if(_roadArray[0].x > _roadArray[1].x){
                                                        _characterMC.setDir(2);
                                                        _xadd = -_addLeng;
                                                        _yadd = 0;
                                                }else{
                                                        _characterMC.setDir(3);
                                                        _xadd = _addLeng;
                                                        _yadd = 0;
                                                }
                                        }                                       

                                        _roadArray.splice(0,1);
                                       
                                }
                                _characterMC.x += _xadd;
                                _characterMC.y += _yadd;
                                
                        }else if(_characterMC.x % 48 == 0 && _characterMC.y % 48 == 0){
                                removeEventListener(Event.ENTER_FRAME, onFrame);
                                if(_roundCtrl == "我方回合"){
                                        _selectBox.visible = true;
                                        _selectBox.x = _characterMC.x + 48;
                                        _selectBox.y = _characterMC.y;
                                }else if(_roundCtrl == "敌方回合"){
                                        _nowChatacter.actionCtrl = true;
                                        _enemyActionCtrl = 0;
                                        _clickCtrl = "NULL";
                                        addEventListener(Event.ENTER_FRAME, onEnemyFrame);
                                }
                        }else{
                       
                                _characterMC.x += _xadd;
                                _characterMC.y += _yadd;
                        }
                }

                //得到战场xml信息
                private function initStage(xml:XML):void{
                        _fightXml = xml;
                        _mapData= new Array();
                        //根据xml内容,得到地形数组
                        for each ( var datement:XML in _fightXml.DataMap.elements( ) ) {
                                var dates:Array = ("" + datement).split( ",");
                                _mapData.push(dates);
                        }
                        _roadQuery = new RoadQuery(this);
                       
                        //我军人物添加
                        _ourArr = new Array();
                        //根据xml内容,得到我军人物,添加至战场
                        for each ( var ourment:XML in _fightXml.Our.elements( ) ) {
                                var ourId:int = int(ourment);
                                var ourchara:XML = XML(_pXml["peo" + ourId]);
                                _characterMC = new CharacterMC(ourId);
                                _characterMC.x = int(ourment.@x)*48;
                                _characterMC.y = int(ourment.@y)*48;
                                _character = new Character(_characterMC,int(ourchara.Move),int(ourchara.sImage),int(ourchara.Arms));
                                _characterSprite.addChild(_characterMC);
                                _ourArr.push(_character);
                        }
                        //敌军人物添加
                        _enemyArr = new Array();
                        //根据xml内容,得到敌军人物,添加至战场
                        for each ( var enemyment:XML in _fightXml.Enemy.elements( ) ) {
                                var enemyId:int = int(enemyment);
                                var enemychara:XML = XML(_pXml["peo" + enemyId]);
                                _characterMC = new CharacterMC(enemyId);
                                _characterMC.x = int(enemyment.@x)*48;
                                _characterMC.y = int(enemyment.@y)*48;
                                _character = new Character(_characterMC,int(enemychara.Move),int(enemychara.sImage),int(enemychara.Arms));
                                _characterSprite.addChild(_characterMC);
                                _enemyArr.push(_character);
                        }
                        //加载地图
                        _pic_loader = new Loader();
                        _pic_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteMap);
                        var mapName:String = "Images/HM/" + _fightXml.Map + ".gif";
                        _pic_loader.load(new URLRequest(mapName));
                }
                //加载地图完毕
                private function onCompleteMap(event:Event):void {
                        _pic_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onCompleteMap);
                        _bmapimage = Bitmap(_pic_loader.content);
                        _mapSprite.addChild(_bmapimage);
                       
                }
                public function get map():Array{
                        return _mapData;
                }
                public function get roundCtrl():String{
                        return _roundCtrl;
                }
                public function get enemyArr():Array{
                        return _enemyArr;
                }
                public function get ourArr():Array{
                        return _ourArr;
                }
               
        }
}

效果如下图




暂时,敌军只会跟随我军某个人物移动,等下面再慢慢研究敌方的AI
下次,在战场上显示人物的攻击防御等属性:)
顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


要显示人物属性了,把相应的人物数据和兵种数据改好,如下<?xml version="1.0" encoding="GB2312"?>
<data>
    <peo1>
        <Name>曹操</Name>
        <Arms>1</Arms>
        <Lv>1</Lv>
        <Exp>0</Exp>
        <HP>124</HP>
        <MP>85</MP>
        <Move>5</Move>
        <Face>1</Face>
        <sImage>1</sImage>
        <Force>80</Force>
        <Intelligence>96</Intelligence>
        <Command>98</Command>
        <Agile>83</Agile>
        <Luck>88</Luck>
        <Attack>82</Attack>
        <Spirit>92</Spirit>
        <Defense>80</Defense>
        <Breakout>85</Breakout>
        <Morale>80</Morale>
        <Introduction></Introduction>
    </peo1>
......
<?xml version="1.0" encoding="GB2312"?>
<data>
    <Arms1>
        <Name>英雄</Name>
        <Property>
            <Attack>A</Attack>
            <Spirit>A</Spirit>
            <Defense>A</Defense>
            <Breakout>A</Breakout>
            <Morale>A</Morale>
        </Property>
        <Weapon>剑</Weapon>
        <Equipment>铠甲</Equipment>
        <Terrain>
            <Terrain0>1</Terrain0>
            <Terrain1>1</Terrain1>
            <Terrain2>2</Terrain2>
            <Terrain3>100</Terrain3>
            <Terrain4>100</Terrain4>
            <Terrain5>1</Terrain5>
            <Terrain6>1</Terrain6>
            <Terrain7>1</Terrain7>
        </Terrain>
        <RangeAttack>
            <List>0,-1</List>
            <List>0,1</List>
            <List>-1,0</List>
            <List>1,0</List>
        </RangeAttack>
        <Introduction></Introduction>
    </Arms1>
......
在data.xml中设定升级所需EXP和能力上限值
<?xml version="1.0" encoding="GB2312"?>
<data>
        <varlable>255</varlable>
        <MaxExp>100</MaxExp>
        <MaxAbility>1000</MaxAbility>
</data>
然后,就像.net编辑From一样,开始准备所需要的MC



在读取完data.xml时,把需要的升级所需EXP和能力上限值保存,方便随时取用
                        Sav.gamedata["MaxAbility"] = xml.MaxAbility;
                        Sav.gamedata["MaxExp"] = xml.MaxExp;
战场上,把整个战场向下移动48个像素,用来仿照曹操传放置按钮,
在曹操传中,左击鼠标用来察看人物属性,但是flash中是没有办法弄成这样的,至少现在不能,因为flash左击鼠标,会弹出flash菜单
所以,我在最上面的菜单上,放置了两个按钮,用来察看我军和敌军属性,按钮用了普通的士兵S形象,点击我军或者敌军的S形象按钮就能察看我军和敌军的属性了
                        //查看武将-我军按钮
                        _ourShow = new PeopleShow();
                        _ourShow.x = 500;
                        addChild(_ourShow);
                        _ourShow.addEventListener(MouseEvent.CLICK, ourShowHandler);
                        //查看武将-敌军按钮
                        _enemyShow = new PeopleShowEnemy();
                        _enemyShow.x = 548;
                        addChild(_enemyShow);
                        _enemyShow.addEventListener(MouseEvent.CLICK, enemyShowHandler);

然后添加现实HP,MP和人物属性的MC
                        _hpmp = new HPMP();
                        _bakSprite.addChild(_hpmp);
                        _hpmp.visible = false;
这个HPMP,是用来显示当前的HP和MP的MC,就是上面一开始准备的第一个图
                        //查看武将MC
                        _peopleShow = new CharacterProperty();
                        _peopleShow.x = (Sav.gamedata["stageWidth"] - _peopleShow.width)/2;
                        _peopleShow.y = (Sav.gamedata["stageHeight"] - _peopleShow.height)/2;
                        this.addChild(_peopleShow);
                        _peopleShow.btnGenerals.visible = false;
                        _peopleShow.visible = false;
这个CharacterProperty就是准备好的显示人物属性的MC,就是上面的第二个图


当鼠标移动到我军或敌军身上时,就显示其HP和MP

                //鼠标移动事件
                private function mouseBakMoveHandler(event:MouseEvent):void{
                        var intX:int = event.currentTarget.mouseX;
                        var intY:int = event.currentTarget.mouseY;
                        _mouseBox.x = Math.floor(intX/48)*48;
                        _mouseBox.y = Math.floor(intY/48)*48;
                        var queryPeople:Boolean = false;
                        var i:int;
                        for(i=0;i<_ourArr.length;i++){
                                _character = _ourArr as Character;
                                if(_character.x == _mouseBox.x && _character.y == _mouseBox.y){
                                        _nowChatacter = _character;
                                        queryPeople = true;
                                        break;
                                }
                        }
                       
                        for(i=0;i<_enemyArr.length && !queryPeople;i++){
                                _character = _enemyArr as Character;
                                if(_character.x == _mouseBox.x && _character.y == _mouseBox.y){
                                        _nowChatacter = _character;
                                        queryPeople = true;
                                        break;
                                }
                        }
                        if(!queryPeople){
                                _hpmp.visible = false;
                        }else{
                                        _hpmp.visible = true;
                                        _hpmp.x = _mouseBox.x  - 102;
                                        _hpmp.y = _mouseBox.y - 48;
                                        if(_hpmp.x < 0){
                                                _hpmp.x = 0;
                                        }
                                        if(_hpmp.y < 0){
                                                _hpmp.y = 0;
                                        }
                                _hpmp.txtHP.text = _nowChatacter.nowHP + "/" + _nowChatacter.HP;
                                _hpmp.spHP.width = 100 * (_nowChatacter.nowHP/_nowChatacter.HP);
                                _hpmp.txtMP.text = _nowChatacter.nowMP + "/" + _nowChatacter.MP;
                                _hpmp.spMP.width = 100 * (_nowChatacter.nowMP/_nowChatacter.MP);
                        }
                }



添加好点击事件,显示人物属性时,实现相应的切换

                        _peopleShow.visible = false;
                        //添加各个按钮点击事件
                        _peopleShow.btnGenerals.addEventListener(MouseEvent.CLICK, onClickGenerals);
                        _peopleShow.btnForce.addEventListener(MouseEvent.CLICK, onClickForce);
                        _peopleShow.btnAbility.addEventListener(MouseEvent.CLICK, onClickAbility);
                        _peopleShow.btnEquipment.addEventListener(MouseEvent.CLICK, onClickEquipment);
                        _peopleShow.btnTactics.addEventListener(MouseEvent.CLICK, onClickTactics);
                        _peopleShow.btnClose.addEventListener(MouseEvent.CLICK, onClickClose);
                        _peopleShow.btnLast.addEventListener(MouseEvent.CLICK, onClickLast);
                        _peopleShow.btnNext.addEventListener(MouseEvent.CLICK, onClickNext);


                //察看武将-按钮全部显示
                private function _peopleBtnToTrue(){
                        _peopleShow.btnGenerals.visible = true;
                        _peopleShow.btnForce.visible = true;
                        _peopleShow.btnAbility.visible = true;
                        _peopleShow.btnEquipment.visible = true;
                        _peopleShow.btnTactics.visible = true;
               
                }
                //察看武将-点击上一武将
                private function onClickLast(event:MouseEvent):void{
                        peopleShowFromIndex(-1);
                }
                //察看武将-点击下一武将
                private function onClickNext(event:MouseEvent):void{
                        peopleShowFromIndex(1);
                }
                //察看武将-点击关闭
                private function onClickClose(event:MouseEvent):void{
                        if(_peopleShow.btnGenerals.visible){
                                _peopleShow.gotoAndStop(1);
                        }
                        _peopleShow.visible = false;
                }
                //察看武将-点击武将列传
                private function onClickGenerals(event:MouseEvent):void{
                        _peopleShow.gotoAndStop(1);
                        _peopleBtnToTrue();
                        _peopleShow.btnGenerals.visible = false;
                        setGenerals();
                }
                //察看武将-点击部队属性
                private function onClickForce(event:MouseEvent):void{
                        _peopleShow.gotoAndStop(2);
                        _peopleBtnToTrue();
                        _peopleShow.btnForce.visible = false;
                        setForce();
                }
                //察看武将-点击能力
                private function onClickAbility(event:MouseEvent):void{
                        _peopleShow.gotoAndStop(3);
                        _peopleBtnToTrue();
                        _peopleShow.btnAbility.visible = false;
                        setAbility();
                }
                //察看武将-点击装备
                private function onClickEquipment(event:MouseEvent):void{
                        _peopleShow.gotoAndStop(4);
                        _peopleBtnToTrue();
                        _peopleShow.btnEquipment.visible = false;
                        setEquipment();
                }
                //察看武将-点击策略
                private function onClickTactics(event:MouseEvent):void{
                        _peopleShow.gotoAndStop(5);
                        _peopleBtnToTrue();
                        _peopleShow.btnTactics.visible = false;
                        setTactics();
                }


                //察看我军
                private function ourShowHandler(event:MouseEvent):void{
                        _peopleShowIndex= 0;
                        _peopleShowCtrl = "Our";
                        peopleShowFromIndex(0);
                }
                //察看敌军
                private function enemyShowHandler(event:MouseEvent):void{
                        _peopleShowIndex = 0;
                        _peopleShowCtrl = "Enemy";
                        peopleShowFromIndex(0);
                }
                //根据人物序号显示人物属性
                private function peopleShowFromIndex(addIndex:int):void{
                        _peopleShowIndex += addIndex;
                        if(_peopleShowCtrl == "Our"){
                                if(_peopleShowIndex < 0){
                                        _peopleShowIndex = _ourArr.length - 1;
                                }else if(_peopleShowIndex >= _ourArr.length){
                                        _peopleShowIndex = 0;
                                }
                                _nowChatacter = _ourArr[_peopleShowIndex] as Character;
                        _peopleShow.txtForceShow.text = "我军";
                        }else if(_peopleShowCtrl == "Enemy"){
                                if(_peopleShowIndex < 0){
                                        _peopleShowIndex = _enemyArr.length - 1;
                                }else if(_peopleShowIndex >= _enemyArr.length){
                                        _peopleShowIndex = 0;
                                }
                                _nowChatacter = _enemyArr[_peopleShowIndex] as Character;
                                _peopleShow.txtForceShow.text = "敌军";
                        }
                        _peopleShow.txtName.text = _pXml["peo" + _nowChatacter.charaIndex].Name.toString();
                        _peopleShow.txtArms.text = _pXml["peo" + _nowChatacter.charaIndex].Arms.toString();
                        _peopleShow.txtLv.text = _pXml["peo" + _nowChatacter.charaIndex].Lv.toString();
                        _peopleShow.txtExp.text = _pXml["peo" + _nowChatacter.charaIndex].Exp + "/" + Sav.gamedata["MaxExp"];
                        _peopleShow.spExp.width = 50 * (int(_pXml["peo" + _nowChatacter.charaIndex].Exp)/int(Sav.gamedata["MaxExp"]));
                        _peopleShow.txtHP.text = _nowChatacter.nowHP + "/" + _nowChatacter.HP;
                        _peopleShow.spHP.width = 100 * (_nowChatacter.nowHP/_nowChatacter.HP);
                        _peopleShow.txtMP.text = _nowChatacter.nowMP + "/" + _nowChatacter.MP;
                        _peopleShow.spMP.width = 100 * (_nowChatacter.nowMP/_nowChatacter.MP);
                        _peopleShow.txtStatus.text = _nowChatacter.getfStatus();
                        for(var i:int = 0;i<_nowChatacter.statusArr.length;i++){
                                _peopleShow.txtStatus.appendText(_nowChatacter.statusArr[0] + "        ");
                        }
                       
                        //加载人物头像
                        var faceStr:String = "Images/Face/" + _pXml["peo" + _nowChatacter.charaIndex].Face.toString().split(",")[0] + ".gif";
                        _pic_loader = new Loader();
                        _pic_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteFace);
                        _pic_loader.load(new URLRequest(faceStr));
                        if(!_peopleShow.btnGenerals.visible){
                                setGenerals();
                        }else if(!_peopleShow.btnForce.visible){
                                setForce();
                        }else if(!_peopleShow.btnAbility.visible){
                                setAbility();
                        }else if(!_peopleShow.btnEquipment.visible){
                                setEquipment();
                        }else if(!_peopleShow.btnTactics.visible){
                                setTactics();
                        }
                }
                //加载人物头像完毕
                private function onCompleteFace(event:Event):void {
                        _pic_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onCompleteFace);
                        _image = Bitmap(_pic_loader.content);
                        SpriteRemove.removeAllChildren(_peopleShow.faceImage);
                        _peopleShow.faceImage.addChild(_image);
                        _peopleShow.visible = true;
                }
                //察看武将-显示武将列传
                private function setGenerals():void{
                        _peopleShow.txtForce.text = _pXml["peo" + _nowChatacter.charaIndex].Force.toString();
                        _peopleShow.txtIntelligence.text = _pXml["peo" + _nowChatacter.charaIndex].Intelligence.toString();
                        _peopleShow.txtCommand.text = _pXml["peo" + _nowChatacter.charaIndex].Command.toString();
                        _peopleShow.txtAgile.text = _pXml["peo" + _nowChatacter.charaIndex].Agile.toString();
                        _peopleShow.txtLuck.text = _pXml["peo" + _nowChatacter.charaIndex].Luck.toString();
                        _peopleShow.txtIntroduction.text = _pXml["peo" + _nowChatacter.charaIndex].Introduction.toString();
                }
                //察看武将-显示部队属性
                private function setForce():void{
                        _peopleShow.txtAttack.text = _arms["Arms" + _nowChatacter.armsIndex].Property.Attack.toString();
                        _peopleShow.txtSpirit.text = _arms["Arms" + _nowChatacter.armsIndex].Property.Spirit.toString();
                        _peopleShow.txtDefense.text = _arms["Arms" + _nowChatacter.armsIndex].Property.Defense.toString();
                        _peopleShow.txtBreakout.text = _arms["Arms" + _nowChatacter.armsIndex].Property.Breakout.toString();
                        _peopleShow.txtMorale.text = _arms["Arms" + _nowChatacter.armsIndex].Property.Morale.toString();
                        _peopleShow.txtArmsPro.text = _arms["Arms" + _nowChatacter.armsIndex].Introduction.toString();
                        _peopleShow.txtArms2.text = _pXml["peo" + _nowChatacter.charaIndex].Arms.toString();
                        _peopleShow.txtWeapon.text = _arms["Arms" + _nowChatacter.armsIndex].Weapon.toString();
                        _peopleShow.txtEquipment.text = _arms["Arms" + _nowChatacter.armsIndex].Equipment.toString();
                        SpriteRemove.removeAllChildren(_peopleShow.armsImage);
                        _peopleShow.armsImage.addChild(new Bitmap(_nowChatacter.character.getBitmapData()));
                }
                //察看武将-显示能力
                private function setAbility():void{
                        _peopleShow.txtAttack1.text = _pXml["peo" + _nowChatacter.charaIndex].Attack.toString();
                        _peopleShow.txtSpirit1.text = _pXml["peo" + _nowChatacter.charaIndex].Spirit.toString();
                        _peopleShow.txtDefense1.text = _pXml["peo" + _nowChatacter.charaIndex].Defense.toString();
                        _peopleShow.txtBreakout1.text = _pXml["peo" + _nowChatacter.charaIndex].Breakout.toString();
                        _peopleShow.txtMorale1.text = _pXml["peo" + _nowChatacter.charaIndex].Morale.toString();
                        _peopleShow.spAttack1.width = 100 * int(_pXml["peo" + _nowChatacter.charaIndex].Attack) / int(Sav.gamedata["MaxAbility"]);
                        _peopleShow.spSpirit1.width = 100 * int(_pXml["peo" + _nowChatacter.charaIndex].Spirit) / int(Sav.gamedata["MaxAbility"]);
                        _peopleShow.spDefense1.width = 100 * int(_pXml["peo" + _nowChatacter.charaIndex].Defense) / int(Sav.gamedata["MaxAbility"]);
                        _peopleShow.spBreakout1.width = 100 * int(_pXml["peo" + _nowChatacter.charaIndex].Breakout) / int(Sav.gamedata["MaxAbility"]);
                        _peopleShow.spMorale1.width = 100 * int(_pXml["peo" + _nowChatacter.charaIndex].Morale) / int(Sav.gamedata["MaxAbility"]);
                }
                //察看武将-显示装备
                private function setEquipment():void{}
                //察看武将-显示策略
                private function setTactics():void{}

就是这样了,然后,运行一下flash,可以看到下面的图

顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


该研究攻击了,这个比较复杂,先来看,我军方面的攻击
当然,首先要把攻击动作等补全
CharacterMC中,把攻击图片和被攻击图片等全部载入
                //Unit_mov图片加载完成
                public function onCompleteUnit_mov(event:Event):void {
                        _image = Bitmap(_loader.content);
                        //初始化显示数组
                        _bitShowArr = new Array();
                        //将位图数据拆分成小块,装入bitmapArr
                        _bitmapArr=ImageCtrl.divide(_image,1,11);
                        var newArr:Array;
                        //得到向上行走数组
                        newArr = new Array(_bitmapArr[2][0],_bitmapArr[3][0]);
                        //将向上行走数组加入到显示数组 编号:0
                        _bitShowArr.push(newArr);
                        //得到向下行走数组
                        newArr = new Array(_bitmapArr[0][0],_bitmapArr[1][0]);
                        //将向下行走数组加入到显示数组 编号:1
                        _bitShowArr.push(newArr);
                        //得到向左行走数组
                        newArr = new Array(_bitmapArr[4][0],_bitmapArr[5][0]);
                        //将向左行走数组加入到显示数组 编号:2
                        _bitShowArr.push(newArr);
                        //得到向右行走数组
                        newArr = new Array(ImageCtrl.bitHorizontal(_bitmapArr[4][0]),ImageCtrl.bitHorizontal(_bitmapArr[5][0]));
                        //将向右行走数组加入到显示数组 编号:3
                        _bitShowArr.push(newArr);
                        //得到向上站立数组
                        newArr = new Array(_bitmapArr[7][0]);
                        //将向上站立数组加入到显示数组 编号:4
                        _bitShowArr.push(newArr);
                        //得到向下站立数组
                        newArr = new Array(_bitmapArr[6][0]);
                        //将向下站立数组加入到显示数组 编号:5
                        _bitShowArr.push(newArr);
                        //得到向左站立数组
                        newArr = new Array(_bitmapArr[8][0]);
                        //将向左站立数组加入到显示数组 编号:6
                        _bitShowArr.push(newArr);
                        //得到向右站立数组
                        newArr = new Array(ImageCtrl.bitHorizontal(_bitmapArr[8][0]));
                        //将向右站立数组加入到显示数组 编号:7
                        _bitShowArr.push(newArr);
                        //得到喘气数组
                        newArr = new Array(_bitmapArr[9][0],_bitmapArr[10][0]);
                        //将喘气数组加入到显示数组 编号:8
                        _bitShowArr.push(newArr);
                       
             //Unit_atk图片加载;           
                          _loader = new Loader();  
                        _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteUnit_atk);
                        var atkName:String = "Images/Unit_atk/" + _imageIndex + ".gif";
                        _loader.load(new URLRequest(atkName));
                }
                //Unit_atk图片加载完成
                public function onCompleteUnit_atk(event:Event):void {
                        _image = Bitmap(_loader.content);
                        //将位图数据拆分成小块,装入bitmapArr
                        _bitmapArr=ImageCtrl.divide(_image,1,12);
                        var newArr:Array;
                        //得到向上攻击数组
                        newArr = new Array(_bitmapArr[4][0],_bitmapArr[5][0],_bitmapArr[6][0],_bitmapArr[7][0]);
                        //将向上攻击数组加入到显示数组 编号:9
                        _bitShowArr.push(newArr);
                        //得到向下攻击数组
                        newArr = new Array(_bitmapArr[0][0],_bitmapArr[1][0],_bitmapArr[2][0],_bitmapArr[3][0]);
                        //将向下攻击数组加入到显示数组 编号:10
                        _bitShowArr.push(newArr);
                        //得到向左攻击数组
                        newArr = new Array(_bitmapArr[8][0],_bitmapArr[9][0],_bitmapArr[10][0],_bitmapArr[11][0]);
                        //将向左攻击数组加入到显示数组 编号:11
                        _bitShowArr.push(newArr);
                        //得到向右攻击数组
                        newArr = new Array(ImageCtrl.bitHorizontal(_bitmapArr[8][0]),ImageCtrl.bitHorizontal(_bitmapArr[9][0]),ImageCtrl.bitHorizontal(_bitmapArr[10][0]),ImageCtrl.bitHorizontal(_bitmapArr[11][0]));
                        //将向右攻击数组加入到显示数组 编号:12
                        _bitShowArr.push(newArr);
                       
             //Unit_spc图片加载;           
                          _loader = new Loader();  
                        _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteUnit_spc);
                        var spcName:String = "Images/Unit_spc/" + _imageIndex + ".gif";
                        _loader.load(new URLRequest(spcName));
                }
                //Unit_spc图片加载完成
                public function onCompleteUnit_spc(event:Event):void {
                        _image = Bitmap(_loader.content);
                        //将位图数据拆分成小块,装入bitmapArr
                        _bitmapArr=ImageCtrl.divide(_image,1,5);
                        var newArr:Array;
                        //得到向上挡格数组
                        newArr = new Array(_bitmapArr[1][0]);
                        //将向上挡格数组加入到显示数组 编号:13
                        _bitShowArr.push(newArr);
                        //得到向下挡格数组
                        newArr = new Array(_bitmapArr[0][0]);
                        //将向下挡格数组加入到显示数组 编号:14
                        _bitShowArr.push(newArr);
                        //得到向左挡格数组
                        newArr = new Array(_bitmapArr[2][0]);
                        //将向左挡格数组加入到显示数组 编号:15
                        _bitShowArr.push(newArr);
                        //得到向右挡格数组
                        newArr = new Array(ImageCtrl.bitHorizontal(_bitmapArr[2][0]));
                        //将向右挡格数组加入到显示数组 编号:16
                        _bitShowArr.push(newArr);
                        //得到受攻击数组
                        newArr = new Array(_bitmapArr[3][0]);
                        //将受攻击数组加入到显示数组 编号:17
                        _bitShowArr.push(newArr);
                        //得到升级数组
                        newArr = new Array(_bitmapArr[4][0]);
                        //将升级数组加入到显示数组 编号:18
                        _bitShowArr.push(newArr);
                       
                        startFrame();
                }

CharacterIndex中,把相应的动作代号补全,以方便使用
package Caocao.Character {
        public class CharacterIndex {
                public static const UP:int = 0;
                public static const DOWN:int = 1;
                public static const LEFT:int = 2;
                public static const RIGHT:int = 3;
                public static const UP_STOP:int = 4;
                public static const DOWN_STOP:int = 5;
                public static const LEFT_STOP:int = 6;
                public static const RIGHT_STOP:int = 7;
                public static const PANT:int = 8;
                public static const ATTACK_UP:int = 9;
                public static const ATTACK_DWON:int = 10;
                public static const ATTACK_LEFT:int = 11;
                public static const ATTACK_RIGHT:int = 12;
                public static const WARD_UP:int = 13;
                public static const WARD_DWON:int = 14;
                public static const WARD_LEFT:int = 15;
                public static const WARD_RIGHT:int = 16;
                public static const TAKE_A_BEAT:int = 17;
                public static const UPGRADE:int = 18;
                public function CharacterIndex() { }
        }
}
然后,继续在人物动作类CharacterMC中加入一个被攻击人员和一个可以随时改变值的自定义函数
                //对手
                public var _rival:Character;
                private var _rivalMC:CharacterMC;
                //执行函数
                public var _fun:Function;

然后,在战场类FightMap中把战斗按钮上加上点击事件
                        //点击攻击事件
                        _selectBox.btnAttAck.addEventListener(MouseEvent.CLICK, charaAttHandler);
                //点击攻击事件
                private function charaAttHandler(event:MouseEvent):void{
                        _clickCtrl = "ATTACK";
                        _selectBox.visible = false;
                        _roadSprite.addEventListener(MouseEvent.CLICK,onClick);
                        setAttRound2(_pXml["peo" + _nowChatacter.charaIndex].Arms);
                }
这里的setAttRound2,用红色半透明MC来显示攻击范围
                //攻击范围显示
                private function setAttRound2(armIndex:int):void{
                        var attRoundArr:Array;
                        var attRound:AttShow;
                        for each ( var roundment:XML in _arms["Arms" + armIndex]["RangeAttack"].elements( ) ) {
                                attRound = new AttShow();
                                attRoundArr = roundment.toString().split(",");
                                attRound.x = (int(attRoundArr[0]) + _nowChatacter.locationX )*48;
                                attRound.y = (int(attRoundArr[1]) + _nowChatacter.locationY) *48;
                                _roadSprite.addChild(attRound);
                        }
                       
                }
这时候,点击状态已经改变为"ATTACK"
在点击事件中,加上攻击事件
......
else if(_clickCtrl == "ATTACK"){
                                //寻找攻击目标
                                for(i=0;i<_enemyArr.length && !queryPeople;i++){
                                        _character = _enemyArr as Character;
                                        _characterMC = _character.character;
                                        if(Math.floor(_characterMC.x/48) == Math.floor(__mouseX/48) && Math.floor(_characterMC.y/48) == Math.floor(__mouseY/48)){
                                               
                                                SpriteRemove.removeAllChildren(_roadSprite);
                                                _nowChatacter.character._rival = _character;
                                                _nowChatacter.character._fun = function(){
                                                        _clickCtrl = "NULL";
                                                        _nowChatacter.actionCtrl = true;
                                                        addEventListener(Event.ENTER_FRAME, onClickFrame);
                                                }
                                                _nowChatacter.attack();
                                               
                                                break;
                                        }
                                       
                                }
                        }
这里的_fun很重要,用来处理攻击完之后的事件代码
当然,给函数赋了值就要有执行的地方,
下面修改人物动作类CharacterMC的动态显示贞事件
                //动态显示
                public function onFrame(event:Event):void {
                        var dir:int = _showIndex;
                        _peopleBitmap.bitmapData = _bitShowArr[dir][_pointer];
                        _count += _speed;
                        _pointer += int(_count) ;
                        _count=_count%1;
                        //当人物攻击时,在攻击的第三个动作,被攻击人物显示被攻击动作
                        if((dir == CharacterIndex.ATTACK_UP || dir == CharacterIndex.ATTACK_DWON ||
                                dir == CharacterIndex.ATTACK_LEFT || dir == CharacterIndex.ATTACK_RIGHT ) && _pointer == 2){
                                //得到被攻击人物动作显示类
                                _rivalMC = _rival.character;
                                //根据攻击人物方向,设定攻击和被攻击完毕之后的人物方向
                                if(_rivalMC.x - this.x > 0){
                                        this._direct = CharacterIndex.RIGHT;
                                        _rivalMC._direct = CharacterIndex.LEFT;
                                }else if(_rivalMC.x - this.x < 0){
                                        this._direct = CharacterIndex.LEFT;
                                        _rivalMC._direct = CharacterIndex.RIGHT;
                                }else if(_rivalMC.y - this.y > 0){
                                        this._direct = CharacterIndex.DOWN;
                                        _rivalMC._direct = CharacterIndex.UP;
                                }else if(_rivalMC.y - this.y < 0){
                                        this._direct = CharacterIndex.UP;
                                        _rivalMC._direct = CharacterIndex.DOWN;
                                }
                                _rivalMC.setDir(CharacterIndex.TAKE_A_BEAT);
                        }
                        if(_pointer >= _bitShowArr[dir].length){
                                //人物动作不是移动动作的时候,动作结束后,根据动作前的方向,显示移动动作
                                switch(dir){
                                        case CharacterIndex.TAKE_A_BEAT:
                                                _showIndex = _direct;
                                                break;
                                        case CharacterIndex.ATTACK_UP:
                                                _showIndex = _direct;
                                                _fun();
                                        case CharacterIndex.ATTACK_DWON:
                                                _showIndex = _direct;
                                                _fun();
                                        case CharacterIndex.ATTACK_LEFT:
                                                _showIndex = _direct;
                                                _fun();
                                        case CharacterIndex.ATTACK_RIGHT:
                                                _showIndex = _direct;
                                                _fun();
                                                break;
                                }
                               
                                _pointer = 0;
                                _count = 0;
                        }
                }
之后,在动作类中,加入两个函数,用来控制人物行动前和行动后的亮度,就像曹操传里的行动完之后,人物会变暗
                //转为静态
                public function stand():void{
                        switch(_showIndex){
                                case CharacterIndex.UP:
                                        setDir(CharacterIndex.UP_STOP);
                                        break;
                                case CharacterIndex.DOWN:
                                        setDir(CharacterIndex.DOWN_STOP);
                                        break;
                                case CharacterIndex.LEFT:
                                        setDir(CharacterIndex.LEFT_STOP);
                                        break;
                                case CharacterIndex.RIGHT:
                                        setDir(CharacterIndex.RIGHT_STOP);
                                        break;
                        }
                        this.transform.colorTransform = _standColor;
                }
                //转为动态
                public function run():void{
                        switch(_showIndex){
                                case CharacterIndex.UP_STOP:
                                        setDir(CharacterIndex.UP);
                                        break;
                                case CharacterIndex.DOWN_STOP:
                                        setDir(CharacterIndex.DOWN);
                                        break;
                                case CharacterIndex.LEFT_STOP:
                                        setDir(CharacterIndex.LEFT);
                                        break;
                                case CharacterIndex.RIGHT_STOP:
                                        setDir(CharacterIndex.RIGHT);
                                        break;
                        }
                        this.transform.colorTransform = _runColor;
                }
主要是这些修改,其他的都是些小改动

目前,只写了我军的攻击,而且只是攻击动作,敌人也不掉血,不过加个掉血并不难,
难的是敌军的攻击,现在敌军回合,敌军依然只会跟随我军某一个人物移动,等研究完敌军攻击之后,把代码放出来,

好了,现在先看一下效果吧



下次,研究一下敌人的攻击

[ 本帖最后由 lufy 于 2010-5-27 17:45 编辑 ]
顶部
性别:未知-离线 klyz505

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 19
编号 14597
注册 2004-8-4


发表于 2010-5-28 09:38 资料 短消息 只看该作者
顶你没商量啊~!!!强人!
我一直在思考,是用c+++dx开发好,还是flash好,最近想通了:用flash更好!
原因有三:
1、flash开发,webGame是当前的潮流,说不定还可以因为兴趣而找到工作,既赚钱又满足兴趣;
2、flash入门比dx快速、简单;
3、任何flash里的游戏资源,只要你想要,基本都是手到擒来,要是其它游戏,基本都要对压缩的游戏资源折腾一番才能拿到。
哥们,继续,加油,呵呵
顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


回复 #13 klyz505 的帖子

是啊,flash开发有它的优势
如果把做好的东西上传到服务器,玩家都不用下载就能玩了
如果做网游的话,不但有socket支持,还可以省了玩家下载几G的游戏资源
利用平台更是不用说,下载个Adobe Flash Player就能玩了,当然iPad和iPhone除外
顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


到了复杂的地方了,敌军的AI问题了

曹操传中敌军的行动方针有很多种,敌军根据相应的行动方针进行不同的行为
所以,我们首先在人物类中,加上行动方针一项
                //行动方针
                private var _mission:String;
默认是"DEFAULT",现在不研究太复杂,目前只考虑这一个行动方针
并且,默认下就选择攻击
敌人选择攻击目标的时候,会优先选择一击可以杀死的人物,
这里就要在选择攻击目标之前,先来判断一下攻击的这个人能否被杀死
那么,就要有物理攻击计算
那就利用曹操传中的物理攻击公式在战场类中写一个方法
                /*物理攻击的伤害值计算
                        X代表攻击方的攻击力,Y代表被攻击方的防御力,Lv表示攻击方的等级。R表示伤害值
                        首先会根据地形修正攻击和防御力为X',Y'
                        if (x'>y')
                        r=Lv+25+(X'-Y')/2;
                        else
                        r=Lv+25-(Y'-X')/2
                        然后再根据兵种相克和宝物进行修正
                */
                public function getAttHurt(attChara:Character,hertChara:Character):int{
                        var r:int;
                        //得到攻击方的攻击力和等级
                        var attLv:int =  int(_pXml["peo" + attChara.charaIndex].Lv);
                        var attAttack:int = int(_pXml["peo" + attChara.charaIndex].Attack);
                        //得到防御方的防御力
                        var hertDefense:int = int(_pXml["peo" + hertChara.charaIndex].Defense);
                        //计算攻击方所在地形
                        var attTerrain:String = "Terrain" + _mapData[attChara.locationY][attChara.locationX];
                        //计算防御方所在地形
                        var hertTerrain:String = "Terrain" + _mapData[hertChara.locationY][hertChara.locationX];
                        //根据地形修正攻击和防御力
                        var attAttackAddition:int = Math.floor((int(_arms["Arms" + attChara.armsIndex].Terrain[attTerrain].@Addition)/100) * attAttack);
                        var hertDefenseAddition:int = Math.floor((int(_arms["Arms" + hertChara.armsIndex].Terrain[hertTerrain].@Addition)/100) * hertDefense);
                        //物理攻击的伤害值计算
                        if(attAttackAddition > hertDefenseAddition){
                                r = attLv + 25 + (attAttackAddition - hertDefenseAddition)/2;
                        }else{
                                r = attLv + 25 + (hertDefenseAddition - attAttackAddition)/2;
                        }
                        return r;
                }
好了,有了伤害计算了,在攻击的时候,先寻找到所有可以攻击到的位置,
                //计算所有攻击范围
                private function getAttRange(chara:Character):Object{
                        var attArr:Array = new Array();
                        var attRoundArr:Array;
                        var i:int;
                        var j:int;
                        var objAll:Object = new Object();
                        var objCheck:Object = new Object();
                        var obj:Object = new Object();
                        var attRound:Array = new Array();
                        //兵种攻击范围
                        for each ( var roundment:XML in _arms["Arms" + chara.armsIndex]["RangeAttack"].elements( ) ) {
                                attRoundArr = roundment.toString().split(",");
                                attRound.push(new Point(int(attRoundArr[0]), int(attRoundArr[1])));
                        }
                        //根据移动范围来计算所有攻击范围
                        for(i=0;i<_roadShowArray.length;i++){
                                for(j=0;j<attRound.length;j++){
                                        obj = new Object();
                                        obj.x = _roadShowArray.x + attRound[j].x;
                                        obj.y = _roadShowArray.y + attRound[j].y;
                                        if(objAll[obj.x + "," + obj.y] == null){
                                                obj.nodeparent = _roadShowArray;
                                                objAll[obj.x + "," + obj.y] = obj;
                                                attArr.push(obj);
                                        }
                                }
                        }
                        objAll.attArr = attArr;
                        return objAll;
                }
这里,添加了一个obj.nodeparent,用来确定攻击的时候所移动的位置

好了,现在就简单了,因为可以利用上面的两个方法轻松找到攻击目标了
                //计算攻击目标
                public function getAttTarget(chara:Character,peoArr:Array):Object{
                        var i:int;
                        var objResult:Object;
                        var obj:Object;
                        //计算所有攻击范围
                        var objAll:Object = getAttRange(chara);
                        var attArr:Array = new Array();
                        var intHert:int;
                        for(i=0;i<peoArr.length;i++){
                                var checkChara:Character = peoArr;
                                obj = objAll[checkChara.locationX + "," + checkChara.locationY];
                                if(obj != null){
                                        intHert = getAttHurt(chara,checkChara);
                                        obj.chara = checkChara;
                                        //判断是否有一击可以杀死的人,有的话直接确立目标
                                        if(intHert >= checkChara.nowHP){
                                                return obj;
                                        }
                                        attArr.push(obj);
                                }
                        }
                        //没有一击可以杀死的人的时候,如果有可以攻击到的人,则随即抽取可以攻击到的人,确立目标
                        if(attArr.length > 0 ){
                                i = Math.random() * attArr.length;
                                return attArr;
                        }
                        //没有可以攻击到的人,没有找到目标
                        return null;
                }
然后,在敌军寻路完成后,就可以判断下行动方针,当然这里的行动方针只有一个,哈哈
                                if(_nowChatacter.mission == "DEFAULT"){
                                        //查找攻击目标
                                        var obj:Object = getAttTarget(_nowChatacter,_ourArr);
                                        if(obj != null){
                                                _nowChatacter.character._rival = obj.chara;
                                                _toPoint = new Point(obj.nodeparent.x,obj.nodeparent.y);
                                        }else{
                                                //开始行动
                                                _toPoint = new Point(_roadShowArray[0].x,_roadShowArray[0].y);
                                                i = Math.random() * _ourArr.length;
                                                _character = _ourArr;
                                                toDistance = Math.abs(_character.locationX - _toPoint.x) + Math.abs(_character.locationY - _toPoint.y) ;
                                                for(i=1;i<_roadShowArray.length;i++){
                                                        checkDistance = Math.abs(_character.locationX - _roadShowArray.x) + Math.abs(_character.locationY - _roadShowArray.y) ;
                                                        if(checkDistance < toDistance){
                                                                toDistance = checkDistance;
                                                                _toPoint.x = _roadShowArray.x;
                                                                _toPoint.y = _roadShowArray.y;
                                                        }
                                                }
                                                _nowChatacter.character._rival = null;
                                        }
                                        _nowPoint = new Point( _nowChatacter.locationX, _nowChatacter.locationY);
                                        _characterMC = _nowChatacter.character;
                                        _nowDirection = _characterMC.getDir();
                                        charaToMove();
                                }

看,obj.nodeparent.x,obj.nodeparent.y就是之前确定好的移动位置

然后,在敌军武将移动完毕时,判断一下是不是有攻击目标
没有的话,结束行动,有的话,进入攻击状态
                                        if(_nowChatacter.rival == null){
                                                _nowChatacter.actionCtrl = true;
                                                _enemyActionCtrl = 0;
                                                _clickCtrl = "NULL";
                                        }else{
                                                _clickCtrl = "ATTACK";
                                        }
                                        addEventListener(Event.ENTER_FRAME, onEnemyFrame);
然后,在控制敌军行动事件中,加上攻击代码,和我军攻击的时候是一样的,不同的是,攻击完毕的时候,所调用的方法不一样,我方攻击的时候,需要调用鼠标点击事件,这次需要调用控制敌军行动事了
if(_clickCtrl == "ATTACK"){
                                removeEventListener(Event.ENTER_FRAME, onEnemyFrame);
                                _nowChatacter.character._fun = function(){
                                        _clickCtrl = "NULL";
                                        _nowChatacter.actionCtrl = true;
                                        _enemyActionCtrl = 0;
                                        addEventListener(Event.ENTER_FRAME, onEnemyFrame);
                                }
                                _nowChatacter.attack();
                        }

好了,运行下程序,可以看到敌军也会进行攻击了
当然攻击是不掉血的,嘿嘿

敌军步兵的攻击

敌军弓兵的攻击


下次,该研究掉血和掉血的时候显示一下了
顶部
性别:未知-离线 klyz505

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 19
编号 14597
注册 2004-8-4


发表于 2010-5-30 19:01 资料 短消息 只看该作者
又学习了,楼主请继续~~~
顶部
性别:未知-离线 klyz505

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 19
编号 14597
注册 2004-8-4


发表于 2010-5-30 19:05 资料 短消息 只看该作者
楼主,这是你自己开发的吗?怎么这么牛~
是否已经开发完了?能不能放出来耍耍~~看着就馋
顶部
性别:男-离线 主席
(宅狼)

Rank: 4
组别 士兵
级别 牙门将军
功绩 6
帖子 569
编号 77513
注册 2006-7-31
来自 荆州重镇
家族 轩辕狼党


发表于 2010-5-30 19:07 资料 短消息 只看该作者
flash版啊!
可以放在移动设备上玩了!
顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


因为已经写好了伤害计算,所以,要加入伤害显示就相当简单了
首先,先来让鼠标移动到敌方人物时显示伤害数值
在显示HP和MP的框架上,另外复制一个spHP,改变一下颜色与spHP区别,命名为spHP1
然后,在显示HP和MP的时候,加上伤害判断与显示,具体如下
                        if(_clickCtrl != "HPMP_HERT"){
                                if(!queryPeople){
                                        _hpmp.visible = false;
                                }else{
                                        //定义伤害数值,初始值是0
                                        var hp2:int = 0;
                                        _hpmp.visible = true;
                                        _hpmp.x = _mouseBox.x  - 102;
                                        _hpmp.y = _mouseBox.y - 48;
                                        if(_hpmp.x < 0){
                                                _hpmp.x = 0;
                                        }
                                        if(_hpmp.y < 0){
                                                _hpmp.y = 0;
                                        }
                                        _hpmp.txtHP.text = _character.nowHP + "/" + _character.HP;
                                        _hpmp.spHP.width = 100 * (_character.nowHP/_character.HP);
                                        _hpmp.txtMP.text = _character.nowMP + "/" + _character.MP;
                                        _hpmp.spMP.width = 100 * (_character.nowMP/_character.MP);
                                        if(_clickCtrl == "ATTACK" ){
                                                //如果目前战场状态是攻击的话,则开始判断是否鼠标在敌方人物身上,是的话,则开始计算伤害数值
                                                for(i=0;i<_roadSprite.numChildren;i++){
                                                        var childSprite:Sprite = Sprite(_roadSprite.getChildAt(i));
                                                        if(_character.their == "ENEMY" &&_mouseBox.x == Math.floor(childSprite.x/48)*48 && _mouseBox.y == Math.floor(childSprite.y/48)*48){
                                                                //调用物理伤害计算方法,开始计算伤害数值
                                                                hp2 = getAttHurt(_nowChatacter,_character);
                                                        }
                                                }
                                        }
                                        //若伤害数值>0,则显示伤害数值]
                                        if(hp2 > 0){
                                                _hpmp.spHP1.width = 100 * (hp2/_character.HP);
                                                _hpmp.spHP1.x = _hpmp.spHP.x + _hpmp.spHP.width - _hpmp.spHP1.width;
                                        }else{
                                                _hpmp.spHP1.width = 0;
                                        }
                                }
这样,就可以看到伤害显示了,如图

然后,再来处理受到攻击的时候,显示伤害值
在战场上,加上两个变量
                //伤害值
                private var _hertHp:int;
                //伤害值显示控制用
                private var _hertHpIndex:int;
_hertHpIndex这个变量,是在显示伤害值时,让HP动态减少时控制用的
接下来,在控制敌军行动事件中,敌军攻击时,自定义函数里,不直接结束行动,
而是,加上伤害值显示,在伤害值显示完之后,再行动结束
原来是
                                _nowChatacter.character._fun = function(){
                                        _clickCtrl = "NULL";
                                        _nowChatacter.actionCtrl = true;
                                        _enemyActionCtrl = 0;
                                        addEventListener(Event.ENTER_FRAME, onEn
                                }
改为-〉
                                _nowChatacter.character._fun = function(){
                                                _clickCtrl = "HPMP_HERT";
                                                _hpmp.visible = true;
                                                _hpmp.x = _nowChatacter.character._rival.x  - 102;
                                                _hpmp.y = _nowChatacter.character._rival.y - 48;
                                                if(_hpmp.x < 0){
                                                        _hpmp.x = 0;
                                                }
                                                if(_hpmp.y < 0){
                                                        _hpmp.y = 0;
                                                }
                                                _hpmp.txtHP.text =  _nowChatacter.character._rival.nowHP + "/" +  _nowChatacter.character._rival.HP;
                                                _hpmp.spHP.width = 100 * ( _nowChatacter.character._rival.nowHP/ _nowChatacter.character._rival.HP);
                                                _hpmp.txtMP.text =  _nowChatacter.character._rival.nowMP + "/" +  _nowChatacter.character._rival.MP;
                                                _hpmp.spMP.width = 100 * ( _nowChatacter.character._rival.nowMP/ _nowChatacter.character._rival.MP);
                                                _hpmp.spHP1.width = 0;
                                }
相同的地方,我军攻击的时候,也进行相同的处理
改完后是
                                                _nowChatacter.character._fun = function(){
                                                        _clickCtrl = "HPMP_HERT";
                                                        _hpmp.visible = true;
                                                        _hpmp.x = _nowChatacter.character._rival.x  - 102;
                                                        _hpmp.y = _nowChatacter.character._rival.y - 48;
                                                        if(_hpmp.x < 0){
                                                                _hpmp.x = 0;
                                                        }
                                                        if(_hpmp.y < 0){
                                                                _hpmp.y = 0;
                                                        }
                                                        _hpmp.txtHP.text = _character.nowHP + "/" + _character.HP;
                                                        _hpmp.spHP.width = 100 * (_character.nowHP/_character.HP);
                                                        _hpmp.txtMP.text = _character.nowMP + "/" + _character.MP;
                                                        _hpmp.spMP.width = 100 * (_character.nowMP/_character.MP);
                                                        _hpmp.spHP1.width = 0;
                                                }
然后在贞事件中,将伤害动态显示
                        //如果状态是伤害显示,则动态显示伤害值
                        if(_clickCtrl == "HPMP_HERT"){
                                //判断一下_hertHpIndex,如果小于伤害值,则动态减少HP,否则结束行动
                                if(_hertHpIndex < _hertHp){
                                        _nowChatacter.rival.nowHP -= 1;
                                        _hpmp.txtHP.text = _nowChatacter.rival.nowHP + "/" + _nowChatacter.rival.HP;
                                        _hpmp.spHP.width = 100 * (_nowChatacter.rival.nowHP/_nowChatacter.rival.HP);
                                        _hertHpIndex++;
                                }else{
                                        //根据我方攻击还是敌方攻击,结束行动,并加上相应的事件
                                        if(_roundCtrl == "我方回合"){
                                                _clickCtrl = "NULL";
                                                _nowChatacter.actionCtrl = true;
                                                addEventListener(Event.ENTER_FRAME, onClickFrame);
                                        }else{
                                                _clickCtrl = "NULL";
                                                _nowChatacter.actionCtrl = true;
                                                _enemyActionCtrl = 0;
                                                addEventListener(Event.ENTER_FRAME, onEnemyFrame);
                                        }
                                }
                               
                        }
好了,可以显示伤害值了 ^0^!
顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21




QUOTE:
原帖由 klyz505 于 2010-5-30 19:05 发表
楼主,这是你自己开发的吗?怎么这么牛~
是否已经开发完了?能不能放出来耍耍~~看着就馋

是自己开发的阿,练习用的,这里御览的部分就是目前开发完的部分,
等稍微成型的时候,就把代码和程序发上来
目前,只是实现了简单的功能,人物撤退,战斗结束等都还没写
下次,研究一下人物撤退的问题
顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


下面来研究一下撤退
就是在每个人行动完之后,加一个HP判断就可以了
HP=0的时候,就让人物不显示,因为曹操传中,还有武将复活等指令,所以不可以从人物数组中删除,只将人物隐藏就可以了
为了方便,我把伤害值动态显示分离出一个方法来

                //动态显示伤害值
                private function hpmpHert():void{
                        //判断一下_hertHpIndex,如果小于伤害值,则动态减少HP,否则结束行动
                        if(_hertHpIndex < _hertHp){
                                _nowChatacter.rival.nowHP -= 1;
                                _hpmp.txtHP.text = _nowChatacter.rival.nowHP + "/" + _nowChatacter.rival.HP;
                                _hpmp.spHP.width = 100 * (_nowChatacter.rival.nowHP/_nowChatacter.rival.HP);
                                _hertHpIndex++;
                        }else{
                                //根据我方攻击还是敌方攻击,结束行动,并加上相应的事件
                                if(_roundCtrl == "我方回合"){
                                        _clickCtrl = "CHECK";
                                        _nowChatacter.actionCtrl = true;
                                }else{
                                        _clickCtrl = "CHECK";
                                        _nowChatacter.actionCtrl = true;
                                        _enemyActionCtrl = 0;
                                }
                        }
                }
这里,结束行动后,_clickCtrl由NULL变为了CHECK,用来判断HP
贞事件中

                        if(_clickCtrl == "CHECK"){
                                if(_nowChatacter.rival.nowHP <= 0){
                                        //人物撤退
                                        characterRemove();
                                }
                        }
                //人物撤退
                private function characterRemove():void{
                        if(_retreatCtrl == 0){
                                _nowChatacter.rival.setAlpha(0);
                        }else if(_retreatCtrl == 3){
                                _nowChatacter.rival.setAlpha(1);
                        }else if(_retreatCtrl == 6){
                                _nowChatacter.rival.setAlpha(0);
                        }else if(_retreatCtrl == 9){
                                _nowChatacter.rival.setAlpha(1);
                        }else if(_retreatCtrl == 12){
                                _nowChatacter.rival.setAlpha(0);
                                if(_roundCtrl == "我方回合"){
                                        _clickCtrl = "NULL";
                                        _retreatCtrl = -1;
                                        addEventListener(Event.ENTER_FRAME, onClickFrame);
                                        this.contextMenu = _roundMenu;
                                }else{
                                        _clickCtrl = "NULL";
                                        _retreatCtrl = -1;
                                        addEventListener(Event.ENTER_FRAME, onEnemyFrame);
                                }
                        }
                        _retreatCtrl++;
                }
这里的_retreatCtrl,用来让人物闪烁
挺简单的,运行下程序,当人物HP变成0的时候,会闪烁几下,然后消失
顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


下面研究反击,反击进行的时间,是在攻击之后,也就是在进行HP判断之后,如果HP还大于0的话,那么这个武将的反击目标又恰好在他的攻击范围之内,那么进行反击

好了,那就在贞事件中判断HP的地方
                        if(_clickCtrl == "CHECK"){
                                if(_nowChatacter.rival.nowHP <= 0){
                                        //人物撤退
                                        characterRemove();
                                }else{
                                        //反击判断
                                        counterCheck();
                                }
                        }

                //反击判断
                private function counterCheck():void{
                        var isOK:Boolean = false;
                        var attRoundArr:Array;
                        //检验反击目标是否在他的攻击范围之内
                        for each ( var roundment:XML in _arms["Arms" + _nowChatacter.rival.armsIndex]["RangeAttack"].elements( ) ) {
                                attRoundArr = roundment.toString().split(",");
                                if((int(attRoundArr[0]) + _nowChatacter.rival.locationX) == _nowChatacter.locationX &&
                                                                                                                                                (int(attRoundArr[1]) + _nowChatacter.rival.locationY) == _nowChatacter.locationY){
                                        isOK = true;
                                        break;
                                }
                        }
                       
                        if(_roundCtrl == "我方回合"){
                                if(!_counter && isOK){
                                        _counter = true;
                                        _clickCtrl = "COUNTER";
                                }else{
                                        _clickCtrl = "NULL";
                                        _counter = false;
                                        addEventListener(Event.ENTER_FRAME, onClickFrame);
                                        this.contextMenu = _roundMenu;
                                }
                        }else{
                                if(!_counter && isOK){
                                        _counter = true;
                                        _clickCtrl = "COUNTER";
                                }else{
                                        _clickCtrl = "NULL";
                                        _counter = false;
                                        addEventListener(Event.ENTER_FRAME, onEnemyFrame);
                                }
                        }
                        //满足反击条件,进行反击
                        if(_clickCtrl == "COUNTER"){
                                _character = _nowChatacter;
                                _nowChatacter = _nowChatacter.rival;
                                _nowChatacter.rival = _character;
                                _hertHp = Math.floor(getAttHurt(_nowChatacter,_nowChatacter.rival)*0.75);
                                _hertHpIndex = 0;
                                _nowChatacter.character._fun = function(){
                                        _clickCtrl = "HPMP_HERT";
                                        _hpmp.visible = true;
                                        _hpmp.x = _nowChatacter.character._rival.x  - 102;
                                        _hpmp.y = _nowChatacter.character._rival.y - 48;
                                        if(_hpmp.x < 0){
                                                _hpmp.x = 0;
                                        }
                                        if(_hpmp.y < 0){
                                                _hpmp.y = 0;
                                        }
                                        _hpmp.txtHP.text =  _nowChatacter.rival.nowHP + "/" +  _nowChatacter.rival.HP;
                                        _hpmp.spHP.width = 100 * ( _nowChatacter.rival.nowHP/ _nowChatacter.rival.HP);
                                        _hpmp.txtMP.text =  _nowChatacter.rival.nowMP + "/" +  _nowChatacter.rival.MP;
                                        _hpmp.spMP.width = 100 * ( _nowChatacter.rival.nowMP/ _nowChatacter.rival.MP);
                                        _hpmp.spHP1.width = 0;
                                }
                                _nowChatacter.attack();
                        }
                }
这里进行反击很简单,只需要把原来的攻击和被攻击人员交换一下,就可以了
运行代码,一切OK

下次,该试着研究下双击和挡格以及爆击等事件了,!^0^!
顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


下面研究双击和致命一击
根据曹操传的计算公式
先来写两个方法
                /*
                        双击概率计算
                        如果Sa/Sd<1,那么H=1;
                        如果1<=Sa/Sd<2,那么H=2+18*(Sa/Sd-1);
                        如果2<=Sa/Sd<=3,那么H=20+80*(Sa/Sd-2);
                        如果Sa/Sd>=3,那么H=100;
                */
                private function getDoubleAtt(attChara:Character,hertChara:Character):int{
                        var h:int;
                        //得到双方的爆发力
                        var attBreakout:int = int(_pXml["peo" + attChara.charaIndex].Breakout);
                        var hertBreakout:int = int(_pXml["peo" +hertChara.charaIndex].Breakout);
                        var rate:Number = attBreakout/hertBreakout;
                        if(rate < 1){
                                h = 1;
                        }else if(rate >= 1 && rate < 2){
                                h = 2 + 18*(rate - 1);
                        }else if(rate >= 2 && rate < 3){
                                h = 20 + 80*(rate - 2);
                        }else if(rate >= 3){
                                h = 100;
                        }
                        if(Math.random()*100 <= h){
                                return 2;
                        }
                        return 1;
                }
                /*
                        致命概率计算
                        如果Sa/Sd<1,那么H=1;
                        如果1<=Sa/Sd<2,那么H=2+18*(Sa/Sd-1);
                        如果2<=Sa/Sd<=3,那么H=20+80*(Sa/Sd-2);
                        如果Sa/Sd>=3,那么H=100;
                */
                private function getFatalAtt(attChara:Character,hertChara:Character):Boolean{
                        var h:int;
                        //得到双方的士气
                        var attMorale:int = int(_pXml["peo" + attChara.charaIndex].Morale);
                        var hertMorale:int = int(_pXml["peo" +hertChara.charaIndex].Morale);
                        var rate:Number = attMorale/hertMorale;
                        if(rate < 1){
                                h = 1;
                        }else if(rate >= 1 && rate < 2){
                                h = 2 + 18*(rate - 1);
                        }else if(rate >= 2 && rate < 3){
                                h = 20 + 80*(rate - 2);
                        }else if(rate >= 3){
                                h = 100;
                        }
                        if(Math.random()*100 <= h){
                                return true;
                        }
                        return false;
                }
方法定义好了,现在就是在哪里使用的问题了
双击判断,我是在攻击之前判断攻击次数,这样做的好处是以后如果弄个绝招三连击五连击什么的,就可以直接将这个攻击次数设为相应的数字,就可以变成连击绝招了
而致命判断,是在攻击或者反击的时候都发生的,于是把它放在攻击的方法里,
只要发生攻击,就判断是否发生致命一击

在敌军或者我军攻击之前,都先进行双击判断
                                                //判断双击
                                                _attCount = getDoubleAtt(_nowChatacter,_nowChatacter.rival);
然后,修改攻击方法
这里考虑到反击的时候不双击,所以要另外加一个控制
                }
                //进行攻击
                private function toAttack(hert:Boolean = true):void{
                        //是否是反击判断
                        if(hert){
                                _hertHp = getAttHurt(_nowChatacter,_nowChatacter.rival);
                        }
                        if(_clickCtrl == "ATTACK"){
                                _attCount -= 1;
                        }
                        _hertHpIndex = 0;
                        //判断致命一击
                        _nowChatacter.fatal = getFatalAtt(_nowChatacter,_nowChatacter.rival);
                        if(_nowChatacter.fatal){
                                _hertHp = Math.floor(_hertHp*1.25);
                                if(_hertHp > _nowChatacter.rival.nowHP){
                                        _hertHp = _nowChatacter.rival.nowHP;
                                }
                        }
                        _nowChatacter.character._fun = function(){
                                _clickCtrl = "HPMP_HERT";
                                _hpmp.visible = true;
                                _hpmp.x = _nowChatacter.rival.x  - 102;
                                _hpmp.y = _nowChatacter.rival.y - 48;
                                if(_hpmp.x < 0){
                                        _hpmp.x = 0;
                                }
                                if(_hpmp.y < 0){
                                        _hpmp.y = 0;
                                }
                                _hpmp.txtHP.text =  _nowChatacter.rival.nowHP + "/" +  _nowChatacter.rival.HP;
                                _hpmp.spHP.width = 100 * ( _nowChatacter.rival.nowHP/ _nowChatacter.rival.HP);
                                _hpmp.txtMP.text =  _nowChatacter.rival.nowMP + "/" +  _nowChatacter.rival.MP;
                                _hpmp.spMP.width = 100 * ( _nowChatacter.rival.nowMP/ _nowChatacter.rival.MP);
                                _hpmp.spHP1.width = 0;
                        }
                        _nowChatacter.attack();
                }
这样就可以判断双击和致命了
然后在动作显示的时候,加上相应的显示
致命一击的时候,人物要发光
先把发光的颜色设定好
                        _fatalColor = new Color;
                        _fatalColor.brightness = 0.5;
                //转为致命一击
                public function startFatalColor():void{
                        this.transform.colorTransform = _fatalColor;
                }
                //结束致命一击
                public function endFatalColor():void{
                        this.transform.colorTransform = _runColor;
                }

然后人物攻击的时候,判断是否显示致命的颜色
                        //当人物攻击时
                        if(dir == CharacterIndex.ATTACK_UP || dir == CharacterIndex.ATTACK_DWON ||
                                dir == CharacterIndex.ATTACK_LEFT || dir == CharacterIndex.ATTACK_RIGHT ){
                                _peopleBitmap.x = -8;
                                _peopleBitmap.y = -8;
                                //在攻击的第一个动作,判断是否是致命一击
                                if(_fatal){
                                        if(_pointer == 0 && _fatalCtrl < 10){
                                                if(_fatalCtrl == 0){
                                                        startFatalColor();
                                                }
                                                _pointer = 0;
                                                _count = 0;
                                                _fatalCtrl++;
                                        }else{
                                                _fatal = false;
                                                _fatalCtrl = 0;
                                                endFatalColor();
                                        }
                                }
                                //在攻击的第三个动作,被攻击人物显示被攻击动作
                                if(_pointer == 2){
                                        //得到被攻击人物动作显示类
                                        _rivalMC = _rival.character;
                                        //根据攻击人物方向,设定攻击和被攻击完毕之后的人物方向
                                        if(_rivalMC.x - this.x > 0){
                                                this._direct = CharacterIndex.RIGHT;
                                                _rivalMC._direct = CharacterIndex.LEFT;
                                        }else if(_rivalMC.x - this.x < 0){
                                                this._direct = CharacterIndex.LEFT;
                                                _rivalMC._direct = CharacterIndex.RIGHT;
                                        }else if(_rivalMC.y - this.y > 0){
                                                this._direct = CharacterIndex.DOWN;
                                                _rivalMC._direct = CharacterIndex.UP;
                                        }else if(_rivalMC.y - this.y < 0){
                                                this._direct = CharacterIndex.UP;
                                                _rivalMC._direct = CharacterIndex.DOWN;
                                        }
                                        _rivalMC.setDir(CharacterIndex.TAKE_A_BEAT);
                                }
                        }else{
                                _peopleBitmap.x = 0;
                                _peopleBitmap.y = 0;
                        }
好了,大致就是这样运行一下,我把曹操的爆发力和士气改为很高,很容易看到效果了

顶部
性别:未知-离线 lufy


Rank: 5Rank: 5
组别 校尉
级别 裨将军
功绩 13
帖子 310
编号 347822
注册 2009-11-21


这是23楼之前的源代码,想看效果的,可以直接打开bin文件夹下的CaoCao.swf


附件: CaoCao.rar (2010-6-2 08:56, 769.09 K)
该附件被下载次数 614
顶部
性别:男-离线 lewulezo


Rank: 4
组别 校尉
级别 仁勇校尉
功绩 27
帖子 158
编号 58100
注册 2006-1-22
来自 上海


发表于 2010-7-16 13:49 资料 文集 短消息 只看该作者
下载了楼主的包,用IE打开一看画面不停的闪动。
顶部
性别:男-离线 lewulezo


Rank: 4
组别 校尉
级别 仁勇校尉
功绩 27
帖子 158
编号 58100
注册 2006-1-22
来自 上海


发表于 2010-7-16 13:53 资料 文集 短消息 只看该作者
下载了楼主的包,用IE打开一看画面不停的闪动。
顶部
性别:未知-离线 将来的mod达人

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 6
编号 389190
注册 2010-7-26


发表于 2010-7-29 11:33 资料 短消息 只看该作者
回复 #26 lewulezo 的帖子

请问是否有FLASH?
顶部
性别:未知-离线 血牛嘎嘎

Rank: 3Rank: 3Rank: 3
组别 士兵
级别 忠义校尉
功绩 3
帖子 257
编号 337293
注册 2009-8-31


发表于 2010-7-30 13:13 资料 短消息 只看该作者
跪求楼主有所突破啊,不过我想到一个问题,就是FLASH游戏大小有限制,界面效果可能不太好啊
顶部
性别:未知-离线 wakin98

Rank: 3Rank: 3Rank: 3
组别 士兵
级别 奋威校尉
功绩 2
帖子 150
编号 50757
注册 2005-10-8


发表于 2010-7-30 16:00 资料 短消息 只看该作者
太牛了,不知楼主能否整个完整的游戏出来让吾辈感受一下
顶部
性别:未知-离线 Axie89

Rank: 4
组别 士兵
级别 牙门将军
功绩 6
帖子 559
编号 312058
注册 2009-2-21
家族 瓦岗寨


发表于 2010-7-30 23:31 资料 短消息 只看该作者
能否试试制作一个类似于金群的復刻版.从而提高ccz的多样性?


顶部

正在浏览此帖的会员 - 共 2 人在线




当前时区 GMT+8, 现在时间是 2024-12-31 00:24
京ICP备2023018092号 轩辕春秋 2003-2023 www.xycq.org.cn

Powered by Discuz! 5.0.0 2001-2006 Comsenz Inc.
Processed in 0.066164 second(s), 9 queries , Gzip enabled

清除 Cookies - 联系我们 - 轩辕春秋 - Archiver - WAP