This question is related to ActionScript 3.0 and Flash CS6
I am trying to make an object shake a bit in a certain for some seconds. I made it a "movieclip" and made this code:
import flash.events.TimerEvent;
var Machine_mc:Array = new Array();
var fl_machineshaking:Timer = new Timer(1000, 10);
fl_machineshaking.addEventListener (TimerEvent.TIMER, fl_shakemachine);
fl_machineshaking.start ();
function fl_shakemachine (event:TimerEvent):void {
for (var i = 0; i < 20; i++) {
Machine.x += Math.random() * 6 - 4;
Machine.y += Math.random() * 6 - 4;
}
}
When testing the movie I get multiple errors looking exactly like this one:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Historieoppgave_fla::MainTimeline/fl_shakemachine()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
Also, the object doesnt shake, but it moves steadily upwards to the left a bit every tick.
To the point:
I wish to know how I stop the script after the object is not in the stage/scene anymore and also how to make it shake around, as I do not see what is wrong with my script, please help, thank you ^_^
AStupidNube brought up a great point about the original position. So adding that to shaking that should be a back and forth motion, so don't rely on random values that may or may not get you what you want. Shaking also has a dampening effect over time, so try something like this:
Link to working code
• http://wonderfl.net/c/eB1E - Event.ENTER_FRAME based
• http://wonderfl.net/c/hJJl - Timer Based
• http://wonderfl.net/c/chYC - Event.ENTER_FRAME based with extra randomness
**1 to 20 shaking items Timer Based code - see link above for ENTER_FRAME code••
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.text.TextField;
import flash.utils.Timer;
public class testing extends Sprite {
private var shakeButton:Sprite;
private var graphic:Sprite;
private var shakerPos:Array;
private var shakers:Array;
private var numShakers:int = 20;
private var dir:int = 1;
private var displacement:Number = 10;
private var shakeTimer:Timer;
public function testing() {
this.shakers = new Array();
this.shakerPos = new Array();
this.addEventListener(Event.ADDED_TO_STAGE, this.init);
}
private function init(e:Event):void {
this.stage.frameRate = 30;
this.shakeTimer = new Timer(33, 20);
this.shakeTimer.addEventListener(TimerEvent.TIMER, this.shake);
this.graphics.beginFill(0x333333);
this.graphics.drawRect(0,0,this.stage.stageWidth, this.stage.stageHeight);
this.graphics.endFill();
this.createShakers();
this.shakeButton = this.createSpriteButton("Shake ");
this.addChild(this.shakeButton);
this.shakeButton.x = 10;
this.shakeButton.y = 10;
this.shakeButton.addEventListener(MouseEvent.CLICK, this.shakeCallback);
}
private function createSpriteButton(btnName:String):Sprite {
var sBtn:Sprite = new Sprite();
sBtn.name = btnName;
sBtn.graphics.beginFill(0xFFFFFF);
sBtn.graphics.drawRoundRect(0,0,80,20,5);
var sBtnTF:TextField = new TextField();
sBtn.addChild(sBtnTF);
sBtnTF.text = btnName;
sBtnTF.x = 5;
sBtnTF.y = 3;
sBtnTF.selectable = false;
sBtn.alpha = .5;
sBtn.addEventListener(MouseEvent.MOUSE_OVER, function(e:Event):void { sBtn.alpha = 1 });
sBtn.addEventListener(MouseEvent.MOUSE_OUT, function(e:Event):void { sBtn.alpha = .5 });
return sBtn;
}
private function createShakers():void {
var graphic:Sprite;
for(var i:int = 0;i < this.numShakers;i++) {
graphic = new Sprite();
this.addChild(graphic);
graphic.graphics.beginFill(0xFFFFFF);
graphic.graphics.drawRect(0,0,10,10);
graphic.graphics.endFill();
// add a 30 pixel margin for the graphic
graphic.x = (this.stage.stageWidth-60)*Math.random()+30;
graphic.y = (this.stage.stageWidth-60)*Math.random()+30;
this.shakers[i] = graphic;
this.shakerPos[i] = new Point(graphic.x, graphic.y);
}
}
private function shakeCallback(e:Event):void {
this.shakeTimer.reset();
this.shakeTimer.start();
}
private function shake(e:TimerEvent):void {
this.dir *= -1;
var dampening:Number = (20 - e.target.currentCount)/20;
for(var i:int = 0;i < this.numShakers;i++) {
this.shakers[i].x = this.shakerPos[i].x + Math.random()*10*dir*dampening;
this.shakers[i].y = this.shakerPos[i].y + Math.random()*10*dir*dampening;
}
}
}
}
Now this is a linear dampening, you can adjust as you see fit by squaring or cubing the values.
You have to remember the original start position and calculate the shake effect from that point. This is my shake effect for MovieClips. It dynamically adds 3 variables (startPosition, shakeTime, maxShakeAmount) to it. If you use classes, you would add them to your clips.
import flash.display.MovieClip;
import flash.geom.Point;
function shake(mc:MovieClip, frames:int = 10, maxShakeAmount:int = 30) : void
{
if (!mc._shakeTime || mc._shakeTime <= 0)
{
mc.startPosition = new Point(mc.x, mc.y);
mc._shakeTime = frames;
mc._maxShakeAmount = maxShakeAmount;
mc.addEventListener(Event.ENTER_FRAME, handleShakeEnterFrame);
}
else
{
mc.startPosition = new Point(mc.x, mc.y);
mc._shakeTime += frames;
mc._maxShakeAmount = maxShakeAmount;
}
}
function handleShakeEnterFrame(event:Event):void
{
var mc:MovieClip = MovieClip(event.currentTarget);
var shakeAmount:Number = Math.min(mc._maxShakeAmount, mc._shakeTime);
mc.x = mc.startPosition.x + (-shakeAmount / 2 + Math.random() * shakeAmount);
mc.y = mc.startPosition.y + (-shakeAmount / 2 + Math.random() * shakeAmount);
mc._shakeTime--;
if (mc._shakeTime <= 0)
{
mc._shakeTime = 0;
mc.removeEventListener(Event.ENTER_FRAME, handleShakeEnterFrame);
}
}
You can use it like this:
// shake for 100 frames, with max distance of 15px
this.shake(myMc, 100, 15);
BTW: In Flash, you should enable 'permit debugging' in your 'publish settings' to have more detailed errors. This also gives back the line numbers where your code is breaking.
update:
Code now with time / maximum distance separated.
Here is a forked version of the chosen answer, but is a bit more flexible in that it allows you to set the frequency as well. It's also based on time as opposed to frames so you can think in terms of time(ms) as opposed to frames when setting the duration and interval.
The usage is similar to the chosen answer :
shake (clipToShake, durationInMilliseconds, frequencyInMilliseconds, maxShakeRange);
This is just an example of what I meant by using a TimerEvent as opposed to a ENTER_FRAME. It also doesn't require adding dynamic variables to the MovieClips you are shaking to track time, shakeAmount, and starting position.
public function shake(shakeClip:MovieClip, duration:Number = 3000, frequency:Number = 30, distance:Number = 30):void
{
var shakes:int = duration / frequency;
var shakeTimer:Timer = new Timer(frequency, shakes);
var startX:Number = shakeClip.x;
var startY:Number = shakeClip.y;
var shakeUpdate:Function = function(e:TimerEvent):void
{
shakeClip.x = startX + ( -distance / 2 + Math.random() * distance);
shakeClip.y = startY + ( -distance / 2 + Math.random() * distance);
}
var shakeComplete:Function = function(e:TimerEvent):void
{
shakeClip.x = startX;
shakeClip.y = startY;
e.target.removeEventListener(TimerEvent.TIMER, shakeUpdate);
e.target.removeEventListener(TimerEvent.TIMER_COMPLETE, shakeComplete);
}
shakeTimer.addEventListener(TimerEvent.TIMER, shakeUpdate);
shakeTimer.addEventListener(TimerEvent.TIMER_COMPLETE, shakeComplete);
shakeTimer.start();
}
-4 <= Math.random() * 6 - 4 < 2
You add this offset to Machine.x 20 times, so chances for moving to the left is greater, than to the right.
It seems that you looking for something like this:
for each (var currentMachine:MovieClip in Machine_mc)
{
currentMachine.x += Math.random() * 6 - 3;
currentMachine.y += Math.random() * 6 - 3;
}
Related
I’m trying to make a simple game that uses a basic equation:
‘linkCount’ / ‘clickCount’ * 100 to create a % success amount, ‘percentCount’
The text fields and the following as3 all live in a Movieclip on root level with instance name ‘counter_int’:
as3:
var clickCount:int = 1; //see below* for what controls this number
var linkCount:int = 1; //see below* for what controls this number
var percentCount:int = (100);
percentCount++;
percent_text.text = (int(linkCount) / int(clickCount) * 100 + "%").toString();
This works fine and displays a % amount in the correct field. However, my question is about truncating the % I get to remove anything after the decimal place. I’ve tried everything I can to get this to work but it’s not having it.
*
Now, here’s the tricky bit that i think is possibly causing my Math.round problem… I basically just don’t know where or how to apply the Math.round instruction?! I also suspect it might be a problem with using ‘int’ and have tried using ‘Number’ but it still displays decimal places.
I am using 2 buttons within 25 different movieclips…
Button locations:
all_int_circles_master.cone.FAILlinkbutton
all_int_circles_master.cone.linkbutton
all_int_circles_master.ctwo.FAILlinkbutton
all_int_circles_master.ctwo.linkbutton
etc … to ctwentyfive
The as3 on FAIL buttons:
FAILlinkbutton.addEventListener(MouseEvent.CLICK, addClick1);
function addClick1(event:MouseEvent):void
{
Object(root).counter_int.clickCount++;
Object(this.parent.parent).counter_int.clicked_total.text = Object(root).counter_int.clickCount.toString();
}
The as3 on successful link buttons:
linkbutton.addEventListener(MouseEvent.CLICK, onClickNextSlide2);
function onClickNextSlide2(event:MouseEvent):void
{
Object(root).counter_int.clickCount++;
Object(this.parent.parent).counter_int.clicked_total.text = Object(root).counter_int.clickCount.toString();
}
The % currently gets returned as e.g.:
74.334753434
but I need it to just be:
74
Any help would be greatly appreciated. I can supply the .fla if necessary. This is kind of what I've been trying but no luck so far:
should the Math.round be applied at root level / globally somehow!?
should the Math.round be applied within the counter_int movieclip?
should the Math.round be applied within all of the all_int_circles_master.cone / two / three... movieclips?
Thanks
Have you tried
percent_text.text = (Math.round(int(linkCount) / int(clickCount) * 100) + "%").toString();
percent_text.text = (int(linkCount) / int(clickCount) * 100 +
"%").toString();
I think you have your clickCount and linkCount backwards, swap those and round the results before adding the percent symbol:
percent_text.text = (Math.round((int(clickCount) / int(linkCount) * 100)).toString() + "%";
A pure AS3 example:
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.MouseEvent;
public class Main extends Sprite {
var clickCount:int = 0;
var linkCount:int = 30;
var clicked_total:TextField;
var button:CustomSimpleButton;
public function Main() {
button = new CustomSimpleButton();
button.addEventListener(MouseEvent.CLICK, onClickNextSlide2);
addChild(button);
clicked_total = new TextField();
clicked_total.text = "0%";
clicked_total.x = 100;
addChild(clicked_total);
}
function onClickNextSlide2(event:MouseEvent):void {
clickCount++;
if (clickCount < linkCount) {
clicked_total.text = (Math.round((clickCount / linkCount) * 100)).toString() + "%";
} else {
clicked_total.text = "Done";
}
}
}
}
import flash.display.Shape;
import flash.display.SimpleButton;
class CustomSimpleButton extends SimpleButton {
private var upColor:uint = 0xFFCC00;
private var overColor:uint = 0xCCFF00;
private var downColor:uint = 0x00CCFF;
private var size:uint = 80;
public function CustomSimpleButton() {
downState = new ButtonDisplayState(downColor, size);
overState = new ButtonDisplayState(overColor, size);
upState = new ButtonDisplayState(upColor, size);
hitTestState = new ButtonDisplayState(upColor, size * 2);
hitTestState.x = -(size / 4);
hitTestState.y = hitTestState.x;
useHandCursor = true;
}
}
class ButtonDisplayState extends Shape {
private var bgColor:uint;
private var size:uint;
public function ButtonDisplayState(bgColor:uint, size:uint) {
this.bgColor = bgColor;
this.size = size;
draw();
}
private function draw():void {
graphics.beginFill(bgColor);
graphics.drawRect(0, 0, size, size);
graphics.endFill();
}
}
I'm currently trying to remove a graphic 'lose_mc' that i added to the scene using addChild.
When trying to use removeChild when the user clicks the next level_btn, this error appears:
TypeError: Error #2007: Parameter listener must be non-null.
at flash.events::EventDispatcher/removeEventListener()
at Function/<anonymous>()
Any one has any ideas of why this isn't working? This is my code at the minute.
**
import flash.net.URLRequest;
import flash.display.MovieClip;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.Event;
import flash.display.Loader;
stop();
//stage.removeEventListener(Event.ENTER_FRAME, nextButtonClick);
var hitObstacle:Boolean=false;
var points=2; //The points will be set at 2
points_txt.text=points.toString(); //Health will be displayed in points_txt box
var lose_mc = new lose();
var win_mc = new win();
//crowhit_mc.visible=false;
var loader:Loader = new Loader()
addChild(loader);
//var url:URLRequest = new URLRequest("test.swf");
//var lose_mc = new lose();
//var win_mc = new win();
//var hitObstacle:Boolean=false;
var leafArray:Array = new Array(leaf01,leaf02,leaf03);
var leafsOnstage:Array = new Array();
var leafsCollected:int = 0;
var leafsLost:int = 0;
for (var i:int = 0; i<20; i++) {
var pickLeaf = leafArray[int(Math.random() * leafArray.length)];
var leaf:MovieClip = new pickLeaf();
addChild(leaf);
leaf.x = Math.random() * stage.stageWidth-leaf.width;// fruit.width is subtracted from the random x position to elimate the slight possibility that a clip will be placed offstage on the right.
leaf.y = Math.random() * -500;
leaf.speed = Math.random() * 15 + 5;
leafsOnstage.push(leaf);
}
basket_mc.addEventListener(MouseEvent.MOUSE_DOWN, dragBasket);
stage.addEventListener(MouseEvent.MOUSE_UP, dragStop);
function dragBasket(e:Event):void {
basket_mc.startDrag();
}
function dragStop(e:Event):void {
basket_mc.stopDrag();
}
stage.addEventListener(Event.ENTER_FRAME, catchLeaf);
function catchLeaf(e:Event):void {
for (var i:int = leafsOnstage.length-1; i > -1; i--) {
var currentLeaf:MovieClip = leafsOnstage[i];
currentLeaf.y += currentLeaf.speed;
if (currentLeaf.y > stage.stageHeight - currentLeaf.height) {
currentLeaf.y = 0 - currentLeaf.height;
leafsLost++;
field2_txt.text = "Total Leaves Lost: " + leafsLost;
}
if (currentLeaf.hitTestObject(basket_mc)) {
leafsCollected++;
removeChild(currentLeaf);
leafsOnstage.splice(i,1);
field1_txt.text = "Total Leaves Collected: " + leafsCollected;
if (leafsCollected >= 20) {
basket_mc.gotoAndStop(20);
} else if (leafsCollected > 15) {
basket_mc.gotoAndStop(15);
} else if (leafsCollected>10) {
basket_mc.gotoAndStop(10);
} else if (leafsCollected>5) {
basket_mc.gotoAndStop(5);
}
}
}
if (leafsOnstage.length <= 0) {
field1_txt.text = "You Win! You have collected enough leaves for the day.";
nextlevel_btn.addEventListener(Event.ENTER_FRAME, fl_FadeSymbolINwin);
nextlevel_btn.alpha = 0;
function fl_FadeSymbolINwin(event:Event)
{
nextlevel_btn.alpha += 0.01;
if(nextlevel_btn.alpha >= 1)
{
nextlevel_btn.removeEventListener(Event.ENTER_FRAME, fl_FadeSymbolIn);
}
}
field2_txt.text = "";
stage.removeEventListener(Event.ENTER_FRAME, catchLeaf);
var win_mc = new win();
win_mc.x = 215.70;
win_mc.y = 163.25;
win_mc.w = 100;
win_mc.h = 145;
addChild(win_mc);
removeChild(crow_mc);
}
if (leafsLost >= 20) {
field1_txt.text = "Sorry you lose. You have lost too many leaves!";
restart_btn.addEventListener(Event.ENTER_FRAME, fl_FadeSymbolIn);
restart_btn.alpha = 0;
function fl_FadeSymbolIn(event:Event)
{
restart_btn.alpha += 0.01;
if(restart_btn.alpha >= 1)
{
restart_btn.removeEventListener(Event.ENTER_FRAME, fl_FadeSymbolIn);
}
}
field2_txt.text = "";
stage.removeEventListener(Event.ENTER_FRAME, catchLeaf);
for (var j:int = leafsOnstage.length-1; j > -1; j--) {
currentLeaf = leafsOnstage[j];
removeChild(currentLeaf);
leafsOnstage.splice(j,1);
lose_mc.x = 215.70;
lose_mc.y = 163.25;
lose_mc.w = 100;
lose_mc.h = 145;
addChild(lose_mc); //this is the movieclip in my library im adding it to the screen
}
}
}
//nextlevel_btn.addEventListener(MouseEvent.CLICK, nextButtonClick);
/*restart_btn.addEventListener(MouseEvent.CLICK, buttonClick)
function buttonClick(e:MouseEvent):void
{
try{
loader_mc.unloadAndStop();
} catch(e:Error) {
}
var urlRequest : URLRequest = new URLRequest("test.swf");
loader_mc.load(urlRequest);
removeChild(win_mc);
}
//function nextButtonClick(e:MouseEvent):void{
//removeChild(win_mc);
//loader.unloadAndStop();
//var request:URLRequest = new URLRequest("test.swf");
//loader.load(request);
crow_mc.addEventListener(MouseEvent.CLICK,rotateCrow);
function rotateCrow(e:MouseEvent):void {
crow_mc.rotation +=10;
var myTween:Tween = new Tween(crow_mc, "alpha", Strong.easeOut, 1,10,25, true);
}
*/
var crow_mcSpeedX:int = -6;
var crow_mcSpeedY:int = 2;
stage.addEventListener(Event.ENTER_FRAME, loop);
function loop(evt:Event) {
crow_mc.x += crow_mcSpeedX;
crow_mc.y += crow_mcSpeedY;
//because the ball's position is measured by where its CENTER is...
//...we need add or subtract half of its width or height to see if that SIDE is hitting a wall
//first check the left and right boundaries
if(crow_mc.x <= crow_mc.width/2){ //check if the x position of the left side of the ball is less than or equal to the left side of the screen, which would be 0
crow_mc.x = crow_mc.width/2; //then set the ball's x position to that point, in case it already moved off the screen
crow_mcSpeedX *= -1; //and multiply the ball's x speed by -1, which will make it move right instead of left
} else if(crow_mc.x >= stage.stageWidth-crow_mc.width/2){ //check to see the right side of the ball is touching the right boundary, which would be 550
crow_mc.x = stage.stageWidth-crow_mc.width/2; //reposition it, just in case
crow_mcSpeedX *= -1; //multiply the x speed by -1 (now moving left, not right)
}
//now we do the same with the top and bottom of the screen
if(crow_mc.y <= crow_mc.height/2){ //if the y position of the top of the ball is less than or equal to the top of the screen
crow_mc.y = crow_mc.height/2; //like we did before, set it to that y position...
crow_mcSpeedY *= -1; //...and reverse its y speed so that it is now going down instead of up
} else if(crow_mc.y >= stage.stageHeight-crow_mc.height/2){ //if the bottom of the ball is lower than the bottom of the screen
crow_mc.y = stage.stageHeight-crow_mc.height/2; //reposition it
crow_mcSpeedY *= -1; //and reverse its y speed so that it is moving up now
}
//}
//points--; //Health is decreased by 1 each time a trap_mc is clicked
//points_txt.text=points.toString();
//lose_mc.visible=true;
if (basket_mc.hitTestObject(crow_mc)) { //If the player_mc hits the sharkfin_mc
if (hitObstacle==false){ //Only subtract health if hitObstacle is false
trace("Hit Object")
//crow_mc.visible=false; //crow_mc becomes invisible
//removeChild(leaf);
//leafsOnstage.visable = false;
//lose_mc.x = 215.70;
//lose_mc.y = 163.25;
//lose_mc.w = 100;
//addChild(lose_mc);
points--; //Points are decreased by 1 each time crow_mc is hit - hittestobject()
points_txt.text=points.toString();
}
hitObstacle=true;
}
}
restart_btn.addEventListener(MouseEvent.CLICK, backButtonClick);
function backButtonClick(e:MouseEvent):void{
removeChild(lose_mc);
loader.unloadAndStop();
var request:URLRequest = new URLRequest("test.swf");
loader.load(request);
}
nextlevel_btn.addEventListener(MouseEvent.CLICK, nextButtonClick);
function nextButtonClick(e:MouseEvent):void{
loader.unloadAndStop();
var request:URLRequest = new URLRequest("snowflake.swf");
loader.load(request);
}
**
This is the area of code that is causing the problem..
**
nextlevel_btn.addEventListener(MouseEvent.CLICK, nextButtonClick);
function nextButtonClick(e:MouseEvent):void{
removeChild(win_mc);
loader.unloadAndStop();
var request:URLRequest = new URLRequest("snowflake.swf");
loader.load(request);
}
**
That is not the area causing the problem because Flash clearly says:
TypeError: Error #2007: Parameter listener must be non-null.
at flash.events::EventDispatcher/removeEventListener()
at Function/<anonymous>()
As we can see, the error is happening in removeEventListener.
removeEventListener takes two parameters: event and listener.
What we can also see, Flash says: parameter listener must be non-null.
That means that parameter listener passed to removeEventListener is null.
The part of your code that may cause the error is the following:
if (leafsOnstage.length <= 0) {
field1_txt.text = "You Win! You have collected enough leaves for the day.";
nextlevel_btn.addEventListener(Event.ENTER_FRAME, fl_FadeSymbolINwin);
nextlevel_btn.alpha = 0;
function fl_FadeSymbolINwin(event:Event)
{
nextlevel_btn.alpha += 0.01;
if(nextlevel_btn.alpha >= 1)
{
nextlevel_btn.removeEventListener(Event.ENTER_FRAME, fl_FadeSymbolIn);
}
}
First, you are adding listener fl_FadeSymbolINwin, but you remove a different listener fl_FadeSymbolIn. Second, for some reason you are declaring a function inside an if block. What you need to do is to get your code formatting right and check where and how you do removeEventListener's with what parameters. Trace them if needed.
Also I suggest using TweenLite (or even TweenNano) for fade effects. You won't have to mess with all these EventListeners. Your code for fading button would look as simple as this:
TweenNano.to(nextlevel_btn, 0.5, {alpha:1});
i want create road parallax scrolling down with flash in as3, when i run the script, the parallax moving up. and this my code
package {
import flash.display.MovieClip;
import flash.events.Event;
public class kelas extends MovieClip{
this i create variable
public var road:road1;
public var road2:road1;
public var roadContainer:MovieClip;
public var roadBreadth:Number;
public var car:Car;
public function kelas(){
and this create car , road and container
car = new Car();
road = new road1();
road2 = new road1();
roadBreadth = 653.7;
car.y = 10.0;
car.x = 10;
road.y = 10.0;
road.x = 10;
road2.y = road.y + roadBreadth;
road2.x = road.x;
//* add child object
roadContainer = new MovieClip();
roadContainer.addChild(road);
roadContainer.addChild(road2);
this.addChild(roadContainer);
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
public function onEnterFrame(event:Event):void
{
car.y = car.y + 15;
roadContainer.y = 10 - car.y + 10;
if (road.y + roadBreadth + roadContainer.y < 0)
{
road.y = road.y + (2 * roadBreadth);
}
if (road2.y + roadBreadth + roadContainer.y < 0)
{
road2.y = road2.y + (2 * roadBreadth);
}
}
}
i want this backgroung moving down is not moving up, please help me
Have a look at this sample, it's a pretty simple idea to wrap an object around. Make sure your multiplier is set to the amount of roads that you're wrapping.
if (road.y > 600) {
road.y -= road.y * 2;
} else {
road.y++;
}
may be your roadContainer contains road, so when you move roadContainer, you moves road too.
so, just move don't let it contains, add when you move the background.y++, road will like moving up
Hello im with a doubt and need your help if its possible.
I have a class dish and i load 1 file ".swf", and i have a little game that works like this:
The dish moves in the x and y axis and i when i click in the dish it falls down.
But i want to have not only 1 dish i want have 10 different dishes with diferent images.
And i want that they appear in a random sequence.
But i dont have ideia how i cant do that...someone can give me "light"?
I use this variables to load my dish to the stage in my game project.
var load_dish:Loader = new Loader();
var path:URLRequest = new URLRequest("dish.swf");
Here's an example of what you could do to get a random dish each time :
// whenever you need to create a new dish
var dishFilenames:Array = ['dish1.swf', 'dish2.swf', 'dish3.swf']; // etc etc
var randomIndex:int = Math.random() * dishFilenames.length;
var filename:String = dishFilenames[randomIndex];
var load_dish:Loader = new Loader();
var path:URLRequest = new URLRequest(filename);
thank for the answer!
so i cant have all the dishes in the same "swf"?
I need to create swf as many as i need?
My class dish is like this until now:
I dont have other way to do that?(with only a swf that contains all the dishes)
package {
import flash.events.Event;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.MouseEvent;
public class Dishe {
var velX: int;
var velY: int ;
var game:Game; //i have also a class game to control everyting
var broken_dish:URLRequest = new URLRequest("broken_dish.swf");
var gravity:int = 2;
var dishFilenames:Array = [ 'dish.swf','second_dish.swf'];
var randomIndex:int = Math.random() * dishFilenames.length;
var filename:String = dishFilenames[randomIndex];
var load_dish:Loader = new Loader();
var path:URLRequest = new URLRequest(filename);
public function Dishe(e:Game, vX:int, vY:int)
{
velX = vX;
velY = vY;
load_dish.x = -180;
load_dish.y = randomBetween(250,-5);
load_dish.load(caminho);
game = e;
game.myStage.addChild(load_dishe);
load_dish.addEventListener(MouseEvent.CLICK, _shoot);
}
public function broken_dish(e:Event)
{
velY += gravity;
load_dish.y +=velY ;
if(load_dish.y >= game.myStage.stageHeight)
{
game.game_states(Game.state_playing);
}
}
public function _enterFrame(e:Event):void
{
if(load_dish.content!=null)
{
load_dish.x += velX;
load_dish.y += velY *(1 - (load_dish.x / game.myStage.stageWidth) * 2 );
if(load_dish.x > game.myStage.stageWidth)
{
load_dish.y = randomBetween(250,-5);
load_dish.x = -180;
}
}
}
public function _shoot(e:MouseEvent):void
{
trace("nice!!");
game.game_states(Game.state_stop);
load_dishe.load(broken_dish);
}
function randomBetween(a:int, b:int) : int {
return a + int(Math.round( (b-a)*Math.random() ));
}
}
}
Clouds,
ducks,
score
display
and
waves
should
each
have
a
class
to
govern
their
movement
and
behavior.
When
ducks
are
clicked
on
they
are
“shot”
and
the
duck
is
removed
from
the
array
as
well
as
from
the
stage
(use
arrayName.splice()
for
this).
The
score
display
should
count
down
as
this
occurs.
The
number
of
ducks
left
should
be
a
property
within
the
Score
Display’s
class
and
adjusted
by
Main
when
the
ducks
are
shot.
When
all
the
ducks
are
“shot”
the
game
should
animate
the
“you
win”
message.
This
can
be
done
by
adding
and
removing
event
listeners
that
associate
an
ENTER
FRAME
event
with
an
animating
function.
(This
is
worth
only,
so
leave
it
for
last).
When
the
ducks
are
“shot”
the
waves
and
clouds
should
also
be
removed
from
view
AND
from
their
respective
arrays.
Game
should
reset
after
player
has
won
or
lost
many
times.
(not
just
once)
I have most of this done, I'm just having trouble with the scoreboard. Any tips on how to reset everything, and code the you win sign would help too.
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
[SWF(width="800", height="600", backgroundColor="#E6FCFF")]
public class Main extends Sprite
{
private var _sittingDucks:Array = []; //always set your arrays with [] at the top
public var _scoreDisplay:TextField
public function Main()
{
//adding the background, and positioning it
var background:Background = new Background();
this.addChild(background);
background.x = 30;
background.y = 100;
for(var i:uint = 0; i < 5; i++)
{
//adding the first cloud, and positioning it
var clouds:Clouds = new Clouds();
this.addChild(clouds);
clouds.x = 130 + Math.random() * 600; //130 to 730
clouds.y = 230;
clouds.speedX = Math.random() * 3;
clouds.width = clouds.height = 200 * Math.random()//randomly changes the clouds demensions
}
var waves:Waves = new Waves();
this.addChild(waves);
waves.x = 0;
waves.y = 510;
waves.speedX = Math.random() * 3;
for(var j:uint = 0; j < 8; j++)
{
var ducks:Ducks = new Ducks();
this.addChild(ducks);
ducks.x = 100 + j * 100;
ducks.y = 475;
_sittingDucks.push(ducks);
ducks.addEventListener(MouseEvent.CLICK, ducksDestroy);
}
var waves2:Waves = new Waves();
this.addChild(waves2);
waves2.x = 0;
waves2.y = 520;
waves2.speedX = Math.random() * 3;
var setting:ForeGround = new ForeGround();
this.addChild(setting);
setting.x = 0;
setting.y = 50;
setting.width = 920;
var board:ScoreDisplay = new ScoreDisplay();
this.addChild(board);
board.x = 570;
board.y = 35;
}
private function ducksDestroy(event:MouseEvent):void
{
//store the crow we clicked on in a new array
var clickedDuck:Ducks = Ducks(event.currentTarget);
//remove it from the crows array
//find the address of the crow we are removing
var index:uint = _sittingDucks.indexOf(clickedDuck);
//remove it from the array with splice
_sittingDucks.splice(index, 1);
//remove it from my document's display list
this.removeChild(clickedDuck);
}
}
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import ScoreDisplayBase; // always import the classes you are using
public class ScoreDisplay extends ScoreDisplayBase
{
private var txt:TextField; // where is it initialized?
private var score:uint = 0;
public function ScoreDisplay()
{
super(); // do you init txt here?
}
public function scoreUpdate():void
{
score += 10; // ok, so I suppose that your score does not represent the remaining ducks as you said, just only a score
txt.text = score.toString();
}
}
Aaaalrighty:
You do want to create the TextField txt in ScoreDisplay's constructor. Instantiate it, set its text to initial score (0), and addChild(txt).
In order to set the score later, we'll need a way to reference the display.
//you want a reference to the ScoreDisplay, not this
public var _scoreDisplay:TextField //no
public var _scoreDisplay:ScoreDisplay //yes
and when you create it in the Main constructor, we need to keep a reference.
_scoreDisplay = :ScoreDisplay = new ScoreDisplay();
this.addChild(_scoreDisplay );
_scoreDisplay .x = 570;
_scoreDisplay .y = 35;
If you want to be able to reset the game, I would recommend taking the duck creation and placing it in a method outside the Main class' constructor. You should also create a 'reset' function that sets the score (and the display) to 0 in ScoreDisplay.
private function spawnDucks() {
for(var j:uint = 0; j < 8; j++)
{
var ducks:Ducks = new Ducks();
this.addChild(ducks);
ducks.x = 100 + j * 100;
ducks.y = 475;
_sittingDucks.push(ducks);
ducks.addEventListener(MouseEvent.CLICK, ducksDestroy);
}
}
and then you call it in the constructor, and can call it again when you need to reset the game.
ducksDestroy(event:MouseEvent) is going to be where you want to recalculate the score, check if you've won, show a message, and reset the game. You'll need some kind of popup to display, here is a decent one if you don't know where to get started at with that.
private function ducksDestroy(event:MouseEvent):void
{
//store the crow we clicked on in a new array
var clickedDuck:Ducks = Ducks(event.currentTarget);
//remove it from the crows array
//find the address of the crow we are removing
var index:uint = _sittingDucks.indexOf(clickedDuck);
//remove it from the array with splice
_sittingDucks.splice(index, 1);
//remove it from my document's display list
this.removeChild(clickedDuck);
//update the score
_scoreDisplay.scoreUpdate();
//Check if all the ducks are gone
if (_sittingDucks.length == 0) {
//All the ducks are dead, we've won the game!
//create some kind of popup to display.
//add it to the screen, have some form
//of button (or a timer) take it away
//whatever takes the popup away, have it call 'reset'
}
}
private function reset():void
{
//write a reset method to clear the score
_scoreDisplay.reset();
//create some ducks and you're ready to go!
spawnDucks();
}