ここから本文です

二つボタンを選ぶと元に戻るようにしたいです。ヒントお願いしますm(__)m ↓元のプ...

jqw********さん

2012/10/923:14:47

二つボタンを選ぶと元に戻るようにしたいです。ヒントお願いしますm(__)m
↓元のプログラミングです。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;

public class Card8{
public static void main(String[]args){
JFrame jf = new JFrame("神経衰弱");
BPanel bp = new BPanel();
bp.setPanel();
jf.getContentPane().add(bp);
jf.pack();
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

class BPanel extends JPanel implements ActionListener{
JButton[] jb = new JButton[20];
int[] panel = new int[20];
int nowClick;
int preClick = -1;
int cnt = 0;

public BPanel(){
setLayout(new GridLayout(4,5));
for(int i=0;i<20;i++){
jb[i] = new JButton();
jb[i].setPreferredSize(new Dimension(75,105));
jb[i].addActionListener(this);
add(jb[i]);
}
}

public void setPanel(){
List<Integer> list = new ArrayList<Integer>();
for(int i=0;i<10;i++){
list.add(i);
list.add(i);
}
Collections.shuffle(list);
for(int i=0;i<20;i++){
panel[i] = list.get(i);
}
}

public void actionPerformed(ActionEvent e){
for(int i=0;i<20;i++){
if(e.getSource() == jb[i]){
nowClick = i;
if(nowClick != preClick){ jb[i].setText(String.valueOf(panel[i]));
cnt++;
break;
}
}
}
if(((cnt%2) == 0) && (panel[nowClick] == panel[preClick])){
jb[nowClick].setEnabled(false);
jb[preClick].setEnabled(false);
}
preClick = nowClick;
}
}

閲覧数:
614
回答数:
1

違反報告

ベストアンサーに選ばれた回答

pz_********さん

2012/10/1013:53:40

最初にロジックの話をします。

その質問のやつは、cnt が偶数か奇数かでゲームを進めるようになっていますが・・・
もっと、きっちりとゲーム進行を管理しないと、いろいろ問題が出てきます。
そこで、カウントはゲーム進行によって・・・
0(めくってない)、1(1枚目をめくった)、2(2枚目をめくった)
・・・ときっちり管理します。
if(((cnt%2) == 0) && (panel[nowClick] == panel[preClick])){
↑この判定は、それを踏まえて↓こんな感じにします。
------------------------------------------------------------------
if(2 == cnt){ // 2枚めっくたら判定する
if(panel[nowClick] == panel[preClick]){
jb[nowClick].setEnabled(false);
jb[preClick].setEnabled(false);
}else{ // 2枚が合っていないなら表示を消す
jb[nowClick].setText("");
jb[preClick].setText("");
}
preClick = -1; //ちゃんと最初の状態に戻す
cnt = 0; // ちゃんと最初の状態に戻す
}else{ // まだ2枚めくっていないとき
preClick = nowClick;
}
------------------------------------------------------------------
ロジックは↑こうなのですが、しかし・・・
重要な問題があります。
合ってないとき2枚のカードの数字を消すわけですが・・・
速くて人の目では2枚目の数字を捉えることが出来ません。
そこで対策が必要になります。

自分なら、約1秒間数字を表示して、その後に消します。
そのためには、Thread を知らなくてはなりません。

なお、現在の処理スレッドを sleep( ) させても、表示が更新されません。
つまり、2枚目の数字が表示されない状態で sleep( ) してしまいます。
それは、 jb[i].setText(String.valueOf(panel[i]) <-- この命令が
描画システムの都合で後で表示されるからです。
なので、別スレッドで時間を計測する必要があります。

なにはともあれコードを出しましょう。

↓まず、クラス BPanel にメンバ変数を追加します。
int flgWait = 0;
int sav_nowClick;
int sav_preClick;

そして、クラス BPanel の actionPerformed( ) の先頭に・・・
↓これを追記します。
if(0 != flgWait) return;

そして・・・
if(((cnt%2) == 0) && (panel[nowClick] == panel[preClick])){
↑これを↓こうします。
------------------------------------------------------------------
if(2 == cnt){ // 2枚めっくたら判定する
if(panel[nowClick] == panel[preClick]){
jb[nowClick].setEnabled(false);
jb[preClick].setEnabled(false);
}else{ // 2枚が合っていないなら1秒後に表示を消す
sav_nowClick = nowClick;
sav_preClick = preClick;
flgWait = 1;
java.util.Timer tmr = new java.util.Timer();
tmr.schedule(new java.util.TimerTask(){
@Override
public void run(){ // 1秒後に実行される
jb[sav_nowClick].setText("");
jb[sav_preClick].setText("");
flgWait = 0;
}
}, 1000); // 1秒=1000ms
}
preClick = -1; //ちゃんと最初の状態に戻す
cnt = 0; //ちゃんと最初の状態に戻す
}else{ // まだ2枚めくっていないとき
preClick = nowClick;
}
------------------------------------------------------------------

・・・こんな感じ。

質問した人からのコメント

2012/10/10 20:57:30

笑う ありがとうございました!実際に実行できました!

あわせて知りたい

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる