ページ 1 / 1
androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月21日(日) 11:30
by mi_l
毎回お世話になっております。
今回の質問は少し前の質問に機能を追加したくて、というものです。
前の質問
そこでは、画像を表示するところまで要ったのですが、その次に私はこの画像(障害物)を移動させてみようと考えました。
そこで、どうやればいいか考えていると、回転のクラスを参考にして作ればいいのではないかと思いました。
(ここでの質問は上記「前の質問」の追加として書きますのでそちらを見なければ意味不明だと思います。手間をかけさせるやり方で申し訳ありません。)
とりあえず、前回の質問同様、やりたいことを書きます。
1、まず移動パターンを何個か作りそれぞれにIDでもつける
(例)まっすぐ下に降りてくるだけ→TypeA
2、最後の「_barrList.add(new BarricadeSquare( xx , yy,100, 100, null , bits));// 画面4隅に四角形を配置」の最後にBConfと同じ形(null or new ・・・)で追加したらその障害物がその動きをする。
参考にしたBConf.java
コード:
package net.dixq.irairabar;
public class BConf {
public float speed = 0;//回転のスピード
public Barricade.eType type = Barricade.eType.OUT;
public BConf(Barricade.eType atype){
type = atype;
}
public BConf(float aspeed){
speed = aspeed;
}
}
私が作ったBMove.java
コード:
package net.dixq.irairabar;
public class BMove
{
public int MoveType = 0;//移動パターン
public Barricade.eType type = Barricade.eType.OUT;//タイプ(当たってはいけない)
public BMove(Barricade.eType atype)
{
type = atype;
}
public BMove(int mType)
{
MoveType = mType;
}
}
参考にしたDiagramCalcr.java
コード:
package net.dixq.irairabar;
import android.graphics.PointF;
public class DiagramCalcr {
// centerを中心に角度ang、頂点群ptを回転する
public static void RotateDiagram(PointF pt[], final PointF center, final float ang) {
for (int i = 0; i < pt.length; i++) {
RotatePt(pt[i], center, ang);
}
}
// rotaPtを中心に角度ang、origPtを回転する
public static void RotatePt(PointF rotaPt, final PointF origPt, final float ang) {
float cx = origPt.x;
float cy = origPt.y;
float x = rotaPt.x;
float y = rotaPt.y;
rotaPt.x = (float) (cx + Math.cos(ang) * (x - cx) - Math.sin(ang) * (y - cy));
rotaPt.y = (float) (cy + Math.sin(ang) * (x - cx) + Math.cos(ang) * (y - cy));
}
// 頂点群ptの線分とcirが接触していたらその接触しているベクトルをverに格納してtrueを返す
public static boolean isHit(PointF pt[], final Circle cir, Vec vec) {
if (pt.length < 2) { // 線でなければ
return false;
}
int len = pt.length;
for (int i = 1; i <= len; i++) {//例えば線分0-1,1-2,2-3,3-0とループさせてつなげる為%を使用してループ
Line line = new Line(pt[i - 1].x, pt[i - 1].y, pt[i % len].x, pt[i % len].y);
if (isHitLC(line, cir) == true) {//接触していれば
vec._x= pt[i % len].x - pt[i - 1].x;//その線分のベクトルを格納する
vec._y= pt[i % len].y - pt[i - 1].y;
return true;
}
}
return false;
}
//線分lineと円cirが当たっていればtrueを返す
public static boolean isHitLC(Line L,Circle C){
// 円と線分の当たり判定関数
if((L._sx*(C._x-L._x) + L._sy*(C._y-L._y)) <= 0){
// 始点を通る、線分に垂直な線を置いたとき、円の中心が線分の範囲外にあったとき
// 「線分の始点から円の中心までの距離の2乗」と「円の半径の2乗」との比較
return (C._r*C._r >= (C._x-L._x)*(C._x-L._x)+(C._y-L._y)*(C._y-L._y));
} else if(((-L._sx)*(C._x-(L._x+L._sx)) + (-L._sy)*(C._y-(L._y+L._sy))) <= 0){
// 終点を通る、線分に垂直な線を置いたとき、円の中心が線分の範囲外にあったとき
// 「線分の終点から円の中心までの距離の2乗」と「円の半径の2乗」との比較
return (C._r*C._r >= (C._x-(L._x+L._sx))*(C._x-(L._x+L._sx))+(C._y-(L._y+L._sy))*(C._y-(L._y+L._sy)));
} else {
// 線分の始点終点に垂線を引っ張ったとき、円の中心がその範囲内にあったとき
float e = (float) Math.sqrt(L._sx*L._sx + L._sy*L._sy); // これでx,y成分を割れば単ベクトルになる
float c2 = (C._x-L._x)*(C._x-L._x)+(C._y-L._y)*(C._y-L._y);
float b = (C._x-L._x)*(L._sx/e)+(C._y-L._y)*(L._sy/e); // 内積で算出した、隣辺の長さ
return (C._r*C._r >= c2 - b*b);
}
}
}
自分で作ったMoveStyle.java
(ここがわかりません・・・)
コード:
package net.dixq.irairabar;
import android.graphics.PointF;
public class MoveStyle
{
private int process = 0;//竜神録のようにcase文を使いたいため
//「Aスタイル」centerを中心に「下に降りてきて一定位置までいくと右に移動」
public static void MoveAType(PointF pt[] , final PointF center)
{
}
}
前の質問からそのまま、
Barricade.java
(28行目のコンストラクタに「BMove move」とでも付け足します。)
コード:
package net.dixq.irairabar;
import android.graphics.Bitmap;//追加
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;//追加
import android.graphics.PointF;
import android.graphics.RectF;//追加
public class Barricade extends Task {
public enum eType{
OUT,
GOAL
}
protected PointF _center = new PointF(0,0); //図形の中心点
protected PointF _pt[]; //図形の頂点
protected Paint _paint = new Paint(); //ペイント
protected eType _type = eType.OUT; //タイプ(当たるとアウトな壁、ゴールの壁、等)
protected float _rotaSpeed = 0; //回転スピード
protected Bitmap bit;
//protected int images;//参照を保持するインスタンス変数(何型の変数?)
//コンストラクタ。 type=タイプ、 n=頂点の数、 conf=設定情報
public Barricade(int n, BConf conf,Bitmap img)
{
bit = img;//格納(記録);
if( conf != null ){
_rotaSpeed = conf.speed; //回転スピード
_type = conf.type; //物体のタイプ
}
switch(_type){
case OUT: //接触してアウトな物
_paint.setColor(Color.RED);
break;
case GOAL: //接触してゴールな物
_paint.setColor(Color.GREEN);
break;
}
_pt = new PointF[n]; //頂点配列を作る
for( int i=0; i<n; i++ ){
_pt[i] = new PointF(); //頂点を作る
}
_paint.setAntiAlias(true);
}
public Barricade(int n , BConf conf)
{
this(n , conf , null);
}
//更新する
public boolean onUpdate(){
if( _rotaSpeed != 0 ){ //回転するなら
DiagramCalcr.RotateDiagram( _pt, _center, _rotaSpeed ); //頂点リスト(_pt)を_centerを中心に回転する
}
return true;
}
//接触しているかを問う。円cirが線分vecと接触していれば接触した物体のタイプを返す。接触していなければNOを返す
public Def.eHitCode isHit( final Circle cir, Vec vec ){
if( DiagramCalcr.isHit( _pt, cir, vec ) == true ){
switch(_type){
case OUT:
return Def.eHitCode.OUT;
case GOAL:
return Def.eHitCode.GOAL;
}
}
return Def.eHitCode.NO;
}
//描画する
public void onDraw(Canvas c)
{
//頂点が1未満の図形なんてないので
if( _pt.length < 1 )
{
return;//返す
}
if( bit == null )
{
Path path = new Path();//パス
path.moveTo(_pt[0].x, _pt[0].y); //パスの初期位置をセット
for( int i=0; i<_pt.length; i++ )
{
path.lineTo(_pt[i].x, _pt[i].y); //頂点の位置へラインを引いていく(軌跡を描いていく)
}
c.drawPath(path, _paint); //引いたラインを描画する
}
else
{
//画像は全体を使うと仮定
c.drawBitmap(bit, null, new RectF(_pt[0].x-10 , _pt[0].y-10 , _pt[2].x+10 , _pt[2].y+10 ), null);
}
}
最後にGameMgr.java
コード:
package net.dixq.irairabar;
import java.util.ArrayList;
import java.util.LinkedList;
import net.dixq.irairabar.Barricade.eType;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.annotation.SuppressLint;
import android.content.res.Resources;
import android.content.Context;
public class GameMgr {
private enum eStatus{
NORMAL,
GAMEOVER,
GAMECLEAR
};
private static final float PI = (float) Math.PI;
private ArrayList<Barricade> _barrList = new ArrayList<Barricade>();//障害物リスト
private LinkedList<Task> _taskList = new LinkedList<Task>();// タスクリスト
private eStatus _status = eStatus.NORMAL;
private Player _player;
private int xx = 50 , yy = 70;
GameMgr(Context con)
{
Resources res = con.getResources();
Bitmap bits = BitmapFactory.decodeResource(res, R.drawable.ic_launcher);
// _barrList.add(new BarricadeSquare( 20, 30, 700,800, null));
_barrList.add(new BarricadeSquare( xx , yy,100, 100, null , bits));// 画面4隅に四角形を配置
/*
_barrList.add(new BarricadeSquare(460, 0, 20,800, null));
_barrList.add(new BarricadeSquare( 0,780,480, 20, null));
_barrList.add(new BarricadeTriangle( 0, 0, 200, new BConf(+PI / 150),));// 左上回転する三角形
_barrList.add(new BarricadeTriangle(480, 0, 180, new BConf(+PI / 150)));// 右上回転する三角形
_barrList.add(new BarricadeStar(240, 240, 50, 200, new BConf(-PI / 360)));// 中央に回転する星
_barrList.add(new BarricadeStar(240, 240, 20, 80, new BConf(+PI / 360)));// 中央に回転する星
_barrList.add(new BarricadeSquare(300, 440, 200, 20, null));//右下の固定通路
_barrList.add(new BarricadeSquare(250, 520, 130, 20, null));//
_barrList.add(new BarricadeSquare(330, 620, 130, 20, null));//
_barrList.add(new BarricadeSquare(230, 390, 20, 350, null));//中央区切り線
_barrList.add(new BarricadeSquare(0, 480, 240, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare( 20, 600, 110, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare(130, 600, 110, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare(185, 600, 55, 20, new BConf(+PI / 360)));// 左下回転するバー
*/
// _barrList.add(new BarricadeSquare(20, 680, 80, 20, null));// ゴールに接触したバー
// _barrList.add(new BarricadeSquare(20, 700, 80, 80, new BConf(eType.GOAL)));// ゴール
for (Barricade bar : _barrList) {
_taskList.add(bar); //タスクリストに障害物を追加
}
_player = new Player();
_taskList.add(_player);
_taskList.add(new FpsController());
}
private boolean Collision(){
Vec vec = new Vec();
final Circle cir = _player.getPt();
for(Barricade barr : _barrList){
Def.eHitCode code = barr.isHit(cir, vec);
switch(code){
case OUT:
_status = eStatus.GAMEOVER;
return true;
case GOAL:
_status = eStatus.GAMECLEAR;
return true;
}
}
return false;
}
public boolean onUpdate()
{
if( _status != eStatus.NORMAL ){
return true;
}
if( Collision() ){
return true;
}
for (int i = 0; i < _taskList.size(); i++) {
if (_taskList.get(i).onUpdate() == false) { // 更新失敗なら
_taskList.remove(i); // そのタスクを消す
i--;
}
}
return true;
}
private void drawStatus(Canvas c){
switch( _status ){
case GAMEOVER:
{
Paint paint = new Paint();
paint.setTextSize(80);
paint.setColor(Color.BLACK);
c.drawText("GameOver", 40, 100, paint);
}
break;
case GAMECLEAR:
{
Paint paint = new Paint();
paint.setTextSize(80);
paint.setColor(Color.BLACK);
c.drawText("GameClear", 40, 100, paint);
}
break;
}
}
@SuppressLint("WrongCall")
public void onDraw(Canvas c)
{
//白く塗りつぶす
c.drawColor(Color.WHITE);
for (Task task : _taskList)
{
//描画
task.onDraw(c);
}
drawStatus(c);
}
}
一応、ここではBarricadeSquare.javaでしか考えませんので
(8行目のさいごに「BMove move」とでも追加します)
コード:
package net.dixq.irairabar;
import android.graphics.Bitmap;
public class BarricadeSquare extends Barricade {
public BarricadeSquare( float x, float y, float w, float h, BConf conf, Bitmap img ){
super(4,conf, img);
_pt[0].x = x; _pt[0].y = y;
_pt[1].x = x+w; _pt[1].y = y;
_pt[2].x = x+w; _pt[2].y = y+h;
_pt[3].x = x; _pt[3].y = y+h;
_center.x = x+w/2;
_center.y = y+h/2;
}
public BarricadeSquare( float x, float y, float w, float h, BConf conf)
{
this(x, y ,w, h, conf, null);
}
}
ご指摘や考え方などご教授お願いします。
よろしくお願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月21日(日) 18:47
by ISLe
BMoveはBConfの拡張ということでBConfを継承する形にすべきかと思います。
そうすればBConfをBMoveに替えてもいままでどおりにコンストラクタに渡せます。
ただしオブジェクト指向的にはDiagramCalcrの機能をBConfが持つべきなのが、分離されてしまっているので、回転処理と移動処理のメソッドを呼び分ける必要が出てきます。
けっこうな改造になりますがオブジェクト指向的に正しい方向へ持っていくか、最小限のコード変更で動くようにするか、どうしたいですか?
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月22日(月) 07:21
by mi_l
返信遅くりました。
ISLeさんにはお世話になりっぱなしです・・・
感謝いたします。
この質問をみて察しがいい方は「東方(竜神録)のような弾幕ゲーでもつくるの?」と思うでしょう・・・
ですが少し違います・・・
確かに最終的な目的地はそこです、しかし今の自分の力量では無理です。
相違点は、こちらは攻撃しないところです
ですが方向性は似ています、私が作りたいのは、あくまで「敵をよけてゴールにたどり着くゲーム」です。
まずは、沢山の敵画像を用意して画面に散らばせる、その敵にも移動(モーション)指せるようにします。
もちろん画面外から出てきて画面がへと消えるてきも作りたいです(画像消去の命令も必要・・・)
そして、ボスも作ります(これも移動できるように)そして、その背後にゴールエリア(画像)をつくり敵を避けながらそこにたどり着くのが目的です。
まぁ・・・・ほぼ似てていますが・・・
そこでなのですが
ISLe さんが書きました:BMoveはBConfの拡張ということでBConfを継承する形にすべきかと思います。
そうすればBConfをBMoveに替えてもいままでどおりにコンストラクタに渡せます。
ただしオブジェクト指向的にはDiagramCalcrの機能をBConfが持つべきなのが、分離されてしまっているので、回転処理と移動処理のメソッドを呼び分ける必要が出てきます。
けっこうな改造になりますがオブジェクト指向的に正しい方向へ持っていくか、最小限のコード変更で動くようにするか、どうしたいですか?
であるように、「オブジェクト指向的に正しい方向へ持っていくか、最小限のコード変更で動くようにするか」という個所では先ずは最小限のコード変更で動くようにしたいです。
これは、とりあえず移動させたいという気持ちからです。
オブジェクト指向的にやるのはその後にしたいです。
まずは、どの個所をどのようにコード変更すれば移動させられるのかその仕組みも知ってからオブジェクト指向的に移りたいと考えております。
我儘な回答ですがよろしくお願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月22日(月) 16:49
by ISLe
いま直せば一日で済むところをあとからだと一ヵ月かかることにもなってしまうような気もしますが
従来部分はそのままで、追加変更する部分だけをできるだけオブジェクト指向的に理想的な形にするという方向でいきましょう。
そのほうが違いが分かりやすいかもしれないですし。
移動パターンは分けて作りたいということなので、移動を制御するクラスと、移動させられるクラスを分けて考えます。
一対多に対応するためです。
移動パターンを持って移動を制御するクラスをBMover
移動させられるクラスは従来のコードを流用する形にしてBConfを継承したBMoveConf
ということにしましょう。
移動パターンにIDを付けるのではなく、BMoverのインスタンスをBMoveConfのコンストラクタに与える形にします。
BMoverのコンストラクタの引数で、どのように移動経路を表すか、を考えます。
どういう引数にしたら良いか、まずはmi_lさん自身で考えてみてください。
BMoveConfはBConfを継承させます。
BConfに変えていままでどおりBarricadeに渡せるようにします。
BMoveConfはBMoverをコンストラクタの引数に取ります。
ここまでの説明で分かる範囲でBMoverとBMoveConfのクラス定義を追加で作ってください。
エラーが出てもそのままにしてください。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月22日(月) 18:31
by mi_l
返信ありがとうございます。
返信にありました通り、自分の考えで二つのクラスを作ってみました
BMover.java
(エラーはなし)
コード:
package net.dixq.irairabar;
public class BMover
{
public float moveX , moveY;//移動するx、y座標(画像の座標でもある)
public BMover(float mX , float mY)
{
moveX = mX;
moveY = mY;
}
}
そしてBMoveConf.java
エラー、7行目、内容「コンストラクター BMover() は未定義です」→new BMover(● 、●);とするのですか?
14行目、「構文エラーがあります。"}" を挿入して ClassBody を完了してください」
16行目、いろいろなエラーメッセージ(インスタンスがうまく生成できれば消えるのかと・・・)
23行目、「トークン "}" に構文エラーがあります。このトークンを削除してください」
コード:
package net.dixq.irairabar;
public class BMoveConf extends BConf
{
public float moX , moY;//移動x、y座標
BMover BM = new BMover();//インスタンス生成
public Barricade.eType type = Barricade.eType.OUT;
public BMoveConf(Barricade.eType atype)
{
super(atype);
//type = atype;
}
public BMoveConf(BM.moveX , BM.moveY)
{
moX = BM.moveX;
moY = BM.moveY;
}
}
ご指摘、ご教授お願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月22日(月) 19:05
by ISLe
BMoverは場所を表すのではなく、移動を表すものです。
なので、『どのように動くのか』を情報として持つ必要があります。
まず『どのように動くのか』をどういう情報で表せるかを考えてください。
その前にどう動かしたいかも(決まってなければ)決めてください。
BMoveConfはBConfを継承しているのでBConfと重複した定義は不要です。
BMoverはコンストラクタの引数で受け取ってメンバに記憶してください。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月22日(月) 20:02
by mi_l
ご指摘ありがとうございます
また、自分なりに訂正してみました
BMover.java
どのように動くのか→「画像のx、y座標を変化させて動く」・・・この考えではないですか(違うでしょうか)?
コード:
package net.dixq.irairabar;
import android.graphics.PointF;
public class BMover
{
public float moveX , moveY;//移動するx、y座標(画像の座標でもある)
//BarricadeSquare bq = new BarricadeSquare();
public BMover(PointF mXY)//基本はBarrucadeSquareno_pt[0]を入れる
{
moveX = mXY.x;
moveY = mXY.y;
/*
if(moveY < 400)//画像の高さの位置が400より上だったら
moveY += 10;//10ずつ下がる
if(moveY > 400)//400を超えたら
{
moveY += 0;//それ以上下がらないで
moveX += 10;//右に10ずつ
}*/
}
}
BmoverConf.java
(エラーはさっきと変わりません)
コード:
package net.dixq.irairabar;
public class BMoveConf extends BConf
{
public float moX , moY;//移動x、y座標
BMover BM = new BMover();//インスタンス生成
public BMoveConf(BM.moveX , BM.moveY)
{
moX = BM.moveX;
moY = BM.moveY;
}
}
よろしくお願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月22日(月) 23:12
by ISLe
mi_l さんが書きました:どのように動くのか→「画像のx、y座標を変化させて動く」・・・この考えではないですか(違うでしょうか)?
『X,Y座標』はありますが、『変化』がありません。
これでは動きません。
書き換えるためのX,Y座標というのは手段であって、目的ではありません。
『変化させて』をどのように表現するのかを考えてください。
手段ではなく、移動の計算に絶対に必要なものは何ですか?
BMoveConfは同じ説明の繰り返しになるので答えを書きます。
コード:
package net.dixq.irairabar;
public class BMoveConf extends BConf
{
protected BMover mover;
public BMoveConf(BMover mover)
{
super(Barricade.eType.OUT); // BConfにデフォルトコンストラクタがないので障害物に設定
this.mover = mover;
}
}
#どうして障害物タイプをBConfとBarricadeで重複して持っているのだろう。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月23日(火) 16:33
by mi_l
返信ありがとうございます。
ISLe さんが書きました:mi_l さんが書きました:どのように動くのか→「画像のx、y座標を変化させて動く」・・・この考えではないですか(違うでしょうか)?
『X,Y座標』はありますが、『変化』がありません。
これでは動きません。
書き換えるためのX,Y座標というのは手段であって、目的ではありません。
『変化させて』をどのように表現するのかを考えてください。
手段ではなく、移動の計算に絶対に必要なものは何ですか?
変化というのがいまいち理解できません・・・
「移動の計算に絶対に必要なものは何ですか?」
移動(対象)画像の座標、演算子、くらいしかでてきません・・・・(「●●.x++;」とかするわけですし・・・)
一応移動タイプ1のメソッドを作りました・・・(コンストラクタの引数はまだわかっていません・・・)
コード:
ackage net.dixq.irairabar;
import android.graphics.PointF;
public class BMover
{
public float moveX , moveY;//移動するx、y座標(画像の座標でもある)
//BarricadeSquare bq = new BarricadeSquare();
public BMover(moveA())//???
{//
}
//移動タイプ1
public void moveA(float movex , float movey)
{
moveX = movex;
moveY = movey;
if(moveY < 400)//画像の高さの位置が400より上だったら
moveY += 10;//10ずつ下がる
if(moveY > 400)//400を超えたら
{
moveY += 0;//それ以上下がらないで
moveX += 10;//右に10ずつ
}
}
}
よろしくお願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月23日(火) 17:03
by ISLe
移動パターンを用意してから、障害物にセットするようにしたいのではありませんでしたか?
BMoverは複数の障害物にセットされるもので、特定の障害物(というか絶対位置)を前提とした処理を書くのはマズイです。
それと実際に動くのはBMoverではないのでBMoverに表示座標を持たせても意味がないです。
移動タイプはBMoverを継承してBMoverAを作るというふうに増やします。
とりあえずBMoverでひな型を作っている段階なのでそこも保留しておいてください。
オブジェクト指向に慣れないうちは、自分で何かしている気になれないのが我慢できないかもしれません。
でもそういうものなので辛抱してください。
移動の計算に絶対に必要なものは『距離』と『時間』です。
小学校の算数で習うので難しい問題ではないと思いますけど。
あとどう動かしたいかということを(以上を踏まえて)具体的に文章にしてください。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月23日(火) 18:21
by mi_l
返信ありがとうございます
ISLe さんが書きました:移動パターンを用意してから、障害物にセットするようにしたいのではありませんでしたか?
BMoverは複数の障害物にセットされるもので、特定の障害物(というか絶対位置)を前提とした処理を書くのはマズイです。
それと実際に動くのはBMoverではないのでBMoverに表示座標を持たせても意味がないです。
移動タイプはBMoverを継承してBMoverAを作るというふうに増やします。
とりあえずBMoverでひな型を作っている段階なのでそこも保留しておいてください。
これは、まったくもってその通りです。
そして
ISLe さんが書きました:移動の計算に絶対に必要なものは『距離』と『時間』です。
小学校の算数で習うので難しい問題ではないと思いますけど。
あとどう動かしたいかということを(以上を踏まえて)具体的に文章にしてください。
の部分ですが、小学校で習った「時間」「距離」で思い出されるのは時間・距離・速さ(頭文字をとって「みはじ」の法則ですがそれの事なのでしょうか?、移動=(ここでの)「速さ」と捉えて大丈夫でしょうか?)
また
(どう動かしたいか)
これをMoverAという新しく作るものに書く、いわゆる「移動パターン」と解釈してしまうと・・・
先ほどの私の返信にあります通り、「y=400というボーダーラインを決めて、障害物のy座標がその地点に達するまで降下し、その後、降下はせず右(xの正の)方向へと移動」
動かし方の形態(これまた解釈しづらいですが)なのであれば、
直線的、また、カーブするような移動もさせてみたいです・・・・
でもこの文章で「時間」や「距離」は使われないですよね・・・・・・・・
(もちろん上記二つでは距離と時間は比例します・・・一定の速さで移動するので移動距離が長くなればそれだけ移動し終わるまでの時間は長くなります・・・)
おそらく、このようなことを答えてほしいという意図ではないと思えて不安になるのですが・・・・
申し訳ありませんが、上記二つが意図してない回答である場合、簡略していいので、回答例をください。
お手数かけて申し訳ありません。
おろしくお願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月23日(火) 19:21
by ISLe
mi_l さんが書きました:の部分ですが、小学校で習った「時間」「距離」で思い出されるのは時間・距離・速さ(頭文字をとって「みはじ」の法則ですがそれの事なのでしょうか?、移動=(ここでの)「速さ」と捉えて大丈夫でしょうか?)
そうです。
移動している物体(オブジェクト)に対しての問いですから。
「太郎くんは交差点にいます」というだけではどれも計算できません。
そして『速さ』はオブジェクトが持つもので、『時間』と『距離』はオブジェクトとは無関係のものです。
mi_l さんが書きました:(どう動かしたいか)
これをMoverAという新しく作るものに書く、いわゆる「移動パターン」と解釈してしまうと・・・
先ほどの私の返信にあります通り、「y=400というボーダーラインを決めて、障害物のy座標がその地点に達するまで降下し、その後、降下はせず右(xの正の)方向へと移動」
そこには『何か』がありますが何を動かそうとしているのでしょうか。
わたしにはそれが見えません。
Y座標400のボーダーラインというのは何を基準にしているのでしょうか。
仮にY座標の初期位置が100のものをY座標400をボーダーラインとして動かす場合、初期位置を200に変更すると移動幅が減ってしまいますがそれで良いのでしょうか。
移動範囲も含めてずらせるようにしておかなくても良いですか?
ちなみにわたしは『何を』動かすかを具体的には想定していません。
すべての障害物に同じBMoverをセットしたら、ステージ全体が動いているように見えるようにしたいとは考えています。
mi_l さんが書きました:申し訳ありませんが、上記二つが意図してない回答である場合、簡略していいので、回答例をください。
どう動かすかというのは、例えば
10フレームかけて100ピクセル下に移動する。1フレームあたり10ピクセルで等速移動する。
ということです。
時間は10フレームで距離は100ピクセルと分かります。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月23日(火) 22:10
by mi_l
返信ありがとうございます。
まず、
ISLe さんが書きました:
そこには『何か』がありますが何を動かそうとしているのでしょうか。
わたしにはそれが見えません。
Y座標400のボーダーラインというのは何を基準にしているのでしょうか。
仮にY座標の初期位置が100のものをY座標400をボーダーラインとして動かす場合、初期位置を200に変更すると移動幅が減ってしまいますがそれで良いのでしょうか。
移動範囲も含めてずらせるようにしておかなくても良いですか?
ちなみにわたしは『何を』動かすかを具体的には想定していません。
すべての障害物に同じBMoverをセットしたら、ステージ全体が動いているように見えるようにしたいとは考えています。
では、あくまで一例、しかも初期y座標が400より上の障害物が対象でした・・・それより下の障害物は違う動作をさせようとか思っていました・・・・とりあえず忘れてもらってかまいません。
そして、
ISLe さんが書きました:
どう動かすかというのは、例えば
10フレームかけて100ピクセル下に移動する。1フレームあたり10ピクセルで等速移動する。
ということです。
時間は10フレームで距離は100ピクセルと分かります。
では、方向キーを使って俊敏に動けるような設定ではないので、かつ、約60fpsなので・・・・
動かして見なくては詳しい微調整はできませんが、
1秒に約100pxか1秒に約60px、
とりあえずは、100では難易度が高くなってしまう可能性があるので1秒に約60px(1フレームあたり1px(上下左右))で最初は試したいです。
ご教授よろしくお願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月24日(水) 00:00
by ISLe
mi_l さんが書きました:では、方向キーを使って俊敏に動けるような設定ではないので、かつ、約60fpsなので・・・・
動かして見なくては詳しい微調整はできませんが、
1秒に約100pxか1秒に約60px、
とりあえずは、100では難易度が高くなってしまう可能性があるので1秒に約60px(1フレームあたり1px(上下左右))で最初は試したいです。
ここはBMoverのコンストラクタの引数を決めるというテーマなので、実は具体的な値を決める必要はないのです。
『時間』と『距離』を表す変数が必要だという話です。
そのままnum_framesフレームでdistanceピクセル移動するといった形に持っていきます。
イメージすることが重要なので。
コンストラクタの引数を決めると言いましたが難しいので、BMover内に定数として持つことにします。
必要であれば汎用化はあとから考えます。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月24日(水) 00:23
by ISLe
ここからはあらかじめmi_l さんに考えてもらうことが難しいので、先に手順を書きます。
BMoverは複数の障害物にセットできるようにしますので、BMover自身は進行状況を管理しません。
進行状況を表す情報はBMoveConfが持ちます。
フレーム数のカウンタをBMoveConfのメンバに加えます。
BMoveConfにBarricadeの座標を更新するメソッドを用意します。
doUpdate(Barricade barricade)
という空のメソッドを『BConf』に追加してください。
BMoveConf以外にも共通に呼び出せるようしておきます。
BMoveConfでオーバーライドしてBMoverのメソッドを呼び出すようにします。
BMoverにBarricadeの座標を更新するメソッドを用意します。
doUpdate(Barricade barricade, int count)
というメソッドを追加します。
#Barricade丸ごと引き渡すあたりがちょっと気に入らないですがとりあえずということで。
上記のことからこの先どのように進めたら良いか分かるのであれば進めてください。
どのようにコードを書いたかは漏れなく報告してください。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月24日(水) 00:30
by mi_l
返信ありがとうございます。
いろいろとご教授ありがとうございます。
とりあえずなのですが、今の段階でご指摘いただいたファイルの中身がどのようになっているかを載せます。
BMover.java
コード:
package net.dixq.irairabar;
public class BMover
{
public int num_frames;//フレーム数
public int distance;//移動距離
public BMover(int frame , int dis)//引数には「フレーム数」と「移動距離」
{
//メンバ変数に登録(格納)
num_frames = frame;
distance = dis;
}
}
そして、
BMoveConf.java
コード:
package net.dixq.irairabar;
public class BMoveConf extends BConf
{
protected BMover mover ;
public BMoveConf(BMover mover)
{
super(Barricade.eType.OUT);
this.mover = mover;
}
}
エラーはありません。
しかし、質問はあります。
BMoveConfで「protected BMover mover」とありますが、ためしにクラス内の適当な場所で「mover.」と打ってみたところ、候補が出てきました(distanceやら・・・・)
私はインスタンスを生成すればそのようにできると書いてあるサイトを多く見てきました。またインスタンス生成は「●● a = new ●●();」という形でした。
このファイルに書いてある記述とどこがどう違うのでしょうか?
お手数かけて申し訳ありませんが気になったことは小さなことでも一つ一つ理解していきたいのでお願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月24日(水) 00:48
by ISLe
BMoverのコンストラクタの引数は無しで良いですよ。
とりあえずBMoverの中で定数を使ってロジックを組みます。
汎用化はあとから考えます。
mi_l さんが書きました:BMoveConfで「protected BMover mover」とありますが、ためしにクラス内の適当な場所で「mover.」と打ってみたところ、候補が出てきました(distanceやら・・・・)
私はインスタンスを生成すればそのようにできると書いてあるサイトを多く見てきました。またインスタンス生成は「●● a = new ●●();」という形でした。
このファイルに書いてある記述とどこがどう違うのでしょうか?
メンバ変数moverには、BMoverのインスタンスが入っていると『想定して』コードを書きます。
コードを書くときには実際にインスタンスが入っているかどうかは関係ありません。
実行するときにメンバ変数moverが参照しているインスタンスにアクセスしますし、nullだとNullPointerExceptionが発生します。
実行するまでにどこかの誰かがあとから作って渡してくれれば良いのです。
BMoverはそれをコンストラクタの引数として受け取ります。
このプロジェクトに関してはどこかの誰かとは未来の自分のことです。
(編集で追記したのを戻しました)
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月24日(水) 01:01
by mi_l
返信ありがとうございます
ISLe さんが書きました:
メンバ変数moverには、BMoverのインスタンスが入っていると『想定して』コードを書きます。
コードを書くときには実際にインスタンスが入っているかどうかは関係ありません。
実行するときにメンバ変数moverが参照しているインスタンスにアクセスしますし、nullだとNullPointerExceptionが発生します。
実行するまでにどこかの誰かがあとから作って渡してくれれば良いのです。
BMoverはそれをコンストラクタの引数として受け取ります。
このプロジェクトに関してはどこかの誰かとは未来の自分のことです。
なるほど!、そのような考えだったのですね!
ご教授ありがとうございます。
また、ご指摘された通り、BMoverのコンストラクタの引数は消しました。
ですが、つぎはBMoverを継承して移動パターンのクラス(仮に「MoveA」)を作るのだと思うのですが・・そこで「super()」でBMoverに渡すというわけではないのですか?(簡略した文章ですが・・)
あくまで私の考えなのですが・・・
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月24日(水) 01:11
by ISLe
mi_l さんが書きました:ですが、つぎはBMoverを継承して移動パターンのクラス(仮に「MoveA」)を作るのだと思うのですが・・そこで「super()」でBMoverに渡すというわけではないのですか?(簡略した文章ですが・・)
既にこの先必要になるメンバやメソッドを作成するように手順を書きました。
まずはそちらを進めてください。
BMoverを継承してBMoverAを作るといった応用は最後になります。
とりあえず動かすために必要なひととおりの実装を目指します。
mi_lさんの理想の動きや移動パターンを作るのは、mi_lさん自身に頑張ってもらうことになると思います。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月24日(水) 01:20
by mi_l
返信ありがとうございます。
なぜか手順を書いていただいた個所だけ読み忘れてました・・・コンストラクタに引数もまだ入れなくていいという部分も・・・
無駄な手間をかけさせて申し訳ありません。
それでは、自分の考え(ソースコード)を次回載せようと思いますので、よろしくお願いします。。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月24日(水) 11:57
by mi_l
No.15で記していただいた手順を自分なりに書いてみました。
この先どのように進めたら良いか分かるのであれば進めてくださいとの質問は下記の私の考えが間違っていたら違う方向に走って行ってしまうことになってしまいそうで不安なので・・・
BConf.java
(追記箇所:16~20行目)
コード:
package net.dixq.irairabar;
public class BConf {
public float speed = 0;//回転のスピード
public Barricade.eType type = Barricade.eType.OUT;
public BConf(Barricade.eType atype){
type = atype;
}
public BConf(float aspeed){
speed = aspeed;
}
//Barricadeの座標を更新する
public void doUpdate(Barricade barricade)
{
//今のところはまだ空
}
}
そして、BMover.java
(追記箇所:16~20行目)
コード:
package net.dixq.irairabar;
public class BMover
{
public int num_frames;//フレーム数
public int distance;//移動距離
public BMover(/*int frame , int dis*/)//引数には「フレーム数」と「移動距離」
{
//メンバ変数に登録(格納)
//num_frames = frame;
//distance = dis;
}
//Barricadeの座標を更新する
public void doUpdate(Barricade barricade, int count)
{
}
}
最後にBMoveConf.java
(追記箇所:6行目、14~20行目)
コード:
package net.dixq.irairabar;
public class BMoveConf extends BConf
{
protected BMover mover ;
protected int f_cnt;//フレームカウンタ
public BMoveConf(BMover mover)
{
super(Barricade.eType.OUT);
this.mover = mover;
}
//進行状況を管理
@Override
public void doUpdate(Barricade barricade)
{
//BMoverのdoUpdateメソッド呼び出し
mover.doUpdate(barricade, f_cnt);
}
}
ご教授、ご指摘よろしくお願します。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月24日(水) 17:15
by ISLe
はい。問題ないですね。
BConfに「座標を更新する」とコメントがありますが、BConfでの更新は座標だけとは限りません。
BMoveConfと同様にしてアニメーションを施す派生クラスを作ることも可能です。
既存のコードでは回転処理が独立していますが、BConfの派生で回転を施すことも可能です。
次は作ったメソッドを呼び出すようにしていきます。
中身は作っていないのでまだ障害物は動きません。
まずはBarricadeクラスに対して変更を加えます。
BarricadeにBConfの参照を保持するメンバ変数を追加してください。
そしてコンストラクタの引数で受け取った参照を代入してください。
BarricadeのonUpdateメソッドで上のメンバ変数を使ってBConfのdoUpdateメソッドを呼び出します。
引数には自分自身を指定します。
これらのコードにどのような意図があるのか、ソースコードだけでなくmi_lさんの分かる範囲で良いので文章にしてみてください。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月24日(水) 21:29
by mi_l
ご指摘、ありがとうございます。
返信いただいた通りとりあえずコードを載せます。
Barricade.java
(追記箇所:25、35、67行目)
(67行目はエラー(当たり前なのですがBConf.javaのdoUpdateメソッドの引数はBarricade型なので・・・・わからないところです・・))
コード:
package net.dixq.irairabar;
import android.graphics.Bitmap;//追加
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;//追加
import android.graphics.PointF;
import android.graphics.RectF;//追加
public class Barricade extends Task {
public enum eType{
OUT,
GOAL
}
protected PointF _center = new PointF(0,0); //図形の中心点
protected PointF _pt[]; //図形の頂点
protected Paint _paint = new Paint(); //ペイント
protected eType _type = eType.OUT; //タイプ(当たるとアウトな壁、ゴールの壁、等)
protected float _rotaSpeed = 0; //回転スピード
protected Bitmap bit;
protected BConf bConf;//追加
//protected int images;//参照を保持するインスタンス変数(何型の変数?)
//コンストラクタ。 type=タイプ、 n=頂点の数、 conf=設定情報
public Barricade(int n, BConf conf,Bitmap img)
{
bit = img;//格納(記録);
bConf = conf;//格納(追加)
if( conf != null ){
_rotaSpeed = conf.speed; //回転スピード
_type = conf.type; //物体のタイプ
}
switch(_type){
case OUT: //接触してアウトな物
_paint.setColor(Color.RED);
break;
case GOAL: //接触してゴールな物
_paint.setColor(Color.GREEN);
break;
}
_pt = new PointF[n]; //頂点配列を作る
for( int i=0; i<n; i++ ){
_pt[i] = new PointF(); //頂点を作る
}
_paint.setAntiAlias(true);
}
public Barricade(int n , BConf conf)
{
this(n , conf , null);
}
//更新する
public boolean onUpdate(){
if( _rotaSpeed != 0 ){ //回転するなら
DiagramCalcr.RotateDiagram( _pt, _center, _rotaSpeed ); //頂点リスト(_pt)を_centerを中心に回転する
}
bConf.doUpdate(this.bConf);
return true;
}
//接触しているかを問う。円cirが線分vecと接触していれば接触した物体のタイプを返す。接触していなければNOを返す
public Def.eHitCode isHit( final Circle cir, Vec vec ){
if( DiagramCalcr.isHit( _pt, cir, vec ) == true ){
switch(_type){
case OUT:
return Def.eHitCode.OUT;
case GOAL:
return Def.eHitCode.GOAL;
}
}
return Def.eHitCode.NO;
}
//描画する
public void onDraw(Canvas c)
{
//頂点が1未満の図形なんてないので
if( _pt.length < 1 )
{
return;//返す
}
if( bit == null )
{
Path path = new Path();//パス
path.moveTo(_pt[0].x, _pt[0].y); //パスの初期位置をセット
for( int i=0; i<_pt.length; i++ )
{
path.lineTo(_pt[i].x, _pt[i].y); //頂点の位置へラインを引いていく(軌跡を描いていく)
}
c.drawPath(path, _paint); //引いたラインを描画する
}
else
{
//画像は全体を使うと仮定
c.drawBitmap(bit, null, new RectF(_pt[0].x-10 , _pt[0].y-10 , _pt[2].x+10 , _pt[2].y+10 ), null);
}
}
}
そして、ここからは私の考え(イメージ)です
まず、BConfというクラスはBMoveConfの親クラスであり、BMoveConfの子クラス的な(正確には違いますが)位置にBMoverがあります。また更に移動パターンをBMoverを継承したクラスで決めます。
ですので、関係でいえば、
BMoverを継承したクラス → (BMoverのdoUpdateメソッドの引数をもとにした細かい情報) → BMoverクラス → (「1フレームあたり何px動くか(何フレームで何px動くか)」という情報) →
→ BMoveConfクラス → (BMoverクラスで決められたフレーム数をカウントする情報を親(管理している)クラスに) → Bconfクラス → (BMoveConfの親クラスであるので、これまで細かく設定してきた(また、管理している)情報) →
→ 敵の情報管理クラスであるBarricadeクラス (ここで「→」は「渡す」という意味を含んでいます)
整理すると、まず、Bariicade.javaは敵の「動作」「描画」など、「敵」に関するすべての情報を最終的に詰め込む所。
そしてBConf.javaとは、「動作(移動)」についての情報を最終的に詰め込む所。
ですので、GameMgr(No.1参照)でBarricadeを呼び出し、Barricadeで設定された引数に値をいれればBarricadeが管理している部署(言い方が変ですが・・)へ情報がいき、
その部署で計算などが行われBarricadeへ情報がかえってきて、それが最終的なところ(ここではGameMgr)にいく・・・・
その際、Barricadeのなかの部署の一つである「移動担当の「BConf」」というところにも値がセットされれば、BConf部署の中で計算され、Barricadeへ渡り最終場所(GameMgr)へいく、ということですか?
ダラダラと構図のイメージを自分なりに記しただけなのですが・・・・・
ご指摘、ご教授お願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月25日(木) 00:05
by ISLe
mi_l さんが書きました:(67行目はエラー(当たり前なのですがBConf.javaのdoUpdateメソッドの引数はBarricade型なので・・・・わからないところです・・))
惜しいですね。
変数bConfは何のメンバですか?
あと変数bConfはnullの場合があるので、nullでないときだけ実行されるようにしてください。
mi_l さんが書きました:整理すると、まず、Bariicade.javaは敵の「動作」「描画」など、「敵」に関するすべての情報を最終的に詰め込む所。
そしてBConf.javaとは、「動作(移動)」についての情報を最終的に詰め込む所。
これまで設計の話ばかりしてきたので情報に傾いてますけど、オブジェクト指向的には振る舞い(メソッド)を見て欲しいです。
Barricadeは障害物の見た目も含めた振る舞いを定義したものです。
BConfはBarricadeに定義された振る舞いを使って、Barricadeに変化を与える役目を持ちます。
例えるとBMoverは台本で、BMoverConfは台本の何ページ目を開いているかを知っています。
「動くということ」というときの『動く』は動いてないのですが、動くところか動かないところかきちんと区別できますか?
インスタンスの件があるのでちょっと心配ですが。
(追記)
従来コードではBConfは単純にパラメータを格納するだけの構造体で、何も振る舞いを持っていませんでした。
混ぜこぜなのでBConfとBarricadeの関係性がややこしくなってますね。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月25日(木) 00:32
by ISLe
次の手順を先に書いておきます。
Barricadeに
move(int vx, int vy)
というメソッドをとりあえず空で追加してください。
BMoveConfはこれを使ってBarricadeを動かすことになります。
Barricadeの内部を隠し自分自身に操作させることで保守性を上げます。
BMoveConfのdoUpdateメソッドに移動処理のコードを加えていきます。
引数のカウントに応じたフレームでの座標の移動差分を求めるロジックになります。
とりあえず一定時間で一定の距離を往復するものでかまわないでしょうか。
いろいろ考えていただいたのですがとりあえず動かすことを最優先にベタなコードのほうが良いかと思いました。
考えていただいたことはイメージする訓練として無駄ではないと思います。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月25日(木) 00:50
by mi_l
返信ありがとうございます。
ISLe さんが書きました:mi_l さんが書きました:(67行目はエラー(当たり前なのですがBConf.javaのdoUpdateメソッドの引数はBarricade型なので・・・・わからないところです・・))
惜しいですね。
変数bConfは何のメンバですか?
あと変数bConfはnullの場合があるので、nullでないときだけ実行されるようにしてください。
というのはいこのようなことでいいのでしょうか?(エラーは出たままなのですが)
(変更(追記)箇所:67,68行目)
コード:
package net.dixq.irairabar;
import android.graphics.Bitmap;//追加
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;//追加
import android.graphics.PointF;
import android.graphics.RectF;//追加
public class Barricade extends Task {
public enum eType{
OUT,
GOAL
}
protected PointF _center = new PointF(0,0); //図形の中心点
protected PointF _pt[]; //図形の頂点
protected Paint _paint = new Paint(); //ペイント
protected eType _type = eType.OUT; //タイプ(当たるとアウトな壁、ゴールの壁、等)
protected float _rotaSpeed = 0; //回転スピード
protected Bitmap bit;
protected BConf bConf;//追加
//protected int images;//参照を保持するインスタンス変数(何型の変数?)
//コンストラクタ。 type=タイプ、 n=頂点の数、 conf=設定情報
public Barricade(int n, BConf conf,Bitmap img)
{
bit = img;//格納(記録);
bConf = conf;//格納(追加)
if( conf != null ){
_rotaSpeed = conf.speed; //回転スピード
_type = conf.type; //物体のタイプ
}
switch(_type){
case OUT: //接触してアウトな物
_paint.setColor(Color.RED);
break;
case GOAL: //接触してゴールな物
_paint.setColor(Color.GREEN);
break;
}
_pt = new PointF[n]; //頂点配列を作る
for( int i=0; i<n; i++ ){
_pt[i] = new PointF(); //頂点を作る
}
_paint.setAntiAlias(true);
}
public Barricade(int n , BConf conf)
{
this(n , conf , null);
}
//更新する
public boolean onUpdate(){
if( _rotaSpeed != 0 ){ //回転するなら
DiagramCalcr.RotateDiagram( _pt, _center, _rotaSpeed ); //頂点リスト(_pt)を_centerを中心に回転する
}
if(bConf != null)
bConf.doUpdate(BConf bConf);
return true;
}
//接触しているかを問う。円cirが線分vecと接触していれば接触した物体のタイプを返す。接触していなければNOを返す
public Def.eHitCode isHit( final Circle cir, Vec vec ){
if( DiagramCalcr.isHit( _pt, cir, vec ) == true ){
switch(_type){
case OUT:
return Def.eHitCode.OUT;
case GOAL:
return Def.eHitCode.GOAL;
}
}
return Def.eHitCode.NO;
}
//描画する
public void onDraw(Canvas c)
{
//頂点が1未満の図形なんてないので
if( _pt.length < 1 )
{
return;//返す
}
if( bit == null )
{
Path path = new Path();//パス
path.moveTo(_pt[0].x, _pt[0].y); //パスの初期位置をセット
for( int i=0; i<_pt.length; i++ )
{
path.lineTo(_pt[i].x, _pt[i].y); //頂点の位置へラインを引いていく(軌跡を描いていく)
}
c.drawPath(path, _paint); //引いたラインを描画する
}
else
{
//画像は全体を使うと仮定
c.drawBitmap(bit, null, new RectF(_pt[0].x-10 , _pt[0].y-10 , _pt[2].x+10 , _pt[2].y+10 ), null);
}
}
ご指摘ご教授お願いします。
No.25に関してはこの質問の返信をいただくまでの時間に考えて書いていきたいと思っております。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月25日(木) 17:06
by ISLe
実引数がおかしいですね。
それは実引数の書き方ではないです。
前のコードで、
this.bConf
とありました。
これは『Barricade』のメンバ変数bConfのことです。
では『Barricade』の部分はどこでしょう。
引数はBarricadeへの参照ですよ。
Barricadeに追加するmoveメソッドの引数の型はfloatにしてください。
自分ではfloatを使わない場面なのでついintと書いてしまいました。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月25日(木) 18:24
by mi_l
返信ありがとうございます
ですがいまいち
ISLe さんが書きました:実引数がおかしいですね。
それは実引数の書き方ではないです。
前のコードで、
this.bConf
とありました。
これは『Barricade』のメンバ変数bConfのことです。
では『Barricade』の部分はどこでしょう。
引数はBarricadeへの参照ですよ。
のところが理解できていません・・・・
以下のコードがあっていたとしても何かモヤモヤします
とりあえず下記ではもともと(bConf.doUpdate();)の引数はBarricade型なのでとりあえずBarricade(型)のメンバ変数を宣言、
そして「bConf.doUpdate();」の引数に設定・・・・という感じなのですが・・・・
Barricade.java
(変更:25、26、68、69行目(ちなみに(当然ながら)エラーはなくなりました))
コード:
package net.dixq.irairabar;
import android.graphics.Bitmap;//追加
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;//追加
import android.graphics.PointF;
import android.graphics.RectF;//追加
public class Barricade extends Task {
public enum eType{
OUT,
GOAL
}
protected PointF _center = new PointF(0,0); //図形の中心点
protected PointF _pt[]; //図形の頂点
protected Paint _paint = new Paint(); //ペイント
protected eType _type = eType.OUT; //タイプ(当たるとアウトな壁、ゴールの壁、等)
protected float _rotaSpeed = 0; //回転スピード
protected Bitmap bit;
protected BConf bConf;//追加
protected Barricade ba;
//protected int images;//参照を保持するインスタンス変数(何型の変数?)
//コンストラクタ。 type=タイプ、 n=頂点の数、 conf=設定情報
public Barricade(int n, BConf conf,Bitmap img)
{
bit = img;//格納(記録);
bConf = conf;//格納(追加)
if( conf != null ){
_rotaSpeed = conf.speed; //回転スピード
_type = conf.type; //物体のタイプ
}
switch(_type){
case OUT: //接触してアウトな物
_paint.setColor(Color.RED);
break;
case GOAL: //接触してゴールな物
_paint.setColor(Color.GREEN);
break;
}
_pt = new PointF[n]; //頂点配列を作る
for( int i=0; i<n; i++ ){
_pt[i] = new PointF(); //頂点を作る
}
_paint.setAntiAlias(true);
}
public Barricade(int n , BConf conf)
{
this(n , conf , null);
}
//更新する
public boolean onUpdate(){
if( _rotaSpeed != 0 ){ //回転するなら
DiagramCalcr.RotateDiagram( _pt, _center, _rotaSpeed ); //頂点リスト(_pt)を_centerを中心に回転する
}
if(bConf != null)
bConf.doUpdate(ba);
return true;
}
//接触しているかを問う。円cirが線分vecと接触していれば接触した物体のタイプを返す。接触していなければNOを返す
public Def.eHitCode isHit( final Circle cir, Vec vec ){
if( DiagramCalcr.isHit( _pt, cir, vec ) == true ){
switch(_type){
case OUT:
return Def.eHitCode.OUT;
case GOAL:
return Def.eHitCode.GOAL;
}
}
return Def.eHitCode.NO;
}
//描画する
public void onDraw(Canvas c)
{
//頂点が1未満の図形なんてないので
if( _pt.length < 1 )
{
return;//返す
}
if( bit == null )
{
Path path = new Path();//パス
path.moveTo(_pt[0].x, _pt[0].y); //パスの初期位置をセット
for( int i=0; i<_pt.length; i++ )
{
path.lineTo(_pt[i].x, _pt[i].y); //頂点の位置へラインを引いていく(軌跡を描いていく)
}
c.drawPath(path, _paint); //引いたラインを描画する
}
else
{
//画像は全体を使うと仮定
c.drawBitmap(bit, null, new RectF(_pt[0].x-10 , _pt[0].y-10 , _pt[2].x+10 , _pt[2].y+10 ), null);
}
}
}
ご指摘、ご教授お願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月25日(木) 19:00
by ISLe
このときbaは何を指しているのでしょう。
何も指してはいませんね。
引数には自分自身を指定してください、と書いたのですが覚えていますか?
正解は
bConf.doUpdate(this);
です。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月25日(木) 20:20
by mi_l
返信ありがとうございます。
ISLe さんが書きました:このときbaは何を指しているのでしょう。
何も指してはいませんね。
引数には自分自身を指定してください、と書いたのですが覚えていますか?
というところですが「引数には自分自身を指定」との言葉が頭から離れていました(コードをみてどの様な引数にすればよいのか理解できなかったあたり、まだ全然未熟でした・・)
一応書き換えたところも含め、ソースを載せます。
Barricade.java
(変更箇所:73,74、61~65行目)
コード:
package net.dixq.irairabar;
import android.graphics.Bitmap;//追加
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;//追加
import android.graphics.PointF;
import android.graphics.RectF;//追加
public class Barricade extends Task {
public enum eType{
OUT,
GOAL
}
protected PointF _center = new PointF(0,0); //図形の中心点
protected PointF _pt[]; //図形の頂点
protected Paint _paint = new Paint(); //ペイント
protected eType _type = eType.OUT; //タイプ(当たるとアウトな壁、ゴールの壁、等)
protected float _rotaSpeed = 0; //回転スピード
protected Bitmap bit;
protected BConf bConf;//追加
//protected int images;//参照を保持するインスタンス変数(何型の変数?)
//コンストラクタ。 type=タイプ、 n=頂点の数、 conf=設定情報
public Barricade(int n, BConf conf,Bitmap img)
{
bit = img;//格納(記録);
bConf = conf;//格納(追加)
if( conf != null ){
_rotaSpeed = conf.speed; //回転スピード
_type = conf.type; //物体のタイプ
}
switch(_type){
case OUT: //接触してアウトな物
_paint.setColor(Color.RED);
break;
case GOAL: //接触してゴールな物
_paint.setColor(Color.GREEN);
break;
}
_pt = new PointF[n]; //頂点配列を作る
for( int i=0; i<n; i++ ){
_pt[i] = new PointF(); //頂点を作る
}
_paint.setAntiAlias(true);
}
public Barricade(int n , BConf conf)
{
this(n , conf , null);
}
//障害物の移動
public void move(float vx , float vy)
{
}
//更新する
public boolean onUpdate(){
if( _rotaSpeed != 0 ){ //回転するなら
DiagramCalcr.RotateDiagram( _pt, _center, _rotaSpeed ); //頂点リスト(_pt)を_centerを中心に回転する
}
if(bConf != null)
bConf.doUpdate(bConf.doUpdate(this));//エラーあり
return true;
}
//接触しているかを問う。円cirが線分vecと接触していれば接触した物体のタイプを返す。接触していなければNOを返す
public Def.eHitCode isHit( final Circle cir, Vec vec ){
if( DiagramCalcr.isHit( _pt, cir, vec ) == true ){
switch(_type){
case OUT:
return Def.eHitCode.OUT;
case GOAL:
return Def.eHitCode.GOAL;
}
}
return Def.eHitCode.NO;
}
//描画する
public void onDraw(Canvas c)
{
//頂点が1未満の図形なんてないので
if( _pt.length < 1 )
{
return;//返す
}
if( bit == null )
{
Path path = new Path();//パス
path.moveTo(_pt[0].x, _pt[0].y); //パスの初期位置をセット
for( int i=0; i<_pt.length; i++ )
{
path.lineTo(_pt[i].x, _pt[i].y); //頂点の位置へラインを引いていく(軌跡を描いていく)
}
c.drawPath(path, _paint); //引いたラインを描画する
}
else
{
//画像は全体を使うと仮定
c.drawBitmap(bit, null, new RectF(_pt[0].x-10 , _pt[0].y-10 , _pt[2].x+10 , _pt[2].y+10 ), null);
}
}
そしてNo.25である
ISLe さんが書きました:
Barricadeに
move(int vx, int vy)
というメソッドをとりあえず空で追加してください。
BMoveConfはこれを使ってBarricadeを動かすことになります。
Barricadeの内部を隠し自分自身に操作させることで保守性を上げます。
BMoveConfのdoUpdateメソッドに移動処理のコードを加えていきます。
引数のカウントに応じたフレームでの座標の移動差分を求めるロジックになります。
とりあえず一定時間で一定の距離を往復するものでかまわないでしょうか。
いろいろ考えていただいたのですがとりあえず動かすことを最優先にベタなコードのほうが良いかと思いました。
考えていただいたことはイメージする訓練として無駄ではないと思います。
という返信については、「moveメソッドの作成」は上記変更箇所にあります。
また、BMoveConfのdoUpdateメソッド内は自分で考えたコードを含めたものを載せます
BMoveConf.java
(doUpdateメソッドの26,27行目以外が私の考えです)
コード:
package net.dixq.irairabar;
public class BMoveConf extends BConf
{
protected BMover mover ;
protected int f_cnt;//フレームカウンタ
public BMoveConf(BMover mover)
{
super(Barricade.eType.OUT);
this.mover = mover;
}
//
@Override
public void doUpdate(Barricade barricade)
{
float mx , my;
//x、yと双方とも等速でかつ1フレームで1ピクセル動くので・・・・・(後の「f_cnt」は「60」にしてもいいかも・・
//「1」は自分でわかりやすくするために))
mx = f_cnt / f_cnt * 1;
my = f_cnt / f_cnt * 1;
//BMoverのdoUpdateメソッド呼び出し
mover.doUpdate(barricade, f_cnt);
barricade.move(mx, my);
}
}
ご指摘、ご教授お願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月25日(木) 22:12
by ISLe
bConf.doUpdate(this);
は引数ではなく、呼び出し文全体です。
thisが呼び出したBarricade自身を指します。
Barricadeのmoveメソッドを使うのはBMoveConfではなく、BMoverの間違いです。
すみませんでした。
BMoveConfはBMoveに処理を委譲するだけです。
#分かりやすく言えば丸投げ。
フレームカウントを進める処理だけを加えてください。
Barricadeのmoveメソッドは引数で与えられたX,Yの差分を使って座標をずらします。
こちらも考えてみてください。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月26日(金) 00:24
by mi_l
返信ありがとうございます。
ISLe さんが書きました:bConf.doUpdate(this);
は引数ではなく、呼び出し文全体です。
thisが呼び出したBarricade自身を指します。
Barricadeのmoveメソッドは引数で与えられたX,Yの差分を使って座標をずらします。
こちらも考えてみてください。
の部分である
Barricade.java
(追記(変更)個所:61~66、75行目)
コード:
package net.dixq.irairabar;
import android.graphics.Bitmap;//追加
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;//追加
import android.graphics.PointF;
import android.graphics.RectF;//追加
public class Barricade extends Task {
public enum eType{
OUT,
GOAL
}
protected PointF _center = new PointF(0,0); //図形の中心点
protected PointF _pt[]; //図形の頂点
protected Paint _paint = new Paint(); //ペイント
protected eType _type = eType.OUT; //タイプ(当たるとアウトな壁、ゴールの壁、等)
protected float _rotaSpeed = 0; //回転スピード
protected Bitmap bit;
protected BConf bConf;//追加
//protected int images;//参照を保持するインスタンス変数(何型の変数?)
//コンストラクタ。 type=タイプ、 n=頂点の数、 conf=設定情報
public Barricade(int n, BConf conf,Bitmap img)
{
bit = img;//格納(記録);
bConf = conf;//格納(追加)
if( conf != null ){
_rotaSpeed = conf.speed; //回転スピード
_type = conf.type; //物体のタイプ
}
switch(_type){
case OUT: //接触してアウトな物
_paint.setColor(Color.RED);
break;
case GOAL: //接触してゴールな物
_paint.setColor(Color.GREEN);
break;
}
_pt = new PointF[n]; //頂点配列を作る
for( int i=0; i<n; i++ ){
_pt[i] = new PointF(); //頂点を作る
}
_paint.setAntiAlias(true);
}
public Barricade(int n , BConf conf)
{
this(n , conf , null);
}
//障害物の移動
public void move(float vx , float vy)
{
vx =_pt[0].x;
vy =_pt[0].y;
}
//更新する
public boolean onUpdate(){
if( _rotaSpeed != 0 ){ //回転するなら
DiagramCalcr.RotateDiagram( _pt, _center, _rotaSpeed ); //頂点リスト(_pt)を_centerを中心に回転する
}
if(bConf != null)
bConf.doUpdate(this);
return true;
}
//接触しているかを問う。円cirが線分vecと接触していれば接触した物体のタイプを返す。接触していなければNOを返す
public Def.eHitCode isHit( final Circle cir, Vec vec ){
if( DiagramCalcr.isHit( _pt, cir, vec ) == true ){
switch(_type){
case OUT:
return Def.eHitCode.OUT;
case GOAL:
return Def.eHitCode.GOAL;
}
}
return Def.eHitCode.NO;
}
//描画する
public void onDraw(Canvas c)
{
//頂点が1未満の図形なんてないので
if( _pt.length < 1 )
{
return;//返す
}
if( bit == null )
{
Path path = new Path();//パス
path.moveTo(_pt[0].x, _pt[0].y); //パスの初期位置をセット
for( int i=0; i<_pt.length; i++ )
{
path.lineTo(_pt[i].x, _pt[i].y); //頂点の位置へラインを引いていく(軌跡を描いていく)
}
c.drawPath(path, _paint); //引いたラインを描画する
}
else
{
//画像は全体を使うと仮定
c.drawBitmap(bit, null, new RectF(_pt[0].x-10 , _pt[0].y-10 , _pt[2].x+10 , _pt[2].y+10 ), null);
}
}
}
そしてBMoveConf.java
(追記:22行目)
コード:
package net.dixq.irairabar;
public class BMoveConf extends BConf
{
protected BMover mover ;
protected int f_cnt;//フレームカウンタ
public BMoveConf(BMover mover)
{
super(Barricade.eType.OUT);
this.mover = mover;
}
//
@Override
public void doUpdate(Barricade barricade)
{
//BMoverのdoUpdateメソッド呼び出し
mover.doUpdate(barricade, f_cnt);;
f_cnt++;//カウントを加算
}
}
そしてBMover.java
(追記:doUpdateメソッド内(途中で自分の考えが間違ってることに気付いたので断念してしまいました・・・一応消さないで残してありますが・・・))
コード:
package net.dixq.irairabar;
public class BMover
{
public int num_frames;//フレーム数
public int distance;//移動距離
public BMover(/*int frame , int dis*/)//引数には「フレーム数」と「移動距離」
{
//メンバ変数に登録(格納)
//num_frames = frame;
//distance = dis;
}
//Barricadeの座標を更新する
public void doUpdate(Barricade barricade, int count)
{
float mx = 0;
float my = 0;
num_frames = count;
mx += distance / num_frames * 1;
my += distance / num_frames * 1;
barricade.move(mx, my);
}
}
ご指摘、ご教授お願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月26日(金) 16:58
by ISLe
引数を書き換えても何も起きませんよ。
Barricadeの座標はどのように管理されているかコードから読み取ってください。
画像を描画するコードに何やらオフセットが加えられていますが、これは何でしょうか。
画像イメージが合わなくて適当に書き加えたのだと推測しますが、ここで指定するサイズには意味があります。
意味を捻じ曲げるようなことはしないでください。
すべての動作に影響してしまいます。
画像に合わせて調整する必要があるのなら、調整するための仕組みを新たに実装してください。
その場しのぎは無駄を増やすだけだと言いましたよね。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月26日(金) 17:34
by ISLe
Barricadeのmoveメソッドです。
引数の変数名を変えました。
コード:
public void move(float dx , float dy)
{
for (int i=0; i<_pt.length; i++) {
_pt[i].offset(dx, dy); // 頂点座標をズラす
}
_center.offset(dx, dy); // 中心座標をズラす
}
BMoverのdoUpdateメソッドです。
distance,num_framesの宣言に初期値を設定してください。
コード:
public void doUpdate(Barricade barricade, int count)
{
float dx = 0.0f;
float dy = 0.0f;
// distanceピクセルの距離を、
// num_framesフレーム掛けて下がって、
// num_framesフレーム掛けて上がる
count %= num_frames * 2; // 往復だとnum_framesの倍の時間
if (count < num_frames) {
// 行き
dy = (float)distance / num_frames;
} else {
// 帰り
dy = -(float)distance / num_frames;
}
barricade.move(dx, dy);
}
誤差が出るやり方なので気に入らないですが踏襲します。
複雑になりますし。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月26日(金) 17:47
by ISLe
画像の描画範囲を頂点座標から求めているのは、前のスレでBarricadeSquareを前提として作成したためです。
他の図形は頂点の数も配置も違うので使えません。
描画先の矩形を示す情報を別に用意してそれぞれのコンストラクタで引数から計算して適切に設定することで他の図形にも対応できます。
BMoverのパターンを増やすなら、BMoverをインターフェースにして、現在のBMoverはインターフェースを継承した別のクラスにしましょう。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月26日(金) 20:01
by mi_l
返信ありがとうございます。
ISLe さんが書きました:
画像を描画するコードに何やらオフセットが加えられていますが、これは何でしょうか。
画像イメージが合わなくて適当に書き加えたのだと推測しますが、ここで指定するサイズには意味があります。
意味を捻じ曲げるようなことはしないでください。
すべての動作に影響してしまいます。
画像に合わせて調整する必要があるのなら、調整するための仕組みを新たに実装してください。
その場しのぎは無駄を増やすだけだと言いましたよね。
については、指摘された通り、実行するときに私が微調整と題してやってしまったことです。申し訳ありませんでした。
実際にコードまで書いていただき、ありがとうございます。
以下に、変更後のコードと、インターフェース、また実装したBMoverの別パターン(BMoverA)のソースも載せます。
Barricade.java
(変更(追記)箇所:61~70、117行目)
コード:
package net.dixq.irairabar;
import android.graphics.Bitmap;//追加
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;//追加
import android.graphics.PointF;
import android.graphics.RectF;//追加
public class Barricade extends Task {
public enum eType{
OUT,
GOAL
}
protected PointF _center = new PointF(0,0); //図形の中心点
protected PointF _pt[]; //図形の頂点
protected Paint _paint = new Paint(); //ペイント
protected eType _type = eType.OUT; //タイプ(当たるとアウトな壁、ゴールの壁、等)
protected float _rotaSpeed = 0; //回転スピード
protected Bitmap bit;
protected BConf bConf;//追加
//protected int images;//参照を保持するインスタンス変数(何型の変数?)
//コンストラクタ。 type=タイプ、 n=頂点の数、 conf=設定情報
public Barricade(int n, BConf conf,Bitmap img)
{
bit = img;//格納(記録);
bConf = conf;//格納(追加)
if( conf != null ){
_rotaSpeed = conf.speed; //回転スピード
_type = conf.type; //物体のタイプ
}
switch(_type){
case OUT: //接触してアウトな物
_paint.setColor(Color.RED);
break;
case GOAL: //接触してゴールな物
_paint.setColor(Color.GREEN);
break;
}
_pt = new PointF[n]; //頂点配列を作る
for( int i=0; i<n; i++ ){
_pt[i] = new PointF(); //頂点を作る
}
_paint.setAntiAlias(true);
}
public Barricade(int n , BConf conf)
{
this(n , conf , null);
}
//障害物の移動
public void move(float dx , float dy)
{
//全ての頂点に対して・・・
for(int i = 0 ; i < _pt.length ; i++)
{
_pt[i].offset(dx, dy);//頂点座標をずらす
}
_center.offset(dx, dy); //中心座標をずらす
}
//更新する
public boolean onUpdate(){
if( _rotaSpeed != 0 ){ //回転するなら
DiagramCalcr.RotateDiagram( _pt, _center, _rotaSpeed ); //頂点リスト(_pt)を_centerを中心に回転する
}
if(bConf != null)
bConf.doUpdate(this);
return true;
}
//接触しているかを問う。円cirが線分vecと接触していれば接触した物体のタイプを返す。接触していなければNOを返す
public Def.eHitCode isHit( final Circle cir, Vec vec ){
if( DiagramCalcr.isHit( _pt, cir, vec ) == true ){
switch(_type){
case OUT:
return Def.eHitCode.OUT;
case GOAL:
return Def.eHitCode.GOAL;
}
}
return Def.eHitCode.NO;
}
//描画する
public void onDraw(Canvas c)
{
//頂点が1未満の図形なんてないので
if( _pt.length < 1 )
{
return;//返す
}
if( bit == null )
{
Path path = new Path();//パス
path.moveTo(_pt[0].x, _pt[0].y); //パスの初期位置をセット
for( int i=0; i<_pt.length; i++ )
{
path.lineTo(_pt[i].x, _pt[i].y); //頂点の位置へラインを引いていく(軌跡を描いていく)
}
c.drawPath(path, _paint); //引いたラインを描画する
}
else
{
//画像は全体を使うと仮定
c.drawBitmap(bit, null, new RectF(_pt[0].x, _pt[0].y, _pt[2].x, _pt[2].y ), null);
}
}
}
BMover.java
(変更(追記)箇所:5~7行目、doUpdateメソッド内)
コード:
package net.dixq.irairabar;
public class BMover
{
//60フレームで60px移動だから・・・・
public int num_frames = 60;//フレーム数
public int distance = 60;//移動距離
public BMover(/*int frame , int dis*/)//引数には「フレーム数」と「移動距離」
{
//メンバ変数に登録(格納)
//num_frames = frame;
//distance = dis;
}
//Barricadeの座標を更新する
public void doUpdate(Barricade barricade, int count)
{
float dx = 0.0f;//x座標
float dy = 0.0f;//y座標
// distanceピクセルの距離を・・・・、
// num_framesフレーム掛けて下り
// num_framesフレーム掛けて上がる
count %= num_frames * 2; // 往復だとnum_framesの倍の時間かかる
if (count < num_frames)
{
// 行き
dy = (float)distance / num_frames;
} else
{
// 帰り
dy = -(float)distance / num_frames;
}
barricade.move(dx, dy);
}
}
そして、ここからはBmoverのパターンを増やそうとしているとかていして作ったものです
(上のBMoverにインターフェースが実装されてないように下記の二つのファイルはプロジェクトにまだ入っていません)
BMovers.java
コード:
package net.dixq.irairabar;
import net.dixq.irairabar.Barricade;
interface BMovers
{
public void doUpdate(Barricade barricade , int count);
}
BMoverA.java
コード:
//BMoverA.javaファイル(BMoverの移動設定を変えたもの)
package net.dixq.irairabar;
public class BMoverA implements BMovers
{
//60フレームで60px移動だから・・・・
public int num_frames = 60;//フレーム数
public int distance = 60;//移動距離
public BMover(/*int frame , int dis*/)//引数には「フレーム数」と「移動距離」
{
//メンバ変数に登録(格納)
//num_frames = frame;
//distance = dis;
}
//Barricadeの座標を更新する
public void doUpdate(Barricade barricade, int count)
{
float dx = 0.0f;
float dy = 0.0f;
// distanceピクセルの距離を・・・・、
// num_framesフレーム掛けて下り
// num_framesフレーム掛けて上がる
count %= num_frames * 3; // 往路+停止+復路のためx3する(全て60フレーム使う設定。)
if (count < num_frames)
{
// 行き
dy = (float)distance / num_frames;//ここでは1pxのこと
}
else if(count >= num_frames && count < (num_frames*2))
{
//停止
dy = (float)distance % num_frames;//0px(停止のこと)
}
else
{
// 帰り
dy = -(float)distance / num_frames;
}
barricade.move(dx, dy);
}
}
ソース変更、インターフェース、また実装クラスに対して、
ご指摘、ご教授お願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月26日(金) 21:55
by ISLe
移動パターンを増やす前に動作確認はしたのでしょうか。
主題である、障害物を動かす目的は果たせたと思いますが。
スレの伸びとともにmi_lさん自身が考えず言われるままコードを書くだけになっていっているように感じます。
既にBMoverで作ってあるところを書き換えないようにするためにはインターフェースの名前がBMoverでないといけません。
Eclipseなら一発で置き換えできますが、コードを書き換えずに拡張することに意味があります。
いつまでもdistanceとnum_framesの変数にこだわる必要はありません。
『時間』と『距離』を意識するためにシンプルな動作を提案しましたが、複雑な動作をさせたいなら『時間』と『距離』をセットにデータをテーブル化したほうが分かりやすいと思います。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月26日(金) 22:49
by mi_l
返信ありがとうございます。
ISLe さんが書きました:
スレの伸びとともにmi_lさん自身が考えず言われるままコードを書くだけになっていっているように感じます。
という個所なのですが、上級者から見れば、まだ全然未熟な私の返答がまったく意図してないことで困惑することもあると思いますが、自分なりに考えた返答を毎回しております。
「なんでここもわからないの?」という感情は当然持たれるとは思います。ですが、丸写しでいいやとか、そのようなことは一切ありません。そのことはご理解いただきたいです
動作確認しましたが・・・動きません
以下は表示が必要だと思ったソース
GameMgr
コード:
package net.dixq.irairabar;
import java.util.ArrayList;
import java.util.LinkedList;
import net.dixq.irairabar.Barricade.eType;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.annotation.SuppressLint;
import android.content.res.Resources;
import android.content.Context;
public class GameMgr {
private enum eStatus{
NORMAL,
GAMEOVER,
GAMECLEAR
};
private static final float PI = (float) Math.PI;
private ArrayList<Barricade> _barrList = new ArrayList<Barricade>();//障害物リスト
private LinkedList<Task> _taskList = new LinkedList<Task>();// タスクリスト
private eStatus _status = eStatus.NORMAL;
private Player _player;
GameMgr(Context con)
{
Resources res = con.getResources();
Bitmap bits = BitmapFactory.decodeResource(res, R.drawable.ic_launcher);
// _barrList.add(new BarricadeSquare( 20, 30, 700,800, null));
_barrList.add(new BarricadeSquare( 70 , 60,100, 100, new BConf(Barricade.eType.OUT) , bits));// 画面4隅に四角形を配置
/*
_barrList.add(new BarricadeSquare(460, 0, 20,800, null));
_barrList.add(new BarricadeSquare( 0,780,480, 20, null));
_barrList.add(new BarricadeTriangle( 0, 0, 200, new BConf(+PI / 150),));// 左上回転する三角形
_barrList.add(new BarricadeTriangle(480, 0, 180, new BConf(+PI / 150)));// 右上回転する三角形
_barrList.add(new BarricadeStar(240, 240, 50, 200, new BConf(-PI / 360)));// 中央に回転する星
_barrList.add(new BarricadeStar(240, 240, 20, 80, new BConf(+PI / 360)));// 中央に回転する星
_barrList.add(new BarricadeSquare(300, 440, 200, 20, null));//右下の固定通路
_barrList.add(new BarricadeSquare(250, 520, 130, 20, null));//
_barrList.add(new BarricadeSquare(330, 620, 130, 20, null));//
_barrList.add(new BarricadeSquare(230, 390, 20, 350, null));//中央区切り線
_barrList.add(new BarricadeSquare(0, 480, 240, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare( 20, 600, 110, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare(130, 600, 110, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare(185, 600, 55, 20, new BConf(+PI / 360)));// 左下回転するバー
*/
// _barrList.add(new BarricadeSquare(20, 680, 80, 20, null));// ゴールに接触したバー
// _barrList.add(new BarricadeSquare(20, 700, 80, 80, new BConf(eType.GOAL)));// ゴール
for (Barricade bar : _barrList) {
_taskList.add(bar); //タスクリストに障害物を追加
}
_player = new Player();
_taskList.add(_player);
_taskList.add(new FpsController());
}
private boolean Collision(){
Vec vec = new Vec();
final Circle cir = _player.getPt();
for(Barricade barr : _barrList){
Def.eHitCode code = barr.isHit(cir, vec);
switch(code){
case OUT:
_status = eStatus.GAMEOVER;
return true;
case GOAL:
_status = eStatus.GAMECLEAR;
return true;
}
}
return false;
}
public boolean onUpdate()
{
if( _status != eStatus.NORMAL ){
return true;
}
if( Collision() ){
return true;
}
for (int i = 0; i < _taskList.size(); i++) {
if (_taskList.get(i).onUpdate() == false) { // 更新失敗なら
_taskList.remove(i); // そのタスクを消す
i--;
}
}
return true;
}
private void drawStatus(Canvas c){
switch( _status ){
case GAMEOVER:
{
Paint paint = new Paint();
paint.setTextSize(80);
paint.setColor(Color.BLACK);
c.drawText("GameOver", 40, 100, paint);
}
break;
case GAMECLEAR:
{
Paint paint = new Paint();
paint.setTextSize(80);
paint.setColor(Color.BLACK);
c.drawText("GameClear", 40, 100, paint);
}
break;
}
}
@SuppressLint("WrongCall")
public void onDraw(Canvas c)
{
//白く塗りつぶす
c.drawColor(Color.WHITE);
for (Task task : _taskList)
{
//描画
task.onDraw(c);
}
drawStatus(c);
}
}
BConf.java
コード:
package net.dixq.irairabar;
public class BConf {
public float speed = 0;//回転のスピード
public Barricade.eType type = Barricade.eType.OUT;
public BConf(Barricade.eType atype){
type = atype;
}
public BConf(float aspeed){
speed = aspeed;
}
//Barricadeの座標を更新する
public void doUpdate(Barricade barricade)
{
//今のところはまだ空
}
}
BMoveConf
コード:
package net.dixq.irairabar;
public class BMoveConf extends BConf
{
protected BMover mover ;
protected int f_cnt;//フレームカウンタ
public BMoveConf(BMover mover)
{
super(Barricade.eType.OUT);
this.mover = mover;
}
//
@Override
public void doUpdate(Barricade barricade)
{
//BMoverのdoUpdateメソッド呼び出し
mover.doUpdate(barricade, f_cnt);
f_cnt++;//カウントを加算
}
}
BMover
コード:
package net.dixq.irairabar;
public class BMover
{
//60フレームで60px移動だから・・・・
public int num_frames = 60;//フレーム数
public int distance = 60;//移動距離
public BMover(/*int frame , int dis*/)//引数には「フレーム数」と「移動距離」
{
//メンバ変数に登録(格納)
//num_frames = frame;
//distance = dis;
}
//Barricadeの座標を更新する
public void doUpdate(Barricade barricade, int count)
{
float dx = 0.0f;//x座標
float dy = 0.0f;//y座標
// distanceピクセルの距離を・・・・、
// num_framesフレーム掛けて下り
// num_framesフレーム掛けて上がる
count %= num_frames * 2; // 往復だとnum_framesの倍の時間かかる
if (count < num_frames)
{
// 行き
dy = (float)distance / num_frames;
} else
{
// 帰り
dy = -(float)distance / num_frames;
}
barricade.move(dx, dy);
}
}
BarricadeSquare
コード:
package net.dixq.irairabar;
import android.graphics.Bitmap;
public class BarricadeSquare extends Barricade {
public BarricadeSquare( float x, float y, float w, float h, BConf conf, Bitmap img ){
super(4,conf, img);
_pt[0].x = x; _pt[0].y = y;
_pt[1].x = x+w; _pt[1].y = y;
_pt[2].x = x+w; _pt[2].y = y+h;
_pt[3].x = x; _pt[3].y = y+h;
_center.x = x+w/2;
_center.y = y+h/2;
}
public BarricadeSquare( float x, float y, float w, float h, BConf conf)
{
this(x, y ,w, h, conf, null);
}
}
長くなりましたがご指摘お願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月27日(土) 00:24
by ISLe
GameMgrで、動かしたい障害物のコンストラクタの実引数のBConfをBMoveConfに替えてください。
mi_l さんが書きました:という個所なのですが、上級者から見れば、まだ全然未熟な私の返答がまったく意図してないことで困惑することもあると思いますが、自分なりに考えた返答を毎回しております。
「なんでここもわからないの?」という感情は当然持たれるとは思います。ですが、丸写しでいいやとか、そのようなことは一切ありません。そのことはご理解いただきたいです
わたしが気にしているのは、わたしが書いてくださいと言ったコードは書くけども、わたしが日本語で説明したことは読んでいないのか理解していないのか同じような失敗を何度も繰り返すことです。
BMoveConfはBConfを拡張して差し替えるものであることは最初に書きました。
どうして「BMoveConfを使うにはどうしたら?」でなく「動きませんどうして?」なのでしょう。
わたしは容易に調べることができることを調べなかったり分からないことを分からないと言わずにその場しのぎをすることに腹を立てますが、分からないことを「こんなことも分からないのか」というのはもっと嫌いです。
世間一般はどうか知りませんが当然だとはまったく思いません。
#調べ方を教えた上で「どうして調べないんだ」ということはしょっちゅうありますが。
mi_lさんはそんなつもりではないと思いますが、わたしのことを、(わたしの考える)最低な人間だとおっしゃったわけです。
これまでの説明で障害物を動かすことはできるはずなので、あとはご自身で頑張ってください。
分からないことは新たにスレを立てれば誰か教えてくれる人が現れるかもしれません。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月27日(土) 10:11
by mi_l
返信ありがとうございます。
このトピックを見直し、自分なりに何回も訂正し、実行を繰り返しましたができませんでした。(移動はできませんでした。)
自分なりにやることはやったつもりですので、それでできないということは見落としがあるとしか思えません。
まだ全然未熟さを感じました。
これ以上は放置になってしまいますのでここで解決とさせてもらいます。(一区切りさせてもらいます)
また、参考書を読み返し、新たなアプリ開発の本でも買い、勉強します。
この質問は、この前のトピックから続いていますがこれまで教わってきた考え方、テクニックは必ず自分の技量につながるので感謝しています。
>>ISLe様
ご教授いただいている立場でありながら最後には不快な記載をして申し訳ありませんでした。これまで長い間丁寧にご指摘いただきありがとうございます。
ここで教わったことは必ず私の技量になりますし、新たなアプリを作ろうと思った時に必ず役に立つと思います。 最後まで感謝いたします。
また、ここの掲示板は利用させていただくことがあると思いますので、今後ともよろしくお願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月27日(土) 11:52
by softya(ソフト屋)
横から失礼します。
ざっと見させてもらいましてが、クラスの継承などの意味が理解できていないのでは無いでしょうか?
質問の流れてみていると、それに付いては一切質問がされていません。 → ISLeさんが問題にしているのもそこです。
BMoveConfがどういう物なのか、どう使うべきなのか、まったく理解できていないのではありませんか?
ISLeさんが分からないなら、そこを聞いて欲しいと言っているんだと思います。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月27日(土) 14:11
by mi_l
>>softyaさん
解決後ですが返信ありがとうございます。
softya(ソフト屋) さんが書きました:横から失礼します。
ざっと見させてもらいましてが、クラスの継承などの意味が理解できていないのでは無いでしょうか?
質問の流れてみていると、それに付いては一切質問がされていません。 → ISLeさんが問題にしているのもそこです。
BMoveConfがどういう物なのか、どう使うべきなのか、まったく理解できていないのではありませんか?
ISLeさんが分からないなら、そこを聞いて欲しいと言っているんだと思います。
というご指摘なのですが、
BMoveConfはBMoverのdoUpdateを呼び出し、フレームの加算をし、コンストラクタにもある通りBMoverを呼び出し続ける・・
そしてBMoverはその設定。ここではdy(y軸だけの移動なので)は「行きと帰り」の動作を行う。よって往復では60x2フレームかかる。
設定では60px/60フレームなので差分の値(60フレーム未満までは+1pxを、60フレーム以上はー1pxを代入し、Barricadeのmoveへと送る(dxは0.0fのまま))
Barricadeのmoveにきて初めて画像がその分(ここだと1px(-1px))動く・・・ということですよね・・・
自分なりに仕組みを整理してみますと
BMoverという部署のdoUpdateメソッドが場合に分けて1フレームあたりの差分の値をdyという入れ物に格納しBarricadeの実際に値を元にして動かす部署(move)へと渡す。
ですがこれでは1px動いて終わる(?)
ここでBMoveConfという部署はBMoverのdoUpdateを呼び出し続け、さらにフレームのカウントを加算する役割がある。
つまり、BMoverのdoUpdateの場合分けはこの加算により機能される。
BMoverがBMoveConfに毎回呼び出され続けることで毎回Barricadeのmoveにも差分の値である1(px)がいく
そこで、60フレームまでBMoveConfがカウントを加算し始めた時、BMoverのdoUpdateメソッドにより処理が変わる(moveに渡す値が1px→ー1pxになる)
BMoveConfは依然としてBMoverを呼び出し、加算を続けるので、実際に障害物は60フレームかけて60px下がり、60フレームかけて60px上がるということになる・・・
というのが私なりの考えなのですが・・・・
なにか「整理」できてない感が否めませんが・・・このような表現が今の私にできるやり方なので・・・・・
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月27日(土) 17:02
by ISLe
ISLe さんが書きました:GameMgrで、動かしたい障害物のコンストラクタの実引数のBConfをBMoveConfに替えてください。
この日本語の文章を読んでいないのでしょうか。それとも理解できなかったのでしょうか。
コードは『想定して』書くものだということも以前書きましたね。
書いただけでは動かないし、Eclipseのデバッグや実行のコマンドを選択したら書いたコードがすべて実行されるわけでもありません。
BMoveConfやBMoverを作ってもそれをどこからも呼び出していないのに障害物が動くはずありません。
クラスがどうとか以前に、プログラムの実行の仕組みそのものを理解できていないと感じます。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月27日(土) 17:20
by softya(ソフト屋)
もしかしたらインスタンスとかクラスを継承することで関連性がどうなるのかがまったく掴めていないんでしょうか?
親の性質は子に継承されますが親は親のままです。
なので、class BConfのインスタンスをどう動かしてもclass BMoveConfの持つ性質は一切発現しません。
class BMoveConfの機能はclass BMoveConfのインスタンスがもっています。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月27日(土) 17:35
by mi_l
返信ありがとうございます
ISLe さんが書きました:ISLe さんが書きました:GameMgrで、動かしたい障害物のコンストラクタの実引数のBConfをBMoveConfに替えてください。
この日本語の文章を読んでいないのでしょうか。それとも理解できなかったのでしょうか。
コードは『想定して』書くものだということも以前書きましたね。
書いただけでは動かないし、Eclipseのデバッグや実行のコマンドを選択したら書いたコードがすべて実行されるわけでもありません。
BMoveConfやBMoverを作ってもそれをどこからも呼び出していないのに障害物が動くはずありません。
クラスがどうとか以前に、プログラムの実行の仕組みそのものを理解できていないと感じます。
の指摘にありますように「解決」とさせていただく段階でGameMgrは書き換え、実行もしてみました。
GameMgr
(変更箇所:41行目)
コード:
package net.dixq.irairabar;
import java.util.ArrayList;
import java.util.LinkedList;
import net.dixq.irairabar.Barricade.eType;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.annotation.SuppressLint;
import android.content.res.Resources;
import android.content.Context;
public class GameMgr {
private enum eStatus{
NORMAL,
GAMEOVER,
GAMECLEAR
};
private static final float PI = (float) Math.PI;
private ArrayList<Barricade> _barrList = new ArrayList<Barricade>();//障害物リスト
private LinkedList<Task> _taskList = new LinkedList<Task>();// タスクリスト
private eStatus _status = eStatus.NORMAL;
private Player _player;
//private BMover bm;
GameMgr(Context con)
{
Resources res = con.getResources();
Bitmap bits = BitmapFactory.decodeResource(res, R.drawable.ic_launcher);
// _barrList.add(new BarricadeSquare( 20, 30, 700,800, null));
_barrList.add(new BarricadeSquare( 70 , 60,100, 100, new BMoveConf(null) , bits));// 画面4隅に四角形を配置
/*
_barrList.add(new BarricadeSquare(460, 0, 20,800, nul
_barrList.add(new BarricadeSquare( 0,780,480, 20, null));
_barrList.add(new BarricadeTriangle( 0, 0, 200, new BConf(+PI / 150),));// 左上回転する三角形
_barrList.add(new BarricadeTriangle(480, 0, 180, new BConf(+PI / 150)));// 右上回転する三角形
_barrList.add(new BarricadeStar(240, 240, 50, 200, new BConf(-PI / 360)));// 中央に回転する星
_barrList.add(new BarricadeStar(240, 240, 20, 80, new BConf(+PI / 360)));// 中央に回転する星
_barrList.add(new BarricadeSquare(300, 440, 200, 20, null));//右下の固定通路
_barrList.add(new BarricadeSquare(250, 520, 130, 20, null));//
_barrList.add(new BarricadeSquare(330, 620, 130, 20, null));//
_barrList.add(new BarricadeSquare(230, 390, 20, 350, null));//中央区切り線
_barrList.add(new BarricadeSquare(0, 480, 240, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare( 20, 600, 110, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare(130, 600, 110, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare(185, 600, 55, 20, new BConf(+PI / 360)));// 左下回転するバー
*/
// _barrList.add(new BarricadeSquare(20, 680, 80, 20, null));// ゴールに接触したバー
// _barrList.add(new BarricadeSquare(20, 700, 80, 80, new BConf(eType.GOAL)));// ゴール
for (Barricade bar : _barrList) {
_taskList.add(bar); //タスクリストに障害物を追加
}
_player = new Player();
_taskList.add(_player);
_taskList.add(new FpsController());
}
private boolean Collision(){
Vec vec = new Vec();
final Circle cir = _player.getPt();
for(Barricade barr : _barrList){
Def.eHitCode code = barr.isHit(cir, vec);
switch(code){
case OUT:
_status = eStatus.GAMEOVER;
return true;
case GOAL:
_status = eStatus.GAMECLEAR;
return true;
}
}
return false;
}
public boolean onUpdate()
{
if( _status != eStatus.NORMAL ){
return true;
}
if( Collision() ){
return true;
}
for (int i = 0; i < _taskList.size(); i++) {
if (_taskList.get(i).onUpdate() == false) { // 更新失敗なら
_taskList.remove(i); // そのタスクを消す
i--;
}
}
return true;
}
private void drawStatus(Canvas c){
switch( _status ){
case GAMEOVER:
{
Paint paint = new Paint();
paint.setTextSize(80);
paint.setColor(Color.BLACK);
c.drawText("GameOver", 40, 100, paint);
}
break;
case GAMECLEAR:
{
Paint paint = new Paint();
paint.setTextSize(80);
paint.setColor(Color.BLACK);
c.drawText("GameClear", 40, 100, paint);
}
break;
}
}
@SuppressLint("WrongCall")
public void onDraw(Canvas c)
{
//白く塗りつぶす
c.drawColor(Color.WHITE);
for (Task task : _taskList)
{
//描画
task.onDraw(c);
}
drawStatus(c);
}
}
この場合は「null」ですがそれ以外の
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月27日(土) 17:37
by mi_l
プレビューと間違え「送信」を押してしまいました。
もう一回正しく返信しなおします。
お手間かけます。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月27日(土) 18:13
by mi_l
返信ありがとうございます
ISLe さんが書きました:ISLe さんが書きました:GameMgrで、動かしたい障害物のコンストラクタの実引数のBConfをBMoveConfに替えてください。
この日本語の文章を読んでいないのでしょうか。それとも理解できなかったのでしょうか。
コードは『想定して』書くものだということも以前書きましたね。
書いただけでは動かないし、Eclipseのデバッグや実行のコマンドを選択したら書いたコードがすべて実行されるわけでもありません。
BMoveConfやBMoverを作ってもそれをどこからも呼び出していないのに障害物が動くはずありません。
クラスがどうとか以前に、プログラムの実行の仕組みそのものを理解できていないと感じます。
との指摘の部分なのですが、「解決」とさせてもたった時に書き換え、実行もしてみました・・・
GameMgr
(変更箇所:33、43行目)
(もちろん、この後、BarricadeSquare , Barricade のコンストラクタの引数も「BMoveConf conf」にしました。 )
コード:
package net.dixq.irairabar;
import java.util.ArrayList;
import java.util.LinkedList;
import net.dixq.irairabar.Barricade.eType;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.annotation.SuppressLint;
import android.content.res.Resources;
import android.content.Context;
public class GameMgr {
private enum eStatus{
NORMAL,
GAMEOVER,
GAMECLEAR
};
private static final float PI = (float) Math.PI;
private ArrayList<Barricade> _barrList = new ArrayList<Barricade>();//障害物リスト
private LinkedList<Task> _taskList = new LinkedList<Task>();// タスクリスト
private eStatus _status = eStatus.NORMAL;
private Player _player;
private BMover bm = new BMover();
GameMgr(Context con)
{
Resources res = con.getResources();
Bitmap bits = BitmapFactory.decodeResource(res, R.drawable.ic_launcher);
// _barrList.add(new BarricadeSquare( 20, 30, 700,800, null));
_barrList.add(new BarricadeSquare( 70 , 60,100, 100, new BMoveConf(bm) , bits));// 画面4隅に四角形を配置
/*
_barrList.add(new BarricadeSquare(460, 0, 20,800, nul
_barrList.add(new BarricadeSquare( 0,780,480, 20, null));
_barrList.add(new BarricadeTriangle( 0, 0, 200, new BConf(+PI / 150),));// 左上回転する三角形
_barrList.add(new BarricadeTriangle(480, 0, 180, new BConf(+PI / 150)));// 右上回転する三角形
_barrList.add(new BarricadeStar(240, 240, 50, 200, new BConf(-PI / 360)));// 中央に回転する星
_barrList.add(new BarricadeStar(240, 240, 20, 80, new BConf(+PI / 360)));// 中央に回転する星
_barrList.add(new BarricadeSquare(300, 440, 200, 20, null));//右下の固定通路
_barrList.add(new BarricadeSquare(250, 520, 130, 20, null));//
_barrList.add(new BarricadeSquare(330, 620, 130, 20, null));//
_barrList.add(new BarricadeSquare(230, 390, 20, 350, null));//中央区切り線
_barrList.add(new BarricadeSquare(0, 480, 240, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare( 20, 600, 110, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare(130, 600, 110, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare(185, 600, 55, 20, new BConf(+PI / 360)));// 左下回転するバー
*/
// _barrList.add(new BarricadeSquare(20, 680, 80, 20, null));// ゴールに接触したバー
// _barrList.add(new BarricadeSquare(20, 700, 80, 80, new BConf(eType.GOAL)));// ゴール
for (Barricade bar : _barrList) {
_taskList.add(bar); //タスクリストに障害物を追加
}
_player = new Player();
_taskList.add(_player);
_taskList.add(new FpsController());
}
private boolean Collision(){
Vec vec = new Vec();
final Circle cir = _player.getPt();
for(Barricade barr : _barrList){
Def.eHitCode code = barr.isHit(cir, vec);
switch(code){
case OUT:
_status = eStatus.GAMEOVER;
return true;
case GOAL:
_status = eStatus.GAMECLEAR;
return true;
}
}
return false;
}
public boolean onUpdate()
{
if( _status != eStatus.NORMAL ){
return true;
}
if( Collision() ){
return true;
}
for (int i = 0; i < _taskList.size(); i++) {
if (_taskList.get(i).onUpdate() == false) { // 更新失敗なら
_taskList.remove(i); // そのタスクを消す
i--;
}
}
return true;
}
private void drawStatus(Canvas c){
switch( _status ){
case GAMEOVER:
{
Paint paint = new Paint();
paint.setTextSize(80);
paint.setColor(Color.BLACK);
c.drawText("GameOver", 40, 100, paint);
}
break;
case GAMECLEAR:
{
Paint paint = new Paint();
paint.setTextSize(80);
paint.setColor(Color.BLACK);
c.drawText("GameClear", 40, 100, paint);
}
break;
}
}
@SuppressLint("WrongCall")
public void onDraw(Canvas c)
{
//白く塗りつぶす
c.drawColor(Color.WHITE);
for (Task task : _taskList)
{
//描画
task.onDraw(c);
}
drawStatus(c);
}
}
・・・・・・・・ですがこれでは(下にしか)動きません。
私はBMoverで
コード:
package net.dixq.irairabar;
public class BMover
{
//60フレームで60px移動だから・・・・
public int num_frames = 60;//フレーム数
public int distance = 60;//移動距離
public BMover(/*int frame , int dis*/)//引数には「フレーム数」と「移動距離」
{
//メンバ変数に登録(格納)
//num_frames = frame;
//distance = dis;
}
//Barricadeの座標を更新する
public void doUpdate(Barricade barricade, int count)
{
float dx = 0.0f;//x座標
float dy = 0.0f;//y座標
count = 0;
// distanceピクセルの距離を・・・・、
// num_framesフレーム掛けて下り
// num_framesフレーム掛けて上がる
count %= num_frames * 2; // 往復だとnum_framesの倍の時間かかる
if (count < num_frames)
{
// 行き
dy = (float)distance / num_frames;
} else
{
// 帰り
dy = -(float)distance / num_frames;
}
barricade.move(dx, dy);
}
}
としっかりISLeさんの提案通り(記載していただいた)通り、往復の手順を書きました。
ですが、実際に動いたのは「下に」だけです・・・
私は60フレームかけて60px降下し、60フレームかけて60px上昇すると書きました(書いたつもしなのかもしれませんが)
ですので、私は「動きません」と書きました。
更に、ISleさんに対し、失礼なことを記載してしまった手前、最後まで上昇をどうすればいいか試行錯誤しましたができなかったので自分勝手に「解決」させてもらいました。
まだ、ご指摘いただけるのであれば、ご指摘お願いします。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月27日(土) 18:46
by softya(ソフト屋)
class BMoverのdoUpdateメソッドの中でcount = 0;としている理由は何ですか?
前になかったはずですが、どういう効果を期待して付け加えましたか?
【補足】
それと解決直前までは、BMoveConfに付いては一切インスタンス化しようとしたことは無かったって事でしょうか。
>GameMgrで、動かしたい障害物のコンストラクタの実引数のBConfをBMoveConfに替えてください。
1)これは理解できなかったって事ですかね? → 理解できないなら質問してほしい所です。
2)あるいは、意味が読み取れなかった?
3)あるいは、見逃した?
4)それともBMoveConfとBConfは同じものだと思っていた?
今後のために聞いておきたいのです。
【追記】
雑談トピックが次のページに行ってしまったので、お礼を書いて解決にしておいてください。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年4月27日(土) 18:52
by ISLe
mi_l さんが書きました:(もちろん、この後、BarricadeSquare , Barricade のコンストラクタの引数も「BMoveConf conf」にしました。 )
どうしてそんなことをしたのでしょうか。
そんなことをしなくてもエラーは出ないですよね。
そのためにBMoveConfはBConfを継承しているのですし、doUpdateメソッドをオーバーライドしているのです。
既存のコードはそのまま、動かしたい障害物にだけBMoveConfを使う。
使っていないところは今までどおりに動き、BMoveConfを使った障害物だけが移動する。
ということも最初に説明しましたよね。
回転やアニメーションする派生クラスを作ることもできると説明しましたよね。
どうしてBMoveConf専用にしてしまうのですか?
GameMgrの既存の障害物をコメントアウトしている理由が分かりませんが。
mi_l さんが書きました:としっかりISLeさんの提案通り(記載していただいた)通り、往復の手順を書きました。
わたしが記載したとおりではないようですが。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年5月15日(水) 18:49
by mi_l
返信が遅くなりましたが、無事に解決できました。
BMoverを実装した設定クラスを作り、ステージも作れました。
ご教授ありがとうございました。
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年5月15日(水) 18:51
by softya(ソフト屋)
mi_l さんが書きました:返信が遅くなりましたが、無事に解決できました。
BMoverを実装した設定クラスを作り、ステージも作れました。
ご教授ありがとうございました。
すいません。解決コードの投稿が基本ルールとなっておりますのでお願いします。
http://dixq.net/board/board.html
Re: androidアプリで困っています。ご教授ください(Ver.2)
Posted: 2013年5月15日(水) 19:03
by mi_l
基本ルールにのっとり、返信していなかったため、上記の私の返信の追加として、コードを載せます
BMover.java
コード:
package net.dixq.irairabar;
public interface BMover {
//Barricadeの座標を更新する(ver1)(なしと考える
public abstract void doUpdate(Barricade barricade, int count);
}
自分で作った「BmoverA」「BMoverB」
コード:
package net.dixq.irairabar;
public class BMoverA implements BMover
{
//60フレームで60px移動だから・・・・
public int num_frames = 60;//フレーム数
public int distance = 60;//移動距離
public BMoverA(/*int frame , int dis*/)//引数には「フレーム数」と「移動距離」
{
//メンバ変数に登録(格納)
//num_frames = frame;
//distance = dis;
}
//Barricadeの座標を更新する(ver1)(なしと考える
public void doUpdate(Barricade barricade, int count)
{
float dx = 0.0f;//x座標
float dy = 0.0f;//y座標
//count = 0;
// distanceピクセルの距離を・・・・、
// num_framesフレーム掛けて下り
// num_framesフレーム掛けて上がる
count %= num_frames * 2; // 往復だとnum_framesの倍の時間かかる
if (count < num_frames)
{
// 行き
dy = (float)distance / num_frames;
}
else
{
// 帰り
dy = -(float)distance / num_frames;
}
barricade.move(dx, dy);
}
}
コード:
package net.dixq.irairabar;
public class BMoverB implements BMover
{
//60フレームで60px移動だから・・・・
public int num_frames = 60;//フレーム数
public int distance = 200;//移動距離
public BMoverB(/*int frame , int dis*/)//引数には「フレーム数」と「移動距離」
{
//メンバ変数に登録(格納)
//num_frames = frame;
//distance = dis;
}
//Barricadeの座標を更新する(ver1)(なしと考える
public void doUpdate(Barricade barricade, int count)
{
float dx = 0.0f;//x座標
float dy = 0.0f;//y座標
//count = 0;
// distanceピクセルの距離を・・・・、
// num_framesフレーム掛けて下り
// num_framesフレーム掛けて上がる
count %= num_frames * 3; // 往復だとnum_framesの倍の時間かかる
if (count < num_frames)
{
// 行き
dy = (float)distance / num_frames;
}
else if(count >= num_frames && count < (num_frames*2))//停止
{
dy = 0;
}
else
{
// 帰り
dy = -(float)distance / num_frames;
}
barricade.move(dx, dy);
}
}
GameMgr.java
(変更(追記)箇所:33,34、45,47行目)
コード:
package net.dixq.irairabar;
import java.util.ArrayList;
import java.util.LinkedList;
import net.dixq.irairabar.Barricade.eType;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.annotation.SuppressLint;
import android.content.res.Resources;
import android.content.Context;
public class GameMgr {
private enum eStatus{
NORMAL,
GAMEOVER,
GAMECLEAR
};
private static final float PI = (float) Math.PI;
private ArrayList<Barricade> _barrList = new ArrayList<Barricade>();//障害物リスト
private LinkedList<Task> _taskList = new LinkedList<Task>();// タスクリスト
private eStatus _status = eStatus.NORMAL;
private Player _player;
private BMoverA bma = new BMoverA();
private BMoverB bmb = new BMoverB();
/*private int Dflag = 0;//描画フラグ
private float x , y;*/
GameMgr(Context con)
{
Resources res = con.getResources();
Bitmap bits = BitmapFactory.decodeResource(res, R.drawable.ic_launcher);
_barrList.add(new BarricadeSquare( 220, 30, 100,100, new BMoveConf(bmb) , bits));
_barrList.add(new BarricadeSquare( 70 , 60, 100, 100, new BMoveConf(bma) , bits));// 画面4隅に四角形を配置
/*
_barrList.add(new BarricadeTriangle( 0, 0, 200, new BConf(+PI / 150),));// 左上回転する三角形
_barrList.add(new BarricadeTriangle(480, 0, 180, new BConf(+PI / 150)));// 右上回転する三角形
_barrList.add(new BarricadeStar(240, 240, 50, 200, new BConf(-PI / 360)));// 中央に回転する星
_barrList.add(new BarricadeStar(240, 240, 20, 80, new BConf(+PI / 360)));// 中央に回転する星
_barrList.add(new BarricadeSquare(300, 440, 200, 20, null));//右下の固定通路
_barrList.add(new BarricadeSquare(250, 520, 130, 20, null));//
_barrList.add(new BarricadeSquare(330, 620, 130, 20, null));//
_barrList.add(new BarricadeSquare(230, 390, 20, 350, null));//中央区切り線
_barrList.add(new BarricadeSquare(0, 480, 240, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare( 20, 600, 110, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare(130, 600, 110, 20, new BConf(+PI / 360)));// 左下回転するバー
_barrList.add(new BarricadeSquare(185, 600, 55, 20, new BConf(+PI / 360)));// 左下回転するバー
*/
// _barrList.add(new BarricadeSquare(20, 680, 80, 20, null));// ゴールに接触したバー
// _barrList.add(new BarricadeSquare(20, 700, 80, 80, new BConf(eType.GOAL)));// ゴール
for (Barricade bar : _barrList) {
_taskList.add(bar); //タスクリストに障害物を追加
}
_player = new Player();
_taskList.add(_player);
_taskList.add(new FpsController());
}
private boolean Collision(){
Vec vec = new Vec();
final Circle cir = _player.getPt();
for(Barricade barr : _barrList){
Def.eHitCode code = barr.isHit(cir, vec);
switch(code){
case OUT:
_status = eStatus.GAMEOVER;
return true;
case GOAL:
_status = eStatus.GAMECLEAR;
return true;
}
}
return false;
}
public boolean onUpdate()
{
if( _status != eStatus.NORMAL ){
return true;
}
if( Collision() ){
return true;
}
for (int i = 0; i < _taskList.size(); i++) {
if (_taskList.get(i).onUpdate() == false) { // 更新失敗なら
_taskList.remove(i); // そのタスクを消す
i--;
}
}
return true;
}
private void drawStatus(Canvas c){
switch( _status ){
case GAMEOVER:
{
Paint paint = new Paint();
paint.setTextSize(80);
paint.setColor(Color.BLACK);
c.drawText("GameOver", 40, 100, paint);
}
break;
case GAMECLEAR:
{
Paint paint = new Paint();
paint.setTextSize(80);
paint.setColor(Color.BLACK);
c.drawText("GameClear", 40, 100, paint);
}
break;
}
}
@SuppressLint("WrongCall")
public void onDraw(Canvas c)
{
//白く塗りつぶす
c.drawColor(Color.WHITE);
for (Task task : _taskList)
{
//描画
task.onDraw(c);
}
drawStatus(c);
}
}
二つの障害物に違う動きをさせることができました。