用AS3.0开发flash版SLG游戏-1
说到经典的战棋游戏,我还是最痴迷于曹操传,以前也曾因为研究曹操传MOD而废寖忘食,也做过一个曹操传的MOD小热一时,
却没想到曹操传MOD已经发展到现在这种地步,无论是画面还是技术都有了大规模的突破
但是,修改永远是修改,总会遇到各种限制,想要突破,当然要自己动手,开发自己的引擎。
但是,在这里,我研究flash版的曹操传,目的并不是想要有任何突破,只是单纯的为了研究一下,熟悉一下用flash完成各种游戏的制作而已。
先看几个预览
下面开始制作过程
首先,先建立一个战场,显示一张地图吧,
导出一张曹操传第一关颖川的地图,把它转化成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 用来控制地图移动的速度,然后只要控制地图不移出指定的范围就可以了
这样,运行一下,就可以让地图自由的移动位置了
接下来,让地图上显示一个人物
导出曹操传中曹操的三个图片,去除背景,并保存为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);
}
运行就可以看到曹操出现在战场上了
下面,开始控制曹操移动
首先,先在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[i] 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[i].isChecked || checkList[i].moveLong < thisPoint.moveLong){
checkList[i].moveLong = thisPoint.moveLong - 1;
loopPath(checkList[i]);
}
}
}
//搜寻最大路径
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;
效果如下图
接下来,显示一下地形,
准备一个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[i] 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):vo
用AS3.0开发flash版SLG游戏-1相关推荐
- Cocos2D教程:使用SpriteBuilder和Cocos2D 3.x开发横版动作游戏——Part 2
本文是"使用Cocos2D 3.x开发横版动作游戏"系列教程的第二篇,同时也是最后一篇.是对How To Make A Side-Scrolling Beat Em Up Game ...
- Java版SLG游戏 竜退治2
剣と魔法の世界のターン制シミュレーションゲーム.マップは小規模ながら完成度は高いです. ストーリーは希薄で.ひたすら仲間やアイテムを集めつつ.淡々とステージクリアしていきます. アイテムの経験値が ...
- 利用java开发简易版扫雷游戏
1.简介 学了几周的Java,闲来无事,写个乞丐版的扫雷,加强一下Java基础知识. 2.编写过程 编写这个游戏,一共经历了三个阶段,编写了三个版本的游戏代码. 第一版:完成了扫雷游戏的基本雏形,实现 ...
- 使用AS3.0开发FC超级马里奥
前言:制作这个游戏完全是因为教手持设备开发的老师布置大作业,要求组队或者个人完成一个手持应用的开发.其实一开始我就后悔报这门选修课,我只玩C,不喜欢JAVA,结果教的偏偏是安卓应用开发,那你倒是取名叫 ...
- 首次试用 NeoSwiff ,用C#开发FLASH版的多国语言翻译
今天才知道了个NeoSwiff ,是个FLASH sdk开发库,感谢"贺星河"在留言回复上给我的指示: NeoSwiff 是COM组件,部分功能用dotnet封装,目前是'免费'测 ...
- cocos2d-x 3 0 制作横版格斗游戏
转自:http://philon.cn/post/cocos2d-x-3.0-zhi-zuo-heng-ban-ge-dou-you-xi cocos2d-x: v3.0-alpha-pre Wind ...
- Cocos2d-x 3.0 制作横版格斗游戏2
转载:https://blog.csdn.net/bridge001/article/details/18882575 git:https://github.com/pj2933/fight2d co ...
- cocos2d-x 3.0 制作横版格斗游戏
cocos2d-x: v3.0-alpha-pre Windows环境: Windows8 + Visual Studio 2012 Linux环境: Ubuntu12.04 + gcc 4.7.2 ...
- flash版小游戏:是男人就下100层
最近买了 android ,在电车上挺无聊的,给android做了个小 游戏 玩玩,顺便弄了个flash版 游戏画面如下: 这个游戏实现起来很简单,代码也很少,首先需要几个碎图: 因为游戏简单,直接把 ...
最新文章
- 智能,万亿维空间中的求解
- Java 高并发_JAVA并发编程与高并发解决方案 JAVA高并发项目实战课程 没有项目经验的朋友不要错过!...
- Eclipse新建SpringBoot后pom.xml代码
- elctron项目_electron项目结构介绍
- 解封装(六):通过遍历获取AVStream音视频流信息并打印参数
- cocos2d-x 观察者模式
- ViewModel中C# Property自动添加OnPropertyChanged处理的小工具, 以及相应Python知识点...
- python按键精灵找图教程_按键精灵实现找图基础命令的方法教程--系统之家
- 访问oracle索引需要什么权限,Oracle索引 权限
- html消除表格线,html5 消除表格线
- nas做服务器虚拟化共享存储,NAS虚拟化的部署及实现解析
- 影视动画特效制作中的光学动作捕捉
- 软件测试如何快速入门
- 多智能体中的图论——多智能体的一致性(二)
- 制作一个简单的chrome插件
- esp8266 nvs应用
- 七月:交通车辆管理、门禁考勤,智能化升级的最优方案你get到了吗?
- android七牛多张图片上传
- html代码正方形变椭圆,椭圆伸缩变换公式
- excel mysql 财务_excel财务函数