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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Java

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

Processing

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

Q&A

解決済

1回答

591閲覧

processing javaでゲーム開発

haniwa3

総合スコア25

Java

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

Processing

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

0グッド

0クリップ

投稿2017/12/11 05:46

編集2017/12/11 06:35

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--;
}
}
}

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

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

例えば敵機を複数用意するのに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というフィールドとして扱った方が自然ということです。
以下のコードを眺めてみてください。着目してほしい点だけにするために元のコードの情報(画像など)はあえて省略しています。

java

1 2Enemy enemy1, enemy2; 3 4void setup() { 5 enemy1 = new Enemy(800, height / 2); 6 enemy2 = new Enemy(800, height / 2); 7} 8 9void draw() { 10 enemy1.move(); 11 enemy2.move(); 12} 13 14class Enemy { 15 float x; 16 float y; 17 18 Enemy(float x, float y) { 19 this.x = x; 20 this.y = y; 21 } 22 23 void move() { 24 ... 25 } 26}

投稿2017/12/11 06:32

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

haniwa3

2017/12/11 06:36

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

2017/12/11 06:41

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

2017/12/11 07:04

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

2017/12/11 07:22 編集

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

2017/12/11 07:35

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

2017/12/11 07:42

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

2017/12/11 07:46

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

2017/12/11 07:51

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問