How to make a for loop call an If statement every Increment of 20 AS3 - actionscript-3

Hey Everyone so I was wondering How I can make my If statement for efficient rather then creating multiple if statements for the same event.
So basically I have a If statement Like so:
if (nScoreJellyBeans == 20)
{
//Add Chocoloate bunny
chocolateBunny = new mcChocolateBunny();
stage.addChild(chocolateBunny);
chocolateBunny.x = stage.stageWidth / 2;
chocolateBunny.y = (stage.stageHeight / 2) - 90;
eggBar.destroyResourceEgg();
tChocolateEggTimer.start();
tEggTimer.stop();
tJellyBeanTimer.stop();
tBlackEggTimer.stop();
//Clear all eggs off the stage
for each(egg in aEggArray)
{
egg.parent.removeChild(egg);
aEggArray = [];
//egg = null;
}
}
Now in the same Function there are multiple of these exact If statements but they change when the score is incremented by 20.
So the Next IF statement would be if (nScoreJellyBeans == 40) so on and so on.
So how could i make it instead of making all these IF statements I would just have one loop that handled all the information in the If statement every time the nScoreJellyBean is incremented by 20?
I had an Idea of creating a for loop but not too sure how I would do it.
Does anyone have any ideas on how I can accomplish this?

You Can use condition like that
if (nScoreJellyBeans % 20 == 0) //this will work for zero also
use
if (nScoreJellyBeans % 20 == 0 && nScoreJellyBeans>0) //for greater than 0 and multiple of 20

Related

Actionscript 3.0 Splice/RemoveChild issue

I have rocks and enemy ninjas moving off the screen. The ninjas are supposed to disappear after being hit by a shuriken once, however they are taking two hits to disappear, although the shurikens disappear every time fine. The code is nearly identical for the shurikens and enemy ninjas, however the ninjas don't seem to work properly. I also get the occasional ninja getting stuck somewhere on the screen and shurikens pass through it.
//If a rock moves off the screen, it is spliced.
if (rock[j].x <= -301){
removeChild(rock[j]);
rock.splice(j, 1);
rockNum--;
}
}
for (var q=shurikens.length - 1; q >= 0; q--){
for (var w=enemy.length - 1; w >= 0; w--){
//If the shurikens hit the ninjas.
if ((shurikens[q]).hitTestObject(enemy[w])){
removeChild(enemy[w]);
enemy.splice(w, 1);
ninjaNum--;
removeChild(shurikens[q]);
shurikens.splice(q, 1);
break;
}
}
}
}
How to fix your code, and give you some performance tips:
This code is very "bug friendly": you are modifying the "length" property of array within a for/in loop that relied on the same property, this is really not a wise thing to do.
The way I would do it:
// Create an array where to store colliding ninjas and shurikens
var depleted:Array = [];
// Create local references to make code more readable and fast (querying arrays all the time is slow).
var ninja:DisplayObject;
var shuriken:DisplayObject;
// Loop in shurikens (no need to check if shurikens have been depleted, since you query only once each of them
for (var q:int=shurikens.length - 1; q >= 0; q--){
shuriken = shurikens[q]; // Assign a shuriken to our variable so you avoid to call further shurikens[q];
for (var w:int=enemy.length - 1; w >= 0; w--){ // Loop in ninjas
ninja = enemy[w]; // Assign ninja
//If the shurikens hit the ninjas. (only if ninjas have not yet been removed)
// This is the core of our improvement, before calling hitTest that is slow, you first check that ninjas have not already been killed
if (depleted.indexOf(ninja) == -1 &&
shuriken.hitTestObject(ninja)){
// It's a hit with a live ninja. I just add both objects to depleted list.
depleted.push(ninja);
depleted.push(shuriken);
break; // Breaking the loop, makes sure shuriken cannot hit 2 ninjas
}
}
}
// Then, you loop in the list of killed ninjas and depleted shurikens, and remove them from arrays and display list
for each (var depletedObj:DisplayObject in depleted) {
// First remove object from the relevant array
if (shurikens.indexOf(depletedObj) != -1) shurikens.splice(shurikens.indexOf(depletedObj), 1); // If it was in the shurikens array remove from there
else if (enemy.indexOf(depletedObj) != -1) enemy.splice(enemy.indexOf(depletedObj), 1); // If it was in the ninjas array remove from there
// The do all necessary stuff to remove object from DisplayList (end eventually add it to an object pooling list)
removeChild(depletedObj);
}
ninjaNum = enemy.length; // Update number of ninjas
Another hint, in case you run this for loops on each frame, if you place ninjas and shurikens in 2 different DisplayObjectContainer, you can first hitTest the 2 large containers, and once they collide, you can run the loops to check fine collisions. Also, in numeric for/in loops, declare variables always as :int. Typing variable makes it faster to access than an untyped variable. You can of course improve this code to make it faster, i.e.: adding a "alive = true" property to shurikens and ninjas, so you do not need to query a third array, etc.

Changing the value of a Number Bug AS3

Hey everyone so I am having some trouble here. Been at it for an hour now and can't find a solution.
So I Have a movie clip named _Bunny added to the stage like so:
_Bunny = new mcBunny;
stage.addChild(_Bunny);
_Bunny.x = (stage.stageWidth / 2) - 225;
_Bunny.y = (stage.stageHeight / 2) - 330;
Now what this _Bunny does is move across the stage horizontally from right to left in a loop which i have set up like so in a Enter_Frame event listener:
private function bunnyView():void
{
_Bunny.x += nBunnySpeed;
if (_Bunny.x >=(stage.stageWidth / 2) + 215)
{
_Bunny.gotoAndStop("leftView");
nBunnySpeed--;
}
if (_Bunny.x <=(stage.stageWidth / 2) - 215)
{
_Bunny.gotoAndStop("rightView");
nBunnySpeed++;
}
}
It's speed is the nBunnySpeed which is equal to 5. Now I have another function that I am trying to change the value of the nBunnySpeed to say 20 whenever the nScore is equal to 1 like so:
private function updateDifficulty():void
{
if (nScore >= 1)
{
//Increase Speed
nBunnySpeed = 20;
}
but the bug that in which is produces is the Bunny shooting off to the right side of the screen which is the "+x" no matter what I do this always happens.
Can anyone see what I might be doing wrong? I don't understand why this is happening. Please help!
You need some kind of a flag that indicates that the difficulty has been already updated. Then, when you call updateDifficulty it first checks if there's a real need to update speed now, if there's none, it just returns. If yes, however, then you update your bunny's speed and set that flag so that the next time the function will not alter the bunny's speed.
var diffUpdated:Boolean=false;
private function updateDifficulty():void
{
if (diffUpdated) return; // here
if (nScore >= 1)
{
//Increase Speed
if (nBunnySpeed<0) nBunnySpeed=-20;
else nBunnySpeed = 20; // retain the direction of bunny's movement
}
diffUpdated=true;
}
Now, whenever you want your difficulty to be updated, you do diffUpdated=false; and voila, bunny's speed will be updated by this. For this, however, you will need more than two levels of speed, maybe one for 10 score, one for 50 and one for say 200.
What you do in this function
private function bunnyView():void
{
_Bunny.x += nBunnySpeed;
if (_Bunny.x >=(stage.stageWidth / 2) + 215)
{
_Bunny.gotoAndStop("leftView");
nBunnySpeed--;
}
if (_Bunny.x <=(stage.stageWidth / 2) - 215)
{
_Bunny.gotoAndStop("rightView");
nBunnySpeed++;
}
}
is check whether the _Bunny is offscreen or not. And if so, the nBunnySpeed will be nBunnySpeed - 1. But since BunnySpeed = 20, it will be 20 + 19 + 18 + 17, still going right. If you'd to turn it to BunnySpeed = -BunnySpeed, it will reverse immediately and go back.

IDs and SubIDs for collision in AS3 SHMUP

My collision process involves checking simple hitbox and pixel perfect bitmap overlap before using object variables to determine if things SHOULD hit. Weapons, enemies, and objects have an ID number and collisionID array that say what should be able to affect what eg. ID = 1, collisionID = [2,3,4], ID 1 collision with ID 2, 3, or 4 are valid.
I want enemy bullets (which share an ID number with all other Weapon objects) to only be affected by a shield weapon. I figured I could make a subID variable, but I can't figure a concise way for that to be referenced. Below is the function that uses the current IDs.
private function compareHitID(object1:WorldObject, object2:WorldObject):Boolean{
var included:Boolean = false;
if(object1 != null && object2 != null){
for(var i:int = 0; i <= object1.collisionID.length - 1; i++){
if(object1.collisionID[i] == object2.gameID)
included = true;
}
}
return included;
}
Any ideas on how to include subIDs, and store and reference them neatly would be greatly appreciated.

Number generation going Wrong

I am trying to generate a random number and comparing with another number, if they are the same i want the random number to increase by one and then add it to the stage. but if it's different to begin with I want it to directly add it to the stage. but it's not working properly if the numbers are same, it does go through radomize++ but still adds the initial number that was generated messing everything up. can somebnody please help me on how to fix this?
function randomizedorder()
{
randomize = Math.floor(Math.random() * (choices.length));
trace("the random number is" + randomize);
if (randomize == indexcount ) {
randomize++;
trace ("it goes through this pahse" + randomize);
}
else {
addChild(choices [randomize]);
}
}
want the random number to increase by one and then add it to the stage
yet you are increasing it by one and not adding anything to the stage since the addChild is in the else clause.
function randomizedorder()
{
randomize = Math.floor(Math.random() * (choices.length));
trace("the random number is" + randomize);
if (randomize == indexcount ) {
randomize++;
randomize = randomize % choices.length;
trace ("it goes through this pahse" + randomize);
}
addChild(choices [randomize]);
}
Also you need to decide on what to do if randomize is equal to indexcount and is also equal to choices.length-1 in that case you can't use it to undex choices.
Edit: I added the modulus operator so if the randomize goes out of bounds it will go back to 0.

Nape Moving Platform

Okay Im relatively new to nape and Im in the process of making a game, I've made a Body called platform of type KINEMATIC, and I simply want to move it back a forth in a certain range on the stage. Can somebody please see where im going wrong , thanks.
private function enterFrameHandler(ev:Event):void
{
if (movingPlatform.position.x <= 150 )
{
movingPlatform.position.x += 10;
}
if (movingPlatform.position.x >= 260)
{
movingPlatform.velocity.x -= 10;
}
}
First of in one of the if blocks you are incrementing position.x by 10 in the other one you are decrementing velocity.x by 10. I guess you meant position.x in both.
Secondly, imagine movingPlatform.position.x is 150 and your enterFrameHandler runs once. movingPlatform.position.x will become 160 and on the next time enterFrameHandler is called none of the if blocks will execute since 160 is neither less than or equal to 150 or greater than or equal to 260.
You can use the velocity to indicate the side its moving and invert it once you go beyond an edge, something like :
// assuming velocity is (1,0)
private function enterFrameHandler(ev:Event):void {
if (movingPlatform.position.x <= 150 || movingPlatform.position.x >= 260) {
movingPlatform.velocity.x = -movingPlatform.velocity.x;
}
movingPlatform.position.x += movingPlatform.velocity.x;
}
Obviously this might cause problems if the object is already at let's say x=100, it will just keep inverting it's velocity, so either make sure you place it between 150-260 or add additional checks to prevent it from inverting it's direction more than once.
This might be a better way of doing it :
// assuming velocity is (1,0)
private function enterFrameHandler(ev:Event):void {
if (movingPlatform.position.x <= 150) {
movingPlatform.velocity.x = 1;
} else if (movingPlatform.position.x >= 260) {
movingPlatform.velocity.x = -1;
}
movingPlatform.position.x += movingPlatform.velocity.x;
}
In general:
Kinematic bodies are supposed to be moved solely with velocity, if you change their position directly then they are not really moving as much as they are 'teleporting' and as far as the physics is concerned their velocity is still exactly 0 so things like collisions and friction will not work as you might expect.
If you want to still work with positions instead of velocities, then there's the method setVelocityFromTarget on the Body class which is designed for kinematics:
body.setVelocityFromTarget(targetPosition, targetRotation, deltaTime);
where deltaTime is the time step you're about to use in the following call to space.step();
All this is really doing is setting an appropriate velocity and angularVel based on the current position/rotation, the target position/rotation and the amount of time it should take to get there.