質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.75%

  • Processing

    237questions

    Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

processngでのゲーム作りに関して

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 170

plarex

score 4

ゲーム画面の切り替えに関して

processingで弾幕ゲームを作成しています。
質問① 弾と自機、レーザーとボスの当たり判定に関して、当たったと識別する条件は書けたのですが、その後、ゲームが停止して、GAMEOVERとGAMECLEARの画面に切り替えるコードの書き方が分かりません。

質問② ゲームスタート画面の表示について、左クリックでゲーム画面に切り替えるコードの書き方が分かりません

 該当のソースコード

Bullet bullet;          
private Boss boss = new Boss(160, 150);                 
private ArrayList<Bullet> danmaku = new ArrayList<Bullet>();      

void setup() {
  size(320, 480);

  frameRate(30);

  noCursor();  // clear mouse cursor

  bullet = new Bullet(width/2, height/2, 10, 0, 0 ); 
}
// ship class
class ship {
  private int sx, sy;
  ship(int x, int y) {
    sx = x;
    sy = y;
  }
  void update() {
    sx = x;
    sy = y;
    stroke(255, 255, 255);
    noFill();
    triangle(x, y -7, x - 10, y + 7, x + 10, y + 7);

    if (mousePressed) {
      line(x, y - 7, x, 0);
      if (abs(sx -boss.tx) < (boss.bw /2))
        boss.hit();
    }
  }
  void hit(){
    int ship.hp = 5;
    ship.hp -= 1;
    if(ship.hp == 0){
     fill( 255, 0, 0 );
     textSize( 30 );
     text( "GAME OVER", width/2, height/2 );
     //Enterを押してリトライできるコードを書きたい



}     
  }
}
class Boss {
  private int tx, ty;
  private int dx, dy;
  private int bw = 20;
  private int bh = 10; 
  private long routine = 0;

  Boss(int x, int y) {
    tx = x;
    ty = y;
    dx = 1;
    dy = -5;
  }
  void move() {
    tx += dx;
    ty += dy;
    if (tx < 0 || tx > width) {
      dx*= -1;
    }
    if (ty < 0 || ty > height) {
      dy*= -1;
    }
   stroke(255,204,0);
   rect(tx - bw/2, ty + bh/2 , bw, bh);
}
  void doShinking() {
    routine++;
    if (routine % 10 == 0) {
      move();
    }
    if (routine % 30 == 0) {
      danmaku.addAll(this.shot());                           
      println("#shot!!" +routine + ":" + tx + "," + ty);
    }
  }
   void hit(){
    int boss.hp = 8;
    if(boss.hp == 0){
        /ここにボスが消えて、ゲームクリアの画面を出すコードを書きたい      


  ArrayList<Bullet> shot() {
    ArrayList<Bullet> danmaku = new ArrayList();
    for (int i = 0; i < 360; i+= 10) {                            
      double rad = radians(i);
      danmaku.add(new Bullet(this.tx, this.ty, 10, Math.cos(rad), Math.sin(rad)));           
    }
    return danmaku;            
  }
}
// Bullet class

class Bullet {

  private double tx, ty;
  private final double tr;
  private double dx, dy;
  private boolean is_alive = true;
  Bullet(double x, double y, double r, double temp_dx, double temp_dy ) {
    tx = x;
    ty = y;
    tr = r;
    dx = temp_dx;
    dy = temp_dy;
  }
  boolean isAlive() {
    return is_alive;
  }
  void update() { 
    tx += dx;
    ty += dy;
    //area check
    if (Math.min(tx, ty) < 0) {
      is_alive = false;
      //println("#" + tx + "," + ty);
      return ;
    }
    if (tx > width || ty > height) {
      is_alive = false;
      return ;
    }
    // hit check
    if (dist(tx, ty, ship.sx, ship.sy) < tr/2) {
      ship.hit();

      return true;


      stroke(255, 0, 0);

      ellipse((float)tx, (float)ty, (float)tr, (float)tr);
    }
  }
  void draw() {
    background(0); // clear

    ship(mouseX, mouseY);
    boss.doShinking();
    ship.hit();

    for (int i = danmaku.size() -1; i  >= 0; i--) {       
      Bullet b = (Bullet)danmaku.get(i);
      if (!b.isAlive()) {
        danmaku.remove(i);
        continue;
      }
      b.update();
    }
  }
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

基本的な考え方は前回の質問Bulletクラスと同じです。

  1. ゲームスタート
  2. ゲームクリア
  3. ゲームオーバー

というゲームの進行状態(シーンとステージ)という概念が出てきたため、
各シーンの状態を表すGameSceneとゲームのステージの状態(GameStage)を管理するクラスを作成します。
BossクラスとShipクラスはGameStageクラスに属します。

/ここにボスが消えて、ゲームクリアの画面を出すコードを書きたい 

コメント欄記載の部分には直接画面表示のコードを書かない方が良いです。
プログラム内のデータと表示処理は分けた方が、表示条件を追加した時に苦労しないです。

1,ゲームのシーンを定義します。
質問文の要件としてあるのはスタート、(プレイ)、ゲームクリア、ゲームオーバーです。
括弧内のプレイは質問文にはないですが、隠れていた要件です。

enum GameScene {
 START,PLAY,CLEAR,OVER;
}
private GameScene scene = GameScene.START;

enum変数:sceneで各シーン遷移を管理します。

void draw()関数内にてsceneの値を判断して、表示処理を分岐させてください。(※この部分は後述します)

2,次にBossクラスについて
2-1,Bossクラスに生存状態を返す関数を作成します。

  boolean isAlive() {
    return hp != 0;
  }

2-2,Bossクラスのprivate long routine = 0;の下行に以下の内容を追加します。

private int hp = 8;

2-3,BossクラスのhitメソッドはBosshpを減らすだけにします。
※hitではなく、被ダメージなので、damageという命名の方が適切かもしれません。
命名に関しては質問者様のわかり易さを優先させてくださいな。
2-4, 2-1~2-3に関してShipクラスにもBossと同じ事が適用できます。共通の親クラスを定義し継承するのも一つの手かと。

3,GameStageクラスについて
3-1,ソースコードの先頭行で宣言していた、ボスクラスの変数:bossGameStageクラスに移動します。あとShipクラスも移動したほうがいいですが、難しそうでしたらそのままで。

private Boss boss = new Boss(160, 150);


3-2,update関数を定義します。draw()関数より呼び出します。
update関数内で、boss.doShinking();を呼び出します。
update関数内でbossis_alive()shipクラスのis_alive()if文で判定して、GameScenescene変数を更新します。

※ゲームオーバーやゲームクリア時の表示として既に発射されていた弾幕をどう扱うかの問題があります。

3-3,draw関数にて、について以下の判断を行います。

変数:sceneの値 クリック判定 行うこと
START - ゲームスタート画面表示。
START mousePressed sceneをPLAYに
PLAY - GameStageクラスのupdateを呼び出す。
OVER - ゲームオーバー画面を表示。
OVER mousePressed sceneをSTARTに
CLEAR - ゲームクリア画面を表示。
CLEAR mousePressed sceneをSTARTに

コード行数が増えて処理が複雑になるとコード管理ができなくなる恐れがあるため、
あまりゲームの仕様を増やさないほうがよいかもしれません。
一度ゲームのステージの進行状態を整理して、メモに書き出してみると条件判定の漏れがなくなります。
例えば、追加要件として道中に雑魚MOBを増やした時に、ボスはまだ表示されてないが、その扱いをどう判断するのか。などなど。

最後に質問文のソースコードはコンパイルエラーがないソースコードを載せてくださいな。


追記コードを見て気になった点。
Bulletクラスのupdateメソッドのship.hit();を行った後に、Bulletの生存フラグをFalseにしないと、次のループで2重判定されてしまいます。
今よくよく考えてみたら、BossクラスやShipクラスと同様にhp値を保持し、HP1として1として設定し、減算するほうがシンプルな気がしてきました。

class GameObject {
  protected int x;
  protected int y;
  protected int dx;
  protected int dy;
  protected int hp;
  GameObject(int x,int y){
    this(x,y,1,1,1);
  }
  GameObject(int x,int y, int dx,int dy, int hp){
    this.x = x;
    this.y = y;
    this.dx = dx;
    this.dy = dy;
    this.hp = hp;
  }
  public boolean isAlive() {
    return this.hp != 0;
  }
}


GameObjectクラスをBossクラス,Ship,クラスBullet,クラスは継承し、コンストラクタ内でsuper()で呼び出す。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Processing

    237questions

    Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。