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

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

ただいまの
回答率

88.79%

processing/jave 関数への引数渡し

解決済

回答 1

投稿 編集

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

noberon

score 9

Processing/javaの関数への引数渡しの質問です。
現在processing でシューティングゲームを作っていて自機の動作(基本操作はキーボードで左と右へ移動、縦は固定)がうまくいきました。そこで自機の数を増やすために、自機の動きの部分を関数にして引数を渡すだけで自機を量産しようとしたところ、自機自体が動かなくなってしまいました。

おそらく関数、引数渡す段階(gamePlay関数の中のplayerMove関数辺り)で上手くいってないと思うので詳しい方教えてください。当方プログラミング初心者のため下手な質問ですみません。

文字数制限があるので変更後のコードは以下に、変更前のコードは編集依頼の返信画面に載せてあります。
お手数おかけしますがご確認よろしくお願いします。

,,,processing 変更後(引数渡し)
int keyy; //流れ管理
PImage player1,bg, bombP;// bP: プレイヤーの弾
PImage[] enemy = new PImage[2];

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

float[] ex =new float[12]; //敵の座標
int[] ey = new int[12];
int[] ef = new int[12]; //フラグ  0:左方向  1:右方向 2:未使用
float[] ev = new float[12]; //敵の移動速度

int[] bPx1 = new int[6];  //Player弾
int[] bPy1= new int[6];
int[] bPx2 = new int[6];  //Player弾
int[] bPy2= new int[6];

int[] bEx = new int[20];  //Enemy弾
int[] bEy = new int[20];
int[] bEv = new int[20]; //E弾速度

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

int scoreS = 0;
int scoreC = 0;

void setup(){
size(600,800);
noStroke();
frameRate(30);
imgLoad();
gameInit(bPy1); //ゲーム初期化
}

void draw(){
background(100);
if( keyy == 0){
gameTitle();

}else if( keyy == 1){
//px1,py1,pw1,ph1,bPx1,bPy1
gamePlay();
}else if( keyy == 2){
gameOver();
}

}

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

for(int i =0; i<12; i++){
ef[i] = 2;
//ex[i] = i*20;
//ey[i] = 110 + i*50;
//ev[i] =random(0.5,2.5);
}
for(int i=0; i<6; i++){
bPy[i] = -20;  //-20:未使用
}
bombWait = 0;
keyKeep = 0;

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

}
void gameTitle(){
keyy =1;
}
//int px,int py,int pw,int ph,int[]bPx,int[]bPy
void gamePlay(){
playerMove(bPx1,bPy1,px1,pw1);
image(player1,px1,py1,pw1,ph1);
enemyMove();
enemyDisp(bPx1,bPy1);
bombPMove(bPx1,bPy1);
bombEMove(px1,py1,pw1,ph1);
scoreDisp();
}
void gameOver(){
scoreDisp();
}

void imgLoad(){
player1 = loadImage("player2.png");
enemy[0] =loadImage("敵.png");
bombP =loadImage("2弾.png");
}
void playerMove(int[] bPx,int[] bPy,int px,int pw){
// 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秒まち
bombPAdd(bPx,bPy,px,pw);


}
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 enemyMove(){
for(int i=0; i<12; i++){
ex[i] += ev[i];
if( (ef[i] ==0) && (ex[i] < -50)  ){
ef[i]= 2;  //画面外皮表示
}
if( (ef[i] ==1) && (ex[i] >600)  ){
ef[i]= 2;  //画面外皮表示
}
}
if ( random(1000)<20){ //敵の発生率
enemyAdd();
}
}

void enemyDisp(int[] bPx,int[] bPy){
for(int i=0;  i<12; i++){
if ( ef[i] <2){
image(enemy[0],ex[i],ey[i],50,50);

for(int j=0; j<6; j++){
if(  (bPx[j] < ex[i]+50) && (bPx[j]+25 > ex[i]) 
&&  (bPy[j] < ey[i]+50) && (bPy[j]+25 > ey[i]) ){
bPy[j] = -20;
ef[i] = 2;
scoreS +=10;
break;
}

}

}
if ( (ef[i] < 2) && (random(2000)<10)  ){ //敵爆弾発生率
bombEAdd(int  (ex[i]),  ey[i] );
}

}

void enemyAdd(){
for(int i=0; i<12; i++){
if( ef[i] == 2){ //未使用の中から敵を追加
ev[i] = random(0.5,2.5);
if (random(100) <50){
ef[i] = 0 ; //左
ex[i] = 600;
ev[i] =-ev[i] ;
}
else{
ef[i] = 1;
ex[i]= -80;
}
ey[i] = int(random(150,650));
break;
}
}
}

void bombPAdd(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の中心
bPy[i] = 70;
break;     //一発のみ
}
}
}

void bombPMove(int[] bPx,int[]bPy){
int bcnt =3;
for(int i= 0; i<3; i++){
if ( bPy[i] >0){
bPy[i] += 5;
bcnt--;
}
if ( bPy[i] >800){ //画面上外
bPy[i] = -20; //未使用に戻す
}
image(bombP,bPx[i],bPy[i]-8,30,30);
//for(int e= 0; e<12; e++){
// if(  (bPx[i] < ex[e]+50) && (bPx[i]+25 > ex[e]) 
//  &&  (bPy[i] < ey[e]+50) && (bPy[i]+25 > ey[e]) ){
//    scoreS +=10;

//  }
//}

}
for(int i=0; i< bcnt; i++){
image(bombP, 230+i*26,10,25,25);
}
}

void bombEAdd(int  xx,  int  yy){
for( int i=0;  i<20;  i++){
if ( bEy[i] ==  -20){
bEx[i] = xx +18;
bEy[i] = yy;
if(     random(100) < 50  ){
bEv[i] = 1;
}else{
bEv[i] = -1;
}
break;
}
}
}

void bombEMove(int px,int py,int pw,int ph ){
for( int i = 0;  i<20;  i++){
//bEv[i] = 1;
if (    (bEy[i] > 0)   ){
//if(     random(100) < 50  ){
bEy[i] -= bEv[i];
// }
//else{
//  bEy[i] +=bEv[i];
//}
}
if(( bEy[i] <= 0)   ||  ( bEy[i] >=800)  )  {
//if(bEy[i] < 90)   {
bEy[i]  = -20;
}

if(  (bEx[i] < px+pw)  && (bEx[i]+10 >px) 
&&  (bEy[i] < py+ph)  && (bEy[i]+10 >py)  )  {
bEy[i]  = -20;
scoreS -=50;
}

fill(0);
rect(bEx[i],bEy[i],10,10);
// image(bombP,bEx[i],bEy[i]-8,10,10);
}
}

void scoreDisp(){
textSize(24);
text( "score:"+scoreS, 10,25);
}

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • jimbe

    2019/05/04 02:51

    https://teratail.com/questions/187520 と同じご質問でしたら, 一方を削除依頼してください. 何度も書かれても回等が付き難くなるだけです. 文言の変更等は, ご質問の編集で行ってください.
    また, コードは「```java」の行と「```」の行で挟んで頂くと分かり易くなります.
    変更して動かなくなったのでしたら, 変更前と変更後のコードをご提示ください.

    キャンセル

  • thkana

    2019/05/04 09:25

    文句を言ってばかりでも...と思って変更後とされる部分を切り出してみましたが、いくつかの変数や関数が未定義になります。あなたが試したものそのままを掲載して下さい。

    キャンセル

  • noberon

    2019/05/04 12:49

    質問の方には文字数制限的に変更後しか載せられなかったため、こちらに変更前のコードを貼っておきます。

    '''processing 変更前

    int keyy; //流れ管理
    PImage player1,bg, bombP;// bP: プレイヤーの弾
    PImage[] enemy = new PImage[2];

    int px,pw=50,py=50,ph=50;

    float[] ex =new float[12];
    int[] ey = new int[12];
    int[] ef = new int[12]; //フラグ  0:左方向  1:右方向 2:未使用
    float[] ev = new float[12]; //敵の移動速度

    int[] bPx = new int[6]; //Player弾
    int[] bPy = new int[6];

    int[] bEx = new int[20]; //Enemy弾
    int[] bEy = new int[20];
    int[] bEv = new int[20]; //E弾速度

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

    int scoreS = 0;
    int scoreC = 0;

    void setup(){
    size(600,800);
    noStroke();
    frameRate(30);
    imgLoad();
    gameInit(); //ゲーム初期化
    }

    void draw(){
    background(100);
    if( keyy == 0){
    gameTitle();

    }else if( keyy == 1){
    gamePlay();
    }else if( keyy == 2){
    gameOver();
    }

    }

    void gameInit(){
    keyy = 0;
    px =240;
    for(int i =0; i<12; i++){
    ef[i] = 2;
    //ex[i] = i*20;
    //ey[i] = 110 + i*50;
    //ev[i] =random(0.5,2.5);
    }
    for(int i=0; i<6; i++){
    bPy[i] = -20; //-20:未使用
    }
    bombWait = 0;
    keyKeep = 0;

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

    }
    void gameTitle(){
    keyy =1;
    }
    void gamePlay(){
    playerMove();
    image(player1,px,py,pw,ph);
    enemyMove();
    enemyDisp();
    bombPMove();
    bombEMove();
    scoreDisp();
    }
    void gameOver(){
    scoreDisp();
    }

    void imgLoad(){
    player1 = loadImage("player2.png");
    enemy[0] =loadImage("敵.png");
    bombP =loadImage("2弾.png");
    }
    void playerMove(){
    // 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秒まち
    bombPAdd();

    }
    }
    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 enemyMove(){
    for(int i=0; i<12; i++){
    ex[i] += ev[i];
    if( (ef[i] ==0) && (ex[i] < -50) ){
    ef[i]= 2; //画面外皮表示
    }
    if( (ef[i] ==1) && (ex[i] >600) ){
    ef[i]= 2; //画面外皮表示
    }
    }
    if ( random(1000)<20){ //敵の発生率
    enemyAdd();
    }
    }


    void enemyDisp(){
    for(int i=0; i<12; i++){
    if ( ef[i] <2){
    image(enemy[0],ex[i],ey[i],50,50);

    for(int j=0; j<6; j++){
    if( (bPx[j] < ex[i]+50) && (bPx[j]+25 > ex[i])
    && (bPy[j] < ey[i]+50) && (bPy[j]+25 > ey[i]) ){
    bPy[j] = -20;
    ef[i] = 2;
    scoreS +=10;
    break;
    }

    }

    }
    if ( (ef[i] < 2) && (random(2000)<10) ){ //敵爆弾発生率
    bombEAdd(int (ex[i]), ey[i] );
    }
    }
    }

    void enemyAdd(){
    for(int i=0; i<12; i++){
    if( ef[i] == 2){ //未使用の中から敵を追加
    ev[i] = random(0.5,2.5);
    if (random(100) <50){
    ef[i] = 0 ; //左
    ex[i] = 600;
    ev[i] =-ev[i] ;
    }
    else{
    ef[i] = 1;
    ex[i]= -80;
    }
    ey[i] = int(random(150,650));
    break;
    }
    }
    }

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

    void bombPMove(){
    int bcnt =3;
    for(int i= 0; i<3; i++){
    if ( bPy[i] >0){
    bPy[i] += 5;
    bcnt--;
    }
    if ( bPy[i] >800){ //画面上外
    bPy[i] = -20; //未使用に戻す
    }
    image(bombP,bPx[i],bPy[i]-8,30,30);
    //for(int e= 0; e<12; e++){
    // if( (bPx[i] < ex[e]+50) && (bPx[i]+25 > ex[e])
    // && (bPy[i] < ey[e]+50) && (bPy[i]+25 > ey[e]) ){
    // scoreS +=10;

    // }
    //}

    }
    for(int i=0; i< bcnt; i++){
    image(bombP, 230+i*26,10,25,25);
    }
    }

    void bombEAdd(int xx, int yy){
    for( int i=0; i<20; i++){
    if ( bEy[i] == -20){
    bEx[i] = xx +18;
    bEy[i] = yy;
    if( random(100) < 50 ){
    bEv[i] = 1;
    }else{
    bEv[i] = -1;
    }
    break;
    }
    }
    }

    void bombEMove(){
    for( int i = 0; i<20; i++){
    //bEv[i] = 1;
    if ( (bEy[i] > 0) ){
    //if( random(100) < 50 ){
    bEy[i] -= bEv[i];
    // }
    //else{
    // bEy[i] +=bEv[i];
    //}
    }
    if(( bEy[i] <= 0) || ( bEy[i] >=800) ) {
    //if(bEy[i] < 90) {
    bEy[i] = -20;
    }

    if( (bEx[i] < px+pw) && (bEx[i]+10 >px)
    && (bEy[i] < py+ph) && (bEy[i]+10 >py) ) {
    bEy[i] = -20;
    scoreS -=50;
    }


    fill(0);
    rect(bEx[i],bEy[i],10,10);
    // image(bombP,bEx[i],bEy[i]-8,10,10);
    }
    }

    void scoreDisp(){
    textSize(24);
    text( "score:"+scoreS, 10,25);
    }

    キャンセル

回答 1

checkベストアンサー

+1

引数は値渡しですので, px1 は playerMive 内で変更しても 呼び出し元の px1 は変更されません.
戻り値として返すか, オブジェクト(の参照)を渡して変更する形にすると良いと思います.


追記

playerMove から px1(px) の値を返す場合です. "****" のコメントの行が修正箇所です.
なお, コンパイル確認等していません.

呼び出し側

  px1 = playerMove(bPx1,bPy1,px1,pw1); //**** "px1="を追加


playerMove

  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秒まち
      bombPAdd(bPx,bPy,px,pw);
    }
    return px; //**** 追加
  }

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/04 12:40

    オブジェクトを渡して変形というのがわからなかったので、returnで戻そうとしたvoid関数なので戻せずint
    に返してみてもうまく動かずお手上げ状態です。お手数ですがPlayerMoveの正しいコードを教えていただけませんか?

    キャンセル

  • 2019/05/04 14:04 編集

    「PlayerMoveの正しいコード」は作者にしか分かりません. 「うまく動かず」では無く, どう修正されてどう動かないのかをご提示頂かなければ, こちらには何も分からないのです.
    一応私が想定した動作のコードは追記致しましたが, 回答本文にも書きました通り, playerMove メソッドで値を変更したことを外部に反映する方法は, (構造そのものの変更も含めれば)外にもあります.
    ですので「正しいコード」の判断はありません.

    キャンセル

  • 2019/05/04 14:36

    こちらの不適切な表現に対し細かく教えていただきありがとうございます。
    無事に時期が左右に動きました。本当にありがとうございました。

    キャンセル

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

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

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