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

首頁 > 編程 > Java > 正文

Java編寫擲骰子游戲

2019-11-26 14:48:39
字體:
來源:轉載
供稿:網友

廢話不多說了,直接奔主題。

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

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

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

 //個線程控制顆骰子 Thread t = new Thread(); Thread t = new Thread(); Thread t = new Thread(); //啟動個線程 t.start(); t.start(); t.start(); //將個線程加入主線程 t.join(); t.join(); t.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.窗體

 package com.sxt.dice; import java.awt.Color; public class DiceFrame extends JFrame implements ActionListener, Observer {  /**  * 《擲骰子》控制臺小游戲,在該游戲中,玩家初始擁有的金錢,每次輸入押大還是押小,  * 以及下注金額,隨機個骰子的點數,如果個骰子的總點數小于等于,則開小,否則開大,  * 然后判斷玩家是否押對,如果未押對則扣除下注金額,如果押對則獎勵和玩家下注金額相同的金錢。  *   * 運用觀察者模式 個子線程分別控制個骰子,都已經結束時,通知觀察者窗體,窗體觀察到所有子線程都結束時,計算游戲結果  *   */  private static final long serialVersionUID = L;  private JTextField txtPut;  private JButton btnStart;  private JLabel labResult;  private JComboBox<String> comboBox;  private JLabel labBigOrSmall;  private JLabel labPut;  private JLabel labSumMoney;  private JLabel labDice;  private JLabel labDice;  private JLabel labDice;  private JLabel labSum;  private JLabel labMes;  private static List<Icon> imgs = new ArrayList<Icon>();  public static void main(String[] args) {   new DiceFrame();  }  public DiceFrame() {   this.setLocationRelativeTo(null);   this.setBounds(, , , );   this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);   getContentPane().setLayout(null);   this.setResizable(false);   labDice = new JLabel("");   labDice.setIcon(new ImageIcon("img/dices.jpg"));   labDice.setBounds(, , , );   getContentPane().add(labDice);   labSum = new JLabel("/u/uF/uD/uD/uFFA");   labSum.setBounds(, , , );   getContentPane().add(labSum);   labDice = new JLabel("");   labDice.setIcon(new ImageIcon("img/dices.jpg"));   labDice.setBounds(, , , );   getContentPane().add(labDice);   labDice = new JLabel("");   labDice.setIcon(new ImageIcon("img/dices.jpg"));   labDice.setBounds(, , , );   getContentPane().add(labDice);   labSumMoney = new JLabel("");   labSumMoney.setForeground(Color.red);   labSumMoney.setBounds(, , , );   getContentPane().add(labSumMoney);   labPut = new JLabel("/uC/uB/uEB/uCE/uFFA");   labPut.setToolTipText(".");   labPut.setBounds(, , , );   getContentPane().add(labPut);   txtPut = new JTextField();   txtPut.setBounds(, , , );   getContentPane().add(txtPut);   txtPut.setColumns();   labBigOrSmall = new JLabel("/uBC/uFFA");   labBigOrSmall.setBounds(, , , );   getContentPane().add(labBigOrSmall);   comboBox = new JComboBox<String>();   comboBox.setBounds(, , , );   getContentPane().add(comboBox);   comboBox.addItem("大");   comboBox.addItem("小");   labResult = new JLabel("");   labResult.setBounds(, , , );   getContentPane().add(labResult);   btnStart = new JButton("START");   btnStart.setBounds(, , , );   getContentPane().add(btnStart);   labMes = new JLabel("<html><font size= color=red>*</font></html>");   labMes.setBounds(, , , );   getContentPane().add(labMes);   this.setVisible(true);   imgs.add(new ImageIcon("img/.png"));   imgs.add(new ImageIcon("img/.png"));   imgs.add(new ImageIcon("img/.png"));   imgs.add(new ImageIcon("img/.png"));   imgs.add(new ImageIcon("img/.png"));   imgs.add(new ImageIcon("img/.png"));   btnStart.addActionListener(this);  }  @Override  public void actionPerformed(ActionEvent e) {   if (e.getSource() == btnStart) {    // 清除上次游戲的結果    labResult.setText("");    // 獲取當前下注金額,用戶余額,用戶押大還是押小    String txt = txtPut.getText().trim();    String remain = labSumMoney.getText().trim();    // 余額不足,不能開始游戲,提示用戶充值    if (Integer.parseInt(remain) <= ) {     JOptionPane.showMessageDialog(null, "當前余額不足,請充值!");     return;    }    // 下注金額合法性檢查    if (txt.length() == ) {     // 提示用戶輸入     labMes.setText("*請輸入下注金額");     labMes.setForeground(Color.RED);     return;    }    // 檢查用戶下注金額是否在有效范圍內    if (Integer.parseInt(txt) <=       || Integer.parseInt(txt) > Integer.parseInt(remain)) {     txtPut.setText("");     labMes.setText("下注金額應在~" + remain + "之間");     return;    }    // 游戲開始后相關項不可更改    txtPut.setEnabled(false);    labMes.setText("");    comboBox.setEnabled(false);    //在主線程上開t,t,t 個子線程    Thread t = new Thread() {     @Override     public void run() {      //每個子線程上再開子子線程,控制圖標變換      IconThread t = new IconThread(labDice, imgs);      //給t添加觀察者,即當前窗體      t.addObserver(DiceFrame.this);      new Thread(t).start();     }    };    Thread t = new Thread() {     @Override     public void run() {      IconThread t = new IconThread(labDice, imgs);      t.addObserver(DiceFrame.this);      new Thread(t).start();     }    };    Thread t = new Thread() {     @Override     public void run() {      IconThread t = new IconThread(labDice, imgs);      t.addObserver(DiceFrame.this);      new Thread(t).start();     }    };    t.start();    t.start();    t.start();   }  }  /**  * 獲取骰子點數和  *   * @param lab  * @return sum  */  private int result(JLabel lab) {   // 獲取當前骰子圖片   Icon icon = lab.getIcon();   int sum = ;   for (int i = ; i < imgs.size(); i++) {    if (icon.equals(imgs.get(i))) {     sum += (i + );     break;    }   }   return sum;  }  // 構建所有被觀察者的集合  Vector<Observable> allObservables = new Vector<Observable>();  @Override  public void update(Observable o, Object arg) {   System.out.println(o + ".................");   // 如果集合中不包含當前被觀察者,將此被觀察者加入集合   if (allObservables.contains(o) == false) {    allObservables.add(o);   }   // 如果集合中被觀察者個數為,說明個骰子線程已經全部結束   if (allObservables.size() == ) {    // 獲取當前下注金額,用戶余額,用戶押大還是押小    String txt = txtPut.getText().trim();    String remain = labSumMoney.getText().trim();    String bigOrSmall = comboBox.getSelectedItem().toString();    // 獲取每個骰子點數    int sum = result(labDice);    int sum = result(labDice);    int sum = result(labDice);    System.out.println(sum + "-" + sum + "-" + sum);    int sum = sum + sum + sum;    System.out.println(sum);    if (sum > && "大".equals(bigOrSmall) || sum <=       && "小".equals(bigOrSmall)) {     // 獎勵玩家相應金額     remain = String.valueOf(Integer.parseInt(remain)       + Integer.parseInt(txt));     labSumMoney.setText(remain);     // 顯示游戲結果     labResult.setText("WIN");     labResult.setForeground(Color.GREEN);     labResult.setFont(new Font("宋體", Font.BOLD, ));    } else {     // 扣除玩家相應金額     remain = String.valueOf(Integer.parseInt(remain)       - Integer.parseInt(txt));     labSumMoney.setText(remain);     labResult.setText("FAIL");     labResult.setForeground(Color.red);     labResult.setFont(new Font("宋體", Font.BOLD, ));    }    txtPut.setEnabled(true);    comboBox.setEnabled(true);    // 本次游戲結束后移除集合中所有線程    allObservables.removeAll(allObservables);   }  } }

2.線程

 package com.sxt.dice; import java.util.List; import java.util.Observable; import java.util.Random; import javax.swing.Icon; import javax.swing.JLabel; public class IconThread extends Observable implements Runnable {  /**  * 運用觀察者模式,將子線程作為被觀察對象,一旦子線程運行完,發生改變,通知觀察者  */  JLabel lab;  Random random = new Random();  List<Icon> imgs;  public IconThread(JLabel lab, List<Icon> imgs) {   this.lab = lab;   this.imgs = imgs;  }  @Override  public void run() {   //設置每顆骰子轉動次   int count = ;   while (count > ) {    //獲取一個隨機數[~)    int index = random.nextInt();    //從imgs集合中取相應圖片放入lab中    lab.setIcon(imgs.get(index));    count--;    try {     Thread.sleep();    } catch (InterruptedException e) {     // TODO Auto-generated catch block     e.printStackTrace();    }   }   this.setChanged();// 子線程運行完,發生改變   this.notifyObservers();// 通知觀察者  } }

以上所述就是關于Java編寫擲骰子游戲的全部內容,希望大家喜歡。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 牡丹江市| 新龙县| 尉犁县| 津南区| 临沭县| 思南县| 积石山| 科技| 安丘市| 乌鲁木齐县| 汶川县| 临汾市| 富顺县| 湟中县| 深泽县| 兴和县| 凤城市| 扎兰屯市| 城市| 营山县| 华安县| 定结县| 枝江市| 保定市| 北海市| 静乐县| 资溪县| 麻栗坡县| 嘉峪关市| 黄平县| 曲麻莱县| 鸡东县| 英山县| 个旧市| 乌兰县| 永新县| 陇南市| 湖南省| 上林县| 革吉县| 扎囊县|