I have this issue in converting a HEX string to Number in as3
I have a value
str = "24421bff100317"; decimal value = 10205787172373271
but when I parseInt it I get
parseInt(str, 16) = 10205787172373272
Can anyone please tell me what am I doing wrong here
Looks like adding one ("24421bff100318") works fine. I have to assume that means this is a case of precision error.
Because there are only a finite amount of numbers that can be represented with the memory available, there will be times that the computer is estimating. This is common when working with decimals and very large numbers. It's visible, for example, in this snippet where apparently the computer can't add basic decimals:
for(var i=0;i<3;i+=0.2){
trace(i);
}
There are a few workarounds if accuracy at this level is critical, namely using datatypes that store more information ("long" instead of "int" in Java - I believe "Number" might work in AS3 but I have not tested it for your scenario) or if that fails, breaking the numbers down into smaller parts and adding them together.
For further reading to understand this topic (since I do think it's fascinating), look up "precision errors" and "data types".
I'm using AS3, but general programming wisdom unspecific to AS3 is great too!
I am creating my first game, a top-down dungeon crawler with tile-based navigation, and I am deciding how to store my maps. I need to be able to access a specific tile at any point in time. My only thought so far is to use nested Vectors or Arrays with the first level being the row and the second being the column, something like this:
private var map:Array = new Array(Array(0,1,0,0,1,1,0),Array(0,1,0,1,0,1,0));
private var row2col3:uint = map[1][2];
/*map would display as such:*/
#|##||#
#|#|#|#
Ultimately, the idea is to build a Map class that will be easily extensible and, again, allow free access to any specific tile. I am looking for help in determining an effective/efficient design architecture for that Map class.
Thanks!
As stated in the comments I would upload and give my source code for a 12 hour challenge project to create a tile based level editor. The source code can be found at: GitHub BKYeates
This level editor focuses on textures being a power of 2, and uses blitting for drawing on all the textures. It can read, write, and store partial tiles. There is also some functionality to erase and draw on collision boxes.
Now in regards to how the storage should be setup, it is really up to you. If you are going to be storing lots of information I recommend using Vectors. Vectors perform faster than most other container types except for ByteArray (if used correctly). In my level editor I used a Vector with a particular setup.
The Vector I used named _map in a class called tilemodel. tilemodel is responsible for updating all the storage information when a change is made. The _map variable is setup like so:
_map = new Vector.<Vector.<Vector.<Object>>>();
This is a pretty heavily nested Vector and in the end stores, can you believe it, an Object! Which admittedly really chunks out the performance gains you get from using Vector when you are indexing the furthest nested elements.
But ignore that because the indexing gain from this setup is really key. The reason it is setup this way is because I can reference a layer, a row, and a column to grab a specific tile object. For example, I have a tile on layer 2 in row 12 column 13 that I want to access:
var tileObject:Object = _map[2][12][13];
That works perfectly for pretty much any scenario I could use in my tile based game, and the speed is comparatively better than that of a Object or Dictionary when this is being accessed multiple times (i.e. - in a loop which happens often).
The level editor is designed to use all blitting and leave onus to my management classes for storage. The speed gain from doing this is very high, and the way it is currently setup the tilemodel can store partial bitmaps making it slightly more flexible than your standard rigidness of a power of 2 texture reader.
Feel free to look through the source code. But here is a summary of what some of the classes do:
tilecontroller - Issues state changes and updates to tilemanager and tilemodel
tilemanager - Responsible for texture drawing and removal.
tilemodel - Stores and updates the current map on state changes.
r_loader - Loads all assets from assetList.txt (paths set to images
there).
hudcontroller - Currently this was the last thing I was working on, lets you draw on collision boxes that are stored in a separate file alongside the map.
g_global & g_keys - Global constants and static methods use
ubiquitously
LevelEditor - Main class, also designed as "View" class ( see MVC pattern: MVC Pattern )
Also as I've mentioned it can read back all the storage. The class used for that I did not upload to GitHub, but figured I would show the important method here:
//#param assets needs to be the list of loaded bitmap images
public function generateMap( assets:* ):void {
var bmd:BitmapData = new BitmapData( g_global.stageWidth, g_global.stageHeight, true, 0 );
_canvas = new Bitmap( bmd, "auto", true );
_mapLayer.addChild( _canvas );
_canvas.bitmapData.unlock();
g_global.echo( "generating map" );
var i:int, j:int, m:int;
for ( m = 0; m < _tiles.length; m++ ) {
for ( i = 0; i < _tiles[m].length; i++ ) {
for ( j = 0; j < _tiles[m][i].length; j++ ) {
//wondering why im type casting in this evaluation? _tiles[i][j].tile == int( _tiles[i][j].tile )
//the level editor stores tiles that are larger than the grid size at indices containing values that are a percent of the tile size
var tile:Object = _tiles[m][i][j];
if ( tile != null && int( tile.tile ) == tile.tile ) {
addTile( g_global.GRIDSIZE * tile.column, g_global.GRIDSIZE * tile.row, { index:tile.tile, bitmap:assets[ tile.tile ] }, tile.rotation );
}
}
}
}
_canvas.bitmapData.lock();
}
Anyway I hope this information finds you well. Good luck!
I asked a similar question a while back: https://gamedev.stackexchange.com/questions/60433/is-it-more-efficient-to-store-my-tile-grid-as-a-dictionary-or-an-array. I'm not sure that it would really matter whether it's an Array or a Vector (the differences in efficiency seem to differ between FP versions, etc.).
But, yeah, you probably want to use one or the other (not a Dictionary or anything), and you probably want to index it like [y * width + x], not [x][y]. Reasons: Efficiency and not having overly complicated data structures.
Also if you need to be able to regularly access the Array or Vector outside of that class, just make the variable internal or public or whatever; making it private and wrapping over it with functions, while being more prim-and-proper class design, would still be overkill.
One method I am using right now for my own thing is that I'm storing my tiles in a black and white pixel bitmap (and wrote a wrapper around that). I'm not sure how efficient this is overall as I've never benchmarked it and just wrote it quickly to create a map for testing purposes, but I am finding that it does offer an advantage in that I can draw my maps in an image editor and view them easily while still allowing random pixel/tile access.
Looking at your sample code, I'm guessing you have only two types of tiles right now, so you could just use black and white pixels as well if you want to try it.
I've done the 2d array method as well (using it still actually for other parts) which works fine too, but perhaps can be harder to visualise at larger sizes. Looking forward to Bennett's answer.
I'm pretty much an actionscript novice and I'm trying just slice the first and last X bytes out of a byte array in as3, and can't seem to find anything anywhere on how to do that.
If it matters, the byte array is a set of floats recorded from a microphone that I'm trying to cut the first and last 1/4 of a second off of before it's encoded as a .wav file.
Assuming you an existing ByteArray, let's call it rawBytes:
var trimmedBytes:ByteArray = new ByteArray();
var quarterSecond:int = 1000; // no. bytes per 1/4 second (arbitrary estimate)
rawBytes.readBytes(trimmedBytes, quarterSecond, rawBytes.length - quarterSecond * 2);
Your trimmedBytes variable will now be populated with the second recording minus the first and last quarter second - assuming that quarterSecond variable has the right value. I don't know what that value should be, I'd imagine it would depend on the bitrate at which you're recording. You could probably get there via trial and error though!
I have a C++ QT application that is sending a ByteArray of ARGB values via a TCP socket. The image is 100 x 100. The problem is that when I read off the ByteArray I can't seem to get the image to display right. I've tried lots of different ways and here is AS3 code that's got me the closest.
bitmapData.lock();
for(var x = 0;x<100; x++){
for(var y = 0;y<100; y++){
alphaValue = byteArray.readUnsignedByte();
redValue = byteArray.readUnsignedByte();
greenValue = byteArray.readUnsignedByte();
blueValue = byteArray.readUnsignedByte();
color = redValue << 16 | greenValue << 8 | blueValue;
bitmapData.setPixel(y,x,color);
}
}
bitmapData.unlock();
I'm just not using the alpha value at the moment because I'm not sure what to do with it. Qt says "The image is stored using a 32-bit RGB format (0xffRRGGBB)." I tried using readUnsignedInt() too, but that didn't work either.
Here is what I'm trying to send and what I see on screen.
Sent : Received in Flash
It's close, but not just right. Does anyone have any idea what I may be doing wrong?
Much easier would be to use readUnsignedInt instead of multiple calls to readByte. Then use bitmap.setPixel32 instead of setPixel. That way you don't have to deconstruct and reconstruct the values.
You might also have to switch the endian-ness (e.g. byteArray.endian = Endian.LITTLE_ENDIAN) depending on how it's encoded. I just can't remember off-hand which way around it is, so you can try that if it doesn't work first time.
A few days ago, this was my question, and I found the answer. Maybe this will help someone else.
A. The first part of the problem: can you amplify sound using Flash? The AS3 documentation for SoundTransform says this about the volume attribute:
"The volume, ranging from 0 (silent) to 1 (full volume).
At face value, this means you can only make sounds quieter. In fact, if you supply a value greater than one (1.0), sounds will be amplified. You risk saturating the sound and getting poor quality, but you can do it, and for voice, you can get away with a lot. (Music is less forgiving, so experiment. This method does not do dynamic compression, which is better suited to music.)
B. The second part of the problem: the order in which you do things.
RIGHT:
soundTransform = new SoundTransform();
soundTransform.volume = volume * volumeAdjustment;
audioChannel.soundTransform = soundTransform;
WRONG:
soundTransform = new SoundTransform();
audioChannel.soundTransform = soundTransform;
soundTransform.volume = volume * volumeAdjustment;
I did some testing in CS3 and CS4, and got different results. In CS3, I could set the volume on the transform AFTER "audioChannel.soundTransform = soundTransform;" and everything was fine. But in CS4 it had no effect. I suspect that CS3 used pass by reference to set the soundTransform, while CS4 uses pass by value semantics and copies the object passed into it. The CS4 approach is better designed, but did break my code that worked fine in CS3.
C. The last question, is how to convert a decibel value to a factor that can be multiplied by the volume to amplify (or quiet) the sound by the desired amount.
var multiplier:Number = Math.pow(10, decibels / 20); // Power vs. amplitude
Note that "decibels" may be a positive number (to amplify) or a negative number (to make quieter). If decibels is zero, no change occurs.
A value for decibels of 3 will (to a close approximation) double the amplitude.
A value of 10 decibels will increase the volume tenfold (exactly).
Your decibel calculation should actually use 20, not 10:
var multiplier:Number = Math.pow(10, decibels / 20);
Digital audio is amplitude, not power (it's a representation of sound pressure, not sound power).