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

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

ただいまの
回答率

87.37%

Processing、通信型シューティングゲームにて弾が発射されない

受付中

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,431

score 9

processingにて通信型シューティングゲームを作成しています。
ゲーム概要としては画面の上と下に横移動しか出来ない自機を2つ配置します。それぞれがスペースキーで弾を打ちます。弾の発射などの基本動作はサーバ側で制御し、クライアント側では自機の位置座標と打った弾の座標を送り、サーバから送られるサーバ側の自機や敵に関する座標を受け取り表示するコードを組みました。
サーバ側の動作はうまくいくのですが、クライアント側の自機から弾が発射されません。
自機の位置に弾を生成し、それを画面外出るまでfor文で回すというシンプルな方法を使っています。サーバ側は同じ概要のコードで正常に動作しているので、データの送受信もしくはクライアント側の弾に関する関数(PlayerMove,bombP2Move辺り)に問題があるとおもいます。デバックがわかりません。詳しい方教えてください。

以前、敵の動きを含めた全コードに関する質問をしましたが、質問の幅が広すぎたので自機の動きに関する部分だけに焦点を当てて質問させてもらいます。https://teratail.com/questions/187947

サーバ側のコード

//ソケット通信のためのライブラリを読み込み
import processing.net.*;
Server server;
//ポート番号を指定(今回は20000)
int port = 20000;


int px1=240,py1=50,ph1=50,pw1=50; //プレイヤー1の座標と高さ幅
int px2=240,py2=700,pw2=50,ph2=50;//プレイヤー2の座標と高さ幅



int[] bPx1= new int[6];  //Player1弾
int[] bPy1= new int[6];
int bcntS; //残弾表示
int[] bPx2 = new int[6];  //Player2弾
int[] bPy2= new int[6];



int bombWait;
int keyKeep; //押下中のキー



void setup(){
  //サーバを生成prot番ポートで立ち上げ
  server = new Server(this, port);

  size(600,800);
  noStroke();
  frameRate(30);

  gameInit(bPy1); //ゲーム初期化
   gameInit(bPy2); 
}

void draw(){
  background(100);
  px1 = playerMove(bPx1,bPy1,px1,pw1);  
  rect(px1,py1,pw1,ph1);
   rect(px2,py2,pw2,ph2);
  bombP1Move(bPx1,bPy1);
  FromC(); //クライアント側からデータ受け取る
   ToC(); //クライアント側にデータを送る



}
void FromC(){
  Client c = server.available();
  if(c != null) {
    //改行コード('\n')まで読み込む
    String msg = c.readStringUntil('\n');
    if (msg != null){
      //メッセージを空白で分割して配列に格納
      String[] data = splitTokens(msg);


       px2 = int(data[0]);
       bPx2[0] = int(data[1]); bPx2[1] = int(data[2]); bPx2[2] = int(data[3]);
       bPy2[0] = int(data[4]); bPy2[1] = int(data[5]); bPy2[2] = int(data[6]);


    }
  }
}

    void ToC(){
    //全てのデータの送信
       String msg = px1+ " "+bPx1[0] + " " +bPx1[1] + " " +  bPx1[2] +" "+bPy1[0] + " " +bPy1[1] + " " +  bPy1[2] +" " + bcntS +'\n';
      print("server: " + msg);
      //サーバが接続しているすべてのクライアントに送信
      //(複数のクライアントが接続している場合は全てのクライアントに送信)
      server.write(msg);
    }


void gameInit(int[] bPy){
 // keyy = 0;
 //px1 =240;


 for(int i =0; i<12; i++){
   //ef[i] = 2;

   }
   for(int i=0; i<6; i++){
     bPy[i] = -20;  //-20:未使用

   }
   bombWait = 0;
   keyKeep = 0;



}
void gameTitle(){
  //keyy =1;
}

void gamePlay(){
  px1 = playerMove(bPx1,bPy1,px1,pw1);  
  rect(px1,py1,pw1,ph1);

   rect(px2,py2,pw2,ph2);
  bombP1Move(bPx1,bPy1);

}


int playerMove(int[] bPx,int[] bPy,int px,int pw){ 

    if( ( keyKeep == LEFT) && (px>0)  ){
      px -= 3;
    }
    if( ( keyKeep == RIGHT) &&(px <600-pw)  ){
      px += 3;
    }
    // }
    if( bombWait>0){
      bombWait--;
    }
    if( (keyPressed == true) && (key == ' ' ) && (bombWait == 0) ){
      bombWait =10; //10秒まち
      bombP1Add(bPx,bPy,px,pw);
      // bombP2Add(bPx,bPy,px,pw);
    }
    return px; 
  }

void keyPressed(){
  if (key == CODED){
    if(   (keyCode == LEFT) || (keyCode == RIGHT)  ){
      keyKeep = keyCode;
    }
  }
}
void keyReleased(){
  if (key == CODED){
    if(   (keyCode == LEFT) || (keyCode == RIGHT)  ){
      keyKeep = 0;
    }
  }
}



  void bombP1Add(int[] bPx,int[]bPy,int px,int pw){
    for(int i=0; i<3; i++){
      if ( bPy[i] ==  -20){ //未使用の弾を使う
      bPx[i] = px + (pw/2)-15; //Pの中心
      bPy1[i] = 70;
      break;     //一発のみ
      }
    }
  }

void bombP1Move(int[] bPx,int[]bPy){
  int bcntS =3;
  for(int i= 0; i<3; i++){
    if ( bPy[i] >0){
      bPy[i] += 5;
      bcntS--;
    }
    if ( bPy[i] >800){ //画面上外
      bPy[i] = -20; //未使用に戻す
    }
    rect(bPx[i],bPy[i]-8,30,30);



  }
  for(int i=0; i< bcntS; i++){
    rect( 230+i*26,10,25,25);

  }
}

クライアント側のコード(恐らくこちらに問題あり)

//ソケット通信のためのライブラリを読み込み
import processing.net.*;
Client client;

//他のマシンに接続するときは適切に変更
String serverAdder = "10.20.216.125";
//ポート番号を指定(今回は20000)
int port = 20000;



int px1=240,py1=50,ph1=50,pw1=50; //プレイヤー1の座標と高さ幅
int px2=240,py2=700,pw2=50,ph2=50;//プレイヤー2の座標と高さ幅
int[] bPx1= new int[6];  //Player1弾
int[] bPy1= new int[6];
int[] bPx2 = new int[6];  //Player2弾
int[] bPy2= new int[6];

int bombWait;
int keyKeep; //押下中のキー


void setup(){
//指定されたアドレスとポートでサーバに接続
  client = new Client(this, serverAdder, port);

  //サーバー側
  size(600,800);
  noStroke();
  frameRate(30);

  gameInit(bPy1); //ゲーム初期化
   gameInit(bPy2); 
}

void draw(){
 background(100);
 rect(px1,py1,pw1,ph1); //サーバ側プレイヤー

  px2 = playerMove(bPx2,bPy2,px2,pw2);  
   rect(px2,py2,pw2,ph2); //クライアント側プレイヤー

   bombP2Move(); //クライアント側の弾の動き

   //サーバ側の弾の生成
   int bcntS =3;
  for(int i= 0; i<3; i++){
    rect(bPx1[i],bPy1[i]-8,30,30);

      bcntS--;
  }
  //残弾の表記
  for(int i=0; i< bcntS; i++){
    rect(230+i*26,10,25,25);

  }



  //サーバに送信するメッセージを作成
  //空白で区切り末尾は改行
  String msg = px2+" "+bPx2[0]+" "+bPx2[1]+" "+bPx2[2]+" "+bPy2[0]+" "+bPy2[1]+" "+bPy2[2]+"\n";
  print("server: " + msg);
  //サーバが接続しているすべてのクライアントに送信
  //(複数のクライアントが接続している場合は全てのクライアントに送信)
  client.write(msg);

 }

 //サーバーからデータを受け取るたびに呼び出される関数
void clientEvent(Client c) {
  //サーバからのデータ取得
  String msg = c.readStringUntil('\n');
  //メッセージが存在する場合
  if (msg != null) {
    //改行を取り除き,空白で分割して配列に格納
    String[] data = splitTokens(msg);

     //int()で文字列から整数に変換

    px1 = int(data[0]);  bPx1[0] = int(data[1]);    bPx1[1] = int(data[2]);     bPx1[2] = int(data[3]);    bPy1[0] = int(data[4]);   bPy1[1] = int(data[5]);    bPy1[2] = int(data[6]); 


  }
}

void gameInit(int[] bPy){

   for(int i=0; i<6; i++){
     bPy[i] = -20;  //-20:未使用

   }
   bombWait = 0;
   keyKeep = 0;

}



  //クライアント側の弾の動き
void bombP2Move(){
  int bcnt =3;
  for(int i= 0; i<3; i++){
    if ( bPy2[i] >0){
      bPy2[i] -= 5;
      bcnt--;
    }
    if ( bPy2[i] >0){ //画面上外
      bPy2[i] = -20; //未使用に戻す
    }
    rect(bPx2[i],bPy2[i]+8,30,30);

  }
  for(int i=0; i< bcnt; i++){
    rect(230+i*26,750,25,25);

  }
}



int playerMove(int[] bPx,int[] bPy,int px,int pw){ //**** void → int
    // if( (keyPressed == true) && (key == CODED) ){
    if( ( keyKeep == LEFT) && (px>0)  ){
      px -= 3;
    }
    if( ( keyKeep == RIGHT) &&(px <600-pw)  ){
      px += 3;
    }
    // }
    if( bombWait>0){
      bombWait--;
    }
    if( (keyPressed == true) && (key == ' ' ) && (bombWait == 0) ){
      bombWait =10; //10秒まち
      //bombP1Add(bPx,bPy,px,pw);
      bombP2Add();
       // bombP2Add(bPx,bPy,px,pw);
    }
    return px; 
  }

  //クライアント側の弾追加発射
   void bombP2Add(){
  //void bombP2Add(int[] bPx,int[]bPy,int px,int pw){
    for(int i=0; i<3; i++){
      if ( bPy2[i] ==  -20){ //未使用の弾を使う
      bPx2[i] = px2 + (pw2/2)-15; //Pの中心
      bPy2[i] = 650;
      break;     //一発のみ
      }
    }
  }

    void keyPressed(){
  if (key == CODED){
    if(   (keyCode == LEFT) || (keyCode == RIGHT)  ){
      keyKeep = keyCode;
    }
  }
}

void keyReleased(){
  if (key == CODED){
    if(   (keyCode == LEFT) || (keyCode == RIGHT)  ){
      keyKeep = 0;
    }
  }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

0

  //クライアント側の弾の動き
void bombP2Move(){
(略)
    if ( bPy2[i] >0){ //画面上外
      bPy2[i] = -20; //未使用に戻す
    }
(略)
}

ここはおかしくありませんか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/08 14:06

    回答ありがとうございます。
    画面下にある自機付近から生成され上に向かって発射される弾が画面の一番上まで行ったら未使用の状態にする。というコードなんですがどこがおかしいですか?

    キャンセル

  • 2019/05/08 14:31

    "noberon さんが 書いたつもりの仕様" を確認しているわけではありません.
    このコードがそのように書かれているかを調べるのがデバックの第一歩ですので, 思い込みやコメントに惑わされずに, コードを読んでみてください.

    キャンセル

  • 2019/05/08 16:03

    合っているはずなのに動かない、と考えていると間違いを見落とします。動かないのだからどこかが間違っているはず、そう信じて探さないと。

    bombP2Add()で爆弾を生成すると、
    bPy2[i] = 650;
    ですね。これがbombP2Move()で
    if ( bPy2[i] >0){
    でどういう挙動を引き起こしますか?

    キャンセル

  • 2019/05/08 16:23

    あ、不等号の向きが逆ですね。お二人のおっしゃる通り思い込みでお手数をおかけしてすみません。ありがとうございます。

    キャンセル

0

基本的な構造自体からかなり突っ込みどころが多いですね。
シューティングゲームは常に弾を発射している状態が多いので、打った弾の座標を送るのは設計的にまずい気がします。
自機の弾を発射する座標が決まっているのなら、スペースを押下を送信すれば同じように作れそうな気はします。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

-1

作成されているゲームに関して幾つもご質問されているようですが, こちらはデバックするところでは無いと思います.
「デバックの方法が分からない」ということでしたら, そのようなご質問をするほうが良いかと思います.

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/08 14:02

    アドバイスありがとうございます。訂正してきます。

    キャンセル

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

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

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