AS3 How to reload a game? - actionscript-3

This code is an attempt to reset the stage to the original setup and start the game over, however it would only delete everything of the stage and leave it blank, it wont load the items on the stage. what am I missing here?
playLvlAgn.addEventListener(MouseEvent.CLICK, doLevelAgain);
function doLevelAgain(event: MouseEvent): void {
stage.removeChildren();
gotoAndPlay(1);
}

Just because things visually go away, it doesn't mean the objects in memory are magically purged.
You would need to handle this resetting yourself. As others have pointed out, to do this, it highly depends on your game's code and how it is organised. We simply can't provide any meaningful help as the possibilities for a game can be near infinite in the ways it is written.
As a somewhat related side thing:
If you are going to stick with frames (which others may be against, but I personally see them as useful in a variety of situations), I'd advise you to not start everything on frame 1. Again, I don't know how you've written your game, but it might be helpful to separate out certain functionality on certain frames.
Just an example:
Maybe asset loading can be on one frame (let's say frame 1)
Then on the next frame perhaps global persistent ui is created, such as help/settings menus. (frame 2)
Then the game level itself such as maps and layout + stuff that survives a reset can be built on the next (frame 3)
Then perhaps game play specific data + stuff that does not survive a reset, say player score and game time (frame 4)
Then the game starts (frame 5)
Then for a reset, if you want to just reset that level, you can do all your resetting/clean up logic, then jump to frame 4 and avoid reloading assets, recreating persistent ui + the physical game level.
It can get quite hairy if you weren't planning for this and in some cases, you may need to rethink/reorganise/rewrite some of your code. This is not a bad thing.

OK I found the solution. all removeChilds had to be inside the button function. I also had to sent it to frame2 and stop just in case someone attempted to reload the game before it was even started to play.
playLvlAgn.addEventListener(MouseEvent.CLICK, doLevelAgain);
function doLevelAgain(event: MouseEvent): void {
gotoAndStop(2);
for (var i: int = 0; i < 3; i++) {
if (balls.length > 0) {
ball = balls.pop();
ball.parent.removeChild(ball);
trace("if--0c")
}
}
if (stage.contains(playLvlAgn)) {
removeChild(playLvlAgn);
trace("if--1")
}
if (stage.contains(yesh8DoorA)) {
removeChild(yesh8DoorA);
trace("if--2")
}
if (stage.contains(yesh8DoorB)) {
removeChild(yesh8DoorB);
trace("if--3")
}
if (stage.contains(yesh8DoorC)) {
removeChild(yesh8DoorC);
trace("if--4")
}
if (stage.contains(yesh8allBuckets1)) {
removeChild(yesh8allBuckets1);
trace("if--5")
}
if (stage.contains(yesh8allBuckets2)) {
removeChild(yesh8allBuckets2);
trace("if--6")
}
if (stage.contains(add8bigGrayBall6)) {
removeChild(add8bigGrayBall6);
trace("if--7")
}
if (stage.contains(yesh8wall5)) {
removeChild(yesh8wall5);
trace("if--8")
}
if (stage.contains(yesh8step)) {
removeChild(yesh8step);
trace("if--9")
}
if (stage.contains(yesh8bomb26)) {
removeChild(yesh8bomb26);
trace("if--10")
}
if (stage.contains(yesh8bomb27)) {
removeChild(yesh8bomb27);
trace("if--10")
}
if (stage.contains(yesh8bomb28)) {
removeChild(yesh8bomb28);
trace("if--10")
}
if (stage.contains(yesh8bomb2)) {
removeChild(yesh8bomb2);
trace("if--11")
}
if (stage.contains(yesh8bomb3)) {
removeChild(yesh8bomb3);
trace("if--12")
}
if (stage.contains(yesh8gBall21)) {
removeChild(yesh8gBall21);
trace("if--13")
}
if (stage.contains(yesh8gBall24)) {
removeChild(yesh8gBall24);
trace("if--14")
}
if (stage.contains(yesh8redHalfSwing)) {
removeChild(yesh8redHalfSwing);
trace("if--15")
}
gotoAndPlay(1);
}

Related

Robot not pressing mouse during mouse movement method

I am currently working on a basic utility software that has the ability to record Keyboard & Mouse input, save the input to a .txt file, and playback the data on a file. I am revising the program for added file and playback functionality. The problem I'm having is with the Robot.mousePress() method within the mouse movement method:
public static void executeMouseMovementData() {
mouseRobot.mousePress(InputEvent.BUTTON1_MASK);
for (int i=0; i < MouseDataHandler.mouseData.size(); i++) {
mouseRobot.moveMouse(MouseDataHandler.mouseData.get(i).getX(), MouseDataHandler.mouseData.get(i).getY());
mouseRobot.delay(MouseDataHandler.mouseData.get(i).getTimeElapsed());
}
mouseRobot.releaseMouse();
}
This program follows a basic sequence of events: 1 Data initialization, 2 Press mouse, 3 Move mouse, 4 Release mouse. Unlike another method I've successfully implemented, this method does not press the mouse at any time for no obvious reason. Mouse movement works beautifully with the playback feature. I just can't seem to get the Robot to execute any type of mouse event other than movement, even if I restructure the method.
I've tried editing the method to make sure the Robot doesn't press the mouse at the time in which the "playback" button on the GUI is pressed, as to not mess with the focus of the mouse event. The error likely isn't related to other aspects of the code, because everything else in the program runs smoothly. The object "mouseRobot" is an basic extension class of the Java.awt.Robot class with a basic interface for compound Robot mouse methods(), and I even directly call the mousePress method from the Robot class.
What could be the malfunction that occurs with within this method?
Solved. Improved the method in which mouse movements are handled to do one mouse movement per frame. The class can now accurately perform various checks and data changes in between mouse movements, while also allowing other classes to function without being held up from a lengthy for loop. The method in the question was extremely inefficient, impractical and basically acted as a 'while' loop.
public void handleMouseMovements() {
if (shouldAttemptToMoveMouse) {
if (!targetHasBeenReached(currentAdjustedX, currentAdjustedY, targetX, targetY)) {
if (!movementCreated) {
calculateDirection(startX, startY, targetX, targetY);
getLineIndexToUse();
initializeMoveData(repositoryFileIndex, fileIndex);
movementCreated = true;
firstTime = System.currentTimeMillis();
}
if (CMMI >= Main.mouseDataHandler.getSizeOfRepositoryIndex(repositoryFileIndex, fileIndex)){
CMMI =0;
loopMovement();
}
if (movementfileIndexTimeHasElapsed(repositoryFileIndex, fileIndex)) {
moveMouse(repositoryFileIndex, fileIndex);
CMMI++;
firstTime = System.currentTimeMillis();
}
}
else {
resetData();
}
}
}
public void moveMouse(int repositoryFileIndex, int fileIndex) {
currentX = MouseDataHandler.mdr.get(repositoryFileIndex).get(fileIndex).get(CMMI).getX();
currentY = MouseDataHandler.mdr.get(repositoryFileIndex).get(fileIndex).get(CMMI).getY();
currentAdjustedX = currentX + distanceX;
currentAdjustedY = currentY + distanceY;
Main.bot.moveMouse(currentAdjustedX + Main.getX(), currentAdjustedY + Main.getY() + 25);
}
This method is vastly more efficient and handles all criteria necessary to determine direction, determine file index of mouse data to be used, calculates target-file index offsets, and has proper time intervals inbetween mouse movements.

as3 slope detection for non uniform terrains

I want to create a 2d game in which a car moves along the edge of an irregular shaped hill. I want to use basic as3 (no physics engine like Box2d or Nape). With a lot of research I found this thing which is exactly what i want but there is only the logic and no source code. Can someone help me with a piece of code that can do this in as3? Also suggest if there is a better alternative to get the desired output.
I myself don't have much knowledge into code like this, and I can't make a comment because I'm short 7 reputation :'( but the article you linked does have another link to a Worms-esque program with code that might be of help to you. Here's a link to that site in question and I'll also provide some appropriate code that you can see if it's of use to you.
So this program has a listener for if any key is down and sets a boolean as true if it's a key your program is using (movement, space for jumping or whatever), that listener looks like this
public function key_down(e:KeyboardEvent) {
if (e.keyCode==37) {
left_key=true;
}
if (e.keyCode==39) {
right_key=true;
}
if (e.keyCode==32) {
space_key=true;
}
}
And then it has a subsequent listener for when a key is released
public function key_up(e:KeyboardEvent) {
if (e.keyCode==37) {
left_key=false;
}
if (e.keyCode==39) {
right_key=false;
}
if (e.keyCode==32) {
space_key=false;
}
}
And finally the stage has an ENTER_FRAME listener for moving the character that runs this function
public function move_character(e:Event) {
//If left key is pressed, we'll move the character to the left
if (left_key) {
for (i=0; i<3; i++) {//Do you remember when we made the character fall? We had to move the character pixel by pixel
if (! terrain_bmpd.hitTest(new Point(terrain_bmp.x,terrain_bmp.y),0x01,new Rectangle(character.x-6,character.y-10,1,17))) {
character.x--; /*If the character doesn't hit the ground, we can move left. However,
the character may be sunk under the ground. We have to lift it*/
while (terrain_bmpd.hitTest(new Point(terrain_bmp.x,terrain_bmp.y),0x01,new Rectangle(character.x-5,character.y+9,10,1))) {
character.y--;
}
}
}
}
if (right_key) {//Well, that's the same for the right key
for (i=0; i<3; i++) {
if (! terrain_bmpd.hitTest(new Point(terrain_bmp.x,terrain_bmp.y),0x01,new Rectangle(character.x+5,character.y-10,1,17))) {
character.x++;
while (terrain_bmpd.hitTest(new Point(terrain_bmp.x,terrain_bmp.y),0x01,new Rectangle(character.x-5,character.y+9,10,1))) {
character.y--;
}
}
}
}
if (space_key&&! jumping) {//That's easy: if he isn't jumping and you press space, his speed will be negative and he'll jump
character_speed=-10;
jumping=true;//Now the character can't jump again
}
character_speed++;//Every frame we will increase character's speed
if (character_speed>0) {
//If the speed is positive, we will check a collision between the terrain and the rectangle below the character
for (i=0; i<character_speed; i++) {//We check the collision pixel by pixel...
if (! terrain_bmpd.hitTest(new Point(terrain_bmp.x,terrain_bmp.y),0x01,new Rectangle(character.x-5,character.y+9,10,1))) {
character.y++;//If there isn't a collision, the character will fall
} else {
jumping=false;//If there's a collision with the ground, the character isn't jumping
character_speed=0;//The speed is 0, because the character hit the ground
}
}
} else {
for (i=0; i<Math.abs(character_speed); i++) {//If the speed is negative, the for loop won't work. We have to use Math.abs().
//Now we will check the collision between the terrain and the rectangle above the character
if (! terrain_bmpd.hitTest(new Point(terrain_bmp.x,terrain_bmp.y),0x01,new Rectangle(character.x-5,character.y-10,10,1))) {
character.y--;
} else {
character_speed=0;//Well, that's the same: the character hit the ground
}
}
}
}
Sorry I couldn't provide any personal experience, if you want more then the article I linked above will provide more information.

AS3: Fast hovering doesn't execute rollOut

I'm having a serious problem that is getting me nervous:
I've made a button _btn that includes ROLLOVER and ROLLOUT animations with coding (an nested movieclip instance called barra that increases to half alpha when you hover over and decreases when you hover out).
[Here it should go a descriptive image but I'm new and I need 10 reputation. I'll appreciate your help]
This works perfectly but the problem occurs when I move my cursor very quickly from one point to another, with the button in between. It seems that the ROLLOUT function is not detected, so the ROLLOVER animation keeps working (and if you look carefully, the animation stops for a few seconds and then continues).
[Here it should go another descriptive image too]
This is the code in the Actions layer:
//Funciones ROLL OVER
function _btnOver(event:MouseEvent):void {
_btn.buttonMode = true;
_btn.addEventListener(Event.ENTER_FRAME,_btnFadeIn);
}
function _btnFadeIn(event:Event):void {
_btn.barra.alpha += 0.1;
if (_btn.barra.alpha >= 0.5)
{
_btn.removeEventListener(Event.ENTER_FRAME,_btnFadeIn);
}
}
_btn.addEventListener(MouseEvent.ROLL_OVER,_btnOver);
//Funciones ROLL OUT
function _btnOut(event:MouseEvent):void {
_btn.addEventListener(Event.ENTER_FRAME,_btnFadeOut);
}
function _btnFadeOut(event:Event):void {
_btn.barra.alpha -= 0.1;
if (_btn.barra.alpha <= 0.2)
{
_btn.removeEventListener(Event.ENTER_FRAME,_btnFadeOut);
}
}
_btn.addEventListener(MouseEvent.ROLL_OUT,_btnOut);
Click here if you want to download the FLA and SWF files, so you can see the problem clearly.
I barely know how to use ActionScript 3 (my only programming knowledge is Processing) and I don't have time now to learn it from head to toe, but I've researched about the problem and it's still not clear.
With tutorials and guides, I managed to learn how to create and understand this code, and I think the problem might be in the functions of the events ROLL_OVER and ROLL_OUT, which contain the addEventListener of the ENTER_FRAME events (where the animations actually are), respectively. But I don't know exactly what I have to do to fix it, what should I add or change.
I would be really glad if someone could help with this, I'm frustrated! What do you recommend me to do?
Thanks in advance
(PD: I don't understand most of the programming language. If you can be as clear and direct as possible, I'll really appreciate it)
Apparently your troubles lay in incoherent animation sequence by using enter frame listeners. You are running two independent listeners, both altering alpha of a single object, this creates a conflict, only one will work (you can determine which if you add both at once and trigger events, the resultant alpha value will indicate which listener changes it last) and you apparently expect one to do a fade in while the other to do a fade out. Instead, you should use one listener (probably even persistent) and give your object "target alpha" property as well as delta to change alpha per frame. An example:
var bbta:Number=0.2; // btn.barra's target alpha
_btn.addEventListener(Event.ENTER_FRAME,_btnFade);
function _btnFade(e:Event):void {
var a:Number=_btn.barra.alpha;
if (Math.abs(a-bbta)<1e-8) return;
// no sense of setting alpha with minuscule difference
const delta:Number=0.1; // how fast to change per frame
if (a>bbta) {
a-=delta;
if (a<=bbta) a=bbta;
} else {
a+=delta;
if (a>=bbta) a=bbta;
}
_btn.barra.alpha=a;
}
function _btnOver(event:MouseEvent):void {
_btn.buttonMode = true; // move this elsewhere, if you don't cancel buttonMode
bbta=0.5; // set target alpha, the listener will do a fade-in
}
function _btnOut(event:MouseEvent):void {
bbta=0.2; // set target alpha, the listener will do a fade-out
}
I edited some code in here, basically i am checking hover state onLoop function, so you can change your settings on here
import flash.events.Event;
var isRolledOver:Boolean = false;
//Funciones ROLL OVER
function _btnOver(event:MouseEvent):void {
isRolledOver = true;
}
function _btnOut(event:MouseEvent):void {
isRolledOver = false;
}
_btn.addEventListener(MouseEvent.ROLL_OVER,_btnOver);
_btn.addEventListener(MouseEvent.ROLL_OUT,_btnOut);
this.addEventListener(Event.ENTER_FRAME,onLoop);
function onLoop(e){
if(this.isRolledOver){
if(_btn.barra.alpha < 0.5) _btn.barra.alpha += 0.1;
}
else{
if(_btn.barra.alpha > 0.5 || _btn.barra.alpha > 0) _btn.barra.alpha -= 0.1;
}
}
I added the sample fla in case

How to make a stick man running when pressing a key?

I created a movieclip named stickman. In that, I created an animation by drawing a sequence of move in everyframe, so that stickman can run. Now what I want is that when I press a key, the stick man will run from left to right and when I release the key, it will stop. This is my code:
RunningMan.stop();
stage.addEventListener(KeyboardEvent.KEY_DOWN,keypresseddown);
function keypresseddown(event:KeyboardEvent):void
{
var key:uint = event.keyCode;
switch (key) {
case Keyboard.LEFT :
{
RunningMan.play();
RunningMan.x-=10;
RunningMan.scaleX=-1;
if(RunningMan.x<=0)
{
RunningMan.x=0;
}
};
case Keyboard.RIGHT :
{
RunningMan.play(); //play animated run
RunningMan.x+=10;
RunningMan.scaleX=1;
if(RunningMan.x>=stage.width)
{
RunningMan.x=stage.width;
}
};
default: RunningMan.stop();
}
}
However, when I pressed and held a key, it moved from left to right without animated run.
How can I fix it?
Thanks in advance.
EDIT:
I have a movieclip called character containing 3 movieclip named: standing, running and jumping, respectively. When I pressed up arrow key, it would jump, but if I released the key right away, it did not jump high as the jump movieclip could not finish its frames. This is the code:
if (key.isDown(Keyboard.LEFT))
{
gotoAndStop("running");
BGround.x+=speed;
scaleX=-1;
if(BGround.x>=stage.stageWidth)
BGround.x=stage.stageWidth;
}
else if (key.isDown(Keyboard.RIGHT))
{
gotoAndStop("running");
BGround.x -= speed;
scaleX=1;
}
else
if (key.isDown(Keyboard.UP))
{
gotoAndStop("jumping");
}
else
gotoAndStop("standing");
How can I fix that?
First of all, I hope RunningMan is an instance of the class, not the class itself. And if it is an instance, you should really follow common naming conventions for when you share your code with others (like you are doing now) so it would be runningMan.
So 1st, make the 1st frame of the runnigMan's timeline a picture of the man standing still and name it "still" or something. then name the second "running" and extend that like 20 frames or however long your animation is. at the last frame you will have to use timeline code. just one line of gotoAndPlay("running") will cause those frames of 2 to 20 (or whatever) to loop. When you tell the timeline to go to frame 1 from outside the timeline code, it wont loop anymore and will stay on the frame of the man standing still. So from outside when you want the loop to start:
runningMan.gotoAndPlay("running"); // frame 2
To stop:
runningMan.gotoAndStop("still"); // frame 1
Or you could do it from inside the RunningMan class
public function startRunAnimation():void{
this.gotoAndPlay("running");
}
public function stopRunAnimation():void{
this.gotoAndStop("still");
}
And you could use them just by replacing these function names with the ones you have if your code ex( instead of play() it would be startRunAnimation() )
EDIT
What you could do for this problem is to have a boolean variable for when your character is in the air (somewhere in your code where you do collision detection with the ground or where you handle gravity - however it is set up) so that this part of your code know when your character is in the air. And then you could simple test for this however way you need it.
...
if (key.isDown(Keyboard.UP) || this.inAir==true)
{
gotoAndStop("jumping");
}
else
gotoAndStop("standing");
Although if your character does not inheirt from a collidable object that has gravity, friction etc... then you would have to make the inAir property of whatever other class, public or make getter function for it - so that you can access it here. I hope this helps.

AS3 Button to stop Movieclip after its finished playing

Ok, so I'm a beginner at AS3 and Flash and I managed to put this code together for an animation. A Button called start_btn is supposed to start and stop a movieclip called main_mc. On the first click of the Button, the Movieclip is supposed to play (which it does), however on the second click, the movie stops in the middle of its animation (which I don't want). My question is, when you click the Button a second time, how can i get the Movieclip to finish playing its animation then stop on the last frame?
I thought about using if (main_mc.currentFrame == main_mc.totalFrames); {main_mc.stop(); but the Movieclip still does not stop on the last frame. The Movieclip itself also has a gotoAndPlay(2); command on the last frame so that the animation repeats before the Button is clicked a second time.
here is the code i have:
`start_btn.addEventListener(MouseEvent.CLICK, mainaniS);
function mainaniS(event:MouseEvent):void
{
main_mc.play();
start_btn.removeEventListener(MouseEvent.CLICK, mainaniS);
start_btn.addEventListener(MouseEvent.CLICK, mainaniSt);
}
function mainaniSt(event:MouseEvent):void
{
if (main_mc.currentFrame == main_mc.totalFrames);
{main_mc.stop();}
start_btn.removeEventListener(MouseEvent.CLICK, mainaniSt);
start_btn.addEventListener(MouseEvent.CLICK, mainaniS);
}`
Try main_mc.gotoAndStop(main_mc.totalFrames).
I was going to provide a quick and dirty solution, but decided instead to try and explain a few of the issues with your current implementation and attempt to refactor and explain and better one. Unfortunately I don't have access to Flash right now, so the code is untested.
You're adding and removing event listeners often, which is generally a bad idea. Instead, since you're using a single button to perform multiple functions it would make sense to track the button state in a separate variable. In this case, a boolean for whether or not the movieclip is currently playing.
var playing:Boolean;
Now we can combine the mainaniS and mainaniSt into one and perform a different action based on whether or not the movieclip is playing, and just keep the one eventlistener on the button. I've also taken the liberty of naming the method something more meaningful:
start_btn.addEventListener(MouseEvent.CLICK, onStartClick);
function onStartClick(event:MouseEvent):void
{
if(playing) {
playing = false;
}
else {
playing = true;
main_mc.play();
}
}
You may be wondering why we don't call main_mc.stop() in the first block: the reason is that you don't want to stop the movieclip as soon as you click the button, but after the movieclip has finished playing if the button has been clicked. Therefore, we just set playing to false to indicate that we want it to stop later.
Finally, we need to make sure the movieclip stops upon completion, but only if playing is false. To do this we add a listener to movieclip that is called every frame, and checks whether playing is false, and if it's on the last frame. Note that the last frame is actually totalFrames - 1: this is because the frame numbers start from zero rather than one (i.e. if totalFrames is 3, the frame numbers will be 0, 1, 2).
main_mc.addEventListener(Event.ENTER_FRAME, animate);
function animate(event:Event):void {
if(!playing && main_mc.currentFrame == main_mc.totalFrames - 1) {
main_mc.stop();
}
}
All the refactored code together:
var playing:Boolean;
start_btn.addEventListener(MouseEvent.CLICK, onStartClick);
main_mc.addEventListener(Event.ENTER_FRAME, animate);
function onStartClick(event:MouseEvent):void
{
if(playing) {
playing = false;
}
else {
playing = true;
main_mc.play();
}
}
function animate(event:Event):void {
if(!playing && main_mc.currentFrame == main_mc.totalFrames - 1) {
main_mc.stop();
}
}