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

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

ただいまの
回答率

90.52%

  • Java

    13766questions

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

  • Swing

    226questions

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

JAVA Timerクラスを使って画像の移動をして 画面から消えたら消すというのがうまくいかない

受付中

回答 1

投稿 編集

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

Alpa

score 26

弾の移動は一応できた?のですが
画面から出ても消えずに
もう一回弾を発射できません
どうしたらいいでしょうか?

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.ImageIcon;

import java.awt.BorderLayout;
import java.awt.event.KeyEvent;

import java.util.Timer;
import java.util.TimerTask;

public class MyGame extends JFrame{

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

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

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

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

    JPanel panel = new JPanel();//panel設定

    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.setLayout(null);//レイアウトマネージャー無効化

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

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

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

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

    }

    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_LEFT){

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

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

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

            }

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

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

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

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

            }

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

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

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

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

            }

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

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

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

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

            }

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

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

                TimerTask task = new TimerTask(){//timertaskを設定
                public void run(){
                    zikidamaX[0] -= 1;//zikidamaX[0]の座標を-1する
                    zikidama.setLocation(zikidamaX[0],zikidamaY[0]);//座標を再設定
                }
                };

                Timer timer = new Timer();//timerを設定
                timer.schedule(task, 0L, 1L);//開始までの時間と実行間隔を設定

                System.out.println("X座標:"+zikidamaX[0]);//座標確認用
                System.out.println("Y座標:"+zikidamaY[0]);

            }

        }
    }

}

変更後

このような使い方でいいでしょうか?
もし間違っているなら
しつこいですが
教えていただけないでしょうか?
理解力がなくてすいません

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.Timer;

import java.awt.BorderLayout;
import java.awt.event.KeyEvent;

public class MyGame extends JFrame{

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

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

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

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

    JPanel panel = new JPanel();//panel設定

    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.setLayout(null);//レイアウトマネージャー無効化

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

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

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

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

    }

    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_LEFT){

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

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

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

            }

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

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

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

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

            }

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

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

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

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

            }

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

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

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

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

            }

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

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

                System.out.println("X座標:"+zikidamaX[0]);//座標確認用
                System.out.println("Y座標:"+zikidamaY[0]);

            }

        }
    }

    void Timer(){

        Timer dama = new Timer(10, event ->{//timerを設定

        zikidamaX[0] -= 1;//zikidamaX[0]の座標を-1する
        zikidama.setLocation(zikidamaX[0], zikidamaY[0]);
            if(zikidamaX[0] <= 0){



            }

        });
    }

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

+3

3点コメントします。

  • 利用するクラス
    以前の質問にコメントしましたが、swingのアプリケーションではjavax.swing.Timerをお勧めします。java.util.Timerやjava.util.TimerTaskでもできなくはないですが、これらを使うと定期処理(runメソッド)はEDT(Event Dispatch Thread)とは異なるスレッドで実行されてしまいます。swing/awtコンポーネントへのアクセスをEDT(Event Dispatch Thread)以外から行うのは禁止事項なので、もしTimerTaskなどを使うならSwingUtilities.invokeLaterを使わないといけないことになり面倒です。その点javax.swing.Timerだと定期処理がEDTで実行されることが保証されます。そういう理由でjavax.swing.Timerの方がお勧めなのです。

  • 定期処理は常に一つだけ動かしておく方が多分簡単では?
    これも以前の質問にコメントしたのですが、弾を発射する度にTimerのインスタンスを生成するなんてことをすると(そうしてもいいのですが・・・)Timerが必要なくなったときにストップして後始末するようにしないと、おそらくアプリケーションの処理がどんどん重くなります。こうした点が配慮できるまではアプリケーション開始時に唯一のタイマーを動かしっぱなしにしてそこで全ての定期処理をする方がプログラムコードがシンプルになると思います。

  • 時間間隔
    本件の問題には直接関係ないと思いますが、アニメーション目的で1ミリ秒ごとに画面更新をするのは高頻度すぎる気がします。例えばTV放送でも1秒にせいぜい30フレームですし。頻度を高めにするとしてもせいぜい10ミリ秒間隔ぐらいでいいんじゃないでしょうか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/10/01 20:29

    このような使い方であっているでしょうか?
    もし間違っているのであれば
    しつこいですが教えていただけないでしょうか?

    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JLabel;
    import javax.swing.ImageIcon;
    import javax.swing.Timer;

    import java.awt.BorderLayout;
    import java.awt.event.KeyEvent;

    public class MyGame extends JFrame{

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

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

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

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

    JPanel panel = new JPanel();//panel設定

    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.setLayout(null);//レイアウトマネージャー無効化

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

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

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

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

    }

    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_LEFT){

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

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

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

    }

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

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

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

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

    }

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

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

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

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

    }

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

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

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

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

    }

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

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

    System.out.println("X座標:"+zikidamaX[0]);//座標確認用
    System.out.println("Y座標:"+zikidamaY[0]);

    }

    }
    }

    void Timer(){

    Timer dama = new Timer(10, event ->{//timerを設定

    zikidamaX[0] -= 1;//zikidamaX[0]の座標を-1する
    zikidama.setLocation(zikidamaX[0], zikidamaY[0]);
    if(zikidamaX[0] <= 0){



    }

    });
    }

    }

    キャンセル

  • 2017/10/01 21:05

    せっかくコメントいただいたのですが・・・

    短いコードなら個人的には見てもかまわないのですが、このような長いコードだとさすがに「うまく動くかどうか試しているかどうかもわからない前の添削」はご勘弁ください。

    多分本サイトは、質問者側が「頑張ってデバッグしてもどうしてもわからない点について具体的な質問をする」&閲覧者側が「短い時間で端的な回答をつける」のが基本だと思います。

    ちなみに、前回の質問回答のコードを参考にしておられると思いますが、書き方や動きがよくわからないのであれば、まずはリファレンスと見比べたり、デバッグして動きを見るなどしてよく調べてみてはいかがでしょか?どう書いたらどう動くかをじっくり把握してからの方が、ご自身のコードを書くのが楽になるはずですので。

    キャンセル

  • 2017/10/01 21:56

    わかりました
    これからは気を付けて質問してみます
    ありがとうございました

    キャンセル

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

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

関連した質問

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

  • Java

    13766questions

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

  • Swing

    226questions

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

  • トップ
  • Javaに関する質問
  • JAVA Timerクラスを使って画像の移動をして 画面から消えたら消すというのがうまくいかない