Androidアプリ、画面遷移について
Androidアプリ、画面遷移について
いつもお世話になっています。
以前、この掲示板で皆様のご教授もあり、イライラバー(Androidの館)のアレンジを作りました。
そこでなのですが、今回はもっと作り込みたいと思いました。
今回やりたいことは、
1、スタート画面を作る。(スタートボタンだけ)、クイックリスナーやインテントの(軽い?)勉強も兼ねて・・
Startクラスを作る(Xmlを指定)・・・クリックリスナーでボタンを押すと作っているイライラバープロジェクトのactivityを継承している「IrairaBarActivity」にインテント。(ここで1面が始まる)
2、GOALにたどり着くとAndroidの館通り「GOAL」と表示させ、画面のどこかをタップすると2面スタート・・・
3、最後の面までクリアした場合・・・・・まだ考えていません
4、どこかで障害物に触れた(GameOverになった)場合、Backボタンでスタート画面に戻る。
ここからは、私が思ったことです。(考えです)
まず、GameMgrがゲーム自身の流れを管理しているのだと思います。
そして、障害物の設定である「Barricadeクラス」、自機の設定である「Playerクラス」、FPSの「FpsControllerクラス」は全てTaskクラスを継承しており、
GameMgrクラスの「_taskList」に追加されていくことから、Taskを継承した(例として1面、2面の二つの)クラスを作り、GameMgrのコンストラクタにインスタンスとして渡す・・・・
というように作るのでしょうか?
ですが、この流れでいくとスタート画面もTaskの継承したクラスで作れそうですが・・・ボタンの設定(タップなど)とかがわかりません・・・
(欲を言うとスター画面にボタンは二つにして、二つのコースを作りたいです・・・)
例、「迷路コース」・・・・作った迷路の面をどんどんプレイ
「逃走コース」・・・作った逃走の面をどんどんプレイ 的な感じで・・・・(ここはもう少し後でも構いません)
どのように始めればよいか教えてください。
また、私の考えに対してご指摘などお願いします。
以前、この掲示板で皆様のご教授もあり、イライラバー(Androidの館)のアレンジを作りました。
そこでなのですが、今回はもっと作り込みたいと思いました。
今回やりたいことは、
1、スタート画面を作る。(スタートボタンだけ)、クイックリスナーやインテントの(軽い?)勉強も兼ねて・・
Startクラスを作る(Xmlを指定)・・・クリックリスナーでボタンを押すと作っているイライラバープロジェクトのactivityを継承している「IrairaBarActivity」にインテント。(ここで1面が始まる)
2、GOALにたどり着くとAndroidの館通り「GOAL」と表示させ、画面のどこかをタップすると2面スタート・・・
3、最後の面までクリアした場合・・・・・まだ考えていません
4、どこかで障害物に触れた(GameOverになった)場合、Backボタンでスタート画面に戻る。
ここからは、私が思ったことです。(考えです)
まず、GameMgrがゲーム自身の流れを管理しているのだと思います。
そして、障害物の設定である「Barricadeクラス」、自機の設定である「Playerクラス」、FPSの「FpsControllerクラス」は全てTaskクラスを継承しており、
GameMgrクラスの「_taskList」に追加されていくことから、Taskを継承した(例として1面、2面の二つの)クラスを作り、GameMgrのコンストラクタにインスタンスとして渡す・・・・
というように作るのでしょうか?
ですが、この流れでいくとスタート画面もTaskの継承したクラスで作れそうですが・・・ボタンの設定(タップなど)とかがわかりません・・・
(欲を言うとスター画面にボタンは二つにして、二つのコースを作りたいです・・・)
例、「迷路コース」・・・・作った迷路の面をどんどんプレイ
「逃走コース」・・・作った逃走の面をどんどんプレイ 的な感じで・・・・(ここはもう少し後でも構いません)
どのように始めればよいか教えてください。
また、私の考えに対してご指摘などお願いします。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: Androidアプリ、画面遷移について
色々と放ったらかしなので、まずちゃんと解決をお願いします。
「androidアプリで困っています。ご教授ください(Ver.2) • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3 ... 7&start=30
「【雑談】プログラミングについて 皆さんに訊いてみたかったことなのですが・・・・ • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=12931
解決コードの投稿が終わっていないようですので、お願いします。
「androidアプリで困っています。ご教授ください(Ver.2) • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3 ... 7&start=30
「【雑談】プログラミングについて 皆さんに訊いてみたかったことなのですが・・・・ • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=12931
解決コードの投稿が終わっていないようですので、お願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: Androidアプリ、画面遷移について
ついこの前同じような内容のスレがありました。
Androidの館についての質問です
Intentで繋いでいく方法が簡単だと思います。
デメリットはAndroid以外のプラットフォームへの応用が期待できない点ですがおそらくまったく問題ないでしょう。
あとはContext縛りによるリークにいっそうの注意が必要です。
Androidの館についての質問です
Intentで繋いでいく方法が簡単だと思います。
デメリットはAndroid以外のプラットフォームへの応用が期待できない点ですがおそらくまったく問題ないでしょう。
あとはContext縛りによるリークにいっそうの注意が必要です。
Re: Androidアプリ、画面遷移について
長らく放置していました。
他の言語にハマってしまいました。
ご指摘、ご教授いただいた皆様、申し訳ありません。
しかし、ここまでやってきたので最後までやりたいです。
スタート画面→ゲームスタート
まではできました。
次は色々な面を作りたいです。
taskを継承することはわかるのですが具体的にどのような事を書けばいいのか今一つはっきりしません(わかりません)
考え方など教えて下さい。
今回のコード
start.java
main.xml(スタート画面)
android:text="次のアクティビティへ" />
</LinearLayout>[/code]
androidMnifest.xml
よろしくお願いします。
他の言語にハマってしまいました。
ご指摘、ご教授いただいた皆様、申し訳ありません。
しかし、ここまでやってきたので最後までやりたいです。
スタート画面→ゲームスタート
まではできました。
次は色々な面を作りたいです。
taskを継承することはわかるのですが具体的にどのような事を書けばいいのか今一つはっきりしません(わかりません)
考え方など教えて下さい。
今回のコード
start.java
package net.dixq.irairabar;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class Start extends Activity implements OnClickListener
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn = (Button) findViewById(R.id.button1);//main.xmlにあるbutton1を見つける
btn.setOnClickListener(this);//onClickが呼ばれるように本インスタンスをセットする
}
@Override
public void onClick(View v)//クリック時に呼ばれる
{
//インテント
Intent intent = new Intent();
intent.setClassName("net.dixq.irairabar", "net.dixq.irairabar.IrairaBarActivity");
startActivity(intent);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
</LinearLayout>[/code]
androidMnifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.dixq.irairabar"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".Start" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".IrairaBarActivity"/>
</application>
</manifest>
Re: Androidアプリ、画面遷移について
GameMgrクラスのコンストラクタで障害物のインスタンスを構築して障害物リストに登録していますから、ステージ番号やコース(を表す値)を使って条件分岐してやれば良いと思います。
クリアしたらIrairaBarActivityにIntentを飛ばし、ゲームオーバーになったらStartにIntentを飛ばします。
mi_lさんのいま現在やりたいことをただ実現するために、Taskを継承して云々は必要ありません。
分からないところはもう少し細かく具体的にしてください。
クリアしたらIrairaBarActivityにIntentを飛ばし、ゲームオーバーになったらStartにIntentを飛ばします。
mi_lさんのいま現在やりたいことをただ実現するために、Taskを継承して云々は必要ありません。
分からないところはもう少し細かく具体的にしてください。
Re: Androidアプリ、画面遷移について
返信ありがとうございます。
今の段階で私がやりたいこと。
1、スタート画面を作る
2、スタートを押すと1面がスタート
ーーーーーーーーーーーーーーーーーーーーここまではできました
3、ゴールに接触したら、「Goal」と表示されるので、ここで画面をタップすると次の面へ
3、同じく敵に接触したら「GameOver」と表示されるので、ここで画面をタップするとスタート画面へ、
ですが、3の二つの場合タップの処理も記述しなければならないので下記のコードは、
3、ゴールに接触したら、「Goal」と表示されるので、この瞬間、インテントで次の面へ’(待ち時間なし)
3、同様に・・・・・・
GameMgr.java
(追記(変更)箇所: 35、39行目、48~63行目、105、106、110~112行目)
変更箇所でコメントしてあるのは、コメントを外してしまうとエラーになってしまうからです。
実行もしましたが、今までと変わりません
(クリアしたら「Clear」とでて終わり・・・)
馬鹿正直にやっただけなのですが・・・・
ご指摘、ご教授お願いします。
今の段階で私がやりたいこと。
1、スタート画面を作る
2、スタートを押すと1面がスタート
ーーーーーーーーーーーーーーーーーーーーここまではできました
3、ゴールに接触したら、「Goal」と表示されるので、ここで画面をタップすると次の面へ
3、同じく敵に接触したら「GameOver」と表示されるので、ここで画面をタップするとスタート画面へ、
ですが、3の二つの場合タップの処理も記述しなければならないので下記のコードは、
3、ゴールに接触したら、「Goal」と表示されるので、この瞬間、インテントで次の面へ’(待ち時間なし)
3、同様に・・・・・・
GameMgr.java
(追記(変更)箇所: 35、39行目、48~63行目、105、106、110~112行目)
package net.dixq.irairabar;
import java.util.ArrayList;
import java.util.LinkedList;
import net.dixq.irairabar.Barricade.eType;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
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 stage = 1;//ステージ番号
/* private float x , y;*/
//インテント
Intent intent = new Intent();
GameMgr(Context con)
{
Resources res = con.getResources();
Bitmap bits = BitmapFactory.decodeResource(res, R.drawable.ic_launcher);
//ステージ
switch(stage)
{
case 1://(まだ今は試作段階なので簡単な配置にする)
_barrList.add(new BarricadeSquare( 220, 30, 100,100, new BMoveConf(bmb) , bits));//動く画像障害物A
_barrList.add(new BarricadeSquare( 70 , 60, 100, 100, new BMoveConf(bma) , bits));//動く画像障害物B
_barrList.add(new BarricadeSquare(20, 700, 80, 80, new BConf(eType.GOAL),bits));// ゴール
break;
case 2:
_barrList.add(new BarricadeSquare( 120, 30, 100,100, new BMoveConf(bmb)));//動く画像なし障害物A
_barrList.add(new BarricadeSquare( 50 , 100, 100, 100, new BMoveConf(bma)));//動く画像なし障害物B
_barrList.add(new BarricadeSquare(190, 700, 80, 80, new BConf(eType.GOAL)));// ゴール
break;
default:
break;
}
/*ここは今のところ関係ないのでコメント
_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),bits));// ゴール
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;
intent.setClassName("net.dixq.irairabar", "net.dixq.irairabar.Start");
//startActivity(intent);
return true;
case GOAL:
_status = eStatus.GAMECLEAR;
stage++;
intent.setClassName("net.dixq.irairabar", "net.dixq.irairabar.IrairaBarActivity");
// startActivity(intent);
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);
}
}
実行もしましたが、今までと変わりません
(クリアしたら「Clear」とでて終わり・・・)
馬鹿正直にやっただけなのですが・・・・
ご指摘、ご教授お願いします。
Re: Androidアプリ、画面遷移について
インスタンス変数GameMgr#_statusの値は、ゲーム開始時にeStatus.NORMALです。
ゲームオーバー時にはeStatus.GAMEOVERになります。
ゲームクリアー時にはeStatus.GAMECLEARになります。
ここまでは分かっているかと思います。
GameMgr#onUpdateメソッドは毎フレーム呼ばれます。
この中で、_statusがeStatus.NORMALでないときはただちにリターンしています。
この条件が表すのは、ゲームオーバーまたはゲームクリアーになったということです。
以上がヒントです。
タッチイベントはViewが拾うしかありません。
イベントリスナー等を使ってGameSurfaceViewからタッチイベントを取得できるようにしてください。
GameMgrのインスタンスなどはGameSurfaceView内で作成されているので、GameMgrに次のシーンに進むといった機能のメソッドを用意してタッチイベントから呼び出すようにすると良いでしょう。
startActivityはActivityクラスのメソッドなので、どうにかしてIrairaBarActivityから(GameSurfaceViewを通して)GameMgrのステータスが見えるようにする必要があるでしょう。
Activityのインスタンスをリレーするのはお勧めしません。
ゲームオーバー時にはeStatus.GAMEOVERになります。
ゲームクリアー時にはeStatus.GAMECLEARになります。
ここまでは分かっているかと思います。
GameMgr#onUpdateメソッドは毎フレーム呼ばれます。
この中で、_statusがeStatus.NORMALでないときはただちにリターンしています。
この条件が表すのは、ゲームオーバーまたはゲームクリアーになったということです。
以上がヒントです。
タッチイベントはViewが拾うしかありません。
イベントリスナー等を使ってGameSurfaceViewからタッチイベントを取得できるようにしてください。
GameMgrのインスタンスなどはGameSurfaceView内で作成されているので、GameMgrに次のシーンに進むといった機能のメソッドを用意してタッチイベントから呼び出すようにすると良いでしょう。
startActivityはActivityクラスのメソッドなので、どうにかしてIrairaBarActivityから(GameSurfaceViewを通して)GameMgrのステータスが見えるようにする必要があるでしょう。
Activityのインスタンスをリレーするのはお勧めしません。
Re: Androidアプリ、画面遷移について
返信ありがとうございます。
タッチイベントは少し後回しにしていただき、
コード
(変更箇所117~132行目)
ご指摘お願いします。
タッチイベントは少し後回しにしていただき、
より、onUpdateでreturn trueではどちらかわからないのでは?、と思いif文で分岐しました。ISLe さんが書きました:インスタンス変数GameMgr#_statusの値は、ゲーム開始時にeStatus.NORMALです。
ゲームオーバー時にはeStatus.GAMEOVERになります。
ゲームクリアー時にはeStatus.GAMECLEARになります。
ここまでは分かっているかと思います。
GameMgr#onUpdateメソッドは毎フレーム呼ばれます。
この中で、_statusがeStatus.NORMALでないときはただちにリターンしています。
この条件が表すのは、ゲームオーバーまたはゲームクリアーになったということです。
以上がヒントです。
コード
(変更箇所117~132行目)
package net.dixq.irairabar;
import java.util.ArrayList;
import java.util.LinkedList;
import net.dixq.irairabar.Barricade.eType;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
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 stage = 1;//ステージ番号
/* private float x , y;*/
//インテント
Intent intent = new Intent();
GameMgr(Context con)
{
Resources res = con.getResources();
Bitmap bits = BitmapFactory.decodeResource(res, R.drawable.ic_launcher);
//ステージ
switch(stage)
{
case 1://(まだ今は試作段階なので簡単な配置にする)
_barrList.add(new BarricadeSquare( 220, 30, 100,100, new BMoveConf(bmb) , bits));//動く画像障害物A
_barrList.add(new BarricadeSquare( 70 , 60, 100, 100, new BMoveConf(bma) , bits));//動く画像障害物B
_barrList.add(new BarricadeSquare(20, 700, 80, 80, new BConf(eType.GOAL),bits));// ゴール
break;
case 2:
_barrList.add(new BarricadeSquare( 120, 30, 100,100, new BMoveConf(bmb)));//動く画像なし障害物A
_barrList.add(new BarricadeSquare( 50 , 100, 100, 100, new BMoveConf(bma)));//動く画像なし障害物B
_barrList.add(new BarricadeSquare(190, 700, 80, 80, new BConf(eType.GOAL)));// ゴール
break;
default:
break;
}
/*ここは今のところ関係ないのでコメント
_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),bits));// ゴール
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 )
{
if(_status == eStatus.GAMECLEAR)
{
stage++;
intent.setClassName("net.dixq.irairabar", "net.dixq.irairabar.IrairaBarActivity");
//startActivity(intent);
}
else if(_status != eStatus.GAMEOVER)
{
intent.setClassName("net.dixq.irairabar", "net.dixq.irairabar.Start");
//startActivity(intent);
}
//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);
}
}
Re: Androidアプリ、画面遷移について
GameMgrはActivityではないので、Intentを操作すべきではないと思います。
もっとも簡単な対応としては、GameMgrクラスの_statusとenum eStatusをpublicにして外から見えるようにします。
GameSurfaceViewクラスの_gameMgrもpublicにします。
IrairaBarActivityクラスで、GameMgrクラスの_statusが変化するのを監視して、変化したらゲームオーバーかゲームクリアーかでIntentを投げます。
ホーリングだと負荷が大きいのでコールバック(リスナー形式)のほうが良いのですが、とりあえずどちらでもかまわないです。
もっとも簡単な対応としては、GameMgrクラスの_statusとenum eStatusをpublicにして外から見えるようにします。
GameSurfaceViewクラスの_gameMgrもpublicにします。
IrairaBarActivityクラスで、GameMgrクラスの_statusが変化するのを監視して、変化したらゲームオーバーかゲームクリアーかでIntentを投げます。
ホーリングだと負荷が大きいのでコールバック(リスナー形式)のほうが良いのですが、とりあえずどちらでもかまわないです。
Re: Androidアプリ、画面遷移について
返信遅れました。
とりあえず、やってみましたが、エラーがでてしまいます。
GameMgr
(変更;20,29,35行目)
GameSurfaceView
変更11行目
変更箇所29~48行目
publicにしたのに34行目の「_status」と36行目の「stage」に「_status を変数に解決できません」というエラーが出てしまいます。
ご指摘おお願いします
とりあえず、やってみましたが、エラーがでてしまいます。
GameMgr
(変更;20,29,35行目)
package net.dixq.irairabar;
import java.util.ArrayList;
import java.util.LinkedList;
import net.dixq.irairabar.Barricade.eType;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
public class GameMgr {
/* private*/ public 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*/public eStatus _status = eStatus.NORMAL;
private Player _player;
private BMoverA bma = new BMoverA();
private BMoverB bmb = new BMoverB();
public int stage = 1;//ステージ番号
/* private float x , y;*/
GameMgr(Context con)
{
Resources res = con.getResources();
Bitmap bits = BitmapFactory.decodeResource(res, R.drawable.ic_launcher);
//ステージ
switch(stage)
{
case 1://(まだ今は試作段階なので簡単な配置にする)
_barrList.add(new BarricadeSquare( 220, 30, 100,100, new BMoveConf(bmb) , bits));//動く画像障害物A
_barrList.add(new BarricadeSquare( 70 , 60, 100, 100, new BMoveConf(bma) , bits));//動く画像障害物B
_barrList.add(new BarricadeSquare(20, 700, 80, 80, new BConf(eType.GOAL),bits));// ゴール
break;
case 2:
_barrList.add(new BarricadeSquare( 120, 30, 100,100, new BMoveConf(bmb)));//動く画像なし障害物A
_barrList.add(new BarricadeSquare( 50 , 100, 100, 100, new BMoveConf(bma)));//動く画像なし障害物B
_barrList.add(new BarricadeSquare(190, 700, 80, 80, new BConf(eType.GOAL)));// ゴール
break;
default:
break;
}
/*ここは今のところ関係ないのでコメント
_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),bits));// ゴール
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);
}
}
変更11行目
package net.dixq.irairabar;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
@SuppressLint("WrongCall")
class GameSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
/* private*/ public GameMgr _gameMgr;
private Thread _thread;
public GameSurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
_gameMgr = new GameMgr(context.getApplicationContext());
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//解像度情報変更通知
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
_thread = new Thread(this); //別スレッドでメインループを作る
_thread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
_thread = null;
}
@Override
public void run() {
while (_thread!=null) { //メインループ
_gameMgr.onUpdate();
onDraw(getHolder());
}
}
@SuppressLint("WrongCall")
private void onDraw(SurfaceHolder holder) {
Canvas c = holder.lockCanvas();
_gameMgr.onDraw(c);
holder.unlockCanvasAndPost(c);
}
}
変更箇所29~48行目
package net.dixq.irairabar;
import net.dixq.irairabar.GameMgr.eStatus;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
public class IrairaBarActivity extends Activity {
GameSurfaceView _view;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//画面のタイムアウト防止
_view = new GameSurfaceView(this);
setContentView(_view);
AcSensor.Inst().onCreate(this); // センサー初期化
}
//インテント
Intent intent = new Intent();
public void judge()
{
if(_status == eStatus.GAMECLEAR)
{
stage++;
intent.setClassName("net.dixq.irairabar", "net.dixq.irairabar.IrairaBarActivity");
//startActivity(intent);
}
else if(_status == eStatus.GAMEOVER)
{
intent.setClassName("net.dixq.irairabar", "net.dixq.irairabar.Start");
//startActivity(intent);
}
}
@Override
protected void onResume() { // アクティビティが動き始める時呼ばれる
super.onResume();
AcSensor.Inst().onResume();// 開始時にセンサーを動かし始める
}
@Override
protected void onPause() { // アクティビティの動きが止まる時呼ばれる
super.onPause();
AcSensor.Inst().onPause();// 中断時にセンサーを止める
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
_view = new GameSurfaceView(this);
setContentView(_view); // 処理の実体はGameSurfaceView内のGameMgr
return false;
} else {
return super.onKeyDown(keyCode, event);
}
}
}
ご指摘おお願いします
Re: Androidアプリ、画面遷移について
_statusはIrairaBarActivityのメンバではなく、GameMgrのメンバです。
_view._gameMgr._statusと記述する必要があります。
いちおう断っておきますが、目的を達成するためにあえて汚い手を使っています。
このようなプログラミング作法を身に付けるのは非常に良くないことです。
以前のスレで書いた気がしますがmi_lさんの人生の貴重な時間を将来に渡って無駄に消費することになります。
書籍などできちんとまともな作法を勉強されることをお勧めします。
IntentによってIrairaBarActivityのインスタンスが再作成される(※)ので、GameSurfaceViewのインスタンスもGameMgrも再作成されます。
※実際に再作成されるか分かりませんがそのように振る舞うはず。
GameMgr#stageはリセットされるのでインクリメントは意味がありません。
Intentでステージ番号を渡してください。
_view._gameMgr._statusと記述する必要があります。
いちおう断っておきますが、目的を達成するためにあえて汚い手を使っています。
このようなプログラミング作法を身に付けるのは非常に良くないことです。
以前のスレで書いた気がしますがmi_lさんの人生の貴重な時間を将来に渡って無駄に消費することになります。
書籍などできちんとまともな作法を勉強されることをお勧めします。
IntentによってIrairaBarActivityのインスタンスが再作成される(※)ので、GameSurfaceViewのインスタンスもGameMgrも再作成されます。
※実際に再作成されるか分かりませんがそのように振る舞うはず。
GameMgr#stageはリセットされるのでインクリメントは意味がありません。
Intentでステージ番号を渡してください。