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

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

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

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

Swing

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

Q&A

1回答

346閲覧

javaswing repaintメソッドを呼び出しても画面が背景色でクリアされない

Mitika-t

総合スコア4

Java

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

Swing

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

0グッド

0クリップ

投稿2023/10/03 22:13

実現したいこと

現在,javaswingでの描画処理の勉強をしてテストプログラムを作っています。
コントローラークラスで、描画するオブジェクトの計算をし、imageインスタンスにグラフィックの情報を代入しています。そして、frameにそれを引数としてわたし、repaintメソッドを呼び出しています。

実行すると描画自体はされているのですが、
これまでに描画していた、画像をがrepaintメソッドを呼び出しても、
描画されてしまっています。
適切に実装するにはどのようにすればよいのでしょうか。

該当のソースコード

java

1package TestRpgWalk; 2 3public class TestArpgWalk { 4public static void main(String[] args) { 5 new GameController(); 6} 7}

java

1package TestRpgWalk; 2 3import java.awt.Color; 4import java.awt.Graphics; 5import java.awt.Image; 6import java.awt.Point; 7 8public class GameController { 9 MainJFrame mainJFrame = null; 10 Image image = null; 11 Enemy enemy = new Enemy(); 12 Hero hero = new Hero(); 13 14 public GameController() { 15 mainJFrame = new MainJFrame(); 16 image = mainJFrame.createImage(mainJFrame.getWidth(), mainJFrame.getHeight()); 17 Thread thread = new Thread(new GameLoop()); 18 thread.start(); 19 } 20 21 class GameLoop implements Runnable { 22 boolean isGame = true; 23 24 @Override 25 public void run() { 26 init(); 27 while (isGame == true) { 28 logic(); 29 draw(); 30 try { 31 Thread.sleep(20); 32 } catch (InterruptedException e) { 33 // TODO 自動生成された catch ブロック 34 e.printStackTrace(); 35 } 36 } 37 } 38 39 public void init() { 40 enemy.init(); 41 hero.init(); 42 } 43 44 public void logic() { 45 enemy.move(); 46 hero.move(); 47 } 48 49 public void draw() { 50 Graphics g = image.getGraphics(); 51 g.setColor(Color.blue); 52 g.fillOval(enemy.point.x, enemy.point.y, 30, 30); 53 mainJFrame.draw(image); 54 } 55 56 } 57} 58 59class Character { 60 Point point = new Point(); 61 62 public void move() { 63 point.x++; 64 point.y++; 65 } 66} 67 68class Hero extends Character { 69 public void init() { 70 point.setLocation(20, 20); 71 } 72} 73 74class Enemy extends Character { 75 public void init() { 76 point.setLocation(50, 50); 77 } 78}

java

1package TestRpgWalk; 2 3import java.awt.Graphics; 4import java.awt.Image; 5 6import javax.swing.JFrame; 7 8public class MainJFrame extends JFrame { 9 Image image =null; 10 public MainJFrame() { 11setDefaultCloseOperation(EXIT_ON_CLOSE); 12setSize(600,600); 13setLocationRelativeTo(null); 14setTitle("Title"); 15setVisible(true); 16 } 17 public void paint(Graphics graphics) { 18 graphics.drawImage(image, 0, 0, this); 19 } 20 public void draw(Image image) { 21 this.image = image; 22 repaint(); 23} 24}

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

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

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

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

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

guest

回答1

0

これまでに描画していた、画像をがrepaintメソッドを呼び出しても、
描画されてしまっています。

これまでに描画していたモノを消していないなら残っているのは当然ではないでしょうか。
一番簡単には、 image をクリアする処理を入れることでしょう。

GameController.GameLoopクラス

java

1 public void draw() { 2 Graphics g = image.getGraphics(); 3 g.setColor(new Color(0x80c080)); //追加 4 g.fillRect(0, 0, mainJFrame.getWidth(), mainJFrame.getHeight()); //追加 5 g.setColor(Color.blue);

JFrame に直接ペイントせず、 JPanel を土台に paintComponent を Override して直接(間に offscreen の image を挟まず)描画します。
描画タイミングには Swing の Timer クラスを使用します。ウインドウのアクティブ状態に合わせて再開/停止を制御します。
データの描画と更新の衝突を防ぐため、 syncronized を入れています。
キャラクタの描画はそれぞれのクラス自身が行います。Hero も赤四角として横に移動させるようにしました。

java

1import java.awt.*; 2import java.awt.event.WindowAdapter; 3import java.awt.event.WindowEvent; 4import java.util.ArrayList; 5import java.util.List; 6 7import javax.swing.*; 8 9public class TestArpgWalk extends JFrame { 10 public static void main(String[] args) { 11 SwingUtilities.invokeLater(() -> new TestArpgWalk().setVisible(true)); 12 } 13 14 TestArpgWalk() { 15 super("Title"); 16 setDefaultCloseOperation(EXIT_ON_CLOSE); 17 18 GamePanel gamePanel = new GamePanel(); 19 setContentPane(gamePanel); 20 21 addWindowListener(new WindowAdapter() { 22 @Override 23 public void windowActivated(WindowEvent e) { 24 //System.out.println("windowActivated"); 25 gamePanel.resume(); 26 } 27 @Override 28 public void windowDeactivated(WindowEvent e) { 29 //System.out.println("windowDeactivated"); 30 gamePanel.pause(); 31 } 32 @Override 33 public void windowClosing(WindowEvent e) { 34 //System.out.println("windowClosing"); 35 windowDeactivated(e); 36 } 37 }); 38 39 pack(); 40 setLocationRelativeTo(null); 41 } 42} 43 44class GamePanel extends JPanel { 45 private List<Character> charaList = new ArrayList<>(); 46 private Timer gameLoop; 47 48 public GamePanel() { 49 super(null); 50 setSize(600, 600); 51 setPreferredSize(getSize()); 52 setMinimumSize(getSize()); 53 54 setBackground(new Color(0x80c080)); 55 56 charaList.add(new Hero()); 57 charaList.add(new Enemy()); 58 } 59 60 void resume() { 61 if(gameLoop != null) throw new IllegalStateException("'gameLoop' NOT null"); 62 gameLoop = new Timer(20, e -> { tick(); repaint(); } ); 63 gameLoop.start(); 64 } 65 66 void pause() { 67 if(gameLoop != null) { 68 gameLoop.stop(); 69 gameLoop = null; 70 } 71 } 72 73 @Override 74 synchronized public void paintComponent(Graphics g) { 75 super.paintComponent(g); 76 for(Character c : charaList) c.draw(g); 77 } 78 79 synchronized private void tick() { 80 logic(); 81 } 82 83 private void logic() { 84 for(Character c : charaList) c.move(); 85 } 86} 87 88abstract class Character { 89 protected Point point = new Point(); 90 91 void move() {} 92 abstract void draw(Graphics g); 93} 94 95class Hero extends Character { 96 Hero() { 97 point.setLocation(20, 20); 98 } 99 100 @Override 101 void move() { 102 point.x++; 103 } 104 105 @Override 106 void draw(Graphics g) { 107 g.setColor(Color.RED); 108 g.fillRect(point.x, point.y, 30, 30); 109 } 110} 111 112class Enemy extends Character { 113 Enemy() { 114 point.setLocation(50, 50); 115 } 116 117 @Override 118 void move() { 119 point.x++; 120 point.y++; 121 } 122 123 @Override 124 void draw(Graphics g) { 125 g.setColor(Color.BLUE); 126 g.fillOval(point.x, point.y, 30, 30); 127 } 128}

投稿2023/10/04 02:00

編集2023/10/04 07:41
jimbe

総合スコア12648

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問