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

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

ただいまの
回答率

90.99%

  • Java

    12186questions

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

  • Swing

    199questions

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

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

解決済

回答 1

投稿 編集

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

miyabi6184

score 24

前提・実現したいこと

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

発生している問題

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

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

該当のソースコード

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;

public class MyGame extends JFrame implements ActionListener, MouseMotionListener{

    int zikiX[] = {750};//自機のX座標
    int zikiY[] = {225};//自機のY座標

    int zikidamaX[] = {zikiX[0]-30};//自機の弾のX座標
    int zikidamaY[] = {zikiY[0]};//自機の弾のY座標

    int count;//カウント感知用変数

    ImageIcon icon1 = new ImageIcon
    ("C:\\Users\\***\\Desktop\\シューティングゲーム\\自機.png");
//自機の画像ファイル指定;//ImageIconのicon1作成
    ImageIcon icon2 = new ImageIcon
    ("C:\\Users\\***\\Desktop\\シューティングゲーム\\自機弾.png");
//自機弾の画像ファイル指定;//ImageIconのicon2作成

    JLabel ziki;//JLabelのziki作成
    JLabel zikizahyou;//JLabelのzikizahyou作成
    JLabel zikidamazahyou;////JLabelのzikidamazahyou作成
    JLabel zikidama;//JLabelのzikidama作成

    JPanel panel;//JPanelのpanel作成

    Timer timer;//Timerのtimer作成

    public static void main(String[] args){

        MyGame frame = new MyGame();//ウィンドウを内部的に作成
        frame.setSize(900, 550);//ウィンドウサイズ設定
        frame.setTitle("シューティングゲーム");
        frame.setLocationRelativeTo(null);//ウィンドウの位置を中央に設定

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //ウィンドウを×で閉じるようにする設定

        frame.setVisible(true);//ウィンドウを可視化

    }

    MyGame(){

        panel = new JPanel();//panel設定
        panel.setLayout(null);//レイアウトマネージャー無効化

        ziki = new JLabel(icon1);//JLabelに自機の画像ファイル設定
        zikizahyou = new JLabel();//自機の座標を入れる
        zikidamazahyou = new JLabel();//自機の弾の座標を入れる
        zikidama = new JLabel(icon2);//JLabelに自機の弾の画像ファイル設定

        ziki.setBounds(zikiX[0], zikiY[0], 80, 40);//zikiのサイズと座標設定
        zikizahyou.setText("自機 "+"X座標:"+zikiX[0]+" Y座標:"+zikiY[0]);//自機の座標を設定
        zikizahyou.setBounds(5, 5, 200, 15);//自機の座標の座標とサイズを設定
        zikidamazahyou.setText("自機の弾 "+"X座標:"+zikidamaX[0]+" Y座標:"+zikidamaY[0]);//自機の座標を設定
        zikidamazahyou.setBounds(5, 17, 200, 15);//自機の座標の座標とサイズを設定

        timer = new Timer(10, this);

        panel.add(ziki);//自機画像をpanelに追加
        panel.add(zikizahyou);//自機の座標を画面に表示
        panel.add(zikidamazahyou);//自機の弾の座標を画面に表示

        pack();

        getContentPane().add(panel, BorderLayout.CENTER);//???

        enableEvents(java.awt.AWTEvent.KEY_EVENT_MASK);//キーイベントの有効化

        addMouseMotionListener(this);

    }

    protected void processKeyEvent(java.awt.event.KeyEvent e){//キーイベントの関数

        if(e.getID() == java.awt.event.KeyEvent.KEY_PRESSED){

            if(e.getKeyCode() == java.awt.event.KeyEvent.VK_A){

                zikidama.setBounds(zikidamaX[0], zikidamaY[0], 20, 20);//自機の弾のサイズと座標を設定
                panel.add(zikidama);//panelにzikidamaを追加

                timer.start();

            }
        }
    }

    public void actionPerformed(ActionEvent e){

        if(zikidamaX[0] <= 0){

            timer.stop();//timerストップ
            panel.remove(zikidama);
            panel.repaint();

        }else{

            zikidamaX[0] -= 15;//zikidamaX[0]を-5
            zikidama.setLocation(zikidamaX[0],zikidamaY[0]);//座標を再設定
            zikidamazahyou.setText("自機の弾 "+"X座標:"+zikidamaX[0]+" Y座標:"+zikidamaY[0]);
            //座標表示を更新

        }

    }

    public void mouseMoved(MouseEvent e){

        Point point = e.getPoint();
        zikiX[0] = point.x-43;
        zikiY[0] = point.y-45;

        if(zikiX[0] <= 0){//座標が画面外に行ったら左端に戻す

            zikiX[0] = 0;//zikiのX座標を0に設定

        }

        if(zikiX[0] >= 804){//座標が画面外に行ったら右端に戻す

            zikiX[0] = 804;//zikiのX座標を804に設定

        }

        if(zikiY[0] <= 1){//座標が画面外に行ったら上端に戻す

            zikiY[0] = 1;//zikiのY座標を1に設定

        }

        if(zikiY[0] >= 471){//座標が画面外に行ったら下端に戻す

            zikiY[0] = 471;//zikiのY座標を471に設定

        }

        ziki.setLocation(zikiX[0],zikiY[0]);//座標を再設定
        zikizahyou.setText("自機 "+"X座標:"+zikiX[0]+" Y座標:"+zikiY[0]);//座標表示を更新

    }

    public void mouseDragged(MouseEvent e){



    }

}

試したこと

・パネルに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というように設定しているから

こんな感じですかね

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • KSwordOfHaste

    2017/10/04 21:11

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

    キャンセル

  • miyabi6184

    2017/10/04 21:15

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

    キャンセル

  • KSwordOfHaste

    2017/10/04 22:57 編集

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

    キャンセル

回答 1

checkベストアンサー

+1

消すまではできたがもう一回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 22:11 編集

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

    キャンセル

  • 2017/10/04 22:18

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

    キャンセル

  • 2017/10/05 20:04 編集

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

    キャンセル

  • 2017/10/06 01:03

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

    キャンセル

  • 2017/10/06 06:44

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

    キャンセル

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

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

関連した質問

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

  • Java

    12186questions

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

  • Swing

    199questions

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