Preloader animation not working - actionscript-3

I was making a preloader for my game I exported my movieclips to the frame 2 except those which are related to the preloader graphics In my Frame 1 i have this code
import flash.events.ProgressEvent;
stop();
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS , onProgress);
function onProgress(e:ProgressEvent):void
{
progbar.width = (this.loaderInfo.bytesLoaded / this.loaderInfo.bytesTotal) * 398;
jot.x = progbar.x + progbar.width; //jot is the name of loader label it moves with the
jot.y = progbar.y; //end point of progbar
jot.loadtext.text = String(Math.round(progbar.width / 398 * 100)) + " %"; // labale has text inside it
if (this.loaderInfo.bytesLoaded == this.loaderInfo.bytesTotal)
{
gotoAndStop(2);
}
}
and At the point where the bar has reach at any given time I wanted to put a bubbling effect for which i amde a class Spark
this is how my spark class looks like
public class Spark extends MovieClip
{
private var pl:Array = new Array();
private var t:int = 0;
public function Spark()
{
this.addEventListener(Event.ENTER_FRAME , onEnter);
}
private var l:int = 0;
private var i:int = 0;
private function onEnter(e:Event)
{
t++;
if (t == 2)
{
t = 0;
var p:P = new P(); // P is the single particle
addChild(p);
pl.push(p); // pl is the array to hold particles
p.width = Math.random() * 20 + 5;
p.height = p.width;
p.vx = Math.random() * 4 - 2;
p.vy = Math.random() * 4 - 2;
}
l = pl.length; //storing length of array to save performance
for (i=0; i< l; i++)
{
pl[i].alpha -= 0.05;
pl[i].y += pl[i].vy;
pl[i].x += pl[i].vx;
}
//removeing completely transparent particles
for (i=0; i< l; i++)
{
if (pl[i].alpha < 0.02)
{
removeChild(pl[i]);
pl.splice(i,1);
break;
}
}
}
}
in the first frame Spark Instance to the stage and added code for its alignment with the progbar
but nothing happened only the bar was going but bubbles were not coming out from its end.
I tried checking and unchecking the spark class "export in frame 2"
I hav named the dragged instance of class Spark as spark1
and when i added this code to frame 1 i am surpirised
if(spark1 != null)
{
trace("its fine");
} else {
trace("something weird");
}
and i got the else statement being traced out. How is that possible

I found the solution
I went to File > Action-script setting.
there int the text field named as export classes in frame ___ .I put there 1 which i was previously having 2
Then unchecked Export to frame 1 FOR ONLY THOSE SYMBOLS WHICH WERE PART OF THE PRELOADER
then ran the movie it worked

Related

How to change MovieClip transparency based on mouse position?

So, I'm trying to make a grid of rectangles each get more transparent the closer the mouse is to it.
Using some basic maths, I thought I had got it, but instead it seems I got a weird graphic bug(maybe?) shown here:
The middle of the rings is where the mouse is.
Part of code that deals with transparency:
private function update(e:Event = null):void
{
for (var i:int = 0; i < buttons.length; i++) {
lightFact = getDistance(buttons[i])
lightBrightness = lightPower - (lightFact * 10)
buttons[i].alpha = lightBrightness
}
}
getDistance is just getting distance from the block to the mouse.
Each rectangle is a movie clip, if that matters.
If you are trying to do this:
Then I think your problem is basically that your alpha value is ranging from 0 to about 3000 or something like that. That's going to cause strange effects. The value needs to range smoothly from 0 to 1 (so it needs to be a floating point number as in Number).
Here is the code which generated the image above which I wrote for you that will get you started in the right direction:
package
{
import flash.display.*;
import flash.events.*;
public class lightFactTest extends MovieClip
{
private var boxesArray: Array = new Array();
private var xDist: Number = 0;
private var yDist: Number = 0;
private var d: Number = 0;
private var size_Glow : Number = 0;
private var size_Radius : Number = 0;
public function lightFactTest(): void
{
// creates a background for rectangles array.
var BG_box: Sprite = new Sprite();
BG_box.graphics.lineStyle();
BG_box.graphics.beginFill(0x080839);
BG_box.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
BG_box.graphics.endFill();
addChild(BG_box);
//# creates a grid of sprites (rectangles).
for (var i:int = 0; i < (stage.stageWidth / 10); i++)
{
for (var j:int = 0; j < (stage.stageHeight / 10); j++)
{
var box: Sprite = new Sprite();
box.graphics.lineStyle();
box.graphics.beginFill(0xFFFFFF);
box.graphics.drawRect(0, 0, 10, 10);
box.graphics.endFill();
addChild(box);
box.x += i*10; //+ 50;
box.y += j*10; //+ 50;
boxesArray.push(box);
}
}
addEventListener(Event.ENTER_FRAME, lightCalc);
}
private function lightCalc(e: Event): void
{
size_Glow = 3.5;
size_Radius = 0.64;
//# iterates through the array calculating each distance and then alpha.
for (var i:int = 0; i < boxesArray.length; i++)
{
xDist = Math.abs(stage.mouseX - boxesArray[i].x);
yDist = Math.abs(stage.mouseY - boxesArray[i].y);
//var d: Number = Math.pow(xDist * xDist + yDist * yDist, 0.5);
d = Math.sqrt(xDist * xDist + yDist * yDist) / (size_Radius / 5);
//# This is the code that you really need to focus on...
boxesArray[i].alpha = Math.min(1 / d * 10, 1 ) * (Math.PI / 0.5 - Math.min(size_Radius, 0) ) * size_Glow;
}
}
}
}
Hope that helps!

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.

ActionScript 3 Looping

I just started using Looping in AS3 recently and I have much to learn. here is the question. Below is a Loop that puts 5 balls one on top of the other on the stage. So far so good. however, I'd like to create a situation when clicking on a button, the bottom ball is removed, and then each ball take the place of the ball below it one by one, continue this for each click until all the balls are gone. . I have created this situation with add/remove child and I thought it could be more efficient with looping. I just don't know how to access the balls since I don't have instance name or class name that I can reference too.
var ball: gBall4M;
var i: Number;
for (i = 0; i < 5; i++) {
ball = new gBall4M();
ball.x = 331.30;
ball.y = 25 + i * 17
addChild(ball);
}
function release2Ball2(event: MouseEvent): void {
This is the effect I want to get https://youtu.be/B4GLolw8QVA
As mentioned in the answer of #daniel-messer, you can use an Array to store your balls, and for the second part of your question, when removing the last ball and moving the other ones, you can use array.pop() to remove the last element of the array, and then you can use array.map() to move the other balls :
function release2Ball2(event:MouseEvent): void
{
if(balls.length > 0){
ball = balls.pop(); // remove and get the last element of the array
ball.parent.removeChild(ball); // remove that element from the DisplayObjectContainer
function move_ball(item:Ball, index:int, array:Array):void {
item.y += 17;
}
// move the rest of elements
balls.map(move_ball, this);
}
}
EDIT :
Take a look on the code working, I added numbers to understand how balls are moving :
Your full code can be like this :
var balls:Array = [],
ball:gBall4M;
for (var i:int = 0; i < 5; i++) {
ball = new gBall4M();
ball.x = 331.30;
ball.y = 25 + i * 17;
balls.push(ball);
addChild(ball);
}
btn.addEventListener(MouseEvent.CLICK, release2Ball2);
function release2Ball2(event:MouseEvent):void {
if (balls.length > 0) {
ball = balls.pop();
ball.parent.removeChild(ball);
function move_ball(item:gBall4M, index:int, array:Array):void {
item.y += 17;
}
balls.map(move_ball, this);
}
}
EDIT 2:
To do that kind of animation, you can use a Timer like this :
var balls:Array = [],
ball:gBall4M;
for (var i:int = 0; i < 5; i++) {
ball = new gBall4M();
ball.x = 30;
ball.y = 25 + i * 17;
balls.push(ball);
addChild(ball);
}
btn.addEventListener(MouseEvent.CLICK, release2Ball2);
function release2Ball2(event:MouseEvent):void {
if (balls.length > 0) {
ball = balls.pop();
ball.parent.removeChild(ball);
if(balls.length > 0){
timer.start();
}
}
}
var timer:Timer = new Timer(150);
timer.addEventListener(TimerEvent.TIMER, function(e:TimerEvent){
if(balls.length >= timer.currentCount){
balls[balls.length - timer.currentCount].y += 17;
} else {
timer.reset();
}
})
Which will give you something like this :
Hope that can help.
Just save the instances inside an array or similar that you can use later.
I hope you are using a code file and not writing the code directly inside a frame inside the flash editor. Otherwise you might end up with issues.
Something similar to this should work
package {
class Main {
var balls:Array = [];
function createBalls() {
var ball: gBall4M;
var i: Number;
for (i = 0; i < 5; i++) {
ball = new gBall4M();
ball.x = 331.30;
ball.y = 25 + i * 17;
balls.push(ball); //Save them to array
addChild(ball);
}
}
function release2Ball2(event: MouseEvent): void {
var clickedBall:gBall4M = event.currentTarget as gBall4M; //this might be wrong depending on what you are listening for, and what type of object gBall4M is...
for(var i=0; i<balls.length; ++i) {
if(balls[i] == clickedBall) {
balls[i].splice(i, 1); //remove instance from array
removeChild(clickedBall); //remove instance from display list
break;
}
}
}
}
}
OK I figured it out. using this code on frame 1
function release2Ball2(event: MouseEvent): void {
if (ballA.length > 0) {
ball = ballA.pop();
removeChild(ball);
ball = null
gotoAndPlay(2);
}
}
stop();
using this code on frame 10:
for (i = 0; i < ballA.length; i++) {
ballA[i].y += 17;
stop();
That does the trick.
Thank you so much for your help

how to make this road not scale itself.And make equally big portion(like size big) sections of the road

Im currently trying to make a road movement animation but cant figure how the road must not scale itself.
The whole code isn`t mine it is from a tutorial ,I just tried to modify it to my needs ,but I cant do the part that the road should move like if Im seeing it from above(bird view) ,at always same speed.
currently i have this swf file
http://www.stouchgames.com/APKs/Road.swf
I dont want it to be like little lines in the top and then in the bottom a big line that moves.I just want to be equally Big lines that move from top to bottom.
So far i have a simple movieClip with 2 frames and the frames have the graphics in this picture:
http://stouchgames.com/APKs/road.jpg
and this code :
package {
import flash.display.MovieClip;
import flash.events.Event;
public class Main extends MovieClip {
//Depth of the visible road
private const roadLines:int = 320;
//Dimensions of the play area.
private const resX:int = 480;
private const resY:int = 320;
//Line of the player's car.
private const noScaleLine:int = 8;
//All the road lines will be accessed from an Array.
private var yMap:Array = [];
private var lines:Array = [];
private var halfWidth:Number;
private var lineDepth:int;
private const widthStep:Number = 0;
private var playerY:Number;
private var speed:int = 2;
private var texOffset:int = 100;
public function Main() {
//Populate the zMap with the depth of the road lines
for (var i:int = 0; i < roadLines; i++) {
yMap.push(1 / (i - resY));
}
playerY = 100 / yMap[noScaleLine];
for (i = 0; i < roadLines; i++) {
yMap[i] *= playerY;
}
//Make the line at the bottom to be in front of the rest,
//and add every line at the same position, bottom first.
lineDepth = numChildren;
for (i = 0; i < roadLines; i++) {
var line = new Road();
lines.push(line);
addChildAt(line, lineDepth);
line.x = resX / 2;
line.y = resY - i;
}
//Scaling the road lines according to their position
addEventListener(Event.ENTER_FRAME, race);
}
private function race(event:Event):void {
for (var i:int = 0; i < roadLines; i++) {
if ((yMap[i] + texOffset) % 100 > 50) {
lines[i].gotoAndStop(1);
} else {
lines[i].gotoAndStop(2);
}
}
texOffset = texOffset + speed;
while (texOffset >= 100) {
texOffset -= 100;
}
}
}
}
i did try to just make just 2 road movieClips with the different graphics ,then use a
for (var i:int = 0; i < 8; i++) {
if (((i % 2) == 0)) {
var line = new Road ;
lines.push(line);
addChildAt(line,lineDepth);
line.x = resX / 2;
line.y = resY - i * 50;
line.alpha = .2;
}
if (((i % 2) == 1)) {
var line = new Road2 ;
lines.push(line);
addChildAt(line,lineDepth);
line.x = resX / 2;
line.y = resY - i * 50;
line.alpha = .5;
}
but then when i get in the Event.EVERY frame function i cant make them move smoothly ... and decided it must be done by the 1st way cause of the much more detailed ending and cause in the end if i want to change the resolutions of the road i can do it much easier with it . Ofcourse i could be wrong cause i haven`t done such a thing like this before.
So can someone help ?
replace yMap[i] with i in race function:
for (var i:int = 0; i < roadLines; i++) {
if ((i + texOffset) % 100 > 50) {
lines[i].gotoAndStop(1);
} else {
lines[i].gotoAndStop(2);
}
}

Remove all Instance on stage as3

Im having trouble on removing instances on the stage.
The error I keep getting after I click the button 2 times is
"The supplied DisplayObject must be a child of the caller"
Can somebody help me with this?
package src
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
public class Main extends MovieClip
{
var positionY:Number = 80;
var positionX:Number = 0;
var motion:MovieClip;
var fCombo:Array = new Array();
var n:Number;
public function Main()
{
generate.addEventListener(MouseEvent.MOUSE_UP, loop);
generate.addEventListener(MouseEvent.MOUSE_DOWN, remove);
n = Number(inputText.text);
}
function loop(me:MouseEvent):void
{
var combo:Array = [Punch, Kick, Knee, Elbow];
n = Number(inputText.text);
for(var i:Number = 0;i < n;i++ )
{
motion = new combo[randomNumber(4)]();
fCombo.push(motion);
motion.y = positionY;
motion.x = positionX;
positionX += 100;
addChild(motion);
if (i == 4 || i == 9 || i == 14)
{
positionY += 40;
positionX = 0;
}
}
}
function remove(me:MouseEvent):void
{
for (var j:Number = 0; j < n; j++ )
{
removeChild(fCombo[j]);//error
}
positionY = 80;
positionX = 0;
}
function randomNumber(max:Number):Number
{
return(Math.floor(Math.random() * max ));
}
}
}
You're adding the new objects you create to the array, and then using that to remove them. But you're forgetting to either create a new list or remove the objects from the old list. So, when time comes to loop over the list you're trying to remove objects that have already been removed.
You can fix this in several ways, one is to remove objects from the stage AND array in your loop:
function remove(me:MouseEvent):void
{
while(fCombo.length)
{
removeChild(fCombo.pop());
}
positionY = 80;
positionX = 0;
}
targetDisplayObject.parent.removeChild( targetDisplayObject ); does the trick assuming the parent is not null.