AS3 Display list and box2d - actionscript-3

I have a function called "brick" inside a subclass called createBrick that extends from the sprite class, also I have a movie clip created in the library exported for runtime sharing called "Brick". For some odd reason when I run the code the brick is not showing up on the stage even though it does get created when I debug the code.
here is the function
public class createBrick extends Sprite {
public function createBrick(_main:Main) {
main = _main;
var go:Brick = new Brick();
addChild(go);
trace(go.x);
brick(475, 235, 30, 30);
}
private function brick(pX: int, pY: int, w: Number, h: Number): void {
var bric:Brick = new Brick();
addChild(bric);
bric.x = pX;
bric.y = pY;
bric.width = w;
bric.height = h;
var polygonShape: b2PolygonShape = new b2PolygonShape();
var polygonFixture: b2FixtureDef = new b2FixtureDef();
polygonShape.SetAsBox(w / 2 / worldScale, h / 2 / worldScale);
polygonFixture.shape = polygonShape;
polygonFixture.density = .2;
polygonFixture.restitution = 0.9;
polygonFixture.friction = 0.9;
var brickbodyDef: b2BodyDef = new b2BodyDef();
brickbodyDef.type=b2Body.b2_dynamicBody;
brickbodyDef.userData = bric;
brickbodyDef.position.Set(bric.x / worldScale, bric.y / worldScale);
var theBrick: b2Body = world.CreateBody(brickbodyDef);
theBrick.CreateFixture(polygonFixture);
}
}
The same function works perfectly if I have all the code with in the main document class and I do see a brick on the stage. Any clues Am I not referencing it properly?

I figured it out, just had to pass the stage reference from main document class for the sprite to show up.

Related

AS3 Update Variable Reports Null.. in a pattern

I'm making a space game in AS3 - I have an enemy class named EnemyShip.
I've already registered the Event.ENTER_FRAME and it works correctly - the problem is that my variable, rowXY of type Array, reports both null and a non-null value.. in a pattern.
How can I keep this from happening (or is there an easier way to animate the ships to move in Flash Professional?).
The pattern is as follows:
EnemyShip:
package
{
import flash.display.Sprite;
import flash.events.Event;
public class EnemyShip extends Sprite
{
internal var id:int;
internal var rowOrder:int;
internal var rowXY:Array;
private var dirUp:Boolean = false;
public function EnemyShip()
{
// add event listeners
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
addEventListener(Event.ENTER_FRAME, update);
}
private function update(e:Event):void
{
moveUpAndDown();
trace(rowXY);
function moveUpAndDown():void
{
if (dirUp)
y -= C.ENEMY_SPEED;
else
y += C.ENEMY_SPEED;
}
}
private function onAddedToStage(e:Event):void
{
// get row XY
if (rowOrder == 1)
rowXY = C.ENEMY_ROW_1;
if (rowOrder == 2)
rowXY = C.ENEMY_ROW_2;
if (rowOrder == 3)
rowXY = C.ENEMY_ROW_3;
// set XY position
x = rowXY[0];
y = rowXY[1];
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
internal function destroy():void
{
rowOrder = null;
rowXY = null;
// remove event listeners
removeEventListener(Event.ENTER_FRAME, update);
// remove from display list
parent.removeChild(this);
}
}
}
C.as (Constants):
package
{
// C stands for constants
public class C
{
// ship constants
public static const FIRE_DELAY:int = 500; // milliseconds
// laser constants
public static const LASER_SPEED:int = 30;
public static const POINTS_KILL:int = 10;
// mcScore constants
public static const SCORE_LOC_X:Number = 345;
public static const SCORE_LOC_Y:Number = -120;
// enemy ship constants
public static const ENEMY_ROW_1:Array = [485, -45];
public static const ENEMY_ROW_2:Array = [485, 25];
public static const ENEMY_ROW_3:Array = [485, 95];
public static const ENEMY_SPEED:int = 5; // 5 pixels
public static const ENEMY_Y_MIN:int = -10;
public static const ENEMY_Y_MAX:int = 10;
}
}
If you're trying to animate using Flash Professional, I would take advantage of their built in Motion Tween feature. You could also animate the ship in your code by taking advantage of the Tween class.
I reproduced the behavior that you've got using this for loop ( you can get the same result by instantiating 3 objects and insert 3 others directly to the stage ) :
for(var i:int = 1; i < 7; i++){
var enemy:EnemyShip = new EnemyShip();
enemy.rowOrder = i;
addChild(enemy);
}
here we can see very clear that where i is 4, 5 or 6, rowOrder will be null which also will fire some #1009 errors for all the instances which has the rowOrder greater that 3 from this line :
x = rowXY[0];
So to avoid that, you can, for example, restrict the value of rowOrder to be between 1 and 3, like this, for example :
enemy.rowOrder = 1 + int(Math.random()*3);
you can also set that value inside the EnemyShip class itself.
...
Hope that can help.
The Solution
It was to my knowledge that the event Event.ENTER_FRAME was only passed to objects on the stage, but this is not true.
The problem was in my EnemyShip class' constructor method - the ENTER_FRAME event was being listened to by both on- and off-stage instances - the off-stage instances had not been assigned a rowXY (this happens in the event ADDED_TO_STAGE).
Old Code:
New Code:
So what's the lesson to be learned here?
Event.ENTER_FRAME happens no matter if the object is displayed or not.
In the screenshot you posted you have this code:
if(rowOrder > 3)
rowOrder = 0;
But when you check rowOrder in onAddedToStage() you don't have a case for 0 -- only 1, 2, or 3. So rowXY never gets set when rowOrder is 0.
Either change that code to set rowOrder to 1 instead of 0, or change your other code to be zero indexed.

Problems applying Math.round to a text field - AS3

I’m trying to make a simple game that uses a basic equation:
‘linkCount’ / ‘clickCount’ * 100 to create a % success amount, ‘percentCount’
The text fields and the following as3 all live in a Movieclip on root level with instance name ‘counter_int’:
as3:
var clickCount:int = 1; //see below* for what controls this number
var linkCount:int = 1; //see below* for what controls this number
var percentCount:int = (100);
percentCount++;
percent_text.text = (int(linkCount) / int(clickCount) * 100 + "%").toString();
This works fine and displays a % amount in the correct field. However, my question is about truncating the % I get to remove anything after the decimal place. I’ve tried everything I can to get this to work but it’s not having it.
*
Now, here’s the tricky bit that i think is possibly causing my Math.round problem… I basically just don’t know where or how to apply the Math.round instruction?! I also suspect it might be a problem with using ‘int’ and have tried using ‘Number’ but it still displays decimal places.
I am using 2 buttons within 25 different movieclips…
Button locations:
all_int_circles_master.cone.FAILlinkbutton
all_int_circles_master.cone.linkbutton
all_int_circles_master.ctwo.FAILlinkbutton
all_int_circles_master.ctwo.linkbutton
etc … to ctwentyfive
The as3 on FAIL buttons:
FAILlinkbutton.addEventListener(MouseEvent.CLICK, addClick1);
function addClick1(event:MouseEvent):void
{
Object(root).counter_int.clickCount++;
Object(this.parent.parent).counter_int.clicked_total.text = Object(root).counter_int.clickCount.toString();
}
The as3 on successful link buttons:
linkbutton.addEventListener(MouseEvent.CLICK, onClickNextSlide2);
function onClickNextSlide2(event:MouseEvent):void
{
Object(root).counter_int.clickCount++;
Object(this.parent.parent).counter_int.clicked_total.text = Object(root).counter_int.clickCount.toString();
}
The % currently gets returned as e.g.:
74.334753434
but I need it to just be:
74
Any help would be greatly appreciated. I can supply the .fla if necessary. This is kind of what I've been trying but no luck so far:
should the Math.round be applied at root level / globally somehow!?
should the Math.round be applied within the counter_int movieclip?
should the Math.round be applied within all of the all_int_circles_master.cone / two / three... movieclips?
Thanks
Have you tried
percent_text.text = (Math.round(int(linkCount) / int(clickCount) * 100) + "%").toString();
percent_text.text = (int(linkCount) / int(clickCount) * 100 +
"%").toString();
I think you have your clickCount and linkCount backwards, swap those and round the results before adding the percent symbol:
percent_text.text = (Math.round((int(clickCount) / int(linkCount) * 100)).toString() + "%";
A pure AS3 example:
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.MouseEvent;
public class Main extends Sprite {
var clickCount:int = 0;
var linkCount:int = 30;
var clicked_total:TextField;
var button:CustomSimpleButton;
public function Main() {
button = new CustomSimpleButton();
button.addEventListener(MouseEvent.CLICK, onClickNextSlide2);
addChild(button);
clicked_total = new TextField();
clicked_total.text = "0%";
clicked_total.x = 100;
addChild(clicked_total);
}
function onClickNextSlide2(event:MouseEvent):void {
clickCount++;
if (clickCount < linkCount) {
clicked_total.text = (Math.round((clickCount / linkCount) * 100)).toString() + "%";
} else {
clicked_total.text = "Done";
}
}
}
}
import flash.display.Shape;
import flash.display.SimpleButton;
class CustomSimpleButton extends SimpleButton {
private var upColor:uint = 0xFFCC00;
private var overColor:uint = 0xCCFF00;
private var downColor:uint = 0x00CCFF;
private var size:uint = 80;
public function CustomSimpleButton() {
downState = new ButtonDisplayState(downColor, size);
overState = new ButtonDisplayState(overColor, size);
upState = new ButtonDisplayState(upColor, size);
hitTestState = new ButtonDisplayState(upColor, size * 2);
hitTestState.x = -(size / 4);
hitTestState.y = hitTestState.x;
useHandCursor = true;
}
}
class ButtonDisplayState extends Shape {
private var bgColor:uint;
private var size:uint;
public function ButtonDisplayState(bgColor:uint, size:uint) {
this.bgColor = bgColor;
this.size = size;
draw();
}
private function draw():void {
graphics.beginFill(bgColor);
graphics.drawRect(0, 0, size, size);
graphics.endFill();
}
}

Adding object within another

I have my main stage as 550x400. The header area is a stats bar. So I have an element underneath it which I named gameStage which is 550x350.
I am creating circles on a 1 second interval and then trying to randomly place them within my gameStage. It does not appear to be working. It seems like they're being added to a 550x350 element, but it starts at the top of my main stage -- not within my gameStage.
Also if I simply do addChild(circle) it creates an even 25 radius circle. As soon as I do gameStage.addChild(circle), the circle gets skewed slightly.
What am I doing wrong?
private function createCircle():void {
var stageSafeX:Number = Math.random()*gameStage.width;
var stageSafeY:Number = Math.random()*gameStage.height;
var circle:Sprite = new Sprite();
circle.graphics.clear();
circle.graphics.beginFill(Math.random()*0xFFFFFF, 1);
circle.graphics.drawCircle(0, 0, circleRadius);
circle.graphics.endFill();
circle.x = stageSafeX;
circle.y = stageSafeY;
circle.name = String(circleCount);
gameStage.addChild(circle);
}
Okay I'm using Flash Develop, so you'll have to forgive me as this program doesn't have FLA files, only classes and it uses a Main class to start the program (more reminiscent of Java if you've ever programmed in that). But the code I'll show you is more or less the same of how you want to do it.
First I would recommend you make a randomNumber function, I used it in making this code so if you want to use it here's the one I use (I put this in the Main class, you can put this wherever you want):
public static function randomNumber(minValue:Number, maxValue:Number):uint {
return Math.floor(Math.random() * (1 + maxValue - minValue)) + minValue;
}
This is inclusive, meaning if you put randomNumber(1, 10) it will give you a number between 1 to 10, including 1 and 10. It's more or less common sense, but I figured I might as well mention it just to clarify.
Now on to the addCircle function:
public static function addCircle(gameStage:Sprite, circleRadius:uint):void {
//Initializing the new circle instance
var newCircle:Sprite = new Sprite();
//Basically the same code you had (you don't need to set the alpha value to 1, it's default value is 1 regardless)
newCircle.graphics.beginFill(Math.random() * 0xFFFFFF);
newCircle.graphics.drawCircle(0, 0, circleRadius);
newCircle.graphics.endFill();
//Since the circle's origin is the center, you want its outer edges to be bound to the gameStage's edges
var safeStageX:Number = Main.randomNumber(newCircle.width / 2, gameStage.width - newCircle.width / 2);
var safeStageY:Number = Main.randomNumber(newCircle.height / 2, gameStage.height - newCircle.height / 2);
//Adding the circle to the gameStage's display field
gameStage.addChild(newCircle);
//Only set the circle's x and y AFTER you add it to the gameStage's display list, otherwise it might not set properly
newCircle.x = safeStageX;
newCircle.y = safeStageY;
}
Now following up I will give the code I made for the creation of the gameStage. You probably already have something for it, but I'll provide mine just in case you want to use it instead:
//Initializing the gameStage instance
var gameStage:Sprite = new Sprite();
//Adding the gameStage to the Stage's display field
this.stage.addChild(gameStage);
//Setting the gameStage's width and height (using "gameStage.width = 550" and "gameStage.height = 350" WILL NOT WORK)
//Use the color of your main game's background so you don't see this fill (unless you want to)
//Either do this or add a background picture, you need to do one or the other in order to set the gameStage's dimensions
gameStage.graphics.beginFill(0x000000);
gameStage.graphics.drawRect(0, 0, 550, 350);
gameStage.graphics.endFill();
//This puts the gameStage on the bottom of the screen (since it's 50 pixels shorter in the y direction)
gameStage.y = 50;
Lastly I will give you the actual for loop to create your circles (this function is present in the same class/FLA that your gameStage is on, because the addCircle function needs to take in that gameStage instance:
//Now let's populate your gameStage
for (var i:uint = 0; i < [number of circles you want]; i++) {
Main.addCircle(gameStage, [radius of the circle]);
}
And you're done! I'll also include the entire Main class, just so you can see how all the functions work together.
package {
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite {
public function Main() {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
var gameStage:Sprite = new Sprite();
this.stage.addChild(gameStage);
gameStage.graphics.beginFill(0x000000);
gameStage.graphics.drawRect(0, 0, 550, 350);
gameStage.graphics.endFill();
gameStage.y = 50;
for (var i:uint = 0; i < 150; i++) {
Main.addCircle(gameStage, Main.randomNumber(15, 25));
}
}
public static function addCircle(gameStage:Sprite, circleRadius:uint):void {
var newCircle:Sprite = new Sprite();
newCircle.graphics.beginFill(Math.random() * 0xFFFFFF);
newCircle.graphics.drawCircle(0, 0, circleRadius);
newCircle.graphics.endFill();
var safeStageX:Number = Main.randomNumber(newCircle.width / 2, gameStage.width - newCircle.width / 2);
var safeStageY:Number = Main.randomNumber(newCircle.height / 2, gameStage.height - newCircle.height / 2);
gameStage.addChild(newCircle);
newCircle.x = safeStageX;
newCircle.y = safeStageY;
}
public static function randomNumber(minValue:Number, maxValue:Number):uint {
return Math.floor(Math.random() * (1 + maxValue - minValue)) + minValue;
}
}
}

Box2D Walls - same code: the left one works, the right one doesn't

I'm making a simple Box2D game ( http://iwanttobeacircle.com ), where you start off as a triangle and bounce off bigger shapes to gain sides.
I'm having a bizarre bug with my walls... both are created from the same class, yet the left one works and the right doesn't. If I only add the right one, then it works, but for some reason adding them both seems to be causing a problem somewhere.
The WallSegment class is below:
package com.carmstrong.iwanttobeacircle {
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.display.Shape;
import Box2D.Collision.Shapes.*;
import Box2D.Dynamics.*;
import Box2D.Common.Math.b2Vec2;
import com.carmstrong.iwanttobeacircle.Config;
public class WallSegment extends Actor {
private var _shape:Sprite;
private var _shapeBody:b2Body;
private var _colour:uint = 0x666666;
private var prevEdge:int;
private var thisEdge:int;
private var side:Number;
private var name:String;
private var _pathWidth:int;
private var _parent:DisplayObjectContainer;
public function WallSegment(Width:int, Position:String, Parent:DisplayObjectContainer) {
name = "Wall";
_pathWidth = Width;
_parent = Parent;
if(Position == "left") {
side = 1;
prevEdge = (Config.WIDTH - Config.PREV_WIDTH)/2;
thisEdge = (Config.WIDTH-_pathWidth)/2;
} else {
side = -1;
prevEdge = Config.WIDTH-(Config.WIDTH - Config.PREV_WIDTH)/2;
thisEdge = Config.WIDTH-(Config.WIDTH-_pathWidth)/2;
}// check if its left or right wall
//Create the costume
drawShape();
drawBody();
super(_shapeBody, _shape);
}//DynamicWall
private function drawShape():void {
//Draw visual
_shape = new Sprite();
var left:Sprite = new Sprite();
left.graphics.beginFill(_colour, 0.5);
left.graphics.moveTo(prevEdge, Config.HEIGHT/2);
left.graphics.lineTo(prevEdge-Config.WIDTH*side, Config.HEIGHT/2);
left.graphics.lineTo(thisEdge-Config.WIDTH*side, -Config.HEIGHT/2);
left.graphics.lineTo(thisEdge, -Config.HEIGHT/2);
left.graphics.endFill();
_shape.addChild(left);
_parent.addChild(_shape);
}//drawShape
private function drawBody():void {
//Create the shape definition
var shapeDef:b2PolygonDef = new b2PolygonDef();
shapeDef.vertexCount = 4;
b2Vec2(shapeDef.vertices[0]).Set(prevEdge/Config.RATIO, Config.HEIGHT/2/Config.RATIO);
b2Vec2(shapeDef.vertices[1]).Set((prevEdge-Config.WIDTH*side)/Config.RATIO, Config.HEIGHT/2/Config.RATIO);
b2Vec2(shapeDef.vertices[2]).Set((thisEdge-Config.WIDTH*side)/Config.RATIO, -Config.HEIGHT/2/Config.RATIO);
b2Vec2(shapeDef.vertices[3]).Set(thisEdge/Config.RATIO, -Config.HEIGHT/2/Config.RATIO);
shapeDef.density = 0;
shapeDef.friction = 10;
shapeDef.restitution = 0.45;
//Create the body definition (specify location here)
var shapeBodyDef:b2BodyDef = new b2BodyDef();
shapeBodyDef.position.Set(0, -Config.HEIGHT*(Config.CURRENT_SEGMENT+1)/Config.RATIO);
//Create the body
_shapeBody = Config.world.CreateBody(shapeBodyDef);
//Create the shape
_shapeBody.CreateShape(shapeDef);
}//drawBody
}//class
}//package
To keep the level dynamic, the walls are drawn just ahead of the player object each time in the main class, using the following code:
private function addWall(Width:int) {
Config.CURRENT_SEGMENT++;
//addWalls
var leftWall:WallSegment = new WallSegment(Width, "left",camera);
var rightWall:WallSegment = new WallSegment(Width, "right",camera);
Config.PREV_WIDTH = Width;
}//addWall
I'm getting this error:
TypeError: Error #1010: A term is
undefined and has no properties. at
com.carmstrong.iwanttobeacircle::GameContactListener/Add()
at
Box2D.Dynamics.Contacts::b2CircleContact/Evaluate()
at
Box2D.Dynamics.Contacts::b2Contact/Update()
at
Box2D.Dynamics::b2ContactManager/Collide()
at Box2D.Dynamics::b2World/Step() at
com.carmstrong.iwanttobeacircle::IWantToBeACircle/everyFrame()
Which refers to the GameContactListener class, shown below (the add function is at the bottom):
package com.carmstrong.iwanttobeacircle {
import Box2D.Collision.b2ContactPoint;
import Box2D.Dynamics.b2ContactListener;
public class GameContactListener extends b2ContactListener {
public function GameContactListener() {
}//GameContactListener
override public function Add(point:b2ContactPoint):void {
if (point.shape1.GetBody().GetUserData() is ShapeActor && point.shape2.GetBody().GetUserData() is ShapeActor) {
//trace("Two shapes collided: Shape 1 has "+ point.shape1.GetBody().GetUserData().sides + " sides and Shape 2 has " + point.shape2.GetBody().GetUserData().sides + " sides");
if (point.shape1.GetBody().GetUserData().sides > point.shape2.GetBody().GetUserData().sides) {
//remove side from shape 1 and add side to shape 2
point.shape1.GetBody().GetUserData().sides--;
point.shape2.GetBody().GetUserData().sides++;
//point.shape2.GetBody().GetUserData().updateColour;
} else if (point.shape1.GetBody().GetUserData().sides < point.shape2.GetBody().GetUserData().sides) {
//remove side from shape 2 and add side to shape 1
point.shape1.GetBody().GetUserData().sides++;
point.shape2.GetBody().GetUserData().sides--;
//point.shape2.GetBody().GetUserData().updateColour;
}// add side to smaller shape and take away from larger shape
if(point.shape1.GetBody().GetUserData().name == "player" || point.shape2.GetBody().GetUserData().name == "player") {
if(point.shape1.GetBody().GetUserData().name == "player" && point.shape2.GetBody().GetUserData().sides <= point.shape1.GetBody().GetUserData().sides) {
Config.FULFILLMENT++;
Config.SOUNDS[3+Math.ceil(Math.random()*5)][1].play();
trace(Config.FULFILLMENT);
} else if (point.shape2.GetBody().GetUserData().name == "player" && point.shape1.GetBody().GetUserData().sides <= point.shape2.GetBody().GetUserData().sides) {
Config.FULFILLMENT++;
Config.SOUNDS[Math.ceil(Math.random()*5)][1].play();
trace(Config.FULFILLMENT);
} else {
Config.SOUNDS[Math.ceil(Math.random()*3)][1].play();
Config.FULFILLMENT = int(Config.FULFILLMENT - 5);
trace(Config.FULFILLMENT);
}//if other shape is less than or equal to player
}//if one of the shapes is player
}// if both collider objects are shapes
super.Add(point);
}// override Add
}//class
}//package
I would appreciate any thoughts or ideas. Also, this is my first go at Box2D so would appreciate any tips on how to make my code more efficient.
Thanks in advance
You're asking two questions here
Why is the left and right wall collision detection not working?
Why is there an error on the GameContactListener/Add() method?
It looks like they may have the same root problem. I'm seeing you're adding the wall segments as children of the "camera" (had to trace where this add was happening... you pass a reference of "camera" into the constructor of the object.)
i.e. var leftWall:WallSegment = new WallSegment(Width, "left",camera);
Within there, you add the leftWall as a child of that object. But I'm not sure what "camera" is... Is this part of your game world object?
Also, what are your trace statements for point.shape1 and point.shape2?
What 2 objects are colliding?

mapping planes onto primitives

I've looped through the vertices and mapped a plane to each one. I'm having problems orientating the planes correctly. I can get it working with a sphere but when i make any alterations to the the primitive - positions are correct but they don't face/tilt the right way.
EDIT: Note - the alternation to the sphere was done before the sphere was created. I have updated the Sphere class to create an elongated sphere.
The code I'm using to place the planes are as follows:
pivotDO3D = new DisplayObject3D();
scene.addChild(pivotDO3D);
var bigSphere:Sphere = new Sphere(null, 500, 20, 20);
for each (var v:Vertex3D in bigSphere.geometry.vertices)
{
var __seatmaterial:ColorMaterial = new ColorMaterial(0x000000);
__seatmaterial.doubleSided = true;
var p:Plane = new Plane(__seatmaterial, 20, 20, 2, 2);
pivotDO3D.addChild(p);
p.position = v.toNumber3D();
p.lookAt(bigSphere);
}
The following demo shows how to minimize the problem. I changed the multiplication factor of 0.6 to 2.0 as well as the sphere size in order to exaggerate the effect so you can see it easily. Make sure to change 0.6 to 2.0 in your Sphere.as as well.
The key is in varying the z location of the target point with the z location of the point on the sphere.
To compare, run it as-is to see the "fixed" version, and change the lookAt target from pivotDO3D2 to bigSphere to see the old version.
package
{
import flash.display.Sprite;
import flash.events.Event;
import org.papervision3d.cameras.*;
import org.papervision3d.core.geom.renderables.*;
import org.papervision3d.materials.*;
import org.papervision3d.objects.*;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.render.*;
import org.papervision3d.scenes.*;
import org.papervision3d.view.*;
[SWF(width='400', height='400', backgroundColor='0x000000', frameRate='30')]
public class PlaneOrientationDemo extends Sprite
{
private var scene:Scene3D;
private var camera:Camera3D;
private var renderer:BasicRenderEngine;
private var viewport:Viewport3D;
private var pivotDO3D:DisplayObject3D;
public function PlaneOrientationDemo()
{
viewport = new Viewport3D(0, 0, true, true);
addChild( viewport );
renderer = new BasicRenderEngine();
scene = new Scene3D( );
camera = new Camera3D();
camera.z = -700;
camera.zoom = 50;
pivotDO3D = new DisplayObject3D();
scene.addChild(pivotDO3D);
var pivotDO3D2:DisplayObject3D = new DisplayObject3D();
var bigSphere:Sphere = new Sphere(null, 150, 20, 20);
for each (var v:Vertex3D in bigSphere.geometry.vertices)
{
var __seatmaterial:ColorMaterial = new ColorMaterial(0x00FF00);
__seatmaterial.doubleSided = true;
var p:Plane = new Plane(__seatmaterial, 20, 20, 2, 2);
pivotDO3D.addChild(p);
p.position = v.toNumber3D();
// This number should match the fx multiplication factor in Sphere.as.
var xFactor:Number = 2.0;
pivotDO3D2.z = v.z / (Math.PI / xFactor);
p.lookAt(pivotDO3D2);
}
stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event: Event): void
{
pivotDO3D.rotationX += 1;
pivotDO3D.rotationY += 1;
renderer.renderScene(scene, camera, viewport);
}
}
}