Hi i am trying to simply drag an away3d mesh with the mouse but with no luck.
as i see it i need to convert the mouseX and MouseY to the 3d world coordinates
however, this is what i tried and it doesnt work. also i need it to be draged in enter frame or TIMER.
HELP PLEASE :)
PlayerHandle = new Mesh(new CubeGeometry(200, 100, 5));
_view.scene.addChild(PlayerHandle);
PlayerHandle.mouseEnabled = true;
PlayerHandle.addEventListener(MouseEvent3D.MOUSE_MOVE, HandlePlayerHandler);
public function HandlePlayerHandler(me3d:MouseEvent3D):void
{
PlayerHandle.x = me3d.scenePosition.x;
}
public function UpdateScene(e:Event):void
{
_view.render();
}
Away3D has built in class,
import away3d.tools.utils.Drag3D;
e.g.
private var _drag3D:Drag3D;
private var _sphere : Sphere;
//create sphere geometry here in a function
.
.
.
_drag3D = new Drag3D(_view, ObjectContainer3D(_sphere));
private function handleEnterFrame(e:Event) : void
{
_drag3D.updateDrag();
_view.render();
}
See this, Drag3DTest Class.
Related
Let's say I have a 2D level that is build out of 2D blocks. Some of them are boxes.
The boxes look just the same. No difference! How can I "copy" or clone the graphics of one box to another ? The only difference the boxes will have is that sprite.x and sprite.y have different values. I would probably go that way:
public static function drawBox(graphics:Graphics):void
{
graphics.clear();
// draw box
}
drawBox(box1.graphics);
drawBox(box2.graphics);
drawBox(box3.graphics);
No textures will be used, only vector drawing!
Is this a good practice ? Is there another way to achieve the same ?
Update: Sometimes I draw sprites randomly (very hard to redraw them if I need many instances of one sprite and all its attributes).
You can use the function copyFrom.
Something like this:
var s:Sprite = new Sprite();
s.graphics.beginFill(0);
s.graphics.drawRect(0, 0, 100, 100);
s.graphics.endFill();
addChild(s);
var s2:Sprite = new Sprite();
// Copyfrom accepts a `Graphics` object.
s2.graphics.copyFrom(s.graphics);
s2.x = 100;
s2.y = 100;
addChild(s2);
Have a look at the documentation about copyFrom().
If you treat it like an object in your game you should probably rather consider the OOP-approach #Pier suggested.
This comes in a lot of flavors:
You could extend a class from Sprite and draw the box as soon as the box is ADDED_TO_STAGE by its parent.
public class box extends Sprite
{
protected var _color:uint;
protected var _size:int;
public function box(size:int=100, color:uint=0x000000)
{
super();
_size = size;
_color = color;
this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
protected function onAddedToStage(event:Event):void
{
this.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
draw();
}
protected function draw():void
{
this.graphics.beginFill(_color);
this.graphics.drawRect(0,0,_size,_size);
this.graphics.endFill();
}
}
This box can be constructed/created by calling:
var b:box = new box();
this.addChild(b);
Or you could let the box contain itself - which could be more feasible if you deal with a lot of Objects. The box would just need a reference to its parent then - and of course it should provide a dispose()-function
public class box
{
private var _parent:Sprite;
protected var s:Sprite;
public function box(parent:Sprite)
{
_parent = parent;
s = new Sprite();
s.graphics.beginFill(0x00000);
s.graphics.drawRect(0,0,100,100);
s.graphics.endFill();
_parent.addChild(s);
}
public function dispose():void
{
_parent.removeChild(s);
}
}
}
In this case you would construct the box as follows - it requires a reference to a Sprite (or any extension of) that has already been added to the stage:
var b:box = new box(this);
In both cases you could dynamically change attributes and make the object more versatile:
public function set size(val:int):void
{
_size = val;
draw();
}
public function set color(val:uint):void
{
_color = val;
draw();
}
I'm using FlashDevelop, actionscript 3 and fxg graphics build with Illustrator (exported as fxg 2.0).
I import a fxg rectangle build with Illustrator, then I set it draggable when you clik on it, so its coordinates change. This works if the rectangle scale is 1 (this means: no scale).
But, if I change its scale (ex. fxgRect.scaleX = fxgRect.scaleY = 0.5; ) you can drag it but its coordinates doesn't change!! And this make me crazy because the sprite changes position but if you ask its coordinates they aren't changed!!
And I set the fxgRect.mouseChildren = false; so I'm sure to move the sprite fxgRect and not something inside it.
(This is just an example, my aim is to build complex graphics with illustrator and use it in FlashDevelop).
Thank you in advance for help me.
This is the code done to test this problem. To use this example you have to create a fxg rectangle (fxgrectangle.fxg) and put it in the same folder of the SimpleDragFxg.as class.
import flash.display.*;
import flash.events.*;
import fxgrectangle;
public class SimpleDragFxg extends Sprite
{
public var fxgRect:Sprite = new fxgrectangle(); // make an istance of fxgRect
public function SimpleDragFxg()
{
//----------------------------------------------------------
addChild(fxgRect);
fxgRect.name = "FXGrect";
fxgRect.x = fxgRect.y = 50;
fxgRect.mouseChildren = false;
fxgRect.scaleX = fxgRect.scaleY = 0.5; //<<< this makes the problem
trace ("I'm ", this.name, "and I contain ", this.fxgRect.name, "which contains ", fxgRect.getChildAt(0).name);
fxgRect.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
//--------------------------------------------------------------
}
private function onMouseDown (e:MouseEvent):void
{
trace ("e.target: ", e.target.name);
if (DisplayObject(e.target).name == "FXGrect")
{
trace ("FXGrect position BEFORE drag: ", fxgRect.x, fxgRect.y);
Sprite(e.target).startDrag();
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
}
private function onMouseUp (e:MouseEvent):void
{
fxgRect.stopDrag();
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
if (DisplayObject(e.target).name == "FXGrect")
{
trace ("FXGrect position AFTER drag: ", fxgRect.x, fxgRect.y);
}
}
}
Try
public var fxgRect:Sprite = new Sprite();
fxgRect.addChild(new fxgrectangle());
I need to add a MovieClip to stage, the limitation being that it should only be added to an empty area on the stage. The stage itself either contains complex shapes or is manipulable by the user i.e. he can drag/move objects to change the empty area. The hitTest and hitTestObject methods need DisplayObject already available on the stage. What is the right way to go - the only solution I can imagine is having added my object on the stage and then repeatedly doing hit tests?
[Imagine it to something like adding sprites in a video game - they must spawn in empty regions; if they pop out from inside of each other, then it'll look really odd.]
Well, when you create a new class, just turn it off with a variable and set the visibility to false, then loop until there is no hitTest.
A silly example:
public class someClass extends Sprite
{
private var objectsOnStage:Array;
public function someClass(objectsArray:Array) {
objectsOnStage = objectsArray;
visible = false;
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event){
removeEventListener(Event.ADDED_TO_STAGE, init);
addEventListener(Event.ENTER_FRAME, SEARCH);
}
private function SEARCH(e:Event) {
var doesHit:Boolean = false;
x = Math.round(Math.random() * (550 - 0)) + 0;
y = Math.round(Math.random() * (400 - 0)) + 0;
for (var i:int = 0; i < objectsOnStage; i++) {
if (doesHit) break;
if (this.hitTestObject(objectsOnStage[i])) {
doesHit = true;
}
}
if (doesHit) return;
placedInit();
}
private function placedInit() {
visible = true;
removeEventListener(Event.ENTER_FRAME, SEARCH);
//now init the stuff you want.
}
}
You just check if bounding boxes of both clips overlaps. Like this:
import flash.geom.Rectangle;
import flash.display.MovieClip;
// create simple movie clips that has a rectangle shape inside
var sym1 : MovieClip = new Sym1();
var sym2 : MovieClip = new Sym2();
// get a rectanle of both clipt
var boundingBox1 : Rectangle = sym1.getBounds(this);
var boundingBox2 : Rectangle = sym2.getBounds(this);
// check if bounding boxes of both movie clips overlaps
// so it works like hitTestObject() method
trace( boundingBox1.intersects( boundingBox2) )
I know this post is super old, but in case it helps anybody --
If you need to do a hit test on a movieclip that isn't on the stage. A workaround is to rasterize it to a bitmap first.
var bitmapData:BitmapData = new BitmapData(mc.width, mc.height, true, 0x0000000);
bitmapData.draw(mc);
if (bitmapData.getPixel32(x, y) > 0) {
// Hit true.
}
I got an error saying "Attempted access of inaccessible method rotation through a reference with static type flash.display:Sprite.ssd.rotation(90)}"
I just want to know how to rotate my image by 90degrees when I double click on it.
var shootingstar:Loader = new Loader();
shootingstar.load(new URLRequest("http://i51.tinypic.com/m8jp7m.png"));
shootingstar.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadingComplete);
var ssd:Sprite = new Sprite();
function onLoadingComplete(event:Event):void
{
ssd.addChild( event.currentTarget.loader.content );
ssd.addEventListener(MouseEvent.MOUSE_DOWN, drag);
ssd.addEventListener(MouseEvent.MOUSE_UP, drop);
ssd.addEventListener(MouseEvent.DOUBLE_CLICK, rotate)
ssd.height=180
ssd.width=124
}
function drag(event:MouseEvent):void{
ssd.startDrag()
}
function drop(event:MouseEvent):void{
ssd.stopDrag()
}
function rotate():void{
ssd.rotation(90)
}
The error suggests that the rotation method is not accessible , i.e , private or protected. Therefore you're not able to call it directly as in your code rotation(90).
Instead you should be using the rotation public property
rotation = 90;
As superfro points out, you should also get an error from the rotate method which requires a MouseEvent parameter. So practically..
function rotate(event:MouseEvent):void
{
ssd.rotation = 90;
}
Finally, makes sure that the doubleClickEnabled property of the Sprite is set to true
function onLoadingComplete(event:Event):void
{
ssd.doubleClickEnabled = true;
etc....
Have you tried ssd.rotation = 90; ?
I am wondering if it is possible to get the data that is stored in a shape/graphics object in flash using actionscript 3?
In my project I would like to be able to draw a shape and then read all the points in that shape into my script. The reason for that is that I need go generate lines from those points that I later can use to check if my characters velocity intersects with any of them.
You can read all parts of Shape.
New feature added to Flash Player 11.6 and AIR 3.6:
flash.display.Grapics.readGraphicsData()
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Graphics.html#readGraphicsData%28%29
Example:
var s :Shape = new Shape();
s.graphics.lineStyle(2, 0xFF0000);
s.graphics.drawCircle(0, 0, 50)
var gd:Vector.<IGraphicsData> = s.graphics.readGraphicsData(false);
var copy_of_s :Shape = new Shape();
copy_of_s.graphics.drawGraphicsData(gd);
addChild(copy_of_s);
To use the new version, you have to update playerglobal.swc
http://www.adobe.com/support/flashplayer/downloads.html
You cannot read the shape info once it's drawn. But if you are drawing it, you can store the info at the time of drawing itself and use it later.
OK, looks like its not possible then, to bad.
I am doing a 2d topdown racing game, and I wanted to generate lines along the walls of the track and check the players velocity against thouse lines. That way I would be able to implement some basic collision response by reflection the players velocity around the normal of the line that it collides with and make it bounce off walls. Does anyone have any good ideas about how to get the same type of collision behavior without the actual lines?
Is it possible to overload the graphics object in flash somehow so that when I draw something it is recorded? Or does the flash IDE not use the Graphics drawing api?
Regards
You can not instantiate or subclass Graphics class. But you can use you own custom graphics class.public class CustomGraphics extends Object{
private static const CLEAR = -1;
private static const MOVETO = 0;
private static const LINETO = 1;
...
...
private var _graphics:Graphics;
private var _actions:Array;
public function CustomGraphics(g:Graphics):void {
_graphics = g;
_actions = new Array();
}
private function recordAction(obj:Object):void {
if (obj.action == -1) {
_actions = null;
_actions = new Array();
return;
}
_actions.push(obj);
}
public function moveTo(x:number, y:Number):void {
g.moveTo(x, y);
recordAction({action:MOVETO, X:x, Y:y});
}
...
...
public function get actions():Array {
return _actions;
}
} Now whenever you want to draw something then you can use CustomGraphics. var cg:CustomGraphics = new CustomGraphics(someDisplacyObject.graphics);
cg.moveTo(0, 0);
cg.drawRect(0, 0, 10,, 200);
...
a:Array = cg.actions;