Dynamic variables in actionscript 3 - actionscript-3

I am coding an ore-calculator, and for this I have repeating variables-names like:
tritaniumlogo:MineralContainer:new MineralContainer(values)
tritaniumtext:MinText=new MinText(values)
The Mineralcontainer and the MinText are some defined classes. Since I was repeating myself, I tried to re-factor the 80 lines of codes.
So I created an Array holding some data with the following code, but it does not work:
private var minsVar:Array = [[50, 98, "Tritanium", emptySpace], [50, 134, "Pyerite", emptySpace], [50, 170, "Mexallon", emptySpace], [50, 206, "Isogen", emptySpace], [230, 98, "Noxcium", emptySpace], [230, 134, "Zydrine", emptySpace], [230, 170, "Megacyte", emptySpace], [230, 206, "Morphite", emptySpace]];
for (var a:int = 0; a < minsVar.length; a++) {
private var [minsVar[a][2] + "logo"] = new MineralContainer(minsvar[a][0], minsvar[a][1], a + 1);
private var [minsVar[a][2] + "textinput"] = new MinText(minsvar[a][0], minsvar[a][1], minsvar[a][2], minsvar[a][3]);
}

If the loop is inside a class method, Then you may do the following:
for (var a:int = 0; a < minsVar.length; a++) {
this[minsVar[a][2] + "Logo"] = new MineralContainer(minsvar[a][0], minsvar[a][1], a + 1);
this[minsVar[a][2] + "Textinput"] = new MinText(minsvar[a][0], minsvar[a][1], minsvar[a][2], minsvar[a][3]);
}
Then, you can access them using this["TritaniumLogo"] or this["PyeriteTextinput"], for example. However, you are better to store your "new" objects inside some associative arrays:
private var minsVar:Array = [[50, 98, "Tritanium", emptySpace], [50, 134, "Pyerite", emptySpace], [50, 170, "Mexallon", emptySpace], [50, 206, "Isogen", emptySpace], [230, 98, "Noxcium", emptySpace], [230, 134, "Zydrine", emptySpace], [230, 170, "Megacyte", emptySpace], [230, 206, "Morphite", emptySpace]];
private var arrLogoes:Array = new Array();
private var arrTextInputs:Array = new Array();
// ...
for (var a:int = 0; a < minsVar.length; a++) {
arrLogoes[minsVar[a][2]] = new MineralContainer(minsvar[a][0], minsvar[a][1], a + 1);
arrTextInputs[minsVar[a][2]] = new MinText(minsvar[a][0], minsvar[a][1], minsvar[a][2], minsvar[a][3]);
}
So that you can access them later using arrLogoes["Tritanium"] or arrTextInputs["Pyerite"], for example.

Related

ACL rules don't lead to LPM classification

The output of the following code
static int test(void) {
struct rte_acl_param param = {
.name = "ctx",
.socket_id = 0,
.rule_size = RTE_ACL_RULE_SZ(3), // proto/0xff + src-ip/mask + dst-ip/mask
.max_rule_num = 10, // TODO: fe'lan 10 million rule ro hard code kardam. ba'd te'dadesh ro dar config besheh ta'yin kard.
};
struct rte_acl_ctx *ctx = rte_acl_create(&param);
struct rte_acl_rule *rule;
rule = rte_zmalloc_socket(NULL, RTE_ACL_RULE_SZ(3), 0, 0);
rule->data.category_mask = 1;
rule->data.priority = 1;
rule->data.userdata = 1;
rule->field[0].value.u8 = 6;
rule->field[0].mask_range.u8 = 0xff;
rule->field[1].value.u32 = RTE_IPV4(192, 168, 1, 1);
rule->field[1].mask_range.u8 = 32;
rule->field[2].value.u32 = RTE_IPV4(192, 168, 1, 2);
rule->field[2].mask_range.u8 = 32;
if (rte_acl_add_rules(ctx, rule, 1)) {
printf("can't add rule #1\n");
return -1;
}
rule = rte_zmalloc_socket(NULL, RTE_ACL_RULE_SZ(3), 0, 0);
rule->data.category_mask = 1;
rule->data.priority = 1;
rule->data.userdata = 2;
rule->field[0].value.u8 = 6;
rule->field[0].mask_range.u8 = 0xff;
rule->field[1].value.u32 = RTE_IPV4(192, 168, 1, 0);
rule->field[1].mask_range.u8 = 24;
rule->field[2].value.u32 = RTE_IPV4(192, 168, 1, 0);
rule->field[2].mask_range.u8 = 24;
if (rte_acl_add_rules(ctx, rule, 1)) {
printf("can't add rule #2\n");
return -1;
}
typedef struct {
uint8_t proto;
uint32_t ip_src;
uint32_t ip_dst;
} ThreeTuple;
ThreeTuple test_data[] = {
{
.proto = 6,
.ip_src = RTE_IPV4(192, 168, 1, 1),
.ip_dst = RTE_IPV4(192, 168, 1, 2),
},
{
.proto = 6,
.ip_src = RTE_IPV4(192, 168, 1, 2),
.ip_dst = RTE_IPV4(192, 168, 1, 1),
},
};
uint32_t results[RTE_DIM(test_data)];
const uint8_t *data[RTE_DIM(test_data)];
for (size_t i = 0; i < RTE_DIM(test_data); i++) {
test_data[i].ip_src = rte_cpu_to_be_32(test_data[i].ip_src);
test_data[i].ip_dst = rte_cpu_to_be_32(test_data[i].ip_dst);
}
for (size_t i = 0; i != RTE_DIM(test_data); i++) data[i] = (uint8_t *)&test_data[i];
struct rte_acl_config cfg;
memset(&cfg, 0, sizeof(cfg));
static const struct rte_acl_field_def fieldDefs[] = {
{
.type = RTE_ACL_FIELD_TYPE_BITMASK,
.size = sizeof(uint8_t),
.field_index = 0,
.input_index = 0,
.offset = offsetof(ThreeTuple, proto),
},
{
.type = RTE_ACL_FIELD_TYPE_MASK,
.size = sizeof(uint32_t),
.field_index = 1,
.input_index = 1,
.offset = offsetof(ThreeTuple, ip_src),
},
{
.type = RTE_ACL_FIELD_TYPE_MASK,
.size = sizeof(uint32_t),
.field_index = 2,
.input_index = 2,
.offset = offsetof(ThreeTuple, ip_dst),
},
};
memcpy(&cfg.defs, fieldDefs, sizeof(fieldDefs));
cfg.num_fields = RTE_DIM(fieldDefs);
cfg.num_categories = 1;
if (rte_acl_build(ctx, &cfg)) {
printf("rte_acl_build failed\n");
return -1;
}
rte_acl_classify(ctx, data, results, RTE_DIM(data), 1);
printf("results: ");
for (size_t i = 0; i < RTE_DIM(results); i++) printf("%d, ", results[i]);
printf("\n");
rte_free(rule);
rte_acl_reset(ctx);
rte_acl_free(ctx);
return 0;
}
is
results: 2, 2,
while the first rule exactly matches the first test data. I expect longest prefix match, as in LPM library. If it's not so, how can I obtain the LPM behavior with ACL library?
I tried changing the ips and fields types, but couldn't find what's wrong. In the following documentation:
Packet Classification and Access Control
provided by Intel in its DPDK documentations, I found a good description and sample code. My code seems similar and close enough to the provided code. But it doesn't work as I expect. Let me know whether ACL library essentially take care of longest prefix matching?

Reading duration of MP3 file from App script

I have a MP3 file in google drive. Is there a way I can get duraton of that MP3 file using google app script?
This page shows how to extract that information from an mp3 file by looking at the byte values.
So I wrote a short example and tested it. It seems to be working fine with all mp3 files I tried so far but there is no guarantee it will always work.
The getPlayTime function returns the play time in seconds.
function getPlayTime(file) {
var bitratesV1 = [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320],
bitratesV2 = [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160];
var bytes = file.getBlob().getBytes();
for(var pos = 0;pos < bytes.length; pos++) {
if(bytes[pos] === -1 && pos < bytes.length - 3 && (bytes[pos+1]&0xF0) === 0xF0) {
var isMpegVersion2 = (bytes[pos+1]&8) !== 8,
isLayer3 = (bytes[pos+1]&6) === 2,
bitRate = ((bytes[pos+2]&0xF0) >>> 4)&0xF;
if(!isLayer3) continue;
if(isMpegVersion2) bitRate = bitratesV2[bitRate];
else bitRate = bitratesV1[bitRate];
var playTime = bytes.length*8/(1000 * bitRate);
return playTime;
}
}
}
function test() {
var file = DriveApp.getFilesByName("music.mp3").next();
var playTime = getPlayTime(file);
Logger.log(playTime);
}
edit:
Here is a hopefully more accurate but also much slower version
function getRunTime(file) {
var playTime = 0, numFrames = 0;
var bitratesV1 = [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320],
bitratesV2 = [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160];
var bytes = file.getBlob().getBytes();
for(var pos = 0;pos < bytes.length; pos++) {
if(bytes[pos] === -1 && pos < bytes.length - 3 && (bytes[pos+1]&0xF0) === 0xF0) {
var isMpegVersion2 = (bytes[pos+1]&8) !== 8,
isLayer3 = (bytes[pos+1]&6) === 2,
bitRate = ((bytes[pos+2]&0xF0) >>> 4)&0xF;
if(!isLayer3) continue;
if(isMpegVersion2) bitRate = bitratesV2[bitRate];
else bitRate = bitratesV1[bitRate];
var pt = bytes.length*8/(1000 * bitRate);
if(!isNaN(pt) && isFinite(pt)) {
playTime += pt;
numFrames++;
}
}
}
return playTime/numFrames;
}

I can't get my drawing on the canvas as its own function

So in my class we're learning how to make animations in HTML5. we were given a sample of just 4 shapes and So I made a cloud. However, as you see, there is a function drawCircle();, and if I put the code to draw my cloud under that, it will appear in the canvas, but if i make a function drawCloud();, it won't show up at all. I even call the function at the end of the code and still nothing. Anyone know why or how to fix this?
<!DOCTYPE html>
<!-- Demonstrates canvas drawing using drawing methods -->
<html>
<body style="text-align:center">
<h1>HTML5 Canvas Drawing</h1>
<canvas id="myCanvas" width="800" height="500" style="border:2px solid #BBBBBB;">
</canvas>
<script>
var canv=document.getElementById("myCanvas");
var c=canv.getContext("2d");
var w = canv.width;
var h = canv.height;
function drawRectangle(){
c.fillStyle="rgb(100,200, 240)";
c.fillRect(100,100,200,200);
c.strokeStyle="black";
c.lineWidth=4;
c.strokeRect(100,100,200,200);
}
// function drawCircle(){
// c.fillStyle="red";
// c.strokeStyle="black";
// c.lineWidth=2;
// c.beginPath();
// c.arc(550, 200, 100, 0, Math.PI*2); //x, y, radius, start angle, end angle
// c.closePath();
// c.fill();
// c.stroke();
// }
function drawCircle(){
c.beginPath();
c.moveTo(170, 80);
c.bezierCurveTo(130, 100, 130, 150, 230, 150);
c.bezierCurveTo(250, 180, 320, 180, 340, 150);
c.bezierCurveTo(420, 150, 420, 120, 390, 100);
c.bezierCurveTo(430, 40, 370, 30, 340, 50);
c.bezierCurveTo(320, 5, 250, 20, 250, 50);
c.bezierCurveTo(200, 5, 150, 20, 170, 80);
// complete custom shape
c.closePath();
c.lineWidth = 5;
c.strokeStyle = 'red';
c.stroke();
}
function drawTriangle(){
c.beginPath();
c.lineWidth=3;
c.strokeStyle="Blue";
c.moveTo(200,350);
c.lineTo(100,450);
c.lineTo(300,450);
c.lineTo(200,350);
c.fillStyle="yellow";
c.closePath();
c.fill();
c.stroke();
}
drawRectangle();
drawCircle();
drawArc();
drawTriangle();
drawCloud();
</script>
</body>
</html>
The issue is, there isn't any function called drawCloud. You named the function drawCircle that is suppose to draw a cloud. Rename that function to drawCloud and comment out the actual drawCircle function. Also, there is no need to use closePath() method.
Here's the fixed version of your code
var canv = document.getElementById("myCanvas");
var c = canv.getContext("2d");
var w = canv.width;
var h = canv.height;
function drawRectangle() {
c.fillStyle = "rgb(100,200, 240)";
c.fillRect(100, 100, 200, 200);
c.strokeStyle = "black";
c.lineWidth = 4;
c.strokeRect(100, 100, 200, 200);
}
function drawCircle() {
c.fillStyle = "red";
c.strokeStyle = "black";
c.lineWidth = 2;
c.beginPath();
c.arc(550, 200, 100, 0, Math.PI * 2); //x, y, radius, start angle, end angle
c.fill();
c.stroke();
}
function drawCloud() {
c.beginPath();
c.moveTo(170, 80);
c.bezierCurveTo(130, 100, 130, 150, 230, 150);
c.bezierCurveTo(250, 180, 320, 180, 340, 150);
c.bezierCurveTo(420, 150, 420, 120, 390, 100);
c.bezierCurveTo(430, 40, 370, 30, 340, 50);
c.bezierCurveTo(320, 5, 250, 20, 250, 50);
c.bezierCurveTo(200, 5, 150, 20, 170, 80);
// complete custom shape
c.lineWidth = 5;
c.strokeStyle = 'red';
c.stroke();
}
function drawTriangle() {
c.beginPath();
c.lineWidth = 3;
c.strokeStyle = "Blue";
c.moveTo(200, 350);
c.lineTo(100, 450);
c.lineTo(300, 450);
c.lineTo(200, 350);
c.fillStyle = "yellow";
c.fill();
c.stroke();
}
drawRectangle();
drawCircle();
drawCloud();
drawTriangle();
<canvas id="myCanvas" width="800" height="500" style="border:2px solid #BBBBBB;"></canvas>

ActionScript 3 - Collision detection of objects in an array issue

I'm working on a small flash game and am currently trying to implement multiplayer for up to 4 players. While the collision detection for 1 player works perfectly, when more players are added only the last player can collide with other objects.
Using trace statements I discovered that calling the x and y coordinates of the problematic players from the main class returns the initial x and y positions and not the current coordinates (trace(players[0].x + "/" + players[0].y);), while calling them from within the player class (trace(this.x + "/" + this.y);) always gives the correct values.
The last player will always return the correct coordinates in both classes. Below is a skeleton of the main class.
public class main extends MovieClip {
public var collisionObject: Array = new Array(14);
public var players: Array = new Array();
private var noOfPlayers = 2;
public function main() {
for (var i = 0; i < noOfPlayers; i++) {
setupPlayer(i);
stage.addChild(players[i]);
}
setupCollisionObject();
stage.addEventListener(Event.ENTER_FRAME, checkForCollision);
}
private function setupCollisionObject() {
/* Determines positions of and spawns objects */
}
private function setupPlayer(playerNo) {
switch (playerNo) {
case 3:
players[3] = new player(1000, 576, 180, 104, 100, 102);
case 2:
players[2] = new player(24, 576, 0, 73, 74, 76);
case 1:
players[1] = new player(1000, 384, 180, 38, 37, 39);
case 0:
players[0] = new player(24, 384, 0, 87, 65, 68);
}
}
public function checkForCollision(e: Event) {
trace("x: "+players[0].x+" y: "+players[0].y);
trace("x: "+players[1].x+" y: "+players[1].y);
for (var i in players) {
for (var j in collisionObject) {
if (players[i].hitTestObject(collisionObject[j])) {
//damage player
}
}
}
}
}
I'm at a loss of why this is happening.
You are missing break; in your switch-case in setupPlayer(), this results in all players but the last reinitialize during each call of setupPlayers(i).
private function setupPlayer(playerNo) {
switch (playerNo) {
case 3:
players[3] = new player(1000, 576, 180, 104, 100, 102);
break;
case 2:
players[2] = new player(24, 576, 0, 73, 74, 76);
break;
case 1:
players[1] = new player(1000, 384, 180, 38, 37, 39);
break;
case 0:
players[0] = new player(24, 384, 0, 87, 65, 68);
break;
}
}

What are width and height supposed to represent for a sprite?

I'm working with a Sprite in AS3. Initially, width,height are 0,0 as expected.
After this:
var tf : TextFormat = new TextFormat();
tf.font = "Arial";
tf.size = 48;
tf.bold = true;
text = new TextField();
text.text = "A";
text.x = 30;
text.y = 16;
text.selectable = false;
text.setTextFormat(tf);
addChild(text);
they are 100,100 (even if I shrink the text size).
After this
graphics.beginFill(0xffffff, 1);
graphics.drawRect(0, 0, 99, 99);
graphics.endFill();
graphics.beginFill(color, 1);
graphics.drawRoundRect(6, 6, 84, 84, 8, 8);
graphics.endFill();
They are 130,116. I would expect them to end up at 99,99, what am I missing?
Modification: here's the code from the first answer, but modified to use a single sprite:
var s = new Sprite();
trace("1:", s.width, ", ", s.height) // <-- 0 , 0
var tf : TextFormat = new TextFormat();
tf.font = "Arial";
tf.size = 48;
tf.bold = true;
var text = new TextField();
text.text = "A";
text.x = 30;
text.y = 16;
text.selectable = false;
text.setTextFormat(tf);
s.addChild(text);
trace("2:", s.width, ", ", s.height) //<-- 100, 100
s.graphics.beginFill(0xffffff, 1);
s.graphics.drawRect(0, 0, 99, 99);
s.graphics.endFill();
s.graphics.beginFill(0x000fff, 1);
s.graphics.drawRoundRect(6, 6, 84, 84, 8, 8);
s.graphics.endFill();
trace("3:", s.width, ", ", s.height) //<-- 130,116
Can anyone explain why these 2 behave differently?
Cheers,
Charlie.
I don't know what you're doing elsewhere, but your code is right.
import flash.display.Sprite;
var s = new Sprite();
trace(s.width, ", ", s.height) // <-- 0 , 0
var tf : TextFormat = new TextFormat();
tf.font = "Arial";
tf.size = 48;
tf.bold = true;
var text = new TextField();
text.text = "A";
text.x = 30;
text.y = 16;
text.selectable = false;
text.setTextFormat(tf);
s.addChild(text);
trace(s.width, ", ", s.height) //<-- 100, 100
var s2 = new Sprite();
with(s2) {
graphics.beginFill(0xffffff, 1);
graphics.drawRect(0, 0, 99, 99);
graphics.endFill();
graphics.beginFill(0x000fff, 1);
graphics.drawRoundRect(6, 6, 84, 84, 8, 8);
graphics.endFill();
}
trace(s2.width, ", ", s2.height) //<-- 99, 99
Are the results I get. Is something else in your code scaling objects?
the width and height attribute for a textfield returns the width and height of the textfield boarder, which by default is 100 x 100
try this to see what I'm talking about
text.border = true;
if you want the actual size of the text in the textfield you need
trace(text.textWidth);
trace(text.textHeight);