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

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

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

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

Q&A

解決済

2回答

2926閲覧

再描画について

nakamura-

総合スコア48

Java

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

1グッド

1クリップ

投稿2016/06/24 08:09

javaでシューティングゲームを作ろうと考えています。
下のプログラムはその途中です。

コード 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 implements Runnable{ int at_x = 0; int at_y = 0; Player player1; Thread thread; /** * MyPanelのコンストラクタ */ public MyPanel(){ setBackground(Color.BLACK); //背景色設定 try{ player1 = new Player("jiki.gif", 0, 0, 32, 32); } catch(IOException ioe){ System.out.println("画像がありません"); } thread = new Thread(this); thread.start(); } /** * キー入力処理 */ protected void processKeyEvent(KeyEvent ke){ /*何かキーが押された場合*/ if(ke.getID() == KeyEvent.KEY_PRESSED){ System.out.println("キー" + ke.getKeyCode() + "が押された"); player1.move(ke.getKeyCode()); if(ke.getKeyCode() == KeyEvent.VK_ENTER){ at_x = player1.m_x; at_y = player1.m_y; for(int i = 0; i < 50; i++){ try{ Thread.sleep(50); } catch(InterruptedException e){ } at_y -= 10; repaint(); System.out.println("yは" + at_y); } } repaint(); } } /** * 描画メソッド */ protected void paintComponent(Graphics g){ super.paintComponent(g); requestFocusInWindow(); //キー入力有効化 player1.draw(g); g.setColor(Color.WHITE); g.fillRect(at_x,at_y, 5, 5); System.out.println("★yは" + at_y); } /** * 再描画を行うメソッド */ public void run(){ /*while(true){ repaint(); }*/ } }
コード 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); //画像表示 } }

このプログラムにおいて

コード protected void processKeyEvent(KeyEvent ke){ /*何かキーが押された場合*/ if(ke.getID() == KeyEvent.KEY_PRESSED){ System.out.println("キー" + ke.getKeyCode() + "が押された"); player1.move(ke.getKeyCode()); if(ke.getKeyCode() == KeyEvent.VK_ENTER){ at_x = player1.m_x; at_y = player1.m_y; for(int i = 0; i < 50; i++){ try{ Thread.sleep(50); } catch(InterruptedException e){ } at_y -= 10; repaint(); System.out.println("yは" + at_y); } } repaint(); } }

MyPanelクラスのprocessKeyEventメソッドでforを使って0.05秒ごとにat_yが10ずつ減って再描画を行っているのですが、実行すると0.05秒ごとに再描画されるのではなく、for文の50回ループが終わった後に1回だけ再描画されています。
repaintを書いているのに機能してないみたいなのですが、なぜなのでしょうか?
よろしくお願いします。

tignear👍を押しています

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

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

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

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

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

guest

回答2

0

ベストアンサー

swingはシングルスレッドでイベント処理や描画処理もシングルスレッドなので描画処理はイベント処理が終わるまで実行されません
なので別スレッドに分けてください
例えばこんな感じ

java

1 protected void processKeyEvent(KeyEvent ke){ 2 /*何かキーが押された場合*/ 3 if(ke.getID() == KeyEvent.KEY_PRESSED){ 4 System.out.println("キー" + ke.getKeyCode() + "が押された"); 5 6 player1.move(ke.getKeyCode()); 7 8 if(ke.getKeyCode() == KeyEvent.VK_ENTER){ 9 at_x = player1.m_x; 10 at_y = player1.m_y; 11 Thread t=new Thread(this); 12 t.start(); 13 repaint(); 14 } 15 } 16 } 17 18@Override 19public void run(){ 20 for(int i = 0; i < 50; i++){ 21 try{ 22 Thread.sleep(50); 23 }catch(InterruptedException e){ 24 } 25 at_y -= 10; 26 repaint(); 27 System.out.println("yは" + at_y); 28 } 29}

一例です
swingでは長時間かかる処理は別スレッドに投げた方がいいです
そうしないと画面が動かない・・などということになります

投稿2016/06/24 08:47

編集2016/06/24 08:48
tignear

総合スコア260

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

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

nakamura-

2016/06/27 01:46

回答ありがとうございます。 別スレッドで処理しないとダメなんですね! プログラムまで描いていただきありがとうございました。
guest

0

repaint関数はすぐに呼び出される関数ではないからです。
repaint関数はメインのスレッドが占有状態でないときにできるだけ早く実行します。

つまり、processKeyEvent内のループ状態でスレッドを占有しているため、
processKeyEventが終了するまで、再描画が行われ無いということになります。

?秒おきに再描画したいという処理をしたいのならば、
別のスレッドを立ててその中で?秒置きにrepaint()を呼び出すようにしてあげれば解決できると思います。

投稿2016/06/24 08:30

Yossi_1982

総合スコア95

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

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

nakamura-

2016/06/27 01:47

回答ありがとうございます。 repaintメソッドはそういうものだったんですね! ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問