android

The Angry GF (A non-released Unity, C# Game for Android & iOS)

Posted on Updated on

スクリーンショット 2015-10-31 10.29.39
For a few months I’ve been working on a simple retro-style “flicking” game for Android & iOS. A lot has changed during the production and well .. long story short: My idea wasn’t good enough.

So why not release it as open source? Makes sense. Plus a lot of people out there need some information which I’m giving away for free and that itself makes me happy 🙂

Enjoy!

You can download the entire source code and its resources (except BGM because I didn’t make them) from my Github: https://github.com/benji011/AngryGF

Samurai Gunship website finally released!

Posted on

Working at Pamprepps Games in Fukuoka Japan is awesome!
Today the official website for the game I developed for Android (iOS is coming soon) has been released!

スクリーンショット 2015-09-14 11.45.37

Link → http://pamprepps.com/samuraigunship/

Samurai Gunship – A retro flavour 2D casual shooter game!

Posted on Updated on

At long last I am ready to unveil a game I have been developing with Pamprepps Games in Japan for a few months. Thanks to my friend Lee Adams (a good friend from all the way back in the day when we used to play Beyblade and talk about Sonic the hedgehog) for composing the BGM!

An iOS is being released soon. Till then stay tuned!

DL link:
https://play.google.com/store/apps/details?id=com.pamprepps.samuraigames

スクリーンショット 2015-09-02 14.17.38

◆◇◆Samurai Gunship◆◇◆
A simple retro flavour shooter game.
Destroy incoming enemy aliens to score points.

◆◇◆How to play◆◇◆
To destroy enemy targets, set your gunship into position by holding down the left or right arrow buttons. The fuel you carry doesn’t last forever, however you can extend the time you have left by collecting points and by moving through each wave.

“signal 11 (SIGSEGV), code 1” – (Cocos2dx, C++ with Android & Eclipse)

Posted on Updated on

The biggest drawback I’ve been having with Eclipse and cocos2dx (not sure if this also applies to Xcode …) I can think of is the annoying “Signal 11” error. But then I ran into this thread on StackOverFlow:

http://stackoverflow.com/questions/18436383/how-to-check-crash-log-using-android-ndk-in-cocos2d-x

I find the perfect answer in http://www.cocos2d-x.org/boards/6/topics/20437.

The solution is:

When you get errors like this on the LogCat, they are saved on $PROJECT_PATH/obj/local/armeabi where $PROJECT_PATH is the path to your cocos2d-x android project. To symbolicate the messages to something understandable, you can use the ndk-stack tool.

Open up the Terminal (or Cygwin, not sure though) and type in

cd $ANDROID_NDK
adb logcat | ./ndk-stack -sym $PROJECT_PATH/obj/local/armeabi

where:

$ANDROID_NDK is the path to your android NDK

$PROJECT_PATH is the path to your cocos2d-x android project

Wow! I just hit the jackpot! okay well time to switch over to my terminal and try this out. I then get the following crash dump:

********** Crash dump: **********
Build fingerprint: 'samsung/SC-04E/SC-04E:4.4.2/KOT49H/SC04EOMUFOB2:user/release-keys'
pid: 18875, tid: 18897, name: Thread-18051  >>> com.benji.etcetc <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
Stack frame #00  pc 00000000  <unknown>
Stack frame #01  pc 000de0b9  /data/app-lib/com.benji.etcetc/libcocos2dcpp.so (GameScene::onTouchBegan(cocos2d::Touch*, cocos2d::Event*)+232): Routine GameScene::onTouchBegan(cocos2d::Touch*, cocos2d::Event*) at /Users/benji0110/Downloads/cocos2d-x-3.3/etcetc/proj.android/jni/../../Classes/GameScene.cpp:355
Crash dump is completed

Awesome! Finally according to my crash dump I was able to locate where my app crashes at line 355 .. it turns out I had deleted a game object at runtime and read that objects size, but because it was now destroyed the object no longer existed causing the program to terminate.

What a treat to end an awesome Friday^^

How to traverse through a 2D CCArray – Cocos2dx, C++ on Android (and 5 month workout progress)

Posted on Updated on

Couldn’t find anything on making a multidimensonal CCArray anywhere so I’m leaving this here so I don’t forget later.

Objective:
Generate an array which holds an array that holds a sprite.

Adding into our 2D CCArray:
Lets open our text editor and write some code!

Somewhere in our header file

	// ... 
    Sprite*                     _spriteImage;
    CCArray*                    _arr_x;
    CCArray*                    _arr_y;
	// ...

Now in our implementation file:
cpp file:

/**
 * add sprites into a 2D CCArray
 */
void Hoge::addIntoMultiCCArray() {
    _arr_x = CCArray::create();

    for (int i = 0; i < ARRAY_SIZE; i++) {
        for (int j = 0; j < ARRAY_SIZE; j++) {
            _arr_y = CCArray::create();

				int randomized_tag  = rand();                                  // generate a random tag to identify which element
				int pos_x           = i * 100 / 1.5f;                          
				int pos_y           = j * 100 / 1.5f;                          
  
                _spriteImage   	   = MySprite::create();
                _spriteImage        -> setPosition(Point(visibleSize.width / 4 + pos_x, visibleSize.height / 2 + pos_y));
                _spriteImage   	  -> setTag(randomized_tag);
                _arr_y         	  -> addObject(_spriteImage);
                this           	  -> addChild(_spriteImage);

                _arr_x   -> addObject(_arr_y);            //  Where the magic happens
        }
    }
    _arr_x -> retain();
    _arr_y -> retain();
}

Adding into a multi CCArray is quite straight forward. For each element in the first CCArray you just need to create another CCArray to produce that multidimensional array.

Now we want to do something else besides adding.

Why the traditional way is a bad idea:
The traditional way of traversing through a 2D array is with for loops:

for (int x = 0; x < ARRAY_SIZE; x++) {
	for (int y = 0; y < ARRAY_SIZE; y++) {
		// do something
	}
}

Lets say we want to edit or delete something. We can’t just do the traditional way like above.

Compiling the code using this method is okay, but at runtime this will produce unexpected behavior and our app will crash due to memory leaks. So to counter this, we need to use CCArrays CCCARRAY_FOREACH method.

Solution:

// ... somewhere below our implementation file

    // traverse through our multi CCArray
    CCObject*   obj_x = NULL;
    CCObject*   obj_y = NULL;

    CCARRAY_FOREACH(_arr_x, obj_x) {
        CCArray* _obj_x_arr = (static_cast<CCArray*>(obj_x));

        CCARRAY_FOREACH(_obj_x_arr, obj_y) {
            Sprite* _spriteImage_y  = (static_cast<Sprite*>(obj_y));
            Rect rect_a         = IntersectionPoint_A -> getBoundingBox();
            Rect rect_b               = _spriteImage_y  -> getBoundingBox();

            if (rect_b.intersectsRect(rect_a)) {                
                // maybe delete this element from _arr_y?
                _obj_x_arr -> removeObject(_spriteImage_y);
                this       -> removeChildByTag(_spriteImage_y -> getTag());	
            }
        }

    }

Hopefully this will help someone out there. Maybe my coding still is weird (and if it is I would love some feedback on how to write better code^^)

Oh yeah before I forget, here is a recent picture of my arm after 5 months of workout!

Not bad eh? Gotta keep eating and working!
Happy coding!

Lambda type Multithreading to process out of scope parameters (Cocos2dx, Android, C++)

Posted on Updated on

Lets pretend you have a vector containing int data, and you also have a class object which you need to pass into a Thread for some heavy duty processing. Lets also pretend that even if this process isn’t heavy at all but the program requires the order for everything to be processed in in exact logical order.

How do we do that? A thread in Cocos2dx with C++ looks like this:

    auto thread = std::thread([](){
        CCLog("start thread");
 
        // code goes here
 
        Director::getInstance()->getScheduler()->performFunctionInCocosThread([](){
            CCLog("finish another thread");
        });
    });
    thread.detach();

The problem:
Great! except our requirement was to pass in some data (a vector containing several int type variables and some class object)

With the above code we can’t do that because a Lambda doesn’t allow you to pass in data from outside of its scope even if it is of the same class. So what can we do about it?

The solution:
The solution is to use std::function. Lets make an example.

Header file:

template                <typename T, typename O>
std::function<T()>      MyThreadClass(T int_vector, O class_object);

I use a template for my variable types for 2 reasons:

1) With templates, You don’t need to worry about what data type goes in, everything is automated for you in the background.

2) I’m lazy (actually, I had a deadline writing this and I couldn’t be bothered to check)

Now in our implementation class we can write something like this:

/**
 * thread class
 */
template <typename T, typename M, typename B>
std::function<T()> MyThreadClass(T int_vector, O class_object) {
    CCLog("start thread");
    auto thread = std::thread([int_vector, class_object](){

        for (std::vector<int>::const_iterator itl = int_vector.begin(); itl != int_vector.end(); ++itl) {
            switch(*itl) {
				case 0: class_object.addNumbers(); 		break;
				case 1: class_object.subtractNumbers(); break;
				case 2: class_object.multiplyNumbers(); break;
				case 4: class_object.divideNumbers(); 	break;      
            }
        }

        Director::getInstance()->getScheduler()->performFunctionInCocosThread([int_vector, class_object);
    });
    thread.detach();
    return 0;
}

Might look a bit intimidating but its actually quite simple to understand.
In our Lambda we have to ‘capture’ data in order to process them. This is where we want to pass data into our thread. But Lambda won’t let us because it cannot see anything outside of its scope. So we pass data into our function which then is captured using something like below:

auto thread = std::thread([int_vector, class_object](){
	// ...
}
	// ...
Director::getInstance()->getScheduler()->performFunctionInCocosThread([int_vector, class_object);
	// ...

If we have no data to pass in from the outside, we can just remove int_vector and class_object.

Happy coding!

Generate array of sprites (Cocos2dx, C++, Android)

Posted on Updated on

alright before i forget i better write this down (being an idiot that i am i’ll forget this later)

i have this image:

which when fired at, a single block explodes gracefully like a new born baby taking its first breath outside of a womans-anyway having 1 massive image like the one above to hold several dozen block images isn’t a good idea.

A better way to do this is to have each block:
block

stored in an array or vector, loop over then before the loop is finished, add each element into our layer.

In code this would look something like this:

Block header file .h

#ifndef __BLOCK_H__
#define __BLOCK_H__
 
#include "cocos2d.h"
 
class Block : public cocos2d::Sprite
{
 
// ....
 
protected:
    Sprite*                 block;
 
public:
    Block();                                                    //  constructor
    Sprite*                 generateBlock(int pos);             //  generate a block
};
 
 
#endif // __BLOCK_H__

Block Implementation file.cpp

// ... 
Sprite* Block::generateBlock(int pos) {
    Block        _block_obj;            // instantiate our block class
// ...
    block      = Sprite::create("block.png");
    block     -> setPosition(Vec2(visibleSize.width/2 + pos, visibleSize.height));
    return block;
}
 
// ...

Now in our game scene we can do something like this:

Game scene header file.h

// ...
std::array<cocos2d::Sprite*, 10> _blockArray;
void    generateBlocksThenAddToArray();                              // generate a block then add into our array
// ...

implementation file .cpp

/**
 *  generate a block then add into our array
 */
void Hoge::generateBlocksThenAddToArray() {
 
    for (int i = 0; i < 10; i++) {
        Sprite* _generatedBlock  = _block_obj.generateBlock((i * 100) / 2);
        _blockArray[i]        = _generatedBlock;
        this                 -> addChild(_generatedBlock);
    }
}

The magic happens in the for loop in Hoge::generateBlocksThenAddToArray() method.
We loop to a suitable range (10 in this case),generate a block from the block class, set its x position by multiplying it by 100 per iteration using i, then add the instantiated block object into our _blockArray with the loop count as its address, then finally add the generated block into our game scene.

There’s probably another (better) way to do this, and I’d love some input from other talented programmers out there so, please give me a shout in the comment section below!