さてテストプレイ編で課題がいくつかあがったので、それらの対策をしていきたいと思います
まずはじめにあがった
1.一番大事な操作感、すべてが小さくて、ちまちましてイライラする
というところ、 ゲームにとって操作は生命線です
操作するだけで楽しい、うまくいくと気持ちがいいという感覚
そういった操作感がゲームの面白さに直結するため非常に重要なところ
今回原因はすべてが小さいところに起因するわけなんで、単純に大きくしてやろうと考えました
グリップを表示して引っ張って放してシュートという方式は直感的でいいのですが、グリップの分どうしても引きしろ範囲を大きくとらねばなりません
なので思い切ってグリップを廃止、画面全体を操作対象にしました
全体的にかなり大きくなったので、操作感は大分良くなりました
ただグリップ式よりも方向が決めにくくなった感があるのでガイドなど表示する必要があるかも
2014年3月6日木曜日
2014年3月3日月曜日
新作Androidアプリ開発 テストプレイ編 作りたいから作った結果がこれ・・・
さて一通りの動きは実装したのでここらでざっくりとテストプレイをしてみたいと思います
本当は誰かほかの人に頼んで意見や感想をもらったりしたほうがいいのでしょうが、なかなか難しいので自分で心を鬼にして厳しいユーザー視点に立ってプレイします
ここでアプリのコンセプト、方向性、課題を厳しくチェックします
んークソゲーか?
見た感じのしょぼさはまだ仮画像なんでおいといて・・・
ゲームとしてどうなのこれ、成り立ってるのか!?
誰だよこの企画を作ったやつは?オレカ・・・しかもこんなことまで言っている
http://anadreline.blogspot.com/2014/02/blog-post.html
>もしこれが企業での企画なら絶対通らないでしょう
>今更バスケットのシュートゲームかよと一蹴されて終わる
>しかしここが個人開発者の最高なところ
>作りたいから作るのです
作りたいから作った結果がこれか・・・
いやしかしそうだ、作りたいんだった、脳内企画ではもっと面白かったはず
まだどうにかする余地はきっとあると思う
とりあえず現状の問題点を挙げよう
残念ながらこのままリリースへ向かえるような状態ではない
とりあえずこれらに対して何かしらの解決策を見出して、根本的にてこ入れを行う必要がある
はあ・・・ゲーム作りって難しいですね
本当は誰かほかの人に頼んで意見や感想をもらったりしたほうがいいのでしょうが、なかなか難しいので自分で心を鬼にして厳しいユーザー視点に立ってプレイします
ここでアプリのコンセプト、方向性、課題を厳しくチェックします
んー
見た感じのしょぼさはまだ仮画像なんでおいといて・・・
ゲームとしてどうなのこれ、成り立ってるのか!?
誰だよこの企画を作ったやつは?オレカ・・・しかもこんなことまで言っている
http://anadreline.blogspot.com/2014/02/blog-post.html
>もしこれが企業での企画なら絶対通らないでしょう
>今更バスケットのシュートゲームかよと一蹴されて終わる
>しかしここが個人開発者の最高なところ
>作りたいから作るのです
作りたいから作った結果がこれか・・・
いやしかしそうだ、作りたいんだった、脳内企画ではもっと面白かったはず
まだどうにかする余地はきっとあると思う
とりあえず現状の問題点を挙げよう
- 一番大事な操作感、すべてが小さくて、ちまちましてイライラする
- ボールの動きがわかりにくい、特に高低差、ゴールしたのかどうか、たまに変な挙動
- 60秒で何ゴールできるかというルールではスコアの頭打ちが早いのではないか
- 何度もやりたくなる気がおきない
残念ながらこのままリリースへ向かえるような状態ではない
とりあえずこれらに対して何かしらの解決策を見出して、根本的にてこ入れを行う必要がある
はあ・・・ゲーム作りって難しいですね
2014年2月28日金曜日
消えそうなアプリがアプリ名変更で大復活! EasyBowlingが5万ダウンロード突破!
2012年に公開したEasyBowlingですが、2013年の3月頃をピークに有効インストールは下がり続けてあとはただ消えゆくのみという状態でした
ある時ふと、GooglePlayの検索時「Bowling 」での検索順位がちょっと低いなぁと感じ、2013年の末にアプリ名を"EasyBowling"から"Easy Bowling"と間にスペースを入れたものに変更してみることにしました
するとびっくり!今まで「Bowling 」での検索100位にも入っていなかったEasyBowlingがいっきに25位になりました
その後インストールが一気に伸びて50000ダウンロードを達成
やはりアプリ名は非常に大事というお話ですね
アプリ名変更前は1日のダウンロード数は50以下程度でしたが、変更後はだいたい200くらいに上昇しました
EasyBowlingの無料スポーツゲームカテゴリでのランクは現在350位くらいなのでランキングからの流入はほとんど見込めません
それでも200ダウンロード/日の自然流入があるというのは、検索からの流入が効いているということかと思います
ある時ふと、GooglePlayの検索時「Bowling 」での検索順位がちょっと低いなぁと感じ、2013年の末にアプリ名を"EasyBowling"から"Easy Bowling"と間にスペースを入れたものに変更してみることにしました
するとびっくり!今まで「Bowling 」での検索100位にも入っていなかったEasyBowlingがいっきに25位になりました
その後インストールが一気に伸びて50000ダウンロードを達成
やはりアプリ名は非常に大事というお話ですね
アプリ名変更前は1日のダウンロード数は50以下程度でしたが、変更後はだいたい200くらいに上昇しました
EasyBowlingの無料スポーツゲームカテゴリでのランクは現在350位くらいなのでランキングからの流入はほとんど見込めません
それでも200ダウンロード/日の自然流入があるというのは、検索からの流入が効いているということかと思います
2014年2月26日水曜日
新作Androidアプリ開発 ボールをランダムに配置しよう編
ボールを操作で投げれるようになったので、今回はボールを任意のエリアにランダムに配置してみましょう
配置したいエリアはというと、距離的にフリースローからスリーポイントまでの間にあたる扇状の青の部分です
操作の都合上、リングの左右側の鋭角を10°程削っています
これをどう計算してランダムな座標を生成するか
もし対象とするエリアが長方形だったりすると話は簡単です
XとY軸の対象範囲をRandom.nextInt(value)するだけ
気持ち悪いですね
今回は変形扇形のエリアではいろいろと方法はあると思いますが、このような考え方で生成しました
赤枠部分フリースローラインからスリーポイントラインまでの範囲でランダムにセットした座標を、対象範囲角をランダムにセットして回転する
ソースとしてはこのような感じ
よさそうです
配置したいエリアはというと、距離的にフリースローからスリーポイントまでの間にあたる扇状の青の部分です
操作の都合上、リングの左右側の鋭角を10°程削っています
これをどう計算してランダムな座標を生成するか
もし対象とするエリアが長方形だったりすると話は簡単です
XとY軸の対象範囲をRandom.nextInt(value)するだけ
Rect area = new Rect(100, 100, 400, 300); Random random =new Random(); int x = area.left + random.nextInt(area.width()); int y = area.top + random.nextInt(area.height());試しに1000個ほど生成して描画してみましょう
Rect area = new Rect(100, 100, 400, 300);
canvas.drawRect(area, paint);
Random random =new Random();
for (int i = 0; i < 1000; i++) {
int x = area.left + random.nextInt(area.width());
int y = area.top + random.nextInt(area.height());
canvas.drawCircle(x, y, 3f, paint);
}
なんか今回は変形扇形のエリアではいろいろと方法はあると思いますが、このような考え方で生成しました
赤枠部分フリースローラインからスリーポイントラインまでの範囲でランダムにセットした座標を、対象範囲角をランダムにセットして回転する
ソースとしてはこのような感じ
Random random =new Random();
Plot ring = new Plot(7500, 1882);
for (int i = 0; i < 1000; i++) {
//リングX座標+フリースローラインまでの距離(4.118m)+フリースローラインからスリーポイントラインの間(2.52m)の間のランダム値
Plot base = new Plot(ring.x + 4118 + ((2520 * random.nextInt(100)) / 100), ring.y);
//削った10度+配置部分160°のランダム値
int angle = 10 + random.nextInt(160);
//回転処理
Plot pos = Utl.rotate(angle, ring, base);
//描画座標変換
pos = Court.getDPlot(pos);
canvas.drawCircle(pos.x, pos.y, 3f, paint);
}
試しに1000個ほど生成して描画よさそうです
2014年2月21日金曜日
2014年2月18日火曜日
新作Androidアプリ開発 ボールを操作で投げる編
投げたボールの処理が代替できたので、次にユーザーの操作でボールを投げるところを作ります
操作手法はこんな感じ
いわゆるAngryBird投射法です
処理の考え方としては引っ張り長さに制限をつけて、引っ張っていない時を0、最大まで引っ張った時を100として初速度を計算します
\times\frac{d}{dm})
v0:初速度
d:引っ張り長さ
dm:最大引っ張り長さ
min:引っ張り0の時の速度
max:引っ張り100の時の速度
式は簡単ですが、minとmaxの値は初速度を決めるパラメータ、つまりはゲームバランスに繋がるのでテストと調整が非常に重要になります
あとは引っ張ったところからボール初期位置への角度を水平方向の投射角として
新作アプリ開発 ボールを投げてみる編で作ったshot関数
に投げてやれば完成
操作手法はこんな感じ
いわゆるAngryBird投射法です
処理の考え方としては引っ張り長さに制限をつけて、引っ張っていない時を0、最大まで引っ張った時を100として初速度を計算します
v0:初速度
d:引っ張り長さ
dm:最大引っ張り長さ
min:引っ張り0の時の速度
max:引っ張り100の時の速度
式は簡単ですが、minとmaxの値は初速度を決めるパラメータ、つまりはゲームバランスに繋がるのでテストと調整が非常に重要になります
あとは引っ張ったところからボール初期位置への角度を水平方向の投射角として
新作アプリ開発 ボールを投げてみる編で作ったshot関数
public void shot(double speed, double vangle, double hangle)に投げてやれば完成
2014年2月15日土曜日
新作Androidアプリ開発 ボールの跳ね返り リング編
前回ボールの跳ね返りをやりました
残るはリングとの衝突と跳ね返り処理です
これはかなり悩みました、3日ほど悩んでむりくりひねり出した結論ですが
※以下の考え方は物理的に正しいかどうかは不明です※
まず例としてこんなボールとリングの衝突と跳ね返りがあるとします
ごく当たり前の跳ね返りですが、これをどうプログラムで計算するのか?
とりあえず衝突点を求めます
そしてリングの断面の中心とボールの中心点を結んで衝突面の法線ベクトルを求めます
その衝突法線ベクトルが作る面に対しての3次元速度ベクトルの反射処理と考えました
この考え方を元にまずボールの移動前、移動後の位置を与えてリング当たっていれば衝突位置を返すメソッドを作成します
このメソッドをボールの移動処理にはさみます
試したところやや動きが怪しいところがありますが、基本方針としてはよさそう
残るはリングとの衝突と跳ね返り処理です
これはかなり悩みました、3日ほど悩んでむりくりひねり出した結論ですが
※以下の考え方は物理的に正しいかどうかは不明です※
まず例としてこんなボールとリングの衝突と跳ね返りがあるとします
ごく当たり前の跳ね返りですが、これをどうプログラムで計算するのか?
とりあえず衝突点を求めます
そしてリングの断面の中心とボールの中心点を結んで衝突面の法線ベクトルを求めます
その衝突法線ベクトルが作る面に対しての3次元速度ベクトルの反射処理と考えました
この考え方を元にまずボールの移動前、移動後の位置を与えてリング当たっていれば衝突位置を返すメソッドを作成します
//リングとの衝突判定関数
public static Plot hitRing(Plot prev, Plot move) {
Plot ret = null;
//大雑把な判定条件として落下方向への移動、移動のZ座標がリング高さをまたがっている
if (move.z < prev.z && move.z - Ball.R <= RING_H && prev.z - (Ball.R / 2) > RING_H) {
int r = (int)((((prev.z - Ball.R) - RING_H) * 100) / (prev.z - move.z));
//ボール下面がリング高さに来る位置取得
Plot pos = Utl.getPlotInLine(r, prev, move);
//リング中央との距離取得
int d = Utl.getDistancePtoP(RING_CENTER, new Plot(pos.x, pos.y));
//リングに当たりそうな距離にあればさらに詳しく判定
if (d > (RING_R - Ball.R) && d <= RING_R + Ball.R) {
float dagl = Utl.getRadians(Court.RING_CENTER, pos);
int dx = (int)(Court.RING_CENTER.x + Court.RING_R * (Math.cos(dagl)));
int dy = (int)(Court.RING_CENTER.y + Court.RING_R * (Math.sin(dagl)));
int bw = Utl.getDistancePtoP(new Plot(dx, dy), new Plot(pos.x, pos.y));
int bz = (int)(Ball.R * Math.sin(Math.acos((double)(Ball.R - bw) / (double)Ball.R)));
r = (int)(((prev.z - (pos.z - bz)) * 100) / (prev.z - move.z));
//実際にリングに当たる位置取得
pos = Utl.getPlotInLine(r, prev, move);
//リング中央との距離取得
d = Utl.getDistancePtoP(Court.RING_CENTER, new Plot(pos.x, pos.y));
//取得した距離からリングに当たるかどうか判定
if (d > (Court.RING_R - Ball.R) && d <= Court.RING_R + Ball.R) {
ret = new Plot(pos);
}
}
}
return ret;
}
こんな感じこのメソッドをボールの移動処理にはさみます
Plot hr = hitRing(prev, move);
if (hr != null) {
//法線ベクトル取得
float angle = Utl.getRadians(Court.RING_CENTER, hr);
int dx = (int)(Court.RING_CENTER.x + Court.RING_R * (Math.cos(angle)));
int dy = (int)(Court.RING_CENTER.y + Court.RING_R * (Math.sin(angle)));
//衝突時の速度ベクトルと法線ベクトルの内積を計算
float ip = Utl.getInnerProduct(new Plot(xSpeed, ySpeed, zSpeed), new Plot(hr.x - dx, hr.y - dy, hr.z - Court.RING_H));
//内積が+のときは裏からの当たりなので処理しない
if (ip < 0) {
//速度ベクトルの跳ね返り後の速度を取得
Plot dv = getReflect(new Plot(xSpeed, ySpeed, zSpeed), new Plot(hr.x - dx, hr.y - dy, hr.z - Court.RING_H));
float dk = 0.6f;
//反発係数dkを速度にかける
xSpeed = (int)(dv.x * dk);
ySpeed = (int)(dv.y * dk);
zSpeed = (int)(dv.z * dk);
//衝突後の経過時間を計算
int citv = (int)((interval * Utl.getDistancePtoP(hr, move)) / Utl.getDistancePtoP(prev, move));
//移動後の位置を変更速度から再計算
move.x = (int)(hr.x + ((xSpeed * citv) / 1000));
move.y = (int)(hr.y + ((ySpeed * citv) / 1000));
move.z = (int)(hr.z + ((zSpeed * citv) / 1000));
prev = new Plot(hr);
}
}
こんな感じ、いろいろと処理がひどいですが見ないでやってください(良い子はまねしちゃダメ)試したところやや動きが怪しいところがありますが、基本方針としてはよさそう
登録:
投稿 (Atom)











