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

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

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

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

Q&A

解決済

1回答

1728閲覧

描画したのもがちらつく原因

nakamura-

総合スコア48

Java

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

1グッド

0クリップ

投稿2016/11/09 06:36

コード public class Game extends JFrame{ /**メインクラス*/ public static void main(String args[]){ new Game(); //フレーム作成 } /**コンストラクタ*/ public Game(){ /**フレームの初期化*/ setBounds(0, 0, 500, 500); //フレームの位置、大きさ設定 setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); /**パネルの生成*/ MainPanel mainPanel = new MainPanel(); add(mainPanel); setVisible(true); //フレーム表示 } }
コード public class MainPanel extends JPanel implements Runnable{ int count; Random rnd = new Random(); SummerBack summerBack[]; /**コンストラクタ*/ public MainPanel(){ summerBack = new SummerBack[100]; for(int i = 0; i < summerBack.length; i++){ summerBack[i] = new SummerBack(); } Thread thread = new Thread(this); thread.start(); } /**メインループ*/ @Override public void run(){ while(true){ count++; repaint(); try{ Thread.sleep(20); } catch(InterruptedException e){ } } } /**描画処理*/ @Override protected void paintComponent(Graphics g){ super.paintComponent(g); if(count % 40 == 0){ newSummerBack(rnd.nextInt(300) + 100, 0, 90, 30); } for(int i = 0; i < summerBack.length; i++){ if(summerBack[i].TorF == true){ summerBack[i].move(); summerBack[i].draw(g); } } } /**初期化*/ public int newSummerBack(double x, double y, double V0xy, double V0xy2){ for(int i = 0; i < summerBack.length; i++){ if(summerBack[i].TorF == false){ summerBack[i].initialization(x, y, V0xy, V0xy2); return i; } } return -1; } }
コード public class SummerBack{ double x; //x座標(現在地) double y; //y座標(現在地) boolean TorF; //インスタンス有効無効(falseならインスタンスは処理されない) /**打ち上がり段階*/ double V0xy; //初速度(合成) double V0x; //初速度(x成分) double V0y; //初速度(y成分) double Vx; //速度(x成分) double Vy; //速度(y成分) /**爆発段階*/ int fireBall = 1000; //分散花火数 double x2[] = new double[fireBall]; //x座標 double y2[] = new double[fireBall]; //y座標 double V0xy2MAX; double V0xy2[] = new double[fireBall]; //初速度(合成) double V0x2[] = new double[fireBall]; //初速度(x成分) double V0y2[] = new double[fireBall]; //初速度(y成分) double Vx2[] = new double[fireBall]; //速度(x成分) double Vy2[] = new double[fireBall]; //速度(y成分) double phi[] = new double[fireBall]; //分散花火の角度 int color; int colorR = 0; //赤 int colorG = 0; //緑 int colorB = 0; //青 double brightness = 0; //明度 /**共通*/ final double G = 9.8; //重力加速度 int count; //カウンタ double t; //時間 Random rnd = new Random(); /**花火管理変数*/ int fireSelect; final int fireUp = 0; final int fireExplosion = 1; /**コンストラクタ*/ public SummerBack(){ TorF = false; } /** * 初期化処理 * @param x x座標 * @param y y座標 * @param V0xy 打ち上がり初速度(合成) * @param V0xy2MAX 爆発初速度(合成)の最大値 */ public void initialization(double x, double y, double V0xy, double V0xy2MAX){ this.x = x; this.y = y; this.V0xy = V0xy; this.V0xy2MAX = V0xy2MAX; TorF = true; /**打ち上がり初速度のx成分 y成分を求める*/ double radian; radian = Math.toRadians(90); //度をラジアンに変換 V0x = V0xy * Math.cos(radian); //鉛直上投げなのでcos90 = 0, sin90 = 1 V0y = V0xy * Math.sin(radian); /**爆発初速度のx成分 y成分を求める*/ for(int i = 0; i < fireBall; i++){ V0xy2[i] = Math.random() * V0xy2MAX; phi[i] = Math.random() * 360; //全方向(0~360) phi[i] = Math.toRadians(phi[i]); //度をラジアンに変換 V0x2[i] = V0xy2[i] * Math.cos(phi[i]); //V0xy2のx成分 V0y2[i] = V0xy2[i] * Math.sin(phi[i]); //V0xy2のy成分 } /**色設定*/ color = rnd.nextInt(7); switch(color){ case 0: //赤 colorR = 255; colorG = 0; colorB = 0; break; case 1: //橙 colorR = 255; colorG = 183; colorB = 76; break; case 2: //黄 colorR = 255; colorG = 255; colorB = 0; break; case 3: //緑 colorR = 0; colorG = 255; colorB = 0; break; case 4: //青 colorR = 0; colorG = 0; colorB = 255; break; case 5: //藍 colorR = 39; colorG = 38; colorB = 114; break; case 6: //紫 colorR = 196; colorG = 0; colorB = 204; break; } brightness = 255; count = 0; fireSelect = fireUp; } /** * 移動処理 */ public void move(){ count++; t = count * 0.08; //時間調整 /**花火分岐*/ switch(fireSelect){ /**打ち上がり*/ case fireUp: Vy = V0y - G * t; //鉛直上投げなので V0 - at y = 500 - (V0y * t - G * t * t / 2); //鉛直上投げなので V0t - at2/2 if(Vy < 0.1){ //頂点に達したら爆発に移行 fireSelect = fireExplosion; count = 0; //カウンタを0に戻す } break; /**爆発*/ case fireExplosion: for(int i = 0; i < fireBall; i++){ Vx2[i] = V0x2[i]; //等速運動なので初速度で一定 Vy2[i] = V0y2[i] - G * t; //鉛直上投げ?なので V0 - at x2[i] = x + (V0x2[i] * t); //等速運動なので初速度×時間 y2[i] = y - (V0y2[i] * t - G * t * t / 2); //鉛直上投げ?なので V0t - at2/2 } /**明度0以下で花火消滅*/ if(brightness <= 0){ TorF = false; //花火消滅 } break; } } /** * 描画処理 */ public void draw(Graphics g){ /**花火分岐*/ switch(fireSelect){ /**打ち上がり*/ case fireUp: g.setColor(Color.BLACK); g.fillRect((int)x, (int)y, 2, 2); break; /**爆発*/ case fireExplosion: if(brightness > 0){ brightness -= 5; g.setColor(new Color(colorR, colorG, colorB, (int)brightness)); //明度を落としていく for(int i = 0; i < fireBall; i++){ g.fillRect((int)x2[i], (int)y2[i], 1, 1); } } break; } } }

花火を打ち上げるプログラムを作ってみました。
これを実行するとちゃんと花火は描画されるのですが、花火が爆発して消えた後すぐに、ちらつきかはわからないのですが花火が爆発している部分が一瞬描画されます。
これを消したいのですがどこを修正すればいいのかわかりませんでした。
わかる方がいればよろしくお願いします!

KiyoshiMotoki👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

打ち上げ終わった直後、

if(count % 40 == 0){

で、newSummerBackから、initializationが呼ばれます。
このとき、moveせずに、brightness = 255;してから、
move・drawしているので、移動前の座標に一瞬表示されるのではないでしょうか。

投稿2016/11/10 02:02

akio221

総合スコア716

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

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

nakamura-

2016/11/10 04:19

回答ありがとうございます! >moveせずに、brightness = 255;してから、 move・drawしているので というのはinitializationメソッドでbrightness = 255;と記述しているのが原因ということでしょうか?
akio221

2016/11/10 04:34

えーと。もうちょっとよく読んでみました。 brightness = 255にしたあと、moveで座標計算してまではいいと思いますが、 drawの、 g.setColor(new Color(colorR, colorG, colorB, (int)brightness)); //明度を落としていく が、 g.fillRect((int)x2[i], (int)y2[i], 1, 1); よりも先に走るため、移動前の描画に対して、カラーコードを変更し、 ちらついていると思われます。 机上デバッグなので間違ってたらごめんなさい。
nakamura-

2016/11/22 07:38

g.setColor(new Color(colorR, colorG, colorB, (int)brightness)); g.fillRect((int)x2[i], (int)y2[i], 1, 1); ではなく g.fillRect((int)x2[i], (int)y2[i], 1, 1); g.setColor(new Color(colorR, colorG, colorB, (int)brightness)); ということでしょうか? この場合色が設定されていないことになり黒で描画されましたが...
akio221

2016/11/22 07:54

いや、毎回そうなるんじゃなくて、打ちあがって消えた直後のみ、逆転するんですよ。
nakamura-

2016/11/28 04:54

ちらつきなく動作することができました。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問