I am trying to rotate video display depend on angle.
I got total 4 angle 0,-90,90,180.
And i make rotation as per following:
if(videoAngle == 180)
{
videoDisplay.rotation = 180;
}
else if(videoAngle == 90)
{
videoDisplay.rotation = -90;
}
else if(videoAngle == -90)
{
videoDisplay.rotation = 90;
}
It rotate the videoDisplay but it's x and y position is changed and also height and width.
I tried many things but didn't succeed.
Is there any solution for that?
Video object have rotation point fixed in top left, so you need to put this video in a container (MC or Sprite) with 'x' and 'y' in the center of video.
You can do it in fla but also in code:
function putInCenter(display:DisplayObject):Sprite {
var box:Sprite = new Sprite()
display.parent.addChild(box)
box.x = display.x + display.width / 2
box.y = display.y + display.height / 2
box.addChild(display)
display.x = -display.width / 2
display.y = -display.height / 2
return box
}
var videoBox:Sprite = putInCenter(videoDisplay)
Now you rotate this container instead of "videoDisplay"
if(videoAngle == 180)
{
videoBox.rotation = 180
}
else if(videoAngle == 90)
{
videoBox.rotation = -90;
}
else if(videoAngle == -90)
{
videoBox.rotation = 90;
}
Related
What I want to do is to keep my MovieClip (which is bigger than the viewport) from having its borders visible. Just like many apps do, e.g. Clash of Clans.
This way if you zoom in and zoom out or pan you will never see the stage under it.
If I was only to pan and not zoom it would be easy because I just had to calculate if my MC rectangle is within my stage and if yes i would just:
mc.x = 0 + mc.width / 2;
//or
mc.x = stage.StageWidth - (mc.width/2);
//or .... The same for y
Now the big problem is when I also zoom! And every time I come up with some code it doesn't work well. There are many examples for zooming via GestureEvent on the web but none of them keeps the MC constrained so you don't see the stage under it.
Can someone please provide an example for me. Lets say the stage is 480x720 and the mc is 1080x720!
You gotta pan and zoom while always covering the stage and the scale of mc will remain within 1-1.5.
Here is my current code:
Multitouch.inputMode = MultitouchInputMode.GESTURE;
stage.addEventListener(TransformGestureEvent.GESTURE_PAN, onPan);
stage.addEventListener(MouseEvent.CLICK, gotoBox);
var isInBox: Boolean = false;
table.x = 203.1;
table.y = 360;
table.scaleX = 1;
table.scaleY = 1;
var mouseTimer: Timer;
function onPan(event: TransformGestureEvent): void
{
if (!isInBox)
{
if (event.phase == GesturePhase.BEGIN)
{
stage.removeEventListener(MouseEvent.CLICK, gotoBox);
trace("noClick");
}
table.x += event.offsetX;
table.y += event.offsetY;
if (table.x > (table.width / 2))
{
table.x = table.width / 2;
}
if (table.x < stage.stageWidth - (table.width / 2))
{
table.x = stage.stageWidth - (table.width / 2)
}
if (table.y > (table.height / 2))
{
table.y = table.height / 2;
}
if (table.y < stage.stageHeight - (table.height / 2))
{
table.y = stage.stageHeight - (table.height / 2)
}
if (event.phase == GesturePhase.END)
{
if (mouseTimer !== null)
{
if (mouseTimer.running)
{
mouseTimer.stop();
mouseTimer.removeEventListener(TimerEvent.TIMER, enableClick);
}
}
mouseTimer = new Timer(250);
mouseTimer.addEventListener(TimerEvent.TIMER, enableClick);
mouseTimer.start();
trace("start");
}
}
}
function enableClick(e: TimerEvent)
{
mouseTimer.stop();
trace("stop");
mouseTimer.removeEventListener(TimerEvent.TIMER, enableClick);
stage.addEventListener(MouseEvent.CLICK, gotoBox);
trace("nowClick");
}
function gotoBox(e: MouseEvent)
{
// here it goes to another frame
}
I cannot add the zooming function because its a total disaster; I used something similar to the function onZoom in this link FlashAndMath
Because I needed to zoom in on a point and out from it, and that is the main issue as I have to move my mc around to make that point in the center WHILE I GOTTA MOVE IT TO MAKE MY WHOLE MC IN A CERTAIN BOUNDARY TO COVER THE STAGE! These too movements act against each other. If this last part is not clear ask me to explain more please:)
After having the right answer from LDMS I updated this question to avoid chat-discussions:)
All you need to do, is whenever you move or scale the object, check to make sure it's not going out of bounds.
So if you made a function called forceBounds, just call it anytime you scale or change the x/y:
function forceBounds():void {
//figure out the bounds to constrain to
//the x, should be the farthest left it can go without the edge being seen on the right. To get this value just subtract the smaller width (stage) from the larger width (mc) - this should be a negative number
var bounds:Rectangle = (stage.stageWidth - mc.width, stage.stageHeight - mc.height, mc.width - stage.stageWidth, mc.height - stage.stageHeight);
if (mc.x > bounds.x + bounds.width) {
mc.x = bounds.x + bounds.width;
}
else if (mc.x < bounds.x) {
mc.x= bounds.x;
}
if (mc.y > bounds.y + bounds.height) {
mc.y = bounds.y + bounds.height;
}
else if (mc.y < bounds.y) {
mc.y = bounds.y;
}
}
Here is a full example I made in FlashPro: (with an object on the the stage with an instance name of mc that is bigger than the stage bounds.
Zoom code taken from FlashAndMath.com
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.events.TransformGestureEvent;
import fl.motion.MatrixTransformer;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.events.GesturePhase;
Multitouch.inputMode = MultitouchInputMode.GESTURE;
stage.addEventListener(TransformGestureEvent.GESTURE_PAN, onPan);
stage.addEventListener(TransformGestureEvent.GESTURE_ZOOM, onZoom);
forceBounds();
function onPan(e:TransformGestureEvent):void {
trace("PAN");
if(e.phase == GesturePhase.BEGIN){
stage.removeEventListener(TransformGestureEvent.GESTURE_ZOOM, onZoom);
}
//localToGlobal is a helper method that converts a point to global coordinates
var p:Point = DisplayObject(e.target).localToGlobal(new Point(e.offsetX, e.offsetY));
//conversely, global to local does the opposite
p = mc.globalToLocal(p);
mc.x = p.x;
mc.y = p.y;
forceBounds();
if(e.phase == GesturePhase.END){
stage.addEventListener(TransformGestureEvent.GESTURE_ZOOM, onZoom);
}
}
function onZoom(event:TransformGestureEvent):void {
trace("ZOOM");
var container:MovieClip = mc;
var locX:Number=event.localX;
var locY:Number=event.localY;
var stX:Number=event.stageX;
var stY:Number=event.stageY;
var prevScale:Number=container.scaleX;
var mat:Matrix;
var externalPoint=new Point(stX,stY);
var internalPoint=new Point(locX,locY);
container.scaleX *= (event.scaleX + event.scaleY) * .5;
if(event.scaleX > 1 && container.scaleX > 6){
container.scaleX=prevScale;
}
if(event.scaleY > 1 && container.scaleY > 6){
container.scaleX=prevScale;
}
if(event.scaleX < 1 && container.scaleX < 0.8){
container.scaleX=prevScale;
}
if(event.scaleY < 1 && container.scaleY < 0.8){
container.scaleX=prevScale;
}
if(container.scaleX < 1) container.scaleX = 1;
if(container.scaleX > 1.5) container.scaleX = 1.5;
container.scaleY = container.scaleX;
mat=container.transform.matrix.clone();
MatrixTransformer.matchInternalPointWithExternal(mat,internalPoint,externalPoint);
container.transform.matrix=mat;
forceBounds();
}
function forceBounds():void {
//figure out the bounds to constrain to
//the x, should be the farthest left it can go without the edge being seen on the right. To get this value just subtract the smaller width (stage) from the larger width (mc) - this should be a negative number
var bounds:Rectangle = new Rectangle(stage.stageWidth - mc.width, stage.stageHeight - mc.height, mc.width - stage.stageWidth, mc.height - stage.stageHeight);
if (mc.x > bounds.x + bounds.width) {
mc.x = bounds.x + bounds.width;
}
else if (mc.x < bounds.x) {
mc.x= bounds.x;
}
if (mc.y > bounds.y + bounds.height) {
mc.y = bounds.y + bounds.height;
}
else if (mc.y < bounds.y) {
mc.y = bounds.y;
}
}
I can scroll the ground left and right, but I can't scroll the ground up and down.
private function scrollStage():void
{
if (lastPosX != lastPosX)
{
canScrollStage = false;
}
else if (lastPosX == lastPosX)
{
canScrollStage = true;
}
if (canScrollStage)
{
if (rightKey)
{
//move background left
//something.x +=(stage.stageWidth * 0.5) - character.x * 2;
}
else if (leftKey)
{
//move backgrounf Roight
}
for (var b:int = 0; b < childrenOnStage; b++)
{
if (getChildAt(b).name == "enemy" || getChildAt(b).name == "enemyRed" || getChildAt(b).name == "knife")
{
getChildAt(b).x += (stage.stageWidth * 0.5) - character.x;
//getChildAt(b).y += - character.y;
}
}
ground.x += (stage.stageWidth * 0.5) - character.x;
//ground.y += (stage.stageHeight * 0.5) - character.y;
//ground.y += (stage.stageHeight) - character.y;
}
else
{
//move the background
}
// do this last, everything moves around object
character.x = stage.stageWidth * 0.5;
lastPosX = character.x;
I have tried doing
character.y = stage.stageHeight * 0.5;
But this just glues the characters y position to the center of the screen.
When the world can scroll I tried implementing this in to my code
//ground.y += (stage.stageHeight * 0.5) - character.y;
but this doesn't really work either.
Can anyone please point me in the same direction or give me tips and advice, I have tried implementing this code
// A 'Camera' is really just a Point within the world we want to center on
// the screen.
var camera:Point = new Point();
// Set the camera coordinates to the char coordinates.
//camera.x = character.x;
camera.y = character.y;
// Adjust the world position on the screen based on the camera position.
// world.x = -camera.x + (stage.stageWidth / 2);
ground.y = -camera.y + (stage.stageHeight / 2);
It does work! But the screen shakes up and down violently
I traced the players y position and it was going up and down
but with out that code the y position stayed the same.
Thank you.
EDIT - GRAVITY
In my main class I have this which stops the player from falling.
for (var c:int = 0; c < childrenOnStage; c++)
{
if (getChildAt(c).name == "player")
{
if (ground.level1Ground.hitTestPoint(getChildAt(c).x + 13, getChildAt(c).y, true) || ground.level1Ground.hitTestPoint(getChildAt(c).x - 13, getChildAt(c).y, true))
{ //if the boundary collides with the player or enemy
while (ground.level1Ground.hitTestPoint(getChildAt(c).x + 13, getChildAt(c).y, true) || ground.level1Ground.hitTestPoint(getChildAt(c).x - 13, getChildAt(c).y, true))
{
OnGround(getChildAt(c)).incrementUp();
//bump up the object until it isn't hitting the boundary;
if (ground.level1Ground.hitTestPoint(getChildAt(c).x + 13, getChildAt(c).y, true) || ground.level1Ground.hitTestPoint(getChildAt(c).x - 13, getChildAt(c).y, true))
{
// do nothing
//touchingGround = false;
}
else
{ // once it isn't hitting the boundary, do this function for keeping the object on the boundary
OnGround(getChildAt(c)).keepOnGround();
touchingGround = true;
}
}
// ends while ( _boundaries.hitTestPoint ( getChildAt(c).x , getChildAt(c).y, true) ) {;
}
else
{
// ends if ( _boundaries.hitTestPoint ( getChildAt(c).x , getChildAt(c).y, true) )
touchingGround = false;
}
this is the the onGround class.
public class OnGround extends MovieClip
{
protected var grav:int = 1;
protected var charIsrunning:Boolean;
protected var isDefending:Boolean;
protected var isJumping:Boolean;
public function OnGround()
{
addEventListener(Event.ADDED_TO_STAGE, init)
charIsrunning = false;
isDefending = false;
//gotoAndStsop("jump");
}
private function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
grav = 1;
addEventListener(Event.ENTER_FRAME, fall);
}
private function fall(e:Event):void
{
grav ++;
if (grav > 15)
{
grav = 10;
}
this.y += grav;
}
public function incrementUp():void
{
//this.y -= 0.1;
}
public function keepOnGround():void
{
grav = 0;
positionOnLand();
}
public function positionOnLand():void
{
//overide
}
}
}
I fear that camera.y can't keep up with character.y or character.y changes despite the code telling the game "Stop falling, your y axis is being invcremented."
Glancing at the code, I'll throw this out as a possible answer. It would seem that the camera's Y position changes with even the slightest change in the player's Y position. (Why that isn't happening on X beats me.)
The first thing that comes to mind is that we need to make the camera a lot less sensitive. We can do this by forcing the function to use an estimation of the position. (By the way, this will only work as long as the character is NOT glued to the center of the screen.)
Since I don't have the whole project, I can't test this. If this line doesn't fix the problem, play with the concept.
camera.y = Math.round(character.y);
Essentially, I'd be forcing the camera to work with whole Y values, not decimal values. That could theoretically cut down on some of the shaking.
If helps some, but not enough, we could implement this to make it go based off of ten pixels, not one. Again, untested (math could be a little off), but you get the idea.
camera.y = Math.round(character.y/10) * 10;
The one theoretical downside of that second method is that the screen will jump when it readjusts. You may need to do some additional coding to make it smooth.
This is a potential answer, whaT I have done is changed this block of code to...
/*if (ground.level1Ground.hitTestPoint(getChildAt(c).x + 13, getChildAt(c).y, true) || ground.level1Ground.hitTestPoint(getChildAt(c).x - 13, getChildAt(c).y, true))
{ //if the boundary collides with the player or enemy
getChildAt(c).y --;
while (ground.level1Ground.hitTestPoint(getChildAt(c).x + 13, getChildAt(c).y, true) || ground.level1Ground.hitTestPoint(getChildAt(c).x - 13, getChildAt(c).y, true))
{
//bump up the object until it isn't hitting the boundary;
if (ground.level1Ground.hitTestPoint(getChildAt(c).x + 13, getChildAt(c).y, true) || ground.level1Ground.hitTestPoint(getChildAt(c).x - 13, getChildAt(c).y, true))
{
// do nothing
//touchingGround = false;
}
else
{ // once it isn't hitting the boundary, do this function for keeping the object on the boundary
OnGround(getChildAt(c)).keepOnGround();
touchingGround = true;
// getChildAt(c).y --;
}
}
// ends while ( _boundaries.hitTestPoint ( getChildAt(c).x , getChildAt(c).y, true) ) {;
}
else
{
// ends if ( _boundaries.hitTestPoint ( getChildAt(c).x , getChildAt(c).y, true) )
touchingGround = false;
}
*/
This! I removed the while!
if (ground.level1Ground.hitTestPoint(getChildAt(c).x + 13, getChildAt(c).y, true) || ground.level1Ground.hitTestPoint(getChildAt(c).x - 13, getChildAt(c).y, true))
{
getChildAt(c).y --;
//OnGround(getChildAt(c)).incrementUp();
OnGround(getChildAt(c)).keepOnGround();
touchingGround = true;
}
else
{
touchingGround = false;
}
I can't explain why it works, (makes me look like a bad programmer) but it doesn't changed the characters Y position when he is on the ground, thus no more earthquake meaning the dragon can sleep for now.
Credits to JasonMC92 for being there for me each step of the way for helping me realize this is a solution for now.
I'm creating a platformer game that involves horizontal and vertical level scrolling. The level is tile based, built out of an array. Everything aside from the character are children of a levelholder mc. My problem is the realignment of the levelholder after a jump. Originally the characters y value would be changed during a jump and then be aligned on top of the tile it lands on (loop through tiles, hittest, mc.y=tile[i].y-mc.height).
Now I'm making it so that the y value of the levelholder is changed instead, keeping the character centered and allowing vertically scrollable levels. How can I realign the levelholder after a tile hits the character?
Basic jump function called from an enter_frame function when the character is not hitting a tile:
function charJump():void
{
if (! charJumping) {
charJumping = true;
jumpSpeed = jumpSpeedLimit * -1;
lvlHolder.y -= jumpSpeed;
} else {
if (jumpSpeed < 0) {
jumpSpeed *= 1 - jumpSpeedLimit / 160;
if (jumpSpeed > -jumpSpeedLimit/5) {
jumpSpeed *= -1;
}
}
if (jumpSpeed > 0 && jumpSpeed <= jumpSpeedLimit) {
jumpSpeed *= 1 + jumpSpeedLimit / 50;
}
lvlHolder.y -= jumpSpeed;
for (var i:int = 0; i<blockHolder.numChildren; i++) {
var hitBlock:MovieClip = MovieClip(blockHolder.getChildAt(i));
var trueY = hitBlock.localToGlobal(new Point(0,0));
if (botBox.hitTestObject(hitBlock)) {
if (jumpSpeed > 0 && charHolder.y<=trueY.y - (charHolder.getChildAt(0).height/2)) {
charJumping = false;
doubleJumping = false;
//lvlHolder.y = stage.stageHeight - lvlHolder.height;
charHolder.y = trueY.y - (charHolder.getBounds(this).y + charHolder.height - charHolder.y)+1;
charOnGround = true;
break;
}
}
}
}
}
So Im trying to constantly add elements on the stage and those elements to have a specific X and Y
what i mean and what i want to get is a stairway effect (up and down) :
lets say 1st element is 100 pix above stage.Y
2nd element: Y is 1st element.y + 2nd element.height and its X position is 1st element.x + 2nd element.width(it appears immediately after we can see the whole body of 1st element)
3rd element : Y is 2st element.y + 3nd element.height and its X position is 2st element.x + 3nd element.width(it appears immediately after we can see the whole body of 2st element)
and the last element before the stairway effect goes down will be stage.stageheight - 100
like in this picture
Yet I dont know how to do this (I know i have to put it in a for loop and in there to have a if statement that checks every time for the up and down border (stage.stageHeight - 100 and stage.Y + 100) but i cant figure it out)
what i have so far is this
private var itemsToAnimate:Array = []
private var magnetBuff:Boolean = false;
private var block:Block = new Block();
private var stage_H:int = stage.stageHeight;
private var block_H:int = block.height;
public function AB_Main()
{
this.addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(evt:Event)
{
this.removeEventListener(Event.ADDED_TO_STAGE, init);
this.addEventListener(Event.ENTER_FRAME, onEveryFrame);
}
private function onEveryFrame(ev:Event):void
{
createItems()
animateItems();
}
private function animateItems():void
{
var itemToTrack:Block;
for(var i:uint = 0; i < itemsToAnimate.length; i++)
{
itemToTrack = itemsToAnimate[i];
itemToTrack.x -= 3;
if(itemToTrack.x < -50)
{
itemsToAnimate.splice(i, 1);
this.removeChild(itemToTrack);
}
}
}
private function createItems():void
{
if(Math.random() > 0.75)
{
var itemToTrack:Block = new Block();
itemToTrack.x = stage.stageWidth - 50;
itemToTrack.y = int( Math.random() * stage.stageHeight)
this.addChild(itemToTrack);
itemsToAnimate.push(itemToTrack);
}
}
and that gets me a random positioning blocks like in the picture
I think you could do something like this (writing it from my head without testing, I hope it will run ok):
function draw(min:Number, max:Number, horSpacing:Number, vertSpacing:Number):void {
var increasing:Boolean = true;
var lastY:Number = min + vertSpacing;
for(var i:int=0; i<100; i++) {
var c:Circle = new Circle(); //where Circle would be your dot with registration point in center
c.x = 20 + i * horSpacing; //hardcoded margin
c.y = (increasing) ? lastY - vertSpacing : lastY + vertSpacing;
lastY = c.y;
addChild(c);
if(c.y <= max) increasing = false;
if(c.y >= min) increasing = true;
}
}
draw(stage.stageHeight - 100, 100, 20, 20);
What you have here is a value that will constantly increase along the x axis and then another that will either be increasing or decreasing along the y axis, alternating when you touch the top or bottom. That's as simple as:
var increaseY:Boolean = true; // Whether we are moving up or down the y axis.
var position:Point = new Point(); // Position to place next item.
var move:int = 10; // How much we move along each axis.
var margin:int = 100; // Distance from top or bottom before alternating.
for each(var i:Sprite in itemsToAnimate)
{
i.x = position.x;
i.y = position.y;
if(increaseY) position.y += move;
else position.y -= move;
position.x += move;
if(position.y < margin || position.y > stage.stageHeight - margin)
{
// Reverse direction.
increaseY = !increaseY;
}
}
move can be adjusted to change the distance between each item along the path.
This question already has answers here:
How to make my character move relative to the mouse position with actionscript 3?
(2 answers)
Closed 9 years ago.
I am making a game where I want my character to move towards the mouse pointer when pressing forward and for it to strafe left and right with the respecting arrow keys.
Here is my current code:
import flash.events.MouseEvent;
//Event Listners
stage.addChild(crosshair_mc);
crosshair_mc.mouseEnabled = false;
crosshair_mc.addEventListener(Event.ENTER_FRAME, fl_CustomMouseCursor);
function fl_CustomMouseCursor(event:Event)
{
crosshair_mc.x = stage.mouseX;
crosshair_mc.y = stage.mouseY;
}
Mouse.hide();
stage.addEventListener(MouseEvent.MOUSE_MOVE,facecursor);
stage.addEventListener(KeyboardEvent.KEY_DOWN, fl_KeyboardDownHandler);
//Functions
function facecursor(event):void
{
character_mc.rotation = (180 * Math.atan2(mouseY - character_mc.y,mouseX - character_mc.x))/Math.PI + 90;
}
function fl_KeyboardDownHandler(event:KeyboardEvent):void
{
trace("Key Code Pressed: " + event.keyCode);
if (event.keyCode == 38)
{
character_mc.y = character_mc.y - 5;
}
if (event.keyCode == 40)
{
character_mc.y = character_mc.y + 5;
}
if (event.keyCode == 39)
{
character_mc.x = character_mc.x + 5;
}
if (event.keyCode == 37)
{
character_mc.x = character_mc.x - 5;
}
}
You have the rotation part right, now all you need is to incorporate that with cos and sin for the x and y axis respectively. Example:
var speed:Number = 8;
var angle:Number = Math.atan2(mouseY - character_mc.y, mouseX - character_mc.x);
character_mc.rotation = angle * 180 / Math.PI;
character_mc.x += Math.cos( angle ) * speed;
character_mc.y += Math.sin( angle ) * speed;
To avoid confusion, I would stop adding 90 degrees onto the rotation and instead rotate your graphics to face right / east.
The strafing thing uses the same logic, you just want to add a quarter of a circle to the rotation in whichever direction you want to strafe. FYI, a quater of a circle in radians is PI / 2. There are 2 PI radians in one circle:
// Augment angle for strafing.
angle += Math.PI / 2;