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

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

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

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

関数型プログラミング

関数型プログラミングとは、関数を用いて演算子を構築し、算出し、コンピュータプログラムを構成する枠組みです。

Eclipse

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

Q&A

1回答

1716閲覧

Java スクリーンにボールを複数生成し,各々異なる方角と速さで運動させたい.

-_sora.

総合スコア12

Java

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

関数型プログラミング

関数型プログラミングとは、関数を用いて演算子を構築し、算出し、コンピュータプログラムを構成する枠組みです。

Eclipse

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

0グッド

0クリップ

投稿2020/08/13 10:25

編集2020/08/13 18:22

前提・実現したいこと

スクリーンにボールを引数の数(mainのargs[0])だけ生成し,各々異なる方角と速さで運動させたい.

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

生成するボールのクラスとスクリーンにボールを一つだけ生成するプログラムは完成したのですが,二つを組み合わせる方法が分かりません.

該当のソースコード

/* ボールを1つだけ生成し,動かすプログラム */ import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RadialGradientPaint; import java.awt.event.KeyEvent;/* キーボードからのイベント */ import java.awt.event.KeyListener;/* キーボードからのイベントのリスナー */ import java.awt.geom.Point2D; import javax.swing.JFrame; public class Kakunin extends JFrame implements Runnable, KeyListener { int x = 150, y = 50, r = 50; // 初期位置と円の半径 int saveX, saveY; // 現在位置のセーブ用 int dx = 11, dy = 7; // 円の速度ベクトル int saveDx, saveDy; // 現在の進行方向ベクトルのセーブ用 final int sleepTime = 10; // 休止時間(ミリ秒) // オフスクリーン画像用のデータ Thread thread = null;/* スレッド用データ */ Thread saveThread = null;/* セーブスレッド用データ */ Image offScreenImage = null;/* 前景オフスクリーン用データ */ Image backGroundImage = null;/* 背景オフスクリーン用データ */ Graphics backG = null;/* 背景グラフィクス */ Graphics offG = null;/* 前景グラフィクス */ Graphics saveOffG = null;/* 前景グラフィクスのセーブ(再開で使用) */ Graphics2D offG2 = null;/* 前景グラフィクスGraphics2D */ private int w; // 横幅 private int h; // 縦幅 java.awt.Color backColor = new java.awt.Color(1.0f,1.0f,1.0f);/*背景色 */ float R = 1.0f, G = 0.0f, B = 0.0f; java.awt.Color ballColor = new java.awt.Color(R,G,B);/*ボールの色;赤色 */ java.awt.Color ballColor2 = new java.awt.Color(Math.max((int)(1.25*R),255), Math.max((int)(1.25*G),255), Math.max((int)(1.25*B),255));/*ボールの色2 */ public Kakunin(String name){ super(name);} public void quit(){ System.exit(0); } /* 以下の3つの関数はキーボードのイベントを取得するために宣言が必要 */ public void keyPressed(KeyEvent e){/* キーが押された時のイベント */ if (e.getKeyCode()==KeyEvent.VK_ESCAPE) quit();/* VK_ESCAPEはキーボードのEscapeボタン */ else if (e.getKeyCode()==KeyEvent.VK_S) {/* ストップ */ stop(); } else if (e.getKeyCode()==KeyEvent.VK_R) {/* Rキー:リズーム(再開) */ resume(); } } public void keyReleased(KeyEvent e){}/* キーがリリースされたとき */ public void keyTyped(KeyEvent e){}/* キーがタイプされたとき */ public void init(){ Dimension d = getSize();// ウィンドウサイズ獲得 w = d.width;//横幅セット h = d.height;//縦幅セット // オフスクリーン(前面)画像用のデータ領域 offScreenImage = createImage(w,h);//前面オフスクリーン領域生成 offG = saveOffG = offScreenImage.getGraphics();//前面オフスクリーン描画用オブジェクト獲得 offG2 = (Graphics2D) offG; // オフスクリーン(背景)画像用のデータ領域 backGroundImage = createImage(w,h);//後面オフスクリーン領域生成 backG = backGroundImage.getGraphics();//後面オフスクリーン描画用オブジェクト獲得 backG.setColor(backColor);//背景は白色 backG.fillRect(0,0,w,h);//背景を白で塗りつぶし addKeyListener(this);/* キーボードのリスナーを設定 */ } public void paint(Graphics g) { /* キャンバスが準備できていない場合は何もしない */ if (offG == null || backGroundImage == null) return; // まず背景オフスクリーン画像を描画 offG.drawImage(backGroundImage,0,0,this); java.awt.Color centerColor = ballColor; java.awt.Color color2 = ballColor2; Point2D center = new Point2D.Double(x, y);/* ボールの中央位置 */ float radius = r;/* 半径 */ float[] dist = {0.15f, 0.8f};/* 0.15(color2), 0.8(centerColor) [0.15-0.8]を補間*/ Color[] colors = {color2, centerColor};/* 補間のための2色 */ RadialGradientPaint rgp = new RadialGradientPaint(center, radius, dist, colors); offG2.setPaint(rgp);/* ボールの色塗り設定 (Graphics2Dクラス(offG2)が必要)*/ offG.fillOval(x-r, y-r, r*2, r*2);/* ボールの描画(前景)*/ g.drawImage(offScreenImage,0,0,this); } public void animate() {/* ボールの位置変更 */ if (thread != null){ // ウィンドウの端で速度ベクトルを反転 java.awt.Rectangle bounds = getBounds(); if ((x - r + dx < 0) || (x + r + dx > bounds.width)) dx = -dx; if ((y - r + dy < 0) || (y + r + dy > bounds.height)) dy = -dy; // 円の移動 (一般にはx = lastx(直前位置) + speedX * dx) x += dx; y += dy; // paint()メソッドを呼び出す(repaint()で間接的に) repaint(); } } /** * This method is from the Runnable interface. It is the body of the * thread that performs the animation. The thread itself is created * and started in the start() method. **/ public void run() { while (true){ if (thread != null) { animate();//描画位置更新 } try { Thread.sleep(sleepTime);// 待つ } catch (InterruptedException e){}//割り込みなし } } /** Start animating when the browser starts the applet */ public void start() { if (thread == null){ thread = saveThread = new Thread(this);//スレッド生成 thread.start();//スレッド開始 } } /** Stop animating when the browser stops the applet */ public void stop() { if (thread != null){ saveX = x; saveY = y;/* 現在位置をセーブ */ saveDx = dx; saveDy = dy;/* 現在の方向をセーブ */ offG = null;/* thread.stop()は非推奨なのでpaintを空回りさせ動きをストップさせる */ thread = null; } } public void resume(){/* スレッド再開 */ if (offG == null && thread == null){ offG = saveOffG;/* セーブしていたオフスクリーングラフィックスを戻す*/ thread = saveThread;/* セーブしていたスレッドを戻す */ x = saveX; y = saveY;/* セーブしていた位置を戻す */ dx = saveDx; dy = saveDy;/* セーブしていたベクトルを戻す */ } } public static void main(String[] args) { Kakunin bcf = new Kakunin("8月16日"); bcf.setSize(600, 600); bcf.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); bcf.setVisible(true); bcf.init(); bcf.start(); } }
/* 生成されるボールのクラス */ import java.util.Date; import java.util.Random; public class Ball { double radius; /* 半径 */ float R,G,B; /* 色の要素 */ double x,y; /* 位置 */ double dx,dy; /* 方向ベクトル */ double lastx,lasty; /* 直前の位置 */ public Ball(){ Date date = new Date();/* 現在の日付(乱数の初期値用)*/ Random rand = new Random(date.getTime());/* 乱数クラス */ radius = rand.nextDouble()*80 /* 0-80までの半径 */; /* 半径が1より小さい間 */ while(radius<1) { radius = rand.nextDouble()*80; } x = rand.nextDouble()*400; /* 0-400までの値 */ y = rand.nextDouble()*400; /* 0-400までの値 */ lastx = x; /* xと同じ */ lasty = y; /* yと同じ */ dx = (rand.nextDouble()*80)-40; /* -40から40までの値 */ dy = (rand.nextDouble()*80)-40; /* -40から40までの値 */ R = rand.nextFloat(); /* 0.0-1.0までの値 */ G = rand.nextFloat(); /* 0.0-1.0までの値 */ B = rand.nextFloat(); /* 0.0-1.0までの値 */ } public void move(java.awt.Rectangle bounds) {/* ボールの位置変更 */ if((x-radius+dx < 0)||(x + radius + dx > bounds.width)){ dx = -dx;//画面の左右の壁にぶつかったら x 方向を変更 } if((y - radius + dy < 0)||(y + radius + dy > bounds.height)){ dy = -dy;//画面の上下の壁にぶつかったら y 方向を変更  } x = lastx + dx; y = lasty + dy; lastx = x; lasty = y; } }

試したこと

Kakuninクラスの最初に Ball[] balls = null; と宣言し,init()関数にて以下のようにBall型変数を生成したのですが,各々についてanimate()関数を実行する方法が分からず行き詰っています.
start()でスレッドが開始されるので,main()の引数args[0]をrun()に渡すことができないかと思考しています.

balls = new Ball[numBalls]; for( int i=0; i<numBalls; i++) { balls[i] = new Ball(); }

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

eclipse2018のjava10を使用しています。

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

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

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

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

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

guest

回答1

0

各々についてanimate()関数を実行する方法が分からず行き詰っています.

animate()でやりたいことは、結局Ball.move()ですよね?

main()の引数args[0]をrun()に渡すことができないかと思考しています.

Kakuninのコンストラクタでもinit()でも好きに引数で渡せばいいのでは?
run()に個数を渡す必要がありますか?

Ballクラスにpublic void paint(Graphics2D g)メソッドを作るといいと思います。
move()paint()update()draw()等になっていることも)の組で処理するのは非常にポピュラーな手法です^^


いろいろつぎはぎで混乱されていると思うので、整理させていただきました(割と好き勝手に変えました^^;

  • おそらくpaintComponentのほうがいいと思うので、JPanelベースに変更
  • 不要なフィールド廃止
  • KeyAdapterで無駄メソッド省略
  • runningフラグでポーズの簡略化
  • できるだけfinal
  • できるだけprivate

等々

Java

1import java.awt.Color; 2import java.awt.Graphics; 3import java.awt.Graphics2D; 4import java.awt.Image; 5import java.awt.RadialGradientPaint; 6import java.awt.Rectangle; 7import java.awt.event.KeyAdapter; 8import java.awt.event.KeyEvent; 9import java.awt.geom.Point2D; 10import java.io.File; 11import java.io.IOException; 12import java.util.Random; 13import javax.imageio.ImageIO; 14import javax.swing.JFrame; 15import javax.swing.JPanel; 16 17public class Kakunin extends JPanel implements Runnable { 18 public static void main(String[] args) throws IOException { 19// int count = Integer.parseInt(args[0]); 20 int count = 5; 21 22 Kakunin panel = new Kakunin(count); 23 JFrame frame = new JFrame("8月16日"); 24 25 frame.setSize(600, 600); 26 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 27 frame.add(panel); 28 frame.setVisible(true); 29 } 30 31 private final int sleepTime = 10; 32 private final Image backGroundImage; // 本来は何か画像が来るんですよね? 33 private final Ball[] balls; 34 35 private boolean running = true; 36 37 public Kakunin(int ballCount) throws IOException { 38 setFocusable(true); 39 40// backGroundImage = ImageIO.read(new File("")); 41 backGroundImage = null; 42 43 balls = new Ball[ballCount]; 44 for (int i = 0; i < balls.length; i++) { 45 balls[i] = new Ball(); 46 } 47 48 addKeyListener(new KeyAdapter() { 49 @Override public void keyPressed(KeyEvent e) { 50 if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { 51 System.exit(0); // quit 52 } else if (e.getKeyCode() == KeyEvent.VK_S) { 53 running = false; // stop 54 } else if (e.getKeyCode() == KeyEvent.VK_R) { 55 running = true; // resume 56 } 57 } 58 }); 59 60 new Thread(this).start(); 61 } 62 63 @Override public void paintComponent(Graphics g) { 64 super.paintComponent(g); 65 66 if (backGroundImage != null) { 67 g.drawImage(backGroundImage, 0, 0, this); 68 } 69 70 for (Ball ball : balls) { 71 ball.paint((Graphics2D) g); 72 } 73 } 74 75 public void run() { 76 while (true) { 77 if (running) { 78 animate(); 79 } 80 try { 81 Thread.sleep(sleepTime); 82 } catch (InterruptedException e) {} 83 } 84 } 85 86 private void animate() { 87 Rectangle bounds = getBounds(); 88 for (Ball ball : balls) { 89 ball.move(bounds); 90 } 91 92 repaint(); 93 } 94} 95 96class Ball { 97 private static final Random rand = new Random(); 98 private static final float[] dist = { 0.15f, 0.8f }; 99 100 private final int radius = rand.nextInt(70) + 10; 101 private final Color[] colors; 102 103 private int x = rand.nextInt(400) + 100; 104 private int y = rand.nextInt(400) + 100; 105 private int dx = rand.nextInt(20) - 10; 106 private int dy = rand.nextInt(20) - 10; 107 108 public Ball() { 109 Color color = new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)); 110 colors = new Color[]{ color.brighter(), color, }; 111 } 112 113 public void move(Rectangle bounds) { 114 if ((x - radius + dx < 0) || (bounds.width < x + radius + dx)) { 115 dx = -dx; 116 } 117 118 if ((y - radius + dy < 0) || (bounds.height < y + radius + dy)) { 119 dy = -dy; 120 } 121 122 x += dx; 123 y += dy; 124 } 125 126 public void paint(Graphics2D g) { 127 Point2D center = new Point2D.Double(x, y); 128 RadialGradientPaint rgp = new RadialGradientPaint(center, radius, dist, colors); 129 g.setPaint(rgp); 130 g.fillOval(x - radius, y - radius, radius * 2, radius * 2); 131 } 132}

投稿2020/08/13 21:29

TN8001

総合スコア9862

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問