Nape - Keeping the same physics behaviour over different screen sizes - actionscript-3

Im wondering how to keep the same physics behaviour over different screen sizes?
For example, i have a wheel fixed on the middle of the stage.
I have a mouse pivot joint that i use to spin the wheel.
The radius of the wheel depends on the screen size, it will always occupy about half of screen size.
Now, when i create a wheel on a bigger screen, it is feels as much heavier object. It is much harder to spin it then on a smaller screen size.
Im wondering what is the best practice way of making the physics simulation run exactly the same across all screen sizes?

This is how I usually handle responsive layout in my Air projects, there is probably smarter ways out there but I thought it could help:
(1) Create Sizes helper variables:
package
{
import starling.errors.AbstractClassError;
public class Sizes
{
public function Sizes() { throw new AbstractClassError(); }
public static const SAFE_WIDTH:int = 320;
public static const SAFE_HEIGHT:int = 480;
public static var fullWidth:Number = 0;
public static var fullHeight:Number = 0;
public static var centerX:Number = 0;
public static var centerY:Number = 0;
public static var remainderWidth:Number = 0;
public static var remainderHeight:Number = 0;
public static var halfRemainderWidth:Number = 0;
public static var halfRemainderHeight:Number = 0;
}
}
(2) Then in you main class initializer (where you instanciate Starling) add this code when your stage is ready:
Sizes.scaleToScreen = Math.min( stageWidth / Sizes.SAFE_WIDTH, stageHeight / Sizes.SAFE_HEIGHT );
Sizes.remainderWidth = ( stageWidth / Sizes.scaleToScreen ) - Sizes.SAFE_WIDTH;
Sizes.remainderHeight = ( stageHeight / Sizes.scaleToScreen ) - Sizes.SAFE_HEIGHT;
Sizes.halfRemainderWidth = Sizes.remainderWidth / 2;
Sizes.halfRemainderHeight = Sizes.remainderHeight / 2;
Sizes.fullWidth = stageWidth / Sizes.scaleToScreen;
Sizes.fullHeight = stageHeight / Sizes.scaleToScreen;
Sizes.centerX = Sizes.fullWidth/2;
Sizes.centerY = Sizes.fullHeight/2;
(3) Modify the Root class of your Starling instance, by setting the screen scale:
public function start(background:Texture, bgRect:Rectangle, assets:AssetManager):void
{
// the asset manager is saved as a static variable; this allows us to easily access
// all the assets from everywhere by simply calling "Root.assets"
sAssets = assets;
var bg:Image = new Image( background );
bg.width = bgRect.width / Sizes.scaleToScreen;
bg.height = bgRect.height / Sizes.scaleToScreen;
scaleX = scaleY = Sizes.scaleToScreen; // where the magic happens :)
addChild(bg);
...
(4) Finally, use the set of helpers, and more specifically the first one Sizes.scaleToScreen to match Starling and the display list scales.
// You can now scale your debug Bitmap to match your starling stage scale:
debug = new BitmapDebug(Sizes.fullWidth, Sizes.fullHeight, 0, true);
debug.display.scaleX = debug.display.scaleY = Sizes.scaleToScreen;
Starling.current.nativeOverlay.addChild(debug.display);
So to answer your question, using this technique you would work within constant safe bounds (in this case 320x480) contained within any scaled screen size.
Hope that helps you and others make great responsive games using Starling and Nape!!

Related

as3 - converting bitmap back to vector in view

So I found a V-CAM source, I am now using it and quite happy however, is it possible to untoggled bitmap when the objects that are bitmapped are viewed by the cam? For instance, lets say I have a vector movieclip with a bunch of vector art, I toggle export as bitmap on the movieclip from my IDE, now would it be possible to add on to my VCAM, that everything in its view (it resizes stage) untoggles or redraws back to vector, while the rest of map/movieclip is still in bitmap? And as the VCAM moves away, what was shifted from bitmap to vector gets shifted back to bitmap?
var camColor: ColorTransform = new ColorTransform();
var parentColor: ColorTransform = new ColorTransform();
var cX: Number;
var cY: Number;
var sX: Number;
var sY: Number;
this.visible = false;
var oldMode: String = stage.scaleMode;
stage.scaleMode = StageScaleMode.EXACT_FIT;
cX = stage.stageWidth / 2;
cY = stage.stageHeight / 2;
sX = stage.stageWidth;
sY = stage.stageHeight;
stage.scaleMode = oldMode;
camColor = this.transform.colorTransform;
parentColor = this.parent.transform.colorTransform;
camControl(new Event(Event.ENTER_FRAME));
addEventListener(Event.ENTER_FRAME, camControl);
addEventListener(Event.REMOVED, resetStage);
function camControl(event: Event): void {
camColor = this.transform.colorTransform;
parent.transform.colorTransform = camColor;
var xScale: Number = sX / this.width;
var yScale: Number = sY / this.height;
parent.x = cX - (this.x * xScale);
parent.y = cY - (this.y * yScale);
parent.scaleX = xScale;
parent.scaleY = yScale;
}
function resetStage(event: Event): void {
removeEventListener(Event.ENTER_FRAME, camControl);
parent.transform.colorTransform = parentColor;
parent.scaleX = 1;
parent.scaleY = 1;
parent.x = 0;
parent.y = 0;
}
I think you'd better use another camera with higher bitmap dimensions (2x-4x) to render those scenes from vector that you feel are too pixelized. In terms of export, just export the character's bitmaps 2x-4x larger, or you can just have it as a vector somewhere in your app, maybe hidden, and do realtime render when needed, or plain have it in your display list as a vector and not a bitmap.
In case you need to have some complex vector form into a bitmap-based engine, you can use realtime bitmap drawing of a single source in various postures/rotations, then use those rendered bitmaps to get performance. Check the game "Enigmata: Stellar War" for this technique, how does it look in the process (hint: when it says "Loading boss" it does all the render behind the scenes).
Getting a vectorized source form bitmaps is a lot more processor consuming than having a ready-made vectorized source stored somewhere. Also you won't get your original vector restored in exact form, as converting a vector to a bitmap is a lossy transformation.

Revmob ads showing in the middle of the screen

I have developed a game in starling and after fixing multi resolution issue , i stuck into another one
when I try implementing Revmob banner ads on bottom it shows in the middle of the screen on samsung note - but on samsung galaxy S2 , it show on the bottom which is perfect.
I don't know how to fix this problem
here is two ways i am trying to implement revmob banner ad
Game.revmob.showBanner(0 , stage.stageHeight);
OR
Game.revmob.showBanner();
here is the code for multi resolution
public class FTC extends MovieClip
{
public static var star:Starling;
public static var debugSprite:flash.display.Sprite;
public static var _baseWidth:Number = 480;
private static const STAGE_WIDTH:int = 320;
private static const STAGE_HEIGHT:int = 480;
public static var DIMX:Number;
public static var DIMY:Number;
/**
* The height that the app is based on, this should be the lowest height such as 480 (iphone) or 512 (ipad)
*/
public static var _baseHeight:Number = 800;
public function FTC()
{
this.stage.align = StageAlign.TOP_LEFT;
this.stage.scaleMode = StageScaleMode.NO_SCALE;
Starling.handleLostContext = true;
// Get the preferred stage size based on our smallest target resolution
var stageArea:Rectangle = new Rectangle(0, 0, STAGE_WIDTH, STAGE_HEIGHT);
// Get the fullscreen size available
var fullscreenArea:Rectangle = new Rectangle(0, 0, stage.fullScreenWidth, stage.fullScreenHeight);
// Fit the stage to the full screen. ScaleMode.SHOW_ALL ensures that everything will be visible (not croping will occur).
var viewport:Rectangle = RectangleUtil.fit(stageArea, fullscreenArea, ScaleMode.SHOW_ALL);
// Create a new instance and pass our class, the stage and the wished viewport
star= new Starling(Game, stage, viewport);
// Show debug stats
// star.showStats = true;
// Define level of antialiasing,
star.antiAliasing = 1;
// Set to our preferred stage size
star.stage.stageWidth = STAGE_WIDTH;
star.stage.stageHeight = STAGE_HEIGHT;
star.start();
}
private function onResized(e:Event):void
{
var viewPort:Rectangle = star.viewPort;
viewPort.width = this.stage.stageWidth;
viewPort.height = this.stage.stageHeight;
star.viewPort = viewPort;
star.stage.stageWidth = stage.stageWidth;
star.stage.stageHeight = stage.stageHeight;
}
}
Try to check if the "onResized" Method has been called or maybe you can force a call to it by placing a onResized(null); after the star.start(); call.

Endless repeating scrolling background

I got a problem with AS3 and AIR. I'm working on a side-scrolling game for smartphones with a plane and I use different backgrounds as layers.
Before all other: I use GPU and only bitmaps, quality is set to low. So Performance settings are all set for smartphone use.
I putted them into a rectangle using the drawing API and move the background with a matrix:
protected var scrollingBitmap:BitmapData;
protected var canvas:Graphics;
protected var matrix:Matrix;
public function move(dx:Number, dy:Number):void {
matrix.translate(dx, dy);
if(dx != 0) matrix.tx %= scrollingBitmap.width;
if(dy != 0) matrix.ty %= scrollingBitmap.height;
drawCanvas();
}
protected function drawCanvas():void {
canvas.clear();
canvas.beginBitmapFill(scrollingBitmap, matrix, true, true);
canvas.drawRect(0, -scrollingBitmap.height, 1404, scrollingBitmap.height);
}
UPDATE2 (
Take a look at this: http://plasticsturgeon.com/2010/06/infinite-scrolling-bitmap-backgrounds-in-as3/
I used this to create my backgrounds.
With this I can simulate that my plane is flying to the right without moving the whole background and I can use a small single graphic which repeats every time (for the foreground layer).
For the background layer I use this method, too, but with a much larger graphic and I move it only with less the speed of my plane to simulate a far background.
My move-method is on an enterframe event. So I can update the background every frame with the "movement" of my plane.
)
The plane can exceed the height of the bitmaps. Everytime the bitmap comes back into the window/screen a real long lag occurs. And when the plane flies very fast, the game start to lag, too.
My first approach was to use .PNG files (but they are very big: 1-3MB size).
My next approach was to use .GIF files (much less size).
With both it's the same. So it can't be that.
I read about draw() and copyPixels() but I don't know, how I can use those to repeat the image.
UPDATE1:
protected var scrollingBitmap:BitmapData;
protected var canvas:Bitmap;
protected function init(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
canvas = new Bitmap(new BitmapData(1404, scrollingBitmap.height, true), "auto", true);
this.addChild(canvas);
drawCanvas();
}
public function move(dx:Number, dy:Number):void {
if(dx != 0) dx %= scrollingBitmap.width;
if(dy != 0) dy %= scrollingBitmap.height;
drawCanvas(dx, dy);
}
protected function drawCanvas(xPos:Number = 0, yPos:Number = 0):void {
canvas.bitmapData.copyPixels(scrollingBitmap, new Rectangle(0, 0, 1404, scrollingBitmap.height), new Point(xPos, yPos), scrollingBitmap);
}
I think you'd be better off with a Bitmap instead of using the graphics object with fill. copyPixels is very fast. So what you'd do is simply copyPixels over the top of whatever was there before, presuming everything is opaque. If everything is not opaque, you'll need to use your source bitmap as its own alpha data so previously drawn pixels don't show through.
Let's reframe your canvas so it is a Bitmap and not a MC. your new code will look like:
protected function drawCanvas():void {
canvas.bitmapData.copyPixels(scrollingBitmap, new Rectangle(0, 0, scrollingBitmap.width, scrollingBitmap.height), new Point(0,0), scrollingBitmap);
}
Oh, and look at that! Not only is this code faster, it's only one line of code!
EDIT: Added working code
package {
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.geom.Point;
public class EndlessBG extends MovieClip{
//this one stays stationary, we're getting the pixels for the right side of the pic from here
private var _source:BitmapData;
//this is the one moving to the left (the pixels for the right side are not visible except for once a cycle);
private var _movingPixels:BitmapData;
private var _canvas:Bitmap;
private var _xOffset:int = 0;
private var _rect:Rectangle = new Rectangle();;
private var _point:Point = new Point();
public function EndlessBG() {
super();
_source = new BathroomStillLife();
_canvas = new Bitmap(new BitmapData(_source.width, _source.height));
_canvas.bitmapData.draw(_source);
_canvas.x = stage.stageWidth/2 - _canvas.width/2;
_canvas.y = 5;
addChild(_canvas);
addEventListener(Event.ENTER_FRAME, gameLoop);
setGeometryDefaults();
_movingPixels = new BitmapData(_source.width, _source.height);
_movingPixels.copyPixels(_source, _rect, _point);
//turn this on to watch red pixels be drawn where the source pixels are coming in
//_source = new BitmapData(_source.width, _source.height, false, 0xFF0000);
}
private function gameLoop(e:Event):void {
_xOffset--;//where the background is moving to
if (_xOffset < -_source.width) {
_xOffset = 0;
//this doesn't seem to work correctly:
//_movingPixels.scroll(_source.width, 0);
_movingPixels = new BitmapData(_source.width, _source.height);
_movingPixels.copyPixels(_source, _rect, _point);
}
trace(_xOffset);
setGeometryDefaults();
_movingPixels.scroll(-1, 0);
//draw the moved part of the canvas
_canvas.bitmapData.copyPixels(_movingPixels, _rect, _point);
//If we stop here, we get a smear to the right
//so, get the remaining pixels directly from the source
//1) reset our rect and point to be to the right side
_rect.x = 0;
_rect.width = -_xOffset;
_point.x = _source.width + _xOffset;
//2) copy from the source
_canvas.bitmapData.copyPixels(_source, _rect, _point);
}
private function setGeometryDefaults():void {
_rect.x=0;
_rect.y=0;
_rect.width = _source.width;
_rect.height = _source.height;
_point.x = 0;
_point.y = 0;
}
}
}
Not ideal, and not polished enough yet for a blog post, but should get you started.
Edit:
Eventually I did write that blog post.
http://www.greensock.com/blitmask
This might help although not free

AS3 Bitmaps are too large and improperly placed

Alright I'm programming in actionscript 3, using flex as a compiler. I have an 16x16 large PNG file that is basically a square outline like this:
http://wiki.urbandead.com/images/1/1c/Square.gif
But in more noticeable colors.
I want to draw an 11x11 grid of these squares, so I use these for loops:
for (i1 = 0; i1 < 11; i1 ++)
{
for (i2 = 0; i2 < 11; i2 ++)
{
new OBJECT_tile().CREATE(CONTAINER,32 + 16*i1,32 + 16*i2);
}
}
Where the CREATE() function makes a new tile object with the container CONTAINER with the given x and y coordinates.
public class OBJECT_tile extends Sprite
{
public var X:Number; public var Y:Number;
public var DEPTH:int = 10 ;
public var SPRITE:Sprite = new Sprite();
public var BITMAP:Bitmap;
public var CONTAINER:Sprite = new Sprite();
[Embed(source = 'TILE.png')]
private var CLASS_IMAGE:Class;
private var IMAGE:Bitmap = new CLASS_IMAGE();
public function CREATE(CONTAINER:Sprite,X:Number,Y:Number):void
{
var DATA:BitmapData = new BitmapData(16,16,true,0);
DATA.draw(IMAGE);
BITMAP = new Bitmap(DATA);
BITMAP.smoothing = false;
addChild(BITMAP);
this.CONTAINER = CONTAINER;
(CONTAINER as MAIN).INSTANCE_LIST[(CONTAINER as MAIN).INSTANCE_LIST.length] = this;
this.X = X; BITMAP.x = this.X;
this.Y = Y; BITMAP.y = this.Y;
DRAW();
}}
However for some reason the tiles are drawn to twice their size (32x32 instead of 16x16) and tend to bunch up or spread out depending on how many tabs I have open in my browser. The bunching up isn't consistent either, for instance the tiles might for a 3x3 group that's perfectly fine but then there will just be a line of messed up tiles next to that group (really hard to describe). Why is this happening?
Okay I figured it out. It turns out as3 will try to scale things behind your back, I'm guessing this is some kind of holdout from Adobe's ide (I detest the thing and program in notepad++). Anyways if you stick this:
stage.scaleMode = StageScaleMode.NO_SCALE;
In your main function it will stop it from scaling unless you say otherwise.

Finding Something lighter than Sprites!

I am making a Sim City like game. There are lots of tiles. When I first started. I was just using a tilesheet. I was copying the necessary pieaces from the tilesheet. on to a blank bitMapData. I then took the bitMapData and put it into a bitMap which I then put into a DisplayObject. It worked great!
tileSheet:BitMapData <----- data is already in
loop { loop through and tiled
bg:bitMapData= new bitMapData();
bg.copyPixel(tileSheet,rect,point);
}
canvas.BitMap(bg);
addChild(canvas);
Only problem was I needed to make my tiles interactive. I needed to highlight them and change colors and stuff. So I used the Sprite object. It works great but I can only have so many on the stage at once. or else it moves slow when I scroll. I need something Lighter then a sprite, but yet I can still turn into a object to make interactive. Anyone have any ideas ???
If you have a lot of tiles, that will impact performance because Flash needs to update the transformations of a lot of display objects (which internally means a lot of matrix calculations, and subsequent redraws of big areas of the screen.)
There is another way to achieve interactivity, if you find that you must use a single bitmap data for performance. Keep an "abstract" (i.e. not graphical) data model in memory, that stores your game state. Make sure that you are able to read from your store where a certain element is positioned in the game world. Then you can use a flat bitmap data to render the game world, because the individual positions are stored elsewhere.
When the user clicks the DisplayObject containing the bitmap data (a Sprite in which the bitmap is drawn using a bitmap fill, or that wraps a Bitmap), look in your model which of your game elements was hit by that click.
// myTileSprite is a Sprite with a bitmap fill
myTileSprite.addEventListener(MouseEvent.CLICK, handleWorldClick);
function handleWorldClick(ev : MouseEvent) : void
{
var i : int;
// Loop through all game element data models
for (i=0; i<myGameElements.length; i++) {
// Test the mouse position against the element model
if (myGameElements[i].hitTest(myTileSprite.mouseX, myTileSprite.mouseY)) {
trace('this was the element that was clicked: '+myGameElements[i].toString());
}
}
}
Here, whenever the player clicks the world graphics, the loop tries to find that element which was directly under the mouse position. You will need to implement a hitTest() method on all your game element data models, of course. Such a method simply checks the supplied world space position against the tile's area:
// GameElement.hitTest():
/**
* Tests a world position against the position and area of this game
* element tile. Returns a boolean indicating whether this tile was hit.
*/
public function hitTest(mouseX : Number, mouseY : Number) : void
{
var rect : Rectangle = new Rectangle(this.worldX, this.worldY, this.width, this.height);
if (mouseX > rect.left && mouseX < rect.right
&& mouseY > rect.top && mouseY < rect.top) {
return true;
}
else return false;
}
The GameElement class is not an display object, but has worldX and worldY properties indicating where it is located in the world. It's width and height properties define it's dimensions.
The trick from hereon is to make sure that the rendered bitmap and your model storage is synchronized, so that a tile's position on the bitmap really corresponds to it's worldX/worldY properties in the data model.
I am one step ahead of you. And that is a great idea. Its alot easier to keep a data representation of the world when the tiles are squared. I therefore can take my mouseX/tileWidth, and thats hw many columns I moved from left to right. same with the Y axis.
Not only that but coordinates start at top left corner.
But issue I have is that my tiles are Isometric. So instead of the X axis start off like...
012345678
0
1
2
3
4
5
6
7
8
My tiles are aligned like...
00
1 1
2 2
3 3
4 4
5 6
its a little sloppy. but the right side represents the y axis and the left represents the x axis. and the center origin is in the center of the screen. not on the top left. I am trying to figure out how to measure where my mouse is from the center and out on both sides. This sounds extremely difficult. I am not sure if its possible. The game is suppose to be like a sim city like game. The first sim city was squares not isometric. I dont think they went isometric until they started using 3d. I wonder if its possible to create a illusion of isometric on a square tile.
Ive been reading this great book on isometrics. They show to calculate tiles in 3d space. and even calculate your mouse in 3d space as well. here is the code. Its alot, but I hope someone else understands it more then I. The book was written by jobe makar on building multiplayer worlds. I wanted to share it because the code it is pretty simple as far as amount of code put into it. only 2 classes needed. I am not that good with trigonometry. so I cant really interpret how the math is getting the results. hopefully someone can explain that for me :D.
Y coordinates are not given because the width is = to height. The coordinates method is just a custom made Point class which holds x, y and z.
package com.gamebook.grid {
import com.gamebook.utils.geom.Coordinate;
import com.gamebook.utils.Isometric;
import flash.display.MovieClip;
import flash.events.MouseEvent;
/**
* ...
* #author Jobe Makar - jobe#electrotank.com
*/
public class Map extends MovieClip{
private var _grid:Array;
private var _iso:Isometric;
private var _tileWidthOnScreen:int;
private var _tileHeightOnScreen:int;
private var _tileWidth:Number;
private var _tileHeight:Number;
private var _cols:int;
private var _rows:int;
private var _lastTile:Tile;
public function Map() {
initialize();
}
private function initialize():void{
_iso = new Isometric();
//when mapped to the screen the tile makes a diamond of these dimensions
_tileWidthOnScreen = 64;
_tileHeightOnScreen = 32;
//figure out the width of the tile in 3D space
_tileWidth = _iso.mapToIsoWorld(64, 0).x;
//the tile is a square in 3D space so the height matches the width
_tileHeight = _tileWidth;
buildGrid();
addEventListener(MouseEvent.MOUSE_MOVE, mouseMoved);
}
private function mouseMoved(e:MouseEvent):void {
if (_lastTile != null) {
_lastTile.alpha = 1;
_lastTile = null;
}
var coord:Coordinate = _iso.mapToIsoWorld(mouseX, mouseY);
var col:int = Math.floor(coord.x / _tileWidth);
var row:int = Math.floor(Math.abs(coord.z / _tileHeight));
if (col < _cols && row < _rows) {
var tile:Tile = getTile(col, row);
tile.alpha = .5;
_lastTile = tile;
}
}
private function buildGrid():void{
_grid = [];
_cols = 10;
_rows = 10;
for (var i:int = 0; i < _cols;++i) {
_grid[i] = [];
for (var j:int = 0; j < _rows;++j) {
var t:Tile = new Tile();
var tx:Number = i * _tileWidth;
var tz:Number = -j * _tileHeight;
var coord:Coordinate = _iso.mapToScreen(tx, 0, tz);
t.x = coord.x;
t.y = coord.y;
_grid[i][j] = t;
addChild(t);
}
}
}
private function getTile(col:int, row:int):Tile {
return _grid[col][row];
}
}
}
Then we have the isometric class that calculates 3d space.
package com.gamebook.utils {
import com.gamebook.utils.geom.Coordinate;
/**
* #author Jobe Makar - jobe#electrotank.com
*/
public class Isometric {
//trigonometric values stored for later use
private var _sinTheta:Number;
private var _cosTheta:Number;
private var _sinAlpha:Number;
private var _cosAlpha:Number;
/**
* Isometric class contrustor.
* #param declination value. Defaults to the most common value, which is 30.
*/
public function Isometric() {
var theta:Number = 30;//even though the tiles are already isometric, you still have to put the degrees the tiles will be turned.
var alpha:Number = 45;//45 degrees on y axis, 30 dgrees on x axis
theta *= Math.PI/180; // then you translate to radians
alpha *= Math.PI/180;
_sinTheta = Math.sin(theta);
_cosTheta = Math.cos(theta);
_sinAlpha = Math.sin(alpha);
_cosAlpha = Math.cos(alpha);
}
/**
* Maps 3D coordinates to the 2D screen
* #param x coordinate
* #param y coordinate
* #param z coordinate
* #return Coordinate instance containig screen x and screen y
*/
public function mapToScreen(xpp:Number, ypp:Number, zpp:Number):Coordinate {
var yp:Number = ypp;
var xp:Number = xpp*_cosAlpha+zpp*_sinAlpha;
var zp:Number = zpp*_cosAlpha-xpp*_sinAlpha;
var x:Number = xp;
var y:Number = yp*_cosTheta-zp*_sinTheta;
return new Coordinate(x, y, 0);
}
/**
* Maps 2D screen coordinates into 3D coordinates. It is assumed that the target 3D y coordinate is 0.
* #param screen x coordinate
* #param screen y coordinate
* #return Coordinate instance containig 3D x, y, and z
*/
public function mapToIsoWorld(screenX:Number, screenY:Number):Coordinate {
var z:Number = (screenX/_cosAlpha-screenY/(_sinAlpha*_sinTheta))*(1/(_cosAlpha/_sinAlpha+_sinAlpha/_cosAlpha));
var x:Number = (1/_cosAlpha)*(screenX-z*_sinAlpha);
return new Coordinate(x, 0, z);
}
}
}