# “AS3.0高级动画编程”学习：第三章等角投影(上)

+关注继续查看

[转载]等角(斜45度)游戏与数学

[转载]使用illustrator和正交投影原理以及基本三视图制图

package {
public class Point3D {
public var x:Number;
public var y:Number;
public var z:Number;
public function Point3D(x:Number=0,y:Number=0,z:Number=0) {
this.x=x;
this.y=y;
this.z=z;
}
}
}


x1 = x - z
y1 = y * 1.2247 + (x + z) * 0.5
z2 = (x + z) * 0.866 - y * 0.707 --用于层深排序，可以先不管

package {

import flash.geom.Point;
public class IsoUtils {

//public static const Y_CORRECT:Number=Math.cos(- Math.PI/6)*Math.SQRT2;
public static const Y_CORRECT:Number = 1.2247448713915892;

//把等角空间中的一个3D坐标点转换成屏幕上的2D坐标点
public static function isoToScreen(pos:Point3D):Point {
var screenX:Number=pos.x-pos.z;
var screenY:Number=pos.y*Y_CORRECT+(pos.x+pos.z)*0.5;
return new Point(screenX,screenY);
}

//把屏幕上的2D坐标点转换成等角空间中的一个3D坐标点
public static function screenToIso(point:Point):Point3D {
var xpos:Number=point.y+point.x*.5;
var ypos:Number=0;
var zpos:Number=point.y-point.x*.5;
return new Point3D(xpos,ypos,zpos);
}
}
}


package {

import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.geom.Point;

[SWF(backgroundColor=0xefefef,height="200",width="300")]
public class IsoTransformTest extends Sprite {
public function IsoTransformTest() {
stage.align=StageAlign.TOP_LEFT;
stage.scaleMode=StageScaleMode.NO_SCALE;

var p0:Point3D=new Point3D(0,0,0);
var p1:Point3D=new Point3D(100,0,0);
var p2:Point3D=new Point3D(100,0,100);
var p3:Point3D=new Point3D(0,0,100);

var sp0:Point=IsoUtils.isoToScreen(p0);
var sp1:Point=IsoUtils.isoToScreen(p1);
var sp2:Point=IsoUtils.isoToScreen(p2);
var sp3:Point=IsoUtils.isoToScreen(p3);

var tile:Sprite = new Sprite();
tile.x=150;
tile.y=50;

tile.graphics.lineStyle(0);
tile.graphics.moveTo(sp0.x, sp0.y);
tile.graphics.lineTo(sp1.x, sp1.y);
tile.graphics.lineTo(sp2.x, sp2.y);
tile.graphics.lineTo(sp3.x, sp3.y);
tile.graphics.lineTo(sp0.x, sp0.y);

trace(Math.cos(- Math.PI/6)*Math.SQRT2);//1.2247448713915892
trace(tile.width,tile.height);//200 100 符合上面提到的2:1
}
}
}


package {
import flash.display.Sprite;
import flash.geom.Point;
import flash.geom.Rectangle;

public class IsoObject extends Sprite {

protected var _position:Point3D;
protected var _size:Number;
protected var _walkable:Boolean=false;

//public static const Y_CORRECT:Number=Math.cos(- Math.PI/6)*Math.SQRT2;
public static const Y_CORRECT:Number=1.2247448713915892;

public function IsoObject(size:Number) {
_size=size;
_position = new Point3D();
}

//更新屏幕坐标位置
var screenPos:Point=IsoUtils.isoToScreen(_position);
super.x=screenPos.x;
super.y=screenPos.y;
}

override public function toString():String {
return "[IsoObject (x:" + _position.x + ", y:" + _position.y+ ", z:" + _position.z + ")]";
}

//设置等角空间3D坐标点的x,y,z值
override public function set x(value:Number):void {
_position.x=value;
}

override public function get x():Number {
return _position.x;
}

override public function set y(value:Number):void {
_position.y=value;
}
override public function get y():Number {
return _position.y;
}

override public function set z(value:Number):void {
_position.z=value;
}

override public function get z():Number {
return _position.z;
}

//_position的属性封装
public function set position(value:Point3D):void {
_position=value;
}
public function get position():Point3D {
return _position;
}

//深度排序时会用到，现在不用理这个
public function get depth():Number {
return (_position.x + _position.z) * .866 - _position.y * .707;
}

//这个暂时也不用理
public function set walkable(value:Boolean):void {
_walkable=value;
}
public function get walkable():Boolean {
return _walkable;
}

public function get size():Number {
return _size;
}

public function get rect():Rectangle {
return new Rectangle(x - size / 2, z - size / 2, size, size);
}
}
}


package {
public class DrawnIsoTile extends IsoObject {
protected var _height:Number;
protected var _color:uint;
public function DrawnIsoTile(size:Number,color:uint,height:Number=0) {
super(size);
_color=color;
_height=height;
draw();
}

//画矩形"贴片"
protected function draw():void {
graphics.clear();
graphics.beginFill(_color);
graphics.lineStyle(0,0,.5);
graphics.moveTo(- size,0);
graphics.lineTo(0,- size*.5);
graphics.lineTo(size,0);
graphics.lineTo(0,size*.5);
graphics.lineTo(- size,0);
}

//height属性暂时不用管（在draw里也没用到）
override public function set height(value:Number):void {
_height=value;
draw();
}
override public function get height():Number {
return _height;
}

//设置颜色
public function set color(value:uint):void {
_color=value;
draw();
}
public function get color():uint {
return _color;
}
}
}


package {
public class DrawnIsoBox extends DrawnIsoTile {
public function DrawnIsoBox(size:Number, color:uint, height:Number) {
super(size, color, height);
}
override protected function draw():void {
graphics.clear();

//提取r,g,b三色分量
var red:int=_color>>16;
var green:int=_color>>8&0xff;
var blue:int=_color&0xff;

//假如光源在右上方（所以左侧最暗，顶上最亮，右侧在二者之间）
var leftShadow:uint = (red * .5) << 16 |(green * .5) << 8 |(blue * .5);
var rightShadow:uint = (red * .75) << 16 |(green * .75) << 8 | (blue * .75);
var h:Number=_height*Y_CORRECT;

//顶部
graphics.beginFill(_color);
graphics.lineStyle(0, 0, .5);
graphics.moveTo(-_size, -h);
graphics.lineTo(0, -_size * .5 - h);
graphics.lineTo(_size, -h);
graphics.lineTo(0, _size * .5 - h);
graphics.lineTo(-_size, -h);
graphics.endFill();

//左侧
graphics.lineStyle(0, 0, .5);
graphics.moveTo(-_size, -h);
graphics.lineTo(0, _size * .5 - h);
graphics.lineTo(0, _size * .5);
graphics.lineTo(-_size, 0);
graphics.lineTo(-_size, -h);
graphics.endFill();

//右侧
graphics.lineStyle(0, 0, .5);
graphics.moveTo(_size, -h);
graphics.lineTo(0, _size * .5 - h);
graphics.lineTo(0, _size * .5);
graphics.lineTo(_size, 0);
graphics.lineTo(_size, -h);
graphics.endFill();
}
}
}


package {

import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.*;
import flash.events.MouseEvent;
import flash.geom.Point;
[SWF(backgroundColor=0xffffff,height=380,width=600)]
public class BoxTest extends Sprite
{
private var world:Sprite;

public function BoxTest()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
world = new Sprite();
world.x = stage.stageWidth / 2;
world.y = 50;
for(var i:int = 0; i < 15; i++)
{
for(var j:int = 0; j < 15; j++)
{
var tile:DrawnIsoTile = new DrawnIsoTile(20, 0xcccccc);
tile.position = new Point3D(i * 20, 0, j * 20);
}
}
}

private function onWorldClick(event:MouseEvent):void
{
var box:DrawnIsoBox = new DrawnIsoBox(20, Math.random() * 0xffffff, 20);
var pos:Point3D = IsoUtils.screenToIso(new Point(world.mouseX, world.mouseY));
pos.x = Math.round(pos.x / 20) * 20;
pos.y = Math.round(pos.y / 20) * 20;
pos.z = Math.round(pos.z / 20) * 20;
box.position = pos;
}

private function resizeHandler(e:Event):void{
world.x = stage.stageWidth / 2;
}
}
}


JavaScript 编程精解 中文第三版 十二、项目：编程语言

1131 0
SAS学习笔记之《SAS编程与数据挖掘商业案例》（4）DATA步循环与控制、常用全程语句、输出控制
SAS学习笔记之《SAS编程与数据挖掘商业案例》（4）DATA步循环与控制、常用全程语句、输出控制 1. 各种循环与控制 DO组 创建一个执行语句块 DO循环 根据下标变量重复执行DO和END之间的语句 DO WHILE 重复执行直到条件为假则退出循环 DO UNTIL 重复执行直到条件为真则退出循环 DO OVER 对隐含下标
1320 0

27697 0
JavaScript 编程精解 中文第三版 一、值，类型和运算符

1271 0
SAS学习笔记之《SAS编程与数据挖掘商业案例》（5）SAS宏语言、SQL过程
SAS学习笔记之《SAS编程与数据挖掘商业案例》（5）SAS宏语言、SQL过程 1. 一个SAS程序可能包含一个或几个语言成分： DATA步或PROC步 全程语句 SAS组件语言（SCL） 结构化查询语言（SQL） SAS宏语言 2. 宏触发：% 是一个宏语句或宏函数；&amp;是一个宏变量引用 3. 局部宏变量：一般程序定义的为宏变量。 全局
1774 0
SAS学习笔记之《SAS编程与数据挖掘商业案例》（2）数据获取与数据集操作
SAS学习笔记之《SAS编程与数据挖掘商业案例》（2）数据获取与数据集操作 1. SET/SET效率高，建立的主表和建表索引的查询表一般不排序， 2. BY语句，DATA步中，BY语句规定分组变量，用于控制SET，MERGE,UPDATE或MODIFY语句。 BY&lt;DESCENDING&gt;variable-1 &lt;...&lt;DESCENDI
1477 0
SAS学习笔记之《SAS编程与数据挖掘商业案例》（1）系统简介和编程基础
SAS学习笔记之《SAS编程与数据挖掘商业案例》（1）系统简介和编程基础 1. SAS系统简介 1.1 SAS是先编译后执行的语言，data步标志着编译的开始。 数据指针：当前内存缓存区，输入数据所在位置。 PDV:Program Data Vector，在DATA步中所有涉及的变量被编程当前向量的一部分。 2. SAS编程基础 2.1 SAS逻
1583 0
JavaScript 编程精解 中文第三版 二、程序结构

1318 0

19976 0
+关注

1102

0

JS零基础入门教程（上册）