今天抽空整理了一下资料,周末继续奋斗。 页游里面的角色是游戏里面核心模块之一,由于一直做模块,没有动手写一个来玩,这次我尝试写一个傻瓜的demo,尝试去做一个非常简单的实验。
下面是今天早上的一个实验过程,这个过程当中包括一些没有解决的问题的思考记录。
一、区分动作类型,进行打包分类
遇到的问题:打包资源动作过多不知道怎样组合
打包一个 还是分开打包好?
在打包swf 写上动作的帧,最大值是多少,方便进行播放?怎样使用时间来合理过渡每一帧之间的时间?
二、尝试播放四个常规的动作
遇到的问题,播放速度比较快?应该怎样调整好?
三、改变速率进行播放
应该怎样做到?
三 、尝试基于时间的播放
/怎样做到基于时间播放?
实验进行中,由于没有素材,于是我在一些游戏网站里面下载了一些缓存的swf。
下载了swf资源后,我尝试将动作区分开来,这次实验尽量的保持简单原则,只是选择了8个方向来实验。至于攻击动作,受创等就不尝试加入去。避免过于复杂。
把这些素材下载后,整理命名,我们将其打包成一个swf来加载。鉴于实验,所以大小那些我就不考虑太多,只管实现成功即可。
注:下载下来的素材基本的动作都是6-8帧,我将每个动作都带前缀区分下来
按上下左右进行对资源命名
如:up_1....up_8
down_1 ....down_8
下面到了编程的时候,写一个简单的方式对其进行实现。
加载后我们打包的swf资源,我将其命名为101.swf,加入域里面去,选择80毫秒播放一下。
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.system.ApplicationDomain;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.utils.getTimer;
public class Main extends Sprite
{
private var avatarActionType:int = 2;
private var avatar:Avatar;
private var circleButton:CircleButton;
public function Main()
{
init();
}
private function init():void
{
var loader:Loader=new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoadCompleteHandler);
loader.load(new URLRequest("101.swf"),new LoaderContext(false,ApplicationDomain.currentDomain));
addEventListener(Event.ENTER_FRAME,onRender);
stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDownHandler);
circleButton=new CircleButton();
circleButton.updateFun=updateAction;
addChild(circleButton);
circleButton.x=260;
circleButton.y=200;
}
private function updateAction():void
{
avatarActionType=circleButton.curDir;
}
private function onKeyDownHandler(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case Keyboard.UP :
avatarActionType = 1;
break;
case Keyboard.DOWN :
avatarActionType = 2;
break;
case Keyboard.LEFT :
avatarActionType = 3;
break;
case Keyboard.RIGHT :
avatarActionType = 4;
break;
}
}
private function onLoadCompleteHandler(event:Event):void
{
event.currentTarget.removeEventListener(Event.COMPLETE,onLoadCompleteHandler);
avatar=new Avatar();
addChild(avatar);
avatar.x = 250;
avatar.y = 180;
}
//进行轮播
private var oldTime:int;
private function onRender(event:Event):void
{
if (! avatar)
{
return;
}
var curTime:int = getTimer();
if (curTime-oldTime>80)
{
oldTime = getTimer();
avatar.play(avatarActionType);
}
}
}
}
角色部分提供一个简单的身体对其进行位图设计。在渲染的时候,不停地切换下一帧。为了省资源,处理反向的资源,采用scaleX =-1的方式进行处理。
package
{
import flash.display.Sprite;
import flash.display.Bitmap;
public class Avatar extends Sprite
{
private var body:Bitmap;//身体
public var curFrame:int = 0;
public var curFrameLabel:String;
public function Avatar():void
{
body = new Bitmap();
addChild(body);
}
public function play(avatarActionType:int):void
{
curFrame++;
if (avatarActionType == ActionType.UP)
{
if ((curFrame > 6))
{
curFrame = 1;
}
curFrameLabel = "up_" + curFrame;
body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);
body.x = - width / 2;
body.y = - height / 2;
this.scaleX = 1;
}
else if (avatarActionType == ActionType.DOWN)
{
if (curFrame > 8)
{
curFrame = 1;
}
curFrameLabel = "down_" + curFrame;
body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);
body.x = - width / 2;
body.y = - height / 2;
this.scaleX = 1;
}
else if (avatarActionType == ActionType.LEFT)
{
if (curFrame > 8)
{
curFrame = 1;
}
curFrameLabel = "right_" + curFrame;
body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);
body.x = - width / 2;
body.y = - height / 2;
this.scaleX = -1;
}
else if (avatarActionType == ActionType.RIGHT)
{
if (curFrame > 8)
{
curFrame = 1;
}
curFrameLabel = "right_" + curFrame;
body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);
body.x = - width / 2;
body.y = - height / 2;
this.scaleX = 1;
}
else if (avatarActionType == ActionType.UP_RIGHT)
{
if (curFrame > 8)
{
curFrame = 1;
}
curFrameLabel = "upRight_" + curFrame;
body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);
body.x = - width / 2;
body.y = - height / 2;
this.scaleX = 1;
}else if (avatarActionType == ActionType.UP_LEFT)
{
if (curFrame > 8)
{
curFrame = 1;
}
curFrameLabel = "upRight_" + curFrame;
body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);
body.x = - width / 2;
body.y = - height / 2;
this.scaleX =-1 ;
}
else if (avatarActionType == ActionType.DWON_LEFT)
{
if (curFrame > 8)
{
curFrame = 1;
}
curFrameLabel = "rightDown_" + curFrame;
body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);
body.x = - width / 2;
body.y = - height / 2;
this.scaleX =-1 ;
}else if (avatarActionType == ActionType.DWON_RIGHT)
{
if (curFrame > 8)
{
curFrame = 1;
}
curFrameLabel = "rightDown_" + curFrame;
body.bitmapData = BitmapPool.getBitmapData(curFrameLabel);
trace(body.bitmapData);
body.x = - width / 2;
body.y = - height / 2;
this.scaleX =1 ;
}
}
}
}
定义一组简单的动作类型。
package
{
//方向8个,资源需要5个
public class ActionType
{
public static const UP:int = 1;//向上炮
public static const DOWN:int = 2;//向下跑
public static const LEFT:int = 3;//向左跑
public static const RIGHT:int = 4;//向右跑
public static const UP_LEFT:int = 5;//左上跑
public static const UP_RIGHT:int = 6;//右上跑
public static const DWON_LEFT:int = 7;//左下跑
public static const DWON_RIGHT:int = 8;//右下跑
public static const UP_STAND:int = 9;//向上站立
public static const UP_LEFT_STAND:int = 10;//向左站立
public static const UP_RIGHT_STAND:int = 11;//向右站立
public static const DOWN_STAND:int = 12;//向下站立
public static const DOWN_LEFT_STAND:int = 13;//向左下站立
public static const DOWN_RIGHT_STAND:int = 14;//向右下站立
}
}
资源池,这里可以不用这样设计,鉴于实验。
package
{
import flash.display.BitmapData;
import flash.system.ApplicationDomain;
import flash.utils.Dictionary;
public class BitmapPool
{
private static var pool:Dictionary=new Dictionary();
public function BitmapPool()
{
}
public static function getBitmapData(name:String):BitmapData
{
var myCls:Class;
if (pool[name] == null)
{
myCls = getClass(name) as Class;
if (myCls)
{
return new myCls();
}
}
else
{
return pool[name];
}
return null;
}
public static function getClass(clsName:String):*
{
if (ApplicationDomain.currentDomain.hasDefinition(clsName))
{
return ApplicationDomain.currentDomain.getDefinition(clsName);
}
return null;
}
}
}
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.filters.GlowFilter;
import flash.text.TextField;
public class CircleButton extends Sprite
{
public var curDir:int;
public var updateFun:Function;
public function CircleButton()
{
var perAngle:Number=2*Math.PI/8;
var dirArr:Array=[ActionType.RIGHT,ActionType.DWON_RIGHT,ActionType.DOWN,ActionType.DWON_LEFT,ActionType.LEFT,
ActionType.UP_LEFT,ActionType.UP,ActionType.UP_RIGHT];
for (var i:int=0; i<8; i++)
{
var shape:Sprite=new Sprite();
addChild(shape);
shape.graphics.beginFill(0xffffff);
shape.graphics.drawCircle(0,0,12);
shape.graphics.endFill();
shape.buttonMode=true;
var msg:TextField=new TextField();
shape.addChild(msg);
msg.autoSize="left";
msg.mouseEnabled=false;
msg.x=-5;
msg.y=-8
msg.text=dirArr[i].toString();
shape.x = Math.cos(i*perAngle) * 140;
shape.y = Math.sin(i*perAngle) * 140;
shape.name = dirArr[i].toString();
shape.filters=[new GlowFilter(0x33333)];
shape.addEventListener(MouseEvent.CLICK,onClick);
}
}
private function onClick(event:MouseEvent):void
{
curDir=int(event.currentTarget.name);
if(updateFun!=null)
{
updateFun.apply(null,null);
}
}
}
}
大体的工作已经完成了。其实我们在EnterFrame 事件触发后,处理帧的播放就能看到不同的切片。这里要是做到更多的功能还需要考虑更多事情,如加载,链
接处理,不同部位i的等方式,一大堆乱七八糟的东西烦着你。这里 基本思路,就是要怎样解决轮播图片的问题,可以参考(D5power 也有相关引擎制作案例),个
人感觉开源里面也很不错,学习起来。
很多功能对角色制作工艺有不一样的,这里更多要尝试去分解他们资源进行学习。毕竟这些东西也不是一两天能够吃套的东西。作为一个简单demo 拿来无聊的时
候写写代码就好了。