当たり判定の処理を一時的に止めるにはどうしたらいいですか?
- 評価
- クリップ 0
- VIEW 1,829
//mysocoreが○○より高く、レベルが○ならレベルが上昇
if((Score.myscore > 160)&&(Level.level==0)){
Level.addLevel();
}
//myscoreが○○より高く、○○より低いか等しい場合、さらにレベルが○ならばクリアの文字を表示する
if((Score.myscore<=180)&&(Score.myscore> 160)&&(Level.level==1)){
title.drawGameclear(gBuf);
}
質問を変えます
上のプログラムは、クラスMyCanvasのプログラムの一部です。レベル上昇の条件と、クリアという文字を表示する処理をしています。
void gameMain()
{
//ゲームオーバーか?
if (objectpool.isGameover())
{
//ゲームオーバー文字を表示
title.drawGameover(gBuf);
これが、ゲームオーバーの文字を表示するプログラムです
ゲームオーバーかどうかを返すプログラムはObjectPoolというクラスにあります
ゲームオーバーになってSPACEキーを押すと、タイトル画面に戻る仕組みです
レベル上昇して、しばらく当たり判定のプログラムを停止させたいです
そうすれば、レベル上昇と同時にゲームオーバーになることは防げると思います
しかし、当たり判定はゲームオーバーと同じくObjectPoolで書かれていて、どうやってMyCanvasで当たり判定のプログラムを停止させる処理を作ればいいのかがわかりません。レベルが上がって、しばらく処理を停止させるにはどうしたらいいでしょうか?
それか、決められた時間の間だけ、文字を表示するにはどうしたらいいですか?
この下が、MyCanvasのすべてのプログラムです
なお、このプログラムはサンプルコードとして配布していたものを私が改造していっている段階です
もともと、このプログラムにはレベルが上がるためのクリア条件というものがありませんでした
500フレーム経過すると、自然とレベルが上がり、ひたすらhiscoreを競うものだったようです。
上記のものは、私がレベルを一つずつ上げるために追加したものです。
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.util.Random;
/**
*描画先コンポーネントクラス(Canvasを継承)<p>
*メインループもここ
*/
public class MyCanvas extends Canvas implements Runnable{
ObjectPool objectpool;
KeyInput keyinput;
Image imgBuf;
Graphics gBuf;
Random random;
Title title;
Score score;
/**
* シーン管理変数<p>
* 0:タイトル画面 1:ゲームのメイン画面
*/
public int scene;
static final int SCENE_TITLE = 0;
static final int SCENE_GAMEMAIN = 1;
public boolean gameover;
int counter;
//押されている
static final int SHOT_PRESSED = 1;
//今押されたばかり
static final int SHOT_DOWN = 2;
int shotkey_state;
/**
* コンストラクタ
*/
MyCanvas()
{
//キーリスナ実装
keyinput = new KeyInput();
addKeyListener(keyinput);
setFocusable(true); //フォーカスを取得できるようにする。
random = new Random(); //乱数オブジェクト
title = new Title();
score = new Score();
}
/**
* 初期化処理<p>
* アプリケーションの開始時、またはリスタート時に呼ばれ、<br>
* ゲーム内で使われる変数の初期化を行う。
*/
public void init()
{
objectpool = new ObjectPool();
Score.loadScore();
//シーンはタイトル画面
scene = SCENE_TITLE;
gameover = false;
//レベルの初期化
Level.initLevel();
//スコアの初期化
Score.initScore();
Title.initTitle();
}
/**
* 外部からスレッドを初期化する。
*/
public void initThread()
{
Thread thread = new Thread(this);
thread.start();
}
/**
* 描画処理<p>
* repaint()の際に呼ばれて、
* オフスクリーンバッファから画像をコピーし表示する。
* @param g 描画先グラフィックハンドル
*/
public void paint(Graphics g)
{
//オフスクリーンバッファの内容を自分にコピー
g.drawImage(imgBuf, 0, 0, this);
}
/**
* メインループ
*/
public void run()
{
//オフスクリーンバッファ作成
imgBuf = createImage(500, 500);
gBuf = imgBuf.getGraphics();
for(counter = 0; ; counter++)
{
shotkey_state = keyinput.checkShotKey();
//バッファをクリア
gBuf.setColor(Color.white);
gBuf.fillRect(0, 0, 500, 500);
//シーン遷移用の変数で分岐
switch (scene)
{
//タイトル画面
case 0:
title.drawTitle(gBuf);
score.drawScore(gBuf);
score.drawHiScore(gBuf);
//スペースキーが押された
if (shotkey_state == SHOT_DOWN)
{
//メイン画面に行く
scene = SCENE_GAMEMAIN;
}
break;
//ゲームのメイン画面
case 1:
gameMain();
break;
}
//再描画を要求
repaint();
try{
Thread.sleep(20); //ループのウェイト
}
catch(InterruptedException e)
{}
}
}
/**
* 画面をいちいちクリアしないようにするため、
* updateメソッドをオーバーライドする。
* @param g 更新先グラフィックハンドル
*/
public void update(Graphics g)
{
paint(g);
}
/**
* ゲーム画面のメイン処理
*/
void gameMain()
{
//ゲームオーバーか?
if (objectpool.isGameover())
{
//ゲームオーバー文字を表示
title.drawGameover(gBuf);
if (shotkey_state == SHOT_DOWN)
{
//スコアをハイスコアに適用、必要があればセーブ
Score.compareScore();
//ゲームを再初期化
init();
}
}
//衝突の判定
objectpool.getColision();
objectpool.movePlayer(keyinput);
//敵出現間隔:レベルに応じて短くなる
if (counter % (100 - Level.getLevel() * 10) == 0)
{
ObjectPool.newEnemy(100 + random.nextInt(300), 0);
}
//500フレーム経過するとレベルが上昇
if ((Score.myscore >100)&&(Level.getLevel() == 0)){
Level.addLevel();
}
if ((150>Score.myscore)&&(Score.myscore >100)&&(Level.getLevel() == 1)){
title.drawGameclear(gBuf);
}
if ((Score.myscore >200)&&(Level.getLevel() == 1)){
Level.addLevel();
}
if ((Score.myscore >300)&&(Level.getLevel() == 2)){
Level.addLevel();
}
if ((Score.myscore >400)&&(Level.getLevel() == 3)){
Level.addLevel();
}
if ((Score.myscore >500)&&(Level.getLevel() == 4)){
Level.addLevel();
}
if((Score.myscore >600)&&(Level.getLevel() == 5)){
Level.addLevel();
}
if((Score.myscore >700)&&(Level.getLevel() == 6)){
Level.addLevel();
}
if((Score.myscore >800)&&(Level.getLevel() == 7)){
Level.addLevel();
}
//スペースキーが押されており、かつカウンタが3の倍数なら弾を撃つ(等間隔に弾を撃てる)
if ((shotkey_state == SHOT_PRESSED)&&(counter % 3 == 0))
{
objectpool.shotPlayer();
}
//ゲームオブジェクトの一括描画処理
objectpool.drawAll(gBuf);
//スコア描画
score.drawScore(gBuf);
score.drawHiScore(gBuf);
}
}
`
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
ざっくりですが、一例を書いてみます。
まずTitleにIsGameclearという関数を追加してください。
そしてこの関数はtitle.drawGameclearが呼ばれるとtrueになり、
title.drawGameclearが終わるとfalseが返るように実装してください。
(Title内にフラグ用のbool変数を用意しておけばそう難しくはないと思います)
後は下記のように書けばゲームクリア演出中かわかるようになるはずです。
if (title.IsGameclear())
{
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
ソースコードが無いので想像ですが、おそらく、スレッドの中で
・判定1 -> 描画1
・判定2 -> 描画2
・判定3 -> 描画3
と繰り返してしているので、取消できないか?という質問に至っている?と想像しました。
ゆえに、順次描画しているところを、ちょっと我慢して、
・判定1 -> 描画1のフラグを立てる
・判定2 -> 描画2のフラグを立てる
・判定3 -> 描画3のフラグを立てる
・全ての判定が終わったら、描画1・2・3のフラグを判定し、優先して描きたい描画だけ行う。
ということではいかがですか。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
まず皆さんも指摘しているとおりにクリアの最中にゲームオーバーになるというのがよくわかりませんが…
Java
の動きとして回答したいと思います。
まず前提として、処理を動いている途中に消す、というのは意図しないタイミングで処理が中断してしまう可能性があるのでおすすめしません。
また、スレッドの一時停止
はブレークポイント
のことでしょうか?
それでしたらこれはデバッグ時に使用するものであり、プログラムの動きではないので、結局動かすときに残ってしまうことになるかと思います。
途中で処理を抜ける、ならわかりますが。
ので、初期化処理を挟んであげるのがスタンダードかと思われます。
以下のように設計し直してみてください。
用意するクラス
- レベルアップクラス
- クリアと表示させるクラス
- ゲームオーバーと表示させるクラス
- 初期表示(クリアともゲームオーバーとも表示されない)クラス
- 実行メインクラス
※初期表示クラスの補足
表示されている文字が何であろうと、初期化し大元の表示に戻すクラス
処理を行うクラス(メインクラス){
処理を行うメソッド{
条件1(レベルアップしたか){
レベルアップ処理の呼び出し
クリア表示処理の呼び出し
初期表示処理の呼び出し
}
条件2(ゲームオーバーになるか){
ゲームオーバー処理の呼び出し
(必要であれば初期表示処理)
}
}
}
実際どのようにコードを書いているかわかりませんので言葉での説明になりましたがこのような感じになるかと思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.10%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
coco_bauer
2016/11/22 12:42
「レベルが上昇」、「クリアと表示」、「ゲームオーバー」という順に起こる訳ですから、クリアを表示しないというのは無理(その時にはゲームオーバーになっていないので)。クリアの条件が整っていたらクリアの表示を削除して、その後にゲームオーバーの表示をするという方針が良さそうに思えます。
ishi9
2016/11/22 12:54 編集
ゲームクリアの演出中にゲームオーバーになる事があるゲームって仕様的にどうなの?(普通のゲームは一旦ストップにしたり無敵にしたりしませんか?)とは思いますが、それが仕様だというのなら、ゲームクリアの演出を中断できるようにしておくのがいいかもしれませんね。でも一番に考えるべきはゲームの仕様ry
Y.H.
2016/12/06 12:18
マルチポスト https://teratail.com/questions/57790
2016/12/06 12:28
こちらの質問が他のユーザから「やってほしいことだけを記載した丸投げの質問」という指摘を受けました
「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。