ランキング用ライブラリ更新2014/07/05

Androidアプリ「Plain Speed」をアップデートしました。
ランキング用ライブラリの更新によるもので、ゲーム内容は変わっていません。


ランキングのライブラリは Google Play Game Servicesではなく、広告用ライブラリに付随されているものを使用しているのですが、

一部の機種で、
ランキングで使用する値がタイム(float)の場合、
ランキングを送信するところでハングアップする

という問題が見つかりましたので、ライブラリ提供先に修正していただき、差し替えました。

これで「Plain Speed」は修正されましたが、ライブラリの開発者ページではこの問題について何も触れられていません。
タイムでランキングを行うアプリは全部、同じことが起こるはずなのですが。

・「(8月頃予定の)次回リリースで修正とさせていただければと思います」
・「結構な頻度でエラーが発生しているのであれば、その箇所だけ修正したカスタムSDKを提供する事は可能なので」(ランキング対応アプリのランキング送信の頻度…)
・「SDKですが、今週中にはお送り致しますので、」(次週の水曜に、こちらからメールを送るまで音沙汰無し)

と、あまり問題だという認識は無いようです。


ここでライブラリの提供先は記しませんが、同じ問題にぶつかった方のために…

ランキングライブラリ内で、
java.lang.NumberFormatException: Invalid int
というクラッシュ報告が上がってきた場合は、ライブラリ提供先に質問してみてください。

「かえすがえす」プロジェクト2014/02/17

Android NDKプログラミングのサンプルとして、アプリ「かえすがえす」のプロジェクトを公開します。


ごちゃごちゃ説明をするよりソースを見てもらったほうがわかると思いますので、特に解説はしません。
また、プロジェクト中のソースは自由に使ってもらって構いませんが、それにより不具合が出ても責任は持ちません。

注意点を2つほど。

・画像やBGMはフリー素材のサイトより頂いていますので、使用する場合は元のサイトの使用条件を読んだ上で、オリジナルデータの方をご使用ください。


・広告表示には、「appC cloud」を使用しています。
ライブラリ(libs/appc_cloud_1.1.2.jar)を使用する場合は、appC Cloudに登録してSDKをダウンロードしてご使用ください。
どのみち、AndroidManifest.xml内にあるメディアキーはアプリ固有のものが必要となりますので。



パズル「かえすがえす」

アプリの素材作成2014/01/11

自分はプログラムは組めますが絵や音楽は苦手なので、アプリの作成にはいろいろなフリーデータやツールのお世話になっています。
今回は「くるんくる~ぱ」で使用させていただいたツール、素材サイトをいくつか紹介します。


文字を立体化し、プラスチックやガラスなどの質感をつけることができるフリーソフトです。
スロープや影をつける、反射率や屈折率を指定するなど様々な効果できれいなロゴを作成することができます。

ただ、いかんせん使いこなすだけのセンスが無いものでほとんどサンプル通りに使用するだけで、いかにも「LogoShader」を使いましたという感じになってしまっています。


商用可、著作権フリーのBGM配布サイトです。
1000曲を超える多くの曲があり、曲の長さや雰囲気などの条件を指定して検索することができます。

「くるんくる~ぱ」のゲーム中のBGMでは、
・ループ無
・長さは約1分
と制約があったのですが、それでもイメージに合う曲を探し出すことができました。

SDKでダイアログ表示2013/12/26

今回は、ダイアログの表示を行います。
ダイアログは SDKの機能を使うので native側のプログラムではないのですが、共通部分でいろいろ変更点があったので挙げておきます。

ダイアログの表示には、DialogFragmentを使用します。
Dialogを直接 create(), show()でもダイアログは表示されますが、アクティビティがダイアログの再生成をするとかで DialogFragmentを使うべき…らしいです。


BaseActivity.java
/********************
    アクティビティ
 ********************/
public class BaseActivity extends FragmentActivity
{
	static {
		System.loadLibrary("native");
    }


	public final static int		KEY_BACK	= 1;		// バックキー
	public final static int		KEY_YES		= 2;		// ダイアログ用
	public final static int		KEY_NO		= 3;

基本アクティビティの変更点です。
Activityではなく FragmentActivityを継承しています。
FragmentActivityを使うためにプロジェクトには android-support-v4.jarを追加しています。

また、アプリ側で汎用的に使えるように KEY_YESと KEY_NOを定義しています。


AppActivity.java
package app;

import sys.BaseActivity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;


/********************
    アクティビティ
 ********************/
public class AppActivity extends BaseActivity
{
	static public AppActivity	app;


	/**********
	    開始
	 **********/
	@Override
	protected void	onCreate(Bundle _savedInstanceState)
	{
		super.onCreate(_savedInstanceState);

		app = this;
	}


	/**************
	    終了確認
	 **************/
	static
	public void		open_dialog()
	{
		ExitDialogFragment	_dlg = new ExitDialogFragment();			// 終了確認ダイアログ

		_dlg.show(app.getSupportFragmentManager(), "dialog");
	}

	/********************
	    終了ダイアログ
	 ********************/
	public static class ExitDialogFragment extends DialogFragment
	{
		@Override
		public Dialog	onCreateDialog(Bundle savedInstanceState)
		{
			AlertDialog.Builder		builder = new AlertDialog.Builder(getActivity());

			builder.setMessage("アプリを終了しますか");
			builder.setPositiveButton("終了",
				new DialogInterface.OnClickListener()
				{
					@Override
					public void		onClick(DialogInterface dialog, int which)
					{
						key_status = KEY_YES;
					}
				});
			builder.setNegativeButton("キャンセル",
				new DialogInterface.OnClickListener()
				{
					@Override
					public void		onClick(DialogInterface dialog, int which)
					{
						key_status = KEY_NO;
					}
				});

			return	builder.create();
		}
	}
}

/***************** End of File ***************************************************/

java側で独自の処理があるので、BaseActivityを継承した AppActivityを作成しています。
nativeから open_dialog()を呼んでダイアログを表示します。

ExitDialogFragmentが使用するダイアログのクラスです。
ボタンを押したときは key_statusに値を入れて BaseActivityの処理で native側に送っています。


AppMain.cpp
/************************
    終了確認ダイアログ
 ************************/
static
void	open_dialog(void)
{
	JNIEnv*		env;
	Bool		attach_flag = FALSE;

	if ( sys::g_JavaVM->GetEnv((void**)&env, JNI_VERSION_1_6) < 0 ) {
		if ( sys::g_JavaVM->AttachCurrentThread(&env, NULL) < 0 ) {
			return;
		}
		attach_flag = TRUE;
	}

	jclass	clazz = env->FindClass("app/AppActivity");

	if ( clazz ) {
		jmethodID	mid = env->GetStaticMethodID(clazz, "open_dialog", "()V");

		if ( mid ) {
			env->CallStaticVoidMethod(clazz, mid);
		}
	}
	if ( attach_flag ) {
		sys::g_JavaVM->DetachCurrentThread();
	}
}

/******************************
    稼働
		戻り値	アプリ続行か
 ******************************/
Bool	update_app(void)
{
	switch ( phase ) {
	  case PHASE_MAIN :				// メイン
		cnt++;
		if ( sys::key_status == sys::KEY_BACK ) {		// バックキー
			open_dialog();								// 終了確認ダイアログ
			phase = PHASE_DIALOG;
		}
		break;

	  case PHASE_DIALOG :			// 終了確認ダイアログ
		switch ( sys::key_status ) {
		  case sys::KEY_YES :
			sys::Renderer::fade_out(60);
			end_cnt = 60;
			phase = PHASE_EXIT;
			break;

		  case sys::KEY_NO :
			phase = PHASE_MAIN;
			break;
		}
		break;

	  case PHASE_EXIT :				// 終了
		if ( --end_cnt == 0 ) {
			return	FALSE;								// アプリ終了
		}
		break;
	}


	sprite[SPR_PHOTO].draw(0.0f, 0.0f);					// 背景
	for (int i = 0; i < 4; i++) {						// ビー玉
		int		t = ((cnt + i*15) % 60) - 30;

		sprite[SPR_BALL_BLUE + i].draw(((i*180 + cnt*4) % 720) - 360, 400 - (30*30 - t*t)/2);
	}

	return	TRUE;
}

native側のサンプルです。
バックキーを押すと、ダイアログを表示するようになっています。


ダイアログ


プロジェクト一式は、こちらです。