Friday, December 9, 2011

Andronavi post

I think this explains the high number of Japanese folks playing the game:

http://andronavi.com/2011/12/144583

Google Chrome butchers it in translation I'm sure.  I can't tell if the reviewer liked it or not.

Tuesday, December 6, 2011

Current standings

Here are the current standings of DB42 in the various markets.  China has got some huge growth going on.  Cool stuff.

Market Name

Upload Date

Publish Date

Downloads

Current Rating (# reviews)

Notes

Android Market

11/27/2011

11/27/2011

813 (324 active)

5/5 (2)



SlideMe

12/4/2011

12/4/2011

287

none yet



AppChina

12/4/2011

12/5/2011

507

none yet



Mobango

12/4/2011

12/6/2011

0

4/5 (1)

There's one review, but the download count is currently 0.  Curious.

Amazon App Store

12/4/2011

Still Waiting







Sunday, December 4, 2011

More alternatives

Uploaded DB42 to Mobango and Amazon.  I said i wasn't going to upload it to Amazon... but since I'm doing the lite version I don't think it counts. ;)

I understand the wait to get something published on Amazon is on the order of a couple weeks.  We'll see if it is up there by mid-December.

Mobango requires a review before an app is published so I'm waiting on that.  On AppChina, my app has entered the 'audit' state, whatever that means.  Hope it is accepted!

Saturday, December 3, 2011

Alternative Android Markets

Taking a tip from Neil Rajah and his blog (Ziggy's Games), I've gone ahead and added DB42 to a couple of new markets: AppChina and SlideMe.  I registered the game on AppChina about an hour ago and am still waiting for it to be approved.  *HOPEFULLY* Google translate didn't totally slaughter the simple descriptions I put in.  I figure the simpler they were, the less likely the translation would be something weird for a Chinese person to understand.  On the flip side, I've fired off an e-mail to a former co-worker of mine that knows Chinese.  Hopefully he can help me round things out.

I registered the app about 5 minutes ago on SlideMe.  It also requires a pre-approval process, but I just got an indication as I was typing up this blog post that it has been published.  We'll see how things go!!!

For Great Justice

DB42 is listed on a Japanese site.  English -> Japanese -> English makes for some weird reading. 

Here's the Japanese -> English translation:

DB42 is a platform puzzle game placed in the path of the robot is great! I droid - 42 Dust Bin specified, DB42 As .... Or just "Deeby", service mark spam bots humble friend and fellow electricity. あなたの大きなものの運命にあるし、最後に、あなたのやる気を証明するあなたの監督の認可が知っている ! The fate of the big things in your last, you know your approval of the director to prove your motivation? あなたの方法 Cynobotic 軍の高度なロボットの訓練の場を作る。 Create opportunities for advanced training of military robots Cynobotic your way. これらのあなたのウィットと知恵を最大限にテストされます ! The wit and wisdom are tested to maximize those of you! ジャンプ、実行、スイング、格闘し、テレポート、トップへの道 ! Jump, run, swing, wrestling, teleport way to the top! ゆっくりと、ゲームのコンポーネントを紹介、入門レベルを探るロープを学ぶ。 Slowly introduce the components of the game, learn the ropes explore the introductory level. そこからは、ブラスト オフに多くのレベルの楽しさと脳のからかいの狂気!道に沿ってあなたの機能を強化するアップグレードを選択します。 From there, the madness of brain teasing fun and many levels of blasting off the enhancements to select the upgrade you along the way. ようなものを見つける:-、迷惑バディ。 Find something like: - Buddy annoying. これは、オブジェクトへの引くため短い範囲トラクター ビームです。 This is a tractor beam to pull a short range to the object. 非常に便利なだけである事を得るため… つ..到達 ! To obtain a very useful ... it is only one arrival ..! -、REPUGNICATOR。 -, REPUGNICATOR. これは、リモート スイッチを押しのようなことをすることができます repulsor レイです.フープを撮影します。 This is the repulsor rays that can be like pressing the remote switch. To shoot hoops. はい。 Yes. 真剣に ! Seriously! -無限現実間質性表面 (アイリス)。 - Infinite Reality stromal surface (iris). テレポートあなたアイリス強化の程度を使用します。 Iris uses a degree of strengthening your report. スペースを折り畳みしないので、簡単にされています ! Space does not collapse, has been easier! 環境レベルとしては、水の危険性、重力のフィールド、およびオブジェクト フィールド サプレッサーのようなものが発生します。 As the environmental level, the risk of water, gravity field, like the object occurs, and the suppressor field. DB42 はカジュアルなプラットフォーム\/パズル、パスにロボットの偉大さに置くゲーム!消化しやすいバージョンには 20 のレベルが含まれています。 DB42 is a platform \ / casual puzzle game placed in the path of the robot is great! Is easily digestible version includes 20 levels. フルバージョン (近刊) 広告を削除し、100 のレベルにする方法の詳細が含まれています ! Full version (in press) to remove the ads, include details of how to level 100! アクセス許可の説明: インターネットとネットワークの状態: 広告 & バグ報告のサービスを提供します。 Description of access: Internet and Network Status: Provides the services of bug reports and advertising.
ハードウェアの振動: 触覚 feedbackBug レポート & フィードバック: ごメール gushikustudios@gmail.com には、または私達のフォーラム、web サイトを参照してください ! Vibration Hardware: feedbackBug report and tactile feedback: gushikustudios@gmail.com Please e-mail, or our forums, please see the web site! [タグ: ロボット、ドロイド、テレポート、ポータル、格闘、トラクター ビーム、レパルスベイ線] [Tags: robots, droids, teleport, portals, wrestling, tractor beam, Repulse Bay Line]

Wrestling?  I don't remember that!  Here's the original English copy.  Funny stuff!

You are a lowly Mark I service droid - Dust Bin Designation 42, aka DB42.... or just "Deeby" to your electro-FRIENDS and fellow junk bots. You KNOW you are destined for greater things and have finally won the approval of your overseer to prove your mettle!

Make your way through the Cynobotic Army's Advanced Robotic Training grounds. These will test your wits and resourcefulness to the UTMOST! Jump, run, swing, GRAPPLE and TELEPORT your way to the top!! Learn the ropes as you explore the introductory levels that slowly introduce you to the components of the game. From there, you BLAST OFF into many more levels of fun and brain-teasing craziness!!!

Along the way you will pick up UPGRADES that enhance your capabilities. Find things like:

- The JUNK BUDDY. This is a short range tractor beam for pulling objects towards you. Very useful for obtaining things that are just... out.. of... REACH!

- The REPUGNICATOR. This is a repulsor ray that allows you to push remote switches and do things like... SHOOT HOOPS. Yes. Seriously!!

- The Infinite Reality Interstitial Surface (IRIS). Use your IRIS enhancements to TELEPORT around a level. Folding space has NEVER been so EASY!

As you level environments, you'll encounter things like water HAZARDS, ANTI-GRAVITY fields, and object field SUPPRESSORS.

DB42 is a CASUAL PLATFORM / PUZZLE GAME that puts you on the path to robotic GREATNESS!

The lite version contains 20 levels.  The full version (forthcoming) removes ads and contains 100 levels with more on the way!

PERMISSIONS EXPLAINED:

Internet and Network State: for serving ads & bug reporting
Hardware vibrate: for haptic feedback

Bug reports & feedback: please send an email to gushikustudios@gmail.com, or visit our Forums on the web site!

[ tags: robot, droid, teleport, portal, grapple, tractor beam, repulse ray ]

DB42 Lite version released

I released the lite version of my game on 11/27/2011 (DB42 Lite on the Android Market).  So, we're not quite a week out here.

Here are the current stats:

60% of the installations are located in Japan
12% of the installations are located in the US

All apps in my category have the following stats:

42% of installations are located in the US
5% of installations are located in Japan

Quite a contrast there!  Hmmm.  I guess "robot" based games are more popular in Japan?  Stay tuned....

Friday, November 25, 2011

Ouch! The pains of a new installation

If you read my previous post, you'll discover I'm not a fan of Dell.  Given the poor customer support from Dell, I switched companies opted for an ASUS G53S laptop.  This has been working nicely so far.  The intent has been to get a portable machine that satiates my gaming needs as well as works for dev efforts... I bring my laptop to work and work on personal stuff over the lunch hour.

Well, starting yesterday I began working on getting the laptop loaded up with my project and the necessary tools to build my game, DB42.  Oi!  What pain!  I've finally got things working and thought I'd post my experiences here for future reference and in the event it might help someone else out.

A bit of background first.  I'm using Eclipse and the Android SDK.  I've forked the libgdx project into my own distribution with a couple of tweaks here and there.  I also don't have to worry completely about relying on a specific nightly build since I've got a snapshot of things.  This means that I also have the support tools for *that* installed -- the Android NDK, MinGW for compiling, Cygwin & ant for building.

So, the first thing I did was install the latest and greatest Eclipse 3.7.1 (codenamed Indigo).  This went off fine.  Next up was TortoiseHG 2.2 so I could pull my repo from the hosting site I'm using.  First problem encountered.  After installing this, I noticed that the icon overlays were missing on the root directory folders.  WTF. Even a reboot did not correct this.  The sub-directories seemed to be ok, but there was no indication on the root as to "no change" or "modifications".  So, I downgraded to 2.1.4.  This cleared up that problem.

Next up was the installation of Android SDK r15.  Downloading as a snap.  Installing the ADT was pretty simple as well (done from within Eclipse). 

After getting all of that going (which took a while -- installing the various Android components results in a pretty big download), I ran into a snag.  I first cloned my repo to my hard drive.  Then, I tried to import the various components.  Instead of giving me a source folder and sub-packages, Eclipse showed everything as a package.  For example, instead of the hierarchy of "src" with "com.gushikustudios.db42lite" as a package, I saw the package "src.com.gushikustudios.db42lite".  I don't know what was up with that, but it hosed the build.  To correct that, all you have to do is right-click on the project > New > Source Folder > src.  For whatever reason, that corrected the layout.

Next up were errors with the project.  I have no clue why, but my project settings were missing.  I had to right-click on the project > properties > Java Build Path.  Here I had to do several things: Add Library > JRE System Lib (which was missing for whatever reason.)  Project references were missing.  Recall that I've got my own build of libgdx, so I reference the project instead of  things like gdx.jar.  My lib settings were also missing, so I had to reference a lib that I have copied in my libs dir.

Ugh.

After correcting all of that, I tried to build my Android project and get an .apk file.  Nothing.  No apk file or anything produced in the bin/ sub-directory.  It turns out that this behavior is the new default for the latest ADT.  To 'fix' this, in Eclipse go to Window > Preferences > Android > Build > deselect the 'Skip packaging' check box.  I also changed build output from 'silent' to normal.  That fixed that problem and I was able to produce an .apk file.

Next up was the desktop build of gdx.  I failed to realize that the resulting gdx.dll that I created referenced other dlls that I didn't have installed on my new laptop.  Oh no, of course when you try to execute, the JVM doesn't give you any sort of error that is helpful in any way.  I kept getting "UnsatisfiedLinkError" / "Can't find dependent libraries" errors.  Great -- which dependent libraries can't you find?  I mean, throw me a bone here.  After poking around in the gdx.dll, it turned out that there were dynamic references to some build dlls: libstdc++-6.dll & libgcc_s_dw2-1.dll.  Oops.  Of course, I didn't discover this until after a couple of hours troubleshooting.

All I had to do was install MinGW and reboot and all was fine.  Very frustrating, but things are finally starting to work.

Monday, November 14, 2011

Will NEVER buy another Dell or recommend their products

I just wasted about an hour and a half talking to Dell tech support about my Dell XPS M1730.  I easily paid over $3000 for this beast 3 years ago... Top of the line.  etc. etc. etc.  My problems with this thing first started up when I installed Win7 on it a couple of years ago.  For whatever reason, the video drivers never quite seemed right with the hardware and although I have 2x8800M video cards installed, I had to disable one due to incompatibilities.  Whatever.

Then, about 7 or 8 months ago, the battery quit holding a charge.  Which, I understand, but instead of dying off quietly, I would getting annoying nags about it, so I just pulled the battery completely.  Last week the Power Supply quit being recognized.  Huh?  So, what does the software do?  Derate of course.  I purchased a new power supply.  That didn't fix it. 

I'm stuck with a machine that is about as crippled as you can get.  The derating brings my programming builds to a crawl.  Oh, and I'm only 149 days out of the extended three year warranty I purchased.  The support people were sympathetic and polite, which is great, but how does that help me?  It doesn't.Their solution was to upgrade the BIOS.  Oh, but wait, you can't run the reflash program unless you have a recognized power supply and battery.  Oops.  There goes that idea.

I figured my only option was to get a new motherboard.  Tech support gave me the out-of-warranty repairs number, who then redirected me to somebody that claimed I shouldn't have been directed to.  Argh!  They said my best bet was to skip a motherboard replacement altogether and instead buy a new computer.  Ummm.  Excuse me?  I have no desire to purchase another Dell.  I recommend everyone avoid them at all costs.  I was considering to 'upgrade' to an Alienware machine -- but they share the Dell taint so I guess I need to look elsewhere.

If you are considering buying a Dell, think again.

A disappointed, FORMER Dell customer.

Thursday, October 27, 2011

Repulser, pass #1



I modded the libgdx particle emitter class to allow the programmer to have old particles track a specific angle.  I did this so that I could get the effect you see above.  It's a repulse ray.  I need to polish it up a bit -- the player's tracer line appears when it shouldn't (this is a screenshot of the first, proof-of-concept pass).  But, it looks functional and I like how it emanates outward.  I was going to try to animate this action with multiple images, but using particles gives a waaaaay better effect.  Things should be fixed up tomorrow.

Wednesday, October 19, 2011

*DING*

Slide rule Android app - 10k user Achievement Unlocked.

Checked the developer console today and saw this:

"10012 total installs (users)"

Cool!  Broke the 10k barrier.

Sunday, October 9, 2011

Training Level 07 is done

Finally.  Done.  With training level 07.  I wanted to create a new pendulum object for this one and had a bit of trouble initially getting it to work the way that I wanted to.  After getting a tip from a Box2D guru, I was able to get things working.  The problem had to do with me creating an axle that had no fixture.  When I did this, the pendulum rod quit swinging.  Double plus ungood.  You need to have a fixture in place or the fixtureless body constrains rotation.

So, yeah, WOOT!  Here's a screenshot.

Saturday, October 8, 2011

Bobbing for crates

I wasn't happy that I had this fancy dancy new water texture but no physics behind it to make things (like crates) float.  I went out and discovered that the Box2DFlash port by "BoristheBrave" had already implemented this.  I ported that over to the libgdx library... and was able to do it by adding shape extensions so I didn't need any updates to the underlying libgdx JNI code which was cool.  After realizing that Box2DFlash's coordinate y-axis was inverted from my environment's y-axis AND fixing a couple of bugs I introduced, it's now working flawlessly.  Here's a screen shot of a couple of crates floating:






One other thing that I did last night was to integrate ACRA.  This is Application Crash Reporting for Android.  If you give your application Internet permission, it will send crashes off to Google docs for analysis.  This will give you the trace you need that the standard 'Force Close' window absolutely does not provide.

The best thing about this is that the overall impact on the app is minimal.  You add a new class and override the onCreate() method in that class, set up a Google docs form, and you are ready to go.  I was a bit confused at first because I wasn't sure how to integrate it with libgdx, but it really boils down to just adding the class as part of the Android project & including the acra .JAR file.  QED!

Monday, October 3, 2011

Training Level 06 is in the bag

Added a new water texture to short out the main character's circuits.  Take a peek below.

Sunday, October 2, 2011

Evolution

It's been a while since I've posted on here.  Why is that?  I've been working pretty damn hard on my game!  That's why!

Below are some screenshots of the current build.  I'm currently looking for an artist to give the game that extra polish.  I've been able to find one on indiegamer and have a offer extended to him that I'm waiting on for acceptance.  We'll see how it goes!  Very exciting stuff.

Monday, July 25, 2011

Rendering results... WAHOO!

Wow!  I can't believe how easy rendering is and the HUGE improvement I had versus the Box2D renderer.  I had it in my mind that it would be overly complicated, but it's that's not the case at all.  The results are so good that my conveyor belt actually WORKS on my phone.  That's great because I've got a couple of cool ideas for some levels using this construct.

My (simplistic) design, as mentioned in the previous post, is working great.  I created a new renderer class that is passed the the Box2D world instance.  From here, I get the list of bodies that are in the world.  I thought that I would have to iterate over all my fixtures in order to get things to appear.  That's not really the case.  Although your object may be comprised of several polygons (especially in the event that you want to a concave type object), your actual object is a single entity.  If you have a texture that 'fits over' that entity, then you are all set.  Much easier than trying to iterate over the fixture list to define individual elements!

I added some info to my user data class -- object texture, size, origin, and color.  The renderer uses these to scale textures appropriately.  When I get the real textures drawn up, it will use those instead.  I wanted to implement scaling because some of my objects don't have a predefined size at compile time (platforms have variable length, gears have variable radius, etc.)  Other objects, on the other hand, will have static sizes so handling those should have less of an impact on CPU time when I define the 'real' textures.

I added a grand total of 2 textures for my own debugging - one shape for circles and one for squares.  I also added a simple line so I can see rotation.  See the screenshot below for an example:


Observations:

1) I had defined some objects with rotation and instead of rotating the object, I rotated the fixture.  This resulted in rendering images that were out of whack with the body (a vertical platform, for example, rendered a texture horizontally).  Bad!  This was easily corrected by setting the shape's rotation to 0 and the body's .angle parameter to the desired angle.  I love quick fixes like that.

2) I need to have ordered rendering. I have some instances where objects overlap.  Sometimes the player's arm/gun is rendered before the body and sometimes it is rendered after.  You either see the gun peaking out when it is rotated or you see it 'correctly' on top of the player.  I need to correct this.  Since I'm iterating over the entire world of objects, I probably will skip this special case and have the player object render itself separately... it knows to draw the player body and then the arm next.  Skipping should be a snap because my user data includes object type info.

3) My fps on my phone on the conveyor belt map was on the order of 14 fps using the debug renderer.  Using my renderer, my fps shot up to close to the max -- 50-60 fps.

4) The screenshot above shows a capture of my game running on the desktop.  The fps says 4774.  With the debug renderer, I was getting 1/4 of that... say around 1400 fps or so.  Notably slower than what I am getting right now.  Most of the operational time was spent rendering joints (40%+).

5) This doesn't obsolete my usage of the debug renderer.  I can always run that AFTER I do my rendering to 'overlay' what the physics engine is thinking it should be displaying.  That's a pretty neat trick.

That's all for now. All in all, I'm pretty happy I got this working.  It was a big disappointment yesterday to see that the conveyor belt killed things!

Rendering

So, yesterday was a major downer with the conveyor belt failure on my phone.  I did some profiling (which is REALLY EASY using the DDMS tool in Eclipse), and the majority of the time was spent rendering / drawing the joints (43% of the time.)  To combat that, and to finally force myself to quit relying solely on the debug renderer, my goal today is to get a basic renderer up and running.

My idea is to use user data for defining texture regions references at object instantation.  Then, during rendering time, iterate over all the objects in the world and simply call their draw methods, accessed via the user data reference.

Sunday, July 24, 2011

5000+ downloads of the slide rule app

Just checked today and the Google Developer Console indicates that there have been 5000+ people that have checked out the slide rule app.  Cool! :)  Now... where's my money?!  Oh right, I released it free of charge.  Heh.

Today's achievement: a conveyor belt

I'm starting to work on my "Main Menu" screen.  My plan is to have some non-interactive game action going on in the background.  I drew up an idea to implement a conveyor belt.  I had three ideas for this and implemented two of them. 

The first (unimplemented) idea consists of creating a surface that detects collisions.  When an object has collided with that surface, an impulse is applied in the direction of the conveyor belt direction.  I think this would work, but seems kinda kludgy.

The second idea consists of creating several rotating circles (ie. gears).  Here's a picture of that implementation:

It works ok.  It does suffer from objects occasionally getting stuck between each gear.  I've got a 'slop' implemented so the gears aren't fighting each other -- it may take some tweaking to nail that down (maybe add joints or a filter type that prevents gear collisions?)

The third implementation took quite a while to figure out.  It deals with defining a chained set of objects (that I call the ChainLink) and two gears.  I took a bit of thinking to figure out an algorithm to define the chain link lengths and how you can programmatically adjust the width / height.  The biggest sticking point was a snafu I had with drawing the chain to revolve around the gears -- I was using degrees and the (poorly documented) API I was using didn't indicate that my units should have been in radians.  Whoops.  I ran into this before and was a bit frustrated that it was something as simple as that.  At any rate, here's an example of the conveyor belt I made up.


There's still a bit of slop to it, so I added a 'magic' variable that I named 'tension' that allows you to adjust the size of the gears.  This either tightens up a loose ChainLink or loosens up one that is too tight.  I've tried it on a couple of different sized gears / widths between gears and it works pretty well.

Saturday, July 23, 2011

Uncovered latent bugs

I've implemented my 'restart' & quit level menu buttons and uncovered a couple of bugs as result:

1) When switching screens, there is a potential bug in the frameworks that I patterned after Mario Zechner's game screen implementation.  Two methods are executed from the libgdx's render() method: update() and then present() -- in that order.  If the update() method logic decides to switch screens, the Game instance will do just that... and then run the new screen's present() method immediately upon returning to the render() method.  This could be a problem if the present() method is making the assumption that the update() has executed at least once.  I added a transition check in the Game class to ensure that a guaranteed transition will occur at the end of the Game's render() method.  The alternatives are to: ignore this behavior (most screens probably don't care) or encode the actual transition in the Screen's present() method.

2) My Level class was braindead.  Some levels included push buttons, doors, and wire lists that are instantiated when the Level class is instantiated.  When I reset the level, the lists were updated without being destroyed before hand.  Oops.  The net result was that after several instances of resetting the level, I'd get a native code error while trying to look up a prismatic joint translation.  In essence, the lists were maintaining references to dead objects (my world object is destroyed and recreated at every reset).  Yeah, that's classically what is known as a "BAD IDEA (tm)".  At any rate.  FIXED.  I added a dispose method to the parent Level class to remind me that I need to nuke those objects on level exit / reset.

Popup Menu first pass implemented

I spent the greater part of today messing around with getting a pop-up menu going and have the first pass done.  I also decided to bite the bullet (to a degree) and implement some placeholder graphics until I get far enough along where I can either spend more time working on better icons or hire someone to do them for me.

Here's what the pop-up menu looks like at the moment:
It consists of 6 graphics: 5 images for buttons and one for the background.  When the user presses the phone's menu button, it slides in from the left.  When the user hits the dismiss button on the screen, it slides out to the left.  Here's what I did to get this effect.

First off, I'm using the screen frameworks that I patterned after SuperJumper from Mario Zechner's libgdx demo suite.  Part of that frameworks includes states of the screens: GAME_READY, GAME_RUNNING, GAME_PAUSED, GAME_LEVEL_END, and GAME_OVER.  Under normal conditions, the state is GAME_RUNNING.  This performs updates and rendering - which currently includes the Box2d renderer and Box2d world step() functions.  When the user hits the menu button, the screen detects this and switches to the GAME_PAUSED screen.  This halts updates to the screen (but still allows the debug renderer to execute - which keeps the background in view).  Further, it's during this state that I allow the pop-menu renderer to execute.

The popup menu is a separate class that I named InGameMenu.  It contains a 2d scene stage, 5 buttons, a background and a group.  All the button and image items are added to a BoundGroup.  The BroundGroup acts kinda like a panel or layout.  Everything that it contains is locally referenced, and the group itself is referenced from the world coordinates.  Therefore, I can stick a button at 0,0, and then move the group itself around without having to worry about updating the button.  Pretty cool.

The popmenu also contains some simple state information indicating whether it is animating or not.  I create it such that it is off to the left side of the screen.  When it activates, the render() method simply increments the group's x parameter until it hits 0 -- meaning the left side of the screen.  To deactivate it, the render() method decrements the group's x parameter until it hits -viewportwidth/2... meaning fully off the screen.

The background graphic is a 1 pixel high x 350 pixel wide image.  I set the height to match the height of the viewport and the libgdx drivers take over rescaling it to fit.

The next bit of programming will be for me to create a scrolling pane text bit within this group (or perhaps, just switch it to another group.)

Things are starting to pick up.  I really do need to implement a whole bunch of levels.  The game frameworks are pretty much set.  I've got tweaking to do, but it's getting close!

Joytouch demo

Here's a quick shot of a level with some point rendering I did to reflect where the "joytouch" areas are.  As in: joystick + touchpad = joytouch. 

On the left hand side is a right/left button.  When you are to the left of the button, the player moves left... on the right, it moves right.  On the right hand side are several buttons.   The two buttons at top are the fire #1 and fire #2.  The bottom two are jump and grapple.  The middle button rotates the gun around its axis.  It works, but I'm not 100% happy with how the gun moves.  I've got a couple of different ideas in mind to see if I can come up with something better.



Today I'll be working on getting my pop-up menu working.  I'll be using the UI controls that have recently been added to libgdx.  I want to get a simple toggle button working and text scrolling.  We'll see how it goes.

Friday, July 22, 2011

The Trance is the Motion

I've got player motion happening on my HTC Incredible now.  The left-hand side of the screen contains the left/right motion for the player.  The right-hand side of the screen contains rotate-left/rotate-right for the gun arm.  Along the top are two push buttons for fire #1 and fire #2, and along the bottom are two push buttons for jump and grapple engage.  Pretty cool.  Things are really starting to come together.

I *really* need to have a transparent overlay of some sort to indicate where the buttons and controls are.  I let my youngest son try the game and he had a tough time understanding what he was pressing.  However, I don't think I'll be able to do anything with this until I get to implementing sprites & textures.  Still, I should probably do *something* simple even if it is just some circle rendering.  Hrm.

Next up will be creating a pop-up menu that displays when the user hits the menu button.  This will need to suspend operations of the game and allow the user to restart or exit.

Box2D game update

With a little luck, I'll be able to hit my game pretty hard over the next few days.  I've got it to the point where I've ported it to my HTC Incredible.  The INITIAL stages at any rate.  I need to figure out how I'm going to handle the controls and how to actually perform user interfacing. 

The first swag I made hasn't gone so well -- I wanted to implement left/right motion with the user touching the left hand side of the screen and a jump button on the right.  The touch areas I've defined don't really match up with what's going on.  I believe it has to do with how the touch is interpreted versus how the point is reported by libgdx.  I *think* I'll need to unproject the point based on the Orthographic Camera to get an accurate position.  Stay tuned.


In other news, this is a really good post on separating your logic from your rendering.  It's given me pause to determine what my 'native' screen size is going to be.

Slide rule update

Just a quick note... I'm only 97 installs away from breaking the 5000 mark.  Woot!  People seem to be more curious about slide rules than anything else.  Of those (nearly) 5000 installs, only about 50% have kept the installation.

Agreed.  The slide rule is a kinda neat, but not very practical, tool.

Monday, July 11, 2011

Life intervenes

For the past two days I've been reduced to tearing down an old shed on my property in preparation for a brand new shed to take its place.  I've only been able to do coding today.  But, I've been pretty productive.

I worked on two primary items, both related.  The first was to get the latest nightlies of libgdx which now include some UI interfaces such as buttons, sliders, panes, windows, etc.  I need these in order to create my user interface.  I spent the earlier part of today working on understanding how all of that stuff goes together.  Mario Z. has things set up pretty damn nice in that you can use 'skins' to alter the look of your stuff.  You do this by referencing an XML file that in turn references a "ninepatch" .png file.  Ninepatch, simply stated, is a set of 9 textures that constitute the area of an expandable button.  You've go the four corners, which are typically rounded.  Then there are the four orthogonal directions.  Finally, you have the center piece.  This makes a total of 9 parts.  They come together and allow buttons (and related graphical items) to look 'nice' when their overall size changes.  I expanded what MZ had by adding a 'transparent' pane background for my level select simply by updating a few lines in the XML file.  COOL!

The second item I worked on was getting my level select screen implemented.  This utilized Java's 'reflection' ability.  First, my LevelSelect screen accepts an array of strings that identify the fully qualified class name for a level... such as "com.mypackage.levels.level1".  The elements of this array are then used as the button names created by the UI above.  Using reflection, I'm able to take the name of the element and create an instance of that class at run-time, depending on which button the user selected.

The code looks like this:

mGame.setScreen(new PlayScreen(mGame,(Level) Class.forName(button.name).newInstance()));

This spawns a new PlayScreen using a reference to the game instance and creating / referencing the level instance the player has chosen.

One of the neat things I think I'll be able to do with the UI panes is make them slide in and out of view when the player hits the menu button.  I can adjust the pane location programmatically and use a state machine to do the animation / determine when the menu should be brought it.

Saturday, July 9, 2011

You're grounded!

I spent time last night working on the motion of the player body in my game last night.  I wanted the effect of moving him around to be that when he is grounded, he moves at a certain speed.  If he jumps and is moving, he continues at that speed in the x-direction and if the player tries to move him while airborne, it's possible but the motion is minimal.  I also wanted quick left / right motions if the body was on the ground.

To achieve this, I have a sensor fixture in the form of a circle on the bodies lower half.  I got this idea from Mario Z.'s physics demo doing something similar.  I use the contact listener and a counter to detect when the sensor is touching or not touching something.  In other words, when a beginContact event occurs for the sensor, it ratchets up a counter.  When an endContact event occurs, it ratchets the counter down.  When the counter reaches 0, the body is considered to be airborne.  This works out pretty well.

Body motion is checked every iteration and its velocity is adjusted if the user is pressing the left or right button.  If the body is airborne, the amount of the velocity is reduced.  If the user is not pressing a motion button and the body is grounded, it immediately stops.  Else, if it is airborne, no change to the velocity is made.  This is working out pretty well. 

Oh yeah, the player presses a button to jump.  This causes an upward impulse to be applied to the body.  If the body is in the air, then the jump button is ignored.  Easy peasy.

This is working out really well, but I need to do some adjustment to the friction when the character flies across the screen at a high rate (such as leaping off a high ledge).  I'm going to attempt to adjust the amount of friction as a persistence from being grounded -- the first short bit after coming down from being airborne will have a low friction then friction will be increased back to normal levels.  I need to play with things to see how that looks and feels.

Friday, July 8, 2011

Slow but steady

I've been making slow but steady progress on the game.  Since I've got a good chunk of the components defined and the majority of operations working, I decided to commit some time to making levels.  The levels range from easy / introductory type stuff to more complicated / tricky solutions.  After about two hours of effort last night, I now have  20 levels defined.  Ideally like to come up with about a hundred (if not more).

Today's main accomplishment was refactoring.  Since things are going to be level based, I needed a frameworks supporting this as well as the capability to have various menus.  The frameworks I created was derived after studying how Mario Zechner (libgdx guru) implemented his SuperJumper.  The concept is fairly simple.  You have two primary objects: the game object and screen objects.  The game object is the ApplicationListener of libgdx and kicks off the very first screen.  The screen objects are really simplified ApplicationListeners themselves, but controlled from the context of the game object.  They have a lot of the same methods that you find in the ApplicationListener.  Rather than having a single render() method, each screen has an update() and present() method, which are called from the game object's render() method.  The update() is for game engine operations while present is for doing all your graphical work.

In this way, you have a separate screen for each activity you want to implement: main screen, help screen, splash screen, game play screen, and so on.  At the moment, I only have a PlayScreen, but at least I have the frameworks in place to allow for the multiple screens you see in your typical games.

Thursday, July 7, 2011

Grapple gun & raycasting

Grapple gun

I implemented the grapple gun as mentioned below and it works semi-perfectly.  I discovered that joint lists are independent, whereas I assumed they'd be inter-related.  Iterating through the player body only gives me the joint for the gun.  For some reason, I expected to see the joint between the gun and the grappled object.  Not so!

I don't limit the gun's range of motion (it runs from 0..360) and have given it a HUUGE torque.  Much hilarity ensues when you grapple an object and then try to move the object through the player body.  Jumps and leaps of enormous proportions!

Raycasting

The raycasting took a little while to figure out -- I had to break out the code for the Ray-Tracing that is in the Box2D testbed demo.  First off, I had to implement this via a callback giving the start and end points of a ray projected out from the gun.  Easy enough.  Just have to do some rotations and transforms to get the ray to start where the gun is situated.  The next part was a learning experience... I was able to grapple through walls which didn't make sense.

The reason behind this is that the callback you supply is not guaranteed to return the nearest object the ray encounters.  You have to set it up to return a fractional amount as an indicator to the caller.  This clips the ray to that point.  If there is an object further out that hasn't been reported, it will not be reported.  If there is an object closer that hasn't been reported, the callback should iterate again with that object, at which point you again return a fractional amount to clip things.  Note -- this is only if you want to locate the nearest object.  Other return values will get you different results.

See below for the player / gun body grappling a circle body.

Box2D contact listener vs solver: The Showdown

I noticed something unusual as I was testing out my map today.  I was debugging my contact listener's beginContact() method, displaying the velocity that was being reported as an object struck a pad object.  If you've been following this blog, you'll know that I take the contacts and place them in an array for later processing.  I then displayed the velocity of the object during the array processing step. THE VELOCITIES FOR THAT SAME OBJECT WERE VERY DIFFERENT.

This was not expected.  I knew that the object may have been traveling fast enough where it may have contacted the ground below the pad and attribute the difference to that.  However, the net effect I wanted was for the velocity to remain unchanged.  Upon further investigation of the Box2D physics, I saw that its Collide() method (which calls the contact listener), executes BEFORE the Solve() method.  In other words, the contact is detected and the object's speed is valid at that point of impact.  However, the solver comes along and adjusst the velocity of the object before my game engine's processing step is able to do anything about it.  Oh yeah?!  We'll see ABOUT THAT!  Heh.

To get around this, I added a velocity vector to my processing array so that I could record what the velocity was at the point of impact.  Things are now happening the way I want them too.  Woot!

Grapple gun and other stuff

Grapple Gun:

The next thing on the list to do is to make a grapple gun that can move objects around in my world.  The idea I have in mind is to take the angle of the 'gun' object, shoot a ray out from it and determine if it hits an object.  If it hits a dynamic object that is 'grapple-able' (value configured via user data settings), project it out a certain distance away from the grapple gun to serve as an anchor point and then create a revolute joint between it and the gun.  When the user decides to drop it, simply destroy the joint.  The object should stay with the facing of the gun due to the joint. 

There are a couple of unknowns -- whether the libgdx Box2D port supports raycasting (if it didn't, that would suck) and whether I need to have a joint as part of a fixture or if it's okay to let it hang in the air (I think it should be ok, but I need to experiment.)

Other stuff:

I learned yesterday that the libgdx Box2D does NOT support contacts based on bodies (see section 9.3 of the Box2d manual.)  You cannot do a myBody.getContactList().  The closest you can get is iterating over all of the world's contacts via myWorld.getContactList().  That sucks.  To work around this, I implemented some contact array lists associated with specific objects whose elements either get removed from the list when acted upon or the endContact() method gets executed, otherwise they get re-checked on the next update iteration of the game step.

Wednesday, July 6, 2011

A door has been opened on the Box2D project

I spent the day messing around with prismatic joints and have created a button, a door, and a wire control.  The button is a simple prismatic joint that is jointed with the bottom edge of my world's arena (hence the joint line you see in the debug rendering).  I give it a vector that indicates you need to push down on it to activate.  I made this as a class that contains some hysteresis and other modifiers that can potentially be affected by other elements in the game.  It has a small motor defined to act as the 'spring' up (ie. button not pushed).  Also included is a method that updates the button state -- it checks the translation to see if the button is pressed or not.

The door is very similar, but instead contains the 'openSesame' and 'closeSesame' methods.  The motor in this case is always pushing out initially.  When the openSesame method is invoked, the motor speed is reversed and the door opens up.  When the closeSesame method is invoked, the motor speed is positive and the door closes.  The graphics below demonstrate a retractable ledge in the upper left corner using this concept (button is in the mid-right portion).

The final component is the wire control.  It's the "go between" for the button and the door.  It is created and passed references to controlling buttons and controlled doors.  Its update() method is invoked on a periodic basis.  If it detects that its button is pressed, the corresponding door is then opened.  Pretty straightforward.  The screenshots below also show a couple of objects I made to kick around in the world: a box and a ball.


Today's Box2D fun will be Prismatic Joints

Did some reading on the Box2D site and discovered that a good way to get a pressure plate / push button effect is to use prismatic joints.  I added a quick prismatic joint (via a custom push button class) to my test arena and it worked great -- just needs some tweaking to prevent bouncing, etc.  The next step will be to tie the opening / closing of a door to the button being depressed.

With all of the experimentation and exploring I've been doing lately, I've thought about maintaining all my finds / tips / tricks in a cookbook format to act as a companion to the Box2D manual.  Sure, there's the demos that are included, but it would be nice to have some written text so you don't have to work at deciphering how to implement a particular activity.

Monday, July 4, 2011

Box2D progress

Here are the things I picked up today:

- Mercurial / TortoiseHG installed
- Assembla repo created
- Learned how get Mercurial to store my Assembla password:

1) From the Hg workbench right-click the project > settings > global settings tab > edit file.  Enter the following:

[extensions]
mercurial_keyring=

Hit save.
2) repo settings > edit file

Set the https URL to https://username@repo.path.com

My hgrc looks something like this:

[paths]
default = https://my_assembla_user_name@hg.assembla.com/ProjectName

- Learned that the libgdx .processEvents method (which implements calls to keyDown, etc.) is executed prior to render().  So, it should be safe to modify Box2D world objects (create, delete, etc.) from the context of a keypress, since the step() method is executed from within the render() method.

- Learned that the BeginContact() method of the libgdx Box2D implementation is executed in the context of the step() method.  It is NOT safe / allowed to modify world objects from within BeginContact.  Since I want to create / delete / whatever as a result of contacts, I created an ArrayList that is modified based on contact.  Then, after the step() resolves, this list is iterated through and actions are performed.  I maintain separate lists depending on the type of actions I want to perform. 
For example, I have one list that operates on bullets hitting objects.  I have another list that operates on special objects interacting with other objects -- the operations of which are completely different than what happens when bullets are resolved.

In my render() method, following step(), I loop on the list not being empty, and simply removing one element at a time.  Since the libgdx mainloop() is single-threaded, operating on these lists shouldn't need to be synchronized and I don't need any sync wrapper methods / protected methods for list operations.


- Discovered a stoopid mistake where I did a shape.dispose() on a shape attached to a body that had been created in the world.  The net result was that my application would crash and I'd get a "pure virtual function called".  Das ist bad, ja!

- Discovered another stoopid mistake where I destroyed a body in one resolution step without updating locally maintained object references.  Then, as I attempted to modify those same (now destroyed) objects, I got to watch the application crash hard again in the middle of a Box2D step.  Yuck.

- Got a better grasp of some simple vector methods.  To get a vector's normal, swap the x & y coordinates, and negate the new y-coordinate.  This effectively translates the vector 90 degrees anticlockwise.  Doing this again rotates that vector by another 90 degress.  Two more times brings you back to the original position.  Certainly information you can use to impress the ladies.

- Got a better understanding of collision filtering.  Bodies that have the same positive group index number always collide.  Bodies that have the same NEGATIVE group index number NEVER collide -- they just pass through each other.  This is helpful if you have a bullet object that you don't want to hit the player body if he is aiming down at his feet.

- Bodies that are connected via joints affect the overall velocity of the jointed body.  In my game, I teleport around objects.  Turns out that when I did my transform to move the object and affect the velocity, I only did it to one of the objects in a jointed system.  The velocity ended up being slower than I predicted until I realized my secondary body was affecting things too.

- Had the assumption that a dynamic fixture with zero density was a sensor.  Not so.  You have to explicitly set the sensor flag to true.  My player body now sinks into the floor because the circle bottom sensor does not evoke any collision contacts.  This is what I originally expected, but figured I must have misunderstood something. 

- I've got the rudiments of my game working.  I need to clean some things up and get rid of some glitches due to my processing multiple contacts in the bullet list described above.  After that, I'll be expanding my test arena to include some kinematic bodies.

Some major refactoring is in order, but I'm holding off with doing that after I've got some more of the game ideas implemented and understood -- things like buttons, doors, anti-grav fields, etc.

Saturday, July 2, 2011

Slide Rule stats

Just thought I'd make a quick post about the current Slide Rule stats:

- I've got one error report, which I believe is automagically generated.  There apparently was a freeze on a platform "OTHERS" relating to "ANR._keyDispatchingTimedOut".  The user did not file an error message so no clue what's up.

- I've had a total of 3927 installs.  The number of 'active' installs is currently riding at 2137 (54% installations).

- Android 2.2 based devices rule at 66.5% of all installs

- Motorola Droid X is the most popular device followed by the HTC Desire HD.  My Droid Incredible is 6th on the list.  Surprisingly, the Samsung Galaxy Tab is 5th on the list.

- The US, UK, and Australia are the top three installation locations.  India comes in at #4.

- English is the top language followed by German.

- Installations continue to climb at a slow and steady rate.

Sunday, June 26, 2011

Box2D game progress

Last night I wrote down a list of things I wanted to get nailed down for my Box2D-based game.

  1. Create a test arena
  2. Create a character actor patterned off of the example written by the libgdx author Mario Zechner (Box2D Platformer Character Controls) and gain understanding of sensor usage.  Additionally, character will have a single arm (ie. an aimed gun) that will shoot projectiles.
  3. Use raytracing to detect where an impact will occur.
  4. Define projectiles
  5. Create response (explosions) at impact points.
  6. Set surface impacts based on the surface - different responses for different surface types
  7. Have effects 'stick' at impact points
  8. Implement a button the character can stand on that opens a remote door.  Closes when the character leaves the button
  9. Create generic actor types that the character can interact with: boxes, elevators, varying gravity fields etc.
I made it through a few of these items and continue to learn lots of cool new stuff.

Creating a test arena was easy enough.  It just consisted of defining a world and supplying static platforms and walls at the periphery.  In the process I got a very good understanding of how OrthographicCamera and PerspectiveCamera's projections work.  Zechner has a very informative and easy to understand overview here.

From there, I started work on the character actor.  The primary shape comes from Zechner's definition in the link above.  I took that and added an arm using a RevoluteJoint.  A RevoluteJoint simply pins two bodies together.  What tripped me up and took a bit of time was that the joint was very...rubber-bandish.  As the character dropped into the arena and the arm caught a platform edge, the arm would get 'stuck' but the character body would continue to descend... It looked like the joint was actually a rubberband.  Here's a picture of the weirdness in action.  The blue line shows the joint (also, I made the arm really long to make getting the effect to happen easier.)



After much debugging, including porting the SliderCrank test from the Box2D C++ TestBed project to libgdx, I finally zeroed in on the density as the culprit.  I had the density of the 'arm' body set to 0.001f.  Bumping this up to 0.5f got rid of the rubber-banding and things started behaving as expected.  This diversion cost me a few hours.

After that, I implemented the capability of firing two different projectiles based on the angle of the arm.  The angle is controlled via the keyboard (atm).  The rotation is implemented via a motor attached to the joint.  When the rotate CW key is pressed the motor speed is set to a predefined > 0 value, and < 0 when the rotate CCW key is pressed. 

When the user hits the 'fire projectile' button, any previous bullet is destroyed and a new bullet is created based on the orientation of the arm using transforms.  To do this, I first create the projectile and then offset the location based on the relation of where the arm was created.  The initial velocity is defined based on this as well.  Then, the velocity vector is rotated following the angle of the arm and the position / angle of the projectile is set according to the arm's transform.

On a side note, one somewhat neat thing about the operation of the character is that I give it a finite impulse upon every jump-key press.  This gives the character the type of motion that you see in the old arcade Joust which is pretty cool looking and fun to mess around with.  This gives me the idea to implement some sort of bird-wing-flapping game.

Here's the current state of the game using the built-in debug renderer.

Friday, June 24, 2011

Box2D and Eclipse

Well, after about an hour and a half of effort, scouring the Internet and some elbow grease (heh) I *FINALLY* have got the Box2D testbed to compile using Eclipse on my Windows 7 x64 box.  It's not all that straightforward.  Here's an outline of the steps you'll need to take:

1) Install Eclipse (duh?) and the CDT (C Development Tools)
2) Install MinGW & related gcc/g++
3) Install & build GLUT for Win32
4) Download Box2D source
5) Install CMAKE, tweak some of the output and have it create your build file


Details for those steps:

1) Install Eclipse and the CDT.  You can grab Eclipse from http://www.eclipse.org.  I'm personally using the Helios release.  I grabbed the Java edition (a while ago, actually).  To install the CDT for C development support, open up Eclipse and go to Help > Install New Software...  Set the "Work with:" drop-down to all sites and enter "CDT" as the filter text.  Eventually you'll be presented with things to install.  I selected everything.  Easy peasy.

2) Install MinGW.  Go to http://www.mingw.org and download and execute the installer.  In the installation options, select pre-packaged catalogues and when queried, select C++ compiler, MSYS Basic System, and MinGW Developer Toolkit. Easy peasy (again).

3) Install GLUT for Win32 w/MinGW support.  I followed the instructions up on http://www.mingw.org/category/wiki/glut which is actually a reference to http://joshuaburkholder.com/glut.  There are instructions there for downloading and building glut-3.7.6 from src files.  Follow steps 2 through 7 on that site.  You'll need to perform these steps using the MSYS Shell prompt installed as part of step 2.  If things work out correctly, you'll see the gear test demo.

The next thing is to be able to build from Eclipse.  Ensure your environment path references the /bin directory of the MinGW installation.  Create a new C++ project in Eclipse.  Set it up as an Empty project and select MinGW GCC from the Toolchain list in the right pane.   This initially did not come up for me until I added the f:\mingw\bin path to my environment.  Anyway, name the project "GLUTDemo".

Go to http://paulsolt.com and follow steps 5c through 6c.  This will create a project containing Demo.cpp that will verify you can create a GLUT based project and that it works.

4) This is really simple.  Just hit the Box2d website at http://box2d.org to grab the latest and greatest source.  I'm running v2.1.2.  Extract that to some directory on your machine.

5) Box2d requires that you have Cmake installed.  Grab that from http://www.cmake.org and install it.  Next, you need to use it to configure the build attributes for Box2D AND specify that you want it to create stuff for Eclipse.  Open a cmd.exe prompt.  Yes, a cmd.exe prompt -- not the MSYS sh.exe.  Navigate to the Box2D Build sub-directory.  From here, enter the following:
cmake -G"Eclipse CDT4 - MinGW Makefiles" -D CMAKE_BUILD_TYPE=Debug ..
You can now go into Eclipse and import the resulting project.  The build will kick off and eventually fail when it gets to the link stage of the TestBed.  Don't fret.   Open up Testbed\CmakeFiles\Testbed.dir\link.txt and add the following to the end of the last line:

-lwinmm -static-libgcc -static-libstdc++
This clears up a few problems: undefined references to joygetdevcaps & some time functions, and also libgcc_s_dw2-1.dll / libstdc++-6.dll not being found when trying to start the resulting .exe.

Right-click on the project and tell it to build.  This time, a testbed.exe should be created and you can happily run it.

Cheers,
--tim

Sunday, June 19, 2011

Crypto alpha

Here's a screenshot of the mono-alphabetic crypto-tool that I wrote.  The example you see is the puzzle and solution to the first entry in Elonka Dunin's Secret Code and Cryptograms book.  The 'Fill' button fills in all of the substitution values with the '@' symbol.  This is used for reference when decrypting so you can see what letters are missing.  The % column shows the frequency analysis on the contents of the base text (updated when the analyze button is hit.)  The decrypt button takes the Base Text and substitutions each alphabetically character with the substitution from above.

Looking at the resulting Alphabetic Subtitution table, it doesn't appear that this key follow the Affine Cipher which I was half-expecting.  There is somewhat of a pattern, but overall it looks random.

Fun Saturday

I'm putting the music app on the back burner for now and am going to concentrate on an idea I've got for a 2D game.  So, I'm hitting the libgdx forums on BadLogic again and diving into how it's implementation of Box2D works (as well as the fundamentals of Box2D itself.)  Spent a good chunk of time yesterday doing that.

On Friday I received a book from my dad entitled "Secret Codes and Cryptograms" which has over 600 codes to crack.  Rather than dive directly into that, I decided to start writing a Java program for doing cryptographic analysis and decryption.  Since my knowledge of the Swing GUI is nil and I wanted a nice GUI to help me in my code-breaking attempts, I started looking into that.

I'm using the Eclipse IDE and found the WindowBuilder Pro plug-in.  WindowBuilder Pro is a Visual Editor for GUIs.  A couple of tutorials later I'm up to speed on that and am currently design my UI for decryption.  The idea is to give it the following capabilities: text entry, letter frequency analysis, 'guessing' based on letter frequency,  mono-alphabetic substitution and (maybe) brute force methods.  We'll see how it goes.

Cheers.

Saturday, June 4, 2011

Been a while since last post...

My progress toward the DrumLine app has pretty much tapered off, unfortunately.  I'm able to create drum tracks programmatically, but there are hiccups in playback due to thread priorities.  The rhythm plays back just fine around 80-90%... but then there are the bits and bobs that make it skip which is extremely annoying and frustrating.  In addition to that, my GUI skills are not all that, so the going is slow.

In other news, at work I've been delving into Mercurial.  It's very similar to Git in that it is a DVCS.  I think they complement each other really well -- if you know Git, you'll understand Mercurial.  I'm getting a lot more familiar with the DVCS concept and the workflows around it.  Not that I'll change how I've got things set up from a DVCS standpoint for my Slide Rule app, but it's cool to grok how things work.

I've got the bug recently to look into cryptography.  I've read about Bitcoin on several different sites including Slashdot, Ron Paul RSS feeds, and Instapundit.com.  It's got my curiosity piqued.  I discovered that there is an FPGA implementation of the Bitcoin algorithm.  I tried getting that going on a BeMicro SDK board I have from Arrow, but that little sucker does not have enough Logic Cells to implement the guys design.  I've got a DE2-112 board on loan from Arrow, but haven't revisited it (yet!).  Anyway, Bitcoin implements hashing algorithms and Merkle trees and I figured it would be fun to learn more about that stuff so I'm slogging my way through an introductory book on Cryptography. 

Friday, April 22, 2011

DrumLine

I decided to forge ahead with the drum line app.  I've got it to the point where things are working from a programmatic standpoint.  The sequencer object reads in the score.  The score consists of measures.  Measures consist of notes.  Measures & notes can be instantiated and added to the score, which is then passed to the sequencer for playing the actual drum line.

The notes right now are limited to drum track samples.  I've got it in mind to expand this to allow any kind of sounds / voices.  But, drum samples are relatively easy to get going.  We'll see how things progress.

The things to do list currently consists of:
  • Create a UI for the sequencer for playing
  • Create an Editor
  • Allow storing / loading of previous compositions
  • Allow importing / exporting of compositions
  • Observe memory usage effects resulting from samples.  Will I need to down sample?
Need to do some experimentation yet, however, to make sure that the Android device is capable of handling this.  As mentioned in a previous post, there are some issues with latency and audio.  Things work fine on my quad-core desktop at up to 160 bpm (haven't messed around too much with that -- but 160-180 is the top end I want to target).... but will they push my HTC Incredible or Nook Color to the limit?  I've got today off so I plan on doing some testing and coding to see where it brings me.

Portal 2

Just completed Portal 2 single player.  Now I can go back to being productive.  Kinda.  Stayed up till around 2am playing it so I'm a bit zoned out at the moment. :P

Sunday, April 17, 2011

Android Market stats

I thought it would be interesting to share this. It's a rendering of what I see in the Developer Console on the Android Market for my app. Unfortunately, an interactive graphic does not show up in that rendering -- at the top in that blank area you see is a Flash graph showing the trending of downloads for an app. It currently states that my app has 254 or so downloads. This conflicts with the market dashboard indicating that value is actually 341. I've noticed a discrepancy between those two values, and although there is info that states the data is updated on a daily basis it doesn't appear to happen that frequently. It looks to be more like one or two days between updates.

Here are some interesting tidbits from that data:

  • There are only 9 installations that utilize something other than Android 2.1 or 2.2.
  • The top three devices that installed it were Motorola Droid X, Samsung Galaxy S, and the HTC Incredible.
  • The top three countries are US, UK, and India. I was surprised that India was #3. It's followed closely by Australia.

Saturday, April 16, 2011

Android Audio bites

Today I thought it would be fun to throw together a Drumkit Soundboard. I was at work the other day and it occurred to me that doing something like this would be really simple and result in something that would be relatively cool.

I've got a program on my desktop named Guitar Pro which is really cool for learning and playing along with songs. It employs something that the company terms "Realistic Sound Engine". What this boils down to is real-world samples of instruments that can be played back at real-time. (OBSERVATION: The Guitar Pro site shows an iPad and iPod, but curiously no Android device... The reasons will become apparent below.)

I took that and created a drum track with the simple drum samples I wanted: snare, bass, high hat, and cymbal. I exported the result and pulled it into open source audio editor Audacity. From there, created individual samples and stored them off as OGG files. I fired up Eclipse and created a libgdx based project called DrumkitSoundboard. After looking up some API calls and creating a really uber-simple quadrant based UI (each quadrant of the screen corresponding to one sound sample), I had the rudiments of my soundboard going. This is where the problem cropped up.

The problem -- the audio on my HTC Incredible lagged to the point of unusability. There is something on the order of 100ms+ gap between the time the user hits the screen to the point that the sample hits the speaker. If you are trying to maintain any kind of rhythm, you are going to be severely messed up trying to play it... I know I was.

As a result, I posted a query on the Bad Logic Games forum about this to see if anyone has run into a similar issue. It turns out that audio latency has been identified as a problem since as early as 2009. The issue is logged here. There are several music app developers that would *love* to port their stuff from the iPhone/iPod to Android, but can't because of this problem with high-latency of real-time sound. Ugh! That royally sucks. ...and also probably explains why there's no Android app from the guys at Guitar Pro.

For fun, I cracked open the Android Market and downloaded a drum kit soundboard I found there (Hit it!). Turns out it has the same lag issue I experienced. Nice.

Needless to say, this put the kibosh on my own drum kit idea. At best, I could create an audio composer of sorts... Where instead of making things interactive, you could create a drum track. For fun, I did this programmatically to see what the result was. With a target tempo of 120 bpm, playing drum samples at an eighth note beat (bass+hihat, hihat, snare+hihat, hihat, repeat ad infinitum) it worked... Mostly. There were times where you could tell it got off the beat by a perceptible amount. Another: Ugh!

I dunno, I think I'd be ultimately disappointed in the result. Still, it would be kinda fun to allow people to compose simple drum lines. Imagine doing that and then hooking up your Android phone to your car stereo... I've already got the name of the app in mind: MasterBeater. :)

Thursday, April 14, 2011

Project hosting

Some guys from work and I are collaborating on Android projects. Mostly to learn from each other as we go along. Initially we opted for using Project Locker for our project hosting. But, that's a bit on the constrained side. You are limited to 3 collaborators and 300MB for your projects and I believe something like only 3 projects. I did some investigating and decided to switch over to Assembla. There you have unlimited projects, 2GB of project space, and up to 10 collaborators on a team. You also can have 'private' (commercial) repos. Not too shabby. Ideally, it'd be best to host our own stuff, but I'm lazy and didn't feel like leaving up a box 24/7.

On the repo side of things we're using Git. I'm still getting my head wrapped around the way that it works, but so far have been okay with it. There's a bunch of stuff you need to get set up beforehand, though, so it definitely has a learning curve (and I'm still on the rising slope in that respect.) Here's some Windows config stuff I recently sent out to the team to give them a leg up on things. Share and Enjoy.

All--

Here's some help with getting Git up and running under Windows. If you run into problems, let me know and I'll see what I can do to help.

Tools you need to set up Git and repo access under Windows:

SSH agent:
http://the.earth.li/~sgtatham/putty/latest/x86/putty.zip

msysgit:
http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.4-preview20110204.exe

TortoiseGit:
http://code.google.com/p/tortoisegit/

Extract the putty files to a directory. Run PuttyGen. You'll use this for generating a private & public key that is required for checking files to the host server. Give it a key comment... I use tim@MY_MACHINE. Save the .ppk off. Don't bother saving the public key off -- if you ever need it in the future, just run PuttyGen and load in your .ppk file to get a copy. Copy & paste the public key -- you'll be using this on Assembla.

The Git Repo hosting is on Assembla.com. You'll need to register there to access the space that I've created for the Pazaak game.

For adding SSH keys:
1) Login
2) Click on "Profile"
3) Scroll down and add a key under the Git repo

If you want to create a project space for yourself:
1) Login
2) Click on "Spaces"
3) Click on "Create a new space"
4) Click on "See all workspace configurations"
5) Click on "Select" next to "Free Git Repository - Unlimited commercial uers" (sic)
6) Give it a name
7) Click on "Create the Space"

Git on Windows

When prompted, tell it you want to use plink. Plink is part of the putty.zip file above.

1) Download & install the msysgit preview.
2) Download & install TortoiseGIT
3) Use TortoiseGIT to create a local repo
4) On Assembla, click on the space you are interested in
5) Reference the Git URL for that space from within Tortoise
6) Do a pull from the server repo to your local repo and you should be good to go (right-click on the dir, TortoiseGit > Pull etc.)
7) In Eclipse, just do an Import... > From Existing Projects


Uber nerds unite!

I'm proud to say that if you put in the search term "uber nerd" in the Android Market, the single result you'll get is my app. Just doing my part to help out all those folk building up their old school nerd-cred. Heh! :)

Memory Leak plugged

Alright. I got it fixed. Wahoo.

As mentioned in my previous post, I was noticing that several objects seemed to hang around across screen orientation changes (ie. going from landscape <--> portrait mode). I went back to square one with the original code that I derived my slide rule app from and discovered that *it* also had the memory leak. It didn't exhibit the same issues as my app, however, because it was using way less memory -- all it did was draw a stinking little icon to the screen.

So, I started tracing things which led me to a class based on a Thread object. It turns out that this guy had some references to a Context object. Yesterday I had read several articles that mentioned keeping references to Context when there is a screen change leads to bad juju. Beyond that -- the orientation causes the Activity to be killed, but if there is a reference somewhere to a Context, the old object doesn't disappear. After a bit, this adds up and eventually you have no more memory that can be allocated.

I updated the Thread such that when it needed to be destroyed, it got rid of its references to the Context (and another object it was referencing... just to be safe.) Further, it turned out that the View that presents the graphics was causing the Thread itself to hang around. I had to get rid of that reference as well to shake loose the Thread.

After making those updates and using the DDMS to dump the heap, I still saw that the 3 primary objects in the App (the Thread, the View, and the Activity) were ratcheting up. HOWEVER, this time around forcing the Garbage Collector to execute caused those bad boys to drop back down to 1 each -- which is what I desired. Wahoo! Problem solved!

If you are a visual person, here are some screen shots that highlight the general approach I took in debugging things.



Wednesday, April 13, 2011

Worse than a running faucet

Well, I don't have a solution yet, but I've learned a bit about how to detect memory leaks. I've verified that I do indeed have one. Here are some quick steps for detecting leaks in your Android app:

1) Install the Eclipse Memory Analyzer. You can do this from the "Install New Software..." option in Eclipse.

2) Set up your application in Debug mode.

3) Download your application to your device or emulator.

4) From the DDMS perspective, highlight your app.

5) Click on the "Dump HPROF File" button.

6) After the HPROF viewer comes up, select the Histogram button.

7) In the regex field, enter part of the name of your app to filter things out.

From there you can see how many objects are available. In my case, I have a class that is called Panel. There should be only one instance of this panel present. After performing several orientation changes (landscape <--> portrait), the number of panels ratchets up... once for each change.

So, now it's a matter of figuring out why. What I've done so far is to strip all graphics and graphics threads out of my app. The problem still occurs. Need to spend some more time on this to figure what's not being released and causing this issue. We'll see where this leads....

Memory Leak woes

I was demoing my Slide Rule to a guy at work yesterday and came across a Force Close. It turns out that my app has a memory leak in it. To replicate: go from landscape to portait and back again several times. Eventually, the app will crash because it runs out of memory.

So, over the lunch hour I read up on handling memory leaks and detecting them. Turns out you can use the Heap profile in DDMS. I'll post details after work today. Hopefully I can get this problem cleaned up tonight and return to my libgdx & OpenGL ES studies.

Tuesday, April 12, 2011

OpenGL ES

Currently working my way through libgdx and OpenGL ES

--tim

Sunday, April 10, 2011

Achievement Unlocked: libgdx Bouncing Sprite

I'm looking at doing development using the libgdx Game Development Framework for Android. It's pretty slick in that you can run things on your desktop before having to worry about deploying them to the target Android device. That, of course, is just the tip of the iceberg... it provides a whole bunch of stuff you need for doing audio, graphics, etc.

I'm running through the initial tutorials and am up to the projection-viewport-camera tutorial, tweaking things as I try things out. I'm thinking it would be a good exercise to port my Slide Rule to utilize libgdx.

Here are a couple of screenshots of my bouncing sprite.

I guess you can buy these things new.

Heh.

Saturday, April 9, 2011

Now it's just time to sit back and wait for the accolades

Got my Slide Rule app uploaded to the Android Market. Now all I have to do is sit back and wait for the accolades to come rolling in.

...

(cue: crickets chirping)

...

Anyway, I learned a bunch of stuff and now it's off to working on my next app.

Slide Rule release

I spent a bunch of time last weekend writing a Slide Rule app. Today I'm in the middle of releasing that to the Android Market.

I couldn't sleep last night, so one other thing I did was to update SwiFTP so that it works in full-screen for my Nook Color. I sent an e-mail to the original developer and now have write access to that project. I submitted my updates for that today. Might be interesting to support that and work on issues that people have logged against it.

Saturday, February 26, 2011

Wow. What ... sloth!

It's Feb 26th, 2011 and I'm trying to get back on the wagon for Android programming. Once again hitting the Android Wireless Application Development book. This time around I have a Nook Color to play around with.

I ran into some issues getting Eclipse 3.6 installed on my Win7 x64 machine. Turns out it's looking for the JDK in a spot different than where the x64 Java installer puts it. Yay. Found a workaround on the 'net where you export your Java node and put in references to Wow6432 or some sort. That worked. However, Eclipse 3.6 has issues with Content Assist... in that it takes upward to 30 seconds when you are typing something before it will show any methods. Not nice. Downgraded to Eclipse 3.5.1 and that cured that problem.

The plan is to hit B&N tomorrow and get together with a buddy to discuss an Android app we can work on. I'm thinking a port of an open source SNES would be a good candidate.

That's it for now.