ねこマタ審査通りました。
2016/12/15 23:52 Waiting For Review
2016/12/19 00:10 In Review
2016/12/19 00:20 Pending Developer Release
申請から約3日ほどで通りました。
審査時間は 10分! だったようです。
“3日坊主のアプリ開発日記” を始めてからほぼ1年での完成となりました。
12/24(土)のお昼頃からアプリストアに並ぶ予定です。
∩∩
(´・ω・)
_| ⊃/(___
/ └-(____/
 ̄ ̄ ̄ ̄ ̄ ̄ ̄
今日は以下を行いました。
・各対人ステージの対人戦歴を参照する機能(履歴取得時、サーバ負荷を減らすため、古い対戦履歴を削除)
・その他、数え切れないほどのバグ修正
もうリリース出来る完成度になったと思います!!!
細かい気になる点はいっぱいありますが・・・
さらに完成度を高めるため、次回は
・対人ステージのバリエーション増加
を行っていきたいと思います。
あとは、アプリの価格をどうするか決めたいと思います。
有料アプリにするか、無料にしてアプリ内課金にするかなどです。
開発期間をかなり長く取ったアプリなので、価格はどうしようか本当に迷います。
価格決めるのにあと1年位かかりそうです。
対人ステージのバリエーション増加
∩∩
(´・ω・)
_| ⊃/(___
/ └-(____/
 ̄ ̄ ̄ ̄ ̄ ̄ ̄
今日は以下項目の実装をしました。
・対人戦の勝者に経験値とロジックパネルを加算する処理
・実装中止:対人戦で特定条件を満たしたユーザに特別なロジックパネルをプレゼントする処理
特別なロジックパネルをプレゼントする処理は実装を中止することとしました。
理由としては、めんどくさいからですいろんなロジックパネルを工夫して組み合わせることでキャラを強く出来ることをゲームの大きな特徴としたいので、やたら強い特別なロジックパネルというのは、そこからずれると思ったからです。
残作業は以下となります。
・各対人ステージの対人戦歴を参照する機能(履歴取得時、サーバ負荷を減らすため、古い対戦履歴を削除)
・対人ステージのバリエーション増加
・サーバ負荷を抑えるため、対人戦は1日に特定回数までに抑制する。
各対人ステージの対人戦歴を参照する機能(履歴取得時、サーバ負荷を減らすため、古い対戦履歴を削除)
∩∩
(´・ω・)
_| ⊃/(___
/ └-(____/
 ̄ ̄ ̄ ̄ ̄ ̄ ̄
(´・ω・`)ショボーン
今日は以下項目の実装をしました。
・対人戦の勝敗確定前処理の調整
・サーバの負荷を減らすため、例えば5分以内に再度サーバアクセスがあったら、前回のキャッシュを使うなどの工夫。
残作業は以下となります。
・対人戦の勝者に経験値とロジックパネルを加算する処理 ※9割方完成
・各対人ステージの対人戦歴を参照する機能(履歴取得時、サーバ負荷を減らすため、古い対戦履歴を削除)
・対人ステージのバリエーション増加
・サーバ負荷を抑えるため、対人戦は1日に特定回数までに抑制する。[NEW!]
・対人戦で特定条件を満たしたユーザに特別なロジックパネルをプレゼントする処理 ※バランス崩壊するから中止するかも
1項目増えました!
作業終えても終えても追加実装したい内容が出てきて終わりません・・・
(´・ω・`)ショボーン
対人戦の勝者に経験値とロジックパネルを加算する処理
∩∩
(´・ω・)
_| ⊃/(___
/ └-(____/
 ̄ ̄ ̄ ̄ ̄ ̄ ̄
対人戦の調整
もうCATAMAのアプリ開発日記つけ始めてから、254日経ったんだな・・・長くかかったな・・・
今回は、対人戦に関していろいろ作業をしていました。バグから、対人バランス調整から、本当にいろいろ作業していました。
もう一息で完成する気配がそこはかとなくしている段階です。本当だってば!
残作業は以下となります。
・対人戦の勝敗確定前処理の調整
・サーバの負荷を減らすため、例えば5分以内に再度サーバアクセスがあったら、前回のキャッシュを使うなどの工夫。
・対人戦の勝者に経験値とロジックパネルを加算する処理 ※9割方完成
・各対人ステージの対人戦歴を参照する機能(履歴取得時、サーバ負荷を減らすため、古い対戦履歴を削除)
・対人ステージのバリエーション増加
・対人戦で特定条件を満たしたユーザに特別なロジックパネルをプレゼントする処理 ※バランス崩壊するから中止するかも
まだ結構あるな・・・
対人戦の作業
∩∩
(´・ω・)
_| ⊃/(___
/ └-(____/
 ̄ ̄ ̄ ̄ ̄ ̄ ̄
対人戦の実装
今回は
・各対人スデージに支配者情報を初期登録する処理
・対人戦で相手のロジックパネルを見えないようにマスクする処理
・”ID”がばれるとデータを乗っ取られてしまうので、IDを他の人に見せないように注意書きをする
・対戦相手のレベルを表示
を行いました。
残作業は以下となります。
・対人戦の対戦内容と勝敗結果をサーバに格納 完了
・対人戦の勝者に経験値とロジックパネルを加算する処理
・対人戦で特定条件を満たしたユーザに特別なロジックパネルを加算する処理
・各対人ステージの対人戦歴を参照する機能
・サーバの負荷を減らすため、例えば5分以内に再度サーバアクセスがあったら、前回のキャッシュを使うなどの工夫。
・サーバの負荷を減らすため、古い対戦履歴を定期削除
・対人戦の勝敗確定前処理の調整 9/3 追加
・対人ステージのバリエーション増加 9/3 追加
9/3追記 いろいろ足りない処理に気づいて、作業増やしました。バグも随時修正しています。中々減らない・・・
対人戦の対戦内容と勝敗結果をサーバに格納
∩∩
(´・ω・)
_| ⊃/(___
/ └-(____/
 ̄ ̄ ̄ ̄ ̄ ̄ ̄
夏休み
私の一番の休息は、アプリを開発することです。
というわけで、夏休みはアプリを開発して遊びました。会社爆発しないかなぁ。
今回は、対人戦のステージ情報を格納するサーバサイドのDB実装と、そのDBを読み取り、クライアントであるiOSアプリに読み込む処理を作っていました。
残り作業は以下となります。もうスタンドアローンとしては完成しているアプリですが、もう一息で対人戦も含めて実装してリリース出来そうです。
・対人戦の勝敗結果と勝者の情報をサーバサイドに格納
・対人戦での相手のロジックパネルを見えないようにマスクする処理
・対人戦の勝者に経験値と相手のロジックパネルを加算する処理、敗者は奪われる処理
・対人戦で特定条件を満たしたユーザに特別なロジックパネルを加算する処理
・各対人ステージの対人戦歴を参照する機能
・”ID”がばれるとデータを乗っ取られてしまうので、IDを他の人に見せないように注意書きをする
・対戦相手のレベルを表示
・サーバの負荷を減らすため、例えば5分以内に再度サーバアクセスがあったら、前回のキャッシュを使うなどの工夫。
対人戦の勝敗結果と勝者の情報をサーバサイドに格納
∩∩
(´・ω・)
_| ⊃/(___
/ └-(____/
 ̄ ̄ ̄ ̄ ̄ ̄ ̄
セーブ/ロード機能の実装
クラウドでのセーブ/ロード機能を実装しました。
AppleのiCloudではなく、独自サーバ上(さくらのVPS)に実装しています。
もちろん、クライアント(objective-c)の開発と共に、サーバ側のサーブレット(java)やユーザテーブル(Mysql)の作成も同時に行いました。
画像の「Change ID」ボタンは、スマホを買い替えた場合などデータを端末間で移動する場合に使用します。元の端末で表示されているIDを、新しい端末で「Change ID」ボタンにより入力すると、データが引き継げます。
iPadにも対応予定のゲームですが、iPhoneやiPad間でIDを同じに設定しておけば、どちらでも同じデータで遊ぶような使い方も可能です。
素晴らしい!
長いIDを入力しなきゃならないこと以外は!!
ID長い方が、何か有り難みがあるよね。うん。だから長くても大丈夫。
対人戦画面の実装
∩∩
(´・ω・)
_| ⊃/(___
/ └-(____/
 ̄ ̄ ̄ ̄ ̄ ̄ ̄
DB接続管理クラスの作成
sql投げるだけで実行してくれるメソッドを持つクラスを作成しました。
コネクションを意識せずに使えるタイプと、自分でコネクションを渡せる2タイプを用意しました。
例外発生時のロギングには、昨日作成した自作クラスを使っています。
使うとき意味なくインスタンス化する必要あるし、ResultSet呼び出し元でcloseしなきゃいけないし、いまいちなので、もうちょっと改造します。
package servlet;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.ResultSet;
import java.sql.Statement;
import servlet.Logging;
public class DBManager {
Connection getConn() {
Connection conn = null;
try {
Class.forName(“com.mysql.jdbc.Driver”);
// MySQLに接続
conn = DriverManager.getConnection(“jdbc:mysql://localhost:3306/catama”, “user”, “password”);
} catch (ClassNotFoundException | SQLException e) {
Logging.out(e);
}
return conn;
}
void releaseConn(Connection conn) {
if (null == conn) {
Logging.out(“connection is null.”);
return;
}
try {
conn.close();
} catch (SQLException e) {
Logging.out(e);
}
}
ResultSet query(String sql) {
Connection conn = null;
ResultSet rs = null;
try {
conn = this.getConn();
rs = this.query(sql, conn);
} finally {
releaseConn(conn);
}
return rs;
}
ResultSet query(String sql, Connection conn) {
if (null == conn) {
Logging.out(“connection is null.”);
return null;
}
ResultSet rs = null;
Statement st = null;
try {
st = conn.createStatement();
rs = st.executeQuery(sql);
} catch(SQLException e) {
Logging.out(e);
} finally {
if (null != st) {
try {
st.close();
} catch (SQLException e) {
Logging.out(e);
}
}
}
return rs;
}
int queryExec(String sql) {
int result = -1;
Connection conn = null;
try {
conn = this.getConn();
result = this.queryExec(sql, conn);
} finally {
releaseConn(conn);
}
return result;
}
int queryExec(String sql, Connection conn) {
int result = -1;
if (null == conn) {
Logging.out(“connection is null.”);
return result;
}
Statement st = null;
try {
st = conn.createStatement();
result = st.executeUpdate(sql);
} catch (SQLException e) {
Logging.out(e);
} finally {
if (null != st) {
try {
st.close();
} catch (SQLException e) {
Logging.out(e);
}
}
}
return result;
}
}
サーバにログインする処理を実装する。サーバに各ユーザの識別ID※とユーザ名を格納する。
※appleの推奨するidentifierForVendor(IDFV)を識別IDとして使います。
∩∩
(´・ω・)
_| ⊃/(___
/ └-(____/
 ̄ ̄ ̄ ̄ ̄ ̄ ̄
ロギングクラスの作成
スタックトレースやクラス名/メソッド名/エラー発生行番号を記録してくれるロギングクラスを作っていました。
package servlet;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Logging {
static void out(Exception e) {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy/MM/dd HH:mm:ss”);
System.out.println(“— ” + sdf.format(date) + ” —“);
e.printStackTrace();
System.out.println(“— ” + sdf.format(date) + ” —“);
}
static void out(String msg) {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy/MM/dd HH:mm:ss”);
StackTraceElement throwableStackTraceElement = new Throwable().getStackTrace()[1];
System.out.println(“— ” + sdf.format(date) + ” —“);
System.out.println(msg + “at ” + throwableStackTraceElement.getClassName() + “#” + throwableStackTraceElement.getMethodName() + “(” + throwableStackTraceElement.getLineNumber() + “)”);
System.out.println(“— ” + sdf.format(date) + ” —“);
}
}
outメソッドに例外を渡すと、
— 2016/07/19 23:29:41 —
java.sql.SQLException: Field ‘prize_panels’ doesn’t have a default value
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:963)
〜略〜
at servlet.DBManager.queryExec(DBManager.java:96)
at servlet.DBManager.queryExec(DBManager.java:79)
at servlet.Login.doGet(Login.java:38)
〜略〜
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
— 2016/07/19 23:29:41 —
のように、日時とスタックトレースを出力します。
outメソッドに文字(エラーが発生しましたよ)を渡すと
— 2016/07/19 23:29:41 —
エラーが発生しましたよ at servlet.DBManager#getConn(13)
— 2016/07/19 23:29:41 —
のように、日時と発生クラス名/メソッド名/行番号を出力します。
メソッドの中身を書き換えて”コンパイル”すれば、120%自由自在にカスタマイズできます。
シンプル!簡単!分かり易い!
え?commons-loggingとかlog4jとかslf4j-apiとかjcl-over-slf4jとかlogback-classicとか使え?
“設定”覚えるのがめんどいんで結構です。
サーバにログインする処理を実装する。サーバに各ユーザの識別ID※とユーザ名を格納する。
※appleの推奨するidentifierForVendor(IDFV)を識別IDとして使います。