Check the existence of an object instance - actionscript-3

I'm surprised I don't know how to do this, but as it turns out I really don't; simply put, I'm trying to make a side-scrolling shooter game, a basic one and in it, I have 50 stars spawned on-screen through a "for" loop upon the game starting. There is a function which does this and a listener is at the beginning. Problem is, when you lose the game and go back to main menu, 50 more stars would be spawned, which isn't what I want. So, I'm trying to make an "if" statement check at the beginning, so that the game checks whether there is an instance/movie clip of the star object/symbol before determining whether the function that spawns stars should be called out with a listener. So, how do I do this? I looked through some other checks and they didn't help as the codes presented were vastly different there and so I'm just getting errors.
Let me know if a better explanation is needed or if you would like to see some of the code. Note that the game overall already has a lot of code, so just giving all of it would probably not be helpful.

I suggest you rethink your approach. You're focusing on whether stars have been instantiated. That's ok but not the most basic way to think about it.
I would do this instead
private function setup():void{
loadLevel(1);
addListeners();
loadMusic();
// etc...
// call all functions that are needed to just get the app up and running
}
private function loadLevel(lev:int):void{
addStars();
// call all functions that are needed each time a new level is loaded
}
private function restartLevel():void{
// logic for restarting level,
// but this *won't* include adding star
// because they are already added
}
There are other ways to do this but this makes more sense to me than your approach. I always break my game functions into smaller bits of logic so they can be reused more easily. Your main workhorse functions should (IMHO) primarily (if not exclusively) just call other functions. Then those functions do the work. By doing it this way, you can make a function like resetLevel by assembling all the smaller functions that apply, while excluding the part about adding stars.

Here's what I did to solve my problem... Here's what I had before:
function startGame():void
{
starsSpawn();
//other code here
}
This is what I changed it to:
starsSpawn();
function startGame():void
{
//other code here
}

when you said existance, so there is a container, i named this container, (which contain stars , and stars was added to it) as starsRoot, which absolutely is a DisplayObject (right?)
now, to checking whole childrens of a DisplayObject, we have to do this :
for (var i:int=0; i<starsRoot.numChildren; i++) {
var child = starsRoot.getChildAt[i];
}
then, how to check if that child is really star!?
as you said
whether there is an instance/movie clip of the star
so your stars's type is MovieClip, and they don't have any identifier (name), so how to find them and make them clear from other existing movieclips. my suggestion :
define a Linkage name for stars from library, thats a Class name and should be started with a capital letter, for example Stars
now, back to the code, this time we can check if child is an instance of Stars
for (var i:int=0; i<starsRoot.numChildren; i++) {
var child = starsRoot.getChildAt[i];
if (child is Stars) {
// test passed, star exist
break;
}
}

Related

How can i get a function to use any movie clip?

I'm a little lost in understanding this kind of function, i get the feeling this has been asked a thousand times but cannot find an explanation of what the code is doing.
Basically i just want a movie clip with instance name box to do something, then reuse the function for other movie clips afterwards
a little like this, but working.
Many Thanks
//my function to be used on "instance name" box
myfunc (box);
function myfunc ();
{
while (this is happening);
{
//in this case box.x = goes where ever i put it
.x = goes here
.y = goes here
}
}
Sorry it's not quite English, my communication skills are terrible
Sure you can do that. You give the function a parameter, then refer to a parameter to change its properties. With such a simple movement function it could accept a DisplayObject - a distant superclass of a MovieClip and thus a superclass to many other possible classes of those objects that can be displayed by Flash.
function myfunc(param:DisplayObject):void {
// no semicolon after declaring the function!
while (somethingIsHappening(param)) {
// why not call a query on that object?
param.x+=1; // move right by 1 pixel
}
}
You might want to look at this manual on ActionScript 3 syntax, and the following pages on variables, functions and classes, to learn more.

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!.

Issues correctly removing childs from flash

hey im having issues removing my enemy blocks. at the moment if i hit everyone of them everything is fine but when i avoid one i get an error message of
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at EnergyJump/onTick()
at flash.utils::Timer/flash.utils:Timer::_timerDispatch()
at flash.utils::Timer/flash.utils:Timer::tick()
here is my code i have:
public function onTick( timerEvent:TimerEvent ):void
{
//if ranrom number is than than i
if ( Math.random() < i )
{
//place block on stage at location X=550, Y=330
var randomX:Number = Math.random() * 550;
var newBlock:Blocks = new Blocks( 550, 335 );
army.push( newBlock );
addChild( newBlock );
//increase speed of spawn
i = i + 0.0001;
}
//move blocks in correct direction
for each ( var block:Blocks in army )
{
block.move();
//if block is hit then remove health and remove child object
if ( avatar.hitTestObject( block ) )
{
hp.checkHP(20);
army.splice(army.indexOf(block), 1);
removeChild( block );
}
}
}
can anyone help me, i dont really know what slice is to be honest or how to use it...
You should have a look at the documentation for Array.splice() here.
The first argument needs to be the index (0, 1, 2 etc.) of the item you want to remove, not the item itself. Flash is trying to read block as an integer, but it defaults to 0, so instead of removing the block that has been hit it's just removing the first block in the list. Try this instead:
army.splice(army.indexOf(block), 1);
I assume you have some code which is clearing any remaining blocks in the list at the end of the game, but because the wrong blocks are being removed from the list it's trying to remove some that were actually hit already.
Are you sure there is a corresponding addChild() call for each of those objects that has been made before the call to removeChild()? There's not enough code being shown, at the moment, to be able to really tell what's going on, but also make sure removeChild() isn't being called more than once on the same object without addChild() being called in between each time.
Okay, I had a quick look through your files. It's getting a bit off topic for this question, but I'll list the problems I found. In general though you need to look at the parts Flash is complaining about and make sure you're really working with the right variables (eg. if you write block, try to make sure you know which block Flash is going to look at, and remember that the order matters when you change things.)
It's easy to accidentally remove the wrong items or try to use things that are null, so check each line and think about what each variable actually is at that point (maybe try tracing the variables out too).
In avatarEnterFrame you're checking for blocks that have gone off the side of the screen, but you haven't added a for each loop like in onTick, so when you use block there Flash is looking at your main public var block:Blocks; instead of the blocks in army.
In onPowerTick you need to adjust your splice in the same way as before, so that you remove the powerups object you're checking instead of the item at 0.
In restartGame you're setting gameOverScreen to null just before trying to remove it, so Flash doesn't know what to remove. Make sure you leave setting it to null until you're done with everything else.
I'll post a separate answer for your game over screen problem so that it's in the right place.

Is my class-less AS2 programming close to OOP in spirit?

So I'm a flash game developer trying to make the transition from AS2 to AS3+OOP, only 3 years or so after everybody else did. There's a plethora of free, very helpful material to go through and I've been spending 2-3 days wrapping my head around some of it, but by now I feel like I just want to start and try it out and learn the harder stuff as I go (just like I did with AS2).
I get the benefits of (most aspects of) OOP and I was once forced to learn to do a couple of games in Processing which had me write a few classes and I really liked the whole inheritance thing, which is the biggest reason I'm keen to move on, I think.
I just wanted to ask about game structure - is my current way of AS2 programming (see the example below, with some pseudo code) close to the way you'd organize things in OOP, or are there some big flaws in my game logic/structure that I can't see? The way I understand I would have to do differently in AS3/OOP is to have a class for moving stuff such as the player, hero, missiles etc, then have an enemy class that extends that class, then have classes for each enemy that extends the enemy class, unlike now where each "class" is instead an object and a function called from the main game loop, and sub-classes are instead "if"-clauses in each function. But except for that, is my programming style on the right track or do I need to re-think the logic behind my code for it to work effectively in an AS3/OOP setting?
Any advice will be much appreciated!
function initializeF() {
initializeVariablesF();
startGameF();
}
function initializeVariablesF() {
enemyO = new Object(); //which will contain each enemy instance
enemyA = new Array(); //which will be a list of all the enemies, maybe superfluous?
playerShotsA=new Array();
//and so on...
enemyDataO = new Object();
enemyDataO.goblin = new Object();
//and then some vars relating to the goblin, sort of a class without methods, right?
}
function startGameF() {
this.onEnterFrame = function() { //my game loop
checkKeysF(); //checks which keys are pressed, saves it to a global object
playerMovementF(); //moves the player about depending on which keys are pressed
playerShotsF(); //deals with the missiles/shots/lasers the player has shot
enemyCreatorF(); //decides when to create a new enemy
enemyF(); //deals with all enemies in the enemyA
enemyShotsF(); //deals with the missiles/etc the enemies have created
};
}
function enemyCreatorF(){
//randomly creates an enemy through a "factory" function:
if (random(20)==1){
attachEnemyF(enemyDataO.goblin, ...and some values like position etc)
}
}
function attachEnemyF(a_enemyType, ... a bunch of values like position){
//create a new enemy object
var enemy=enemyO[new unique enemy name]
enemy.enemyType=a_enemyType
enemy.clip=attachMovie(a_enemyType,"clip", [values like x and y passed on])
enemyA.push(enemy)
}
function playerShotsF(){
for (every shot in playerShotsA){
//move it about
for (every enemy in enemyA){
//if it hits an enemy, add damage to the enemy
}
}
}
function enemyF() {
for (every enemy in enemyA) {
//check if it's dead/less health than zero, if so remove it from the array, remove it's clip, null it's object
//if it's not, move it about, maybe have it shoot
//if it touches the player, decrease the player's health
//different behavior depending on the enemy's type by "if" or "switch" statements
}
}
I'm not sure the question is a good fit for SO as it's mostly asking for opinions, but anyway:
Having a base class with basic functions such as "move", "hitTest", "render", etc. is indeed what you should do. Then have the player's avatar, enemies, etc. inherit from this class.
The F suffix (and even O and A suffixes) are quite superfluous, since any good AS3 editor will already tell you whether the class member is a function, or an array, object, etc.
You don't need to store your enemies in both an array and an object, it's going to make it unnecessary complicated to remove or add an enemy. Instead, just store them all in an array and use simple loops to inspect their properties.

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.