国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

擲骰子游戲窗體實現--Java初級小項目

2019-11-14 14:59:56
字體:
來源:轉載
供稿:網友

擲骰子

**多線程&&觀察者模式

題目要求:《擲骰子》窗體小游戲,在該游戲中,玩家初始擁有1000的金錢,每次輸入押大還是押小,以及下注金額,隨機3個骰子的點數,如果3個骰子的總點數小于等于9,則開小,否則開大,然后判斷玩家是否押對,如果未押對則扣除下注金額,如果押對則獎勵和玩家下注金額相同的金錢。

分析:這個題目要求靈活運用多線程的相關知識,達到點擊開始按鈕時,有3個線程啟動,分別控制3顆骰子的轉動,在3顆骰子全部轉完以后,回到主線程計算游戲結果。

 1 //3個線程控制3顆骰子 2 Thread t1 = new Thread(); 3 Thread t2 = new Thread(); 4 Thread t3 = new Thread(); 5 //啟動3個線程 6 t1.start(); 7 t2.start(); 8 t3.start(); 9 //將3個線程加入主線程10 t1.join();11 t2.join();12 t3.join();

 

But,,,寫完代碼以后發現,這樣做雖然能夠保證游戲能夠正確運行,但是當我點擊開始按鈕時,由于3個骰子線程都是直接開在主線程上的,點擊開始按鈕時,按鈕出現下沉情況,子線程一直在后臺運行,我窗體中的圖片根本不會發生改變,而是直接顯示最后的結果,意思就是骰子一直在后臺轉動,不在前臺的窗體中及時更新顯示。后來在網上苦苦找尋,大神們說如果想要通過點擊JButton使窗體中的JLabel/JTextFeild等其他組件及時更新,直接在JButton的監聽事件的實現方法里面直接創建匿名線程,也就是說直接在actionPerformed()方法中修改代碼即可,這樣能保證你的組件中內容的及時變換,實現非常炫酷的效果。

 

代碼如下:

public void actionPerformed(ActionEvent e) {            new Thread(new Runnable() {                    @Override        public void run() {                            //將外部線程類轉移到窗體內部                        }    }).start();        }

 

But,,,But,,,   雖然非常炫酷了,能夠實現圖片的及時更新了,游戲結果卻錯了,每次我的骰子還在轉動呢,我的游戲結果卻早早的就出來了。

原因:3根骰子線程屬于子線程,窗體線程屬于主線程,問題就在于:子線程可以通過變成精靈線程來保持與主線程的同生死,但是主線程卻無法控制子線程何時死亡,只有等待子線程執行完所屬的run()方法,結束線程后才知道。

解決方法:在主線程(main)中開3個子線程(t1,t2,t3),在每個子線程上再開一個子子線程(t11,t21,t31)。

t1,t2,t3只運行一次,負責創建子子線程;t11,t21,t31每個線程運行多次,負責控制窗體中的圖標及時更新。

 

這樣主線程就不受子線程的影響,開始按鈕也不回出現下沉的情況。

但是同樣在此處使用join方法也是hold不住子線程的,畢竟t1,t2,t3只運行了一次,join對他們來說根本不起作用,想要掌控t11,t21,t31,最容易理解的辦法,就是使用觀察者模式了。

將窗體看做觀察者,子線程看做被觀察者。子線程運行完時,通知觀察者我已經運行完成,當觀察者觀察到子線程全都運行完時,才開始運行后續步驟。

全部代碼:

1.窗體

  1 package com.sxt.dice;  2   3 import java.awt.Color;  4   5 public class DiceFrame extends JFrame implements ActionListener, Observer {  6   7     /**  8      * 《擲骰子》控制臺小游戲,在該游戲中,玩家初始擁有1000的金錢,每次輸入押大還是押小,  9      * 以及下注金額,隨機3個骰子的點數,如果3個骰子的總點數小于等于9,則開小,否則開大, 10      * 然后判斷玩家是否押對,如果未押對則扣除下注金額,如果押對則獎勵和玩家下注金額相同的金錢。 11      *  12      * 運用觀察者模式 3個子線程分別控制3個骰子,都已經結束時,通知觀察者窗體,窗體觀察到所有子線程都結束時,計算游戲結果 13      *  14      */ 15  16     PRivate static final long serialVersionUID = 1L; 17     private JTextField txtPut; 18     private JButton btnStart; 19     private JLabel labResult; 20     private JComboBox<String> comboBox; 21     private JLabel labBigOrSmall; 22     private JLabel labPut; 23     private JLabel labSumMoney; 24     private JLabel labDice3; 25     private JLabel labDice2; 26     private JLabel labDice1; 27     private JLabel labSum; 28     private JLabel labMes; 29  30     private static List<Icon> imgs = new ArrayList<Icon>(); 31  32     public static void main(String[] args) { 33         new DiceFrame(); 34     } 35  36     public DiceFrame() { 37         this.setLocationRelativeTo(null); 38         this.setBounds(200, 50, 380, 297); 39         this.setDefaultCloSEOperation(JFrame.DISPOSE_ON_CLOSE); 40         getContentPane().setLayout(null); 41         this.setResizable(false); 42  43         labDice1 = new JLabel(""); 44         labDice1.setIcon(new ImageIcon("img/dices.jpg")); 45         labDice1.setBounds(30, 50, 96, 96); 46         getContentPane().add(labDice1); 47  48         labSum = new JLabel("/u5269/u4F59/u91D1/u989D/uFF1A"); 49         labSum.setBounds(10, 10, 69, 23); 50         getContentPane().add(labSum); 51  52         labDice2 = new JLabel(""); 53         labDice2.setIcon(new ImageIcon("img/dices.jpg")); 54         labDice2.setBounds(136, 50, 96, 96); 55         getContentPane().add(labDice2); 56  57         labDice3 = new JLabel(""); 58         labDice3.setIcon(new ImageIcon("img/dices.jpg")); 59         labDice3.setBounds(242, 50, 96, 96); 60         getContentPane().add(labDice3); 61  62         labSumMoney = new JLabel("3000"); 63         labSumMoney.setForeground(Color.red); 64         labSumMoney.setBounds(86, 10, 63, 23); 65         getContentPane().add(labSumMoney); 66  67         labPut = new JLabel("/u672C/u6B21/u4E0B/u6CE8/uFF1A"); 68         labPut.setToolT); 69         labPut.setBounds(10, 199, 69, 23); 70         getContentPane().add(labPut); 71  72         txtPut = new JTextField(); 73         txtPut.setBounds(80, 200, 69, 21); 74         getContentPane().add(txtPut); 75         txtPut.setColumns(10); 76  77         labBigOrSmall = new JLabel("/u62BC/uFF1A"); 78         labBigOrSmall.setBounds(45, 232, 34, 27); 79         getContentPane().add(labBigOrSmall); 80  81         comboBox = new JComboBox<String>(); 82         comboBox.setBounds(80, 234, 69, 23); 83         getContentPane().add(comboBox); 84         comboBox.addItem("大"); 85         comboBox.addItem("小"); 86  87         labResult = new JLabel(""); 88         labResult.setBounds(136, 156, 126, 27); 89         getContentPane().add(labResult); 90  91         btnStart = new JButton("START"); 92         btnStart.setBounds(263, 199, 88, 58); 93         getContentPane().add(btnStart); 94  95         labMes = new JLabel("<html><font size=5 color=red>*</font></html>"); 96         labMes.setBounds(152, 203, 101, 15); 97         getContentPane().add(labMes); 98  99         this.setVisible(true);100 101         imgs.add(new ImageIcon("img/1.png"));102         imgs.add(new ImageIcon("img/2.png"));103         imgs.add(new ImageIcon("img/3.png"));104         imgs.add(new ImageIcon("img/4.png"));105         imgs.add(new ImageIcon("img/5.png"));106         imgs.add(new ImageIcon("img/6.png"));107 108         btnStart.addActionListener(this);109     }110 111     @Override112     public void actionPerformed(ActionEvent e) {113         if (e.getSource() == btnStart) {114 115             // 清除上次游戲的結果116             labResult.setText("");117 118             // 獲取當前下注金額,用戶余額,用戶押大還是押小119             String txt = txtPut.getText().trim();120             String remain = labSumMoney.getText().trim();121 122             // 余額不足,不能開始游戲,提示用戶充值123             if (Integer.parseInt(remain) <= 0) {124                 JOptionPane.showMessageDialog(null, "當前余額不足,請充值!");125                 return;126             }127 128             // 下注金額合法性檢查129             if (txt.length() == 0) {130                 // 提示用戶輸入131                 labMes.setText("*請輸入下注金額");132                 labMes.setForeground(Color.RED);133                 return;134             }135             // 檢查用戶下注金額是否在有效范圍內136             if (Integer.parseInt(txt) <= 0137                     || Integer.parseInt(txt) > Integer.parseInt(remain)) {138                 txtPut.setText("");139                 labMes.setText("下注金額應在0~" + remain + "之間");140                 return;141             }142 143             // 游戲開始后相關項不可更改144             txtPut.setEnabled(false);145             labMes.setText("");146             comboBox.setEnabled(false);147 148             //在主線程上開t1,t2,t3 3個子線程149             Thread t1 = new Thread() {150                 @Override151                 public void run() {152                     //每個子線程上再開子子線程,控制圖標變換153                     IconThread t11 = new IconThread(labDice1, imgs);154                     //給t11添加觀察者,即當前窗體155                     t11.addObserver(DiceFrame.this);156                     new Thread(t11).start();157                 }158             };159 160             Thread t2 = new Thread() {161                 @Override162                 public void run() {163                     IconThread t21 = new IconThread(labDice2, imgs);164                     t21.addObserver(DiceFrame.this);165                     new Thread(t21).start();166                 }167             };168 169             Thread t3 = new Thread() {170                 @Override171                 public void run() {172                     IconThread t31 = new IconThread(labDice3, imgs);173                     t31.addObserver(DiceFrame.this);174                     new Thread(t31).start();175                 }176             };177 178             t1.start();179             t2.start();180             t3.start();181         }182 183     }184 185     /**186      * 獲取骰子點數和187      * 188      * @param lab189      * @return sum190      */191     private int result(JLabel lab) {192         // 獲取當前骰子圖片193         Icon icon = lab.getIcon();194         int sum = 0;195         for (int i = 0; i < imgs.size(); i++) {196             if (icon.equals(imgs.get(i))) {197                 sum += (i + 1);198                 break;199             }200         }201         return sum;202     }203 204     // 構建所有被觀察者的集合205     Vector<Observable> allObservables = new Vector<Observable>();206 207     @Override208     public void update(Observable o, Object arg) {209         System.out.println(o + ".................");210         // 如果集合中不包含當前被觀察者,將此被觀察者加入集合211         if (allObservables.contains(o) == false) {212             allObservables.add(o);213         }214 215         // 如果集合中被觀察者個數為3,說明3個骰子線程已經全部結束216         if (allObservables.size() == 3) {217             // 獲取當前下注金額,用戶余額,用戶押大還是押小218             String txt = txtPut.getText().trim();219             String remain = labSumMoney.getText().trim();220             String bigOrSmall = comboBox.getSelectedItem().toString();221             // 獲取每個骰子點數222             int sum1 = result(labDice1);223             int sum2 = result(labDice2);224             int sum3 = result(labDice3);225             System.out.println(sum1 + "-" + sum2 + "-" + sum3);226             int sum = sum1 + sum2 + sum3;227             System.out.println(sum);228 229             if (sum > 9 && "大".equals(bigOrSmall) || sum <= 9230                     && "小".equals(bigOrSmall)) {231 232                 // 獎勵玩家相應金額233                 remain = String.valueOf(Integer.parseInt(remain)234                         + Integer.parseInt(txt));235                 labSumMoney.setText(remain);236 237                 // 顯示游戲結果238                 labResult.setText("WIN");239                 labResult.setForeground(Color.GREEN);240                 labResult.setFont(new Font("宋體", Font.BOLD, 40));241 242             } else {243                 // 扣除玩家相應金額244                 remain = String.valueOf(Integer.parseInt(remain)245                         - Integer.parseInt(txt));246                 labSumMoney.setText(remain);247 248                 labResult.setText("FAIL");249                 labResult.setForeground(Color.red);250                 labResult.setFont(new Font("宋體", Font.BOLD, 40));251 252             }253             txtPut.setEnabled(true);254             comboBox.setEnabled(true);255             // 本次游戲結束后移除集合中所有線程256             allObservables.removeAll(allObservables);257         }258     }259 260 }

2.線程

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 秭归县| 武宣县| 邯郸市| 通化县| 连江县| 穆棱市| 彩票| 铁力市| 墨玉县| 大理市| 海淀区| 盐池县| 嘉义县| 彩票| 延庆县| 桃源县| 大悟县| 永丰县| 赣榆县| 同心县| 蕲春县| 渭源县| 威海市| 达尔| 罗源县| 新昌县| 那坡县| 咸阳市| 钟山县| 望奎县| 元氏县| 乌鲁木齐县| 都昌县| 韶山市| 江北区| 大英县| 交口县| 汝阳县| 平昌县| 潼关县| 康马县|