Java實(shí)現(xiàn)經(jīng)典大富翁游戲的示例詳解
前言
大富翁,又名地產(chǎn)大亨。是一種多人策略圖版游戲。參與者分得游戲金錢,憑運(yùn)氣(擲骰子)及交易策略,買地、建樓以賺取租金。英文原名monopoly意為“壟斷”,因?yàn)樽詈笾坏靡粋€(gè)勝利者,其余均破產(chǎn)收?qǐng)觥?/p>
《大富翁》游戲是用java語(yǔ)言實(shí)現(xiàn),采用了swing技術(shù)進(jìn)行了界面化處理,設(shè)計(jì)思路用了面向?qū)ο笏枷搿?/p>
主要需求
可多人參與的大富翁游戲,玩家有初始資金,通過(guò)擲骰子,玩家移動(dòng)指定骰子點(diǎn)數(shù)步驟,根據(jù)對(duì)應(yīng)格子上的交易策略,來(lái)決定是賺錢還是虧錢,其他玩家破產(chǎn),即唯一玩家勝利。
主要設(shè)計(jì)
1、用戶數(shù)據(jù)設(shè)定-人物設(shè)置:設(shè)置兩個(gè)玩家的角色頭像和用戶名
2、用戶數(shù)據(jù)設(shè)定-場(chǎng)景設(shè)置:選擇不同的地圖
3、用戶數(shù)據(jù)設(shè)定-游戲設(shè)置:游戲天數(shù),勝利金錢,玩家初始金錢
4、設(shè)置默認(rèn)勝利條件:破產(chǎn)為失敗
5、擲骰子效果
6、角色移動(dòng)的步數(shù)效果
7、不同地圖的策略設(shè)計(jì)算法:不同的格子,效果不同
功能截圖
用戶數(shù)據(jù)設(shè)定頁(yè)面-人物設(shè)置

用戶數(shù)據(jù)設(shè)定頁(yè)面-場(chǎng)景設(shè)置

用戶數(shù)據(jù)設(shè)定頁(yè)面-游戲設(shè)置

開(kāi)始游戲界面

擲骰子

移動(dòng)效果

觸發(fā)策略效果


金幣不足時(shí)提示

游戲結(jié)束

代碼實(shí)現(xiàn)
游戲配置窗口
/**
*
* 讀取用戶配置
*
* */
public class FrameConfig extends JFrame {
private JButton jbnStart = new JButton("開(kāi)始游戲");
//private JButton jbnradom = new JButton("隨機(jī)");
private JButton jbnCancel = new JButton("重置設(shè)定");
private JButton jbnPlayer01 = new JButton("1P確認(rèn)角色");
private JLabel jbnPlayerNameLabel01 = new JLabel("名字:");
private JTextField jbnPlayerNameField01 = new JTextField(12);
private JButton jbnPlayerName01 = new JButton("1P確認(rèn)名字");
private JButton jbnPlayer02 = new JButton("2P確認(rèn)角色");
private JLabel jbnPlayerNameLabel02 = new JLabel("名字:");
private JTextField jbnPlayerNameField02 = new JTextField(12);
private JButton jbnPlayerName02 = new JButton("2P確認(rèn)名字");
/**
* 選項(xiàng)卡
* */
private JTabbedPane tabs;
/**
* 可選圖片
* */
private ImageIcon[] img = Photo.PLAYER_CHOOSE;
/**
* 人物1
**/
private JLabel jlPlayer01Choose = null;
private final JLabel jlPlayer01Selected = new JLabel(
Photo.PLAYER_01_SELECTED);
private JButton leftButton01;
private JButton rightButton01;
/**
* 人物2
**/
private JLabel jlPlayer02Choose = null;
private final JLabel jlPlayer02Selected = new JLabel(
Photo.PLAYER_02_SELECTED);
private JButton leftButton02;
private JButton rightButton02;
/**
* 1P 2P可選人物
*/
private int[] chooses = { 0, 0 };
/**
* 1P 2P已選人物
*/
private int[] selected = { -1, -2 };
/**
* 1P 2P已填名字
*/
private String[] selectedName = { "", "" };
/**
*
* 主面板
*
* */
private JFrameGame jFrameGame;
public FrameConfig(WaitFrame wFrame,JFrameGame jFrameGame) {
wFrame.setVisible(false);
this.jFrameGame = jFrameGame;
setTitle("用戶數(shù)據(jù)設(shè)定");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 設(shè)置布局管理器為邊界布局
this.setLayout(new BorderLayout());
// 添加主面板
this.add(this.createMainPanel(), BorderLayout.CENTER);
// 添加按鈕面板
this.add(this.createButtonPanel(), BorderLayout.SOUTH);
this.setResizable(false);
this.setSize(380, 370);
// 居中對(duì)齊
FrameUtil.setFrameCenter(this);
setVisible(true);
}
/**
* 添加主面板
*/
private JTabbedPane createMainPanel() {
this.tabs = new JTabbedPane();
this.tabs.setOpaque(false);
this.tabs.add("人物設(shè)置", this.createPlayerSelectPanel());
this.tabs.setToolTipTextAt(0, "完成人物設(shè)置");
this.tabs.add("場(chǎng)景設(shè)置", this.createMapSelectPanel());
this.tabs.setToolTipTextAt(1, "可以設(shè)置游戲場(chǎng)景");
this.tabs.add("游戲設(shè)置", this.createGameSelectPanel());
this.tabs.setToolTipTextAt(2, "可以設(shè)置游戲勝利條件等...");
return tabs;
}
/**
*
* 游戲勝利條件設(shè)置
*
*/
private Component createGameSelectPanel() {
JPanel panel = new JPanel(new GridLayout(0, 1));
panel.setBackground(new Color(235,236,237));
// --------------------------------
final JPanel dayPanel = new JPanel();
dayPanel.setBorder(BorderFactory.createTitledBorder(""));
JLabel day = new JLabel("游戲天數(shù)");
final String[] days = { "無(wú)限制", "20", "40", "80", "120", "240", "480" };
final Choice daysChoice = new Choice();
for (String a : days) {
daysChoice.add(a);
}
daysChoice.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent arg0) {
String str = days[daysChoice.getSelectedIndex()];
if (str.equals("無(wú)限制")) {
GameRunning.GAME_DAY = -1;
} else {
GameRunning.GAME_DAY = Integer.parseInt(str);
}
}
});
dayPanel.add(day);
dayPanel.add(daysChoice);
// --------------------------------
JPanel moneyPanel = new JPanel();
moneyPanel.setBorder(BorderFactory.createTitledBorder(""));
JLabel money = new JLabel("勝利金錢");
final String[] money_ = { "無(wú)限制", "10000", "20000", "40000", "80000",
"200000" };
final Choice moneyChoice = new Choice();
for (String a : money_) {
moneyChoice.add(a);
}
moneyChoice.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent arg0) {
String str = money_[moneyChoice.getSelectedIndex()];
if (str.equals("無(wú)限制")) {
GameRunning.MONEY_MAX = -1;
} else {
GameRunning.MONEY_MAX = Integer.parseInt(str);
}
}
});
moneyPanel.add(money);
moneyPanel.add(moneyChoice);
// ---------------------------------
// --------------------------------
JPanel cashPanel = new JPanel();
cashPanel.setBorder(BorderFactory.createTitledBorder(""));
JLabel cash = new JLabel("玩家初始金錢");
final String[] cash_ = { "1000", "2000", "5000", "7000", "10000",
"20000" };
final Choice cashChoice = new Choice();
for (String a : cash_) {
cashChoice.add(a);
}
cashChoice.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent arg0) {
String str = cash_[cashChoice.getSelectedIndex()];
GameRunning.PLAYER_CASH = Integer.parseInt(str);
// System.out.println(GameRunning.PLAYER_CASH);
}
});
cashPanel.add(cash);
cashPanel.add(cashChoice);
JPanel infoPanel = new JPanel();
infoPanel.setBorder(BorderFactory.createTitledBorder(""));
JLabel info = new JLabel();
info.setText("<html>可以改變游戲的勝利條件.<strong>(默認(rèn)破產(chǎn)為失敗)</strong></html>");
infoPanel.add(info);
panel.add(dayPanel);
panel.add(moneyPanel);
panel.add(cashPanel);
panel.add(infoPanel);
return panel;
}
/**
*
* 地圖選擇面板
*
*/
private JPanel createMapSelectPanel() {
JPanel jp = new JPanel();
jp.setLayout(new GridLayout());
jp.setBackground(new Color(235,236,237));
JPanel lPane = new JPanel(new BorderLayout());
String[] maps = { "\"LOVE地圖\"", "\"鬼屋地圖\"", "\"好運(yùn)地圖\"" };
final ImageIcon[] maps1 = {
new ImageIcon("images/other/1.png"),
new ImageIcon("images/other/2.png"),
new ImageIcon("images/other/3.png") };
final JList jlst = new JList(maps);
jlst.setSelectedIndex(0);
final JLabel mapV = new JLabel(maps1[0]);
final JButton ok = new JButton("確定");
ok.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
GameRunning.MAP = jlst.getSelectedIndex() + 1;
ok.setText("已選");
}
});
jlst.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
mapV.setIcon(maps1[jlst.getSelectedIndex()]);
ok.setText("確定");
}
});
lPane.add(jlst);
lPane.add(ok, BorderLayout.SOUTH);
JPanel rPane = new JPanel();
rPane.add(mapV);
JSplitPane jSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
false, lPane, rPane);
jp.add(jSplitPane);
return jp;
}
/**
* 人物選擇面板
* */
private JPanel createPlayerSelectPanel() {
JPanel jp = new JPanel();
jp.setLayout(null);
jp.setBackground(new Color(235,236,237));
// 增加1P面板
addPlayer01Config(12, 0, jp);
// 增加2P面板
addPlayer02Config(212, 0, jp);
// 增加重置按鈕
addCancelButton(jp);
return jp;
}
private void addCancelButton(JPanel panel) {
jbnCancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
reLoad();
}
/**
* 重新加載 人物選擇選項(xiàng)卡
*/
private void reLoad() {
leftButton01.setEnabled(true);
rightButton01.setEnabled(true);
jbnPlayer01.setEnabled(true);
jlPlayer01Selected.setVisible(false);
jlPlayer01Choose.setIcon(img[0]);
jbnPlayerNameField01.setText("");
jbnPlayerNameField01.setEditable(true);
jbnPlayerName01.setEnabled(true);
selected[0] = -1;
chooses[0] = 0;
leftButton02.setEnabled(true);
rightButton02.setEnabled(true);
jbnPlayer02.setEnabled(true);
jlPlayer02Selected.setVisible(false);
jlPlayer02Choose.setIcon(img[0]);
jbnPlayerNameField02.setText("");
jbnPlayerNameField02.setEditable(true);
jbnPlayerName02.setEnabled(true);
selected[1] = -2;
chooses[1] = 0;
repaint();
}
});
jbnCancel.setBounds(256 + 7, 235, 80, 30);
panel.add(jbnCancel);
}
/**
* 增加1P面板
*/
private void addPlayer01Config(int x, int y, JPanel jp) {
// 創(chuàng)建 人物圖像label
jlPlayer01Choose = new JLabel(img[chooses[0]]);
jlPlayer01Choose.setBounds(x + 8, y, 128, 128);
// 創(chuàng)建人物圖像已選擇label
jlPlayer01Selected.setBounds(x + 8, y, 128, 128);
jlPlayer01Selected.setVisible(false);
// 創(chuàng)建左按鈕
leftButton01 = this.createButton(x, 92 + y, Photo.BUTTON_LEFT, 'a');
// 添加監(jiān)聽(tīng)事件
leftButton01.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 設(shè)置為循環(huán)
if (chooses[0] <= 0) {
chooses[0] = img.length;
}
jlPlayer01Choose.setIcon(img[--chooses[0]]);
}
});
jp.add(leftButton01);
// 創(chuàng)建右按鈕
rightButton01 = this.createButton(128 + x, 92 + y, Photo.BUTTON_RIGHT,
'd');
// 添加監(jiān)聽(tīng)事件
rightButton01.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// 設(shè)置循環(huán)
if (chooses[0] >= img.length - 1) {
chooses[0] = -1;
}
jlPlayer01Choose.setIcon(img[++chooses[0]]);
}
});
jp.add(rightButton01);
// 增加確定框
jbnPlayer01.setBounds(12 + x, 128 + y, 120, 30);
// 增加事件監(jiān)聽(tīng)
jbnPlayer01.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
if ((chooses[0] != selected[1])) {
// 設(shè)置不能點(diǎn)擊
leftButton01.setEnabled(false);
rightButton01.setEnabled(false);
jbnPlayer01.setEnabled(false);
// 增加選擇圖片
jlPlayer01Selected.setVisible(true);
selected[0] = chooses[0];
}
}
});
jp.add(jbnPlayer01);
jp.add(jlPlayer01Selected);
jp.add(jlPlayer01Choose);
// 增加名字框
jbnPlayerNameLabel01.setBounds(x + 12, y + 128 + 36, 50, 30);
jbnPlayerNameField01.setBounds(x + 12 + 30, y + 128 + 36, 120 - 30, 30);
jbnPlayerName01.setBounds(x + 12, y + 128 + 36 + 36, 120, 30);
// 按鈕添加監(jiān)聽(tīng)
jbnPlayerName01.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!jbnPlayerNameField01.getText().equals("")) {
selectedName[0] = jbnPlayerNameField01.getText();
jbnPlayerNameField01.setEditable(false);
jbnPlayerName01.setEnabled(false);
}
}
});
jp.add(jbnPlayerNameLabel01);
jp.add(jbnPlayerNameField01);
jp.add(jbnPlayerName01);
}
/**
* 增加2P面板
*/
private void addPlayer02Config(int x, int y, JPanel jp) {
// 創(chuàng)建 人物圖像label
jlPlayer02Choose = new JLabel(img[chooses[1]]);
jlPlayer02Choose.setBounds(x + 8, y, 128, 128);
// 創(chuàng)建人物圖像已選擇label
jlPlayer02Selected.setBounds(x + 8, y, 128, 128);
jlPlayer02Selected.setVisible(false);
// 創(chuàng)建左按鈕
leftButton02 = this.createButton(x, 92 + y, Photo.BUTTON_LEFT, 'a');
// 添加監(jiān)聽(tīng)事件
leftButton02.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 設(shè)置為循環(huán)
if (chooses[1] <= 0) {
chooses[1] = img.length;
}
jlPlayer02Choose.setIcon(img[--chooses[1]]);
}
});
jp.add(leftButton02);
// 創(chuàng)建右按鈕
rightButton02 = this.createButton(128 + x, 92 + y, Photo.BUTTON_RIGHT,
'd');
// 添加監(jiān)聽(tīng)事件
rightButton02.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// 設(shè)置循環(huán)
if (chooses[1] >= img.length - 1) {
chooses[1] = -1;
}
jlPlayer02Choose.setIcon(img[++chooses[1]]);
}
});
jp.add(rightButton02);
// 增加確定框
jbnPlayer02.setBounds(12 + x, 128 + y, 120, 30);
// 增加事件監(jiān)聽(tīng)
jbnPlayer02.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
if (selected[0] != chooses[1]) {
// 設(shè)置不能點(diǎn)擊
leftButton02.setEnabled(false);
rightButton02.setEnabled(false);
jbnPlayer02.setEnabled(false);
// 增加選擇圖片
jlPlayer02Selected.setVisible(true);
selected[1] = chooses[1];
}
}
});
jp.add(jbnPlayer02);
jp.add(jlPlayer02Selected);
jp.add(jlPlayer02Choose);
// 增加名字框
jbnPlayerNameLabel02.setBounds(x + 12, y + 128 + 36, 50, 30);
jbnPlayerNameField02.setBounds(x + 12 + 30, y + 128 + 36, 120 - 30, 30);
jbnPlayerName02.setBounds(x + 12, y + 128 + 36 + 36, 120, 30);
// 按鈕添加監(jiān)聽(tīng)
jbnPlayerName02.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!jbnPlayerNameField02.getText().equals("")) {
selectedName[1] = jbnPlayerNameField02.getText();
jbnPlayerNameField02.setEditable(false);
jbnPlayerName02.setEnabled(false);
}
}
});
jp.add(jbnPlayerNameLabel02);
jp.add(jbnPlayerNameField02);
jp.add(jbnPlayerName02);
}
/**
*
* 圖標(biāo)按鈕
*
* */
public JButton createButton(int x, int y, ImageIcon[] img, char keyLinstenr) {
JButton add = new JButton("", img[0]);
add.setPressedIcon(img[3]);
add.setRolloverIcon(img[2]);
add.setMnemonic(keyLinstenr);
add.setBounds(x, y, img[0].getIconWidth(), img[0].getIconHeight());
return add;
}
/**
* 添加按鈕面板
*/
private JPanel createButtonPanel() {
JPanel jp = new JPanel(new FlowLayout(FlowLayout.RIGHT));
// 開(kāi)始按鈕添加監(jiān)聽(tīng)器
jbnStart.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (selected[0] < 0 || selected[1] < 0) {
JOptionPane.showMessageDialog(null, "請(qǐng)完成人物設(shè)置!");
} else if (selectedName[0].equals("")
|| selectedName[1].equals("")) {
JOptionPane.showMessageDialog(null, "請(qǐng)完成名字設(shè)置!");
} else {
int choose = JOptionPane.showConfirmDialog(null, "是否開(kāi)始?");
if (choose == JOptionPane.OK_OPTION) {
// 開(kāi)始游戲
startGame();
}
}
}
/**
* 開(kāi)始游戲
* */
private void startGame() {
setVisible(false);
jFrameGame.setVisible(true);
Control control = jFrameGame.getPanelGame().getControl();
// 處理玩家數(shù)據(jù)配置
dealPlayers(control);
// 控制器啟動(dòng)
control.start();
}
/**
* 處理玩家數(shù)據(jù)配置
*/
private void dealPlayers(Control control) {
List<PlayerModel> tempPlayer = control.getPlayers();
// 傳入名字
tempPlayer.get(0).setName(selectedName[0]);
tempPlayer.get(1).setName(selectedName[1]);
// 傳入使用角色編號(hào)
tempPlayer.get(0).setPart(selected[0]);
tempPlayer.get(1).setPart(selected[1]);
// 傳入 角色對(duì)立角色
tempPlayer.get(0).setOtherPlayer(tempPlayer.get(1));
tempPlayer.get(1).setOtherPlayer(tempPlayer.get(0));
}
});
jp.add(jbnStart);
//jp.add(jbnradom);
return jp;
}
}游戲總控制器
/**
*
* 游戲總控制器
*
*
* @author Administrator
*
*/
public class Control {
/**
*
* 游戲tick值
*
*/
public static long tick;
/**
*
* 每秒畫面刷新頻率
*
*/
public static int rate = 30;
/**
*
* 游戲主面板
*
*/
private JPanelGame panel;
/**
*
* 游戲?qū)ο?
*
*/
private GameRunning run = null;
private List<Port> models = new ArrayList<Port>();
private List<PlayerModel> players = null;
private BuildingsModel building = null;
private BackgroundModel background = null;
private LandModel land = null;
private TextTipModel textTip = null;
private DiceModel dice = null;
private EventsModel events = null;
private EffectModel effect = null;
private Music music = null;
/**
*
* 游戲計(jì)時(shí)器
*
*/
private Timer gameTimer = null;
public Control() {
// 創(chuàng)建一個(gè)游戲狀態(tài)
this.run = new GameRunning(this, players);
// 初始化游戲?qū)ο?
this.initClass();
// 向游戲狀態(tài)中加入玩家模型
this.run.setPlayers(players);
}
public void setPanel(JPanelGame panel) {
this.panel = panel;
}
/**
*
* 初始化游戲?qū)ο?
*
*/
private void initClass() {
// 創(chuàng)建一個(gè)新的事件模型
this.events = new EventsModel();
this.models.add(events);
// 創(chuàng)建一個(gè)新的場(chǎng)景效果模型
this.effect = new EffectModel();
this.models.add(effect);
// 創(chuàng)建新的背景模型
this.background = new BackgroundModel();
this.models.add(background);
// 創(chuàng)建新的土地模型
this.land = new LandModel();
this.models.add(land);
// 創(chuàng)建新的文本顯示模型
this.textTip = new TextTipModel();
this.models.add(textTip);
// 創(chuàng)建一個(gè)新的建筑模型
this.building = new BuildingsModel(land);
this.models.add(building);
// 創(chuàng)建一個(gè)新的玩家數(shù)組
this.players = new ArrayList<PlayerModel>();
this.players.add(new PlayerModel(1, this));
this.players.add(new PlayerModel(2, this));
this.models.add(players.get(0));
this.models.add(players.get(1));
// 創(chuàng)建一個(gè)新的骰子模型
this.dice = new DiceModel(run);
this.models.add(dice);
// 創(chuàng)建一個(gè)播放器
this.music = new Music();
}
/**
*
* 游戲計(jì)時(shí)器
*
*/
private void createGameTimer() {
this.gameTimer = new Timer();
this.gameTimer.schedule(new TimerTask() {
@Override
public void run() {
tick++;
// 更新各對(duì)象
for (Port temp : models) {
temp.updata(tick);
}
// UI更新
panel.repaint();
}
}, 0, (1000 / rate));
}
/**
*
* 控制器啟動(dòng)
*
*/
public void start() {
// 創(chuàng)建一個(gè)計(jì)時(shí)器
this.createGameTimer();
// 刷新對(duì)象初始數(shù)據(jù)
for (Port temp : this.models) {
temp.startGameInit();
}
// 游戲環(huán)境開(kāi)始
this.run.startGameInit();
// panel 初始化
this.panel.startGamePanelInit();
// 游戲背景音樂(lè)
this.startMusic();
// 游戲開(kāi)始產(chǎn)生地圖效果
this.effect.showImg("start");
}
/**
*
* 游戲背景音樂(lè)
*
*/
private void startMusic() {
music.start();
}
public List<PlayerModel> getPlayers() {
return players;
}
public BuildingsModel getBuilding() {
return building;
}
public BackgroundModel getBackground() {
return background;
}
public LandModel getLand() {
return land;
}
public EffectModel getEffect() {
return effect;
}
public TextTipModel getTextTip() {
return textTip;
}
public GameRunning getRunning() {
return run;
}
public DiceModel getDice() {
return dice;
}
public EventsModel getEvents() {
return events;
}
public JPanelGame getPanel() {
return panel;
}
/**
*
*
* 按下骰子
*
*
*/
public void pressButton() {
PlayerModel player = this.run.getNowPlayer();
if (player.getInHospital() > 0 || player.getInPrison() > 0) {
this.run.nextState();
if (player.getInHospital() > 0) {
this.textTip.showTextTip(player, player.getName() + "住院中.", 3);
} else if (player.getInPrison() > 0) {
this.textTip.showTextTip(player, player.getName() + "在監(jiān)獄.", 3);
}
this.run.nextState();
} else {
// 設(shè)置骰子對(duì)象開(kāi)始轉(zhuǎn)動(dòng)時(shí)間
this.dice.setStartTick(Control.tick);
// 設(shè)置骰子對(duì)象結(jié)束轉(zhuǎn)動(dòng)時(shí)間
this.dice.setNextTick(this.dice.getStartTick()
+ this.dice.getLastTime());
// 將運(yùn)行對(duì)象點(diǎn)數(shù)傳入骰子對(duì)象
this.dice.setPoint(this.run.getPoint());
// 轉(zhuǎn)換狀態(tài)至“移動(dòng)狀態(tài)”
this.run.nextState();
// 骰子轉(zhuǎn)動(dòng)完畢后玩家移動(dòng)
this.run.getNowPlayer().setStartTick(this.dice.getNextTick() + 10);
this.run.getNowPlayer().setNextTick(
this.run.getNowPlayer().getStartTick()
+ this.run.getNowPlayer().getLastTime()
* (this.run.getPoint() + 1));
}
}
/**
*
*
* 玩家移動(dòng)
*
*
*/
public void movePlayer() {
// 人物運(yùn)動(dòng)
for (int i = 0; i < (60 / this.run.getNowPlayer().getLastTime()); i++) {
// 移動(dòng)玩家
if (GameRunning.MAP == 1){
this.move01();
} else if (GameRunning.MAP == 2){
this.move02();
} else if (GameRunning.MAP == 3) {
this.move03();
}
}
}
/**
*
* 玩家中途路過(guò)建筑
*
*/
public void prassBuilding() {
// 當(dāng)前玩家
PlayerModel player = this.run.getNowPlayer();
// 該地點(diǎn)房屋
Building building = this.building.getBuilding(player.getY() / 60,
player.getX() / 60);
if (building != null && player.getX() % 60 == 0
&& player.getY() % 60 == 0) {
// 經(jīng)過(guò)房屋發(fā)生事件
int event = building.passEvent();
// 進(jìn)入經(jīng)過(guò)房屋事件處理
disposePassEvent(building, event, player);
}
}
/**
*
* 經(jīng)過(guò)房屋事件處理
*
*/
private void disposePassEvent(Building b, int event, PlayerModel player) {
switch (event) {
case GameState.ORIGIN_PASS_EVENT:
// 中途經(jīng)過(guò)原點(diǎn)
passOrigin(b, player);
break;
default:
break;
}
}
/**
*
* 中途經(jīng)過(guò)原點(diǎn)
*
*/
private void passOrigin(Building b, PlayerModel player) {
this.textTip.showTextTip(player, player.getName() + " 路過(guò)原點(diǎn),獎(jiǎng)勵(lì) "
+ ((Origin) b).getPassReward() + "金幣.", 3);
player.setCash(player.getCash() + ((Origin) b).getPassReward());
}
/**
*
*
* 玩家移動(dòng)的方法
*
*
*/
private void move02() {
int dice = this.run.getPoint() + 1;
PlayerModel p = this.run.getNowPlayer();
// 單位移動(dòng)像素
int movePixel = 1;
if (p.getX() < 12 * 60 && p.getY() == 0) {
p.setX(p.getX() + movePixel);
} else if (p.getX() == 12 *60 && p.getY() < 2 * 60){
p.setY(p.getY() + movePixel);
} else if (p.getX() == 12 * 60 && p.getY() == 2 * 60){
if ((int)(Math.random() * 2 ) == 0){
p.setX(p.getX() - movePixel);
} else {
p.setY(p.getY() + movePixel);
}
} else if (p.getX() == 12 * 60 && p.getY() > 2 * 60 && p.getY() < 4 * 60){
p.setY(p.getY() + movePixel);
} else if (p.getX() > 8 * 60 && p.getX() <= 12 * 60 && p.getY() == 4 * 60){
p.setX(p.getX() - movePixel);
} else if (p.getX() == 8 * 60 && p.getY() == 4 * 60){
if ((int)(Math.random() * 2 ) == 0){
p.setX(p.getX() - movePixel);
} else {
p.setY(p.getY() + movePixel);
}
} else if (p.getX() > 4 * 60 && p.getX() < 8 * 60 && p.getY() == 4 * 60) {
p.setX(p.getX() - movePixel);
} else if (p.getX() == 8 * 60 && p.getY() > 4 * 60 && p.getY() < 7 * 60){
p.setY(p.getY() + movePixel);
} else if (p.getX() > 4 * 60 && p.getX() <= 8 * 60 && p.getY() == 7 * 60){
p.setX(p.getX() - movePixel);
} else if (p.getX() > 4 * 60 && p.getX() < 12 * 60 && p.getY() == 2 * 60){
p.setX(p.getX() - movePixel);
} else if (p.getX() == 4 * 60 && p.getY() >= 2 * 60 && p.getY() < 7 * 60){
p.setY(p.getY() + movePixel);
} else if (p.getX() > 0 && p.getX() <= 4 * 60 && p.getY() == 7 * 60){
p.setX(p.getX() - movePixel);
} else if (p.getX() == 0 && p.getY() > 0){
p.setY(p.getY() - movePixel);
}
}
/**
*
*
* 玩家移動(dòng)的方法
*
*
*/
private void move01() {
int dice = this.run.getPoint() + 1;
PlayerModel p = this.run.getNowPlayer();
// 單位移動(dòng)像素
int movePixel = 1;
Boolean turn = dice % 2 != 0;
if (p.getX() < 9 * 60 && p.getY() == 0) {
// 上面
if (p.getX() == 4 * 60 && turn) {
// 分岔點(diǎn)情況
p.setY(p.getY() + movePixel);
} else {
p.setX(p.getX() + movePixel);
}
} else if (p.getX() == 9 * 60 && p.getY() >= 0 && p.getY() < 60) {
// [0,9]
// ↓
p.setY(p.getY() + movePixel);
} else if (p.getX() >= 8 * 60 && p.getX() < 12 * 60
&& p.getY() >= 1 * 60 && p.getY() <= 60 * 1.5) {
// →
p.setX(p.getX() + movePixel);
} else if (p.getX() == 12 * 60 && p.getY() >= 1 * 60
&& p.getY() < 7 * 60) {
// ↓
p.setY(p.getY() + movePixel);
} else if (p.getX() > 0 && p.getY() == 7 * 60) {
// ←
p.setX(p.getX() - movePixel);
} else if (p.getX() == 0 && p.getY() > 0) {
// ↑
p.setY(p.getY() - movePixel);
} else if (p.getX() == 4 * 60 && p.getY() > 0 && p.getY() < 7 * 60) {
// ↓
p.setY(p.getY() + movePixel);
}
}
/**
*
*
* 玩家移動(dòng)的方法
*
*
*/
private void move03() {
PlayerModel p = this.run.getNowPlayer();
// 單位移動(dòng)像素
int movePixel = 1;
if (p.getX() < 12 * 60 && p.getY() == 0) {
p.setX(p.getX() + movePixel);
} else if (p.getX() == 12 *60 && p.getY() < 7 * 60){
p.setY(p.getY() + movePixel);
} else if (p.getX() > 0 && p.getY() == 7 * 60){
p.setX(p.getX() - movePixel);
} else if (p.getX() == 0 && p.getY() > 0){
p.setY(p.getY() - movePixel);
}
}
/**
*
* 玩家移動(dòng)完畢,停下判斷
*
*/
public void playerStopJudge() {
// 當(dāng)前玩家
PlayerModel player = this.run.getNowPlayer();
if (player.getInHospital() > 0) {
this.textTip.showTextTip(player, player.getName() + "當(dāng)前在醫(yī)院,不能移動(dòng).",
2);
// 更換玩家狀態(tài)
this.run.nextState();
} else if (player.getInPrison() > 0) {
this.textTip.showTextTip(player, player.getName() + "當(dāng)前在監(jiān)獄,不能移動(dòng).",
2);
// 更換玩家狀態(tài)
this.run.nextState();
} else {
// 進(jìn)行玩家操作(買房 事件等)
this.playerStop();
}
}
/**
*
* 玩家移動(dòng)完畢,停下操作
*
*/
public void playerStop() {
// 當(dāng)前玩家
PlayerModel player = this.run.getNowPlayer();
// 該地點(diǎn)房屋
Building building = this.building.getBuilding(player.getY() / 60,
player.getX() / 60);
if (building != null) {// 獲取房屋
int event = building.getEvent();
// 觸發(fā)房屋信息
disposeStopEvent(building, event, player);
}
}
/**
*
* 停留房屋事件處理
*
*
*/
private void disposeStopEvent(Building b, int event, PlayerModel player) {
switch (event) {
case GameState.HOSPITAL_EVENT:
// 停留在醫(yī)院
stopInHospital(b, player);
break;
case GameState.HUOSE_EVENT:
// 停留在可操作土地
stopInHouse(b, player);
break;
case GameState.LOTTERY_EVENT:
// 停留在樂(lè)透點(diǎn)上
stopInLottery(b, player);
break;
case GameState.NEWS_EVENT:
// 停留在新聞點(diǎn)上
stopInNews(b, player);
break;
case GameState.ORIGIN_EVENT:
// 停留在原點(diǎn)
stopInOrigin(b, player);
break;
case GameState.PARK_EVENT:
// 停留在公園
stopInPack(b, player);
break;
case GameState.POINT_EVENT:
// 停留在點(diǎn)卷位
stopInPoint(b, player);
break;
case GameState.PRISON_EVENT:
// 停留在監(jiān)獄
stopInPrison(b, player);
break;
case GameState.SHOP_EVENT:
// 停留在商店
stopInShop(b, player);
break;
}
}
/**
*
* 停留在商店
*
*/
private void stopInShop(Building b, PlayerModel player) {
if (player.getNx() > 0){
// 為商店的貨架從新生成商品
((Shop_) b).createCards();
// 為商店面板更新新的卡片商品
this.panel.getShop().addCards((Shop_) b);
// 將商店面板推送至頂
this.panel.getShop().moveToFront();
} else {
this.run.nextState();
}
}
/**
*
* 停留在監(jiān)獄
*
*/
private void stopInPrison(Building b, PlayerModel player) {
int days = (int) (Math.random() * 3) + 2;
player.setInPrison(days);
int random = (int) (Math.random() * ((Prison) b).getEvents().length);
String text = ((Prison) b).getEvents()[random];
this.textTip.showTextTip(player, player.getName() + text + "停留"
+ (days - 1) + "天.", 3);
new Thread(new MyThread(run, 1)).start();
}
/**
*
* 停留在點(diǎn)卷位
*
*/
private void stopInPoint(Building b, PlayerModel player) {
player.setNx(((Point) b).getPoint() + player.getNx());
this.textTip.showTextTip(player, player.getName() + " 獲得 "
+ ((Point) b).getPoint() + "點(diǎn)卷.", 3);
new Thread(new MyThread(run, 1)).start();
}
/**
*
* 停留在公園
*
*/
private void stopInPack(Building b, PlayerModel player) {
int random = (int) (Math.random() * ((Park) b).getImgageEvents().length);
switch (random) {
case 0:
case 1:
// 減一金幣
player.setCash(player.getCash() - 1);
break;
case 2:
// 減200金幣
player.setCash(player.getCash() - 200);
break;
case 3:
// 加200金幣
player.setCash(player.getCash() + 200);
break;
}
// 在事件層顯示事件
this.events.showImg(((Park) b).getImgageEvents()[random], 3, new Point(
320, 160, 0));
new Thread(new MyThread(run, 3)).start();
}
/**
*
* 停留在原點(diǎn)
*
*/
private void stopInOrigin(Building b, PlayerModel player) {
this.textTip.showTextTip(player, player.getName() + " 在起點(diǎn)停留,獎(jiǎng)勵(lì) "
+ ((Origin) b).getReward() + "金幣.", 3);
player.setCash(player.getCash() + ((Origin) b).getReward());
new Thread(new MyThread(run, 1)).start();
}
/**
*
* 停留在新聞點(diǎn)上
*
*/
private void stopInNews(Building b, PlayerModel player) {
int random = (int) (Math.random() * ((News) b).getImgageEvents().length);
switch (random) {
case 0:
case 1:
// 設(shè)置天數(shù)
player.setInHospital(player.getInHospital() + 4);
// 玩家位置切換到醫(yī)院位置
if (LandModel.hospital != null) {
player.setX(LandModel.hospital.x);
player.setY(LandModel.hospital.y);
}
break;
case 2:
case 3:
player.setCash(player.getCash() - 1000);
break;
case 4:
player.setCash(player.getCash() - 1500);
break;
case 5:
player.setCash(player.getCash() - 2000);
break;
case 6:
case 7:
player.setCash(player.getCash() - 300);
break;
case 8:
player.setCash(player.getCash() - 400);
break;
case 9:
// 點(diǎn)卷小于不能發(fā)生事件
if (player.getNx() < 40) {
stopInNews(b, player);
return;
}
player.setNx(player.getNx() - 40);
break;
case 10:
player.setCash(player.getCash() - 500);
break;
case 11:
player.setCash(player.getCash() + 1000);
break;
case 12:
case 13:
player.setCash(player.getCash() + 2000);
break;
case 14:
player.setCash(player.getCash() + 3999);
player.setNx(player.getNx() + 100);
break;
case 15:
player.setNx(player.getNx() + 300);
break;
case 16:
for (int i = 0; i < player.getCards().size();i++){
// System.out.println(player.getCards().get(i).getcName());
// 嫁禍卡
if (player.getCards().get(i).getName().equals("CrossingCard")){
player.getCards().remove(i);
// 對(duì)手減少金錢.
player.getOtherPlayer().setCash(player.getOtherPlayer().getCash() - 3000);
this.textTip.showTextTip(player, player.getName() + "將一筆\"3000元\"嫁禍給 "+ player.getOtherPlayer().getName()+"。真是人算不如天算啊.", 6);
this.events.showImg(((News) b).get3000(), 3, new Point(
420, 160, 0));
new Thread(new MyThread(run, 3)).start();
return;
}
}
player.setCash(player.getCash() - 3000);
break;
}
// 在事件層顯示事件
this.events.showImg(((News) b).getImgageEvents()[random], 3, new Point(
420, 160, 0));
new Thread(new MyThread(run, 3)).start();
}
/**
*
* 停留在樂(lè)透點(diǎn)上
*
*/
private void stopInLottery(Building b, PlayerModel player) {
// 未制作
new Thread(new MyThread(run, 1)).start();
}
/**
*
*
* 停留在可操作土地
*
*
*/
private void stopInHouse(Building b, PlayerModel player) {
if (b.isPurchasability()) {// 玩家房屋
if (b.getOwner() == null) { // 無(wú)人房屋
// 執(zhí)行買房操作
this.buyHouse(b, player);
} else {// 有人房屋
if (b.getOwner().equals(player)) {// 自己房屋
// 執(zhí)行升級(jí)房屋操作
this.upHouseLevel(b, player);
} else {// 別人房屋
// 執(zhí)行交稅操作
this.giveTax(b, player);
}
}
}
}
/**
*
* 執(zhí)行交稅操作
*
*
*/
private void giveTax(Building b, PlayerModel player) {
if (b.getOwner().getInHospital() > 0) {
// 增加文本提示
this.textTip.showTextTip(player, b.getOwner().getName()
+ "正在住院,免交過(guò)路費(fèi).", 3);
} else if (b.getOwner().getInPrison() > 0) {
// 增加文本提示
this.textTip.showTextTip(player, b.getOwner().getName()
+ "正在監(jiān)獄,免交過(guò)路費(fèi).", 3);
} else {
int revenue = b.getRevenue();
// 該玩家減少金幣
player.setCash(player.getCash() - revenue);
// 業(yè)主得到金幣
b.getOwner().setCash(b.getOwner().getCash() + revenue);
// 增加文本提示
this.textTip.showTextTip(player, player.getName() + "經(jīng)過(guò)"
+ b.getOwner().getName() + "的地盤,過(guò)路費(fèi):" + revenue + "金幣.", 3);
}
new Thread(new MyThread(run, 1)).start();
}
/**
*
* 執(zhí)行升級(jí)房屋操作
*
*/
private void upHouseLevel(Building b, PlayerModel player) {
if (b.canUpLevel()) {
// 升級(jí)房屋
int price = b.getUpLevelPrice();
String name = b.getName();
String upName = b.getUpName();
int choose = JOptionPane.showConfirmDialog(null,
"親愛(ài)的:" + player.getName() + "\r\n" + "是否升級(jí)這塊地?\r\n" + name
+ "→" + upName + "\r\n" + "價(jià)格:" + price + " 金幣.");
if (choose == JOptionPane.OK_OPTION) {
if (player.getCash() >= price) {
b.setLevel(b.getLevel() + 1);
// 減少需要的金幣
player.setCash(player.getCash() - price);
// 增加文本提示
this.textTip.showTextTip(player, player.getName() + " 從 "
+ name + " 升級(jí)成 " + upName + ".花費(fèi)了 " + price
+ "金幣. ", 3);
} else {
// 增加文本提示
this.textTip.showTextTip(player, player.getName()
+ " 金幣不足,操作失敗. ", 3);
}
}
}
new Thread(new MyThread(run, 1)).start();
}
/**
*
* 執(zhí)行買房操作
*
*
*/
private void buyHouse(Building b, PlayerModel player) {
int price = b.getUpLevelPrice();
int choose = JOptionPane.showConfirmDialog(
null,
"親愛(ài)的:" + player.getName() + "\r\n" + "是否購(gòu)買下這塊地?\r\n"
+ b.getName() + "→" + b.getUpName() + "\r\n" + "價(jià)格:"
+ price + " 金幣.");
if (choose == JOptionPane.OK_OPTION) {
// 購(gòu)買
if (player.getCash() >= price) {
b.setOwner(player);
b.setLevel(1);
// 將該房屋加入當(dāng)前玩家的房屋列表下
player.getBuildings().add(b);
// 減少需要的金幣
player.setCash(player.getCash() - price);
this.textTip.showTextTip(player, player.getName()
+ " 買下了一塊空地.花費(fèi)了: " + price + "金幣. ", 3);
} else {
this.textTip.showTextTip(player, player.getName()
+ " 金幣不足,操作失敗. ", 3);
}
}
new Thread(new MyThread(run, 1)).start();
}
/**
*
* 停留在醫(yī)院
*
*/
private void stopInHospital(Building b, PlayerModel player) {
int days = (int) (Math.random() * 4) + 2;
player.setInHospital(days);
int random = (int) (Math.random() * ((Hospital) b).getEvents().length);
String text = ((Hospital) b).getEvents()[random];
this.textTip.showTextTip(player, player.getName() + text + "停留"
+ (days - 1) + "天.", 3);
new Thread(new MyThread(run, 1)).start();
}
/**
*
* 卡片效果作用
*
*/
public void cardsBuff() {
List<Card>delete = new ArrayList<Card>();
for (Card a : this.run.getNowPlayer().getEffectCards()) {
int buff = a.cardBuff();
cardBuff(a, buff,delete);
}
this.run.getNowPlayer().getEffectCards().removeAll(delete);
this.run.nextState();
}
/**
*
* 卡片效果持續(xù)
*
*
*/
private void cardBuff(Card card, int buff,List<Card>delete) {
switch (buff) {
case GameState.CARD_BUFF_TORTOISE:
// 烏龜卡BUff
buffTortoiseCard((TortoiseCard) card,delete);
break;
case GameState.CARD_BUFF_STOP:
// 停留卡Buff
buffStopCard(card,delete);
break;
}
}
/**
*
* 停留卡Buff
*
*
*/
private void buffStopCard(Card card,List<Card>delete) {
// 增加文本提示
this.textTip.showTextTip(card.geteOwner(), card.geteOwner().getName()
+ " 受\"停留卡\" 作用,不能移動(dòng).. ", 2);
// 移除卡片
delete.add(card);
this.run.nextState();
new Thread(new MyThread(run, 1)).start();
}
/**
*
* 烏龜卡BUff
*
*/
private void buffTortoiseCard(TortoiseCard card,List<Card>delete) {
if (card.getLife() <= 0) {
delete.add(card);
return;
} else {
card.setLife(card.getLife() - 1);
}
this.textTip.showTextTip(card.geteOwner(), card.geteOwner().getName()
+ " 受\"烏龜卡\" 作用,只能移動(dòng)一步.. ", 2);
this.run.setPoint(0);
}
/**
*
* 使用卡片
*
*/
public void useCards() {
PlayerModel p = this.run.getNowPlayer();
while (true) {
if (p.getCards().size() == 0) {
// 無(wú)卡片,跳過(guò)階段
this.run.nextState();
break;
} else {
Object[] options = new Object[p.getCards().size() + 1];
int i;
for (i = 0; i < p.getCards().size(); i++) {
options[i] = p.getCards().get(i).getcName() + "\r\n";
}
options[i] = "跳過(guò),不使用";
int response = JOptionPane.showOptionDialog(null,
" " + p.getName() + ",選擇需要使用的卡片", "卡片使用階段.",
JOptionPane.YES_OPTION, JOptionPane.PLAIN_MESSAGE,
null, options, options[0]);
if (response != i && response != -1) {
// 獲得卡片
int th = p.getCards().get(response).useCard();
// 使用卡片
useCard(p.getCards().get(response), th);
} else {
// 不使用,跳過(guò)階段.
this.run.nextState();
break;
}
}
}
}
/**
*
* 使用卡片
*
*/
private void useCard(Card card, int th) {
switch (th) {
case GameState.CARD_ADDLEVEL:
// 使用加蓋卡
useAddLevelCard(card);
break;
case GameState.CARD_AVERAGERPOOR:
// 使用均貧卡
useAveragerPoorCard(card);
break;
case GameState.CARD_CHANGE:
// 使用換屋卡
useChangeCard(card);
break;
case GameState.CARD_CONTROLDICE:
// 使用遙控骰子卡
useControlDiceCard(card);
break;
case GameState.CARD_HAVE:
// 使用購(gòu)地卡
useHaveCard(card);
break;
case GameState.CARD_REDUCELEVEL:
// 使用降級(jí)卡
useReduceLevelCard(card);
break;
case GameState.CARD_ROB:
// 使用搶奪卡
useRobCard(card);
break;
case GameState.CARD_STOP:
// 使用停留卡
useStopCard(card);
break;
case GameState.CARD_TALLAGE:
// 使用查稅卡
useTallageCard(card);
break;
case GameState.CARD_TORTOISE:
// 使用烏龜卡
useTortoiseCard(card);
break;
case GameState.CARD_TRAP:
// 使用陷害卡
useTrapCard(card);
break;
case GameState.CARD_CROSSING:
// 使用嫁禍卡
useCrossingCard(card);
break;
}
}
/**
*
* 使用嫁禍卡
*
*/
private void useCrossingCard(Card card) {
Object[] options1 = { "重新選擇" };
JOptionPane.showOptionDialog(null, " 嫁禍卡在大事件發(fā)生時(shí)會(huì)自動(dòng)使用.",
"卡片使用階段.", JOptionPane.YES_OPTION,
JOptionPane.PLAIN_MESSAGE, null, options1,
options1[0]);
}
/**
*
* 使用陷害卡
*
*/
private void useTrapCard(Card card) {
Object[] options = { "確認(rèn)使用", "重新選擇" };
int response = JOptionPane.showOptionDialog(null, "確認(rèn)使用\"陷害卡\"將 \""
+ card.getOwner().getOtherPlayer().getName() + "\"入獄2天?",
"卡片使用階段.", JOptionPane.YES_OPTION, JOptionPane.PLAIN_MESSAGE,
null, options, options[0]);
if (response == 0) {
// 使用
PlayerModel cPlayer = card.getOwner().getOtherPlayer();
// 設(shè)置天數(shù)
cPlayer.setInPrison(cPlayer.getInPrison() + 2);
// 玩家位置切換到醫(yī)院位置
if (LandModel.prison != null) {
cPlayer.setX(LandModel.prison.x);
cPlayer.setY(LandModel.prison.y);
}
// 增加文本提示
this.textTip
.showTextTip(card.getOwner(), card.getOwner().getName()
+ " 使用了 \"陷害卡\",將 \""
+ card.getOwner().getOtherPlayer().getName()
+ "\"入獄2天.", 2);
// 減去卡片
card.getOwner().getCards().remove(card);
}
}
/**
*
* 使用烏龜卡
*
*
*/
private void useTortoiseCard(Card card) {
Object[] options = { card.getOwner().getName(),
card.getOwner().getOtherPlayer().getName(), "重新選擇" };
int response = JOptionPane.showOptionDialog(null,
" 請(qǐng)選擇目標(biāo)玩家,對(duì)其打出\"烏龜卡\".", "卡片使用階段.", JOptionPane.YES_OPTION,
JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
if (response == 0) {
card.getOwner().getEffectCards().add(card);
card.seteOwner(card.getOwner());
// 增加文本提示
this.textTip.showTextTip(card.getOwner(), card.getOwner().getName()
+ " 對(duì)自己使用了\"烏龜卡\". ", 2);
card.getOwner().getCards().remove(card);
} else if (response == 1) {
card.getOwner().getOtherPlayer().getEffectCards().add(card);
card.seteOwner(card.getOwner().getOtherPlayer());
this.textTip.showTextTip(card.getOwner(), card.getOwner().getName()
+ " 對(duì)\"" + card.getOwner().getOtherPlayer().getName()
+ "\"使用了\"烏龜卡\". ", 2);
card.getOwner().getCards().remove(card);
}
}
/**
*
* 使用查稅卡
*
*
*/
private void useTallageCard(Card card) {
Object[] options = { "確認(rèn)使用", "重新選擇" };
int response = JOptionPane.showOptionDialog(null, "確認(rèn)使用\"查稅卡\"從 \""
+ card.getOwner().getOtherPlayer().getName() + "\"手中獲得 10%稅款?",
"卡片使用階段.", JOptionPane.YES_OPTION, JOptionPane.PLAIN_MESSAGE,
null, options, options[0]);
if (response == 0) {
// 使用
int money = (int) (card.getOwner().getOtherPlayer().getCash() / 10);
card.getOwner().setCash(card.getOwner().getCash() + money);
card.getOwner()
.getOtherPlayer()
.setCash(card.getOwner().getOtherPlayer().getCash() - money);
// 增加文本提示
this.textTip.showTextTip(card.getOwner(), card.getOwner().getName()
+ " 使用了 \"查稅卡\",從 \""
+ card.getOwner().getOtherPlayer().getName()
+ "\"手中獲得 10%稅款", 2);
// 減去卡片
card.getOwner().getCards().remove(card);
}
}
/**
*
*
* 使用停留卡
*
*/
private void useStopCard(Card card) {
Object[] options = { card.getOwner().getName(),
card.getOwner().getOtherPlayer().getName(), "重新選擇" };
int response = JOptionPane.showOptionDialog(null,
" 請(qǐng)選擇目標(biāo)玩家,對(duì)其打出\"停留卡\".", "卡片使用階段.", JOptionPane.YES_OPTION,
JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
if (response == 0) {
card.getOwner().getEffectCards().add(card);
card.seteOwner(card.getOwner());
// 增加文本提示
this.textTip.showTextTip(card.getOwner(), card.getOwner().getName()
+ " 對(duì)自己使用了\"停留卡\". ", 2);
card.getOwner().getCards().remove(card);
} else if (response == 1) {
card.getOwner().getOtherPlayer().getEffectCards().add(card);
card.seteOwner(card.getOwner().getOtherPlayer());
this.textTip.showTextTip(card.getOwner(), card.getOwner().getName()
+ " 對(duì)\"" + card.getOwner().getOtherPlayer().getName()
+ "\"使用了\"停留卡\". ", 2);
card.getOwner().getCards().remove(card);
}
}
/**
*
*
* 使用搶奪卡
*
*
*/
private void useRobCard(Card card) {
if (card.getOwner().getCards().size() >= PlayerModel.MAX_CAN_HOLD_CARDS) {
// 無(wú)法使用
Object[] options = { "重新選擇" };
JOptionPane.showOptionDialog(null, " 您的卡片數(shù)量已經(jīng)達(dá)到上限,無(wú)法使用\"搶奪卡\"",
"卡片使用階段.", JOptionPane.YES_OPTION,
JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
} else if (card.getOwner().getOtherPlayer().getCards().size() == 0) {
// 無(wú)法使用
Object[] options = { "重新選擇" };
JOptionPane.showOptionDialog(null, " \""
+ card.getOwner().getOtherPlayer().getName()
+ "\"沒(méi)有卡片,無(wú)法使用\"搶奪卡\"", "卡片使用階段.", JOptionPane.YES_OPTION,
JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
} else {
PlayerModel srcPlayer = card.getOwner().getOtherPlayer();
// 隨機(jī)選取一張
// System.out.println(srcPlayer.getCards().size() + "zhang");
Card getCard = srcPlayer.getCards().get((int) (srcPlayer.getCards().size() * Math.random()));
// 對(duì)手喪失卡片
srcPlayer.getCards().remove(getCard);
// 卡片擁有者獲得
card.getOwner().getCards().add(getCard);
// 更改獲得卡片擁有者
getCard.setOwner(card.getOwner());
// 增加文本提示
this.textTip.showTextTip(card.getOwner(), card.getOwner().getName()
+ " 使用了 \"搶奪卡\",搶奪了 \"" + srcPlayer.getName() + "\"的一張\""
+ getCard.getcName() + ".\". ", 2);
// 減去卡片
card.getOwner().getCards().remove(card);
}
}
/**
*
* 使用降級(jí)卡
*
*/
private void useReduceLevelCard(Card card) {
Building building = this.building.getBuilding(
card.getOwner().getY() / 60, card.getOwner().getX() / 60);
if (building.getOwner() != null
&& building.getOwner().equals(card.getOwner().getOtherPlayer())) {// 是對(duì)手的房屋
if (building.getLevel() > 0) { // 可以降級(jí)
// 降級(jí)
building.setLevel(building.getLevel() - 1);
// 增加文本提示
this.textTip.showTextTip(card.getOwner(), card.getOwner()
.getName()
+ " 使用了 \"降級(jí)卡\",將\""
+ card.getOwner().getOtherPlayer().getName()
+ "\"的房屋等級(jí)降低一級(jí). ", 2);
// 減去卡片
card.getOwner().getCards().remove(card);
} else {
// 無(wú)法使用,不可降級(jí)
Object[] options = { "重新選擇" };
JOptionPane.showOptionDialog(null, " 當(dāng)前房屋不可降級(jí)", "卡片使用階段.",
JOptionPane.YES_OPTION, JOptionPane.PLAIN_MESSAGE,
null, options, options[0]);
}
} else {
// 無(wú)法使用.
Object[] options = { "重新選擇" };
JOptionPane.showOptionDialog(null, " 當(dāng)前房屋不能使用該卡片.", "卡片使用階段.",
JOptionPane.YES_OPTION, JOptionPane.PLAIN_MESSAGE, null,
options, options[0]);
}
}
/**
*
* 使用購(gòu)地卡
*
*/
private void useHaveCard(Card card) {
// 該地點(diǎn)房屋
Building building = this.building.getBuilding(
card.getOwner().getY() / 60, card.getOwner().getX() / 60);
if (building.getOwner() != null
&& building.getOwner().equals(card.getOwner().getOtherPlayer())) {// 是對(duì)方的房屋
Object[] options = { "確認(rèn)使用", "重新選擇" };
int response = JOptionPane.showOptionDialog(null,
"確認(rèn)使用\"購(gòu)地卡\"將此地收購(gòu)?需要花費(fèi):" + building.getAllPrice() + " 金幣.",
"卡片使用階段.", JOptionPane.YES_OPTION,
JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
if (response == 0) {
if (card.getOwner().getCash() >= building.getAllPrice()) {
// 金幣交換
building.getOwner().setCash(
building.getOwner().getCash()
+ building.getAllPrice());
card.getOwner().setCash(
card.getOwner().getCash() - building.getAllPrice());
building.setOwner(card.getOwner());
// 增加文本提示
this.textTip.showTextTip(card.getOwner(), card.getOwner()
.getName() + " 使用了 \"購(gòu)地卡\",收購(gòu)獲得了該土地. ", 2);
// 減去卡片
card.getOwner().getCards().remove(card);
} else {
Object[] options1 = { "重新選擇" };
JOptionPane.showOptionDialog(null, " 金幣不足,無(wú)法購(gòu)買房屋!",
"卡片使用階段.", JOptionPane.YES_OPTION,
JOptionPane.PLAIN_MESSAGE, null, options1,
options1[0]);
}
}
} else {
Object[] options1 = { "重新選擇" };
JOptionPane.showOptionDialog(null, "此房屋無(wú)法使用該卡片.", "卡片使用階段.",
JOptionPane.YES_OPTION, JOptionPane.PLAIN_MESSAGE, null,
options1, options1[0]);
}
}
/**
*
*
* 使用遙控骰子卡
*
*
*/
private void useControlDiceCard(Card card) {
Object[] options = { "1點(diǎn)", "2點(diǎn)", "3點(diǎn)", "4點(diǎn)", "5點(diǎn)", "6點(diǎn)", "重新選擇" };
int response = JOptionPane.showOptionDialog(null,
"確認(rèn)使用\"遙控骰子卡\"遙控骰子點(diǎn)數(shù)?", "卡片使用階段.", JOptionPane.YES_OPTION,
JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
if (response == -1 || response == 6) {
return;
} else {
// 使用
this.run.setPoint(response);
// 增加文本提示
this.textTip.showTextTip(card.getOwner(), card.getOwner().getName()
+ " 使用了 \"遙控骰子卡\".", 2);
// 減去卡片
card.getOwner().getCards().remove(card);
}
}
/**
*
* 使用換屋卡
*
*/
private void useChangeCard(Card card) {
Building building = this.building.getBuilding(
card.getOwner().getY() / 60, card.getOwner().getX() / 60);
if (building.getOwner() != null
&& building.getOwner().equals(card.getOwner().getOtherPlayer())) {// 是對(duì)手房屋
Object[] options = { "確認(rèn)使用", "重新選擇" };
int response = JOptionPane.showOptionDialog(null,
"確認(rèn)使用\"換屋卡\"與對(duì)手交換一塊同類型的房屋(隨機(jī))", "卡片使用階段.",
JOptionPane.YES_OPTION, JOptionPane.PLAIN_MESSAGE, null,
options, options[0]);
if (response == 0) {
// 找尋相等級(jí)別房屋
int thisBuildingLevel = building.getLevel();
Building changeBuilding = null;
for (Building a : card.getOwner().getBuildings()) {
if (a.getLevel() == thisBuildingLevel) {
changeBuilding = a;
break;
}
}
// 找到同類型房屋
if (changeBuilding != null) {
changeBuilding.setOwner(card.getOwner().getOtherPlayer());
building.setOwner(card.getOwner());
// 增加文本提示
this.textTip.showTextTip(card.getOwner(), card.getOwner()
.getName()
+ " 使用了 \"換屋卡\",將某處房屋與"
+ card.getOwner().getOtherPlayer().getName()
+ "該地的房屋進(jìn)行交換.. ", 2);
// 減去卡片
card.getOwner().getCards().remove(card);
} else {
Object[] options1 = { "重新選擇" };
JOptionPane.showOptionDialog(null, " 當(dāng)前房屋不可使用\"換屋卡\"",
"卡片使用階段.", JOptionPane.YES_OPTION,
JOptionPane.PLAIN_MESSAGE, null, options1,
options1[0]);
}
}
} else {
Object[] options = { "重新選擇" };
JOptionPane.showOptionDialog(null, " 當(dāng)前房屋不可使用\"換屋卡\"", "卡片使用階段.",
JOptionPane.YES_OPTION, JOptionPane.PLAIN_MESSAGE, null,
options, options[0]);
}
}
/**
*
* 使用均貧卡
*
*/
private void useAveragerPoorCard(Card card) {
Object[] options = { "確認(rèn)使用", "重新選擇" };
int response = JOptionPane.showOptionDialog(null,
"確認(rèn)使用\"均貧卡\"與對(duì)手平分現(xiàn)金?", "卡片使用階段.", JOptionPane.YES_OPTION,
JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
if (response == 0) {
// 使用
int money = (int) (card.getOwner().getCash() + card.getOwner()
.getOtherPlayer().getCash()) / 2;
card.getOwner().setCash(money);
card.getOwner().getOtherPlayer().setCash(money);
// 增加文本提示
this.textTip.showTextTip(card.getOwner(), card.getOwner().getName()
+ " 使用了 \"均貧卡\",與對(duì)手平分了現(xiàn)金,現(xiàn)在雙方現(xiàn)金數(shù)為:" + money + " 金幣. ", 2);
// 減去卡片
card.getOwner().getCards().remove(card);
}
}
/**
*
* 使用加蓋卡
*
*/
private void useAddLevelCard(Card card) {
Building building = this.building.getBuilding(
card.getOwner().getY() / 60, card.getOwner().getX() / 60);
if (building.getOwner() != null
&& building.getOwner().equals(card.getOwner())) {// 是自己的房屋
if (building.canUpLevel()) { // 可升級(jí)
// 升級(jí)
building.setLevel(building.getLevel() + 1);
// 增加文本提示
this.textTip.showTextTip(card.getOwner(), card.getOwner()
.getName() + " 使用了 \"加蓋卡\",將房屋等級(jí)提升一級(jí). ", 2);
// 減去卡片
card.getOwner().getCards().remove(card);
} else {
// 無(wú)法使用,不可升級(jí)
Object[] options = { "重新選擇" };
JOptionPane.showOptionDialog(null, " 當(dāng)前房屋不可升級(jí).", "卡片使用階段.",
JOptionPane.YES_OPTION, JOptionPane.PLAIN_MESSAGE,
null, options, options[0]);
}
} else {
// 無(wú)法使用.
Object[] options = { "重新選擇" };
JOptionPane.showOptionDialog(null, " 當(dāng)前房屋不能使用該卡片.", "卡片使用階段.",
JOptionPane.YES_OPTION, JOptionPane.PLAIN_MESSAGE, null,
options, options[0]);
}
}
/**
*
* 退出商店
*
*/
public void exitShop() {
new Thread(new MyThread(run, 1)).start();
}
/**
*
* 商店里買卡片操作
*
*
*/
public void buyCard(Shop_ shop) {
int chooseCard = this.panel.getShop().getChooseCard();
if (chooseCard >= 0
&& this.panel.getShop().getCard().get(chooseCard) != null) {
// 購(gòu)買卡片 如果購(gòu)買成功
if (this.buyCard(shop, chooseCard)) {
// UI消去卡片
this.panel.getShop().getCard().get(chooseCard).setEnabled(false);
// 初始化已選卡片
this.panel.getShop().setChooseCard(-1);
}
}
}
/**
*
* 購(gòu)買卡片
*
*
*/
public boolean buyCard(Shop_ shop, int p) {
if (this.panel.getShop().getCard().get(p) != null) {
if (this.run.getNowPlayer().getCards().size() >= PlayerModel.MAX_CAN_HOLD_CARDS) {
JOptionPane.showMessageDialog(null, "您最大可持有:"
+ PlayerModel.MAX_CAN_HOLD_CARDS + "張卡片,目前已經(jīng)不能再購(gòu)買了!");
return false;
}
if (this.run.getNowPlayer().getNx() < shop.getCards().get(p)
.getPrice()) {
JOptionPane.showMessageDialog(null, "當(dāng)前卡片需要:"
+ shop.getCards().get(p).getPrice() + "點(diǎn)卷,您的點(diǎn)卷不足.");
return false;
}
// 設(shè)置卡片擁有者
shop.getCards().get(p).setOwner(this.run.getNowPlayer());
// 向玩家卡片庫(kù)中添加卡片
this.run.getNowPlayer().getCards().add(shop.getCards().get(p));
// 減去對(duì)應(yīng)點(diǎn)卷
this.run.getNowPlayer().setNx(
this.run.getNowPlayer().getNx()
- shop.getCards().get(p).getPrice());
}
return true;
}
/**
*
* 游戲結(jié)束~
*
*
* @param winer
*/
public void gameOver () {
this.run.setNowPlayerState(GameRunning.GAME_STOP);
this.panel.getBackgroundUI().moveToFront();
this.panel.getRunning().moveToFront();
this.panel.getPlayerInfo().moveToFront();
this.panel.getEffect().moveToFront();
this.music.gameOver();
this.effect.showImg("timeover2");
}
}游戲運(yùn)轉(zhuǎn)處理
/**
*
* 游戲運(yùn)轉(zhuǎn)處理
*
* @author MOVELIGHTS
*
*/
public class GameRunning {
/**
* 玩家列表
*/
private List<PlayerModel> players = null;
/**
* 當(dāng)前操作玩家
*/
private PlayerModel nowPlayer = null;
/**
* 骰子當(dāng)前點(diǎn)數(shù)
*/
private int point;
/**
* 玩家使用卡片狀態(tài)
*/
public static int STATE_CARD = 1;
/**
* 玩家卡片作用狀態(tài)
*/
public static int STATE_CARD_EFFECT = 2;
/**
* 玩家擲點(diǎn)狀態(tài)
*/
public static int STATE_THROWDICE = 3;
/**
* 玩家移動(dòng)狀態(tài)
*/
public static int STATE_MOVE = 4;
/**
*
* 游戲終止?fàn)顟B(tài)
*
*/
public static int GAME_STOP = 5;
/**
*
* 玩家目前狀態(tài)
*
*/
private int nowPlayerState;
/**
*
* 游戲進(jìn)行天數(shù)
*
*/
public static int day = 1;
/**
*
* 當(dāng)前地圖代碼
*
*/
public static int MAP = 1;
/**
*
* 游戲上限天數(shù) - 1為無(wú)上限
*
*/
public static int GAME_DAY = -1;
/**
*
* 游戲金錢上線(即勝利條件)-1為無(wú)上限
*
*/
public static int MONEY_MAX = -1;
/**
*
* 初始化玩家初始金錢
*
*/
public static int PLAYER_CASH = 1000;
private Control control;
public GameRunning(Control control, List<PlayerModel> players) {
this.control = control;
this.players = players;
}
/**
*
* 獲得當(dāng)前玩家狀態(tài)
*
*/
public int getNowPlayerState() {
return this.nowPlayerState;
}
/**
*
* 轉(zhuǎn)換玩家狀態(tài)
*
*/
public void nextState() {
// 判斷游戲是否得出結(jié)果
if (gameContinue()) {
if (this.nowPlayerState == STATE_CARD) {
// “擲點(diǎn)狀態(tài)”
this.nowPlayerState = STATE_CARD_EFFECT;
// 卡片BUFF
this.control.cardsBuff();
} else if (this.nowPlayerState == STATE_CARD_EFFECT) {
// “卡片生效狀態(tài)”
this.nowPlayerState = STATE_THROWDICE;
} else if (this.nowPlayerState == STATE_THROWDICE) {
// 移動(dòng)狀態(tài)
this.nowPlayerState = STATE_MOVE;
} else if (this.nowPlayerState == STATE_MOVE) {
// 換人操作
this.nowPlayerState = STATE_CARD;
this.nextPlayer();
// 產(chǎn)生一個(gè)點(diǎn)數(shù)
this.setPoint((int) (Math.random() * 6));
// 完畢后執(zhí)行下一個(gè)玩家的動(dòng)作 - STATE_CARD
this.control.useCards();
}
}
}
/**
*
* 獲取當(dāng)前玩家
*
*/
public PlayerModel getNowPlayer() {
return this.nowPlayer;
}
public void setNowPlayerState(int nowPlayerState) {
this.nowPlayerState = nowPlayerState;
}
/**
*
* 獲取非當(dāng)前玩家
*
*/
public PlayerModel getNotNowPlayer() {
return this.nowPlayer.equals(this.players.get(0)) ? this.players.get(1)
: this.players.get(0);
}
/**
* 換人操作
*/
private void nextPlayer() {
// 減少時(shí)間
if (this.nowPlayer.getInPrison() > 0) {
this.nowPlayer.setInPrison(this.nowPlayer.getInPrison() - 1);
}
if (this.nowPlayer.getInHospital() > 0) {
this.nowPlayer.setInHospital(this.nowPlayer.getInHospital() - 1);
}
// 換人
if (this.nowPlayer.equals(this.players.get(0))) {
this.nowPlayer = this.players.get(1);
} else {
this.nowPlayer = this.players.get(0);
// 結(jié)束后游戲天數(shù)增加
day++;
}
}
/**
*
* 判斷游戲是否結(jié)束
*
*
*/
public boolean gameContinue() {
PlayerModel p1 = this.nowPlayer;
PlayerModel p2 = this.nowPlayer.getOtherPlayer();
// 天數(shù)
if (GAME_DAY > 0 && day >= GAME_DAY) {
this.control.gameOver();
return false;
}
// 最大金錢
if (MONEY_MAX > 0 && p1.getCash() >= MONEY_MAX) {
this.control.gameOver();
return false;
} else if (MONEY_MAX > 0 && p2.getCash() >= MONEY_MAX) {
this.control.gameOver();
return false;
}
// 破產(chǎn)
if (p1.getCash() < 0) {
this.control.gameOver();
return false;
} else if (p2.getCash() < 0) {
this.control.gameOver();
return false;
}
return true;
}
public void setPlayers(List<PlayerModel> players) {
this.players = players;
}
public int getPoint() {
return point;
}
public void setPoint(int point) {
this.point = point;
}
public int getDay() {
return day;
}
/**
*
* 開(kāi)始游戲設(shè)置
*
*/
public void startGameInit() {
// 設(shè)定當(dāng)前游戲玩家
this.nowPlayer = this.players.get(0);
// 設(shè)定當(dāng)前玩家狀態(tài)為“使用卡片”
this.nowPlayerState = STATE_CARD;
// 隨機(jī)設(shè)定點(diǎn)數(shù)
this.setPoint((int) (Math.random() * 6));
// 首個(gè)玩家使用卡片
this.control.useCards();
}
}總結(jié)
通過(guò)此次的《大富翁》游戲?qū)崿F(xiàn),讓我對(duì)swing的相關(guān)知識(shí)有了進(jìn)一步的了解,對(duì)java這門語(yǔ)言也有了比以前更深刻的認(rèn)識(shí)。
java的一些基本語(yǔ)法,比如數(shù)據(jù)類型、運(yùn)算符、程序流程控制和數(shù)組等,理解更加透徹。java最核心的核心就是面向?qū)ο笏枷?,?duì)于這一個(gè)概念,終于悟到了一些。
以上就是Java實(shí)現(xiàn)經(jīng)典大富翁游戲的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Java大富翁游戲的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Retrofit+RxJava實(shí)現(xiàn)帶進(jìn)度條的文件下載
這篇文章主要為大家詳細(xì)介紹了Retrofit+RxJava實(shí)現(xiàn)帶進(jìn)度條的文件下載,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06
Eclipse添加xml文件提示及Hibernate配置學(xué)習(xí)
文件提示功能在開(kāi)發(fā)過(guò)程中很實(shí)用的,本文實(shí)現(xiàn)了一個(gè)Eclipse添加xml文件提示,感興趣的朋友可以了解下啊,希望本文對(duì)你有所幫助2013-01-01
SpringBoot?thymeleaf實(shí)現(xiàn)餅狀圖與柱形圖流程介紹
這篇文章主要介紹了SpringBoot?thymeleaf實(shí)現(xiàn)餅狀圖與柱形圖流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-12-12
SpringBoot結(jié)合Swagger2自動(dòng)生成api文檔的方法
這篇文章主要介紹了SpringBoot結(jié)合Swagger2自動(dòng)生成api文檔的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05
springboot多模塊項(xiàng)目mvn打包遇到存在依賴但卻無(wú)法發(fā)現(xiàn)符號(hào)問(wèn)題
在SpringBoot多模塊項(xiàng)目中,如果遇到依賴存在但無(wú)法發(fā)現(xiàn)符號(hào)的問(wèn)題,常見(jiàn)原因可能是pom.xml配置問(wèn)題,例如,如果某個(gè)模塊僅作為依賴而不是啟動(dòng)工程,不應(yīng)在其pom中配置spring-boot-maven-plugin插件,因?yàn)檫@將影響jar包的生成方式2024-09-09
JavaEE多線程中阻塞隊(duì)列的項(xiàng)目實(shí)踐
本文主要介紹了JavaEE多線程中阻塞隊(duì)列的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-09-09
mybatis 自定義實(shí)現(xiàn)攔截器插件Interceptor示例
這篇文章主要介紹了mybatis 自定義實(shí)現(xiàn)攔截器插件Interceptor,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10

