How to make a slider where you have to hit the middle of it in order to cause it to go to another scene - actionscript-3

I am new to flash and want to make a slider where something moves back and for until you hit space bar in order to make land in the middle which would trigger a new scene. Sort of like a mini game.
Again im really new to actionscript so any help would be nice. I was thinking of calling like a function where the pointer is continuously moving until the space bar is hit. But Im really stuck. Please and thank you for your time.

Make sure your slider has the instance name "slider". Then try this code:
//x position of the most left position of the slider
var left_limit:Number = 50
//x position of the most right position of the slider
var right_limit:Number = 250
var speed:Number = 10
var dir:int = 1
//How close the slider has to be to the middle to trigger the next scene
var tolerance:Number = 10
addEventListener(Event.ENTER_FRAME,loop)
addEventListener(KeyboardEvent.KEY_DOWN,keydown)
function loop(e:Event){
slider.x += speed*dir
if(slider.x>right_limit){
slider.x = right_limit
dir = -1
}else if(slider.x<left_limit){
slider.x = left_limit
dir = 1
}
}
function keydown(e:KeyboardEvent){
if(e.keyCode==Keyboard.SPACE){
removeEventListener(Event.ENTER_FRAME,loop)
if(Math.abs((slider.x-left_limit)-(right_limit-left_limit)/2)<tolerance){
//succeeded go to next scene
gotoAndStop("scene2")
}else{
//failed
}
}
}

Related

How to display player lives in game AS3

Hey everyone so having a little trouble trying to accomplish this. I understand how to add lives and display them through a Dynamic Text Field on the stage. My game is set up right now to where this happens and whenever the player dies a live decrements so it works fine.
But I want to display and Image of all 3 lives a custom Movie Clip that I drew in Flash CS6 to represent the lives. So All 3 lives will be displayed in the game and once the player dies one of the lives images is removed.
I have some idea on what to do. For instance I created a "for loop" to display all 3 images on the screen and created variables to place them horizontally next to each other with a space of 30 pixels.
But I'm not sure if this is the correct way to approach this. Also kind of confused on how I would remove one of the images when the player dies?
Her is my code so far:
public var playerLives:mcPlayerLives;
private var nLives:Number = 3;
private var startPoint:Point;
private var aPlayerLivesArray:Array;
In my main class Engine:
aPlayerLivesArray = new Array;
addPlayerLivesToStage();
Then the addplayerlivestostage function:
public function addPlayerLivesToStage():void
{
var startPoint:Point = new Point((stage.stageWidth / 2) - 300, (stage.stageHeight / 2) - 200);
var xSpacing:Number = 30;
for (var i = 0; i < nLives; i++)
{
trace(aPlayerLivesArray.length);
playerLives = new mcPlayerLives();
stage.addChild(playerLives);
playerLives.x = startPoint.x + (xSpacing * i);
playerLives.y = startPoint.y;
aPlayerLivesArray.push(playerLives);
}
}
So like i stated above everything works fine and it does display the 3 images that represent the lives, but would this be the correct approach or is there an easier method?
i think you're using right way to add lives.
and for removing them, you don't need to remove all and add new lives, you can remove the last element of lives array, so, it's done, i think thats already an easy method
so, you can implement this
for (var i = 0; i < nLives; i++)
to make a better usage for "adding lives in-game (earning lives)"
something like
for (var i = aPlayerLivesArray.length; i < nLives; i++)
but don't forget to decrease array length by 1 after removing last element of livesArray when player dies
Looks pretty close to a reasonable approach. I would have a blank container movieclip on stage where you want the lives icons to display. Create one life icon in your library and link it for export with actionscript. When you generate your game view, you can populate this container with the starting value of three lives. Place the first one, then place the subsequent ones based on the first location.
Some untested code:
NOTE: The following presumes your container clip for the lives is named lives_container and your link instance name for the life icon in the library is Life_icon.
var numberOfLives:Number = 3;
var iconSpacing:Number = 5;
var nextX:Number = 0;
for(var i:int = 0; i < numberOfLives; i++ )
{
var icon:MovieClip = new Life_icon();
icon.x = nextX;
lives_container.addChild( icon );
nextX += icon.width + iconSpacing;
}
This way you could add extra lives easily if the player gained any by adding new icons at the last nextX value, like so:
function addLife():void
{
var icon:MovieClip = new Life_icon();
icon.x = nextX;
lives_container.addChild( icon );
nextX += icon.width + iconSpacing;
}
or remove them as the player loses them:
function removeLife():void
{
var numberOfLivesDisplayed:Number = lives_container.numChildren();
lives_container.removeChildAt( numberOfLivesDisplayed - 1 );
nextX -= icon.width + iconSpacing;
}
Using a container clip for the lives icons makes adjusting the location of the life icons easier if it becomes necessary later.

Snakes and Ladders AS3.. how can a movie clip climb a ladder?

I am having this problem in developing this snakes and ladders game and i am very much hoping that you guys can help me out. i already created the board and the avatar. only thing is i cant make the avatar move up the ladder, and move down with the snake. can somebody help me? i am very much desperate right now, and every help is appreciated, thank you guys!
EDIT:
here's the code that i have written so far here are some of the codes I have written so far..
stop();
var xCoord:Array = [141,251,360,471,580,691,799,910,1019,1127,1238,1238,1127,1019,910,799,691,580,471,360,251,251,360,471,580,691,799,910,1019,1127,1238,1238,1127,1019,910,799,691,580,471,360,251,251,360,471,580,691,799,910,1019,1127,1238,1238,1127,1019,910,799,691,580,471,360,251,251,360,471,580,691,799,910,1019,1127,1238,1238,1127,1019,910,799,691,580,471,360,251,251,360,471,580,691,799,910,1019,1127,1238,1238,1127,1019,910,799,691,580,471,360,251];
var yCoord:Array = [675,670,670,670,670,670,670,670,670,670,670,602,602,602,602,602,602,602,602,602,602,534,534,534,534,534,534,534,534,534,534,466,466,466,466,466,466,466,466,466,466,399,399,399,399,399,399,399,399,399,399,331,331,331,331,331,331,331,331,331,331,262,262,262,262,262,262,262,262,262,262,195,195,195,195,195,195,195,195,195,195,127,127,127,127,127,127,127,127,127,127,60,60,60,60,60,60,60,60,60,60];
var arrSquares:Array = new Array(xCoord.length);
var spaceIndex:Number = 0;
var delay:Number = 400;
var tm:Timer = new Timer(delay);
tm.addEventListener(TimerEvent.TIMER, mover);
tm.addEventListener(TimerEvent.TIMER_COMPLETE, moveDone);
spinner.addEventListener(MouseEvent.CLICK, doSpin);
var total:Number =0;
function doSpin(mevt:MouseEvent):void {
var rn:Number = Math.round(5*Math.random()+1);
txtCount.text = String(rn);
total = total + rn;
txtTotal.text = String(total);
txtCount.visible = true;
spinner.removeEventListener(MouseEvent.CLICK, doSpin);
tm.reset();
tm.repeatCount = rn;
tm.start();
}
function mover(tevt:TimerEvent):void {
spaceIndex = (spaceIndex+1)%(xCoord.length);
chip.x = xCoord[spaceIndex];
chip.y = yCoord[spaceIndex];
}
function moveDone(tevt:TimerEvent):void {
spinner.addEventListener(MouseEvent.CLICK, doSpin);
txtCount.visible = false;
}
i dont know where to put the if statement of executing the motion tween attached to the chip(avatar)
Well here are my initial thoughts. I would create an animation with your character who you want to move up and down. To make it simple, make an animation for climbing, then one for falling. It's really easy to do, just use the tween option on the timeline after inserting your keyframes.
Looks like you've created your animations. Now, whether or not he slides up or falls down depends on where your snakes and ladders are. Only you know that, so at those particular spots on your board (for example, x = 200 and y = 200) we want the if statement to occur. But we only want it to occur after your avatar is done moving. Probably create a new function and add the following to the mover function
var checkX:Number = chip.x;
var checkY:Number = chip.y
checkLandingSpace(checkX,checkY);
Now let's make a function checkLandingSpace which will check if we are on a shoot or ladder
function checkLandingSpace(checkX:Number,checkY:Number):void
{
if (checkX = (your point) || (another point) //first check all x points...continue like this for all points where a ladder is...the || means or
{
if (checkY = (your points....etc)
{
mc_avatarLadder.play(); //choose your instance name to be mc_avatar, then play the tween
}
}
}
Or check this post for equating one variable to any element in an array If [Get Variable] is equal to [Array]
Now write the that for your ladder. Then do the exact same thing with all of your shoots points. Except, make a new animation with instance name mc_avatarShoot then just say mc_avatarShoot.play();
After that, make sure on the last frame for both instances, you just put in gotoAndStop(1); just to make sure it's ready next time you go to play the animation.
Of course, adjust your timer appropriately. This should pretty much do it, there might be a couple things to adjust for your own game, but follow this and understand it and you'll get it.

How to make a movieclip appear and reappear in the same location?

Well, I'm working on a shooting game in which I have to click enemies to make two counters count the number of hits I get. In this case the enemies are ghosts and I tried making some kind of animation when they are shot so the animation replaces them after I click on them.
However I can't seem to make them reappear again in the same location, it's a very simple drawing made with the shape and drawing tools of Flash CS5.
The code I use in this case for the shooting part is this one:
function disparar (event:MouseEvent):void{
contar +=1;
disparos.text = contar.toString();
var destino1:Boolean = this.mira.hitTestObject(this.FRojo)
if (destino1 == true){
cuenta +=1;
aciertos.text = cuenta.toString();
this.FRojo.visible = false;
colorante.color = 0xFF0000;
this.bang.transform.colorTransform = colorante;
this.bang.x = this.FRojo.x;
this.bang.y = this.FRojo.y;
this.bang.scaleX = this.FRojo.scaleX;
this.bang.scaleY = this.FRojo.scaleY;
this.bang.play();
this.FRojo.visible = true;
}
In fact you can see the whole file in here, it's very simple, but I can't seem to make the movieclip either disappear and reappear or make the animation that follows reappear each time I hit one of the ghosts. Could anyone help me with this? I'd really appreciate the help.
You're hiding the movie clip by setting this.FRojo.visible = false; and then setting it back to true pretty much right after so it never hides.
Try replacing this.FRojo.visible = true;
with
setTimeout(function(){FRojo.visible = true;}, 1000);
That will make it reappear after 1 second (1000 milliseconds).
So remove this and make sure each one is FRojo, FAzul and FMorado.
If you use a tweening library like greensock you can do some cool fades rather than it just reappearing.
EDIT
You have another error inside your BANG movie clip. On frame 10 replace
this.bang.x = 50;
this.bang.y = 10;
this.bang.scaleX = 1;
this.bang.scaleY = 1;
with
this.x = 50;
this.y = 10;
this.scaleX = 1;
this.scaleY = 1;

startdrag start point limitations?

I have a slider that controls a movie clip by dragging it through the frames to animate and this works great when dragging from left to right, But i want the slider to start in the middle and drag through the movie clip from a center point being able to go 350 to the right and 350 to the left.
Is this possible?
Heres my code so far and as you can see it drags 350 to the right through dialSpin_mc.
Is there a way to make the slider start at a certain frame and go backwards and forwards?
dialSpin_mc.stop();
slider_mc.knob_mc.buttonMode = true;
slider_mc.knob_mc.addEventListener(MouseEvent.MOUSE_DOWN, onDragKnob);
stage.addEventListener(MouseEvent.MOUSE_UP, onReleaseKnob)
slider_mc.knob_mc.buttonMode = true;
function onDragKnob(myEvent:Event):void
{
slider_mc.knob_mc.startDrag(false, new Rectangle(0,0,350,0));
slider_mc.knob_mc.addEventListener(Event.ENTER_FRAME, onScrubMovie);
}
function onReleaseKnob(myEvent:Event):void
{
slider_mc.knob_mc.stopDrag();
slider_mc.knob_mc.removeEventListener(Event.ENTER_FRAME, onScrubMovie);
}
function onScrubMovie(myEvent:Event):void {
var playHead:int=Math.round((slider_mc.knob_mc.x/350*8)+1);
dialSpin_mc.gotoAndStop(playHead);
}
As discussed in comments this is how you could code the slider functionality without using the startDrag() and stopDrag() functions.
The idea is that when you press the mouse button down over the slider, an ENTER_FRAME listener is created. Every frame the sliders X position will be updated to match the mouseX position, and to make sure it can only travel 175 pixels either way we also check the sliders new position.
After making sure the sliders position is valid, you can use the same code to set the dialSpin_mc frame.
Once the mouse button is released, the enter frame listener is removed.
The sliderOrigin declared at the top of the code will need to be changed to whatever is appropriate for your project (whatever the sliders xposition is when you move it to the middle of the slide area rather than the very left).
var sliderOrigin:int = 150; // The x position the slider is in when in the center of the slide bar
slider_mc.x = sliderOrigin;
slider_mc.addEventListener(MouseEvent.MOUSE_DOWN, mDown);
slider_mc.addEventListener(MouseEvent.MOUSE_UP, mUp);
function mDown(e:MouseEvent):void
{
addEventListener(Event.ENTER_FRAME, UpdateDrag);
}
function mUp(e:MouseEvent):void
{
removeEventListener(Event.ENTER_FRAME, UpdateDrag);
}
function UpdateDrag(e:Event):void
{
slider_mc.x = mouseX;
// Check if the slider is 'out of bounds' and change its position if it is
if(slider_mc.x < sliderOrigin - 175)
slider_mc.x = sliderOrigin - 175;
else if(slider_mc.x > sliderOrigin + 175)
slider_mc.x = sliderOrigin + 175
var playHead:int = Math.round((slider_mc.x/350*8)+1);
dialSpin_mc.gotoAndStop(playHead);
}
Depending on the start position of the slider the range of playHead will change (so if the slider starts at x pos 200 the range would be between 2 and 10, at x pos 400 the range is between 6 and 14 - simple fix by changing the offset from +1 to whatever is necassary).

Loop an image in Flash

I want to have a scene where an image which is 5000 pixels high is moving up 5 pixels each frame-refresh. When the image is all up, I'd like to see the top of the image connected to the bottom of the image. This should be done untill the level is 'done'. How can I 'loop' such an Image?
You can create a copy of that image which you keep hidden/above and the trick is to update the position and loop accordingly so when one image goes bellow the screen it goes back on top and repeats.
Here's a basic snippet to illustrate the idea using the DisplayObject class and the scrollRect property:
//ignore this, you have your content already
var dummyContent:BitmapData = new BitmapData(100,100,false);
dummyContent.perlinNoise(10,10,8,12,true,true);
//important stuff starts here
var container:Sprite = addChild(new Sprite()) as Sprite;//make a container
container.scrollRect = new Rectangle(0,0,dummyContent.width,dummyContent.height);//set a scrollRect/'mask'
var part1:DisplayObject = container.addChild(new Bitmap(dummyContent));//add two copies
var part2:DisplayObject = container.addChild(new Bitmap(dummyContent));//of the same content
part2.y -= part2.height;//set the 2nd at the top of the 1st
addEventListener(Event.ENTER_FRAME,update);
function update(e:Event):void{
//move both
part1.y += 5;
part2.y += 5;
//check if any reach the bottom so they can be moved back up
if(part1.y >= part1.height) part1.y = -part1.height;
if(part2.y >= part2.height) part2.y = -part2.height;
//the above can also be nicely placed in a loop if you plan on using more seamless looping clips/images
}
Obviously you will have different content, but the principle is the same.
If you're working with images, you can simply use BitmapData's copyPixels method:
var s:int = 5;//scroll speed
//make some content
var w:int = 100;
var h:int = 100;
var dummyContent:BitmapData = new BitmapData(w,h,false);
dummyContent.perlinNoise(10,10,8,12,true,true);
//prepare for stiching
var renderPos:Point = new Point();//position to render the current image to
var prenderPos:Point = new Point();//position to render the previous image (the 'hidden' copy above)
var render:BitmapData = new BitmapData(w,h,false);//create a bitmap data instance to render updated pixels int
addChild(new Bitmap(render));//and add it to the stage
addEventListener(Event.ENTER_FRAME,update);
function update(e:Event):void{
renderPos.y = (renderPos.y+s)%h;//update the scroll position for the 1st part, % is used to loop back to 0 when the position gets to the content height
prenderPos.y = renderPos.y - h;//update the scroll position for the 2nd part (above)
render.lock();//freeze pixel updates
render.copyPixels(dummyContent,dummyContent.rect,renderPos);//copy pixels from the scroll position to the bottom
render.copyPixels(dummyContent,dummyContent.rect,prenderPos);//copy pixels from the top to the scroll position
render.unlock();//unfreeze/update ALL THE PIXELS
}
You can try to use a Rectangle object which changes height (height-scrollPosition) so you potentially access less pixels each time or you can manually work out single for loops using BitmapData's getVector method, but that's something to look into if performance is actually an issue for such a simple task and it's worth checking what's faster ( copy full bitmap rect vs copy partial bitmap rect vs manually copy values using vector )
Be warned, Flash cannot load an image greater than 16,769,025 pixels (or 4095x4095). The height of 5000 pixels will work as long as the width is not greater than 3353.
That said, I'd loop the image by keeping two copies of the image onstage, move both at the same time with a parent object, and reset to origin once your loop point is met.
Consider the following stage setup:
Stage ¬
0: MainTimeline:MovieClip ¬
0: Container:MovieClip ¬
0: img1:Bitmap
1: img2:Bitmap
Now moving container up, you'd just need to check that the looping second image reaches the origin point of the first image.
function onEnterFrame(e:Event):void {
Container.y = Container.y - 5;
if (Container.y < -5000) {
Container.y = -5;
}
}