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

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

ただいまの
回答率

91.28%

  • Java

    10819questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Processing

    175questions

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

processing javaでゲーム開発

解決済

回答 1

投稿 編集

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

haniwa3

score 12

processingと言うものでjavaを使ったシューティングゲームを作成しています。
自機から弾を打ち、敵機に当たったら、敵機のライフをインクリメントして
インクリメントした値に応じてメソッドを呼び出す仕組みを考えましたが、
呼び出されたと思ったら、すぐに消えてしまいます。
消える原因は下記に記載しています、enemy_life = 3の値が変わらないことが原因だと言うことはわかっていますので、変えるにはどうしたらいいのかご教示いただきたいと思います。技術者の方、何卒よろしくお願い致します。

##################################################

//BGM
import ddf.minim.*;
Minim minim;
AudioPlayer bgm;
AudioPlayer shot_sound;
AudioPlayer bakuhatu_sound;

int GAMEOVER_count,GAMEOVER_number,LIFE,startWordCount,mouseClickCount,quiteNumber;
String[] startWord = {"","A","HAPPY NEW","YEAR READY?"};

PImage space;

PImage player;
int player_x;
int player_y;
int player_life;

PImage shot;
int shot_x; 
int shot_y; 
int shot_life;

//敵の行動を定義
PImage enemy;
int enemy_life;        
int enemy_width = 60;      //敵の幅
float enemy_x, enemy_y;    //敵の位置    
float xspeed = 6;  // 敵のスピード(横)
float yspeed = 10;  //敵のスピード(縦)
int xdirection = 1;  // 右か左か
int ydirection = 1;  // 上か下か

PImage enemy2;
float enemy2_x, enemy2_y;

//BOSS
PImage boss;
int boss_x;
int boss_y;

//爆発
PImage bakuhatu;
PImage kieru;

//背景のスクロールを制御
int state;
float t;
long t_start = millis();//背景スクロール用
final int SCROLL_SPEED = 4;//スクロールスピード
int scroll_x, scroll_y;//スクロールの横と縦

/*-------Setup-------*/
void setup(){
size(800,350);

noStroke();
noCursor();

GAMEOVER_count=0;
GAMEOVER_number=2;
mouseClickCount=0;
quiteNumber=0;

enemy_x = 800;
enemy_y = height/2;
enemy = loadImage("enemy1.png");

enemy2_x = 400;
enemy2_y = 100;
enemy2 = loadImage("enemy2.png"); 

bakuhatu = loadImage("enemy_bakuhatu.png");
kieru = loadImage("kieru.png");
player = loadImage("player.PNG");

shot = loadImage("shot.PNG");

//BGM
minim = new Minim(this); 
bgm = minim.loadFile("digitalworld.MP3");
//ショット音
shot_sound = minim.loadFile("launcher1.mp3");
//爆発音
bakuhatu_sound = minim.loadFile("small_explosion1.mp3");

rectMode(CENTER);//長方形の基準を真ん中に
}

/*-------Draw-------*/
void draw(){
background(0);    
game();
}

void game(){
//敵機のライフを3に設定
enemy_life = 3;
print("enemy_life" + enemy_life);
frameRate(30);

Player pl = new Player();
pl.player_move();

Shot sh = new Shot();
sh.shot_fire();
sh.shot_move();

Hantei hit = new Hantei();
hit.atari();

if(enemy_life == 3){
//敵1
Enemy en = new Enemy();
en.enemy_action1();
}else if(enemy_life == 2){
//敵2
Enemy2 en2 = new Enemy2();
en2.enemy_action2();
}     
}

/*-------自機------*/
class Player{
void player_move(){
player_x =mouseX;
player_y =mouseY;
image(player, player_x, player_y);
}
}
/*-------敵機------*/
class Enemy {
//引数を受け取る 
void enemy_action1(){
//直進するだけ
image(enemy, enemy_x, enemy_y);
enemy_x --;
if(enemy_x < 0){
enemy_x = 800;
image(enemy, enemy_x, enemy_y);
}
}
}

//引数を受け取る
/*-------敵機------*/
class Enemy2 {
//引数を受け取る 
void enemy_action2(){
//直進するだけ
image(enemy2, enemy2_x, enemy2_y);
enemy2_x --;
if(enemy2_x < 0){
enemy2_x = 800;
image(enemy2, enemy2_x, enemy2_y);
}
}
}

/*-------弾------*/
class Shot{
void shot_display(){
shot = loadImage("shot.PNG");
}
/*-------弾の処理-------*/  
void shot_fire(){
//マウスが押された時に横に飛び出す
if(mousePressed == true && shot_life == 0){
//発車位置
shot_x = mouseX;
shot_y = mouseY;
shot_life = 1;
shot_sound.play();
}
}
void shot_move(){
if(shot_life == 1){
shot_x += 8;
//横幅800を超えたら、弾を発車する処理に戻る
if(shot_x > 800) { shot_life = 0; }
image(shot, shot_x, shot_y);
}
}
}

/*-------弾と敵機の当たり判定-------*/
class Hantei{
//実行されたらライフを返すメソッド
//返してメソッドを実行する このメソッドが呼び出す
void atari(){
if(
//X1 + W1 < X2 
shot_x + shot.width < enemy_x
||
//X1 > X2 + W2 
shot_x > enemy_x + enemy.width
||
//Y1 + H1 < Y2
shot_x + shot.height < enemy_y
||
//Y1 > Y2 + H2
shot_y > enemy_y + enemy.height
)
{
print("☆");
}else{
enemy = bakuhatu;
bakuhatu = kieru;
bakuhatu_sound.play();
//ライフのグローバル変数をインクリメント
enemy_life--;
}
}
}

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

直接的な回答ではないですが、プログラムの設計をもう少しだけオブジェクト指向として自然になるように工夫(?)した方がよいと思います。

例えば敵機を複数用意するのにEnemy, Enemy2という2つのクラスを定義してますがEnemyは一つのクラスとして定義し、2機の敵を設けたいならインスタンスの方を2つ作るといった考え方にしたほうがよいと思います。

こうなっている理由は(鶏卵的でどちらがどちらの原因になっているかわかりませんが)敵機の座標などの属性をグローバルに定義していることにある気がします。本来は各々のインスタンスの属性はEnemyクラスのインスタンスフィールドとして扱うのが自然です。Playerなどについても同様です。

質問者さんのコードの変数名に着目してみてください。変数名の付け方を

player_x
pleyer_y
..
enemy_x
enemy_y
...

などとしていますね?これはplayerのx座標だからplayer_xとしているのですが、

player_x => player.x
enemy_x  => enemy.x

のように各々のインスタンスのxというフィールドとして扱った方が自然ということです。
以下のコードを眺めてみてください。着目してほしい点だけにするために元のコードの情報(画像など)はあえて省略しています。

Enemy enemy1, enemy2;

void setup() {
  enemy1 = new Enemy(800, height / 2);
  enemy2 = new Enemy(800, height / 2);
}

void draw() {
  enemy1.move();
  enemy2.move();
}

class Enemy {
  float x;
  float y;

  Enemy(float x, float y) {
    this.x = x;
    this.y = y;
  }

  void move() {
    ...
  }
}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/11 15:36

    ありがとうございます。参考にさせていただきます。

    キャンセル

  • 2017/12/11 15:41

    この回答を付けた理由は、今のままの構造で質問者さんの希望どおりの修正をするのがとても分かりにくいと感じたからです。個人的には上記でコメントした設計変更の際にenemy_lifeをどう扱うかを考えてほしいと思ったからなのですが・・・正直言いますと今のコードでenemy_lifeが何を表すのか自分に見えなかったのです。敵機の数なのか、各々の敵機のライフなのか・・・変数名からすると敵機のライフのように思えるのですが、定義の仕方からすると敵機の数のようにも思えます。

    キャンセル

  • 2017/12/11 16:04

    enemy_lifeは初期値を3にしてゲームがスタートします。3の時は
    敵機1体がまっすぐ、直進してきます。当たり判定が実行されて、1体の敵きが爆発したら、ライフを1つ減らします。ライフが1つ減ると、enemy_lifeは2になるので今度はジグザグに向かって来る敵機が一体出てきます。と言うようにしたいと考えて作ったソースになります。わかりづらかったら申し訳ございません。

    キャンセル

  • 2017/12/11 16:22 編集

    ということはenemy_lifeじゃなくてenemy_behaviorとでもいうべきものなのですね。それはEnemyクラスの属性と考えEnemyのフィールドにしてもよいかも知れません。そうしておくとあるEnemyインスタンスは直進移動、別のEnemyインスタンスはジグザグに移動なんて芸当も可能になってきます。プログラム上で一つのグローバル変数にしてしまうとそういう芸当が不可能になってしまいます。

    キャンセル

  • 2017/12/11 16:35

    ありがとうございます。参考になります。

    キャンセル

  • 2017/12/11 16:42

    まだまだ素人で申し訳ございません。この場合、イメージを読み込む際にはどの様に定義したらよろしいでしょうか?

    キャンセル

  • 2017/12/11 16:46

    インスタンスごとにイメージを変えたいようなので、あらかじめ必要な種類だけイメージを読み込んでおき、Enemyの各インスタンスの生成時にどのイメージなのかをコンストラクターで与えるといった方法が思いつきます。その辺りも含めてクラス、インスタンスとは何かを把握できるようになるとよいですね。

    キャンセル

  • 2017/12/11 16:51

    失礼いたしました。なんとかできました。作成進めていきたいと思います。お時間頂きましてありがとうございます

    キャンセル

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

ただいまの回答率

91.28%

関連した質問

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

  • Java

    10819questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Processing

    175questions

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