Monday, March 12, 2012

Node.js and sequential steps

One of the things I have come across as I work with Node.js, is that my code tends to creep to the right.


That's because of two factors.

1) Node.js encourages asynchronous functions.
2) Most examples out there use anonymous functions.

Combine anonymous and asynchronous and you get nesting nightmare. (it's even worse in CoffeeScript where there's no close curly to show where a block ends, instead you have to count the tabs or hold a ruler up to your monitor)

However, it's not that hard to clean this by switching to non-anonymous functions. I recommend any time you get beyond 3 or 4 levels deep you should break it up like this.


Update: Or use IcedCoffeeScript!

Thursday, December 8, 2011

NativeActivity

So I was using the SanAngeles sample because I couldn't get the NativeActivity sample to work.

But I found an answer to this issue.

The answer is to set android:hasCode="true" in AndroidManifest.xml

Thursday, November 10, 2011

Box2D on Android NDK

Ok so I want in my game to be able to flick things around, I want them to bounce off walls, bounce off each other. Like air hockey kind of.

But I don't want to do all that physics math myself. I am LAZY! (don't forget that laziness is a virtue in developers.) So I need a 2D physics engine! One written in C++. With not many dependencies.

Well we are in luck, Box2D is perfect for this. Thank you Box2D developers, I love you for doing math so I don't have to!

Download the code, drop it in my JNI directory. Well note, we don't actually want ALL of that code. Just the library itself. So the Box2d directory (the one with the Box2d.h in it) put that in your jni directory.

Then two things you need to do. Add the following .cpp files to your Android.mk
Box2D/Collision/b2BroadPhase.cpp \
Box2D/Collision/b2CollideCircle.cpp \
Box2D/Collision/b2CollideEdge.cpp \
Box2D/Collision/b2CollidePolygon.cpp \
Box2D/Collision/b2Collision.cpp \
Box2D/Collision/b2Distance.cpp \
Box2D/Collision/b2DynamicTree.cpp \
Box2D/Collision/b2TimeOfImpact.cpp \
Box2D/Collision/Shapes/b2ChainShape.cpp \
Box2D/Collision/Shapes/b2CircleShape.cpp \
Box2D/Collision/Shapes/b2EdgeShape.cpp \
Box2D/Collision/Shapes/b2PolygonShape.cpp \
Box2D/Common/b2BlockAllocator.cpp \
Box2D/Common/b2Draw.cpp \
Box2D/Common/b2Math.cpp \
Box2D/Common/b2Settings.cpp \
Box2D/Common/b2StackAllocator.cpp \
Box2D/Common/b2Timer.cpp \
Box2D/Dynamics/b2Body.cpp \
Box2D/Dynamics/b2ContactManager.cpp \
Box2D/Dynamics/b2Fixture.cpp \
Box2D/Dynamics/b2Island.cpp \
Box2D/Dynamics/b2World.cpp \
Box2D/Dynamics/b2WorldCallbacks.cpp \
Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp \
Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp \
Box2D/Dynamics/Contacts/b2CircleContact.cpp \
Box2D/Dynamics/Contacts/b2Contact.cpp \
Box2D/Dynamics/Contacts/b2ContactSolver.cpp \
Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp \
Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp \
Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp \
Box2D/Dynamics/Contacts/b2PolygonContact.cpp \
Box2D/Dynamics/Joints/b2DistanceJoint.cpp \
Box2D/Dynamics/Joints/b2FrictionJoint.cpp \
Box2D/Dynamics/Joints/b2GearJoint.cpp \
Box2D/Dynamics/Joints/b2Joint.cpp \
Box2D/Dynamics/Joints/b2MouseJoint.cpp \
Box2D/Dynamics/Joints/b2PrismaticJoint.cpp \
Box2D/Dynamics/Joints/b2PulleyJoint.cpp \
Box2D/Dynamics/Joints/b2RevoluteJoint.cpp \
Box2D/Dynamics/Joints/b2RopeJoint.cpp \
Box2D/Dynamics/Joints/b2WeldJoint.cpp \
Box2D/Dynamics/Joints/b2WheelJoint.cpp \
Box2D/Rope/b2Rope.cpp

I also have these things in my Android.mk YMMV
LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog
LOCAL_C_INCLUDES := $(LOCAL_PATH)
include $(BUILD_SHARED_LIBRARY)

Then you need to create a Application.mk file that looks like this:
APP_PROJECT_PATH := $(call my-dir)/..
APP_STL := gnustl_static

Now you can #include in your code, and off you go!

Wednesday, November 9, 2011

Making some models

Well I wanted to make some models to use for my game.

I found the easiest way is to make them in Google SketchUp, and export to Collada (.dae)


Then use MeshLab, import the .dae and export it to .obj.



You want .obj because it's easy and fast to deserialize in your game!

Up and running with Android and NDK

I wanted to share some of my adventures with the NDK.
What is the NDK? The Android Native Development Kit.
What is the NDK useful for? Well I think the most obvious use of the NDK is to make it so you can write your app in C/C++ and easily port your app to IOS and Android and WebOS and whatever else. (but not Windows Phone because it doesn't support native.) Secondary to that, native code is faster than java. If you're writing a 3D game, you want native.

It took me a while to figure this all out, and I thought this might save you some time.

Let's start off with configuration!

1) Install Cygwin, I put mine at c:\cygwin.
2) Install the Java SDK, I put mine at c:\Java\jdk1.7.0_01
3) Download the Android SDK, I put mine at C:\Android\android-sdk
4) Launch "SDK Manager.exe" from the Android SDK directory, and install the platforms you want. I recommend 2.2. You only need SDK Platform, you might want Samples and Google APIs.
5) Download the Android NDK, I put mine at C:\Android\android-ndk-r6b
6) Download Eclipse. I put mine at C:\eclipse
7) Install the ADT.
8) Install the CDT
9) Install the Sequoyah plugin

Well that's the basics.

Now that you have that, let's get our hands dirty.
Open Eclipse.
File->New->Project
Android/Android Project
Next
Create project from existing source
For Location enter the location of the san-angeles sample (for me C:\Android\android-ndk-r6b\samples\san-angeles)
For Project Name, name it SanAngeles
Next
Select your platform, I selected Android 2.2
Next
Set Application Name to SanAngeles
Finish

Right click on SanAngeles in Project Explorer
click Android Tools
click Add Native Support...
click Finish
Would you like to change to the Android Native Development Perspective? Yes. :)
Right click on SanAngeles in Project Explorer again
Properties
C/C++ Build
Instead of "Use default build command", you want to specify Build Command to "bash c:\Android\android-ndk-r6b\ndk-build"
Click OK
Right click on SanAngeles in Project Explorer again
Click Build Project.
If you have never run code on your android phone, set it up (enable usb debugging and unknown sources) make sure your drivers are installed, unlock the lock screen, and plug it into your computer.
Right click SanAngeles in Project Explorer again.
Click Run As -> Android Application
You should see SanAngeles running on your phone. You compiled that! If you change the code in jni/app-android.c or jni/demo.c and build and run it again, you'll see your changes running.

So now you are all set up!
The native code is inside the "jni" directory.
With this setup, you can edit the native code and the java code in Eclipse, build and deploy.

So take a peek at src/com.example.SanAngeles/DemoActivity.java
see where it's calling the native functions? For example the onTouchEvent that calls nativePause()
You can customize those native calls, and pass any data you want.
Try modifying the onTouchEvent to pass the touch's X/Y coordinate to a new native function, make sure to follow the function name pattern in app-android.c, it's important.

Well now I have shown you how to get a project built and running, so you have a basis for your own project.

Friday, December 3, 2010

Threading is so easy in C#

Last time I tried to do threading in C# it was hard.  It's a lot easier now.



becomes

Thursday, December 2, 2010

xbmc

I was at a thanksgiving party in San Francisco, and there was some music playing in the background.  I noticed that the television was displaying a visualization I didn't recognize.  It wasn't Windows Media Player, or Zune, or QuickTime or iTunes, or Xbox or PS3... And it was beautiful.  I wanted it.  I asked our host about it, and it turns out this was XBMC.

I looked it up and they have ports for pretty much any OS, and they also have their own Linux distribution based on Ubuntu.

So I downloaded the source.  2.5 gigs later... I tried to open the Windows project with VS2010.  Dear god it took forever.  But it opened.  Then I tried to build.  I figured chances were low that it would actually work.  Surprisingly, only 12 errors out of the box.


For such a huge project I am impressed!
Looks like I am missing the Simple DirectMedia Layer.
A project for tomorrow.