Convert a decimal number to a fraction AS3 - actionscript-3

I'm trying to get to convert the decimals to a fraction so for example, I had written something such as var _pow:int = Math.pow(base,i) and if i turned out to be a negative number it would give out a decimal (example: 3 ^ -2) and I'm currently stuck trying to find a way to turn _pow into a franction (so _pow out of a 100) so I tried to do var _pow:int = Math.pow(base,i) * 100 which should stop it from being a decimal but it's not showing in the dynamic text, and this only happens if i is negative
package{
import flash.display.*;
import flash.events.MouseEvent;
public class name_ extends MovieClip{
public function _name_(){
btn.addEventListener(MouseEvent.CLICK, input)
base.restrict = "0-9\\.\\-";
pow.restrict = "0-9\\.\\-";
answer.multiline = true;
}
private function input(event:MouseEvent):void{
var pow = pow.text;
var base = base.text;
var answerText:String = "";
if(pow > 0){
for(var i = 1; i <= pow; i++){
_pow = Math.pow(base,i);
answerText += ("\n" + base + " exposant(power) " + i + " = "+ _pow );
answer.text = answerText;
}
}else{
for(i = 1; i <= pow; i++){
var _pow:int = Math.pow(base,i) * 100
answerText += ("\n" + base + " exposant(power) " + i + " = "+ _pow );
answer.text = answerText; //Dynamic text
}
}
}
}
}

Have you tried using an "if" statement? Something like if(i <= 0){code}.
You can also try using the Math.floor(number to be rounded down); or Math.ceiling(number to be rounded up)

Related

Text Field Not Updating

I'm trying to get the log on my program to update with every button press *see picture below, however it will only display the data on the first time it has been pressed. I'm not sure if that's because it's in a for loop.
Initialise button
stop();
import flash.events.MouseEvent;
var MAX_ORGANISMS: int = 12;
var MAX_GENES: int = 2;
var genotype: Array = new Array();
var MAX_PARENTS: int = 2; // number of parents organisms to select
var MAX_CHILDREN: int = 2; // number offspring per selected parent
var generation: int = 0; // to count the generation being shown
var list_selected: Array = new Array(); // list of selected org.
var number_selected: int;
var geno_text: String = "";
function random_genotype_initialisation(): void {
generation = 0;
number_selected = 0;
var org: int;
for (org = 0; org < MAX_ORGANISMS; org++) {
list_selected[org] = 0;
var genotype_1organism: Array = new Array();
genotype_1organism[0] = randomRangeInteger(1, 4);
// gene1 = head colour (4 types)
genotype_1organism[1] = randomRangeInteger(46, 49);
// gene2 = head width (44 - 48)
genotype_1organism[2] = randomRangeInteger(50, 55);
// gene3 = head legnth
genotype_1organism[3] = randomRangeInteger(1, 4);
// gene4 = eye type (4 types)
genotype_1organism[4] = randomRangeInteger(30, 35);
// gene5 = eye width (30 - 35)
genotype_1organism[5] = randomRangeInteger(1, 4);
// gene6 = nose type (4 types)
genotype_1organism[6] = randomRangeInteger(10, 18);
// gene7 = nose height (10 - 18)
genotype[org] = genotype_1organism.slice();
}
}
function randomRangeInteger(min: int, max: int): int {
var randomNum: int = Math.floor(Math.random() * (max - min + 1)) + min;
return randomNum;
}
function show_phenotype(): void {
var org: int;
var org_property: String;
for (org = 0; org < MAX_ORGANISMS; org++) {
org_property = "o" + org + "_head";
this[org_property].gotoAndStop(genotype[org][0]);
this[org_property].width = genotype[org][1];
this[org_property].height = genotype[org][2];
org_property = "o" + org + "_eyes";
this[org_property].gotoAndStop(genotype[org][3]);
this[org_property].width = genotype[org][4];
org_property = "o" + org + "_nose";
this[org_property].gotoAndStop(genotype[org][5]);
this[org_property].height = genotype[org][6];
geno_text += "Geno" + org + " has initialised." + "This Geno has a " + genotype[org][1] + " by " + genotype[org][2] + " face" + "\n" ;
geno_log.text = geno_text;
}
}
function initialise(event: MouseEvent) {
random_genotype_initialisation();
show_phenotype();
}
initialise_btn.addEventListener(MouseEvent.MOUSE_UP, initialise);
The program has some faces, which change features randomly, each time the user presses the initialise button. Which by my knowledge shows that the button handler works, and the program is performing correctly, however, the text does not follow suit and only changes once.

Type Coercion failed: cannot convert []#13a355b9 to flash.display.DisplayObject

I get this error when running, no compile errors.
package {
import flash.display.*;
import flash.events.*;
import flash.utils.*;
public class mainCode extends MovieClip{
//global variables go here
public var circled:Shape = new Shape();
public var circled2:Shape = new Shape();
public var circled3:Shape = new Shape();
public var angled:int = new int();
public var circlearray1:Array = new Array(4);
public var circlearray2:Array = new Array(4);
public function mainCode(){
makeCircle(circled, 100);
makeCircle(circled2, 50);
makeCircle(circled3, 50);
for(var i:int=0; i<4; i++){circlearray1[i] = new Array(20);}
for(var n:int=0; n<4; n++){circlearray2[n] = new Array(20);}
stage.addEventListener(Event.ENTER_FRAME, mainLoop);
}
//functions go here
private function mainLoop(e:Event){
trace(1);
angled+=1;
angled%=360;
circled.x = stage.stageWidth / 2;
circled.y = stage.stageHeight/ 2;
circled2.x = circled.x + 100*Math.cos(radians(angled));
circled2.y = circled.y + 100*Math.sin(radians(angled));
circled3.x = circled.x + 100*Math.cos(radians((angled + 180) % 360));
circled3.y = circled.y + 100*Math.sin(radians((angled + 180) % 360));
trace(2);
for (var i:int = 0; i < 4; i++)
{
trace(3);
if (circlearray1[i][0] != undefined)
{removeChild(circlearray1[i][0]);}
if (circlearray2[i][0] != undefined)
{removeChild(circlearray2[i][0]);}
trace(4);
for (var m:int = 0; m < 19; m++)
{
circlearray1[i][m] = circlearray1[m+1];
circlearray2[i][m] = circlearray2[m+1];
}
circlearray1[i][19] = new Shape();
circlearray2[i][19] = new Shape();
makeCircle(circlearray1[i][19], 25);
makeCircle(circlearray2[i][19], 25);
circlearray1[i][19].x = circled2.x + 50*Math.cos(radians(((-angled + (i*90)) * 2) % 360));
circlearray1[i][19].y = circled2.y + 50*Math.sin(radians(((-angled + (i*90)) * 2) % 360));
circlearray2[i][19].x = circled3.x + 50*Math.cos(radians(((-angled + (i*90)) * 2) % 360));
circlearray2[i][19].y = circled3.y + 50*Math.sin(radians(((-angled + (i*90)) * 2) % 360));
trace(8);
}
}
private function makeCircle(circles:Shape, radius:int)
{
circles.graphics.clear();
circles.graphics.lineStyle(2,0x000000);
circles.graphics.beginFill(0x990000);
circles.graphics.drawCircle(0,0,radius);
circles.graphics.endFill();
addChild(circles);
}
private function degrees(radians:Number):Number
{
return radians * 180/Math.PI;
}
private function radians(degrees:Number):Number
{
return degrees * Math.PI / 180;
}
private function killCircle(circlei:Shape):void {
removeChild(circlei);
}
}
}
I've traced it down to {removeChild(circlearray1[i][0]);}, which seems to be returning the error. I have no idea why it's doing this, I've tried alternatives such as circlearray1[i][0].parent.removeChild(circlearray1[i][0]); and if (circlearray1[i][0] is Shape) ... , but no dice.
For reference, I'm trying to make some circles circle around other circles, but have the outermost circles leave an "image lag" (or afterimage) while moving. I do this by creating objects and deleting them using for loops and multidimensional arrays, as I dont feel like typing out 50 create object calls manually and edit each one manually.
Probably, this part:
for (var m:int = 0; m < 19; m++)
{
circlearray1[i][m] = circlearray1[m+1];
circlearray2[i][m] = circlearray2[m+1];
}
You assign to endpoint elements, which you initially assume to be Shapes the elements which are Arrays. Then later you go at circlearray1[i][0] assuming it is Shape if it is not empty, but it is already an Array due to the assignment above. It's probably a typo and you meant this:
for (var m:int = 0; m < 19; m++)
{
circlearray1[i][m] = circlearray1[i][m+1];
circlearray2[i][m] = circlearray2[i][m+1];
}
There's actually a more clean way to do that. Array in AS3 is a lot like C# ArrayList, you can insert elements to either end and extract elements from either end without re-indexing elements manually:
trace(3);
// If you are sure the first element is not empty
// you can get its reference removing them from
// the Array at the same time.
removeChild(circlearray1[i].shift());
removeChild(circlearray2[i].shift());
trace(4);
// All Array elements are automatically shifted
// by -1 so you don't need to move each of them manually.
circlearray1[i][19] = new Shape();
circlearray2[i][19] = new Shape();

Multi arguments to CALLBACK in addEventListener in the FOR statement is difficult

For loop generates Button
I wanted to generate dynamic amount button.
And wanted to recognize which one was clicked.
This is real code...
for(var col:int = 1; col <= MaxColumn; col++){
for(var row:int = 1; row <= MaxRow; row++){
makeGrid(col, row);
Button["btn_" + col + "_" + row] = new Button();
Button["btn_" + col + "_" + row].label = col + "行" + row + "列" ;
Button["btn_" + col + "_" + row].setStyle("fontSize", 10);
Button["btn_" + col + "_" + row].setStyle("cornerRadius", 0);
Button["btn_" + col + "_" + row].x = 1150 - 500/MaxRow * (row - 1);
Button["btn_" + col + "_" + row].y = 150 + 500/MaxColumn * (col - 1);
Button["btn_" + col + "_" + row].width = 500/MaxRow;
Button["btn_" + col + "_" + row].height = 500/MaxColumn;
Button["btn_" + col + "_" + row].setStyle("color", 0x191970);
Button["btn_" + col + "_" + row].setStyle("fontSize", 7);
Button["btn_" + col + "_" + row].addEventListener(MouseEvent.CLICK, onGridClick(col, row));
rootPanel.addElement(Button["btn_" + col + "_" + row]);
}
}
private function onGridClick(col, row):void{
makeGridId(col, row);
return function(event:Event):void{
var createGridDialog:CreateGridDialog = PopUpManager.createPopUp(this, CreateGridDialog, true) asCreateGridDialog;
PopUpManager.centerPopUp(createGridDialog);
createGridDialog.setGridId(globalGridId);
createGridDialog.setMaxRow(MaxRow);
createGridDialog.addEventListener(CreateGridEvent.GRID_SUBMIT, tmpSave);
}
}
public function makeGridId(col:int, row:int):void{
globalGridId = (col - 1) * MaxRow + row;
}
addEventListener's callback function is difficult
Because, in
private function onGridClick(col, row):void{
,
makeGridId(col, row);
repeated in each for blocks, so globalGridId is overwritten in the end after compile.(row = MaxRow,col = MaxColumn)
If the callback function could accept col&row directly, this issue would close.
But addEventListener's callback is difficult...
addEventListener(MouseEvent.CLICK, **onGridClick**)
The callback basically accept only one argument:MouseEvent directly, and only return void type.
I want to make globalGridId when I click, and I want to send it to where I click.
How should I do?
I Notice
please see this...
<s:Button id="Grid1" x="220" y="0" width="80" height="80" click="onSubClick(event, 0)"/>
private function onSubClick(event:MouseEvent, division:int):void {
var subSymbolDialog:SubSymbolDialog = PopUpManager.createPopUp(this, SubSymbolDialog, true) as SubSymbolDialog;
PopUpManager.centerPopUp(subSymbolDialog);
subSymbolDialog.setDivision(division);
subSymbolDialog.addEventListener(SubSymbolEvent.SUB_CLOSE, onSubClose);
}
this is weird.
click="onSubClick(event, 0)"
Why this is working?
you cannot pass arguments to listeners callback functions.
Try extends the buttonClass as follow:
package
{
public class MyButton extends Button
{
public var row:int;
public var col:int;
public function MyButton()
{
super();
}
}
}
After that you just have to fill the row and col property for the buttons.
for(var col:int = 1; col <= MaxColumn; col++){
for(var row:int = 1; row <= MaxRow; row++){
makeGrid(col, row);
Button["btn_" + col + "_" + row] = new MyButton();
Button["btn_" + col + "_" + row].col = col;
Button["btn_" + col + "_" + row].row = row;
//...
on the callback function you can retrieve it as follow:
private function onGridClick(e:Event):void
{
var b:MyButton = event.target as MyButton;
makeGridId(b.col, b.row);
var createGridDialog:CreateGridDialog = PopUpManager.createPopUp(this, CreateGridDialog, true) asCreateGridDialog;
PopUpManager.centerPopUp(createGridDialog);
createGridDialog.setGridId(globalGridId);
createGridDialog.setMaxRow(MaxRow);
createGridDialog.addEventListener(CreateGridEvent.GRID_SUBMIT, tmpSave);
}
PS: I warn you about the use of your array named Button exactly the same a s the class Button.
If you can use upercase first letters only for class name and keep lowercase first letter for variable, it's better (ex: MyClassName, myVariableName) ;)

Convert seconds to minutes and seconds in Actionscript 3

I'm working with the youtube API and I'm getting the current time on the video as seconds.
What I want to do is to convert them into this: MM:SS
I've tried to google and try different things by myself but nothing seemed to work and be efficient.
I'll be glad to see how it can be done in a good and efficient way thanks in advance!
Something like:
var formattedTime =
(Math.floor(seconds/60)) + ":" + // minutes
(seconds % 60 >= 10 ? "": "0") + // padding for seconds if needed
(seconds % 60)); // seconds
here is a little class I use all the time just for what you need. I've also added a timecodes to seconds method. Simply use it like Timecodes.secondsToTimecode(634); which will output 00:10:34
package com.ronnieswietek.utils
{
public class Timecodes
{
public function Timecodes()
{
}
public static function timecodeToSeconds(tcStr:String):Number
{
var t:Array = tcStr.split(":");
return (t[0] * 3600 + t[1] * 60 + t[2] * 1);
}
public static function secondsToTimecode(seconds:Number):String
{
var minutes:Number = Math.floor(seconds/60);
var remainingSec:Number = seconds % 60;
var remainingMinutes:Number = minutes % 60;
var hours:Number = Math.floor(minutes/60);
var floatSeconds:Number = Math.floor((remainingSec - Math.floor(remainingSec))*100);
remainingSec = Math.floor(remainingSec);
return getTwoDigits(hours) + ":" + getTwoDigits(remainingMinutes) + ":" + getTwoDigits(remainingSec);
}
private static function getTwoDigits(number:Number):String
{
if (number < 10)
{
return "0" + number;
}
else
{
return number + "";
}
}
}
}
var timeStr:String;
//Video's length >= 1 hour
if( seconds >= 60*60 ){
//Format-> H:MM:SS
timeStr = (""+Math.floor(seconds/(60*60))) + //Hours
":"+
("0"+Math.floor((seconds%(60*60))/60)).substr(-2)+ //Minutes
":"+
("0"+(seconds%60)).substr(-2); //Seconds
}else{
//Format-> MM:SS
timeStr = ("0"+Math.floor(seconds/60)).substr(-2)+ //Minutes
":"+
("0"+(seconds%60)).substr(-2); //Seconds
}
Something a little easier to read to get your head around it:
var seconds:int = 200;
var minutes:int = 0;
while(seconds >= 60)
{
seconds -= 60;
minutes ++;
}
trace(minutes, seconds);
The leading zeros part can be done like so:
var secStr:String = String(seconds);
var minStr:String = String(minutes);
secStr = (secStr.length == 1) ? "0" + secStr : secStr;
minStr = (minStr.length == 1) ? "0" + minStr : minStr;
trace(minStr + ":" + secStr);

Drawing an honeycomb with as3

I'm trying to create an honeycomb with as3 but I have some problem on cells positioning.
I've already created the cells (not with code) and for cycled them to a funcion and send to it the parameters which what I thought was need (the honeycomb cell is allready on a sprite container in the center of the stage).
to see the structure of the cycle and which parameters passes, please see the example below, the only thing i calculate in placeCell is the angle which I should obtain directly inside tha called function
alt text http://img293.imageshack.us/img293/1064/honeycomb.png
Note: the angle is reversed but it isn't important, and the color are useful in example only for visually divide cases.
My for cycle calls placeCell and passes cell, current_case, counter (index) and the honeycomb cell_lv (cell level).
I thought it was what i needed but I'm not skilled in geometry and trigonometry, so I don't know how to position cells correctly:
import flash.display.Sprite;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
function createHoneycomb (cells:int):void {
var honeycomb:Sprite = new Sprite ();
addChild (honeycomb);
var cell_lv:int = 1;
var increment:int = 6;
var tot_cur_cells:int = 1;
var current_case:int = 0;
var case_counter:int = 1;
var case_length:int = 1;
var max_cases:int = 6;
var nucleus:Sprite = new cell (); // hexagon from library
honeycomb.addChild (nucleus);
for (var i:int = 1; i <= cells; i ++) {
if (case_counter < case_length) {
case_counter ++;
} else {
current_case ++;
if (current_case > max_cases) current_case = 1;
case_counter = 1;
}
if (i == tot_cur_cells) { // if i reach the current level
if (i > 1) cell_lv ++;
case_length = cell_lv;
tot_cur_cells += (increment * cell_lv);
}
var current_cell:Sprite = new cell (); // hexagon from library
honeycomb.addChild (current_cell);
placeCell (current_cell, case_counter, current_case, cell_lv);
}
function centerHoneycomb (e:Event):void {
honeycomb.x = stage.stageWidth / 2
honeycomb.y = Math.round (stage.stageHeight / 2);
}
stage.addEventListener (Event.RESIZE, centerHoneycomb)
stage.dispatchEvent (new Event (Event.RESIZE));
}
function placeCell (cell:Sprite, counter:int, current_case:int, cell_lv:int):void {
var margin:int = 2;
// THIS IS MY PROBLEM
var start_degree:Number = (360 / (cell_lv * 6));
var angle:Number = (start_degree * ((current_case - 1) + counter) - start_degree);
var radius:Number = (cell.width + margin) * cell_lv;
cell.x = radius * Math.cos (angle);
cell.y = radius * Math.sin (angle);
// end of the problem
if (angle != 0) trace ("LV " + cell_lv + " current_case " + current_case + " counter " + counter + " angle " + angle + " radius " + radius);
else trace ("LV " + cell_lv + " current_case " + current_case + " counter " + counter + " angle " + angle + " radius " + radius);
}
createHoneycomb (64);
if you copy and paste this code, it works but you need to create an hexagon and call it in the actionscript library as cell
how can I do to solve it?
I've also thought to use a switch with the cases to align it, but i think is a little bit buggy doing this
Okay, I really loved this question. It was interesting, and challenging, and I got a working result. I didn’t use any of your code as the base though, but started from scratch, so depending on your final use, you might need to change a bit.
I did however created similar variables to those inside of your cells (in the picture). For each cell you have the following properties:
the iterating variable i is equally to your cell number
the radius r equals your level, and expresses the distance from the center (with 0 being the center)
the position p expresses the position in the current radius
the sector s equals your case, but starts with zero
p % r equals your index
I don’t have an angle, simply because I don’t position the individual hexagons using an angle. Instead I base the position of the (fixed) positions of the hexagons at radius 1 and calculate the missing ones in between.
The following code shows my implementation with 61 (60 + the center; but it’s configurable). You can also see the code in action on Wonderfl.
package
{
import flash.display.Sprite;
public class Comb extends Sprite
{
public function Comb ()
{
Hexagon.scale = 0.5;
this.x = stage.stageWidth / 2;
this.y = stage.stageHeight / 2;
// draw honeycomb with 60 cells
drawComb( 60 );
}
private function drawComb ( n:uint ):void
{
var colors:Array = new Array( 0x33CC33, 0x006699, 0xCC3300, 0x663399, 0xFF9900, 0x336666 );
var sectors:Array = new Array(
new Array( 2, 0 ),
new Array( 1, 1 ),
new Array( -1, 1 ),
new Array( -2, 0 ),
new Array( -1, -1 ),
new Array( 1, -1 ) );
var w:Number = 0.50 * Hexagon.hxWidth;
var h:Number = 0.75 * Hexagon.hxHeight;
var r:uint, p:uint, s:uint;
var hx:Hexagon;
for ( var i:uint = 0; i <= n; i++ )
{
r = getRadius( i );
p = getPosition( i, r );
s = getSector( i, r, p );
// create hexagon
if ( r == 0 )
hx = new Hexagon( 0xCCCCCC );
else
hx = new Hexagon( colors[s] );
hx.x = w * ( r * sectors[s][0] - ( p % r ) * ( sectors[s][0] - sectors[ ( s + 1 ) % 6 ][0] ) );
hx.y = h * ( r * sectors[s][1] - ( p % r ) * ( sectors[s][1] - sectors[ ( s + 1 ) % 6 ][1] ) );
addChild( hx );
}
}
private function getRadius ( i:uint ):uint
{
var r:uint = 0;
while ( i > r * 6 )
i -= r++ * 6;
return r;
}
private function getPosition ( i:uint, r:uint ):uint
{
if ( r == 0 )
return i;
while ( r-- > 0 )
i -= r * 6;
return i - 1;
}
private function getSector ( i:uint, r:uint, s:uint ):uint
{
return Math.floor( s / r );
}
}
}
import flash.display.Shape;
class Hexagon extends Shape
{
public static var hxWidth:Number = 90;
public static var hxHeight:Number = 100;
private static var _scale:Number = 1;
public function Hexagon ( color:uint )
{
graphics.beginFill( color );
graphics.lineStyle( 3, 0xFFFFFF );
graphics.moveTo( 0, -50 );
graphics.lineTo( 45, -25 );
graphics.lineTo( 45, 25 );
graphics.lineTo( 0, 50 ),
graphics.lineTo( -45, 25 );
graphics.lineTo( -45, -25 );
graphics.lineTo( 0, -50 );
this.scaleX = this.scaleY = _scale;
}
public static function set scale ( value:Number ):void
{
_scale = value;
hxWidth = value * 90;
hxHeight = value * 100;
}
public static function get scale ():Number
{
return _scale;
}
}