Showing all entries for: December 2010

Corona Collision No-No

While working on our latest project (Biffy directing this one), I ran into what seemed like a bug with collisions in Corona. I hadn’t got very far into the project yet, so the collisions were still pretty basic.

After looking over my code to see if it could possibly be my fault (and not a bug), I didn’t find anything and decided to submit a bug report to the Ansca Bugs team.

Here’s a closer look at what was going on…

The code I was working on involved shooting bullets at moving enemy targets. The crashes seemed to occur pretty randomly, which is why I thought it was a Corona bug. It didn’t occur on every collision though, and never after a specific number of collisions, so identifying it was a little frustrating.

After exchanging some emails with Ansca engineers, and doing more investigating on my own, it turns out it wasn’t a bug within Corona, but a limitation of the Box2D physics engine itself.

Here’s what my code looked like (that produced the crash):

local bulletCollision = function( self, event )
    if event.phase == "began" then
        self.isBodyActive = false
        self.isVisible = false

        event.other.isBodyActive = false
        event.other.isVisible = false
        event.other.lives = event.other.lives - 1
    end
end

Looks pretty basic right?

Well, as it turns out, Box2D will crash if you try to change the properties of an object that is involved in a collision at the exact time of the collision. Due to variances in collisions (especially when it comes to shooting bullets), sometimes it would result in a crash, and sometimes it wouldn’t—the timing had to be just right.

Surely you’re going to run into a time when objects need to be modified, moved around, etc. upon collisions, so how do you get around this Box2D limitation?

It’s actually pretty simple. You wait, and then execute your code.

The workaround seemed to fix the issue as it worked flawlessly every time (even after turning up the amount of objects to produce an overwhelming amount of simultaneous collisions):

local bulletCollision = function( self, event )
    if event.phase == "began" then
        local doCollision = function()
            self.isBodyActive = false
            self.isVisible = false

            event.other.isBodyActive = false
            event.other.lives = event.other.lives - 1
        end

        local collisionTimer = timer.performWithDelay( 1, doCollision, 1 )
    end
end

The only thing I did was “wrap” the existing code into a local function, and then call a timer with a 1 millisecond delay to execute the function. Like I said, it worked flawlessly every time.

I even tried a timer with a 0 millisecond delay with success, but I didn’t do extensive testing with that so I recommend sticking with 1. There’s not much time difference there anyway.

Admittedly, the whole thing seems a little weird, and Ansca engineers said they’re working on a way to incorporate something like that automatically into Corona’s backend so it’s never an issue.

Until then, this workaround is simple enough to implement and you should be using it with all of your collisions where you need to change any attribute of the objects involved—especially x/y values, I noticed changing those produced the crash nearly every time.

Needless to say, it was a little bit of a headache trying to figure out what was going on, and figuring out how to make things work, so hopefully this will save you some headache in the near future :-)

Point Reduction, Curve Fitting, & Bezier Curves

(video removed)

Special thanks to Carlos Icaza for a great contribution that will undoubtedly open up some possibilities for developers who otherwise would have no clue how to accomplish what he just did in the video (cough… me… cough).

The video shows two algorithms, a variant of the Douglas-Peucker polygon point reduction algorithm and Philip J Schneider’s CurveFit algorithm from Graphic Gems I with material from Philip’s book Geometric Tools for Computer Graphics, as well as material from Mark de Berg Computational Geometry and lastly, Gerald Farin’s Curves and Surfaces for CADG 5th Edition.

Infinitely useful, but also infinitely complicated. Thankfully, the source code will be made available soon so Corona developers can easily leverage Carlos’ hard work.

I’ve said it before, and I’ll say it again, the possibilities of the Corona SDK are endless. Carlos dug out books from way back before Corona even existed and was able to apply the same logic to a Corona project that’ll be soon be available to import into our own projects.

I’ll update this post once the source code is available, so stay tuned!

BeebeGames Class 1.6 Released. Per user request, added event.name and event.count parameters to listeners passed to the performAfterDelay() function.

Top 5 Things the iPhone Has Given the World. Great read from PC World (ironically, since it’s about Apple):

In addition to making shareware trendy, the App Store did something much more important: It turned the cell phone into a computing platform.

Suddenly, cell phones could do just about anything, even if that usually equates to playing games. As Apple advertised, if you can find a task, there’s likely “an app for that.”

Again, this wasn’t entirely new. Significant amounts of money and time had been invested in making it possible to run Java applications on phones for years. However, Apple shifted the focus in a way only it can.

The iPhone personally changed my opinion about mobile platforms. Before the iPhone, I was a web developer who had no interest in focusing on mobile platforms. I heard about the iPhone in 2007, but still wasn’t interested.

Then, in 2008, I finally used one, and it changed all my preconceptions of mobile computing. When it comes to work, mobile is all I focus on now.

Useful Circular Movement Tutorial. The tutorial is for ActionScript, but the logic can be easily converted to Lua. Circular movement is kind of confusing, but useful for many animations in games. I might consider adding a related function to the BeebeGames Class eventually.

Outstanding Collision Filters Chart. Special thanks to Brent Sorrentino of Ignis Design LLC for this amazing resource.

Collision filters (a Box2D concept) is something that I have always been pretty confused about when it came to setting up new ones and how it all worked. The chart that Brent provided (back in October!) makes the whole thing a billion times simpler.

The page shows an example chart with step-by-step “how to” instructions, and then provides a link to a blank chart (PDF).

I recommend using an app such as Skim so you can draw on the PDF document and create a collision filter chart for each of your projects (that need it).

BeebeGames Class 1.5 Released. If you downloaded this class previously, this update is a MUST. It fixes a major bug that pretty much rendered the entire module useless if you used physics. Don’t worry, all of your previous code should work. I try my best to make each update backwards compatible so you’re not having to modify your code as you download new updates.

Here are a few more changes/fixes:

  • Better compatibility with Ricardo Rauber’s Director Class. In previous versions, sometimes you’d get errors while changing scenes. This update fixes that.

  • Added table to keep track of all objects created with newObject().

  • Added a function that allows you to destroy all objects created with newObject() all at once (destroyAllObjects).

I was going to wait until more features were added before releasing version 1.5 (because updates are coming VERY frequently), but after I ran into that big bug I knew I had to release this update right away.

I apologize for any inconvenience that the bug caused anyone in the meantime, but thankfully it’s fixed now.

BeebeGames Class Version 1.4 Released. A very small update that adds an onStart parameter to the doTransition method.

BeebeGames Class 1.3 Released. In additions to new things added in 1.2 today, this version includes a table that holds all active timers (timers that haven’t been canceled) as well as functions to pause, resume, and cancel all timers with one line respectively.

Also, I just published a tutorial on how to take advantage of all new additions in 1.2 and 1.3.

How to Use the New Time Functions

Combined, the BeebeGames Class version 1.2 and 1.3 features 6 new time-related functions, one of which being a complete replacement for the built-in timer.performWithDelay() as well as a—much requested—table that holds all active timers.

Before we get started on anything, you’ll want to import the beebegames.lua module into your project and localize the functions you’ll be using:

game = require( "beebegames" )

local resetTimeCounter = game.resetTimeCounter
local getCountedTime = game.getCountedTime
local performAfterDelay = game.performAfterDelay

local pauseAllTimers = game.pauseAllTimers()
local resumeAllTimers = game.resumeAllTimers()
local cancelAllTimers = game.cancelAllTimers()

resetTimeCounter() and getCountedTime()

These two functions go hand-in-hand and have to do with counting time as it passes. This can be useful for many different scenarios, for example, checking to see how long it took a player to complete a round… but I’ll leave the “when” up to you.

Here’s how to use it:

-- create a new counter variable
local timeCounter = resetTimeCounter()

The above code will start/restart the time counter. Then, when you want to find out how much time has passed (in milliseconds), use the next function:

local timePassed = getCountedTime( timeCounter )

You must pass your counter variable as an argument to getCountedTime() in order for things to work properly.

Now for the really good stuff…

performAfterDelay

You’re probably already familiar with Corona’s built-in timer.performWithDelay() function, because performing a specific action after a set delay in time is a task that is common to many games and apps.

However, there is one limitation to the built-in function that could cause a lot of unnecessary headache: the inability to pause and resume active timers! Thankfully, the BeebeGames Class has you covered with performAfterDelay() :-)

As a quick note, you’ll still be responsible for keeping track of and removing active timers during screen transitions, etc. In fact, everything is still the same as the old timer.performWithDelay() function, only with some minor changes and additions.

The most notable change is the fact that you specify your delay in seconds instead of milliseconds. So if you need to get between seconds, you simply pass decimals. So for a 350 millisecond delay, you’d pass 0.35 instead. Here’s what the whole function looks like:

performAfterDelay( secondsToWait, functionToCall, howManyTimes, isFps60 )

The last argument is also new. If you modified your config.lua and have your app set to 60 FPS, you’ll pass true to this argument. Otherwise, you can set it to false or leave it out (it defaults to 30 FPS). This is so timing stays on track (and is responsible for allowing you to pause/resume each timer).

As with the old function, passing 0 to the howManyTimes argument will result in an infinitely-looping timer (will continue to go until it is paused or canceled).

In the example below, we’ll call a function to print the words “Hello World” to the console after 10 seconds:

local printMessage = function()
    print( "Hello World" )
end

local newTimer = performAfterDelay( 10, printMessage, 1, true )

And if you want to pause the timer mid-way through:

newTimer:pause()

And to resume:

newTimer:resume()

When you’re finished with the timer, you can destroy it by calling:

newTimer:cancel()
newTimer = nil

You cannot resume a canceled timer. It is also best practice to always assign these timers to a variable (or you won’t be able to pause/resume), and to make all timer variables local. You’ll also need to nil-out the variable you used to hold the timer manually.

One Table to Rule Them All

Beginning in version 1.3, the BeebeGames Class includes a—much requested—table to hold all active timers (timers that haven’t been canceled), as well as functions that will allow you to pause, resume, or cancel all of these timers with just one line of code respectively.

All timers are held in a table called beebegames.activeTimers, and below is how you can perform bulk actions on all of your timers:

  • pauseAllTimers() –> pauses all timers

  • resumeAllTimers() –> resumes all timers

  • cancelAllTimers() –> cancels all timers

All of the functions above put every single timer on the same level, so if you have some paused and some active, all will still be paused and resumed upon calling the above functions.

I hope you find all of the new additions in version 1.2 and 1.3 useful—I know my own projects will. Once again, you can get the module from the Corona Code Exchange.

BeebeGames Class Version 1.2 Released. Added functions that deal with time. Here’s a short rundown:

  • resetTimeCounter()

  • getTimeCounted()

  • performAfterDelay()

In case you’re wondering, the performAfterDelay() function is a complete replacement for the existing timer.performWithDelay() function that now supports pausing and resuming!

I plan on publishing a tutorial that covers the new additions sometime today, so stay tuned.

Holidazed is Ansca’s App of the Week. Congratulations to reallyMedia for the awesome job! Very interesting, especially since our next game, Antsy Pantsy, will also be a side-scrolling platformer.

BeebeGames Class Updated to 1.1 - Fixes Bug. Quick update that fixes a bug where the text size argument in newRetinaText() wasn’t working correctly. No new features added this time around, but the next update should have some.

Exciting Announcement from Ansca Mobile. According to co-founder Carlos Icaza, great things are in store for the Corona SDK in 2011. And to top things off with a side note, the communication from Ansca Mobile to the developers using their product is outstanding, and even then, they’re still striving to make it better with some of the new things coming.

Lua is 24% Faster Than UnrealScript. Nothing new, but something I found that was very interesting (and uplifting):

Lua is performing at around 1/7th the speed of C++ for n=1000 and 1/40th for n=7000. It is about 24% faster than UnrealScript.

Once again, great decision on Ansca Mobile’s part for choosing Lua as the language to interface with the Corona SDK.

BeebeGames Class: newRetinaText() Tutorial

When I finally got an iPod touch 4 and began making our games compatible with the new retina displays, everything looked amazing. Everything except text, that is. The graphics were really sharp, but any text created using display.newText() came out looking blurry because as-is, it’s not yet optimized for the retina display.

I discovered a workaround, which required significantly more work than displaying text the regular way, so I included a new function in the BeebeGames Class that should make displaying retina-screen compatible text just as effortless as displaying text using the old method.

Things do get a little bit different, however, when it comes to updating existing text that’s not center-aligned (there is an alignment setting with this new function).

Here’s what the function looks like:

newRetinaText( textString, x, y, fontName, fontSize, r, g, b, alignment, parentGroup )

For the most part, it’s the same as the original display.newText() function, with some additions. The r, g, b arguments are there so you can go ahead and set the text color without wasting an extra line of code, and the alignment setting works in the same fashion as just about any text editor (“left”, “right”, “center”).

Remember, before you can use any of the BeebeGames Class functions, you need to include it in your module. I also recommend localizing the newRetinaText() function as well:

game = require( "beebegames" )
local newRetinaText = game.newRetinaText

Now, let’s display some (white) text at the top-right of the screen (offset a little), which is a common place for a score display in many games.

local scoreLabel = newRetinaText( "Score: 0", 305, 15, "Helvetica-Bold", 20, 255, 255, 255, "right", textGroup )

And that’s it when it comes to simply displaying text. As you can see, it’s similar to the newText() function, but you can get even more done with just that one line.

Updating Text

Now, since the text we displayed isn’t center-aligned, things are a little different when it comes to updating a text object you’ve created. If you simply change the .text attribute (like you would normally do), chances are, your text’s position on the screen is going to get a little screwed up.

Thankfully, I created an updateText() method that makes things easy. So let’s say we want to update our text object to read “Game Paused” instead. Here’s how you’d do it:

scoreLabel:updateText( "Game Paused" )

It doesn’t get much simpler than that, folks :-)

Test it out and build for an iPhone 4 or iPod touch 4, you’ll be amazed at how clear the text is.

Once again, you can download the BeebeGames Class from the Corona Code Exchange when you’re ready to get started.

Introduction to beebegames.newObject()

Yesterday, I released the BeebeGames Class, so today I’m going to describe how to use one of the main features, and that’s the newObject() function. In a nutshell, here’s what it does:

the newObject() function replaces display.newImage, display.newImageRect, AND movieclip.newAnim for those who want to get an image object on the screen, positioned, and into a group with just one line of code.

It does more than that, but that’s the basics of it. Before we do anything though, we need to import the beebegames.lua module into our project. If you have more than one module in your app, then I would NOT make it local so other modules can access it:

game = require( "beebegames" )

And that’s it. To speed things up, you should store some of the functions you’ll be using as local calls like so:

local newObject = game.newObject

And that covers the preliminary work that needs to be done to start using the newObject() function.

To better demonstrate the effectiveness of this new function, I’ll go over the old way of doing things, and then I’ll show you the BeebeGames Class alternative. First, we’ll cover static images, and then go on to cover animated objects.

Let’s say we want to place a new display object on the screen, at the coordinates 150, 150, and we want that image to be compatible with content scaling. We also want it’s opacity (alpha) to be set to 0.5 (50% opacity). Lastly, we need that object to be placed in a group called imagesGroup.

Here’s how you would normally do it:

local myObject = display.newImageRect( "myImage.png", 48, 64 )
myObject.x = 150; myObject.y = 150
myObject.alpha = 0.5
imagesGroup:insert( myObject )

Okay, so that’s not that bad. But let’s use newObject() to condense all that into one line of code. First, here’s what the newObject() function with its arguments looks like:

newObject( { imageTable }, width, height [, x, y, secondsBetweenFrames, fps60, alpha, parentGroup ] )

And here’s how we use that to create our object:

local myObject = newObject( { "myImage.png" }, 48, 64, 150, 150, nil, nil, 0.5, imagesGroup )

The two nil values have to do with animations, and since this object isn’t animated, we simply set those arguments to nil.

Now going from 4 short lines to one long one might not be enough of a payoff to you, but now that you’ve created the object using newObject(), you now have access to these useful methods:

  • doTransition( )

  • move( )

  • moveTowards( )

  • getAngleTo( )

  • getDistanceTo( )

  • destroy( )

Plus a few animation-related functions. Speaking of animations, let’s go over the old movieclip method of creating an animated object. There’s also spritesheets, but that’s even more complex.

Let’s create an animation that consists of two images (a character walking, for instance), looping indefinitely with 200 milliseconds between the frames, with all the same properties as the last object we created.

Remember, this is the old movieclip method:

local movieclip = require( "movieclip" )

local myObject = movieclip.newAnim{ "myImage1.png", "myImage2.png" }
myObject.x = 150; myObject.y = 150
myObject.alpha = 0.5
myObject.frameNumber = 1
imagesGroup:insert( myObject )

local objectAnimation = function()
    if myObject.frameNumber == 1 then
        myObject:stopAtFrame( 2 )
        myObject.frameNumber = 2
    else
        myObject:stopAtFrame( 1 )
        myObject.frameNumber = 1
    end
end

local myObject.animTimer = timer.performWithDelay( 200, objectAnimation, 0 )

This is where you’ll see the BeebeGames Class really shine. Here’s how to do that same thing using beebegames.newObject():

local myObject = newObject( { "myImage1.png", "myImage2.png" }, 48, 64, 150, 150, 0.2, true, 0.5, imagesGroup )
myObject:startAnimation()

If you set your app to 60 FPS in your config.lua, then you should set the fps60 argument to true, otherwise, set it to false (or nil). This is because the BeebeGames Class uses frame-based animations, rather than time-based. That way, animations are able to be paused/resumed very easily.

Everything starts paused automatically, so make sure your the game.isActive variable is set to true if your animations aren’t playing.

Also, notice that the secondsBetweenFrames is set to 0.2. In movieclip, you use milliseconds, with newObject, you use actual seconds.

Some animation-related methods you now have access to using newObject() include:

  • startAnimation( )

  • stopAnimation( )

  • nextFrame( )

  • showFrame( )

One last thing, if you want your animation to be paused, simply set game.isActive to false, and then back to true when you’re ready to resume. The same goes for the new doTransition() function, but that goes beyond the scope of this article.

And that’s it as far as the newObject() function goes! There’s a lot more to the BeebeGames Class than just that, but I wanted to go over the newObject function because it is one of the main benefits to using the module.

Remember, you can get the BeebeGames Class at the Corona Code Exchange when you’re ready to get started.

Search Added to the Sidebar

Recently, I realized a few things:

  • My blog’s getting bigger, and the content is growing.

  • The search feature in the Tumblr Archives page for this blog is broken.

As a result, I added a new search feature to the sidebar (see it on the right?).

It works great. By default, it’ll search through the posts on my blog, but you can click the ‘Network’ tab (after you do a search) and it’ll run the same search through Biffy’s Blog, the Ansca Blog, and even the Corona Forums!

BeebeGames Class for Corona SDK

No, I’m not talking about an actual “class” where you sit down and learn something, rather, the BeebeGames Class is a module you can import into your projects to take advantage of additional functionality.

You can download it from the Corona Code Exchange.

A Closer Look

So what does it do? Well, it does many things, but the main highlights include:

  • newObject() function that replaces display.newImage, display.newImageRect, AND movieclip.newAnim for those who want to get an image object on the screen, positioned, and into a group with just one line of code.

  • A replacement for movieclip.lua that allows you to control the interval between frames in an animation. Also useful for non-animating object with multiple images you need to switch to-and-from periodically—uses the same newObject() function!

  • A cool—but optional—flipping animation that can be applied when switching between image frames. Comes in handy for card games, etc.

  • New doTransition() function that supports pausing/resuming! Right now, it only supports linear transitions on the x, y, xScale, or yScale properties.

  • Other useful object-related functions such as a relative move() function, a moveTowards() function, as well as functions to get the angle and pixel distance between two different objects!

  • newRetinaText() function that completely replaces the old newText() function, and—you guessed it—shows up clear on retina displays. Also has a few cool features like an updateText() method and an alignment setting.

  • Pause/resume your game by simply switching a .isActive variable to true or false.

  • Allows for an easier way to transfer information between modules (such as a gameScore variable, or anything you need), saving/loading of files in just one line of code, and even a function to place commas in the thousands digit of a number (very helpful when it comes to large score numbers).

All in all, the BeebeGames Class will shave off a lot of time when it comes to doing some of the tedious little tasks, or get an image animating at just the right interval without having to deal with the complexities of spritesheets.

It also cuts out the need for you to figure out complex calculations for getting angles, distances, and provides a lot of other functions that can be applied to many apps, and especially games in particular.

Once again, you can get it at the Code Exchange—feel free to leave me comments/questions there.

Enjoy!

Inheritance In Lua. Very useful resource from Adam Bucketz (Zombies Ala Mode) that I’ll definitely take a closer look at very soon.

UPDATE: The article is very small, but extremely valuable. Everything else I’ve read about this online was too confusing to understand, but Adam breaks it all down in a very consumable way.

Biffy's Graphics = Amazing Work

Biffy’s graphics are amazing, and getting better and better.

I can’t get over how nice the graphics in our latest Corona sample app, Martian Control, are. It makes me kinda jealous that we’re not submitting it to the app store as one of our own :-(

She worked hard for hours yesterday, and got the UFO’s and all the little subtleties of the game graphics just right to give it more of a polished look-and-feel. I’m pretty proud of the little app, but I can’t say I would be as much if it was just the little lines and vector circles that it was before her graphics were in place.

@BiffyBeebe: Great job love :-)

Corona-Made eBook is Ansca’s App of the Week. The eBook, Rabbit and Turtle’s Amazing Race, is also on the top of Apple’s list, as well as another Unicorn Labs eBook—great job guys!

Flight Control Clone with Corona in 30 Hours

NOTE: The video gets choppy at times, but don’t worry, it’s just the video. Actual gameplay is very smooth and works great. Don’t believe me? Wait for the source code… EDIT: It is now available at the Code Exchange.

Biffy and I spent all day yesterday working on yet another sample app with the Corona SDK, to show the world just what it’s capable of, and in a relatively short amount of time at that.

As usual, Biffy worked on graphics while I did the code. Combined, it took us 30 hours to pull this one off. It’s called Martian Control and it’s a clone of popular titles such as Flight Control, Harbor Master, and I’m sure countless others.

Martian Control isn’t just a demo though. This is a full-featured game that has unlimited levels because the goal is simple: reach a higher level, and a higher score than you did before :-)

Déjà vu?

Just last week (but less than a week ago), we created a two-level clone of the popular Angry Birds in 36 hours (Ghost vs. Monsters), so you might be thinking, Why is Beebe Games trying to rip off popular app store hits?

It’s simple: We’re not.

These apps aren’t being submitted to the app store, rather, they’re for Ansca Mobile to deliver (open-source) to show developer’s the Lua-logic behind million-dollar hits such as Angry Birds, Flight Control, etc. and of course, prove that it CAN be done—and done well—using 100% Corona SDK.

So in the meantime, enjoy the—somewhat choppy—video while you’re waiting for the source code to be released by Ansca :-)

UPDATE: It is now available at the Corona Code Exchange.

Biffy’s New Header & Colors Look Great. Features a lot from our upcoming title, Antsy Pantsy, which is being directed by Biffy herself :-)

Check out her site. Leave comments!

Outstanding Lua Performance Doc. Bookmark it, save it, ScrapBook-it (recommended, for Firefox users). In short, every Lua programmer should have this stuff ingrained in their heads (for me, TEST 8 in particular).

Beebe Games Website Revamp Complete. Now with individual app pages :-)

A Few Notes for the Day...

The Ghosts vs. Monsters sample app has had a great response so far, so we’re really happy about that.

Biffy will be directing our next game, a side-scrolling platformer (think, Mario Bros.) that we’ll begin development on shortly.

Afterwards, I think I’ll revisit the Ghost vs. Monsters source code and expand it into a real game (with different graphics and much different gameplay, of course).

Also, expect another full-length Corona SDK review sometime after in-app purchases come out. My previous review covered Corona while still in beta/alpha, so I think it’ll be time for an updated one in a couple of months.

Ansca Mobile on Ghosts vs. Monsters:

After just 36 hours (that’s right, hours!) from our initial sit-down to talk about the game, Jonathan came back to me and asked, “Is this what you had in mind?” We were blown away…

Angry Birds Clone with Corona in 36 Hours

The video above shows a sample app that Biffy and I made for Ansca Mobile to be shared with the community (open-source) so everyone can see how a viable clone of the best-selling Angry Birds can be made in a very short period of time.

The whole thing—from start to finish—took Biffy and I a total of 36 hours. That’s a combined total for code, graphics, gathering sound assets, etc. The game is full featured, optimized for the retina display, and works as-is. There are two playable levels, as well as OpenFeint and Facebook Connect integration.

Anyone in the game development business knows that 36 hours is an extremely SHORT amount of time for a game such as the one we made. Of course, it only has two levels, but creating levels didn’t take up that much time, it was everything else.

The true benefits of using the Corona SDK really shine through with our little sample app. It’s possible to create powerful, full-featured apps that perform just as well as native apps in a very SHORT amount of time.

Please keep in mind that the sample app is not meant for you to take the graphics, code, etc. package it up as your own game and submit it as-is (it’s not production-level as-is). Rather, it is meant to show developers (you) the source code to a clone of a very popular game, in case you want to take some of the logic and use in your own projects.

It is open source, however, so if you do use the graphics or anything else, I suggest you modify them to make it unique to your own game, and please don’t forget to give attribution :-)

This should satisfy anyone who’s ever emailed me asking for the source code to Tilt Monster, Dragon’s Keep, or Dungeon Tap and I was unable to provide it.

Ansca should be releasing “Ghosts vs. Monsters” to the public soon, so if you’re a Corona developer and want to pick apart the source code, stay tuned!

EDIT: Looks like they already released it. Visit the Corona Codebase to get it now!

In-App Purchases Scheduled for Mid-January!

Carlos Icaza made an exciting announcement in the Ansca forums today. I’ll let his words speak for themselves:

The number one requested feature: In App Purchases will be on the next drop expected Mid-January.

As well as a ton of bug fixes, android fixes, there will be a few other features such as

Push Notification, Universal Binaries, Bitmap Masking, Async http, Daily Builds, Open Bug Base

Wow. This is amazing. I can’t wait to start adding in-app purchases to our apps, and creating new apps that feature them… this is great news for mine and Biffy’s business :-)

I’m also very excited about Push Notifications, Universal Binaries, and Bitmap Masking (and I’m sure Async http will come in very handy one of these days as well).

Needless to say, I can’t wait until mid-January. When I was a kid, this time of year went especially slow waiting for Christmas day to come so I can open presents, and while this next build isn’t scheduled until mid-January… I feel like that kid again :-)

Tilt Monster 2.0.1 Is Now Available. This update (which was approved surprisingly fast) was meant to help ease the transition for those who loved Doodle Dash! by adding these new features/improvements:

  • New audio engine (powered by OpenAL).

  • Subtle footsteps sound added. Will play if music is turned off and sound effects on.

  • Improved performance even more on older devices (such as iPhone 1st generation and 3G).

  • Classic theme uses the old DD music. Spook theme sticks with music from 2.0.0.

  • An easy, medium, and hard game mode (last version was medium-only)—change in the Game Themes & Settings Page.

  • 3 New Leaderboards specifically for Easy mode.

  • OpenFeint updated to 2.7.5 (from 2.7.4)

  • Better Facebook connectivity for publishing your score to your wall.

So if you have Tilt Monster (or Doodle Dash!), go update now!

Ansca’’s First Game of the Week Announced. The winner, Zombies Ala Mode by Crawl Space Games, is very well done, looks great, and was made with the Corona SDK.

There’s a lot to learn from that game, as well as their website. Congratulations, Crawl Space Games!

2011 is the Year of iPhone Development

Well… for us anyway, mostly due to the amazingly fast development made possible by the Corona SDK.

I’ve been using the Corona framework for less than five months (since July 27, 2010), and this is what’s happened in that timeframe:

  • Learned Lua and ported over my GameSalad-made game, Doodle Dash (first Corona version: 1.1)

  • Got a little better at Lua and ported over our other GameSalad-made game, She Doodle, and renamed it to Dragon’s Keep.

  • Took my improved Lua skills and cleaned up Doodle Dash code as much as I could (it was a complete mess because it’s what I learned Lua with), added some new features to the game and released the update (v1.2), and then added a new game theme and released version 1.3.

  • Started a brand new project, Dungeon Tap, and released 1.0 to the app store.

  • Due to initial feedback, I issued a quick update (1.1) to Dungeon Tap which made the game more fun (and added a plethora of new features).

  • Since my Lua skills get better with each new release, I took my improved skills and decided to completely re-code Dragon’s Keep for performance, redesign a lot of the game mechanics, and update the graphics for the new retina display. Issued the update (version 1.2).

  • Added in-game OpenFeint achievements to Dungeon Tap and released version 1.1.1.

  • Faced some trademark issues with Playfirst, Inc. in regards to Doodle Dash, so I removed the game from sale and started working on an update to rename the game.

  • Since the Doodle Dash codebase was a complete mess, my Lua skills have improved by leaps and bounds since I worked on the last update (1.3), and the graphics weren’t optimized for the new retina display, I took this as an opportunity to completely revamp Doodle Dash, so I started with a clean slate and completely recoded Doodle Dash and renamed it to Tilt Monster (version 2.0.0).

  • Took initial Tilt Monster feedback and issued a quick update within days of the last version being released (2.0.1 in the review process now).

And of course, my wife and partner in crime Biffy helped me with the steps above by completely designing Dragon’s Keep, doing 100% of the graphics for it as well as much of the graphics for the other two games.

What an Adventure!

So you see, in the past five months, I’ve learned a lot, did a lot, and re-did a lot. We released three full-length titles (four if you count Tilt Monster separately since I started it with a brand-new codebase and re-did most of the graphics), as well as countless updates to our apps.

Now, cut out the beginning learning processes, trademark issues, etc. Do you think we could have released five or six quality titles in the past—less than—five months, or major updates that made any one of our games much better than previous versions?

I think so, which is why I’ve declared 2011 to be the year of iPhone game development for Beebe Games.

Faster Garbage Collection With Corona

Before Tilt Monster was released, I was browsing around the Corona developer forums and came across a thread titled, Garbage Collect Delay?

A Corona developer, tempop, said he noticed a pretty significant delay when calling the Lua function, collectgarbage( “collect” ), but the delay isn’t present when adding that call to a timer delay, even if the delay is only for a single millisecond, which ultimately results in faster memory freeing.

I never knew there was a delay, so my interest was definitely peaked. The developer said that they ran tests to confirm that the delay was in-fact present, and that the delay was absent when added to a timer.

I decided to replace any garbage collection lines in Tilt Monster with:

timer.performWithDelay(1, function() collectgarbage("collect") end)

And it did in fact result in overall better performance!

I’ve also experienced ZERO game crashes since I added that line, so I’m very thankful to have read that thread.

Before the “hack”, I had optimized my code to the point I felt I could really go no further, but was still experiencing crashes every once in a blue moon (due to memory warnings). The crashes no longer occur since replacing the garbage collection lines with timer-delayed ones.

Looking back, I guess the crashes were a result of the garbage collection delay. Most likely, a few calls to “collectgarbage()” were probably called before any were able to actually execute (because of the delay) and I assume that’s what caused memory problems to occur.

I think this kind of instant garbage collection is absolutely essential for arcade-style games where you need to load and unload objects quickly between rounds, and where rounds can begin/end in a matter of seconds.

The whole thing above sounds kind of like a bug to me, but at least for the time being, the 1 millisecond delay should fix garbage collection delay problems. So special thanks to tempop for the awesome catch!

Tilt Monster 2.0.1 Submitted

It know it’s kinda fast for an update, but we decided to submit a quick one for a few reasons.

The first being to address problems that loyal Doodle Dash! fans are having transitioning to the new Tilt Monster and it’s increased difficulty.

To remedy things, a new difficulty setting is going to be introduced which will add the ability to switch between easy, medium, and hard modes. Version 2.0.0 (currently out now) is identical to medium mode.

The most significant addition is easy mode, which makes the following gameplay changes (to make Tilt Monster a little more like Doodle Dash!):

  • Game move speed starts off slower. Crossing checkpoints don’t increase speed AS much.

  • Less bunnies.

  • Bombs only take away one heart (instead of both).

  • Also earn points by getting further in the round.

Once again, the above changes apply ONLY to easy mode. Medium is identical to the Tilt Monster that is currently available now, and Hard mode merely increases the game speed (for the few who actually think Tilt Monster is easy!).

Here is a complete list of changes in the 2.0.1 update:

  • New audio engine (powered by OpenAL).

  • Classic theme uses the old Doodle Dash! music. Spook theme sticks with music from 2.0.0.

  • An easy, medium, and hard game mode (last version was medium-only).

  • 3 New Leaderboards specifically for Easy mode.

  • OpenFeint updated to 2.7.5 (from 2.7.4)

  • Better Facebook connectivity for publishing your score to your wall due to a newer version of the Facebook api being used (and will now show your difficulty setting in your status post).

I expect the update to be approved anywhere from 7-9 days. If we’re lucky, hopefully it’ll be sooner.

Ansca Mobile Quarterly iPad Giveaway

Just received Ansca’s latest email newsletter issue and found out that they are giving away an iPad every quarter to the developer of a random app in their showcase.

I currently don’t own an iPad, but really want one. Unfortunately, at the moment it doesn’t fit in with our budget. Needless to say, I really, really hope one of our 3 apps in the Corona Developer Showcase gets selected for the “iPad winner” … then we can start porting our apps over to the iPad and also make some iPad-specific games as well.

I don’t want to get my hopes up though, I don’t think I’ve ever won anything by being “selected” in a random drawing, but one can dream right?

To those who HATE Tilt Monster...

Although most folks upgrading from Doodle Dash 1.3 love the new update, there’s quite a large group who hate Tilt Monster and wish things could just go back to the way they were.

Well, I’ve got some bad news and some good news for those people.

If you want the old Doodle Dash back, bad news, Tilt Monster is here to stay. The core gameplay, new items, moving bunnies, deadly bombs, etc. aren’t going anywhere.

HOWEVER, I have decided that I’m going to compromise, because I want as many people as possible to love Tilt Monster, especially loyal Doodle Dash fans who never had a problem with the game before almost everything got changed up.

The NEXT version of Tilt Monster will add anywhere from 1-2 more game modes, while the current one will remain in-tact.

One of the game modes will make the game overall more easier to play by slowing down the game speed, allow scoring by getting further (rather than just collecting gems and stars, as with Doodle Dash), have fewer bunnies, add a third heart, and maybe a few more changes.

The other game mode will likely make the game harder for the hardcore “tilters” out there (can you believe some of the scores on the leaderboard???).

Along with the two new game modes, the next version should feature a new theme, more music tracks, and hopefully OpenAL audio and a little bit better Facebook connectivity.

If you’re an older Doodle Dasher and have something to add, please feel free to contact me and share your thoughts. Biffy and I want to please as many of our customers as possible, and want to make sure Tilt Monster is everything you could possibly want in a tilt-action iOS game :-)

2010 White Macbooks Are TOUGH

I made a huge mistake.

I dropped my 2010 White Macbook… and it didn’t just drop, it did a full skid across the floor and ended up on the linoleum in the kitchen.

After picking it up, absolutely nothing was wrong with it—everything still works! There is a very minor scratch on the right-edge of the laptop, but barely noticeable.

Now THAT’S durable, lol.

Tilt Monster on Page 1 of Great Search Term

I noticed sales picked right back up since I put Tilt Monster back on sale (which was just a day before the Tilt Monster update went live), so Biffy did a quick search in the app store for the term “tilt” and surprisingly, Tilt Monster is already on page 1 of that search term! (#14 as of a couple minutes ago)

I’m pretty sure “tilt” is a common search phrase for those looking for games, mainly due to popular titles such as Tilt to Live (which is extremely fun by the way), so I’m thankful that Tilt Monster—at least for the time being—has a spot on the first page of that search phrase.

And for those worried, “Tilt” is not currently a registered trademark in games/software, so since I’m already using the word in my game, it shouldn’t be an issue (neither is “monster”).

So far I’m very happy with how Tilt Monster is doing. Hopefully the sales keep coming, because I’ve got a broken iTouch 4 screen I need repaired, and I’m getting impatient!

Current Gripes Regarding Tilt Monster

While almost all of the feedback with Tilt Monster is so far very positive, there are a few gripes that have been brought up. This post will address them.

Thankfully, most complaints fall in the “minor” section, and nothing major has been brought up (yet). Thankfully, nobody has complained about crashes, which is awesome because that was unfortunately the #1 complaint with Doodle Dash! (it’s what I learned Lua/Corona with, which explains a lot of it).

Game Music

This is probably the biggest complaint, and it’s because people have such a wide variety of opinions when it comes to music, regardless of demographics, so there is no choosing a “perfect” song for the game.

Fortunately, Carlos (co-founder of Corona) let us know in the forums that playing music from your device’s iTunes library is on their todo list and will be coming after the new year. I plan on allowing folks who don’t like the in-game music to optionally play their own once this feature is available in Corona. We’ll also be adding new music tracks into the game once the new OpenAL audio engine in Corona is available.

The current music track was a little daring, so I sort of expected some people to love it, and others to hate it. Thankfully we added the option to disable music but keep sound effects so this issue should be a non-issue for those who don’t like the current game music.

Someone also mentioned there’s a little skip when the music track loops. Unfortunately, that’s a drawback to the current sound engine in Corona. When the OpenAL audio engine is in place, this problem will be fixed 100% (don’t ask me how I know that, I just do).

Small OpenFeint Annoyance

Someone mentioned that it’s a little annoying how the OpenFeint ‘New High Score’ drop-down notification shows at the top after every round. Because of the new Most Lifetime Gems leaderboard, every time you get another gem it registers as a new high score at the end of the round.

At the moment, Corona doesn’t give us an option to disable specific OpenFeint notifications so until that option is available, this little annoyance is going to remain because I don’t think losing that leaderboard is worth it. Thankfully, it’s easy to get used to and doesn’t require any input from the player so it’s not a very big problem at all.

Missing Old Charm?

One person mentioned that there’s a certain amount of “charm” lost with the new menu system, because things slide in and out of place instead of switching to a completely different screen every round (or game over). I think this is a matter of opinion and isn’t really an issue because most people love the way the new menus work.

The reasoning behind the change was to make the game easier to pickup, play, and re-play with as few stops and waits as possible. I figured that minimizing as many actual screen transitions and unloading/reloading of objects as possible, and utilizing sliding menus instead was the best way to accomplish that (plus, in my opinion, it looks and works much better this way).

In all actuality, I think Tilt Monster has way more charm than its predecessor.

Not As Responsive As Doodle Dash!

This is most likely due to the sheer number of additions that Tilt Monster added to the table. It’s unlikely you’ll notice this UNLESS you’re coming from Doodle Dash! but I won’t dispute it, at least for older devices. For the newer devices (iTouch4 and iPhone4), the game is smooth ever (and it’s just as smooth on iPod touch 2g with iOS >= 4.1).

If you’re coming from Doodle Dash! just give it a few rounds, you’ll get used to everything. If you’re not, then everything should seem just fine (once you’ve set your preferred tilt sensitivity option).

It could also be the fact that the default tilt sensitivity has been tuned down from Doodle Dash! due to the addition of five different tilt sensitivity options. So before making any judgments on the responsiveness, try them all out and see if one is just right for you. If not, play a few rounds and I’m sure you’ll get used to it (there are so many tilt games out there, the “standard” can be a little different for everyone).

Higher Difficulty Than Before

The game does start off faster than before, but difficulty is very subjective. The only people who are mentioning this are those coming from Doodle Dash! which is understandable. I think those who got used to Doodle Dash! quickly found the game repetitive and boring, so to overcome that, we decided to make the game pace faster, add unlockable items, and make some of the OpenFeint achievements more creative (as well as the different leaderboards).

Faster game speed which means you’re in a round quick, and most of the time, out of a round very quick. So the game pace changed, which for those coming from Doodle Dash! means more difficult, but for new players, it just means fun. Doodle Dashers will find the new gameplay to be funner as well, but it’s a matter of getting used to the change and not expecting so much to be the same (think sequel, rather than update).

Unlockable items give players an initial goal. Once items are unlocked, they can be used to help further your score, and also making the game more exciting. The new, faster pace of the game only adds to the excitement, and also makes beating your score much more rewarding. So in all actuality, the game didn’t get more difficult, it’s just a whole different game now (with the same basic premise).

And That’s About It

There were numerous good things said about the game, but I only wanted to address the gripes because all of the good things are apparent. Generally, most everyone loves the new update.

There isn’t a such thing as a game with absolutely no gripes from anyone, so I was expecting some. Thankfully, they’re not that bad, and many are going to be fixed as the next few versions of Corona come out.

So thanks again for everyone who has tried the game out and expressed your opinions (whether good or bad)… it all helps!

Tilt Monster is Live! This update (which is more like a sequel) to Doodle Dash! 1.3 is now live in the app store. No more legal issues with the name, and WAY more fun (and looks much better too!).