Replacements for Adobe Flash's hitTestObject Method - actionscript-3

so I've recently had problems with using hitTestObject. I did a bit of research about hitTestPoint and that is too exact. And, using the bitmap is a bit too complicated for me.
Is there any other user-made collision detection functions? If so, how would I use it? I am trying to test if the object eChar collides with an objecy called bd1. I've found one, but that required my code to be in a class, which it isn't (it's programmed in the action window).

A very popular API is PixelPerfectCollisionDetection.
All you do is import it (import PixelPerfectCollisionDetection;) and check collisions like:
if(PixelPerfectCollisionDetection.isColliding(eChar, bd1, commonParent, pixelPrecise (set to True for Pixel detections), tolerance:Number = 0 (for testing if testing for same Alpha) )) which either returns true or false

Related

On the use of frames and functions in Flash AS3

My question is, in a flash game I use different frames for levels. And I am confused on how functions work for this. My first frame works fine but I need help with using functions on other frames and keeping functions specific to one frame. Any help is appreciated, just a quick simple explanation
You cannot associate a function with a specific frame.
When you execute code on a frame, what actually happens is the MovieClip containing that frame will call a function called addFrameScript(), passing to it a representation of the code you write on the frame.
This means:
Until you visit a frame that defines a function, you cannot call said function.
Once you have visited a frame that defines a function, that function is attached to the parent MovieClip, and you are able to call the function at any point in the timeline that is earlier or later.
If you try to define a new function with the same name on a different frame, you will get a 1021: Duplicate function definition error.
Instead of making a new function for every frame or level, you should make a single function that is able to handle different information that is representative of a level, e.g.
function loadLevel(level:int):void
{
// Do stuff with the value of level.
// For example, this function might look at a data source that maps
// the level numbers to some level data representing tile placement.
}
This could be defined on the first frame, then on each subsequent frame:
loadLevel(1); // Frame 2
loadLevel(2); // Frame 3
// ...etc
All of this of course is not ideal and could be done better avoiding the timeline and instead using to OOP paradigm that AS3 provides.
I have found using multiple levels within the same scene causes no end to headaches for me.
I'm no expert & i'm sure its possible to do so in many cases and I have seen some great games created using 1 frame 1 scene & all code in an external .as.
However I find it much easier myself to just use 1 frame per level and put each level in a different Scene.

Loader.as returning blank bitmap

I have an application which pulls in Bitmap resources from a server - currently I use the Loader class to do this, then, once they're loaded, generate a BitmapData based on the loader dimensions and draw the instance of Loader directly to it (the BitmapData is used for Away3D textures as well as Bitmap instances, so I have no need for the Loader once fetched).
This has always worked for me, but recently I started getting 0x0 Loaders, and invalid BitmapData as a result.
I stopped doing this:
this.imageBitmap = new BitmapData(this.imageLoader.width, this.imageLoader.height, true, 0);
..and started doing this:
this.imageBitmap = new BitmapData(event.target.content.width, event.target.content.height, true, 0);
Where event is the Event.COMPLETE event fired by the loader. This fixed the dimension problem, but the BitmapData is just a plain white bitmap (and it's set to transparent by default, so this is being drawn into it). Frustratingly, this doesn't happen every time, if I refresh the application it works as it should around 25% of the time, otherwise it plays up like this.
I've got a tight deadline and I'm really screwing about this, if anyone could help or suggest a better way of doing it you'd really be saving my neck!
Sounds like you need to adjust the image decoding policy for the loader - to ensure it decodes the image before COMPLETE fires - then the width and height etc should be reliable.
To do it, just add a suitable LoaderContext object to the Loader.load method:
var loaderContext:LoaderContext = new LoaderContext();
//set decode policy
loaderContext.imageDecodingPolicy = ImageDecodingPolicy.ON_LOAD;
//load image
loader.load(yourUrl, loaderContext);
The default decode policy is ImageDecodingPolicy.ON_DEMAND - which doesnt decode the image until it is actually required.
Lang docs: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/ImageDecodingPolicy.html
Fixed it, stupid oversight and bit of an obscure situation but I'll leave an answer in case anyone runs into something similar.
My loader is contained in an Asset class - when another object requires the internal bitmap, it queries this class - if the bitmap's present, it returns it, if not it loads it with a loader and registers a callback for a COMPLETE event which is fired when the Loader has loaded and transferred its contents to a BitmapData instance.
The stupid mistake I'd made was that, if several objects were querying the same (as-yet-unloaded) asset, it would start reloading the asset each time, creating a new Loader as it did so...so when the first Loader was complete, it would fire an event but no reference to it would exist, not only creating a memory leak but causing the Asset class to extract the BitmapData from the most-recently-created Loader, which was not complete! The asynchronous nature of Loader is the reason it worked sometimes, as on occasion the final Loader would be ready in time for BitmapData extraction.
Simple solution was to create an internal boolean, _isLoading, which is set to true the first time load() is called - any subsequent calls are ignored if it's true, but callbacks still registered, works a treat!

How can AS3 front-end code and AS2 server-side scripting send objects back and forth, while keeping their methods?

Given the following AS3 front-end code:
m_nc.connect("rtmp://" + pPrimaryIP + "/appname/"+ pVID, pUID, pConfig);
and the following AS2 server-side scripting code:
application.onConnect = function(pClientObj, pUID, pConfig)
{
// do stuff
}
where pConfig is an object of type Configuration, as defined in the AS3 code, having the method:
public function copy(pConfig:Configuration):void
apparently when you try to send the object across while connecting, it loses that method and any other methods. Yet its fields remain basically intact, at least if they're primitives. I can see why this might be so, but is there not some way to keep this loss from happening? I really want to be able to not just send it to the AS2 without losing anything, but to also be able to send it back to the AS3 without losing anything. Is this possible? If so how? Thanks!
You should look at LocalConnection, a class available to both AS2 as AS3 (AS1 even)
clicky

referencing existing sound objects on the timeline via actionscript 3

In Actionscript 3 / Flash 10, is it possible to programmatically reference a sound object that exists on the timeline? I've found lots of examples for referencing DisplayObjects via the following sytax:
var m:MovieClip = stage.getChildByName("SomeMovieClipClass");
var n:MovieClip = stage.getChildByIndex(1);
But this doesn't seem to include sound objects. Similarly, it seems straightforward to instantiate and play a sound that exists in the Library via Actionscript:
var s:SoundClip1 = new SoundClip1(); // exported in first frame via properties
s.play();
For my purposes, though, I'd like to reference sound clips (ideally in a specific layer, although that seems to be a design-time element) that designers have adjusted and arranged on the timeline, so that I can inspect their waveforms via code, at runtime. Something like this:
// Imaginary Code
sc = timeline.getSoundClipByName("SoundClip1");
sc.extract(waveform,sc.length/1000 * bitrate);
Is this possible? Thanks!
As of this date, no it is not possible to access the soundChannel generated by a timeline sound. It's a feature I would love to see implemented.
I was going to try to test the feasibility of using computeSpectrum to get the waveform of a timeline sound but I'm having problems importing mp3s right now. In absence of firsthand proof of concept, I searched around and found this thread:
http://www.kirupa.com/forum/showthread.php?t=329632
Which links to this solution
http://www.mail-archive.com/flashcoders#chattyfig.figleaf.com/msg43157.html
But of course this doesn't allow you to disambiguate between different timeline sounds. I'm pretty sure you won't be able to do that at all.
I have not ever used Sound.extract(), but if the sounds exist in the fla library this indicates to me that you can simply give them a Class name and at runtime use extract() to gather the waveform for your own purposes, yes? Then whenever the appropriate timeline sound plays, you can tap into the waveform from the Sound object. Perhaps a timeline callback or event would suffice for this?

BlackBerry - Exception when creating a graphics object from a bitmap

I am making the following call in my blackberry application (API ver 4.5)...
public void annotate(String msg, EncodedImage ei)
{
Bitmap bitmap = ei.getBitmap();
Graphics g = new Graphics(bitmap);
g.drawText(msg,0,0);
}
And I keep getting an IllegalArgumentException when I instantiate the Graphics object. Looking at the documentation for Graphics is confusing as it leaves many things unstated.
What does it mean by 'default type of the device'?
How do you know if the type of 'bitmap' is not supported? Does this mean that there are different types of bitmaps? Can different encodedImages generate different types of bitmaps?
Is there another way to add my string to the associated encoded image?
public Graphics(Bitmap bitmap)
Constructs a Graphics object for drawing to a bitmap.
Parameters:
bitmap - Bitmap to draw into. Must be Bitmap.COLUMNWISE_MONOCHROME or the default type of the device.
Throws:
IllegalArgumentException - If the type of 'bitmap' is not supported, or the bitmap is readonly.
Are you sure that your Bitmap is mutable? You can't create Graphics objects from immutable Bitmaps. That is one cause of an IllegalArgumentException. You can set the decode mode for your EncodedImage (EncodeImage.setDecodeMode). There are different modes that allow you to specify whether the file is native or readonly...along with other modes that can be combined.
The size of the bitmap might be another IllegalArgumentException. Of course, this is relevant to the target device.
I'd imagine that the default type depends on the graphics chip and hardware. (If you have a monochrome screen, the default would probably be different than if you had a color one.)
Bitmap has a static method getDefaultType(), which "Queries the default Bitmap type for the device". There's also a non-static method getType(). It seems to be telling you the rule is that for the code above to work then either:
bitmap.getType() == Bitmap.getDefaultType()
...or...
bitmap.getType() == COLUMNWISE_MONOCHROME
And presumably neither of these conditions are true. You can do a sanity check on that, and maybe print out the result of getDefaultType() so you know what your target is.
Looks like you'll have to convert the bitmap or get it from somewhere else.
The Graphics object isn't normally constructed explicitly. Rather, you are given an instance of it in the paint() method, if you've overridden it.
I suspect what you want to do is create a subclass of BitmapField and override the paint() method to include your code for drawing text on the bitmap.