Flash-APE物理引擎学习<二>
昨天整理了下代码,新的Demo在这里:
在说具体实现之前,丢个Flash物理引擎在产品展示中的应用:http://www.carlosulloa.com/.
这是一款汽车产品的展示平台,用方向键控制机车移动,点鼠标左键复位汽车初始位置。
不过,这个不是2d物理引擎完成的,而是基于PV3D的,,,,恩,3D物理引擎是在比较难搞……有时间尝试整理下……
下边来说下Demo的具体实现,首先要收下物理引擎,物理引擎是干嘛用的呢?
物理引擎是一个处理物理现象的引擎。
那什么是物理现象呢?
举个例子,一个风筝在天上飞,它会受到风力,阻力,摩擦力,还有重力,绳子的作用力,etc。。。而物理引擎就是帮你处理这些力的一个框架集。
你要做的就是给它个重力,然后都作用在风筝上,至于这些里之间的相互作用,都由引擎来搞定。
下边来代码,先是文档类,也就是主容器了:
package org.nwhy.bubble_bobble{
import flash.display.*;
import flash.events.Event;
import org.cove.ape.*;
public class BubbleBobble extends Sprite{
private var bulletHolder:Group;
public function BubbleBobble(){
init();
}
private function init(){
initStage();
initGroups()
}
private function initStage(){
stage.scaleMode = StageScaleMode.NO_SCALE;//设置为不缩放
//stage.align = StageAlign.TOP_LEFT;
stage.frameRate = 55;//设置帧频
stage.addEventListener(Event.ENTER_FRAME, run);
}
private function initGroups(){
//初始化2D物理引擎
APEngine.init(1/4);
APEngine.container = this;
APEngine.addForce(new VectorForce (false,0,1));//加上重力
//放bullet的容器,bullet就是那个各种颜色的球~
bulletHolder = new Group(true);
APEngine.addGroup(bulletHolder);
//加入墙壁
var wall:Wall = new Wall();
APEngine.addGroup(wall);
//gun,就是下边那个大伯说有点像啥的那个啥……囧一个
var gunGroup:GunGroup = new GunGroup(stage);
APEngine.addGroup(gunGroup);
//设置bullet的碰撞检测内容
bulletHolder.addCollidableList(new Array(wall,gunGroup));
}
private function run(e:Event) {
APEngine.step();
APEngine.paint();
}
//增加bullet的对外接口
public function addBullet(bullet:CircleParticle){
bulletHolder.addParticle(bullet);
}
}
}
这里边干的事就是加入各种Group(APE物理引擎里的碰撞单元是Particle,单个或多个Particle组成Group),至于Group里具体是啥Group里自己处理。
Flash – APE物理引擎学习<一>
APE是什么就不介绍了,下边先上Demo:
点击鼠标发射子弹,击中那个囧就过关了。
代码实现其实也很简单,APE里边所有的Item都是以Group的形式存在。
在这个Demo里,上边的5个球是一组,例子里是Avatar类,里边有5个WheelParticle,不知道为何CircleParticle没有旋转的。
AS3-类似于机战的角色移动(基于Tile)
先来看下Demo:
源代码下载地址:http://dl.dropbox.com/u/477487/flash/game/mapMove.rar
只做了移动,重叠和阻挡的部分没做,短时间内不会有时间做的=,=
主要逻辑是这样,选中Role就显示可以行走的范围,选其中一点之后Role就移动。
下边看下简单的实现。主要是OverlayView.as和Role.as,我很懒,其他代码大家自己看……
Flex – MXML组件开发
一下内容基本来自《Flash Builder4中文快速入门》。
项目开发中,会出现不少重复使用的组件,这时候自然就会需要组件开发。
Flash Builder中,组件可以被定义在MXML或ActionScript文件中。而定义在MXML中的组件都可以转化为定义在ActionScript 中的组件。Flex SDK中的大部分组件都定义在ActionScript文件中的。
MXML 组件开发的优点:
1. 可以利用“设计”模式,进行所见即所得的界面开发。
2. 可以快速的添加子组件。不需要申明一个实例,然后再调用 addChild(),将其添加到父组件的布局中去。
3. 可以很方便地进行数据绑定。使用 “{ binding_expression }”可以快速将任意可绑定的数据源绑定到指定位置。
4. 可以很方便的定义类实例,不需要显示的初始化。例如定义
例。
MXML 语言的缺点:
1. 没有 ActionScript 的辅助,无法完成复杂的逻辑。
2. MXML 组件默认都是 public 的,没有访问限制。
3. MXML 标签中定义的事件是不可以被移除的。如
4. 不能自定义构造函数。
使用 Flash Builder 4 和 MXML 语言开发组件的步骤:
1. 新建 Flex 库项目。Flex 库项目编译后可以产生 swc 文件,可以作为组件发布的主要形式。
2. 新建 MXML 组件文件,文件名即为组件名。
3. 继承现有组件。文件内部第一级标签即为所继承组件名。
4. 在 MXML 文件主标签里加 implements 属性可以继承接口。
5. 在 MXML 文件里添加各种标签,包括可视组件,数据服务,验证,特效等。如果是非可视的标签,如特效等要加到
<fx :Declarations></fx>
标签里,这是 Flex 4 的新特点。
6. 可以在
<fx :Script></fx>
标签里添加 ActionScript 代码,以实现逻辑,比如事件处理等。代码要被 < ![CDATA[ 和 ]]>
包围。
7. 可以在
<fx :Style></fx>
标签里添加CSS样式代码,以设置组件样式。
8. 可以添加
<fx :XML></fx>,<fx :XMLList></fx>,<fx :Array></fx>,<fx :Model></fx>
等实用标签,以提供更好的功能。这些标签都
加在
<fx :Declarations></fx>
标签里。
唉,在用的WP代码插件对MXML的解析很有问题。。。。。。。。。。。。
Flash – Text Search Engine Class
Learned from http://www.pippoflash.com/index.php/2006/07/10/downaload-flash-text-search-engine-class/
看日期会很惊讶的发现这是06年的文章。下边是Demo:
Flex 4 List Scrolling on Android with Flash Player 10.1
Learned from http://www.jamesward.com/2010/02/19/flex-4-list-scrolling-on-android-with-flash-player-10-1/
One of the challenges of running existing web content on mobile devices is that user interactions differ between mediums. For instance, on a normal computer with a mouse, scrolling though lists is often done by clicking on scroll bars or mouse wheels. On mobile devices that lack a pointing device this is not the best interaction paradigm. On devices with touch screens the paradigm for scrolling is usually a swipe gesture.
In Flash Player 10.1 there are APIs for gestures and multitouch events. I thought it would be fun to hook up the list scrolling on a Flex 4 List to the TouchEvent on my Nexus One. Check out the video:
If you want to see how I created this simple demo, check out the source code. Let me know if you have any questions.
---------------------------------------------------------------------------------------------------------------------
视频很卡,只是随便看了下。看源代码的情况,是一个twitter的list列表展示。
看起来,Flash Player在Android下边运行的不错,希望赶紧出个可以直接发布成APK的Flash IDE吧。
不过真的要是发布了,那也是个头疼的事儿,到底是用Flash开发呢还是用Eclipse开发?
Flash的效率会是如何?对硬件的支持呢?慢慢等吧……只有尝试了才知道。
AS3-aSpaceEscape 迷宫脱离游戏(四)整合部分
前边咱讲了地图和角色的生成以及逻辑代码部分,接下去就是2者的整合了。
这个整合的类我把它命名成Controller.as,在主场景的时间轴里写上:
import org.nwhy.aSpaceEscape.*; var controller:Controller = new Controller(stage,0); addChild(controller);
然后是Controller.as:
package org.nwhy.aSpaceEscape{
import flash.display.Sprite;
import flash.display.Stage;
public class Controller extends Sprite{
private var mStage:Stage;
public static var level:uint;//等级
private var role:Role;
public function Controller(stage:Stage,levelID:uint){
mStage = stage;
level = levelID;
drawMap();
drawRole();
}
private function drawMap(){
var map:Map = new Map(Config.MAP[level]);
addChild(map);
}
private function drawRole(){
role = new Role(mStage);
addChild(role);
}
}
}
代码内容很简单,画一个Map,然后画一个Role,就完成了~
整个游戏的代码地址(Full source):http://dl.dropbox.com/u/477487/flash/game/aSpaceEscape.rar
AS3-aSpaceEscape 迷宫脱离游戏(三)角色部分
刚我们讲了地图,看起来还是挺简单的,只要输入一个数组,或者说是一个地图矩阵块,一个地图就被生成了。
那下边我们无敌的主角就要上场了,就是那个看起来在大笑,那个很嚣张的东东,我们就起个类名叫Role好了,当然你也可以把这个类叫JJ,GG,MM,DD,etc~
跟角色有关的逻辑应该尽量都放在这个类内部,为啥说应该尽量呢,有些时候有变态的特殊需求嘛。
好,来看Role.as:
package org.nwhy.aSpaceEscape{
import flash.display.Sprite;
import flash.display.Stage;
import flash.geom.Rectangle;
import flash.events.*;
public class Role extends Sprite {
private var mStage:Stage;//根场景的stage;
private var level:uint;
private var mSpeed:int = Config.TILE_SIZE;//移动速度
private var xSpeed:int;
private var ySpeed:int;
private var mDown:Array = [0,0,0,0];//按键组合,只需要上下左右不需要45度角,so...
private var isKeyDown:Boolean;
public function Role(stage:Stage):void {
level = Controller.level;
mStage = stage;
reset();
//添加事件监听
addEventListeners();
}
private function addEventListeners():void{
mStage.addEventListener(KeyboardEvent.KEY_DOWN, mKeyDownHandler);//Keyboard事件
mStage.addEventListener(KeyboardEvent.KEY_UP, mKeyUpHandler);
addEventListener(Event.ENTER_FRAME, mUpdate);
}
private function mKeyDownHandler(e:KeyboardEvent):void{
if(!isKeyDown){
switch (e.keyCode) {
case 37 :
mDown[0]=1;
break;
case 38 :
mDown[1]=1;
break;
case 39 :
mDown[2]=1;
break;
case 40 :
mDown[3]=1;
break;
}
isKeyDown = true;
}
checkKeyDown(mDown.join(""));
}
private function mKeyUpHandler(e:KeyboardEvent):void {
switch (e.keyCode) {
case 37 :
mDown[0]=0;
break;
case 38 :
mDown[1]=0;
break;
case 39 :
mDown[2]=0;
break;
case 40 :
mDown[3]=0;
break;
}
}
private function checkKeyDown(k:String){
switch(k){
case "1000" :
//trace("left");
xSpeed = - mSpeed;
ySpeed = 0;
break;
case "0100" :
//trace("top");
xSpeed = 0;
ySpeed = - mSpeed;
break;
case "0010" :
//trace("right");
xSpeed = mSpeed;
ySpeed = 0;
break;
case "0001" :
//trace("down");
xSpeed = 0;
ySpeed = mSpeed;
break;
}
}
private function mUpdate(e:Event){
var posX:int = (x+xSpeed)/mSpeed;
var posY:int = (y+ySpeed)/mSpeed;
if(posX>=Config.TILE_PERLINE || posY>=Config.TILE_PERLINE || posX< =-1 || posY<=-1){
trace("out of stage");
xSpeed = 0;
ySpeed = 0;
reset();
isKeyDown = false;
}else if(Config.MAP[level][posY][posX] > 1 && Config.MAP[level][posY][posX] !=5){
xSpeed = 0;
ySpeed = 0;
isKeyDown = false;
//trace(posX,posY,Config.MAP[level][posY][posX]);
}else if(Config.MAP[level][posY][posX] == 5){
trace("succ");
x += xSpeed;
y += ySpeed;
xSpeed = 0;
ySpeed = 0;
}
x += xSpeed;
y += ySpeed;
}
private function reset(){
x = Config.ROLE_POSITION[Controller.level][0] * Config.TILE_SIZE;
y = Config.ROLE_POSITION[Controller.level][1] * Config.TILE_SIZE;
}
}
}
AS3-aSpaceEscape 迷宫脱离游戏(二)地图生成部分
这个游戏一开始,我们需要一个地图类,用来生成地图,这里我用的是方格的形式,每个方格Tile使用的是同一个类Tile.as,至于不同的Tile素材,只要在库里弄个元件,不同帧放上不同的素材,然后绑定Tile类就可以了。
Map类的代码是这样:
package org.nwhy.aSpaceEscape{
import flash.display.Sprite;
public class Map extends Sprite{
private var data:Array;
public function Map(mapData:Array){
data = mapData;
drawMap();
}
private function drawMap(){
var len:uint = data.length;
var tile:Tile;
for(var i:uint=0;i<len;i++){
for(var j:uint=0;j<Config.TILE_PERLINE;j++){
tile = new Tile(data[i][j]+1);
tile.x = j * Config.TILE_SIZE;
tile.y = i * Config.TILE_SIZE;
addChild(tile);
}
}
}
}
}
填充的Tile.as:
package org.nwhy.aSpaceEscape{
import flash.display.MovieClip;
public class Tile extends MovieClip{
private var tileID:uint;
public function Tile(id:uint){
tileID = id;
showTile();
}
private function showTile(){
gotoAndStop(tileID);
}
}
}
代码是相当的简单。给个tileID 然后跑到指定帧就可以了~
然后是配置文件:
package org.nwhy.aSpaceEscape{
public class Config{
public static const TILE_SIZE:uint = 30;
public static const TILE_PERLINE:uint = 12;//指定每行的Tile数,列数并不固定
public static const MAP:Array = [[[0,0,0,0,0,0,0,0,0,0,0,0],
[0,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,2,1,0],
[0,1,1,2,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,5,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,0],
[0,1,2,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,2,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,0],
[0,0,0,0,0,0,0,0,0,0,0,0]]];
public static const ROLE_POSITION:Array = [[2,2]];
}
}
AS3-aSpaceEscape 迷宫脱离游戏(一)分析
分享知识点:
1.Flash里的代码(Class,Actionscript)和库中的UI元件(MovieClip,Sprite)如何绑定。
2.KeyboardEvent,按键事件的绑定和处理。
3.如何把一个库中的UI元件加入到场景中。
4.stage的使用。
5.视图的刷新。
最近在想,做点什么Flash的分享好。在上一个周末,玩了一个Flash小游戏,觉得还不错,就写了一个。
来来来,咱来看一下Demo:
先来说说游戏的玩法,用小键盘的上下左右键控制移动那个看起来很嚣张的怪物,话说这个怪物是啥我也不知道……XX表情里扣出来的……
怪物只能直线移动,中途不能换方向,碰到树桩就会停下,跑出屏幕外就挂了(接着会被搬回到出发点),跑到Exit的地方就过关了。
是个很简单的游戏对吧,那应该怎么来实现呢?Follow me~
首先我们来整理一下需要的东西(PS:不包括素材):
1.怪物对象(Role Class);就是那个很嚣张的怪物
2.地图对象(Map Class);看到的全部方块的集合,包括树,出口
3.填充地图的对象(Tile Class);树,出口等
4.参数配置对象(Config Class/XML);
5.控制器(Controller Class);场景控制
6.etc;占位,可能会需要的东西
AS3 – dispatchEvent()
忽然想说下dispatchEvent(),这谈到dispatchEvent()就要提起EventDispatcher:
包 flash.events
类 public class EventDispatcher
继承 EventDispatcher Object
实现 IEventDispatcher
子类 Animator, Camera, ContextMenu, ContextMenuItem, DataProvider, DisplayObject, FileReference, FileReferenceList, IME, LoaderInfo, LocalConnection, Locale, Microphone, NetConnection, NetStream, PrintJob, RadioButtonGroup, SharedObject, Socket, Sound, SoundChannel, StyleSheet, Timer, Transition, TransitionManager, Tween, URLLoader, URLStream, XMLSocket语言版本 : ActionScript 3.0
Player 版本 : Flash Player 9EventDispatcher 类实现 IEventDispatcher 接口,并且是 DisplayObject 类的基类。 EventDispatcher 类允许显示列表上的任何对象都是一个事件目标,同样允许使用 IEventDispatcher 接口的方法。
事件目标是 Flash ® Player 事件模型的重要组成部分。 事件目标是事件如何通过显示列表层次结构这一问题的焦点。 当发生鼠标单击或按键等事件时,Flash Player 会将事件对象调度到从显示列表根开始的事件流中。 然后该事件对象在显示列表中前进,直到到达事件目标,然后从这一点开始其在显示列表中的回程。 在概念上,到事件目标的此往返行程被划分为三个阶段:捕获阶段包括从根到事件目标节点之前的最后一个节点的行程,目标阶段仅包括事件目标节点,冒泡阶段包括回程上遇到的任何后续节点到显示列表的根。通常,使用户定义的类能够调度事件的最简单方法是扩展 EventDispatcher。 如果无法扩展(即,如果该类已经扩展了另一个类),则可以实现 IEventDispatcher 接口,创建 EventDispatcher 成员,并编写一些简单的挂钩,将调用连接到聚合的 EventDispatcher 中。
所有实现了IEventDispatcher接口的对象,都可以dispatchEvent()事件,EventDispatcher的所有子类自然也是。
那么dispatchEvent()是干嘛用的呢?
dispatchEvent () 方法
public function dispatchEvent(event:Event):Boolean语言版本 : ActionScript 3.0
Player 版本 : Flash Player 9将事件调度到事件流中。 事件目标是对其调用 dispatchEvent() 方法的 EventDispatcher 对象。
参数 event:Event — 调度到事件流中的 Event 对象。 如果正在重新调度事件,则会自动创建此事件的一个克隆。 在调度了事件后,其 target 属性将无法更改,因此您必须创建此事件的一个新副本以能够重新调度。
返回 Boolean — 如果成功调度了事件,则值为 true。 值 false 表示失败或对事件调用了 preventDefault()。
引发 Error — 已达到事件调度递归限制。
简单的说,就是发送事件用的,通常情况下只有在发送自定义事件的时候才会用到dispatchEvent()啦,很多时候为了代码的可读性,也需要一些自定义事件啦。
Flash-TextHighlighter
最近是越来越懒了,Blog有段时间接近于荒废……今天更新下哈。
顾名思义,TextHighlighter就是代码高亮,Demo和做法在这里:http://blog.formatlos.de/2009/06/22/as3-texthighlighter/
1.0版的下载:TextHighlighter_01.zip。
Code:
// highlight container
var highlight : Sprite = new Sprite();
addChild(highlight);
// create textfield
var textField : TextField = new TextField();
addChild(textField);
// apply text style and add text
...
// highlight style
var style : IHighlightStyle = new SimpleHighlightStyle(0x00ff00, 0.5);
// highlighter
var textHighlighter : TextHighlighter = new TextHighlighter(textField, highlight, style);
textHighlighter.highlight(/far/gi);
textHighlighter.highlight("Duden", false);
Flash-鼠标,键盘事件
今天咱来看下Flash的鼠标和键盘事件。。
先放Demo:
这个Demo实现的功能很简单,鼠标放到小球上,小球透明度会变成0.5,鼠标移开会恢复到1,按住鼠标可以拖动小球。按下键盘的上下左右键可以移动小球。
下边咱慢慢来看下,显示fla文档下的代码:
//设置舞台属性,坐上角对齐,不拉伸
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
//new一个Role类的实例出来,并居中显示
var mRole = new Role(stage);
addChild(mRole);
setCenter(mRole);
function setCenter(obj:DisplayObject):void{
obj.x = (stage.stageWidth - obj.width)/2;
obj.y = (stage.stageHeight - obj.height)/2;
}
//onResize事件
stage.addEventListener(Event.RESIZE,mResize);
function mResize(e:Event):void{
//场景大小变化时的操作
}
Flash-SWFAddress
SWFAddress是个干嘛用的东西呢?请看下边的内容:
主要就是一个SEO优化和URL语义化的东西,建议Flash整站的都看下吧~
SWFAddress - Deep linking for Flash and Ajax
SWFAddress is a small but powerful library that provides deep linking for Flash and Ajax. It's a developer tool, allowing creation of unique virtual URLs that can point to a website section or an application state. SWFAddress enables a number of important capabilities which are missing in today's rich web technologies including:
- Bookmarking in a browser or social website
- Sending links via email or instant messenger
- Finding specific content with the major search engines
- Utilizing browser history and reload buttons
Download SWFAddress 2.4 (12MB, Including docs, samples and sources) or just the core scripts and libraries (39KB).
Samples
Flash | Flex | Ajax | SEO | More »
License
SWFAddress is licensed under the MIT license.
Source
The latest and greatest development version of the project can be found at SourceForge.