as3 move object back and forth on iPad or tablet - actionscript-3

I am working on a 2d project for iPad where a ball moves back and forth. When it hits the border it has to rotate a bit and roll back in another direction and leaving a child behind that also starts to move and follows a random path. (I made the project in Scratch. See code.)
ball_mc.addEventListener(Event.ENTER_FRAME, moveBall);
function moveBall(e:Event):void {
ball_mc.rotation += 1;
if (ball_mc.x < (stage.stageWidth - 100)) {
//trace('move forward');
ball_mc.x += 2;
} else {
// while(ball_mc.x > 100)?
// trace('move backward');
// how does it roll back?
ball_mc.x += -2;
}
}
}

You need a variable that holds the value of the direction or velocity. This variable should be changed to 2 if the ball passes a left side boundary and changed to -2 if the ball passes a right side boundary. Like this:
var ballSpeed:Number = 0; // this should go where you declare global variables such as at the beginning of your main class before the constructor
ball_mc.addEventListener(Event.ENTER_FRAME, moveBall);
function moveBall(e:Event):void {
ball_mc.rotation += ballSpeed;
if (ball_mc.x < (stage.stageWidth - 100)) {
ballSpeed = 2;
} else if (ball_mc.x > stage.stageWidth){
ballSpeed = -2;
}

Related

Moving away object when hit each other

I don't wanna to overlap each other the objects.Also I wanna keep the objects in stage limit.The buttons must move away when hit each other.I tried hitTestObject but buttons move like this.
Sample move code for fish 2 *UPDATE
var fish2x:Number=10;
var fish2y:Number=14;
 
stage.addEventListener(Event.ENTER_FRAME,h42);
function h42(s:Event = null) {
fish2.x+=fish2x;
fish2.y+=fish2y;
if ((fish2.x>=stage.stageWidth-fish2.width/2)|| (fish2.x <= fish2.width/2 )) {
fish2x*=-1;
}
if ((fish2.y>=stage.stageHeight-fish2.height/2)|| (fish2.y <= fish2.height/2 )) {
fish2y*=-1;
}
if (fish2.hitTestObject(fish3)){
fish2y *= -1;
fish3y *= -1;
h42();
}
}
Also I tried in diffrent function
stage.addEventListener(Event.ENTER_FRAME,crash);
function crash(s:Event) {
 
if (fish2.hitTestObject(fish || fish3 )) {
fish2y*=-1;
message.text="crash";
}
}
For more than 2 fish not work.
I set null fish2 and fish 3 than I use this code.
if (fish2.hitTestObject(fish3 || fish4)){
fish2y *= -1;
fish2x *= -1;
h42();
}
I changed hittestoject all off them.All function change like this but it not work.
Update 2
Now it's no error,but not happens when fish3 hit each other.I removed "null" fish and fish 3 just used for fish 2.
if (fish2.hitTestObject(fish || fsih3)){
fish2y *= -1;
fish2x *= -1;
fishy*=-1;
fishx*=-1;
fish3y*=-1;
fish3x*=-1;
}
}
I think it is because they are both moving. When you check collisions between A and B Fishes, if the collision is true, don't just change their speed by *=-1. Instead, also move them one time.
if (A.hitTestObject(B)){
Ay *= -1;
Ax *= -1;
By *= -1;
Bx *= -1;
h42();
}
and add null to your default value like this:
function h42(s:Event = null) {

How can I code an object to spawn onto the stage in the Actions panel?

I am trying to introduce a new ball into my pong game, sort of like a power up. I am writing all of my code in the Actions panel in the first frame. The new ball should appear on the stage and start moving around randomly like the original ball. Although I am using a code snippet and not .as file. So all of my code is in the Actions panel(Accessed by pressing f9).
I would also like my dynamic text box to merge with the stage colour so that you can't see the white background.
I can't show you what the fla looks like because I have less than 10 reputation, but the dynamic text box will not merge into the background and instead has a white surrounding. This hides the ball when the ball goes up.
import flash.events.Event;
import flash.ui.Mouse;
//hide mouse
Mouse.hide();
init(); //initialises everything
var bSpeedX:int = -3.5;
var bSpeedY:int = -2.5;
// assign a maximum speed to the AI
var compPaddleSpeed:int = 3.5;
var pScore:int = 0;
var cScore:int = 0;
// Updates the score
function scoreUpdate():void {
playerScore.text = ("Player Score: " + pScore);
computerScore.text = ("AI Score: " + cScore);
}
function init():void //tells flash not to return values
{
stage.addEventListener(Event.ENTER_FRAME, loop);
}
/*we want the ySpeed to be larger if there
is a greater difference between the y
positions of the ball and paddle, so I started with
(gameBallY-padY). To convert this difference
into a number between -1 and 1, I divided
this number by 25, which
is half the height of the paddle. Finally, I wanted
the ySpeed to be more powerful than
just -1 to 1, and after a bit of trial and error
I decided to times by 5 at the end
to change the total magnitude of the new ySpeed.*/
//defying the laws of Physics
function calculategameBallAngle(padY:Number, gameBallY:Number):Number
{
var ySpeed:Number = 5 * ((gameBallY-padY) / 25 );
return ySpeed;
}
//main loop
function loop(e:Event):void
{
//makes the paddle track the mouse
playerPaddle.y = mouseY;
//paddle AI
if(compPaddle.y < gameBall.y - 10){
compPaddle.y += compPaddleSpeed;//make it go up
} else if(compPaddle.y > gameBall.y + 10){
compPaddle.y -= compPaddleSpeed;//make it go down
}
//Collisions
if( playerPaddle.hitTestObject(gameBall) == true ){
if(bSpeedX < 0){
bSpeedX *= -1;
bSpeedY = calculategameBallAngle(playerPaddle.y, gameBall.y);
}
} else if(compPaddle.hitTestObject(gameBall) == true ){
if(bSpeedX > 0){
bSpeedX *= -1;
bSpeedY = calculategameBallAngle(compPaddle.y, gameBall.y);
}
}
//makes the gameBall move
gameBall.x += bSpeedX; //each frame, we add the bSpeedX to the ball's x position.
gameBall.y += bSpeedY; //same for the bSpeedY to the ball's y postion.
// checks to see if the ball misses the paddle
if(gameBall.x <= gameBall.width/2){
gameBall.x = gameBall.width/2;
bSpeedX *= -1;
cScore ++;
scoreUpdate();
//keeps the ball within the stage
} else if(gameBall.x >= stage.stageWidth-gameBall.width/2){
gameBall.x = stage.stageWidth-gameBall.width/2;
bSpeedX *= -1;
pScore ++;
scoreUpdate();
}
if(gameBall.y <= gameBall.height/2){
gameBall.y = gameBall.height/2;
bSpeedY *= -1;
}
else if(gameBall.y >= stage.stageHeight-gameBall.height/2){
gameBall.y = stage.stageHeight-gameBall.height/2;
bSpeedY *= -1;
}
//-------------------------------------------------------
//keeps the player paddle within the stage
//check if paddle is above top of the screen
if(playerPaddle.y - playerPaddle.height/2 < 0){
playerPaddle.y = playerPaddle.height/2;
} else if(playerPaddle.y + playerPaddle.hieght/2 > stage.stageHeight){
playerPaddle.y = stage.stageHeight - playerPaddle.height/2;
//check if paddle is below bottom of the screen
} else if(playerPaddle.y + playerPaddle.height/2 > stage.stageHeight){
playerPaddle.y = stage.stageHeight - playerPaddle.height/2;
}
}
If you only want your ball to be replaced with new one which has diffrent grphics and/or speed you can for example export your ball class to action script:
Library>RMB on your symbol>Properties>ActionScript Linkage>Export for ActionScript
Type your class name under Class: field like "MyBallClass" and hit OK.
Now you can construct this ball in your code and replace old one like this:
var newBall:MyBallClass = new MyBallClass();
addChild(newBall);
newBall.x = gameBall.x; newBall.y = gameBall.y;
gameBall = newBall;
Additionally you can define new variable like var speedModifier:Number = 1; to use with:
gameBall.x += bSpeedX * speedModifier;
gameBall.y += bSpeedY * speedModifier;
And change that also when you change the ball.
If You want to have multiple balls at same time You really should consider build this in OOP. For simplest example in addition to previous one
You can create MyBallClass.as file and write in it something like:
package
{
import flash.display.Sprite;
import flash.geom.Point;
public class MyBallClass extends Sprite
{
public var speedFactor:Number;
public var speed:Point = new Point(-3.5, -2.5);
public function MyBallClass(x:Number, y:Number, speedFactor:Number = 1)
{
this.x = x; this.y = y;
this.speed = speed;
}
}
}
Now you can create container for all the balls in yor game.
var balls:Vector<MyBallClass> = Vector<MyBallClass>([]);
and run your physics for all of them in a loop.
Generally main code would look something like this:
var balls:Vector.<MyBallClass> = Vector.<MyBallClass>([]);
addBall(...)//place first ball.
function loop(e:Event):void {
processBalls();
if(wantToAddNewSuperSpeedBall) addBall(x,y,3);
...
}
function processBalls() {
for (var i:int = 0; i < balls.length; i++) {
detecCollision(balls[i]);
moveBall(balls[i]);
//any code that process a single ball...
}
}
function addBall(x:Number, y:Number, speedFactor:Number = 1) {
var newBall:MyBallClass = new MyBallClass(x,y, speedFactor);
addChild(newBall);
balls.push(newBall);
}
function moveBall(ball:MyBallClass) {
ball.x += ball.speed.x * ball.speedFactor;
ball.y += ball.speed.y * ball.speedFactor;
}
So you should modify all functions which affect ball behavior to work with ball passed as argument, not only one specific instance and then use them for all balls.
There are more to cover in this topic and this isn't maybe the best approach but I've tried to make it easy to understend. There a lot of guides for OOP so you can get better idea about what is going on if you read them.
I hope that helped you somehow.

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

Flash (AS3) Movieclip Rotation

if (rotCW)
{
tramp1.rotation += 3;
if (tramp1.rotation = 90){
tramp1.rotation += 0;
}
}
I'm trying to make it so that if the movieclip's rotation is 90, its rotation speed is 0.
But every time I press the ' key (which triggers rotCW), the movieclip's rotation just goes to 90.
your problem is assignment within the 2nd condition. you need to use "=="
if (rotCW)
{
tramp1.rotation += 3;
if (tramp1.rotation == 90){
tramp1.rotation += 0;
}
}
edit: the +=3 line you have executes regardless of angle. if you are passing 90 and dont want to, you can test for the opposite condition and increment in that case. eg: if less than 90.
if (rotCW)
{
if (tramp1.rotation < 90){
tramp1.rotation += 3;
}
}

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).