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

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

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

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

Swing

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

Q&A

解決済

1回答

732閲覧

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

Alpa

総合スコア80

Java

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

Swing

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

0グッド

0クリップ

投稿2017/10/01 10:05

編集2017/10/01 11:33

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

JAVA

1 2 3import javax.swing.JFrame; 4import javax.swing.JPanel; 5import javax.swing.JLabel; 6import javax.swing.ImageIcon; 7 8import java.awt.BorderLayout; 9import java.awt.event.KeyEvent; 10 11import java.util.Timer; 12import java.util.TimerTask; 13 14public class MyGame extends JFrame{ 15 16 int zikiX[] = {750};//自機のX座標 17 int zikiY[] = {225};//自機のY座標 18 19 int zikidamaX[] = {zikiX[0]-30};//自機の弾のX座標 20 int zikidamaY[] = {zikiY[0]};//自機の弾のY座標 21 22 ImageIcon icon1 = new ImageIcon 23 ("C:\Users\miyab\Desktop\シューティングゲーム\自機.png");//画像ファイル指定 24 ImageIcon icon2 = new ImageIcon 25 ("C:\Users\miyab\Desktop\シューティングゲーム\自機弾.png"); 26 27 JLabel ziki = new JLabel(icon1);//JLabelに自機の画像ファイル設定 28 JLabel zikizahyou = new JLabel();//自機の座標を生成 29 JLabel zikidama = new JLabel(icon2);//JLabelに自機の弾の画像ファイル設定 30 31 JPanel panel = new JPanel();//panel設定 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.setLayout(null);//レイアウトマネージャー無効化 50 51 ziki.setBounds(zikiX[0], zikiY[0], 80, 40);//zikiのサイズと座標設定 52 zikizahyou.setText("X座標:"+zikiX[0]+" Y座標:"+zikiY[0]);//自機の座標を設定 53 zikizahyou.setBounds(5, 5, 150, 15);//自機の座標の座標とサイズを設定 54 55 panel.add(ziki);//自機画像をpanelに追加 56 panel.add(zikizahyou);//自機の座標を画面に表示 57 58 getContentPane().add(panel, BorderLayout.CENTER);//??? 59 60 enableEvents(java.awt.AWTEvent.KEY_EVENT_MASK);//キーイベントの有効化 61 62 } 63 64 protected void processKeyEvent(java.awt.event.KeyEvent e){//キーイベントの関数 65 66 if(e.getID() == java.awt.event.KeyEvent.KEY_PRESSED){ 67 68 if(e.getKeyCode() == java.awt.event.KeyEvent.VK_LEFT){ 69 70 zikiX[0] -= 10;//座標を左に移動 71 if(zikiX[0] <= 0){//座標が画面外に行ったら左端に戻す 72 73 zikiX[0] = 0;//zikiのX座標を0に設定 74 75 } 76 ziki.setLocation(zikiX[0],zikiY[0]);//座標を再設定 77 zikizahyou.setText("X座標:"+zikiX[0]+" Y座標:"+zikiY[0]);//座標表示を更新 78 79 } 80 81 if(e.getKeyCode() == java.awt.event.KeyEvent.VK_RIGHT){ 82 83 zikiX[0] += 10;//座標を右に移動 84 if(zikiX[0] >= 804){//座標が画面外に行ったら右端に戻す 85 86 zikiX[0] = 804;//zikiのX座標を804に設定 87 88 } 89 ziki.setLocation(zikiX[0],zikiY[0]);//座標を再設定 90 zikizahyou.setText("X座標:"+zikiX[0]+" Y座標:"+zikiY[0]);//座標表示を更新 91 92 } 93 94 if(e.getKeyCode() == java.awt.event.KeyEvent.VK_UP){ 95 96 zikiY[0] -= 10;//座標を上に移動 97 if(zikiY[0] <= 1){//座標が画面外に行ったら上端に戻す 98 99 zikiY[0] = 1;//zikiのY座標を1に設定 100 101 } 102 ziki.setLocation(zikiX[0],zikiY[0]);//座標を再設定 103 zikizahyou.setText("X座標:"+zikiX[0]+" Y座標:"+zikiY[0]);//座標表示を更新 104 105 } 106 107 if(e.getKeyCode() == java.awt.event.KeyEvent.VK_DOWN){ 108 109 zikiY[0] += 10;//座標を下に移動 110 if(zikiY[0] >= 471){//座標が画面外に行ったら下端に戻す 111 112 zikiY[0] = 471;//zikiのY座標を471に設定 113 114 } 115 ziki.setLocation(zikiX[0],zikiY[0]);//座標を再設定 116 zikizahyou.setText("X座標:"+zikiX[0]+" Y座標:"+zikiY[0]);//座標表示を更新 117 118 } 119 120 if(e.getKeyCode() == java.awt.event.KeyEvent.VK_A){ 121 122 zikidama.setBounds(zikidamaX[0], zikidamaY[0], 20, 20);//自機の弾のサイズと座標を設定 123 panel.add(zikidama);//panelにzikidamaを追加 124 125 TimerTask task = new TimerTask(){//timertaskを設定 126 public void run(){ 127 zikidamaX[0] -= 1;//zikidamaX[0]の座標を-1する 128 zikidama.setLocation(zikidamaX[0],zikidamaY[0]);//座標を再設定 129 } 130 }; 131 132 Timer timer = new Timer();//timerを設定 133 timer.schedule(task, 0L, 1L);//開始までの時間と実行間隔を設定 134 135 System.out.println("X座標:"+zikidamaX[0]);//座標確認用 136 System.out.println("Y座標:"+zikidamaY[0]); 137 138 } 139 140 } 141 } 142 143} 144 145

###変更後

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

JAVA

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

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

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

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

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

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

guest

回答1

0

ベストアンサー

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 10:38

KSwordOfHaste

総合スコア18394

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

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

Alpa

2017/10/01 11: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){ } }); } }
KSwordOfHaste

2017/10/01 12:05

せっかくコメントいただいたのですが・・・ 短いコードなら個人的には見てもかまわないのですが、このような長いコードだとさすがに「うまく動くかどうか試しているかどうかもわからない前の添削」はご勘弁ください。 多分本サイトは、質問者側が「頑張ってデバッグしてもどうしてもわからない点について具体的な質問をする」&閲覧者側が「短い時間で端的な回答をつける」のが基本だと思います。 ちなみに、前回の質問回答のコードを参考にしておられると思いますが、書き方や動きがよくわからないのであれば、まずはリファレンスと見比べたり、デバッグして動きを見るなどしてよく調べてみてはいかがでしょか?どう書いたらどう動くかをじっくり把握してからの方が、ご自身のコードを書くのが楽になるはずですので。
Alpa

2017/10/01 12:56

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問