Oct 132011
 

This example demonstrates a progress bar that updates while assets are being loaded.  The typical use is when your assets are large enough that the user might think your app has frozen if there isn’t some sort of feedback.

A few notes about the code below:

  • Because of the way that the Corona SDK scopes modules, I chose to have a global “World State” variable declared in main.lua so I can share values between modules. The name I chose for that variable is: gWS.  So if you see values prefaced with “gWS.” they are global values declared in main.lua
  • The gWS.nScaleX and gWS.nScaleY values are used to let me switch devices and have everything scale properly.
  • This example uses the “ui” and “director” modules from Ansca (included in the complete code on GitHug
  • The code is under the MIT license so feel free to use, modify, etc the code to your hearts content.

You can get the full source code along with assets from GitHub here

---------------------------------------------------------------------------------------
-- Date: October 12, 2011
--
-- Version: 1.0
--
-- File name: cSceneLoad.lua
--
-- Code type: Example Code
--
-- Author: Ken Rogoway
--
-- Update History:
--
-- Comments: The space images used are from NASA and are in the public domain.
--           The horse image sheets are from the horse demo provided by Ansca.
--
-- Sample code is MIT licensed:
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:

-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Software.

-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-- THE SOFTWARE.
--
-- Copyright (C) 2011 Ken Rogoway. All Rights Reserved.
---------------------------------------------------------------------------------------

module(..., package.seeall)

local bUseListener = false
local nMeterX = 272     -- final X position of the meter bar when at 100 percent
local nMeterY = 562     -- Y position of the meter bar
local nMeterW = 480     -- Width of my meter bar image
local nMeterH = 30      -- Height of my meter bar image

-- This is set to 1/2 second (500 ms) so let it go slow enough to
-- see the bar advance since we are using a very small set of data
-- You would want to set this to a much smaller value, so there is
-- minimal delay between chunks, but probably at least 1/30 of a
-- second (33 ms) so there is time to update the display.
local nDelayBetweenChunks = 500

-- Main function - MUST return a display.newGroup()
function new()
    local splashGroup = display.newGroup()
    local loadingImage, loadingBar, loadingMask

    loadingImage = display.newImageRect( gWS.pImageDir.."load_bkgd.png", display.contentWidth, display.contentHeight )
    splashGroup:insert( loadingImage )
    loadingImage.x = display.contentCenterX
    loadingImage.y = display.contentCenterY

    loadingBar = display.newImageRect( gWS.pImageDir.."load_bar.png", math.floor( nMeterW * gWS.nScaleX ), math.floor( nMeterH * gWS.nScaleY ) )
    splashGroup:insert( loadingBar )

    loadingBar:setReferencePoint( display.TopLeftReferencePoint )
    loadingBar.x = math.floor( (nMeterX-nMeterW) * gWS.nScaleX )
    loadingBar.y = math.floor( nMeterY * gWS.nScaleY )

    loadingMask = display.newImageRect(	gWS.pImageDir.."load_mask.png", display.contentWidth, display.contentHeight )
    splashGroup:insert( loadingMask )

    loadingMask.x = display.contentCenterX
    loadingMask.y = display.contentCenterY

    -- Update the percent complete bar
    function updateBar()
        local nPercent = math.floor( 100 * (gWS.nLoadIndex-1) / gWS.nLoadCount )
        --print( "Percent = ", nPercent )
        loadingBar.x = math.floor( (nMeterX-nMeterW + (nMeterW*nPercent/100)) * gWS.nScaleX )
        if ( nPercent >= 100 ) then
            -- final resting place at 100 percent
            loadingBar.x = math.floor( nMeterX * gWS.nScaleX )
        end
    end

    function myLoadChunk()
        -- Load a chunk of data
        gWS.pAssetLoader.LoadChunk()

        if ( bUseListener == false ) then
            -- update the loading bar.  See the comments above
            -- regarding using a event to trigger this
            updateBar()
        end

        -- Are there any chunks remaining?  If so, set a timer to
        -- load the next one.
        if ( gWS.nLoadIndex <= gWS.nLoadCount ) then
            timer.performWithDelay( nDelayBetweenChunks, myLoadChunk )
        else
            -- Done, so finish any data stuff
            gWS.pAssetLoader.Shutdown()

            if ( bUseListener == true ) then
                Runtime:removeEventListener( "enterFrame", updateBar )
            end

            -- Onward and outward
            director:changeScene( "cSceneGame" )
        end
    end

    -- Set everything up so we can start going
    gWS.pAssetLoader.Initialize()

    updateBar()	-- update it once for 0 percent

    -- Start it going
    timer.performWithDelay( nDelayBetweenChunks, myLoadChunk )

    if ( bUseListener == true ) then
        Runtime:addEventListener( "enterFrame", updateBar )
    end

    clean = function()

        if loadingImage then
            display.remove( loadingImage )
            loadingImage = nil
        end

        if loadingBar then
            display.remove( loadingBar )
            loadingBar = nil
        end

        if loadingMask then
            display.remove( loadingMask )
            loadingMask = nil
        end
    end

    -- MUST return a display.newGroup()
    return splashGroup
end

 

P.S.: Like this article?! Want to support?! Be free to donate with bitcoins! 19r39vr2zs14aHW6DMNtPjmRga9xERQTTP

 Posted by at 5:50 am

Please excuse my mess

 Uncategorized  Comments Off on Please excuse my mess
Oct 132011
 

For some reason my prior install of WordPress stopped working. I could see the blog entries, but couldn’t log in or admin the site.  Rather than wait on my ISP to update the version of PHP to something more recent, so I could reinstall the latest WordPress, I decided to use my ISP’s idiot proof installer to redo my site.

After getting the site set up, I had to go into my MySQL database for the prior blog entries and copy them into this new site.  Unfortunately this resulting in my site having a couple of the blog entries in the wrong order.  Everyone knows that “Hello World” should come first.

So please excuse my mess as I try and get things up and running again.

P.S.: Like this article?! Want to support?! Be free to donate with bitcoins! 19r39vr2zs14aHW6DMNtPjmRga9xERQTTP

 Posted by at 3:41 am

iPhone – Why do you taunt me?

 Rants and Ramblings  Comments Off on iPhone – Why do you taunt me?
Oct 132011
 

Overall I love my iPhone. Almost all of the features you’d want in a phone are there, and the User Interface is intuitive and easy to learn. However, there are some things that Apple just doesn’t seem to understand. For me, most of these issues revolve around their email application.

Pop Email Hell

If you have had your email account for more than a few months you get Spam. I get 400+ Spam emails a day. If I turn my ISP’s automatic Spam filter to be more aggressive to reduce the emails in my Inbox, then it also tosses important emails. Sure I could go in and check my web mail spam folder every day, but I don’t always have web access throughout the day. This results in getting a LOT of emails on my iPhone for my personal email account.

Since I get a lot of mail, once I have scanned it I want to be able to select all of the messages and delete them. You’d think that Apple would have a “Select All” feature. Nope! This means I have to select each email individually. Annoying and a waste of time; especially if I haven’t checked mail in a while. However, even MORE annoying than having to select each email so I can delete them, is the bug where your selected mails spontaneously deselect! So I have just selected 30+ emails and am about to press Delete, when BAM! they all deselect. This happens randomly, with no pattern that I can discern.

I don’t recall seeing the deselection bug happen prior to iOS 4.2. Apple, can you fix these two items? Surely you have people smart enough to address these bugs/features? If not, I am willing to volunteer my time (for free) to help you address these items.

While I am on the topic of the iPhone, can anyone tell me why you cannot end a call by pressing the big red “End” button? Yes, it works most of the time, but about 20% of the time I press the End button and it doesn’t hang up. So I press it again. Still no disconnect. I press it again and again. No luck. Then 10-20 seconds later it hangs up on it’s own. Maybe the Apple engineer that wrote the code to handle the End button wanted to write a game and wasn’t allowed to, so he made hanging up a game; albeit a lousy and frustrating game.

Apple, if I press the button, I see it depress, then PLEASE hang up the phone! If you need help, the offer I made above for your email bugs applies to this as well.

P.S.: Like this article?! Want to support?! Be free to donate with bitcoins! 19r39vr2zs14aHW6DMNtPjmRga9xERQTTP

 Posted by at 3:22 am

printf( “Hello world!” );

 Uncategorized  Comments Off on printf( “Hello world!” );
Oct 132011
 

“Hello World” is an apt title for my first blog post. Typically when you are learning a new programming language you start with a trivial application that outputs the message “Hello World” and since a person’s first blog post tends to be perfunctory it seems appropriate to leave the post with that title.

Let me introduce myself. My name is Ken Rogoway. I have been programming professionally for almost 30 years. The majority of that time has been spent writing video games, but I have also developed software for industries such as: insurance, audio processing, project management, biomedical and video processing for golf training. Currently I am developing casino games for the Class II and Class III markets.

I have a game centric biography on Moby Games that can be found here. My LinkedIn profile can be found here. Currently I am the Principal Engineer and Studio Director at a small casino development company.

The purpose of this blog should be fairly self evident based on the domain name. However, for those of you that prefer a written explanation, I decided to create this blog to discuss anything that comes to mind; whether or not it is programming related. In general I will tend to keep to technical issues, but as often happens in blogs I may digress into more personal and mundane topics from time to time.

P.S.: Like this article?! Want to support?! Be free to donate with bitcoins! 19r39vr2zs14aHW6DMNtPjmRga9xERQTTP

 Posted by at 3:17 am
Oct 132011
 

I wanted to work on an iPhone/Android port of Arrow Antics; one of my older games. The original game was written using SDL, but the current state of SDL 1.3 is still a bit flaky and not ready to release products with.

I started looking at various 2D iPhone solutions. The two most popular 2D iPhone SDK’s appear to be Corona by Ansca, and Cocos2D.

Cocos2D
Cocos2D has an Objective-C based API. Personally, if I wanted to use Objective-C I would just code directly to the iOS SDK. However, for less experienced programmers there is a lot of value in not having to write the functionality included in the Cocos2D SDK. So, for me, I quickly ruled out Cocos2D.

Corona
Corona SDK is a Lua based solution that supports iOS based apps (iPhone/iPad) and Android based apps (Droid, NexusOne, myTouch, GalaxyTab). Since all of the app logic is written in Lua, it is a “write once, run anywhere” type solution; at least for iOS and Android based systems.

Corona Pros
Obviously the biggest strength of Corona is that it is a cross platform solution. If you are only targeting iOS then you can go with the iOS SDK or Cocos2D. However, if you think that you might want to deploy your app on other platforms then you will want a solution like Corona. There are a lot of nice features that Corona supports, including physics using Box2D, Facebook Connect, OpenFeint support, and most importantly native device features.

Corona Cons
The most obvious drawback to Corona is the lack of a UI Layout tool. If you want to place images, buttons, widgets, etc on the screen you have to do it all in Lua like this:


local helpGroup = display.newGroup()
local backgroundImage = display.newImageRect( "Background.png", 480, 320 )
backgroundImage.x = 240; backgroundImage.y = 160
thisGroup:insert( backgroundImage )

Sure, this is only a few lines of code. However, it means you have to do something like this for EVERY display object in your app. Why not have a layout tool that writes out a layout file in XML or JSON? Then for each screen in your app you could just load the data file and it would create your display objects and add them to the display group.

Conclusion
I will no doubt find other strengths and weaknesses with Corona as I continue the port of Arrow Antics. Look for more info soon.

P.S.: Like this article?! Want to support?! Be free to donate with bitcoins! 19r39vr2zs14aHW6DMNtPjmRga9xERQTTP

 Posted by at 3:15 am