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,我很懒,其他代码大家自己看……
Android-用HttpClient抓取html页面内容
用的类库为commons-httpclient-3.1.jar.有兴趣的下载去。代码如下:
private String getHtmlContent(final String url) {
String result = "";// 返回的结果
StringBuffer resultBuffer = new StringBuffer();
// 构造HttpClient的实例
HttpClient httpClient = new HttpClient();
// 创建GET方法的实例
GetMethod getMethod = new GetMethod(url);
// 使用系统提供的默认的恢复策略
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler());
// getMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,"GB2312");
getMethod.getParams().setContentCharset("GB2312");
try {
// 执行getMethod
int statusCode = httpClient.executeMethod(getMethod);
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: "
+ getMethod.getStatusLine());
}
// 流式读取
// 读取内容
// byte[] responseBody = getMethod.getResponseBody();
// 处理内容
// String result = new String(responseBody,"GBK");
// result = getMethod.getResponseBodyAsString();
// System.out.println(result);
// System.out.println(getMethod.getResponseCharSet());
// 推荐做法
BufferedReader in = new BufferedReader(new InputStreamReader(
getMethod.getResponseBodyAsStream(), getMethod
.getResponseCharSet()));
String inputLine = null;
while ((inputLine = in.readLine()) != null) {
resultBuffer.append(inputLine);
resultBuffer.append("\n");
}
result = new String(resultBuffer);
return result;
} catch (HttpException e) {
// 发生致命的异常,可能是协议不对或者返回的内容有问题
System.out.println("Please check your provided http address!");
e.printStackTrace();
} catch (IOException e) {
// 发生网络异常
e.printStackTrace();
} finally {
// 释放连接
getMethod.releaseConnection();
}
return result;
}
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的效率会是如何?对硬件的支持呢?慢慢等吧……只有尝试了才知道。
Lazyer – 寻视觉设计师一枚
09年即将成为历史,在新的一年里,车间需要新生力量的加入。
寻找视觉设计师一枚,要求很简单,MM,36D+就可以了
呵呵,开个玩笑,言归正传,需求如下:
1.对手机终端UI开发有兴趣滴。
2.有手机 and 电脑 ?
3.每周有2天+空闲时间。
4.在杭州优先.
5.MM优先。
6.单身优先。
7.36D+优先。。。
8.党员不考虑。
-------------------------------------------------------------------------------------------
2009 will become history in the new year, we need new members next year.
Looking for a visual designer to require very simple, MM, 36D + could be a good choice.
Ha,just a joke, get on, demand is as follows:
1. For developers interested in mobile terminals UI drops.
2. Have a mobile phone and a computer?
3. Week 2 days + idle time.
4. In Hangzhou priority.
5.MM priority.
6. Single priority.
7.36D + priority. . .
8. Party members are not considered.
jQuery – Plupload 文件批量上传
线上Demo地址:http://www.plupload.com/example_queuewidget.php
可以批量上传图片和zip文件。我看我是越来越懒了,啥都不想介绍了,自己看吧孩子们。
The developers of TinyMCE brings you Plupload, a highly usable upload handler for your Content Management Systems or similar.
Plupload is currently separated into a Core API and a jQuery upload queue widget this enables you to either use it out of the box or write your own custom implementation.
1. Drag/drop support of files is currently only available in Firefox 3.5+. WebKit/Opera doesn't support this feature yet.
2. Image resizing is only possible on Firefox 3.5+ and only at a fixed quality. WebKit/Opera doesn't support direct data access to the selected files.
3. File type filtering is currently not supported by any browser. But we fill the HTML 5 accept attribute so once the support is there it will work.
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]];
}
}
