why is only one actionscript working at a time? - actionscript-3

I'm new to Flash and trying to build a very simple game involving moving one movieclip using arrowkeys and avoiding three other movie clips. There is also a start button on the first frame. Each individual actionscript works by itself as long as the other 4 are commented out. But as soon as I try to use more than one actionscript, none of them work. I have each actionscript in it's own layer.
I'm sure it's something obvious I'm missing , but how do multiple actionscripts at the same time work?
Any thanks would be greatly appreciated
Here's the code
/*Start*/
import flash.events.MouseEvent;
stop();
btn1.addEventListener(MouseEvent.CLICK,buttonClickHandler);
function buttonClickHandler(event:MouseEvent):void{
gotoAndPlay(2);
}
/*Drive*/
function hearKey(yourEvent:KeyboardEvent):void{
if (yourEvent.keyCode==Keyboard.RIGHT){
LionOne_mc.x += 8;
};
if (yourEvent.keyCode==Keyboard.LEFT){
LionOne_mc.x -= 8;
};
if (yourEvent.keyCode==Keyboard.UP){
LionOne_mc.y -= 8;
};
if (yourEvent.keyCode==Keyboard.DOWN){
LionOne_mc.y += 8;
};
};
stage.addEventListener(KeyboardEvent.KEY_DOWN,hearKey);
/*Colision*/
kangaTwo.addEventListener(Event.ENTER_FRAME,LionHit2);
function LionHit2(event:Event):void {
if (kangaTwo.hitTestObject(LionOne_mc)) {
tackle_mc.visible = true;
} else {
tackle_mc.visible = false;
}
}

You can have scripts across multiple layers in a frame. There is no problem with that. They will just run from top most layer, to the bottom.
Although it is technically possible, I would not recommend it. Timeline code is messy at the best of times, so it is best to keep it all in one layer. It is also best practice for this layer to be at the top, with no visual element on it, and for the layer to be named "Actions".
If you are calling gotoAndStop(2);, then all the code on frame one will stop running.
When you get the chance you should definitely look at using external ActionScript classes, rather than writing timeline code. There is a great tutorial here: active.tutsplus.com - AS3 101: OOP Introduction – Basix

Related

Possible to have multiple timelines? (separate part without affecting the keyframes of other layers) AS3

http://i.snag.gy/eu7iz.jpg
So im doing this generator/designer on flash. It has different features on it so the keyframes clashes with other features considering a lot of the action scripts deal with nextframes and gotos. Its getting confusing once i add little features.
Like right now i wanna add next buttons for the design part. I can do it easily with a blank stage, i can easily click next and back, but when applied to my project, its getting a little dizzying.
This is the script for the first frame:
stop();
small.addEventListener(MouseEvent.CLICK,play1);
function play1(event:MouseEvent):void{
gotoAndStop("3");
}
medium.addEventListener(MouseEvent.CLICK,play2);
function play2(event:MouseEvent):void{
gotoAndStop("6");
}
large.addEventListener(MouseEvent.CLICK,play3);
function play3(event:MouseEvent):void{
gotoAndStop("8");
}
item_mc.addEventListener(MouseEvent.MOUSE_DOWN, dragTheObject);
item_mc.addEventListener (MouseEvent.MOUSE_UP, itemRelease);
item_mc1.addEventListener(MouseEvent.MOUSE_DOWN, dragTheObject);
item_mc1.addEventListener (MouseEvent.MOUSE_UP, itemRelease);
item_mc2.addEventListener(MouseEvent.MOUSE_DOWN, dragTheObject);
item_mc2.addEventListener (MouseEvent.MOUSE_UP, itemRelease);
function dragTheObject(event:MouseEvent):void {
var item:MovieClip=MovieClip(event.target);
item.startDrag();
var topPos:uint=this.numChildren-1;
this.setChildIndex(item, topPos);
}
function itemRelease(event:MouseEvent):void {
var thisItem:MovieClip=MovieClip(event.target);
thisItem.stopDrag();
};
This is the fla file: https://www.dropbox.com/s/77euop1luqjreos/FINAL.fla
MovieClips have their own timeline.You may want to modularize your program into Movieclip components and export for Actionscript manipulation that you can instantiate at run time as necessary. Now that is one way to do it to avoid code spread across one single timeline.But If you still want to stick to your way (use of single timeline), You still could achieve your next/previous implementation without affecting frame logic at any rate.A simple way to do this goes like this:
Encapsulate all logic into functions and put these functions solely on frame 1 and nothing else.
This keeps logic clean and separate from the components.Also, the logic layer in principal should not have nothing else.Why on Frame 1?. Well, we want to expose and keep in memory first the logic, so that whatever component related code that follows on the subsequent frames should be aware of the previous logic and hence throw no run time errors when interacting frame 1 logic.
Spread your components and related code across the subsequent frames respectively.
Put only component related code on a frame that has the component in question. registering event listeners could have targets as their dependency. define event listeners and put them on frame 1 as part of the logic and simply put code for registering listeners on the component frames as per demand.
Example:
//On Frame 1
function onAMouseClick(event:Event):void
{
//implement logic
}
function onBMouseClick(event:Event):void
{
//implement logic
}
//Implemented function for next/back buttons
//Also on Frame 1
function navigate(event:Event):void
{
var frame:int;
switch(event.target.name)
{
case "nextBtn":
frame=currenFrame<numFrames?+1:numFrames;
gotoAndStop(frame);
break;
case "backBtn":
frame=currenFrame>2?-1:currentFrame;
gotoAndStop(frame);
break;
}
}
//On Frame 2 for A component
A.addEventListener(MouseEvent.CLICK, onAMouseClick)
//On Frame 3 for B component
B.addEventListener(MouseEvent.CLICK, onAMouseClick)
Put Next/Back button components on a single layer spreading from frame 2 all the way to the end of the last frame where you want the buttons to be visible. Then implement related code having its visibility spanning across between frame 2 and the last frame as the following shows:
//navigate handler is declared and implemented on **frame 1**
nextBtn.addEventListener(MouseEvent.Click, navigate)
nextBtn.addEventListener(MouseEvent.Click, navigate)
Well, that is your way of doing things (Single timeline scripting). Not bad for simple timeline scripting.You may try the other way also of instantiating Movieclips (exported for action scripiting)
at run time and the add these to the display list as per demand as on clicks next/back buttons.In doing so you will not only have one single point of logic but will have MC code encapsulated in each individual component.
Hope the foregoing helps. Thanks.
Do not be scared to change code! Let alone afraid to run into errors! That's way forward you want to learn to fix things that's a beauty of it!
.....cheers!.

Action Script 3. Multiple stages are like 1

I'm creating a simple flash game, where characters move on the groundwith some stages to jump over.
The problem is all the stages are acting as 1 object, which can make the character appear like it's flying in the air:
All stages are called: ground3
Here is part of code where the character jumps and stay on the ground:
if(Hero.y_speed>0 && Hero.hitTestObject(ground3)){
Hero.y_speed=0;
if(space){
trace("You clicked SPACE");
Hero.y -= 80;
}
Have you any ideas how to fix this?
Use external libraries for your purposes, like
this one.
Here is described, how to use it (you can find there also other useful informations).
import com.coreyoneil.collision.CollisionList;
var myCollisionList:CollisionList = new CollisionList(hero);
//add all stages separately
myCollisionList.addItem(stage[1...n]);
if(myCollisionList.checkCollisions().length > 0) {
//colision detected
}

ActionsScript 3 Collision

Frog
I'm developing a flash game called Frog, at the moment my code for collision between my frog and fly doesn't work as expected. I'd like to have it so it works something similar to the method linked below (last example).
Collision detection methods, hitTest and hitTestObject alternatives
Any help would be appreciated.
function hitTargetFunction():void {
for (i = 0; i < insectsMC.length; i++) {
for (j = 0; j < insectsMC[i].length; j++) {
if (frogMC.hitTestObject(insectsMC[i][j])) {
trace('Target: ' + insectsMC[i][j].name);
score += 1;
trace('Score: '+score);
insectsMC[i][j].x = 0 - insectsMC[i][j].width * 2;
}
}
}
}
Might I suggest trying out the fantastic Collision Detection Kit?
I'm sure it will do everything you need and more. It's also AS3 which is what your code sample is written in, so I hope you find it useful.
Creating a movieclip/sprite inside the frog movieclip will probably be the best thing for you in this situation. PixelPerfectCollision is very awesome and useful(however on larger games, expensive) but the collision would then be with any piece of the frog. You could of course break apart your frog movieclip and just do PixelPerfectCollision on just the tongue. But if this is for coursework I'd stick to just doing hitTest() on a display object of some kind inside the the frog.
If you're not allowed to use a third-party library for your coursework you should have a look at this excellent tutorial on pixel-level collision detection with ActionScript 3.0.
The general idea is that you create BitmapData copies of your vector graphics and use the hitTest method of that class to check for a collision at a pixel-level.

Game logic and game loops in ActionScript 3

I am making a Shooting game in flash actionscript 3 and have some questions about the flow of logic and how to smartly use the OOPs concepts.
There are mainly 3 classes:
Main Class: Initializes the objects on the screen.
Enemy Class: For moving the enemies around on the screen.
Bullet Class: For shooting.
What I want to do is find out if the Enemy has been hit by a bullet and do things which must be done as a result ...
What I am doing right now is that I have a ENTER_FRAME event in which i check collision detection of each enemy unit (saved in an array) with the bullet instance created, and if it collides then perform all the necessary actions in the Main class .. clogging the Main class in the process ..
Is this the right technique ? or are there better solutions possible ?
Try to think more OOP, what is every object responsible for?
We have the enemies wich we can hit:
class Enemy : extends NPC implements IHittable {
. . .
function update(delta) {
// move, shoot, etc.
}
function handleHit(bullet) {
// die
}
}
A hittable object:
interface IHittable {
function handleHit(bullet);
}
The bullet is suppose to move and hit things:
class Bullet : {
function update(delta) {
// update position
}
function checkHits(world:World) {
for each(var hittable:IHittable in world.objects) { // might want to cluster objects by location if you're handling lots of objects / bullets)
if (isColidingWith(hittable))
o.handleHit(bullet);
}
}
}
And then we have the world with everything inside:
class World {
var npcs: Array ...
var bullets: Array ...
var hittables: Array ...
function update(delta) {
foreach(var c:NPC in npcs)
c.update(delta);
foreach(var b:Bullet in bullets) {
b.update(delta);
b.checkCollisions(world);
}
}
}
And your main loop is just simple as that:
var lastTime:int;
function onEnterFrame(...) {
var now:int = getTimer(); // FlashPlayer utility function to get the time since start (in ms)
world.update(now - lastTime);
lastTime = now;
}
A few other notes:
try to do all the computation based on a delta of time, otherwise the game's speed will vary with the framefrate.
what happens when a character dies? bullet disappear? Well, you could do it several ways:
fire an event, like EnemyDied and remove it from the world
implement an interface CanDie that has a (get dead():Boolean property) and use that to cleanup the world at every update.
but don't write the code to remove the enemy in the Enemy class, because then you will be polluting the class with code that should be handled by the World, and that will be hard to maintain later.
Sorry for the long answer, but I couldn't help myself :)
Was clogging the Main class the problem, or finding out what bullet hit what enemy the problem? If it was the bullet, you need to describe the bullet behavior - can it hit multiple enemies, how fast does it move (is it possible that when testing using "enterFrame" the bullet will first appear in front of the enemy, and, on the second frame, it will appear behind the enemy?). May enemy be simplified to some basic geometrical shape like circle or rectangle, or do you need pixel-perfect precision? Finally, how many bullets and how many enemies are you planning to have at any one time? It could be too expensive to have a display object per bullet, if you are going to have hundreds of them, and then it could make more sense to draw them into single shape / bitmapdata.
If the problem is that the Main class is too long, there are several possibilities here.
A nobrainer answer to this problem - use inheritance to simply put parts of the code in separate files. Not the best way, but a lot of people do it.
If you did the first, then you'd realize that there are certain groups of functions you put into superclass and subclasses - this will help you split the "clogged" class into several smaller independent pieces that have more particular specialization.
After you did the second, you may find out that there is certain dependency between how you split the big class into smaller classes, so you can try generating those smaller classes by a certain pattern.
And then you write the clogged code that generalizes those parts you just managed to split.
Above is basically the cycle from more concrete to more generic code. In the process of perfecting the last step, you'll write some concrete code again. And that will move you to the step 1. Lather, rinse, repeat :) In fact, you don't want to write OO code, or procedure code or anything that fashion of the day tells you to do. You want to write good code :) And you do it by moving from more generic to more specific and back to more generic, until it's perfect :P
Probably not the best answer, but you must admit, you didn't give much info to give you more precise answer.

AS3 Flip effect leaving a trail?

I'm trying to create something with a flip effect tutorial from tutplus - http://active.tutsplus.com/tutorials/effects/iphone-page-transition-flash/
However my flip area is much bigger than the tutorial, it's 900px wide. Everything works fine except that it leaves a trail when the width is that big. You'll see it when you flip it a few times.
Someone else posted the same problem in the comments from last year, but no one replied.
Does anyone know a solution to this?
Edit:
Here is a screen shot: http://imageshack.us/f/823/unled2lo.jpg/ (click to enlarge)
The front is purple and the back is white.
As you can see it left a bit of the purple as the page flipped to white.
I couldn't get a screen shot of it turning, but it's even more obvious as the page is actually flipping because the width become narrow which reveals a whole lot more that's left behind on the page.
The tutorial you are using create the flip effect using the build in flash tween classes, they are absolute rubbish, and very slow if you compare to other third part tween classes. That may be causing the trail! Lee Brimelow has a great video tutorial about how to do exact what you need: http://gotoandlearn.com/play.php?id=91 he is using caurina, but I highly recommend you to replace it with tweenLight so far the best tween I ever used.
Ok, thats the walkthrough:
1- Download the files from Lee Brimelow tutorial here http://gotoandlearn.com/files/3dflip.zip
2- Download tweenLight AS3 classes here: http://www.greensock.com/tweenlite/
3- copy the com folder inside greensock-as3 and past it inside 3dflip folder. Now you have all the tween classes you need for your flip!
4- open the flash file 3dflip.fla and replace the original code (located in the first frame) with this:
import com.greensock.TweenLite;
import fl.video.*;
con.visible = false;
var flv:FLVPlayback = con.vid.flvp;
flv.addEventListener(VideoEvent.PLAYING_STATE_ENTERED, onStart);
function onStart(e:Event):void
{
con.visible = true;
loading.visible = false;
}
con.vid.spin.addEventListener(MouseEvent.CLICK, cl);
con.tclip.spin.addEventListener(MouseEvent.CLICK, cl);
var isTurning:Boolean = false;
function cl(e:Event):void
{
if(!isTurning)
{
TweenLite.to(con, 1, {rotationY:con.rotationY+180, onComplete:function(){isTurning=false;}});
isTurning = true;
}
}
addEventListener(Event.ENTER_FRAME, loop);
function loop(e:Event):void
{
if(con.rotationY > 90 && con.rotationY < 270)
con.addChild(con.tclip);
else
con.addChild(con.vid);
if(con.rotationY >= 360) con.rotationY = 0;
}
Thats it. Now publish and see the result. Now all you have to do is replace the video player with the content that you want!
I would check the state of first side - it seems that it's forgotten on stage when "the other side" kicks in.