Number generation going Wrong - actionscript-3

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.

Related

Control timeline with pinchzoom in Actionscript 3.0

I'm using Actionscript 3.0 in Flash. Is there a way to control the timeline with pinching (so instead of zooming out/in you are moving the timeline back/forth)? I'm working on an story app where the player is in control of the story.
You could do something like the following:
import flash.events.TransformGestureEvent;
Multitouch.inputMode = MultitouchInputMode.GESTURE;
stop();
//listen on whatever object you want to be able zoom on
stage.addEventListener(TransformGestureEvent.GESTURE_ZOOM , zoomGestureHandler);
function zoomGestureHandler(e:TransformGestureEvent):void{
//get the zoom amount (since the last event fired)
//we average the two dimensions (x/y). 1 would mean no change, .5 would be half the size as before, 2 would twice the size etc.
var scaleAmount:Number = (e.scaleX + e.scaleY) * 0.5;
//set the value (how many frames) to skip ahead/back
//we want the value to be at least 1, so we use Math.max - which returns whichever value is hight
//we need a whole number, so we use Math.round to round the value of scaleAmount
//I'm multiplying scaleAmount by 1.25 to make the output potentially go a bit higher, tweak that until you get a good feel.
var val:int = Math.max(1, Math.round(scaleAmount * 1.25));
//determine if the zoom is actually backwards (smaller than before)
if(scaleAmount < 1){
val *= -1; //times the value by -1 to make it a negative number
}
//now assign val to the actual target frame
val = this.currentFrame + val;
//check if the target frame is out of range (less than 0 or more than the total)
if(val < 1) val = this.totalFrames + val; //if less than one, add (the negative number) to the totalFrames value to loop backwards
if(val > this.totalFrames) val = val - this.totalFrames; //if more than total, loop back to the start by the difference
//OR
if(val < 1) val = 0; //hard stop at the first frame (don't loop)
if(val > this.totalFrames) val = this.totalFrames; //hard stop at the last frame (don't loop)
//now move the playhead to the desired frame
gotoAndStop(val);
}

AS3 - How can multiple objects that appear randomly NEVER touch each other?

I have multiple objects that appear randomly on stage, but i want them to never touch each other when they appear.
object1.x = Math.random() * stage.stageWidth;
object1.y = Math.random() * stage.stageHeight;
object2.x = Math.random() * stage.stageWidth;
object2.y = Math.random() * stage.stageHeight;
object3.x = Math.random() * stage.stageWidth;
object3.y = Math.random() * stage.stageHeight;
etc...
And also how can i make them appear inside a box, instead of the stage.
I have multiple objects that appear randomly on stage, but i want them
to never touch each other when they appear
They obviously can't appear at random then.
A naive but quick to code solution is to use bounding box collision before actually placing the element using:
// http://stackoverflow.com/questions/2752349/fast-rectangle-to-rectangle-intersection
function rectIntersection(r1,r2) {
return !(r2.left > r1.right ||
r2.right < r1.left ||
r2.top > r1.bottom ||
r2.bottom < r1.top);
}
If there is indeed a collision you can re-run the random placement of that particular element until there is not any collision.
This method is naive because you need to run the collision detection for all elements on your screen each time you are attempting to do a random placement. If it fails (meaning there is a collision), then you need to run it again until there is not.
Keep in mind that you can also pre-calculate the placements instead of checking on animation runtime (if it's an animation).
For the second part of you question.
And also how can i make them appear inside a box, instead of the
stage.
Instead of using the stageWidth as a placement variable, you can use a function that returns a random integer within a range.
The ranges provided would be:
top-left/top-right for width
bottom-left/bottom-right for height
..of the box you want to constraint your elements in.
The function would return a random integer within those ranges and your boxes would always fall within that box.
Here's a code snippet to get you started:
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

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.

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.

How to display the highest value from a random created list of numbers in AS3

I m building kind of a game in Flash (AS3) where sound input (microphone) trigger a equalizer (the micLevel.height controls the height of a mask (showing the equalizer). The activityLevel of the microphone gives me a number ( 0 - 100 ) wich is displayed in textfield prosent. The contestant shout in the microphone and try to reach 100 ( I use the mc.gain to make it hard to reach 100 ). So far so good! I m pretty new to AS3 so I feel kind of lost.
I need to display the highest number they manage to reach and I want to have a time limit on this. The highest sound level in lets say 5 seconds.
Here is the code so far:
var mic:Microphone = Microphone.getMicrophone();
Security.showSettings("privacy");
mic.setLoopBack(true);
if(mic != null)
{
mic.setUseEchoSuppression(true);
stage.addEventListener(Event.ENTER_FRAME, showLevel);
}
function showLevel(e:Event)
{
micLevel.height = mic.activityLevel * 6;
//mic.gain = 1;
//trace(mic.activityLevel);
prosent.text = "Activity: " + String(mic.activityLevel) + "%";
}
I just need some code that grab the highest number from the text field "prosent" (with a time limit) and display it in a new text field.
Im sorry if I m unclear, but if anyone could help me out I would be very happy!
Br Harald
Just create a variable that will be updated whenever the micLevel.height value is higher than it, e.g.
var highest:Number = 0;
function showLevel(e:Event):void
{
if(micLevel.height > highest)
{
// The mic level was higher than the previous highest level.
highest = micLevel.height;
// Change your other text field to show the value of 'highest'.
// ..
}
prosent.text = "Activity: " + String(mic.activityLevel) + "%";
}
Start a Timer to reset your highestLevel var. This will show you then the highest level every 5 seconds. You could add a timer start-stop button too if you wanted to keep one highest always showing.
Then in your showLevel function, use Math.max() to get the highest number (between current activity and recent highest)
var highestLevel:Number = 0;
var timer:Timer = new Timer(5000); // fires every 5 seconds
function initLevels(e:TimerEvent){
timer.stop(); // you could stop your timer here automatically and then use a button to start again
highestLevel = 0; // when timer fires restart your highestLevels var
}
function showLevel(e:Event) {
highestLevel = Math.max(mic.activityLevel * 6, highestLevel);
prosent.text = "Activity: " + String(highestLevel) + "%";
}
timer.start();
timer.addEventListener(TimerEvent.TIMER, initLevels);
addEventListener(Event.ENTER_FRAME, showLevel);