Rotating a camera feed in Actionscript 3 - actionscript-3

I am trying to rotate a live camera feed 90 degrees so it's the correct orientation. Here is what I have so far but it just won't do anything with the rotation.
public function setupCamera(param1:int, param2:int) : void
{
camera = Camera.getCamera("1");
camera.addEventListener(StatusEvent.STATUS,camStatusHandler);
camera.setMode(param1,param2,stage.frameRate);
video = new Video(param1,param2);
video.scaleX = -1;
video.rotation = 90;
video.x = video_placement.x + video_placement.width;
video.y = video_placement.y;
video.attachCamera(camera);
addChildAt(video,0);
}

Most likely, the rotation is working. The problem is when you rotate 90 degrees the registration/anchor point is now effectively the top-right corner (so if it's at position 0,0 the video will appear off-screen making it look like it's not working).
You can compensate by adding the width of the video to it's position:
video.x = video.width + video_placement.x;
In the same manner, setting the scale to -1 inverts the registration point, and since you've rotated the object you need to compensate for it on the y plane by adding the height of the video to it's position:
video.y = video.height + video_placement.y;

Related

Libgdx / Physics Editor Rotation of body

and a nice evening.
I've the following problem:
A Box2d dynamic body with one fixture all vertices placed with positiv x / y from the origin of the body.
http://i.stack.imgur.com/MXQRr.png
But the rotation is on body origin 0/0 not on mass center..
So I tried these approaches:
1:
Set origin of Body in the Middle of the body(vertices positive and negativ)
Problem: rotation works, Sprite positioning is nearly impossible
2:
Set mass data center =
originOfBody.x + width / 2, originOfBody.y + height / 2
Problem: It's like I'm doing nothing, still rotation around origin of body at 0, 0
In the following Code snippet you can see my instantiation.
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(new Vector2(200, 2));
body = world.createBody(bodyDef);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.density = 0.6f;
fixtureDef.friction = 0.4f;
fixtureDef.restitution = 0.2f;
bodyLoader.attachFixture(body, "Rocket1n2", fixtureDef, WIDTH);
originOfBody = bodyLoader.getOrigin("Rocket1n2", WIDTH);
MassData data = body.getMassData();
data.center.set(Box2DUtils.getWidth(body) / 2, 0);
data.I = body.getMassData().I; //without this line programm fails with assertion
body.setMassData(data);
Vector2 cpy = data.center.cpy();
I rotate the player with following code:
body.setAngularVelocity(addition); //addition is predefined(atm 1 / -1)
I currently use Body Physics Editor from aurelia(?) with some hacks it worked, I dont have any Problems with other objects, because I dont rotate them. Placement works like a charm..
I wish I do a significant error.. Normally box2d must calculate the rotationcenter (Mass Center) automatically?
I cant help myself this time.. :(
I'd recommend getting your first approach to work.
Set origin of Body in the Middle of the body(vertices positive and
negativ) Problem: rotation works, Sprite positioning is nearly
impossible
The rotation works fine, but the sprite positioning is difficult. I had this same problem when I was making a physics game last year. What helped me was seeing exactly how the positioning worked.
Box2D bodies are center-focused. That means that calling the position of the body will give you the object's middle. Sprites are corner focused, meaning a sprite's position is it's bottom-left corner. Thus, you can't just set each of them as the same thing. I recommend shifting the sprite from the body's position down and to the left by half the body's height and width, respectively.

How to rotate all objects of canvas at once using Fabric.js?

I am working on custom product designer which uses Fabric.js. I want to rotate all objects of canvas at once by pressing one button (rotate left, rotate right).
I have achieved this using this code :
stage.forEachObject(function(obj){
obj.setAngle(rotation).setCoords();
});
stage.renderAll();
But it has one bug that every element rotates with its own center point. I want that every element rotates with respect to whole canvas element.
Grouping and rotating the group did not work so well for me. Here is another solution based on this js fiddle.
rotateAllObjects (degrees) {
let canvasCenter = new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2) // center of canvas
let radians = fabric.util.degreesToRadians(degrees)
canvas.getObjects().forEach((obj) => {
let objectOrigin = new fabric.Point(obj.left, obj.top)
let new_loc = fabric.util.rotatePoint(objectOrigin, canvasCenter, radians)
obj.top = new_loc.y
obj.left = new_loc.x
obj.angle += degrees //rotate each object buy the same angle
obj.setCoords()
});
canvas.renderAll()
},
You could add all the objects to a group an then rotate the group. This way you can also set the center for rotation.
This is how it could be solved
function rotate(a) {
var group = new fabric.Group(canvas.getObjects());
//angle is var with scope out of this function,
//so you can use this function as rotate(90) and keep rotating
angle = (angle + a) % 360;
group.rotate(angle);
canvas.centerObject(group);
group.setCoords();
canvas.renderAll();
}
FabricJS rotate everything and maintain the relative position also.
You can download the files here - https://drive.google.com/file/d/1UV1nBdfBk6bg9SztyVoWyLJ4eEZJgZRf/view?usp=sharing

How do I make smoother rotation for my objects in my game?

I am making a game where insects from the top of the screen come down. The object of the game is to kill these insects. I have made a code for these insects on how they move, but what seems to be the problem is that they seem to rotate in a non smooth pattern. They twitch!
This is the code:
else // Enemy is still alive and moving across the screen
{
//rotate the enemy between 10-5 degrees
tempEnemy.rotation += (Math.round(Math.random()*10-5));
//Find the rotation and move the x position that direction
tempEnemy.x -= (Math.sin((Math.PI/180)*tempEnemy.rotation))*tempEnemy.speed;
tempEnemy.y += (Math.cos((Math.PI/180)*tempEnemy.rotation))*tempEnemy.speed;
if (tempEnemy.x < 0)
{
tempEnemy.x = 0;
}
if (tempEnemy.x > stage.stageWidth)
{
tempEnemy.x = stage.stageWidth;
}
if (tempEnemy.y > stage.stageHeight)
{
removeEnemy(i);
lives--;
roachLevel.lives_txt.text = String(lives);
}
}
}
}
Another problem that I am experiencing is that some of the insects are going along the edge of the screen. The user can barely kill them because half of their bodies are on the screen, and the other half are off. Can I make them move a bit away from the edge, like an offset? Thank you!
From your code, it looks like they are twitching because you're changing the rotation by a large amount right away:
tempEnemy.rotation += (Math.round(Math.random()*10-5));
Instead you should interpolate/animate to your desired rotation instead of just jumping right to it. There are a few ways to do this, but not sure how your animation is set up.
To keep insects from going right to the screen edges you could put in an offset and limit the x/y positions.
Such as going:
var offset:int = 100; // limits the max x to be 100 pixels from the right edge of the stage
if (tempEnemy.x > (stage.stageWidth - offset)){
tempEnemy.x = stage.stageWidth - offset;
}

Scaling tile grid

I'm working on my own tile bliting engine, this one is using hexagonal tiles - but I think it doesn't differ much from regular tiles.
I have huge x,y array of tiles and they have their x,y coordinates for rendering on canvas, I iterate only the ones that should be visible on canvas in current camera position.
So I'm stuck with scaling and cant resolve this on my own.
Here is my code for drawing tiles on canvas:
public function draw():Void{
clearCanvas(); //Clear canvas (bitmapData)
var _m:Matrix;
iterateTiles(function(_tile:HexTile):Void{ // loop every tile that is visible on screen
_m = new Matrix();
_m.translate(_tile.x + cameraPoint.x,_tile.y + cameraPoint.y);//Get pre calculated tile x,y and add camera x,y
_m.scale(matrixScale, matrixScale);
drawToCanvas(_tile,_m);//Send to draw tile on canvas using Matrix
},true);
}
This works nice and fast but only problem is it scales tiles from left top corner (like regular scale would work)
Before scale
After scale
My question is how to transform tiles to always scale from center. So if tile 10:10 is in center of screen before scaling, then it should
stay there after scaling.
Sorry, I misunderstood the question, but I think I've got it now:
// Scale the distance from the original point to the center of the canvas
var xDistance:Number = ((_tile.x + cameraPoint.x) - xCenter) * matrixScale;
var yDistance:Number = ((_tile.y + cameraPoint.y) - yCenter) * matrixScale;
// Add the distances to the center of the canvas. This is where you want the tile
// to appear.
var x:Number = xCenter + xDistance;
var y:Number = yCenter + yDistance;
// Because the coordinate is going to be scaled, you need to increase it first.
x = (1 / matrixScale) * x;
y = (1 / matrixScale) * y;
_m.translate(x, y);
I have not tested this, I've just drawn it out on graph paper. Let me know if it works.

How to get visual corner (eg. topLeft) of rotated displayObject in actionscript 3?

When rotating a display object (around its center) the visual corner of the element moves (the actual x and y of the "box" remains the same). For example with 45 degrees of rotation the x coordinate will have increased and the y coordinate will have decreased as the top left corner is now at the top center of the "box".
I've tried to use displayObject.getBounds(coordinateSpace).topLeft however this method is simply returning the x and y of the box and thus doesn't change after an object has been rotated.
So, how do you get the x and y of a visual corner of a rotated display object?
Update: this is what I mean with the position of a visual corner after rotation -->
alt text http://feedpostal.com/cornerExample.gif
You simply need to translate the point to its parent's coordinate space.
var box:Shape = new Shape();
box.graphics.beginFill(0xff0099);
box.graphics.drawRect(-50, -50, 100, 100); // ... the center of the rectangle being at the middle of the Shape
addChild(box);
box.x = 100; // note: should be 100 + box.width * .5 in case you want to use the topleft corner to position
box.y = 100;
box.rotation = 45;
// traces the result (Point)
trace( box.parent.globalToLocal(box.localToGlobal(box.getBounds(box).topLeft)) );