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

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

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

JFrameはJFC/Swingフレームワークのコンポーネントであり、トップレベルのコンテナです。

Java

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

Swing

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

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Javaアプレット

Javaアプレットは、Webページに組み込まれて実行されるJavaアプリケーションの形式です。Java SE 11で廃止となりました。

Q&A

解決済

1回答

2093閲覧

ウインドウの端に当たると反射する丸のアニメーションを表示するプログラムをつくりたい

yastem

総合スコア2

JFrame

JFrameはJFC/Swingフレームワークのコンポーネントであり、トップレベルのコンテナです。

Java

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

Swing

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

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Javaアプレット

Javaアプレットは、Webページに組み込まれて実行されるJavaアプリケーションの形式です。Java SE 11で廃止となりました。

1グッド

0クリップ

投稿2020/06/16 07:42

前提・実現したいこと

javaでウインドウの端に当たると反射する丸のアニメーションを表示するプログラム(古いwindowsで、ロゴが画面内を反射しながら動くスクリーンセーバーがありましたが、丁度あの感じです)を作成したいのですが、狙い通りに動作しません。
最初に丸が左から斜め右下に動くことはいいとして、その後反射せずそのまま進んでいき、最終的には画面外に出ます。

発生している問題・エラーメッセージ

エラーメッセージの類は表示されませんでした。

該当のソースコード

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class R6_1a extends JPanel {
ArrayList<Figure> figs = new ArrayList<Figure>();
Circle c1 = new Circle(Color.BLUE, 100, 100, 20);
Text t1 = new Text(20, 40, "?", new Font("serif", Font.BOLD, 36)); //テキストのオブジェクト

public R6_1a() { setOpaque(false); figs.add(t1); figs.add(c1); final long tm0 = System.currentTimeMillis(); //開始時刻の取得 new javax.swing.Timer(50, new ActionListener() { //タイマーの設定.50ミリ秒間隔で繰り返す. public void actionPerformed(ActionEvent evt) { double tm = 0.001 * (System.currentTimeMillis() - tm0); //経過時間を計算 t1.setText(String.format("%5.2f", tm)); //経過時間の表示 int dx = 100, dy = 50; for (int i = 0; i < 1000; ++i) { if (tm * dy > getHeight() || tm * dy <= 0) { //フレームの下辺あるいは上辺にぶつかると反射する c1.moveTo(20 + (int)(tm * dx) , 20 + (int)(tm * -dy)); //円の移動 } if (tm * dx > getWidth() || tm * dx <= 0) { //フレームの横辺にぶつかると反射する c1.moveTo(20 + (int)(tm * -dx) , 20 + (int)(tm * dy)); //円の移動 } else{ c1.moveTo(20 + (int)(tm * dx) , 20 + (int)(tm * dy)); } } repaint(); } }).start(); //タイマーの開始 } public void paintComponent(Graphics g) { for (Figure f : figs) { f.draw(g); } } public static void main(String[] args) { JFrame app = new JFrame(); app.add(new R6_1a()); app.setSize(400, 400); app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); app.setVisible(true); } interface Figure { public void draw(Graphics g); } static class Circle implements Figure { Color col; int xpos, ypos, rad; public Circle(Color c, int x, int y, int r) { col = c; xpos = x; ypos = y; rad = r; } public boolean hit(int x, int y) { return (xpos - x) * (xpos - x) + (ypos - y) * (ypos - y) <= rad * rad; } public void setColor(Color c) { col = c; } public void moveTo(int x, int y) { xpos = x; ypos = y; } public void draw(Graphics g) { g.setColor(col); /*int dypos = 100; int dxpos = 80;*/ g.fillOval(xpos - rad, ypos - rad, rad * 2, rad * 2); /*for (int i = 0; i < 1000; ++i) { if (ypos - rad > 400 || ypos <= 0) { //フレームの下辺あるいは上辺にぶつかると反射する dypos = -dypos; g.setColor(new Color(35, 185, 15)); } if (xpos - rad > 400 || xpos <= 0) { //フレームの横辺にぶつかると反射する dxpos = -dxpos; g.setColor(new Color(220, 70, 240)); } ypos = ypos + dypos; xpos = xpos + dxpos; }*/ } } static class Text implements Figure { int xpos, ypos; String txt; Font fn; public Text(int x, int y, String t, Font f) { xpos = x; ypos = y; txt = t; fn = f; } public void setText(String t) { txt = t; } public void draw(Graphics g) { g.setColor(Color.BLACK); g.setFont(fn); g.drawString(txt, xpos, ypos); } }

}

試したこと

補足情報(FW/ツールのバージョンなど)

java初心者です。

TN8001👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

//タイマーの設定.50ミリ秒間隔で繰り返す.

actionPerformedが繰り返し呼ばれるのは分かっておられるんですよね?
なぜfor文が出てくるのでしょう??

yastemさんの実装を尊重するなら、総移動距離からなん折り返し目かを計算するような感じでしょうか?(回数ではなくどちら向きかが重要)

Java

1new javax.swing.Timer(50, new ActionListener() { 2 @Override 3 public void actionPerformed(ActionEvent evt) { 4 double tm = 0.001 * (System.currentTimeMillis() - tm0); 5 t1.setText(String.format("%5.2f", tm)); 6 int dx = 100, dy = 50; 7 8 double x = tm * dx; // 総移動距離 9 double y = tm * dy; 10 int w = getWidth() - 40; // 折り返しサイズ 11 int h = getHeight() - 40; 12 13 if ((int) (x / w) % 2 == 0) { // 総移動距離を横折り返しサイズで割った商が偶数なら→向き 14 x = x % w; // 余りをそのままxに 15 } else { // 奇数なら←向き 16 x = w - x % w; // 反転されるのでwから引く 17 } 18 if ((int) (y / h) % 2 == 0) { // 縦も同様 19 y = y % h; 20 } else { 21 y = h - y % h; 22 } 23 c1.moveTo(20 + (int) x, 20 + (int) y); 24 25 // 1行で書くならこんなん?? 26 // c1.moveTo(20 + (int) Math.abs((x + w) % (w * 2) - w), 20 + (int) Math.abs((y + h) % (h * 2) - h)); 27 repaint(); 28 } 29}).start();

投稿2020/06/17 09:29

編集2020/06/20 07:53
TN8001

総合スコア9831

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

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

yastem

2020/06/20 07:23

ご回答ありがとうございます。 いえ、折り返し回数を計算する目的はございません。経過時間のプログラムは、今の所特に意味を持たないとお考え下さい。 このプログラムの目的は、題意の通り「ウィンドウに当たると反射するプログラム」の作成です。 actionPerformedに関しては、完全に失念しておりました。
TN8001

2020/06/20 07:54 編集

> 総移動距離からなん折り返し目かを計算するような感じでしょうか? の部分は書き方が悪かったですね^^; 質問ではなく「こんな実装ではどうでしょう?」という提案です。 ラムダにしていましたが、yastemさんのコードに合わせます。 一応これで目的は達成できてると思います。 「yastemさんの実装を尊重するなら」という部分は、 「ウィンドウに当たると反射するプログラム」(ありがちなのはブロック崩し) において、 「タイマ1回の増分をdx dyとして持っておいて、壁に当たったら符号を逆にする」 という作りがポピュラーかなと思うのですが、だいぶ書き直すことになるので回答コードのほうが楽であろうという意味です。
yastem

2020/06/22 01:54

そういう意味でしたか。勘違いしてしまい、申し訳ございません。 はい。TN8001さんの実装で、こちらとしては問題ございません。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問