How to position an rotated MovieClip? - actionscript-3

It's very easy to position a sprite object in relation to another sprite object, if you don't mess with the rotation. As the title states I want to know how to position 2 MC in relation to an already rotated MC, so they are aligned to each other. The big rocket is at an angle of 35 degrees. First i set the angle of the big rocket to 0 degree, I am adding the 2 small rockets on the stage and position them on each side of the bigger rocket. So far so good... I am rotating everything back to the initial angle (35 degrees), but something is not right, as you can see the results in pic1 What must I change, so that the 2 small rockets stays perfectly aligned (one on the left side, the other on the right side of the bigger rocket) and rotated, as in pic2? The registration point for all objects is in the upper-left corner. Edit: The 2 small rockets must reside outside the bigger rocket container, because, eventually they will be animated independently from the container.
pic1
pic2
var _rot = rocketShip.rotation;
rocketShip.rotation = 0;
addChild(_leftRocket);
addChild(_rightRocket);
_leftRocket.x = rocketShip.x - _leftRocket.width;
_leftRocket.y = rocketShip.y + 20;
_rightRocket.y = rocketShip.x + _rightRocket.width;
_rightRocket.y = rocketShip.y + 20;
rocketShip.rotation = _rot;
_leftRocket.rotation = _rightRocket.rotation = rocketShip.rotation;

Try to move _leftRocket and _rightRocket to the right position after rotation.
Here is the code move _leftRocket
//the old left bottom point of rocketShip
var point1:Point= new Point(0, rocketShip.height);
//the old right-bottom poiny of leftship
var point2:Point = new point(_leftRocket.width, _leftRocket.height);
//the old right bottom point of rocketShip
var point5:Point= new Point(rocketShip.width, rocketShip.height);
//the old left-bottom point of rightship's
var point6:Point = new point(0, _leftRocket.height);
//.. Your code
//get the new position of rocketship's left bottom point after rotation,leftShip's right bottom corner will be in this point
var point3:Point = rocketShip.transform.matrix.transformPoint(point1);
//get the new point of leftship's right-bottom-corner after rotation.
var point4:Point = _leftRocket.transform.matrix.transformPoint(point2);
//move the leftShip
_leftRocket.x -= point4.x - point3.x;
_leftRocket.y -= point4.y - point3.y;
Here to for right ship
//get the new position of right bottom point of rocketShip after rotation,rightShip's left bottom corner will be in this point
var point7:Point = rocketShip.transform.matrix.transformPoint(point5);
//get the new point of rightship's left-bottom-corner after rotation.
var point8:Point = _rightRocket.transform.matrix.transformPoint(point6);
//move the rightShip
_rightRocket.x -= point8.x - point7.x;
_rightRocket.y -= point8.y - point7.y;
And I think you should Change
_rightRocket.y = rocketShip.x + _rightRocket.width;
To
_rightRocket.x = rocketShip.x + rocketShip.width;

Related

Sprites that are partially off screen

I have a sprite 300x200px and when it is partially off the screen, it starts appearing on the left side (like a cycled sides). Hidden area becomes visible on the left side.
How to avoid that?
var ss = queue.getResult(spriteName);
ss.images = [queue.getResult(spriteName + "_png")];
var ssheet = new createjs.SpriteSheet(ss);
var sprite = new createjs.Sprite(ssheet);
sprite.gotoAndPlay("ssh");
sprite.x = 550;
stage.addChild(sprite);
Update (to be more clear):
Stage is 640x480 in size; Sprite is on the right side of the stage and 30% of the sprite is hidden because its off screen. For some reason this 30% of hidden sprite are being shown and played on the left side of the stage. It looks like a cycled tube. Hidden part are immediately shown on the other side of the stage.

AS3 image rotate within / scale to fit sprite

We're making bitmap data from a sprite where we want to take an image and rotate within / scale to fit. This is our code, which includes a rotation.
_rotation defines how much the user has input.
The problem is, we're getting an output file that is 100% white.
We think that the image is rotating about 0x0y therefore rotating the image outside the bounds of the sprite.
Furthermore, the image is not scaling to the child, instead is sort of "cropping" as it inherits.
What is the best way of doing this? Basically we want to take an image and rotate within / scale to fit
var sprite1:Sprite = new Sprite();
addChild(sprite1);
var photoBitmap:Bitmap = new Bitmap(_bitmapData);
sprite1.addChild(photoBitmap);
sprite1.rotation = _rotation;
var sprite2:Sprite = new Sprite();
addChild(sprite2);
sprite2.addChild(sprite1);
var bitmapData:BitmapData = new BitmapData(sprite2.width,sprite2.height,false,0xFFFFFF);
bitmapData.draw(sprite2);
The simple way to draw sprite with scaling/rotating is using Matrix in method bitmapData.draw().
Example:
var sourceImage:SomeSprite = new SomeSprite();
var matrix:Matrix = new Matrix();
matrix.scale(0.5, 0.5);
matrix.rotate(0.5 * Math.PI);
var newImage:BitmapData = new BitmapData(sourceImage.width/2, sourceImage.height/2);
newImage.draw(sourceImage, matrix);
Your issue is likely a cause of rotating around the top left corner (which can make the entire object left of or above the registration point (0 x and 0 y) and not get drawn.
An easy way you can account for this, is to move sprite1 after the rotation to account for the new size and position caused by rotating:
...
sprite2.addChild(sprite1);
var actualPosition:Rectangle = sprite2.getBounds(sprite2); //this gets the new position/dimensions of the object
sprite1.x = -actualPosition.x;
sprite1.y = -actualPosition.y;
var bitmapData:BitmapData = new BitmapData(sprite2.width,sprite2.height,false,0xFFFFFF);
...

AS3 - Shooting arrows / targeting

I am creating a game where fairies cross the screen (bottom to top). There is a laser at the bottom of the screen that goes from right to left. I want to shoot the laser, and have the laser bullets to go from bottom to top. The code that I have has it going from top to bottom. I have tried to reverse the direction by changing out the + = 10 to - = 10... This did get the bullets in the right direction, however, it started it towards the top of my screen.
stage.addEventListener(MouseEvent.MOUSE_DOWN, targeting)
function targeting(e:MouseEvent):void{
var newArrow:blackArrow = new blackArrow();
addChild(newArrow);
newArrow.y = 50;
newArrow.x = shooterMC.x;
newArrow.addEventListener(Event.ENTER_FRAME, shoot);
}
function shoot(e:Event):void {
var arrowMC:MovieClip = MovieClip(e.target);
arrowMC.y += 10;
}
Thank you in advance for any help that you can give me.
You have to change this line to your desired position you want to start the laser animation from:
newArrow.y = 50;
The coordinate system starts in the upper left corner. So the lower right corner is window width | window height.

Loop an image in Flash

I want to have a scene where an image which is 5000 pixels high is moving up 5 pixels each frame-refresh. When the image is all up, I'd like to see the top of the image connected to the bottom of the image. This should be done untill the level is 'done'. How can I 'loop' such an Image?
You can create a copy of that image which you keep hidden/above and the trick is to update the position and loop accordingly so when one image goes bellow the screen it goes back on top and repeats.
Here's a basic snippet to illustrate the idea using the DisplayObject class and the scrollRect property:
//ignore this, you have your content already
var dummyContent:BitmapData = new BitmapData(100,100,false);
dummyContent.perlinNoise(10,10,8,12,true,true);
//important stuff starts here
var container:Sprite = addChild(new Sprite()) as Sprite;//make a container
container.scrollRect = new Rectangle(0,0,dummyContent.width,dummyContent.height);//set a scrollRect/'mask'
var part1:DisplayObject = container.addChild(new Bitmap(dummyContent));//add two copies
var part2:DisplayObject = container.addChild(new Bitmap(dummyContent));//of the same content
part2.y -= part2.height;//set the 2nd at the top of the 1st
addEventListener(Event.ENTER_FRAME,update);
function update(e:Event):void{
//move both
part1.y += 5;
part2.y += 5;
//check if any reach the bottom so they can be moved back up
if(part1.y >= part1.height) part1.y = -part1.height;
if(part2.y >= part2.height) part2.y = -part2.height;
//the above can also be nicely placed in a loop if you plan on using more seamless looping clips/images
}
Obviously you will have different content, but the principle is the same.
If you're working with images, you can simply use BitmapData's copyPixels method:
var s:int = 5;//scroll speed
//make some content
var w:int = 100;
var h:int = 100;
var dummyContent:BitmapData = new BitmapData(w,h,false);
dummyContent.perlinNoise(10,10,8,12,true,true);
//prepare for stiching
var renderPos:Point = new Point();//position to render the current image to
var prenderPos:Point = new Point();//position to render the previous image (the 'hidden' copy above)
var render:BitmapData = new BitmapData(w,h,false);//create a bitmap data instance to render updated pixels int
addChild(new Bitmap(render));//and add it to the stage
addEventListener(Event.ENTER_FRAME,update);
function update(e:Event):void{
renderPos.y = (renderPos.y+s)%h;//update the scroll position for the 1st part, % is used to loop back to 0 when the position gets to the content height
prenderPos.y = renderPos.y - h;//update the scroll position for the 2nd part (above)
render.lock();//freeze pixel updates
render.copyPixels(dummyContent,dummyContent.rect,renderPos);//copy pixels from the scroll position to the bottom
render.copyPixels(dummyContent,dummyContent.rect,prenderPos);//copy pixels from the top to the scroll position
render.unlock();//unfreeze/update ALL THE PIXELS
}
You can try to use a Rectangle object which changes height (height-scrollPosition) so you potentially access less pixels each time or you can manually work out single for loops using BitmapData's getVector method, but that's something to look into if performance is actually an issue for such a simple task and it's worth checking what's faster ( copy full bitmap rect vs copy partial bitmap rect vs manually copy values using vector )
Be warned, Flash cannot load an image greater than 16,769,025 pixels (or 4095x4095). The height of 5000 pixels will work as long as the width is not greater than 3353.
That said, I'd loop the image by keeping two copies of the image onstage, move both at the same time with a parent object, and reset to origin once your loop point is met.
Consider the following stage setup:
Stage ¬
0: MainTimeline:MovieClip ¬
0: Container:MovieClip ¬
0: img1:Bitmap
1: img2:Bitmap
Now moving container up, you'd just need to check that the looping second image reaches the origin point of the first image.
function onEnterFrame(e:Event):void {
Container.y = Container.y - 5;
if (Container.y < -5000) {
Container.y = -5;
}
}

as3 finding the offset of a block

I am trying to make a pong like game but i need to find the offset from the center of the paddle so that i can make it bounce differently depending on where it hits the paddle. How can i achieve this?
Try:
// get the center of the paddle
var centerXpaddle = paddle.x - paddle.width/2;
var centerYpaddle = paddle.y -paddle.height/2;
if (objectThatHits.hitTestObject(paddle)) {
// get the current point of object
var offsetX = objectThatHits.x - centerXpaddle;
var offsetY = objectThatHits.y - centerYpaddle;
}
The first two lines get the center of the the paddle (it's current position minus half the width and half the height) and the second part is a "test" for when the "object that hits" hits the "paddle".