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

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

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

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

Q&A

解決済

2回答

2600閲覧

何個も描画する方法

nakamura-

総合スコア48

Java

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

0グッド

0クリップ

投稿2016/06/27 08:11

シューティングゲームのようなものを作っています。
下はその途中のプログラムです。

コード public class Part01 extends JApplet{ /** * 初期メソッド */ public void init(){ setSize(1000, 700); //画面サイズ設定 MyPanel mp = new MyPanel(); //MyPanelインスタンス化 getContentPane().add(mp); //MyPanel追加 } }
コード public class MyPanel extends JPanel{ Player player1; Gun gun1; /** * MyPanelのコンストラクタ */ public MyPanel(){ setBackground(Color.BLACK); //背景色設定 try{ player1 = new Player("jiki.gif", 0, 0, 32, 32); gun1 = new Gun(this); } catch(IOException ioe){ System.out.println("画像がありません"); } } /** * キー入力処理 */ protected void processKeyEvent(KeyEvent ke){ /*何かキーが押された場合*/ if(ke.getID() == KeyEvent.KEY_PRESSED){ System.out.println("キー" + ke.getKeyCode() + "が押された"); player1.move(ke.getKeyCode()); gun1.move(ke.getKeyCode(), player1.m_x, player1.m_y); repaint(); } } /** * 描画メソッド */ protected void paintComponent(Graphics g){ super.paintComponent(g); requestFocusInWindow(); //キー入力有効化 player1.draw(g); gun1.draw(g); } }
コード public class Player{ BufferedImage m_bi; int m_x = 485; int m_y = 640; /** * Playerのコンストラクタ */ public Player(BufferedImage bi){ m_bi = bi; } public Player(BufferedImage bi, int x, int y, int w, int h){ m_bi = bi.getSubimage(x, y, w, h); } public Player(File file, int x, int y, int w, int h) throws IOException{ BufferedImage bi = ImageIO.read(file); m_bi = bi.getSubimage(x, y, w, h); } public Player(String str, int x, int y, int w, int h) throws IOException{ File file = new File(str); BufferedImage bi = ImageIO.read(file); m_bi = bi.getSubimage(x, y, w, h); } /** * 移動メソッド */ public void move(int keyCode){ /*押されたキーが左右だった場合*/ if(keyCode == KeyEvent.VK_RIGHT){ m_x += 32; } if(keyCode == KeyEvent.VK_LEFT){ m_x -= 32; } } /** * 描画メソッド */ public void draw(Graphics g){ g.drawImage(m_bi, m_x, m_y, null); //画像表示 } }
コード public class Gun implements Runnable{ MyPanel mypanel; Thread thread = new Thread(this); int m_x = -100; //初期位置非表示 int m_y = -100; //初期位置非表示 /** * Gunのコンストラクタ */ public Gun(MyPanel mp){ mypanel = mp; } /** * 移動メソッド */ public void move(int keyCode, int x, int y){ /*押されたキーがENTERだった場合*/ if(keyCode == KeyEvent.VK_ENTER){ m_x = x; m_y = y; thread.start(); } } /** * runメソッド */ public void run(){ /*gun管理スレッド ここから*/ Thread gunManageThread = new Thread(new Runnable(){ public void run(){ while(true){ try{ Thread.sleep(50); } catch(InterruptedException e){ } m_y -= 10; } } }); gunManageThread.start(); /*ここまで*/ while (true){ mypanel.repaint(); } } /** * 描画メソッド */ public void draw(Graphics g){ g.setColor(Color.WHITE); g.fillRect(m_x, m_y, 5, 5); } }

今、機体を左右の矢印のキーを押して動かして、ENTERを押すと攻撃するようになっているのですが、ENTERを2回押すと1回目の攻撃がリセット(消える)されて、最初からになります。
ENTERを押すとx,yに元の位置の値が代入されるのでリセットされるのはわかっているのですが、
リセットされずに攻撃を何回も出来るようにするにはどうすればいいのでしょうか?
とっかかりだけでも教えていただけたらと思います。
よろしくお願いします。

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

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

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

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

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

guest

回答2

0

Gunクラスを複数生成して順番に使えば良いと思います。
Gun gun[10];
Player.shoot_count = 0;
既にてますが、たま数が可変の場合はArrayListを使うのも手ですね。

ゲームの場合はBaceObjectクラスを継承して型を合わせるのが後々便利だと思います。
BaseObject{ ⇦共通パラメータは放り込んでおく
int x,y;
int hp;
}
Player extends BaseObject{}
Gun extends BaseObject{}

投稿2016/06/27 09:31

MasaakiIrie

総合スコア1021

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

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

nakamura-

2016/06/28 08:21

回答ありがとうございます。 ArrayListを使ってやってみたいと思います。 BaceObjectの方も参考にさせていただきます ありがとうございました。
guest

0

ベストアンサー

MyPanelにGunのインスタンスが1つしかないからです。たくさん弾を描画したいなら、Gunのインスタンスはたくさん持たなければいけません。List<Gun>などのリストにして持つのが良いでしょう。

順を追って改善すべき点を列挙します。

  1. List<Gun> gunListという変数を作り、可変長な配列を扱えるようにします
  2. MyPanelでEnterが押される度にGunのインスタンスを生成し、gunListに格納します
  3. Gunを生成したら、新しく生成されたGun#moveで初期位置をPlayerのm_x、m_yにします
  4. いままでと違い、GunはEnterを押すごとに無制限に生成され、永遠に飛んでいくので、画面外に出たらgunListから取り除く処理を実装します

とりあえずここまでで弾がたくさん飛ぶようになるでしょう。

ここからはゲームプログラミングをする上での現状の構造に対する指摘点です。

  • 一定間隔の更新処理を呼び出すコードが、各オブジェクトに記載されるのは構造的におかしいです。毎フレーム呼ばれるべき処理をupdateというメソッド内に記述し、一括管理されたゲーム全体の制御ループでそれらのupdateを呼ぶべきです。でなければPlayerとGunの更新頻度に差が出てしまいます。
  • repaintを呼ぶ箇所が散在しすぎています。ゲーム全体の制御ループで毎フレームごとに1回だけ呼ぶようにしましょう。

Java

1// MyPanelコンストラクタ内 2Thread gameLoopThread = new Thread(new Runnable() { 3 while(true) { 4 try{ 5 Thread.sleep(50); 6 } 7 catch(InterruptedException e){ 8 } 9 player.update(); 10 for(Gun gun : gunList) { 11 gun.update(); 12 } 13 repaint(); 14 } 15}); 16gameLoopThread .start();

投稿2016/06/27 08:39

編集2016/06/27 10:07
masaya_ohashi

総合スコア9206

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

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

nakamura-

2016/06/28 08:19

回答ありがとうございます。 リストを使うんですね! ご指摘もありがとうございます。 これじゃダメなんですね笑 参考にさせていただきます ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問