Javaの道 Javaに関する
 ニュースJava基本Servlet・JSPオープンソースFAQ掲示板
Javaの道 >  掲示板 >  掲示板(ボールアニメーションプログラムの不具合に関する質問)
閲覧数:731
掲示板(ボールアニメーションプログラムの不具合に関する質問)
名前
匿名
題名 ボールアニメーションプログラムの不具合に関する質問
質問内容

質問を評価する
(0ポイント)
以下のボールプログラムで、次の進行方向に棒をのばしたいのですがうまくいきません。
どこをどう改良したらよいのでしょうか?
おそらく、Angleの更新などが問題だと思うのですが…

Dot.java
import java.util.Random;

class Dot {
    private int x;
    private int y;
    private int vx;
    private int vy;        
    public int w;
    public int r;
    public int h;
    public int Angle;
    public int v;
    public int m = 10;
    int cos;
    int sin;
    boolean bl = false;    
    Random rnd = new Random();

    public Dot(int x, int y, int v, int cos, int sin, int Angle) {
        this.x = x;
        this.y = y;
        this.v = v;
        this.sin = sin;
        this.cos = cos;
        this.Angle= Angle;
        vx = v * cos;
        vy = v * sin;
    }
    
    
    public void action(int w, int h, int r) {
    if ( x < 0){ 
            vx = -vx;
            if (Angle > 180){
                Angle =90 + Angle;
            }
            else{
                Angle = 180 - Angle;                        
            }
        }
        if ( x > w-2*r){ 
            vx = -vx;
            if( Angle < 180){
                Angle = 270 - Angle;
            }
            else{
                Angle = 540 - Angle;            
            }
        }
        if ( y< 0){ 
            vy = -vy;
            if( Angle < 90){
                Angle = 180 + Angle;
            }
            else{
                Angle = 360 - Angle;            
            }            
        }
        if (y > h-2*r){ 
            vy = -vy;
            Angle = 360 - Angle;            
        }        
        x = x + vx * m;
        y = y + vy * m;
    }
    public void setX(int x){
        this.x = x;
    }
    public void setY(int y){
        this.y = y;
    }
    public void setM(int m){
        this.m = m;
    }
    public void setV(int v){
        this.v = v;
    }    
    public int getX() {
       return x;
    }
    public int getY() {
        return y;
    }
    public int getCos() {
       return cos;
    }
    public int getSin() {
        return sin;
    }
     public int     Angle() {
        return Angle;
    }
}    

MyPanel.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.Random;

class MyPanel extends JPanel implements Runnable{
    int num;
    int ballNum;
    Dot[] dot;             
    Frame frame = null;
    Random rnd = new Random();
    int r = rnd.nextInt(100);
    int Angle; 
    int v;
    int vx;
    int vy;
    int sin;
    int cos;
    
        
    public MyPanel(Frame frame){
        this.frame = frame;
        num = 100;
        dot = new Dot[num];
        setBackground(Color.YELLOW);
        ballNum = 0;
        v = 1;
    
        for( int k = 0; k<dot.length; k++){
            int a = rnd.nextInt(100);
            int b = rnd .nextInt(100);
            Angle = rnd.nextInt(360 + 1);    
            double c =  (Math.cos(Math.toRadians(Angle))* 10);
            double d =  (Math.sin(Math.toRadians(Angle)) * 10);
            int cos = (int)c;
            int sin = (int)d;    
               dot[k] = new Dot(a,b,v,cos,sin,Angle);
            }
        Thread th = new Thread(this);
        th.start();
        addMouseListener(new SampleMouseListener());
    }
    
    class SampleMouseListener extends MouseAdapter{
        public void mouseClicked(MouseEvent e){
            dot[ballNum].setX(e.getX());
            dot[ballNum].setY(e.getY());        
            ballNum++;
        }
    }
    
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        for( int k = 0; k<ballNum; k++){
            if (dot[k].bl == true){
                dot[k].action(frame.getWidth(),frame.getHeight(), r);
                g.fillOval(dot[k].getX(),dot[k].getY(),r, r);
                if (dot[k].Angle() >0 && dot[k].Angle() < 90){
                    g.drawLine(dot[k].getX()+r/2,dot[k].getY()+r/2,dot[k].getX()+r*(int)(Math.cos(dot[k].Angle())*10) ,dot[k].getY()+r*(int)(Math.sin(dot[k].Angle())*10));    
                }
                if (dot[k].Angle() >90 && dot[k].Angle() < 180){
                    g.drawLine(dot[k].getX()+r/2,dot[k].getY()+r/2,dot[k].getX()-r*(int)(Math.cos(dot[k].Angle())*10),dot[k].getY()+r*(int)(Math.sin(dot[k].Angle())*10));    
                }
                if (dot[k].Angle() >180 && dot[k].Angle() < 270){
                    g.drawLine(dot[k].getX()+r/2,dot[k].getY()+r/2,dot[k].getX()-r*(int)(Math.cos(dot[k].Angle())*10),dot[k].getY()+r*(int)(Math.sin(dot[k].Angle())*10));    
                }
                if (dot[k].Angle() >270 && dot[k].Angle() < 360){
                    g.drawLine(dot[k].getX()+r/2,dot[k].getY()+r/2,dot[k].getX()+r*(int)(Math.cos(dot[k].Angle())*10),dot[k].getY()-r*(int)(Math.sin(dot[k].Angle())*10));    
                }    
            }
            else if (dot[k].bl == false){
                g.fillOval(dot[k].getX(),dot[k].getY(),r, r);
                g.drawLine(dot[k].getX()+r/2,dot[k].getY()+r/2,dot[k].getX()+r*(int)(Math.cos(dot[k].Angle())*10),dot[k].getY()+r*(int)(Math.sin(dot[k].Angle())*10));    
            }
        }
    }
    
    public void setV(int ve){
        this.v = ve;
    }
    
    public void run(){        
        while(true){
            repaint();
            try{
                Thread.sleep(10);
            }catch(Exception e){
            }
        }
    }
}

Frame.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;

import java.util.Random;

public class Frame extends JFrame{
        
    private JPanel pn = new JPanel();
    public MyPanel mpn =new MyPanel( this ); 
    
    private JButton bt[] = new JButton[2];
 
    public JSlider slider1  = new JSlider(1,10);
    
    public  JLabel label = new JLabel();
     
    Frame(){
        super();
        setSize(400,200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            
        bt[0] = new JButton("start");
           bt[1] = new JButton("stop");        
        
        pn. setLayout(new FlowLayout());
        
        for( int i = 0; i< bt.length; i++){ 
            pn.add(bt[i]);
        }    
        
        add(pn, BorderLayout.NORTH);
        add(mpn, BorderLayout.CENTER);

        pn.add(slider1, BorderLayout.NORTH);
        pn.add(label, BorderLayout.SOUTH);
        
          
        slider1.addChangeListener(new SampleChangeListener());
        pn.add(slider1,BorderLayout.NORTH);

        label.setText(slider1.getValue() + "倍速");
        
        for(int i=0; i<bt.length; i++){
            bt[i].addActionListener(new SampleActionListener());
        }
    }    
    
    class SampleActionListener implements ActionListener{
        public void actionPerformed(ActionEvent e){
            JButton tmp = (JButton) e.getSource();
            for( int k = 0; k<mpn.dot.length; k++){
                if( tmp == bt[0] ){  //startボタンのアクション 
                    mpn.dot[k].bl = true;
                }
                if( tmp == bt[1] ){   //stopボタンのアクション 
                    mpn.dot[k].bl = false;
                }
            }
        }
    }
    
    
    class SampleChangeListener implements ChangeListener{
        public void stateChanged(ChangeEvent e) {
            label.setText(slider1.getValue() + "倍速");
            for (int k=0; k < mpn.dot.length; k++){
                mpn.dot[k].setM( slider1.getValue());
                mpn.setV( slider1.getValue());
            }
        }
    }

    public static void main(String args[]){
        Frame frame = new Frame();
        frame.setVisible(true);
    }
}
質問日時 2013-05-21 17:51:00
名前
匿名
回答内容

回答を評価する
(0ポイント)
デバッグ文入れて、どこからうまくいかなくなってるのかを探そう。
回答日時 2013-05-21 22:04:35
名前
回答内容

回答を評価する
(0ポイント)
根本的な構造に問題がありそうです。
paintComponent は repaint だけが呼び出すわけではありませんから、
アニメーション自体は定期的に実行される run メソッドのループ内に
書かないとおかしな動きになる可能性があります。
しかし、run メソッドは GUI とは別スレッドなので何らかの方法で
同期を取らないと不具合が出るでしょう。
javax.swing.SwingUtilities の invokeAndWait や invokeLater が
そういった目的のために用意されてます。

ただ、javax.swing.Timer を使った方が実装しやすいと思います。
回答日時 2013-05-21 23:14:51

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。



このページのトップへ
 ニュースJava基本Servlet・JSPオープンソースFAQ掲示板
Javaの道_CopyrightJavaの道