コードは長いですが、簡単なゲームをつくろうとしています。このコードで実行⇒スタート(ボタン)⇒右上の画像ボタン(最初は別の画像で、押すと消える)を押すと元のウィンドウは消え、別ウィンドウに画像が表示されるイベント処理があります。1回目は成功するのですが、なぜか2回目からはこの動作が複数回起き(2回程度)、続けていると1回のクリックに対する動作の回数が増えていき、最終的にはウィンドウの嵐になります。対処法を教えてください。
コードは長いですが、バグに関係あるのはタイマー処理に関係する部分と、CATCH1~3()のところだと思ってます。
java
package sample;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
class TASK extends TimerTask{
// タイマー処理のメソッドを誘発させる public void run(){ Fishing Act = new Fishing(); // これができなければ詰んでた Act.ROLL(); }
}
class TASK2 extends TimerTask{
// タイマー処理のメソッドを誘発させる public void run(){ Fishing Act = new Fishing(); Act.ROLL2(); }
}
public class Fishing extends JFrame implements ActionListener
{
private static final long serialVersionUID = 1L;
//クラス変数定義
public static int flag=0;
static int gamescore =0;
static int alltime =0; //60sカウントに使う。
static int[] fish_score1={0,50,50,100,100};
static int[] fish_score2={150,150,200,200,250};
static int[] fish_score3={300,300,400,400,500};
static int[] fish_scoreQ={-50,-50,-100,0,1000};
static ImageIcon[] fish1={new ImageIcon("N0.jpg"),new ImageIcon("N1.jpg"),new ImageIcon("N2.jpg"),new ImageIcon("N3.jpg"),new ImageIcon("N4.jpg"),};
static ImageIcon[] fish2={new ImageIcon("R0.jpg"),new ImageIcon("R1.jpg"),new ImageIcon("R2.jpg"),new ImageIcon("R3.jpg"),new ImageIcon("R4.jpg"),};
static ImageIcon[] fish3={new ImageIcon("SR0.jpg"),new ImageIcon("SR1.jpg"),new ImageIcon("SR2.jpg"),new ImageIcon("SR3.jpg"),new ImageIcon("SR4.jpg"),};
static ImageIcon[] fishQ={new ImageIcon("SC0.jpg"),new ImageIcon("SC1.jpg"),new ImageIcon("SC2.jpg"),new ImageIcon("SC3.jpg"),new ImageIcon("SC4.jpg"),};
static JButton[] Bbt={new JButton(new ImageIcon("しーん.jpg")),new JButton(new ImageIcon("!.jpg")),
new JButton(new ImageIcon("!!.jpg")),new JButton(new ImageIcon("!!!.jpg")),new JButton(new ImageIcon("?.jpg"))};
ImageIcon Titlegazo = new ImageIcon("タイトル画像.jpg");
ImageIcon RULE1 = new ImageIcon("ルール1.jpg"); ImageIcon RULE2 = new ImageIcon("ルール2.jpg");
ImageIcon NINGEN = new ImageIcon("釣りbasic2.jpg"); ImageIcon SEA = new ImageIcon("海.jpg");
static JButton CHANGEBt=Bbt[0];
JButton bt1 = new JButton("スタート"); JButton bt2 = new JButton("あそびかた");
JButton bt3 = new JButton("つぎへ"); JButton bt4 = new JButton("タイトルへ");
JButton bt5 =new JButton("もどる");
JPanel p4 = new JPanel(); Timer timer2 = new Timer(true); Timer timer1 = new Timer(true);
// タイマー処理(本命)
public void ROLL(){
timer2.cancel();
int x= Atrandom();
//p4.revalidate();
//p4.remove(CHANGEBt); p4.add(Bbt[x]);
CHANGEBt.setBounds(0,0,0,0);
CHANGEBt=Bbt[x];
CHANGEBt.setBounds(378,120,375,280);
p4.revalidate();
p4.repaint();
switch(x){
case 1:
{
timer1.schedule(new TASK2(),600); break;
}
case 2:
{
timer1.schedule(new TASK2(),400); break;
}
}
}
//もう一つのタイマー処理
public void ROLL2(){
//if(flag%2==0){
timer1.cancel();
CHANGEBt.setBounds(0,0,0,0);
CHANGEBt=Bbt[0];
CHANGEBt.setBounds(378,120,375,280);
p4.revalidate();
p4.repaint();
// System.exit(0);
//Fishing Act = new Fishing(); Act.MAINGAME();
//}
}
//1~4までの非等倍乱数を得る。
public int Atrandom(){
int Ra[]={1,1,1,1,1,1,1,1,2,2,2,2,1,3,3,2,1,2,1,2}; Random r=new Random(); //4,4,4,4,4
int A=r.nextInt(20); int B = Ra[A];
return B;
}
//タイトル画面
public void TITLE(){
setBounds(550, 100, 770, 800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("魚釣りゲーム~タイトル~");
JLabel titleLabel = new JLabel(Titlegazo);
JPanel p1 = new JPanel();
p1.setLayout(null);
bt1.setBounds(310,580,130,30); bt2.setBounds(310,650,130,30);
bt1.addActionListener(this ); bt1.addActionListener(event -> dispose());
bt2.addActionListener(this ); bt2.addActionListener(event -> dispose());
p1.add(bt1); p1.add(bt2);
p1.add(titleLabel); titleLabel.setBounds(-10,0,770,760);
add("Center",p1);
setVisible(true);
}
//ルール説明1
public void Explain1(){
setBounds(550, 100, 770, 800);
setTitle("魚釣りゲームのルール説明");
JPanel p2 = new JPanel();
p2.setLayout(null);
bt3.setBounds(100,540,130,30);
bt3.addActionListener(this ); bt3.addActionListener(event -> dispose());
p2.add(bt3);
JLabel RURELabel1 = new JLabel(RULE1);
p2.add(RURELabel1); RURELabel1.setBounds(0,150,760,460);
add("Center",p2);
setVisible(true);
}
//ルール説明2
public void Explain2(){
setBounds(550, 100, 770, 800);
setTitle("魚釣りゲームのルール説明");
JPanel p3 = new JPanel();
p3.setLayout(null);
bt4.setBounds(50,520,180,30);
bt4.addActionListener(this ); bt4.addActionListener(event -> dispose());
p3.add(bt4);
JLabel RURELabel2 = new JLabel(RULE2);
p3.add(RURELabel2); RURELabel2.setBounds(0,150,760,460);
add("Center",p3);
setVisible(true);
}
// ゲーム画面
public void MAINGAME(){
setBounds(550, 100, 770, 800);
setTitle("魚釣りゲーム");
p4.setLayout(null);
JLabel SCORE_Label = new JLabel();
SCORE_Label.setText("SCORE: "+gamescore+"点");
p4.add(SCORE_Label); SCORE_Label.setBounds(100,0,400,400);
JLabel SEA_Label = new JLabel(SEA);
p4.add(SEA_Label); SEA_Label.setBounds(195,400,560,350);
JLabel NINGEN_Label = new JLabel(NINGEN);
p4.add(NINGEN_Label); NINGEN_Label.setBounds(0,180,380,380);
p4.add(CHANGEBt); CHANGEBt.setBounds(378,120,375,280);
CHANGEBt.addActionListener(this ); CHANGEBt.addActionListener(event -> dispose());
p4.add(Bbt[1]); p4.add(Bbt[2]); p4.add(Bbt[3]); p4.add(Bbt[4]); //サイズで表示非表示を表現するなら、ボタンは全部Addされていないといけない
Bbt[1].addActionListener(this ); Bbt[1].addActionListener(event -> dispose()); Bbt[3].addActionListener(this ); Bbt[3].addActionListener(event -> dispose());
Bbt[2].addActionListener(this ); Bbt[2].addActionListener(event -> dispose()); Bbt[4].addActionListener(this ); Bbt[4].addActionListener(event -> dispose());
add("Center",p4); //saigo
setVisible(true); //saigo
Random r = new Random(); int R;
R=100*(r.nextInt(50) +1); // 100<= R <= 5000
alltime = alltime + R; // 総合時間を加算
timer2.schedule(new TASK(),R); //タイマー処理は最後にコンパイラされる
}
// !ボタンが押されたとき
public void CATCH1(){
//flag=flag+1;
setBounds(550, 100, 770, 800); setTitle("魚釣りゲーム");
JPanel p5 = new JPanel(); p5.setLayout(null);
Random r = new Random(); int B= r.nextInt(5);
bt5.setBounds(280,650,130,30);
bt5.addActionListener(this ); bt5.addActionListener(event -> dispose());
p5.add(bt5);
ImageIcon A = fish1[B]; gamescore= gamescore+fish_score1[B];
JLabel CATCH_Label = new JLabel(); CATCH_Label.setText("釣り上げた!");
p5.add(CATCH_Label); CATCH_Label.setBounds(305,120,100,100);
JLabel A_Label = new JLabel(A);
p5.add(A_Label); A_Label.setBounds(150,200,400,400);
add("Center",p5); setVisible(true);
}
//!!ボタンが押されたとき
public void CATCH2(){
flag=flag+1;
setBounds(550, 100, 770, 800); setTitle("魚釣りゲーム");
JPanel p6 = new JPanel(); p6.setLayout(null);
Random r = new Random(); int B= r.nextInt(5);
bt5.setBounds(280,650,130,30);
bt5.addActionListener(this ); bt5.addActionListener(event -> dispose());
p6.add(bt5);
ImageIcon A = fish2[B]; gamescore=gamescore+fish_score2[B];
JLabel CATCH_Label = new JLabel(); CATCH_Label.setText("釣り上げた!");
p6.add(CATCH_Label); CATCH_Label.setBounds(305,120,100,100);
JLabel A_Label = new JLabel(A);
p6.add(A_Label); A_Label.setBounds(150,200,400,400);
add("Center",p6); setVisible(true);
}
//!!!ボタンが押されたとき
public void CATCH3(){
flag=flag+1;
setBounds(550, 100, 770, 800); setTitle("魚釣りゲーム");
JPanel p7 = new JPanel(); p7.setLayout(null);
Random r = new Random(); int B= r.nextInt(5);
bt5.setBounds(280,650,130,30);
bt5.addActionListener(this ); bt5.addActionListener(event -> dispose());
p7.add(bt5);
ImageIcon A = fish3[B]; gamescore=gamescore+fish_score3[B];
JLabel CATCH_Label = new JLabel(); CATCH_Label.setText("釣り上げた!");
p7.add(CATCH_Label); CATCH_Label.setBounds(305,120,100,100);
JLabel A_Label = new JLabel(A);
p7.add(A_Label); A_Label.setBounds(150,200,400,400);
add("Center",p7); setVisible(true);
}
// クリックからメソッドを誘導する
public void actionPerformed(ActionEvent e) {
if(e.getSource()==bt2){
Fishing ive = new Fishing(); ive.Explain1();
}
else if(e.getSource()==bt3){
Fishing ive = new Fishing(); ive.Explain2();
}
else if(e.getSource()==bt4){
Fishing ive = new Fishing(); ive.TITLE();
}
else if(e.getSource()==bt1){
Fishing ive = new Fishing(); ive.MAINGAME(); // スタート→メイン画面へ遷移
}
else if(e.getSource()==Bbt[1]){
Fishing ive = new Fishing(); ive.CATCH1();
}
else if(e.getSource()==Bbt[2]){
Fishing ive = new Fishing(); ive.CATCH2();
}
else if(e.getSource()==Bbt[3]){
Fishing ive = new Fishing(); ive.CATCH3();
}
else if(e.getSource()==bt5){ // 釣り上げ→メイン画面へ遷移
if(alltime<60000)
{
//flag=flag+1;
CHANGEBt=Bbt[0];
Fishing ive = new Fishing(); ive.MAINGAME();
}
else
{
//game end
}
}
}
//メインメソッド
public static void main(String[] args)
{
Fishing set = new Fishing(); set.TITLE();
}
}