用away3D 做了一个渲染360°全环境贴图的demo,并制作了一个环绕漫游相机对着中间的盒子进行y轴和x轴的旋转,这样可以更好看看到周围的环境与中间盒子的细节。
skybox

由于单页面渲染多个3D视图 或者 同浏览器多标签渲染 3D视图 会导致 fps 丢失,因此这个demo 放在 》继续阅读 的页面中。
所以先上代码:
[cc lang=”actionscript3″ nowrap=”false”]
package
{
import away3d.materials.utils.CubeMap;
import away3d.primitives.SkyBox;

import flash.events.Event;
import flash.geom.Vector3D;
import flash.ui.ContextMenu;

[SWF(width=”500″,height=”500″,frameRate=”60″)]
public class ViewportClipping extends away3D
{
// Environment map.
[Embed(source=”../Embed/envMap/snow_positive_x.jpg”)]
private var EnvPosX:Class;
[Embed(source=”../Embed/envMap/snow_positive_y.jpg”)]
private var EnvPosY:Class;
[Embed(source=”../Embed/envMap/snow_positive_z.jpg”)]
private var EnvPosZ:Class;
[Embed(source=”../Embed/envMap/snow_negative_x.jpg”)]
private var EnvNegX:Class;
[Embed(source=”../Embed/envMap/snow_negative_y.jpg”)]
private var EnvNegY:Class;
[Embed(source=”../Embed/envMap/snow_negative_z.jpg”)]
private var EnvNegZ:Class;

private var _wave:Number = 0;
private var _origin:Vector3D=new Vector3D(0,0,0);

public function ViewportClipping()
{
var myMenu:ContextMenu=new ContextMenu();
myMenu.hideBuiltInItems();
this.contextMenu=myMenu;

_createView();
_createScene();
_createCamera();
_createSkyBox();
}

protected function _createSkyBox():void
{
var _cubeMap:CubeMap=new CubeMap(new EnvPosX().bitmapData,new EnvNegX().bitmapData,new EnvPosY().bitmapData,
new EnvNegY().bitmapData,new EnvPosZ().bitmapData,new EnvNegZ().bitmapData);

_view.scene.addChild(new SkyBox(_cubeMap));
}

protected override function _onEnterFrame(ev:Event):void
{
_cube1.rotationY-=.5;
_cube1.rotationX-=.5;

_view.camera.position=_origin;
_view.camera.rotationY += .1;
_view.camera.rotationX += .1;
_view.camera.moveBackward(1000);
_wave+= .005;
_view.camera.y = 400+Math.sin(_wave)*200;

_view.render();
}
}
}
[/cc]
Continue reading

研究了一段时间的Unity3D,觉得这货不靠谱。不是说引擎不好,而是已经完全脱离flash的范畴了。其代码是采用js的。唯一和flash有联系的部分就是可以输出成swf文件罢了。

于是打算研究下away3d. 嘛,手头上的资料都是away3D 3.6 的。4.0的资料除了官方 api 和 demo外 基本就没有了,研究的非常吃力。 4.0 和 3.6 的变化非常大,包括 camera3D 就少了 target,focus,zoom 。

放1个立方体旋转的demo,左侧立方体跟随鼠标旋转,右侧立方体随机旋转。

本demo需要 flash player 11.0.0+ 如果你的版本为 10.0.0+ 的话,是无法观看的。

之后是源码部分:
Continue reading

准备了一个国外空间~购买时间是1年,先看看服务怎样吧。
访问速度比国内慢个5倍这样,可以接受啦,稳定的话,就专门放一些demo上去好了。
国内的空间管理起来太麻烦了,迁移也非常麻烦。每次更换空间提供商,就需要重新备案什么的。实在受不了这折腾。
等这个空间到期,而国外空间稳定的话,就搬去国外空间了。
到时候换个VPS吧!

国外空间的地址是 http://www.aoicon.in

啊啊~周一了《未来日记》的熟肉出了,果断去看之~

今天给网游加上用户登录和注册的数据库验证机制

AS编译的swf是不允许直接访问或修改硬盘文件的(共享对象和上传下载功能例外,编译成AIR RUNTIME可以彻底解决此问题) 因此必须借用外部方法比如js,asp,php,asp.net等。

AS验证数据类: 使用类似amfphp的方式,建立一个控制类Command.php 然后由Command.php判断该调用哪些类(Login.php 或 Register.php)来解析数据

[cc lang=”actionscript3″ nowrap=”false”]
package com.client
{
import com.Config;

import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;

public class DataBaseCheck extends EventDispatcher
{
public static const SUCCESS=”success”;
public static const FAILURE=”failure”;

private var _userName;
private var _passWord;
private var _login:Boolean;

private var myLoader:URLLoader;
private var myXML:XML;

public function DataBaseCheck(userName:String,passWord:String,Login:Boolean=true)
{
_userName=userName;
_passWord=passWord;
_login=Login;
init();
}

private function init()
{
myLoader=new URLLoader();
myLoader.dataFormat=URLLoaderDataFormat.VARIABLES;
myLoader.load(new URLRequest(Config.WWWROOT+”Command.php?userName=”+_userName+”&passWord=”+_passWord+”&isLogin=”+_login));
myLoader.addEventListener(Event.COMPLETE,onCom);
myLoader.addEventListener(IOErrorEvent.IO_ERROR,onError);
}

private function onError(e:IOErrorEvent)
{
this.dispatchEvent(new Event(FAILURE));
}

private function onCom(e:Event)
{
var data:String=e.target.data[“result”];
myLoader.removeEventListener(Event.COMPLETE,onCom);
myLoader.removeEventListener(IOErrorEvent.IO_ERROR,onError);
myLoader=null;

if(data==”true”)
{
this.dispatchEvent(new Event(SUCCESS));
}else{
this.dispatchEvent(new Event(FAILURE));
}
}
}
}
[/cc]

PHP命令中心
Command.php

[cc lang=”php” nowrap=”false”]
check();
?>
[/cc]

Continue reading

周末给数据包对象加了一个对战信息的字段后,有几率的出现【堆栈上溢】或者是 【RangeError: Error #2006: 提供的索引超出范围。】 的错误。

具体结果2种:

1.数据包该字段的数值实际为其他字段的字段名或其他字段的数值。

2.直接报错,程序退出。

这里以一个4字节长度的数值字段举例:发送的数据包中的某个字段中的数据本应是4个字节长度的,但是该字段由于某些原因没有被赋值,实际为null。既:数据包解析器要解析4个字节长度的数据,但是实际数据为null,长度不为4. 这时数据包解析器认为当前的数据没有解析完毕,开始等待新的数据流,而新的数据流实际又是另一个数据包中的数据。这时就会产生递归死循环。

实际上这其实是一个人为的可以避免的错误。首先给 Object对象的动态属性赋值是一个逃避编译器的错误校验的,因此编译程序的时候编译器无法检测到Object对象的某一属性值为null。解决方法就是给数据包也编译一个反射类,并判断个属性是否为null。

ps:突然觉得做一个ui管理器和event管理器很有必要啊。晚上搞定它吧。

中午吃了烤肉,晚上果断有力量了有木有!!!

然后把网游对战系统部分完成了。由于手头没有攻击招数这部分的模型。所以以文字对战的形式来实现。

具体过程是:点击一个玩家发送对战请求,对方玩家弹出提示(是否接收对战),选择 是 ,发起对战者2次确认后,对战开始,同步对战信息,对战结束。

以下是同步对战信息的java服务端代码:
[cc lang=”java” nowrap=”false”]
// 广播对战信息
if(myHashMap.get(“Event”).equals(this.BATTLE_START)){
Person p1=new Person();
Person p2=new Person();
p1.userName=selfUser.target;
p2.userName=selfUser.initiator;
nameFight myFight=new nameFight(p1, p2);
String battleInfo=myFight.Fight();

while (iterator.hasNext()) {
MyThread thread = iterator.next();
if (thread.getName().equals(selfUser.initiator) || thread.getName().equals(selfUser.target)) { //仅向对战的双方主动推送对战信息
HashMap myObj = new HashMap();
myObj.put(“Event”, this.BATTLE_START);
myObj.put(“Target”, selfUser.target);
myObj.put(“Initiator”, selfUser.initiator);
myObj.put(“BattleInfo”, battleInfo);

thread.sendObj(myObj, thread.client);
}
}
return;
}
[/cc]

昨天终于吧战锤40k-星际战士通关了的说~ 话说手头还有好多游戏要通关啊。

神马《爱丽丝-疯狂回归》,《Dirt3》,《死亡空间3》 =。= 玩的都把手头的项目给暂停了。

貌似 苍穹之法芙娜 的中文字幕也出了!!! 啊啊,好多东西要玩想看啊。

好吧~这周末把闲置的项目都试着继续完善吧:

1.Unity3D 的赛车游戏demo

2.网游对战系统

3.一些莫名其妙的东西

先放个比较热血的PV

然后放一个目前的进度裁图 可以算是经过了 alpha 到达了milestone的阶段了啊
准备把人物模型换成英雄传说系列的。 毕竟大话西游的人物太多人认识了,会被人误解的,这样不好不好~

原本完全没想到这些,无意中在某博客中看到的demo.才突然顿悟。写下自己的思考,以后有机会来实现。

多人游戏场景加载的一般方式是:

打开游戏,出现一个进度条。表示当前游戏场景的加载进度,加载完毕后,进入游戏。

某博客中的场景加载方式是:

打开游戏,无需等待,直接进入游戏。游戏场景在游戏中分块加载完毕。即玩家可以看到地图区块慢慢填满屏幕的效果。

我思考的场景加载方式是:

以玩家所在位置做放射状地图加载,这种方式可以比较容易的实现卡马克卷轴算法。

要实现的方式并不复杂。首先,将地图场景进行切块。然后根据行列值存进xml的节点中。

进入游戏后,根据玩家所在的地图坐标,算出玩家所在的行列值。然后去xml列表中找到对应的地图区块,并以此为原点放射性的加载周围的地图。

实现卡马克卷轴算法的方式是:玩家与屏幕边距的差值/地图区块的大小。算出玩家到地图四周个需要几行,几列。 在放射性加载地图区块的函数中,用一个递归循环去加载区块到边沿。这样遍实现了,玩家所能看到的区域就是所需绘图的区域,玩家看不见的区域完全不进行绘图。这样能提高地图的加载速度和fps.

嘛~以上! 顺便再次哀悼下:乔帮主,您走好~