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

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

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

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

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

Q&A

解決済

1回答

278閲覧

同じJLabelを同じパネルに追加したい&座標設定がうまくいかない

Alpa

総合スコア80

Java

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

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

0グッド

0クリップ

投稿2017/10/04 11:39

編集2017/10/04 14:04

###前提・実現したいこと

パネルにzikidamaを追加して消したあともう一回zikidama追加したい
zikidamaの座標設定をzikiの左にしっかり設定したい

###発生している問題

・パネルにzikidamaを追加して消したあともう一回zikidama追加したい↓
消すまではできたがもう一回zikidamaを追加できない

・zikidamaの座標設定をzikiの左にしっかり設定したい↓
zikiを移動させても初期値の場所からしか発射されない

###該当のソースコード

java

1 2import javax.swing.*; 3 4import java.awt.*; 5import java.awt.event.*; 6 7public class MyGame extends JFrame implements ActionListener, MouseMotionListener{ 8 9 int zikiX[] = {750};//自機のX座標 10 int zikiY[] = {225};//自機のY座標 11 12 int zikidamaX[] = {zikiX[0]-30};//自機の弾のX座標 13 int zikidamaY[] = {zikiY[0]};//自機の弾のY座標 14 15 int count;//カウント感知用変数 16 17 ImageIcon icon1 = new ImageIcon 18 ("C:\Users\***\Desktop\シューティングゲーム\自機.png"); 19//自機の画像ファイル指定;//ImageIconのicon1作成 20 ImageIcon icon2 = new ImageIcon 21 ("C:\Users\***\Desktop\シューティングゲーム\自機弾.png"); 22//自機弾の画像ファイル指定;//ImageIconのicon2作成 23 24 JLabel ziki;//JLabelのziki作成 25 JLabel zikizahyou;//JLabelのzikizahyou作成 26 JLabel zikidamazahyou;////JLabelのzikidamazahyou作成 27 JLabel zikidama;//JLabelのzikidama作成 28 29 JPanel panel;//JPanelのpanel作成 30 31 Timer timer;//Timerのtimer作成 32 33 public static void main(String[] args){ 34 35 MyGame frame = new MyGame();//ウィンドウを内部的に作成 36 frame.setSize(900, 550);//ウィンドウサイズ設定 37 frame.setTitle("シューティングゲーム"); 38 frame.setLocationRelativeTo(null);//ウィンドウの位置を中央に設定 39 40 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 41 //ウィンドウを×で閉じるようにする設定 42 43 frame.setVisible(true);//ウィンドウを可視化 44 45 } 46 47 MyGame(){ 48 49 panel = new JPanel();//panel設定 50 panel.setLayout(null);//レイアウトマネージャー無効化 51 52 ziki = new JLabel(icon1);//JLabelに自機の画像ファイル設定 53 zikizahyou = new JLabel();//自機の座標を入れる 54 zikidamazahyou = new JLabel();//自機の弾の座標を入れる 55 zikidama = new JLabel(icon2);//JLabelに自機の弾の画像ファイル設定 56 57 ziki.setBounds(zikiX[0], zikiY[0], 80, 40);//zikiのサイズと座標設定 58 zikizahyou.setText("自機 "+"X座標:"+zikiX[0]+" Y座標:"+zikiY[0]);//自機の座標を設定 59 zikizahyou.setBounds(5, 5, 200, 15);//自機の座標の座標とサイズを設定 60 zikidamazahyou.setText("自機の弾 "+"X座標:"+zikidamaX[0]+" Y座標:"+zikidamaY[0]);//自機の座標を設定 61 zikidamazahyou.setBounds(5, 17, 200, 15);//自機の座標の座標とサイズを設定 62 63 timer = new Timer(10, this); 64 65 panel.add(ziki);//自機画像をpanelに追加 66 panel.add(zikizahyou);//自機の座標を画面に表示 67 panel.add(zikidamazahyou);//自機の弾の座標を画面に表示 68 69 pack(); 70 71 getContentPane().add(panel, BorderLayout.CENTER);//??? 72 73 enableEvents(java.awt.AWTEvent.KEY_EVENT_MASK);//キーイベントの有効化 74 75 addMouseMotionListener(this); 76 77 } 78 79 protected void processKeyEvent(java.awt.event.KeyEvent e){//キーイベントの関数 80 81 if(e.getID() == java.awt.event.KeyEvent.KEY_PRESSED){ 82 83 if(e.getKeyCode() == java.awt.event.KeyEvent.VK_A){ 84 85 zikidama.setBounds(zikidamaX[0], zikidamaY[0], 20, 20);//自機の弾のサイズと座標を設定 86 panel.add(zikidama);//panelにzikidamaを追加 87 88 timer.start(); 89 90 } 91 } 92 } 93 94 public void actionPerformed(ActionEvent e){ 95 96 if(zikidamaX[0] <= 0){ 97 98 timer.stop();//timerストップ 99 panel.remove(zikidama); 100 panel.repaint(); 101 102 }else{ 103 104 zikidamaX[0] -= 15;//zikidamaX[0]を-5 105 zikidama.setLocation(zikidamaX[0],zikidamaY[0]);//座標を再設定 106 zikidamazahyou.setText("自機の弾 "+"X座標:"+zikidamaX[0]+" Y座標:"+zikidamaY[0]); 107 //座標表示を更新 108 109 } 110 111 } 112 113 public void mouseMoved(MouseEvent e){ 114 115 Point point = e.getPoint(); 116 zikiX[0] = point.x-43; 117 zikiY[0] = point.y-45; 118 119 if(zikiX[0] <= 0){//座標が画面外に行ったら左端に戻す 120 121 zikiX[0] = 0;//zikiのX座標を0に設定 122 123 } 124 125 if(zikiX[0] >= 804){//座標が画面外に行ったら右端に戻す 126 127 zikiX[0] = 804;//zikiのX座標を804に設定 128 129 } 130 131 if(zikiY[0] <= 1){//座標が画面外に行ったら上端に戻す 132 133 zikiY[0] = 1;//zikiのY座標を1に設定 134 135 } 136 137 if(zikiY[0] >= 471){//座標が画面外に行ったら下端に戻す 138 139 zikiY[0] = 471;//zikiのY座標を471に設定 140 141 } 142 143 ziki.setLocation(zikiX[0],zikiY[0]);//座標を再設定 144 zikizahyou.setText("自機 "+"X座標:"+zikiX[0]+" Y座標:"+zikiY[0]);//座標表示を更新 145 146 } 147 148 public void mouseDragged(MouseEvent e){ 149 150 151 152 } 153 154} 155

###試したこと
・パネルにzikidamaを追加して消したあともう一回zikidama追加したい↓
とくに何もしていない

・zikidamaの座標設定をzikiの左にしっかり設定したい↓
座標設定をzikiにしてみた

###追記

弾の発射処理について
まずAを押したらキーイベントで押したことを判定して
panelにzikidamaを追加
そのあとtimerをスタートさせて
画面の端に来たらtimerをストップさせ
zikidamaをpanelから削除して
そのあとpanelをrepaintしています

タイマーハンドラーについて
タイムハンドラーではzikidamaXが0になるまで
zikidamaX-15をしてそのあと座標を再設定
そしてzikidamaの座標の表示の更新をしています
そしてzikidamaXが0になったらtimerをストップして
zikidamaをpanelから消して
そのあとpanelをrepaintしています

弾の座標にどんな値が指定されているかについて
弾の座標にはzikiの X座標-30 Y座標±0 が設定されています
またそれはzikiの座標をまず X=750 Y=225 に設定していて
その座標の X-30 Y±0 をzikidamaのX,Yというように設定しているから

こんな感じですかね

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

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

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

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

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

KSwordOfHaste

2017/10/04 12:11

質問文の本文において、コードタグで囲むのはプログラムコード部分のみです。発生している問題(つまり通常の文章)はコードタグでは囲まないでください。
Alpa

2017/10/04 12:15

すいませんテンプレートをそのまま使ったので直します
KSwordOfHaste

2017/10/04 13:57 編集

タイマーハンドラーとはactionPerformedメソッドのことです。
guest

回答1

0

ベストアンサー

消すまではできたがもう一回zikidamaを追加できない
zikiを移動させても初期値の場所からしか発射されない

いずれも原因は同じです。弾を発射するときに今回発射する弾の位置をフィールドへ設定しないままアニメーションを開始してしまってます。連続処理(今回ならアニメーション)を開始する際に、必要な情報が適切に初期化できているか、よく考えるようにしましょう。

ちなみに画面上に弾の座標をデバッグ表示するよう工夫していますよね?せっかくそうしているのですから2回目の弾を発射する際に「ありゃ?X座標が最初から0のままだぞ・・・」というぐあいに気づけるとよかったのですが・・・


追記:

弾の座標にはzikiの X座標-30 Y座標±0 が設定されています

またそれはzikiの座標をまず X=750 Y=225 に設定していて
その座標の X-30 Y±0 をzikidamaのX,Yというように設定しているから

「720, 225が設定される」と書けばGOODだったのですが、「zikiの X座標-30 Y座標±0」と説明しておられることから、「アプリケーション開始後にzikiの座標が変化しても、zikiの座標の変化に追従して弾の初期値も変化してくれるかのように思い込んだ」ということのように思います。実際はそうでなく、あくまで720, 225が弾の座標初期値**(あくまで1発目を発射する場合の初期値)**になります。この点が

zikiを移動させても初期値の場所からしか発射されない

という疑問が解消しなかった原因では?

また1発目を発射しそれが画面左端に到達した後、弾の座標(を保持しているフィールドの値)は最後の位置(X<=0つまり画面左端)のままです。そのままで2発目を発射すればどうなるかは自明と思います。(質問者さんにとって自明でないなら、2発目発射の際に座標がどうなるかを述べてみてください)

投稿2017/10/04 12:23

編集2017/10/04 15:51
KSwordOfHaste

総合スコア18392

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

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

Alpa

2017/10/04 13:11 編集

すいません うまく理解できなかったので 例などを教えていただけますか?
KSwordOfHaste

2017/10/04 13:18

本回答の説明より詳しい説明をするとしたら、あなたがどのようにプログラムの動作を理解しているかを把握したいです。弾の発射処理、タイマーハンドラーの2つについて、弾の座標にどんな値が指定されることになるか、またそれはなぜか、わかる点・わからない点を詳しく説明してみてください。(本文を編集するのがよいです)
Alpa

2017/10/05 11:04 編集

追記に質問なんですが アプリケーション開始後にzikiの座標が変化しても zikiの座標の変化に追従して弾の初期値も変化してくれるようにと 2発目の座標をもう一回zikiに設定するには どうしたらいいでしょうか? それがまったく思い浮かびません
KSwordOfHaste

2017/10/05 16:03

そういうこともできなくはないですがプログラムが難解になるだけであり、もっと適切な解決法があります。解決法は最初の回答の中で述べた「連続処理(今回ならアニメーション)を開始する際に、必要な情報を適切に初期化する」です。 要するに発射の際に「自機の座標に基いて新しく発射する弾の発射時の座標を設定してやる」ことです。
Alpa

2017/10/05 21:44

考えていろいろやってみたらできましたありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問