How do I slowdown an animation in AS3 without decreasing the fps - actionscript-3

I have this code that I found online that does an infinite rotating gallery, now my problem is that on enter frame it jumps and too fast. I want it to be as fast at after you hover out of the logo.
Here is the code:
//Import TweenMax
import com.greensock.TweenMax;
//Save the horizontal center
var centerX:Number = stage.stageWidth / 2;
//Save the width of the whole gallery
var galleryWidth:Number = infiniteGallery.width;
//Speed of the movement (calculated by the mouse position in the moveGallery() function)
var speed:Number = 0;
//Add an ENTER_FRAME listener for the animation
addEventListener(Event.ENTER_FRAME, moveGallery);
function moveGallery(e:Event):void {
//Calculate the new speed
speed = -(0.02 * (mouseX - centerX));
//Update the x coordinate
infiniteGallery.x+=speed;
//Check if we are too far on the right (no more stuff on the left edge)
if (infiniteGallery.x>0) {
//Update the gallery's coordinates
infiniteGallery.x= (-galleryWidth/2);
}
//Check if we are too far on the left (no more stuff on the right edge)
if (infiniteGallery.x<(-galleryWidth/2)) {
//Update the gallery's coordinates
infiniteGallery.x=0;
}
}
and here is the demo »

The speed of the scroller is based on three things:
1- The frame rate. The ENTER_FRAME event handler gets called on every frame, thus is directly influenced by the frame rate.
2- The speed damping number. In your case this is equal to 0.02. If you want to slow down the scrolling, make this a smaller number. Try 0.01 for half the speed.
3- The distance of the mouse pointer to the center x coordinate of your stage. The difference between the mouse pointer and the center of your stage is multiplied by your speed damping number. If you want the movement to stop when you are at or around the center change you code as follows:
var buffer:Number = 50;
function moveGallery(e:Event):void {
var diff = mouseX - centerX;
if (Math.abs(diff) > buffer)
speed = -(0.02 * (diff + (diff > 0 ? -buffer : buffer)));
else
speed = 0;
AS REQUESTED:
var centerX:Number = stage.stageWidth / 2;
var galleryWidth:Number = infiniteGallery.width;
var speed:Number = 0;
addEventListener(Event.ENTER_FRAME, moveGallery);
var buffer:Number = 100;
function moveGallery(e:Event):void {
var diff = mouseX - centerX;
if (Math.abs(diff) > buffer)
speed = -(0.02 * (diff + (diff > 0 ? -buffer : buffer)));
else
speed = 0;
infiniteGallery.x += speed;
if (infiniteGallery.x>0) {
infiniteGallery.x = -galleryWidth / 2;
}
if (infiniteGallery.x < -galleryWidth / 2) {
infiniteGallery.x = 0;
}
}

Related

Orbiting objects with equal spacing AS3

I have a monster that produces crystals. I want each crystal to orbit the monster, but when there is more than one crystal, I want them to orbit at an equal distance from each other. I've been trying to get this to work using two blocks of code I already have, but each one does something different and i need one block of code that does it all.
This block simply allows an object to orbit another:
orbitRadius = 110;
angle += orbitSpeed;
rad = (angle * (Math.PI / 180));
orbitX = monster.x + orbitRadius * Math.cos(rad);
orbitY = monster.y + orbitRadius * Math.sin(rad);
Here's a video of what it looks like:
https://www.youtube.com/watch?v=ACclpQBsjPo
This block of code arranges crystals around the monster based on the amount of crystals there are:
radius = 110;
angle = ((Math.PI * 2) / targetArray.length) * targetArray.indexOf(this);
orbitX = monster.x - (radius * Math.cos(angle));
orbitY = monster.y - (radius * Math.sin(angle));
And here's this video: https://www.youtube.com/watch?v=TY0mBHc2A8U
I do not know how to both space the crystals equally and make them circle around the monster at the same time. What needs to be done in order to achieve this?
1) Hierarchical way: put crystals into the same container so they spread equally (like you are doing on the second video) then rotate the container.
2) Math way.
Implementation:
public class Orbiter extends Sprite
{
// Pixels.
public var radius:Number = 100;
// Degrees per second.
public var speed:Number = 360;
public var items:Array;
public var lastTime:int;
public function start()
{
stop();
rotation = 0;
items = new Array;
lastTime = getTimer();
addEventListener(Event.ENTER_FRAME, onFrame);
}
public function stop():void
{
items = null;
removeEventListener(Event.ENTER_FRAME, onFrame);
}
public function onFrame(e:Event = null):void
{
var aTime:int = getTimer();
rotation += speed * (aTime - lastTime) / 1000;
lastTime = aTime;
for (var i:int = 0; i < items.length; i++)
{
// Get the object.
var anItem:DisplayObject = items[i];
// Get the object's designated position.
var aPos:Point = getPosition(i);
// Follow the position smoothly.
anItem.x += (aPos.x - anItem.x) / 10;
anItem.y += (aPos.y - anItem.y) / 10;
}
}
private function getPosition(index:int):Point
{
// Calculate the angle with regard to the present items amount.
var anAngle:Number = (rotation - 360 / items.length) * Math.PI / 180;
var result:Point = new Point;
// Figure the position with regard to (x,y) offset.
result.x = x + radius * Math.cos(anAngle);
result.y = y + radius * Math.sin(anAngle);
return result;
}
}
Usage:
var O:Orbiter = new Orbiter;
// Define the offset.
O.x = monster.x;
O.y = monster.y;
// Set radius and rotation speed.
O.radius = 110;
O.speed = 270;
// Enable the rotation processing.
O.start();
// Append items to orbit.
O.items.push(Crystal1);
O.items.push(Crystal2);
O.items.push(Crystal3);
You can change radius and speed any time, as well as add/remove items, thanks to motion smoothing that all will look equally fine.

if a ball is hitting a box from every side, how to know which side hittest is true

i am creating a brick breaker game in which ball is hitting a square object. i want to change the direction of ball when he hit square object.
square is of 15 px. and
ball is of 10 px.
for example
if hits on the right side, Speed in x direction will reverse
if hits on the left side, Speed in x direction will reverse
if hits on the up side, Speed in y direction will reverse
if hits on the down side , Speed in y direction will reverse.
I tried it hard but found nothing. any help will be appreciated. here is the code:
import flash.events.*;
import flash.display.*;
stop();
// speed of ball in x and y
var speedx : Number = 10;
var speedy : Number = 10;
// start running
function begin_code (event:MouseEvent):void{
addEventListener(Event.ENTER_FRAME,move_ball);
stage.addEventListener(MouseEvent.MOUSE_DOWN,by_key);
addEventListener(Event.ENTER_FRAME,ht_mc);
start_game.alpha=0;
}
start_game.addEventListener(MouseEvent.CLICK, begin_code) ;
//start ball moving
function move_ball(e:Event):void{
Ball.x += speedx;
Ball.y += speedy;
Ball.rotation +=speedx;
var ballposition : Number = Ball.x -Hitbar.x;
var ballhitpercent : Number = (ballposition /(Hitbar.width-Ball.width));
if(Ball.x <= x1.x+Ball.width/2){
speedx = speedx *-1;
}
if(Ball.x >= x2.x-Ball.width/2){
speedx = speedx *-1;
}
if(Ball.y <=(55)){
speedy = speedy *-1;
}
else if (Ball.y >= stage.stageHeight-Ball.height){
speedy = speedy *-1;
trace("hit y");
}
//start ball angle
else if(Ball.hitTestObject(Hitbar)){
speedx = ballhitpercent*10;
speedy = speedy *-1;
}
}
//start hitbar moving
// code for keys!!!!!!!!!
var distance : Number = 0;
function by_key(e:MouseEvent):void{
if (mouseX>Hitbar.x){
distance = (mouseX-Hitbar.x);
Hitbar.x += distance;
}
else if (mouseX<Hitbar.x){
distance = (Hitbar.x-mouseX);
Hitbar.x -= distance;
}
}
//restart
function by_key_up(e:MouseEvent):void{
}
stage.addEventListener(MouseEvent.MOUSE_UP, by_key_up);
function pLimiter(e:Event):void{
Hitbar.y = 406.2;
if (Hitbar.hitTestObject(x1)){
Hitbar.x = 32.6;
}
if (Hitbar.hitTestObject(x2)){
Hitbar.x = 287.55;
}
}
addEventListener(Event.ENTER_FRAME, pLimiter);
// Bricks set hit
var pickup:Array =new Array();
for (var i = 0;i<numChildren;i++){
if(getChildAt(i) is abc){
pickup.push(getChildAt(i));
}
}
function hittest_box(e:Event):void{
for (var f = 0;f<pickup.length;f++){
if (Ball.hitTestObject(pickup[f])){
if(pickup[f].parent) {
pickup[f].parent.removeChild(pickup[f]);
}
}
}
}
function ht_mc(e:Event):void{
for (var j = 0;j<pickup.length;j++){
var ball_pos_x: Number = ( Ball.x - pickup[j].x);
var ball_pos_y: Number = ( Ball.y - pickup[j].y);
if( ball_pos_x < 11.5 && ball_pos_x > -11.5){
speedy = speedy *-1;
trace("box y");
addEventListener(Event.ENTER_FRAME,hittest_box);
}
else if ( ball_pos_y < 11.5 && ball_pos_y > -11.5){
speedx = speedx *-1;
trace("boxx");
addEventListener(Event.ENTER_FRAME,hittest_box);
}
}
}
edit
To turn my two point example into a one-ball-moving version, the main thing you need to do is to declare the p1 then move the ball and then declare p2.
p1.x = ball.x;
p1.y = ball.y;
moveBall();
p2.x = ball.x;
p2.y = ball.y;
Now you have p1 and p2. Run the calculations as below to find which brick is hit and which side was hit.
A few more calculations will be needed (and you'll have to loop through this whole thing for every collision that occurs in between frames). But I can't post all that here.
Original Answer
My answer is meant to be able to be used in any situation in which you have a point object that is moving and needs to detect when it collides with sides of a square. Simple hitTest solutions are inadequate because a point object moving fast enough could "jump over" a corner. Additionally, if the walls of the object are infinitely thin, there couldn't easily be a "collision", so what we really want to calculate is whether or not the point passed through a wall during the last tick. Also, if the ball is going fast enough to jump over an entire brick, you'll get collision with bricks that are surrounded by other bricks. This method fixes that. Here we go...
My illustration shows the basic method I'm using. It breaks down like this:
define end points for each line segment (corners of block and 2 positions of ball)
check first if ball bounding box and block overlap with simple hit test type of conditional statement
if they do, determine which edge the ball passed through by comparing the 3 angles as shown in the diagram (angle 1 just has to be between angle 2 and 3)
then determine which of the points that make up the lines that the ball passed through during the last frame transition and determine which of these points is nearest the where the ball was on the previous frame (this will be a point contained in the line that the ball will hit!)
lastly, determine which line contains that point
There could certainly be some optimizations added, but this works like a charm for what it is.
This code will add a bunch of LineTestBlock objects to the stage as well as 2 Point objects associated with circles. Move the Points such that 1 will represent the first frame location of the ball, and the second Point can be dragged to a place representing where the ball will be on the 2nd frame. You will see that wherever the line between these passes through, the closest edge of a block will light up.
And here is the code. It is a main document class named BlockDoc and a LineTestBlock class.
package {
import flash.display.MovieClip;
import flash.geom.Point;
import flash.events.Event;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.geom.Rectangle;
import flash.display.Shape;
public class BlockDoc extends MovieClip {
// this holds the circle handles (the actual sprite objects)
var cArray = new Array();
// this holds all the bricks
var brickArray = new Array();
//ball position in frame 1
//these are just point objects. p1 will need to represent where the ball was on the last frame
var p1:Point = new Point();
// and p2 will need to be where the ball is "going" to be on the next frame
// although, if it hits something, the ball will not end up p2 on the next screen update, obviously
var p2:Point = new Point();
// just an array used for putting the 1 and 2 on the handles
// you won't eventually need this, of course
var pointNameArray:Array = new Array();
// this is the Sprite object that holds the rectangle
// which describes the bounding box made by the ball in the two frames
var recASprite:Sprite = new Sprite();
// rec is the Sprite that holds the bricks, or you could just put the bricks on the stage. I like having them in a container so I can remove them all or move them all or change them all just by changing the container
var rec:Sprite = new Sprite();
// lines is the Shape object that all the bricks edge lines are drawn to
var lines:Shape = new Shape();
// mainLine is the Shape object that the line connecting the two ball positions is drawn to
var mainLine:Shape = new Shape();
// you won't need either of these lines in your version
public function BlockDoc() {
// just a background so you can see the alpha better.
// you won't need this in yours
var bkgnd:Sprite = new Sprite();
bkgnd.graphics.lineStyle();
bkgnd.graphics.beginFill(0x0);
bkgnd.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
bkgnd.graphics.endFill();
addChild(bkgnd);
makeBricks();
createArray();
addChild(mainLine);
addChild(lines);
createHandles(); // creates the circle handles
addEventListener(Event.ENTER_FRAME,gameTick);
}
private function drawLine(container:Shape,p1:Point,p2:Point,color:uint=0xffbbee):void{
container.graphics.clear();
container.graphics.lineStyle(2,color);
container.graphics.moveTo(p1.x,p1.y);
container.graphics.lineTo(p2.x,p2.y);
}
private function makeBricks():void{
// creates rectangle object defined by frame 1 and 2 of ball position
updateBallBoundingBox(recASprite,p1,p2);
addChild(rec); // the parent for all bounding boxes
makeSimpleRectangle(recASprite); // this is the bounding box for the 2 positions of the ball
// these are the bricks
for (var i:int = 0; i < 5; i++){
for (var j: int = 0; j < 3; j++){
var b: LineTestBlock = new LineTestBlock(50,25);
rec.addChild(b);
b.alpha = .5;
brickArray.push(b);
b.x = 100 * i + 50;
b.y = 80 * j +100;
// top left corner of brick
b._p1.x = b.x;
b._p1.y = b.y;
// top right corner of brick
b._p2.x = b.x + b.width;
b._p2.y = b.y;
// bottom right corner of brick
b._p3.x = b.x + b.width;
b._p3.y = b.y + b.height;
// bottom left corner of brick
b._p4.x = b.x;
b._p4.y = b.y + b.height;
}
}
}
private function makeSimpleRectangle(rect:Sprite,color:uint = 0x0):void{
rect.graphics.lineStyle(0,0x0,0);
rect.graphics.beginFill(color,.5);
rect.graphics.drawRect(0,0,50,50);
rect.graphics.endFill();
}
private function updateBallBoundingBox(rec:Sprite,p1:Point,p2:Point):void{
rec.x = Math.min(p2.x,p1.x);
rec.y = Math.min(p2.y,p1.y);
rec.width = Math.max(p2.x,p1.x)-rec.x;
rec.height = Math.max(p2.y,p1.y)-rec.y;
}
private function checkIntersection(A1:Point,A2:Point,B1:Point,B2:Point):Boolean{
// adjusts the current "bounding box" using the position 1 and position 2 of the ball
updateBallBoundingBox(recASprite,A1,A2);
// if bounding boxes hit
// define the angles to be used (further optimization can easily be done here by
// only checking the 2 possible sides of contact, or using a look up table
// instead of using Math.atan2)
// angle between position 1 and 2 of the ball
var A1_A2_r:Number = Math.atan2(A2.y - A1.y,A2.x - A1.x);
// angle between position 1 and one corner
var A1_B1_r:Number = Math.atan2(B1.y - A1.y,B1.x - A1.x);
// angle between position 1 and the second corner
var A1_B2_r:Number = Math.atan2(B2.y - A1.y,B2.x - A1.x);
// and if angle from position 1 to position 2 is between angle from one corner to the other corner...
if (A1_A2_r > A1_B1_r && A1_A2_r < A1_B2_r){
// return true
return true;
} else {
return false;
}
}
private function gameTick(e:Event):void{
// p1 and p2 are the point objects that describe frame 1 and frame 2 of the moving ball
// for actual moving ball:
//p1.x = Ball.x;
//p1.y = Ball.y;
//move_ball();
//p2.x = Ball.x;
//p2.y = Ball.y;
//or use this for experimenting with the handles
//p1.x = cArray[0].x;
//p1.y = cArray[0].y;
//p2.x = cArray[1].x;
//p2.y = cArray[1].y;
// draw line between position 1 and 2
drawLine(mainLine,p1,p2);
checkCollision();
}
private function checkCollision():void{
// clears previously drawn lines on bricks
lines.graphics.clear();
var xDir:int;
var yDir:int;
// determine direction of ball (you probably already have this as a variable somewhere so probably don't need this
if (p1.x < p2.x){
xDir = 1;
} else if (p1.x > p2.x){
xDir = -1;
} else {
xDir = 0;
}
if (p1.y < p2.y){
yDir = 1;
} else if (p1.y > p2.y){
yDir = -1;
} else {
yDir = 0;
}
// this array will hold all the Point objects involved in true collision
var arr:Array = new Array();
var arrLines:Array = new Array();
var nearestDistance:Number = 2000; // change this to something sensible (maybe the speed of the ball...);
var nearestPoint:Point = new Point(); // change this to something sensible
// first check bounding boxes
for (var i:int = 0; i < brickArray.length; i++){
var b:LineTestBlock = brickArray[i];
var a:Sprite = recASprite;
updateBallBoundingBox(a,p2,p1);
// this is just a bounding box hittest, and hitTestObject used to work, but I broke something, so I have to do it like this now
if (a.x+a.width > b.x && a.y + a.height > b.y && a.x < b.x+b.width && a.y<b.y+b.height){
// now that we know the rectangles overlap, we check the two sides that are hittable
// instead of xDir and yDir just use your variable or property that holds the x and y speeds;
// I use xDir and yDir because my example doesn't actually use motion.
if (xDir > 0){
if (checkIntersection(p1,p2,b._p1,b._p4)){
// ball hits left wall of brick
//drawLine(lines,b._p1,b._p4,0x00ffee);
// instead of drawLine above, put in your function for collision of left wall
arr.push(b._p1,b._p4);
arrLines.push({p1:b._p1,p2:b._p4,brick:brickArray[i]});
// that last array there simply holds an object with 3 properties
// for use later in comparing what should actually receive the hit.
}
if (yDir > 0) {
if (checkIntersection(p2,p1,b._p1,b._p2)){
// ball hits top wall of brick
arr.push(b._p1,b._p2);
arrLines.push({p1:b._p1,p2:b._p2,brick:brickArray[i]});
}
} else if (yDir < 0){
if(checkIntersection(p2,p1,b._p3,b._p4)){
// ball hits bottom wall of brick
arr.push(b._p3,b._p4);
arrLines.push({p1:b._p3,p2:b._p4,brick:brickArray[i]});
}
}
} else if (xDir < 0){
if(checkIntersection(p2,p1,b._p2,b._p3)){
// ball hits right edge of brick
arr.push(b._p2,b._p3);
arrLines.push({p1:b._p2,p2:b._p3,brick:brickArray[i]});
}
if (yDir > 0) {
if (checkIntersection(p2,p1,b._p1,b._p2)){
// ball hits top edge of brick
arr.push(b._p1,b._p2);
arrLines.push({p1:b._p1,p2:b._p2,brick:brickArray[i]});
}
} else if (yDir < 0){
if(checkIntersection(p2,p1,b._p3,b._p4)){
// ball hits bottom edge of brick
arr.push(b._p3,b._p4);
arrLines.push({p1:b._p3,p2:b._p4,brick:brickArray[i]});
}
}
}
}
}
for (var i:int = 0; i < brickArray.length; i++){
brickArray[i].alpha = 0.3;
}
for (var i:int = 0; i < arr.length; i++){
var d:Number = dist(arr[i],p1);
if(d < nearestDistance){
nearestDistance = d;
nearestPoint = arr[i];
}
}
for (var j:int = 0; j < arrLines.length; j++){
if (arrLines[j].p1 == nearestPoint){
drawLine(lines,nearestPoint,arrLines[j].p2);//THIS IS THE EDGE THAT GETS HIT!!
arrLines[j].brick.alpha = 0.7; // THIS IS THE BRICK THAT GETS HIT!!
} else if (arrLines[j].p2 == nearestPoint){
drawLine(lines,nearestPoint,arrLines[j].p1); //THIS IS THE EDGE THAT GETS HIT!!
arrLines[j].brick.alpha = 0.7; // THIS IS THE BRICK THAT GETS HIT!!
}
}
}
private function dist(p1:Point, p2:Point):Number{
var dx:Number = p1.x - p2.x;
var dy:Number = p1.y - p2.y;
return Math.sqrt(dx * dx + dy * dy);
}
private function createHandles():void{
// these are the circle handles for moving the balls around
for (var i:int = 0; i < 2; i++){
var c:Sprite = new Sprite();
var tf:TextField = new TextField();
c.graphics.lineStyle();
c.graphics.beginFill(0x5555ff+0x5555*i);
c.graphics.drawCircle(0,0,10);
c.graphics.endFill();
addChild(c);
c.addChild(tf);
c.x = 50*i+50;
c.y = 50;
c.addEventListener(MouseEvent.MOUSE_DOWN,dragObject);
c.addEventListener(MouseEvent.MOUSE_UP,dragStopObject);
cArray.push(c);
tf.height = 20;
tf.width = 10;
tf.text = pointNameArray[i];
tf.x = -5;
tf.y = -10;
tf.mouseEnabled = false;
}
}
private function createArray():void{
// just used for putting the fancy 1 and 2 on the handles
pointNameArray = ["1","2"];
}
private function radsFromPoints(p1:Point,p2:Point):Number{
return Math.atan2(p1.y - p2.y, p1.x - p2.y);
}
private function dragObject(me:MouseEvent):void{
me.target.startDrag(true);
}
private function dragStopObject(me:MouseEvent):void{
me.target.stopDrag();
}
}
}
and the LineTestBlock class:
package {
import flash.display.*;
import flash.text.*;
import flash.geom.Point;
public class LineTestBlock extends Sprite{
var _p1:Point = new Point();
var _p2:Point = new Point();
var _p3:Point = new Point();
var _p4:Point = new Point();
public function LineTestBlock(w:Number,h:Number) {
var s:Sprite = new Sprite();
s.graphics.lineStyle();
s.graphics.beginFill(0xff5599,0.5);
s.graphics.drawRect(0,0,w,h);
s.graphics.endFill();
addChild(s);
}
}
}
Obviously the stuff about lines and alpha are just for display purposes. You'll be able to erase a bunch of this code and will need to replace some of it with actual bounce functions.
One thing to keep in mind is how you deal with the bouncing off of the ball. You can't simply reverse the x or y speed of the ball, as you might think because then it is inside of a brick, or on the opposite side of the brick trying to come back out, which will work, but could look funny and actually allow the ball access to bricks that should be off limits because the are surrounded by other bricks. But I've already answered the question at hand, so I'll stop there.

Resetting a players x position (Flash As3)

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).x +=(stage.stageWidth * 0.5) - character.x
}
}
ground.x += (stage.stageWidth * 0.5) - character.x
}
else
{
//move the background
}
// do this last, everything moves around object
character.x = stage.stageWidth * 0.5;
lastPosX = character.x;
}
Someone told me to move the objects around the player and then update the players x position.
This is what I've done by looking at a tutorial ("Cartoon Smart");
In my player class I have a reset function.
private var xSpeed:int;
private var resetPos:Point;
public function player()
{
addEventListener(Event.ADDED_TO_STAGE, onAdd)
}
private function onAdd(e: Event): void
{
xSpeed = 3;
resetPos = new Point(x, y);
}
public function reset():void
{
x = resetPos.x;
y = resetPos.y;
//trace(resetPos);
//trace(resetPos + "player");
}
When the player falls to death this function is called
private function playerFalls():void
{
if (character.y > stage.stageHeight)
{
//take life away and go back to check point or back to reset
character.x = stage.stageWidth * 0.5;
character.y = 20;
//goblin1.reset();
//goblin2.reset();
//goblin3.reset();
//stage.x = stage.stageWidth * 0.5;
//canScrollStage = false;
}
}
if I use
character.x = stage.stageWidth * 0.5;
Then my character ends up in the middle, but it will end up in the middle since the scroll function dictates the player to be in the center always.
character.x = (stage.stageWidth * 0.5) - 400;// moves him back
but if character falls off left of the screen then he is moved back.
Any one have a solution for this please?
My question is, I want to reset the player's x position to 300 and y position to 10;
But I can't do this because the stage shifts and the co ordinate system changes.
In order for the player to go back to the original coordinate of the stage, the stage must scroll.
That's my idea, or perhaps the ground and enemies must do the opposite?
I sincerely apologize for the late answer. Okay, so your saying that when the character falls you don't want the screen to scroll all the way back to the character's start position. What you need to do is find the start positions of your character and ground (as well as any other layers such as backgrounds etc). Then wherever your fall function comes into place simply set the character and background positions to their starting coordinates.
function fall(){
char.x=charStartX;
char.y=charStartY;
ground.x=groundStartX;
ground.y=groundStartY;
//etc
}
For example, let's say you have a check point. If player hits check point charResetPoint = 100. If player falls then set it's x pos to charResetPoint
But I can't move the players x position because it will always be stage.stageWidth/2 due to my code.
So in theory it will be difficult to make a resetPoint, because when I add goblin 1.x , it's x pos is 900, if I scroll right goblon1 x pos will change. Everythings x pos changes and so does the stages.
I can't get a grasp on the concept, sortlry

Calculate a trajectory for an object, when given an angle and a velocity in flash

I am trying to launch a cannonball from a cannon and have it follow a realistic path. The angle of fire changes depending on the orientation of the cannon (automatically orientates to mouse pointer). So what I'm trying to figure out, is how to move a cannonball along a parabolic path, when given an angle, and a set velocity.
I've read that this can be done without complicated trigonometry (never listened to it in highschool), and can be calculated simply by adding gravity to the yVelocity every tick. However, at this moment, I don't know how to calculate the initial yVelocity (again, depending on cannon orientation).
You can see the current animation here: http://kate.ict.op.ac.nz/~welfajw1/portfolio/videos/task3-assignment2.swf
This is all done in AS3, and the code I have is as follows:
Main timeline code:
import flash.display.*;
import flash.events.*;
import flash.geom.*;
var cannonball:ball_mc;
var angleDegree;
myCannon.addEventListener(Event.ENTER_FRAME, cannonEnterFrame);
function cannonEnterFrame(pEvt)
{
var mc = myCannon;
var mg = myCannon.myGun;
//find angle for orientation
var angleRadian = Math.atan2(mouseY - mc.y, mouseX - mc.x);
//convert to degrees
angleDegree = angleRadian * 180 / Math.PI;
//limit rotation
if(angleDegree > -63 && angleDegree < 20)
mg.rotation = angleDegree;
}
stage.addEventListener(Event.ENTER_FRAME, stageRefresh);
function stageRefresh(pEvt)
{
if (cannonball)
{
//move every "tick"
cannonball.move();
}
}
stage.addEventListener(MouseEvent.CLICK, mouseClicked);
function mouseClicked(pEvt)
{
//starting position of the ball
cannonball = new ball_mc(100, 475);
//SEND IN INITIAL x, y VELOCITIES
cannonball.fire(20, angleDegree);
//add to stage
stage.addChild(cannonball);
}
ball_mc code:
package
{
import flash.display.MovieClip;
import flash.sensors.Accelerometer;
import flashx.textLayout.formats.Float;
public class ball_mc extends MovieClip
{
//constant gravity
public static const g:Number = 2;
//starting velocities
private var ux:Number;
private var uy:Number;
public function ball_mc(startX:int, startY:int)
{
x = startX;
y = startY;
}
public function fire(vx:Number, vy:Number):void
{
ux = vx;
uy = vy;
}
public function move():void
{
//distance moved in x dir
var sx:Number = ux;
//new velocity in y dir
var vy:Number = uy + g;
//distance moved in y dir
var sy:Number = uy + g/2;
//apply movement
x += sx;
y += sy;
//save new y velocity
uy = vy;
}
}
}
You need a little bit of physics.
Initial speed must be calculated by using some criteria that you add on your own. One example is to calculate initial speed by using the distance between the mouse and the cannon, at the time the mouse is pressed. If the distance is greater the projectile will have a bigger speed, and if the distance is smaller the projectile will have smaller speed.
The you add an Event Listener with type ENTER_FRAME.
I guess it's 2 dimensional animation so you have to find the current x and y at any point in time.
Here's a little bit of code:
var TimeperFrame:Number = 1/fps //fps is not a constant, here you should add a number, a value that you previously added in fla. document properties. I usualy use 60 fps
var Time:Number = 0;
addEventListener(ENTER_FRAME, movingCannonBall);
function movingCannonBall(e:Event):void
{
Time += TimeperFrame;
}
Now here's the equitation for trajectory of projectile.
x = xo + vxo·t
y = yo + vyo·t - 0.5·g·t^2
yo = initial height of your cannon ball
vyo = initial y velocity; vyo = vo·sin θ
t = time passed, we conrol that by upper code
g = acceleration (9,81 m/s^2) at Earth's surface
xo = initial distance for the start
vxo = initial x velocity; vxo = vo·cos θ
Now in the upper code we add these equitations and it should look like this:
var TimeperFrame:Number = 1/fps
var Time:Number = 0;
var initx: Number = cannonball.x;
var inity: Number = cannonball.y;
var initVelocity: Number = (you define initial Velocity by your criteria)
var G: Number = 9.81;
addEventListener(ENTER_FRAME, movingCannonBall);
function movingCannonBall(e:Event):void
{
Time += TimeperFrame;
cannonball.x = initx + Math.cos(angle) * initVelocity * Time;
cannonball.y = inity + Math.sin(angle) * initVelocity * Time - G * Time * Time * 0.5
}
This should work. I have use this code many times and it's effiecient and also it's simple.

How to create an infinite wrapping orbiting background in Actionscript 3

So I have been searching for a way to have a background orbit around a centerpoint. I came across the greensock blitmask that does an amazing job of wrapping the bitmap data to do infinte scrolling effects. However, I can't figure out a way to use this blitmask to rotate the bitmap data and still have the wrapping effect. Below is a link to my SWF.
The image that moves is the one that I wish to wrap and have the infinite scrolling effect. The problem is dealing with repositioning after the image has moved off the screen since it has been rotated.
EDIT: I totally forgot about this issue and decided put it on the backburner for my game since it was taking too long to figure. I recently returned to this concept because I had an idea to make it work. Below is a link to the .SWF that shows what I was trying to accomplish. Though this example works, I dont feel its the best solution.
"WASD" control movement
Orbiting Background
I used some trigonometry to calculate the distance a star is from the player. If that star is beyond that distance, reposition it using it's angle * -1. The code for this is under the link.
var travelVal:Number = 0;
var turnVal:Number = 0;
var currentChild:DisplayObject;
var currentStar:Star;
var childIndex:int = 0;
var angle:Number = 0;
var distance:Number = 0;
if (controller.isKeyDown(Keyboard.A))
{
turnVal += TURN_SPEED;
}
if (controller.isKeyDown(Keyboard.D))
{
turnVal -= TURN_SPEED;
}
if (controller.isKeyDown(Keyboard.W))
{
travelVal += PLAYER_SPEED;
}
if (controller.isKeyDown(Keyboard.S))
{
travelVal -= PLAYER_SPEED
}
for (childIndex = 0; childIndex < numChildren; childIndex++)
{
currentChild = getChildAt(childIndex);
//if (currentChild != player && currentChild != debugOutput && currentChild != blackBkgd)
if(currentChild is Star)
{
currentStar = currentChild as Star;
//move this child based on the travel value
currentChild.y += travelVal * currentStar.speed;
//calculate the orbiting
distance = Math2.distanceBetweenObjects(player, currentChild);
angle = Math.atan2(currentChild.y - player.y, currentChild.x - player.x);
if (distance > STAGE_WIDTH ) angle = angle * -1;
//get orginal angle in radians
//angle = Math.atan2(currentChild.y - player.y , currentChild.x - player.x);
angle = Math2.radiansToDegress(angle);
angle += turnVal;
//currentStar.rotation = angle;
angle = Math2.degreesToRadians(angle);
currentChild.x = player.x + (distance * Math.cos(angle));
currentChild.y = player.y + (distance * Math.sin(angle));
}
}
In order to rotate around a certain centerpoint, you first translate by (-centerpoint.x,-centerpoint.y), then rotate around (0,0) and then translate back by (centerpoint.x,centerpoint.y).