Convert input text to 2d array - actionscript-3

Im trying to make a level editor for the game.
Now I can create a new map (using mouse) and click "generate" button to trace map array
(string). After that I can simple copy the code from the output
and use it to create a new level.
Lets say I have a class called NewLevel.as
I create a new array and paste code from output window, so I have 2d array.
Then adding tiles to stage using for loops.
var array:Array =
// code below is what I get in output window
[
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[7, 7, 7, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7],
[7, 7, 7, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7]
];
for (var row:int = 0; row < array.length; row++)
{
for (var column:int = 0; column < array[row].length; column++)
{
var tile = new Tile();
addChild(tile);
tile.x = column * tile.width;
tile.y = row * tile.height;
tile.gotoAndStop(array[row][column] +1);
}
}
It works without problems,this gives me the map I created using level editor.
but what I want is that players input their "map code" and load the map they created.
I guess you have seen that in many games.
I have a textarea so users can input their string,
how can I convert their input to 2d array and load it (as you see in example)?
It should be 2d array.
I also added event listener to textarea
textarea.addEventListener(Event.CHANGE, changes);
function changes(e:Event):void
{
// convert input text to 2d array to build a new map
// Do not know how to get input to use with JSON
var myStr = levelTextarea.text;
var a2:Array = JSON.parse(myStr) as Array;
trace( a2 );
}

You can use JSON for this kind of job, this class is available in Flash Player 11.
package
{
import flash.display.Sprite;
import flash.events.Event;
/**
* ...
* #author
*/
public class Main extends Sprite
{
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
var a:Array = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[7, 7, 7, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7],
[7, 7, 7, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7]
];
var txt:String = JSON.stringify( a )
trace( txt );
var a2:Array = JSON.parse( txt ) as Array;
trace( a2 );
}
}
}

Related

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;
}

AS3: Tile based movement system

very new to as3 and using a tutorial found here to try my hand at tile based movement. However, i cant seem to get the code to work. I keep getting the error code:
"1046: Type was not found or was not a compile-time constant:hero."
The line it is reference is:
var character: hero = new hero();
My full code is:
package {
import flash.display.MovieClip;
import flash.events.*;
public class main2 extends MovieClip {
var hero;
public function main2() {
// Create map
var mapWidth = 10;
var mapHeight = 10;
var tileSide = 32;
var totalTiles = mapWidth * mapHeight;
var myMap: Array = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 1, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 1, 0, 0, 1],
[1, 0, 0, 1, 0, 0, 1, 0, 0, 1],
[1, 0, 0, 1, 1, 1, 1, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
];
for (var i: int = 0; i < mapHeight; i++) {
for (var u: int = 0; u < mapWidth; u++) {
var cell: MovieClip = new tile();
cell.gotoAndStop(myMap[i][u] + 1);
cell.x = tileSide * u;
cell.y = tileSide * i;
addChild(cell);
}
}
// Hero management
var heroSpawnX = 4;
var heroSpawnY = 2;
var character: hero = new hero();
addChild(character);
character.x = heroSpawnX * tileSide;
character.y = heroSpawnY * tileSide;
var heroX = heroSpawnX;
var heroY = heroSpawnY;
// Basic movement
stage.addEventListener(KeyboardEvent.KEY_DOWN, movement);
function movement(event: KeyboardEvent):void {
if (event.keyCode == 40 && myMap[heroY + 1][heroX] == 0) {
character.gfx.rotation = 0;
character.y += tileSide;
heroY++;
}
if (event.keyCode == 38 && myMap[heroY - 1][heroX] == 0) {
character.gfx.rotation = 180;
character.y -= tileSide;
heroY--;
}
if (event.keyCode == 39 && myMap[heroY][heroX + 1] == 0) {
character.gfx.rotation = 270;
character.x += tileSide;
heroX++;
}
if (event.keyCode == 37 && myMap[heroY][heroX - 1] == 0) {
character.gfx.rotation = 90;
character.x -= tileSide;
heroX--;
}
}
}
}
}
Any help on this issue would be great, been at it for an hour now.
also if you have any recommendations on as3 resources please let me know...specifically tiled based systems.
thanks is advanced.
That error means your class Hero is not found. you should put the hero.as file at where your main2.as file is(at same location as main2.as). and then import it:
import Hero;
 
and my recommendation on as3 resources:
1.http://republicofcode.com:I think best site for starting as3.I started from it.
2.http://kirupa.com: a good site with a lot of articles
3.http://flashandmath.com: for professionals
and don't forget Adobe ActionScript-3 API reference:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/
I   H☺ P E   this helps !

fillStyle on array [HTML5 Canvas]

I have this:
var ctx = canvas.getContext( '2d' );
....
....
ctx.fillStyle = 'blue';
The real thing I need to change, is the shapes of a tetris game. They're written like this:
var shapes = [
[ 1, 1, 1, 1 ],
[ 1, 1, 1, 0,
1 ],
[ 1, 1, 1, 0,
0, 0, 1 ],
[ 1, 1, 0, 0,
1, 1 ],
[ 1, 1, 0, 0,
0, 1, 1 ],
[ 0, 1, 1, 0,
1, 1 ],
[ 0, 1, 0, 0,
1, 1, 1 ]
];
I would like to change the color of the first one, which is [1,1,1,1] or shapes[0], but none of what I've tried works.
ctx.fillStyle = 'blue'; works, but it changes the color of all the objects.
Live version can be viewed here:
http://harlem-shake-it.com/tetris/
From this code, I assume you only want the current object to be blue?
for (var y = 0; y < 4; ++y) {
for (var x = 0; x < 4; ++x) {
if (current[y][x]) {
ctx.fillStyle = '#0068ff';
drawBlock(currentX + x,currentY + y);
}
}
}
If that's the case, you'll need to first save the current canvas state with ctx.save();, use the fillStyle, draw the block, and then ctx.restore();. This should allow you to fill your blocks with multiple colors, if you want. Or, in this case, have the fallen blocks be rendered black.
You should also declare a doctype: <!doctype html>. And the <center> tag is deprecated. You should use text-align: center; in CSS moving forward, or margin: 0 auto; depending on what you're styling.

Key generator method?

I really feel stupid for posting this but since i got no answers on my question and i am still junior programmer i will post this :
//List of keys
byte[] Key0 = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; //mode 10 = 0
byte[] Key1 = { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 }; // i + 2
byte[] Key2 = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }; // i mode 2 = 0
byte[] Key3 = { 66, 77, 88, 99, 111, 222, 110, 112, 114, 115 }; // mode 11 = 0
byte[] Key4 = { 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121 }; //x^2
byte[] Key5 = { 6,17,34,57,86,121,162,209 }; //3x^2+2x+1
byte[] Key6 = { 77,78,79,80,81,82,83,84,85,86,87 }; // only in range
//Add all keys to the list
List<byte[]> oKeysList = new List<byte[]>();
oKeysList.Add(Key0);
oKeysList.Add(Key1);
oKeysList.Add(Key2);
oKeysList.Add(Key3);
oKeysList.Add(Key4);
oKeysList.Add(Key5);
oKeysList.Add(Key6);
Random oRandom = new Random();
//Generate random key index to be used in the encryption
int ListSelectedIndex = oRandom.Next(0, oKeysList.Count);
byte[] GeneratedKey = oKeysList[ListSelectedIndex];
//Generate 3 random number from the selected key and concate the key index to it
byte[] GeneratedBytes = new byte[4];
for (int i = 0; i < 3; i++)
{
GeneratedBytes[i] = GeneratedKey[oRandom.Next(0,GeneratedKey.Length)];
}
//Add the list of key index
GeneratedBytes[3] = (byte)ListSelectedIndex;
//Return the genreated bytes
return GeneratedBytes;
As you see i generate this 4 byte array along with a 8 bytes generated with from RNG Cryptography, and when i want to check my serial i take the last 4 bytes and use the mathematical relations between them, I want to generate many serials and be able to check if they are valid or not. I know its probably pretty old method with a very bad security so please if any one could help me or add anything to my code or suggest anything new i would be really thankful.
I am not sure that anyone will analyze your code here. I suggest the following: do not make software protection too complex. It won't make a significant affect on piracy, but 100% will affect people, who purchased your software. Keep your software protection mechanisms as simple as possible.

Cleanly merge two arrays in ActionScript (3.0)?

What's a nice way to merge two sorted arrays in ActionScript (specifically ActionScript 3.0)? The resulting array should be sorted and without duplicates.
To merge (concatenate) arrays, use .concat().
Below are two examples of how you can concatenate arrays and remove duplicates at the same time.
More convenient way: (you can use ArrayUtil.createUniqueCopy() from as3corelib)
// from as3corelib:
import com.adobe.utils.ArrayUtil;
var a1:Array = ["a", "b", "c"];
var a2:Array = ["c", "b", "x", "y"];
var c:Array = ArrayUtil.createUniqueCopy(a1.concat(a2)); // result: ["a", "b", "c", "x", "y"]
Slightly faster way: (you can loop through the arrays yourself and use Array.indexOf() to check for duplicates)
var a1:Array = ["a", "b", "c"];
var a2:Array = ["c", "b", "x", "y"];
var a3:Array = ["a", "x", "x", "y", "z"];
var c:Array = arrConcatUnique(a1, a2, a3); // result: ["a", "b", "c", "x", "y", "z"]
private function arrConcatUnique(...args):Array
{
var retArr:Array = new Array();
for each (var arg:* in args)
{
if (arg is Array)
{
for each (var value:* in arg)
{
if (retArr.indexOf(value) == -1)
retArr.push(value);
}
}
}
return retArr;
}
This is kind of an simple algorithm to write. I would be surprised if there were a more direct way to do this in Actionscript.
function merge(a1:Array, a2:Array):Array {
var result:Array = [];
var i1:int = 0, i2:int = 0;
while (i1 < a1.length && i2 < a2.length) {
if (a1[i1] < a2[i2]) {
result.push(a1[i1]);
i1++;
} else if (a2[i2] < a1[i1]) {
result.push(a2[i2]);
i2++;
} else {
result.push(a1[i1]);
i1++;
i2++;
}
}
while (i1 < a1.length) result.push(a1[i1++]);
while (i2 < a2.length) result.push(a2[i2++]);
return result;
}
Using Array.indexOf to detect duplicates is going to be painfully slow if you have a List containing a large number of elements; a far quicker way of removing duplciates would be to throw the contents of the Array into a Set after concatenating them.
// Combine the two Arrays.
const combined : Array = a.concat(b);
// Convert them to a Set; this will knock out all duplicates.
const set : Object = {}; // use a Dictionary if combined contains complex types.
const len : uint = combined.length;
for (var i : uint = 0; i < len; i++) {
set[combined[i]] = true;
}
// Extract all values from the Set to produce the final result.
const result : Array = [];
for (var prop : * in set) {
result.push[prop];
}
If your program makes heavy use of Collections then if may be prudent to make use of one of the many AS3 Collections frameworks out there which provide a simple interface for manipulating data and will always take the optimal approach when it comes to the implementation.
AS3Commons Collections
Polygonal DS
function remDuplicates(_array:Array):void{
for (var i:int = 0; i < _array.length;++i) {
var index:int = _array.indexOf(_array[i]);
if (index != -1 && index != i) {
_array.splice(i--, 1);
}
}
}
Then for the "merge" use concat.
exemple :
var testArray:Array = [1, 1, 1, 5, 4, 5, 5, 4, 7, 2, 3, 3, 6, 5, 8, 5, 4, 2, 4, 5, 1, 2, 3, 65, 5, 5, 5, 5, 8, 4, 7];
var testArray2:Array = [1, 1, 1, 5, 4, 5, 5, 4, 7, 2, 3, 3, 6, 5, 8, 5, 4, 2, 4, 5, 1, 2, 3, 65, 5, 5, 5, 5, 8, 4, 7];
testArray.concat(testArray2);
trace(testArray);
remDuplicates(testArray);
trace(testArray);
Please follow the below step to get your answer:
Concat two array using "Concat" Methos.
New Array (concated) sort using "Sort" method which provided as API in Array Class
Make user defined function to remove duplicates (see below functions)
> function removeDuplicates(p_arr:Array):Array {
var ansArr:Array = new Array();
var len:uint = p_arr.length;
var i:uint = 0;
var j:uint = 0;
ansArr[j] = p_arr[i];
i++;
j++;
while(i<len)
{
if(ansArr[j] != p_arr[i])
{
ansArr[j] = p_arr[i];
j++;
}
i++;
}
return ansArr;
}
Returned "ansArr" will be sorted and without duplicate merged array of two array.