But wait, there’s more!
With all the excitement about the Windows Beta, the really awesome 3rd party tools, and the new Indie iOS price point, it’s easy to miss all the cool new features we added to plain ol’ Corona.
So let’s walk through them and show some code:
In-app purchase
In the movie All the President’s Men, Deep Throat tells Woodward to “follow the money”, so let’s start with in-app purchase (IAP). There’s a more extensive walkthrough here, but I’ll just show you a brief code snippet so you get the gist.
To access it you use the new store module. On the coding side, there’s basically 3 steps:
- Initialize the store: This is just loading the store module and registering a transaction listener.
- Load valid products: You request which products you want to load. Every product is specified by a product identifier that you have to register through Apple’s site.
- Purchase a product: Once an identifier is validated, the purchase can proceed.
Here’s a code snippet (minus a bunch of code for error checking and user feedback) showing all the pieces together:
local store = require("store")
-- listeners needed for IAP.
local function onTransaction( event )
if event.transaction.state == "purchased" then
-- (4) Transaction succeeded
native.showAlert( "Thanks for your purchase!", "Transaction successful.", { "OK" } )
end
end
local function onLoadProduct( event )
local products = event.products
if products and #products > 0 then
if store.canMakePurchases then
-- (3) purchase all valid products
store.purchase( products )
end
end
end
-- (1) Initialize the store
store.init( onTransaction )
-- (2) Load the products. (3) and (4) happen inside the listeners
store.loadProducts( { "com.anscamobile.myProduct" }, onLoadProduct )
Amazingly, the hardest thing about IAP is actually setting up the products on Apple’s server/website. In our internal testing, we actually hit a big roadblock where the test product identifier was coming back as invalid. After scouring the Internet, we realized we had to complete the banking contracts portion of the iTunes Connect portal before any product identifier could be validated. Hopefully, this little tip saves you some heartache!
Right now, the store module is only available on iOS. We’re looking into how we might offer something on Android.
Bitmap masking
Everyone’s been dying to use masking, so we wanted to make it really cool.
Here are the key lines from the Flashlight sample code:
local image = display.newImageRect( "image.png", 768, 1024 )
image:setMask( mask )
That’s it! You create a mask object based on an image and then apply it to another image. Here’s the basic equation:

And if you’re wondering, yes, you can reuse the mask object and call setMask() on another display object.
Now in the actual sample, you’ll notice that as you touch and move your finger, the circle becomes elongated, as if the flashlight were getting tilted to illuminate the edges of the screen. That’s because you can set the position, scale, and rotation of the mask independently of the image that’s getting masked!
Some caveats that you should be aware of (full description):
- Important: You must have at least a 3-pixel black border for your mask image. Otherwise, strange artifacts will appear. This is related to the fact to the power-of-2 nature of texture dimensions and the way OpenGL treats boundary conditions.
- Nested masking has limitations (i.e. a mask inside a mask) because of per-device hardware limitations. The depth is generally one less than the number of texture units in the OpenGL hardware. This is especially true on Android devices, e.g. Nexus One only has 2 texture units, so you cannot have a mask within a mask. Again, it depends on the Android device you’re dealing with.
- You may see problems masking text objects
- This is not available yet in the current Windows Beta.
After we implemented this, we’ve realized there’s only so much you can coax the fixed-function pipeline (i.e. OpenGL-ES 1.x) to do when it comes to cool image processing effects and still deliver decent performance. I’ll save that topic for a future post…
Async HTTP
And (at long last!) you can now do http requests asynchronously. This includes secure http (https)! With the new network module, you can perform asynchronous http requests. The network.request() function lets you obtain responses from a request and the network.download() function lets you download a file.
Here’s a quick example of a secure http request. The listener is invoked when the request is complete:
if ( event.isError ) then
print( "Response is an error!")
end
print ( "RESPONSE: " .. event.response )
end
-- Access Google over SSL:
network.request( "https://encrypted.google.com", "GET", onResponse )
We realized that a lot of you probably wanted to download images asynchronously, so we added a new function to the display module that lets you do that:
if ( event.isError ) then
print ( "Remote image load failed: ".. event.response )
else
print ( "Image downloaded to file: " .. event.response )
end
end
myImage = display.loadRemoteImage( "http://developer.anscamobile.com/demo/hello.png", "GET", networkListener, "helloCopy.png", system.TemporaryDirectory, 60, 280 )
The best part is that display.loadRemoteImage() is implemented entirely in Lua. I’ll show you how it was done in a future post.
Walter, can we create a mask out of primitives rather than from an image?
cheers,
Jayant C Varma
The current implementation only supports masking based on bitmaps. It converts an RGB image to grayscale and uses that to modulate the alpha of the image you want to mask.
Great!!!
Can I use this masks in display groups?
ok. maybe an obvious question, but are we supposed to re-download the sdk? if so, the site is not real clear about gettting an “update”.
Do we download the 3rd party tools separately or does Corona provide it in the SDK
@Jayant, on the flip side, if you apply a mask to a vector object (e.g. a rect), it will mask that object.
@Ricardo, yes, it works with groups.
@Ross, yes, you must download the update. It should be build 268.
@Olek, d/l them separately, except the photoshop exporter which comes bundled in the dmg. Here’s a link: http://www.anscamobile.com/corona/tools/
It does not appear the params argument is working for the Async HTTP request. I am trying to add custom headers and set a cookie value but it doesnt work. If you set params.headers to anything, the Simulator crashes. Is there a workaround or code example of setting a cookie and custom headers on an SSL request?
Thanks so much!
@ray – it is a bug and it has been fixed will be out in a few days
C
Great! Thanks so much. I just started using Corona yesterday and I like what I see so far. Also I have a few more questions if I may:
how are cookies handled? I notice that sending requests sometimes has cookies already attached, do you pull local cookies from Safari?
Will they be overriden if specified as a param?
Is it possible to retrieve the response headers from the response with Async HTTP (I need to grab the set-cookies)?
Thanks, I hope I didnt miss a doc with these answers.
Ray
@ray
use the forum – some users may have had the similar question and could answer you faster or see if someone else has implemented it
c
I would but I cant post. In fact when I login, the only forum available is “New Users Start Here”. I have to log out to see the other forums and I cant post to any.
Does Corona SDK come with its own Photoshop or do we have to get it fro somewhere else