1. 程式人生 > >java擲骰子游戲聯機版

java擲骰子游戲聯機版

目前只實現了一個人的客戶端,由服務端進行判斷輸贏,返回結果!人數,可以自行增加!

我使用多執行緒的方式,即每次押注都會通知伺服器端新開執行緒,在參與人數比較少的情況下,不會又問題!但是如果參與人數比較多,由於我的基準值,也就是初始金錢值使用的是同一個靜態變數,必然有可能會造成金錢變化的不及時,並且,所有人用的也都是同一個金錢值,當然也不太合理!

還有許多控制元件的功能並沒有完全實現!

總算是完成了自己的第一個GUI程式吧!

java 的學習至此也要告一段落了,下一階段該學什麼呢?

//客戶端
package cgame;
import java.awt.*;
import java.awt.event.*;

public class ClientGame extends Frame implements WindowListener{
	
	public TextArea ta;
	public ClientGame(){
		super("骰子游戲客戶端");
		MenuUI bar=new MenuUI(this);//設定框架選單欄
		//註冊時間監聽//第一個this表示自己,給自己註冊監聽器,是誰,還是自己(第二個this)
		//註冊監聽器的意思就是說,被監聽物件有動作時,自動執行監聽器的對應函式
		this.addWindowListener(this);
		//設定主介面
		initUI();
		this.setSize(400,400);
		this.setVisible(true);
	}
	private void initUI(){
		//初始化上部
		Panel pNorth=initNorth();
		this.add(pNorth,BorderLayout.NORTH);
		//初始化右側
		Panel pEast=initEast();
		this.add(pEast, BorderLayout.EAST);
		//初始化中部
		Panel pCenter=initCenter();
		this.add(pCenter, BorderLayout.CENTER);
	}
	//初始化上部函式,返回上部面板
	private Panel initNorth(){
		Panel p=new Panel();//新建一個面板物件
		//設定佈局管理器
		BorderLayout b1=new BorderLayout();
		p.setLayout(b1);
		//建立控制元件
		Label lbTitle=new Label("歡迎加入骰子大戰");
		//新增一個多行文字空間
		ta=new TextArea();//換成類屬性,這個每個版塊都可以呼叫了
		ta.append("系統提示資訊:\n");
		ta.append("初始金錢:1000\n");
		//設定不可編輯
		ta.setEditable(false);
		//新增到容器
		p.add(lbTitle,BorderLayout.NORTH);
		p.add(ta,BorderLayout.CENTER);
		//設定背景色
		p.setBackground(Color.GRAY);
		return p;
	}
	//初始化右側函式,返回右側面板
	private Panel initEast(){
		Panel p=new Panel();
		//設定佈局管理器為邊界式
		BorderLayout bl=new BorderLayout();
		p.setLayout(bl);
		//建立控制元件
		Label lbTitle=new Label("當前線上:");
		List listUser=new List();
		listUser.add("所有人");
		listUser.add("Tom");
		listUser.add("Mike");
		//新增控制元件到容器
		p.add(lbTitle, BorderLayout.NORTH);
		p.add(listUser,BorderLayout.CENTER);
		//設定背景色
		p.setBackground(Color.CYAN);
		return p;
	}
	//初始化中部函式,返回中部面板
	private Panel initCenter(){
		Panel p=new Panel();
		//設定佈局管理器
		GridLayout gl=new GridLayout(4,4);
		p.setLayout(gl);
		//建立控制元件物件,並依次新增
		String[] content={
				"回顯功能","200","192.168.1.108","Txt3",
				"回顯功能","Label1","Label2","Label3",
				"Label4","Label5","Label6","Label7",
				"壓大","壓小","聊天","Button3",
		};
		//為了方便呼叫標籤元件,構造Label元件放在構造txt前面
			Label[] DicNum=new Label[8];
			int j=0;
			for(int i=4;i<12;i++,j++){
				DicNum[j]=new Label(content[i]);
				p.add(DicNum[j]);
			}
		//構造Txt元件
		TextField[] userIP=new TextField[4];
		for(int i=0;i<4;i++){
			userIP[i]=new TextField(content[i]);
			p.add(userIP[i]);
		}
		//註冊Text0的監視器,這裡實際是userIP[0]
		TextToLabel ttl=new TextToLabel(userIP[0],DicNum[0],ta);//將事件源文字框傳過去
		userIP[0].addActionListener(ttl);
		
		//構造 button元件
		j=0;
		Button[] btn=new Button[4];//這裡僅僅只是宣告,還不算初始化
		for(int i=12;i<16;i++,j++){
			btn[j]=new Button(content[i]);
			p.add(btn[j]);
		}
		//為壓大和壓小按鈕註冊監聽器,將文字框1都傳過去,按鈕和多行文字控制元件也要傳過去
		//文字框1押注金額0-3,傳遞的引數:文字框1:輸押注金額,文字框2:輸ip,
		//按鈕:壓大小,多行文字:顯示提示
		DicGame dg=new DicGame(userIP[1],userIP[2],btn[0],btn[1],ta);
		btn[0].addActionListener(dg);
		btn[1].addActionListener(dg);
		btn[2].addActionListener(dg);
		
		return p;
	}
	public static void main(String[] args) {
		// TODO 自動生成的方法存根
		ClientGame ss=new ClientGame();
	}
	@Override
	public void windowActivated(WindowEvent arg0) {
		// TODO 自動生成的方法存根
		
	}
	@Override
	public void windowClosed(WindowEvent arg0) {
		// TODO 自動生成的方法存根
		
	}
	@Override
	public void windowClosing(WindowEvent arg0) {
		// TODO 自動生成的方法存根
		System.exit(0);
		
	}
	@Override
	public void windowDeactivated(WindowEvent arg0) {
		// TODO 自動生成的方法存根
		
	}
	@Override
	public void windowDeiconified(WindowEvent arg0) {
		// TODO 自動生成的方法存根
		
	}
	@Override
	public void windowIconified(WindowEvent arg0) {
		// TODO 自動生成的方法存根
		
	}
	@Override
	public void windowOpened(WindowEvent arg0) {
		// TODO 自動生成的方法存根
		
	}
	

}
package cgame;
import java.awt.*;
import java.util.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class DicGame implements ActionListener {

	Label lab1;
	TextArea ta;
	TextField txt1,txt2;//txt1用於押注金額,txt2用於輸入ip
	Button btn0,btn1,btn2;
	static int money=1000;//初始金額
	public DicGame(TextField txt1,TextField txt2,Button btn0,Button btn1,TextArea ta){
		this.txt1=txt1;
		this.txt2=txt2;
		this.btn0=btn0;
		this.btn1=btn1;
		this.btn2=btn2;
		this.ta=ta;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO 自動生成的方法存根
		
		Socket socket=null;//客戶端 宣告網路連線物件
		InputStream is=null;
		OutputStream os=null;
		//伺服器端IP地址在txt2中,通過函式來得到
		String serverIP=addIP(txt2);
		//伺服器埠號
		int port=10000;
		//傳送內容就限定為byte型的0和1,壓大是1,壓小是0
		//兩個按鈕註冊的是同一個監聽物件,就需要得到事件源,判斷是哪個按鈕事件
		String data=null;
		Button b=(Button)e.getSource();
		if(b==btn0)
			data="1";//壓大
		else if(b==btn1)
			data="0";//壓小

		//獲得押注金額,txt1內容轉換為字串
		String stake=txt1.getText();
		
		//將多個String連線成一個字串,大小和押注金額
		String sdata=linkData(data,stake);
		showLabel(sdata);
		try{
			//建立連線
			socket=new Socket(serverIP,port);
			//傳送資料
			//就簡單理解為,此操作後,os就是連線輸出流,輸出內容寫入到輸出流os中即可
			os=socket.getOutputStream();//得到網路連線的輸出流
			os.write(sdata.getBytes());
			//接受資料
			is=socket.getInputStream();//同上理解,得到連線輸入流
			byte[]d=new byte[1024];
			int n=is.read(d);
			//輸出反饋資料
			String s=new String(d,0,n);//反饋資料即為此s字串
			showLabel(s);
			//解析s字串,並輸出結果
			showResult(s);
			
			
		}catch(Exception e1){
			e1.printStackTrace();
		}finally{
			try{
				//關閉流和連線
				is.close();
				os.close();
				socket.close();
			}catch(Exception e2){}
		}

	}
	String addIP(TextField txt2){
		return txt2.getText();//這裡對IP地址的非法情況不做判斷,由連線異常來反應
	}
	//將傳送資料都整合到一個字串裡面
	String linkData(String str1,String str2){
		//StringBuffer sb=new StringBuffer(str1);
		//sb.append(str2);
		return str1+" "+str2;//String本來就過載了+,可以直接使用
	}
	//反饋資料解析並顯示函式
	void showResult(String s){
		StringTokenizer an=new StringTokenizer(s," ");//空格作為分隔依據
		
			String str1=an.nextToken();
			String str2=an.nextToken();//我這種簡單的網路協議就不需要用迴圈了
			//資料解析完成後顯示
			showLabel(str1);showLabel("顯示麼?");
			if(str1=="0"){
				showLabel("輸");
			}else {
				showLabel("贏");
			}
			showLabel("剩餘金錢:");
			showLabel(str2);
			
	}
	//將字串在多行文字上顯示
	public void showLabel(String s){
		ta.append(s+'\n');
	}
	
}
package cgame;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JOptionPane;

public class MenuUI implements ActionListener {
		MenuItem versionMi;
		MenuItem authorMi;
		Frame frm;
	public MenuUI(Frame frm){
		this.frm=frm;//傳遞框架物件,不然彈出對話方塊的時候,找不到依賴對話方塊
		MenuBar bar=new MenuBar();//建立選單欄
		//建立選單
		Menu fileMenu=new Menu("檔案");
		Menu helpMenu=new Menu("幫助");
		Menu aboutMenu=new Menu("關於");
		//建立選單項
		MenuItem openMi=new MenuItem("開啟");
		MenuItem printMi=new MenuItem("列印");
		MenuItem exitMi=new MenuItem("退出");
		MenuItem helpMi=new MenuItem("幫助");
		versionMi=new MenuItem("版本");
		authorMi=new MenuItem("作者");
		//新增到選單
		fileMenu.add(openMi);
		fileMenu.add(printMi);
		fileMenu.add(exitMi);
		aboutMenu.add(versionMi);
		aboutMenu.add(authorMi);
		helpMenu.add(helpMi);
		helpMenu.add(aboutMenu);
		//新增到選單欄
		bar.add(fileMenu);
		bar.add(helpMenu);
		//設定選單欄
		frm.setMenuBar(bar);
		//註冊同一個監聽器,方法內部判斷髮生事件的選單項,然後進行不同的邏輯處理 
		versionMi.addActionListener(this);
		authorMi.addActionListener(this);
	}
	public void actionPerformed(ActionEvent e){
		//獲得發生事件的控制元件
		MenuItem mi=(MenuItem)e.getSource();
		//判斷,彈出有模式對話方塊
		if(mi==versionMi){
			JOptionPane.showMessageDialog(frm, "v1.2\n單機擲骰子","版本", JOptionPane.INFORMATION_MESSAGE);
		}
		else if(mi==authorMi){
			JOptionPane.showMessageDialog(frm, "Andy\n座右銘:勤耕不輟,方得始終!","作者", JOptionPane.INFORMATION_MESSAGE);
		}
	}
}
package cgame;
import java.awt.*;
import java.awt.event.*;
public class TextToLabel implements ActionListener {

	TextField txt1;
	Label Lab1;
	TextArea ta;
	//構造方法要將事件源文字框傳過來
	public TextToLabel(TextField txt1,Label Lab1,TextArea ta){
		this.txt1=txt1;
		this.Lab1=Lab1;
		this.ta=ta;
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO 自動生成的方法存根
		String word=txt1.getText();//獲得輸入文字
		Lab1.setText(word);
		ta.append(word+'\n');
		System.out.println(word);
	}

}
//*********************************************************
//伺服器端
package sgame;
import java.awt.*;
import java.awt.event.*;
public class DicGame implements ActionListener {

	Label lab1;
	TextArea ta;
	TextField txt2;
	Button btn0,btn1;
	static int money=1000;//初始金額
	public DicGame(TextField txt2,Label lab1,Button btn0,Button btn1,TextArea ta){
		this.lab1=lab1;
		this.txt2=txt2;
		this.btn0=btn0;
		this.btn1=btn1;
		this.ta=ta;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO 自動生成的方法存根
		
		//showLabel(changeChar(money),ta);//顯示初始金額
		int diceNum=0;
		int type=0;
		//判斷押寶型別
		//獲得按鈕物件
		Button b=(Button)e.getSource();
		if(b==btn0)
			type=1;//1壓大
		else if(b==btn1)
			type=2;//2壓小
		int cMoney=changeInt();
		boolean success;
		//遊戲過程,應該是不需要死迴圈的
		//輸入非法,則程式直接完成了,GUI執行緒本身是死迴圈了,輸入正確執行else
		if(!checkCMoney(money,cMoney)){
			showLabel("輸入非法",ta);
		}
		//輸入有效後,開始擲骰子
		else {
			diceNum=doDice();//擲骰子
			//判斷勝負
			success=isSuccess(type,diceNum);
			//金錢變化
			money=changeMoney(money,success,cMoney);
			//遊戲結束
			if(money<=0){
				showLabel("請充值!",ta);
			}
		}
			

	}
	//定義一個將整形轉換為字串的函式
	public String changeChar(int i){
		return Integer.toString(i);
	}
	//將字串在多行文字上顯示
	public void showLabel(String s,TextArea ta){
		ta.append(s+'\n');
	}
	//將文字框獲得內容轉為整形數
	public int changeInt(){
		String s=txt2.getText();
		return Integer.parseInt(s);
	}
	//判定下注金額是否非法
	public static boolean checkCMoney(int money,int cMoney){
		
		if(cMoney<=0)
			return false;
		else if(cMoney<=money)
			return true;
		else
			return false;
	}
	//擲骰子,返回點數和
	public static int doDice(){
		int n=(int)(Math.random()*6)+1;
		int n1=(int)(Math.random()*6)+1;
		int n2=(int)(Math.random()*6)+1;
		return n+n1+n2;
	}
	//勝負判斷
	public  boolean isSuccess(int type,int diceNum){
		//計算莊家型別
		int bankerType=0;
		if(diceNum<=9){
			bankerType=2;
		}else{
			bankerType=1;
		}
		if(bankerType==type){
			showLabel("贏",ta);
			return true;
		}
		else{
			showLabel("輸",ta);
			return false;
		}
	}
	//金錢變化
	public int changeMoney(int money,boolean success,int cMoney){
		if(success){
			money+=cMoney;
		}else{
			money-=cMoney;
		}
		showLabel("當前金錢:",ta);
		showLabel(changeChar(money),ta);
		return money;
	}
}
package sgame;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
public class LogicThread extends Thread {
	Socket socket;
	TextArea ta;
	InputStream is;
	OutputStream os;
	int dicNum,result,nowMoney;//返回結果為result nowMoney
	public LogicThread(Socket socket,TextArea ta){
		this.socket=socket;
		this.ta=ta;
		start();
	}
	public void run(){
		byte[]b=new byte[1024];
		try{
			//得到連線中的輸入輸出流
			os=socket.getOutputStream();
			is=socket.getInputStream();
			//讀取資料
			int n=is.read(b);
			//邏輯處理
			String str=sHandle(b,n);//n代表實際讀取位元組數
			//傳送str內容
			os.write(str.getBytes());
			ta.append("&&&&&&&&");
			ta.append(str);
			System.out.println("&*&*&*執行緒到這裡就該結束了");
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			close();
		}
	}
	//關閉流和連線
	private void close(){
		try{
			//關閉流和連線
			System.out.println("&*&*&*&*&*");
			os.close();
			is.close();
			socket.close();
		}catch(Exception e){}
	}
	//邏輯處理函式
	String sHandle(byte[] b,int n){
		//首先要將b陣列解析出來
		String str=new String(b,0,n);//將位元組陣列轉換為字串
		ta.append(str+'\n');
		StringTokenizer ad=new StringTokenizer(str," ");//空格分隔
		String str1=ad.nextToken();//實際則代表了客戶端發來的壓大小資訊
		String str2=ad.nextToken();//代表客戶所押金額
		ta.append("********");
		ta.append(str1+'\n');
		ta.append(str2+'\n');
		//判斷客戶所押為大還是小,並得到押注金額,將字串轉變為整型數
		int type=Integer.parseInt(str1);
		int cMoney=Integer.parseInt(str2);
		System.out.println(type);
		System.out.println(cMoney);
		ta.append("*********");
		//判斷押注金額是否非法,呼叫DicGame類中的靜態變數和方法
		boolean success;
		System.out.println("靜態變數金錢:"+DicGame.money);
		if(!DicGame.checkCMoney(DicGame.money,cMoney)){
			ta.append("輸入非法");//將字串在多行文字空間中顯示
			result=0;
			nowMoney=DicGame.money;
			}
			else{//輸入有效開始判斷大小
				dicNum=DicGame.doDice();
				//判斷勝負
				success=isSuccess(type,dicNum);
				//金錢變化,這裡金錢使用的是靜態變數,但是還是值傳遞的方式,
				//每次不管怎麼變,原來的靜態變數沒有變,所以總是以1000為基準
				nowMoney=changeMoney(DicGame.money,success,cMoney);
				//遊戲結束
				if(nowMoney<=0)
					ta.append("請充值!\n");
			}
		//遊戲至此就已經完成,轉換要返回的資料並返回
		return Integer.toString(result)+" "+Integer.toString(nowMoney);
		
	}
	//勝負判斷
		public  boolean isSuccess(int type,int dicNum){
			//計算莊家型別
			int bankerType=0;
			if(dicNum<=9){
				bankerType=0;
			}else{
				bankerType=1;
			}
			if(bankerType==type){
				ta.append("贏\n");
				result=1;
				return true;
			}
			else{
				ta.append("輸\n");
				result=0;
				return false;
			}
		}
		//金錢變化
		public int changeMoney(int money,boolean success,int cMoney){
			if(success){
				money+=cMoney;
			}else{
				money-=cMoney;
			}
			System.out.println("變化後的金錢:");
			System.out.println(money);
			ta.append("剩餘金錢:\n");;
			//將剩餘金錢轉換為字串並顯示
			ta.append(Integer.toString(money));
			DicGame.money=money;//金錢變化後,要修改基準值
			return money;
		}
}
package sgame;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JOptionPane;

public class MenuUI implements ActionListener {
		MenuItem versionMi;
		MenuItem authorMi;
		Frame frm;
	public MenuUI(Frame frm){
		this.frm=frm;//傳遞框架物件,不然彈出對話方塊的時候,找不到依賴對話方塊
		MenuBar bar=new MenuBar();//建立選單欄
		//建立選單
		Menu fileMenu=new Menu("檔案");
		Menu helpMenu=new Menu("幫助");
		Menu aboutMenu=new Menu("關於");
		//建立選單項
		MenuItem openMi=new MenuItem("開啟");
		MenuItem printMi=new MenuItem("列印");
		MenuItem exitMi=new MenuItem("退出");
		MenuItem helpMi=new MenuItem("幫助");
		versionMi=new MenuItem("版本");
		authorMi=new MenuItem("作者");
		//新增到選單
		fileMenu.add(openMi);
		fileMenu.add(printMi);
		fileMenu.add(exitMi);
		aboutMenu.add(versionMi);
		aboutMenu.add(authorMi);
		helpMenu.add(helpMi);
		helpMenu.add(aboutMenu);
		//新增到選單欄
		bar.add(fileMenu);
		bar.add(helpMenu);
		//設定選單欄
		frm.setMenuBar(bar);
		//註冊同一個監聽器,方法內部判斷髮生事件的選單項,然後進行不同的邏輯處理 
		versionMi.addActionListener(this);
		authorMi.addActionListener(this);
	}
	public void actionPerformed(ActionEvent e){
		//獲得發生事件的控制元件
		MenuItem mi=(MenuItem)e.getSource();
		//判斷,彈出有模式對話方塊
		if(mi==versionMi){
			JOptionPane.showMessageDialog(frm, "v1.2\n單機擲骰子","版本", JOptionPane.INFORMATION_MESSAGE);
		}
		else if(mi==authorMi){
			JOptionPane.showMessageDialog(frm, "Andy\n座右銘:勤耕不輟,方得始終!","作者", JOptionPane.INFORMATION_MESSAGE);
		}
	}
}
package sgame;
import java.awt.*;
import java.net.*;
import java.awt.event.*;

public class ServiceGame extends Frame implements WindowListener{
	
	static public TextArea ta;//設定為公共屬性,大家都可以呼叫來顯示提示資訊
	public ServiceGame(){
		super("骰子游戲服務端");
		MenuUI bar=new MenuUI(this);//設定框架選單欄
		//註冊時間監聽//第一個this表示自己,給自己註冊監聽器,是誰,還是自己(第二個this)
		//註冊監聽器的意思就是說,被監聽物件有動作時,自動執行監聽器的對應函式
		this.addWindowListener(this);
		//設定主介面
		initUI();
		this.setSize(400,400);
		this.setVisible(true);
	}
	private void initUI(){
		//初始化上部
		Panel pNorth=initNorth();
		this.add(pNorth,BorderLayout.NORTH);
		//初始化右側
		Panel pEast=initEast();
		this.add(pEast, BorderLayout.EAST);
		//初始化中部
		Panel pCenter=initCenter();
		this.add(pCenter, BorderLayout.CENTER);
	}
	//初始化上部函式,返回上部面板
	private Panel initNorth(){
		Panel p=new Panel();//新建一個面板物件
		//設定佈局管理器
		BorderLayout b1=new BorderLayout();
		p.setLayout(b1);
		//建立控制元件
		Label lbTitle=new Label("歡迎加入骰子大戰");
		//新增一個多行文字空間
		ta=new TextArea();//換成類屬性,這個每個版塊都可以呼叫了
		ta.append("系統提示資訊:\n");
		ta.append("初始金錢:1000\n");
		//設定不可編輯
		ta.setEditable(false);
		//新增到容器
		p.add(lbTitle,BorderLayout.NORTH);
		p.add(ta,BorderLayout.CENTER);
		//設定背景色
		p.setBackground(Color.GRAY);
		return p;
	}
	//初始化右側函式,返回右側面板
	private Panel initEast(){
		Panel p=new Panel();
		//設定佈局管理器為邊界式
		BorderLayout bl=new BorderLayout();
		p.setLayout(bl);
		//建立控制元件
		Label lbTitle=new Label("當前線上:");
		List listUser=new List();
		listUser.add("所有人");
		listUser.add("Tom");
		listUser.add("Mike");
		//新增控制元件到容器
		p.add(lbTitle, BorderLayout.NORTH);
		p.add(listUser,BorderLayout.CENTER);
		//設定背景色
		p.setBackground(Color.CYAN);
		return p;
	}
	//初始化中部函式,返回中部面板
	private Panel initCenter(){
		Panel p=new Panel();
		//設定佈局管理器
		GridLayout gl=new GridLayout(4,4);
		p.setLayout(gl);
		//建立控制元件物件,並依次新增
		String[] content={
				"Txt1","Txt2","Txt3","Txt4",
				"Label1","Label2","Label3","Label4",
				"Label5","Label6","Label7","Label8",
				"壓大","壓小","Button3","Button4",
		};
		//為了方便呼叫標籤元件,構造Label元件放在構造txt前面
			Label[] DicNum=new Label[8];
			int j=0;
			for(int i=4;i<12;i++,j++){
				DicNum[j]=new Label(content[i]);
				p.add(DicNum[j]);
			}
		//構造Txt元件
		TextField[] userIP=new TextField[4];
		for(int i=0;i<4;i++){
			userIP[i]=new TextField(content[i]);
			p.add(userIP[i]);
		}
		//註冊Text1的監視器,這裡實際是userIP[0]
		TextToLabel ttl=new TextToLabel(userIP[0],DicNum[0],ta);//將事件源文字框傳過去
		userIP[0].addActionListener(ttl);
		
		//構造 button元件
		j=0;
		Button[] btn=new Button[4];//這裡僅僅只是宣告,還不算初始化
		for(int i=12;i<16;i++,j++){
			btn[j]=new Button(content[i]);
			p.add(btn[j]);
		}
		//為壓大和壓小按鈕註冊監聽器,將標籤2,3,4和文字框1都傳過去,按鈕也要傳過去
		DicGame dg=new DicGame(userIP[1],DicNum[1],btn[0],btn[1],ta);
		btn[0].addActionListener(dg);
		btn[1].addActionListener(dg);
		
		return p;
	}
	public static void main(String[] args) {
		// TODO 自動生成的方法存根
		ServiceGame ss=new ServiceGame();//這一步只是生成了介面
		//就是說只是開啟了一個執行緒來做介面這件事情,主函式,也就是主執行緒,還要往下執行
		//System.out.println("hello");
		ServerSocket serverSocket=null;
		Socket socket=null;
		//監聽埠號
		int port=10000;
		try{
			//建立連線
			serverSocket=new ServerSocket(port);//監聽程式碼
			ta.append("伺服器已啟動\n");
			int i=1;
			while(i>0){
				//獲得連線到伺服器端的客戶端連線,釋放伺服器埠,擁塞方法
				socket=serverSocket.accept();
				//啟動執行緒
				System.out.println("執行緒開始");
				LogicThread tt=new LogicThread(socket,ta);
				System.out.println("第"+i+"次迴圈");
				i++;
				System.out.println("執行緒結束了!");
				
			}
	}catch(Exception e){
		e.printStackTrace();
	}finally{
		try{
			//關閉連線
			serverSocket.close();
		}catch(Exception e){}
	}
}
	@Override
	public void windowActivated(WindowEvent arg0) {
		// TODO 自動生成的方法存根
		
	}
	@Override
	public void windowClosed(WindowEvent arg0) {
		// TODO 自動生成的方法存根
		
	}
	@Override
	public void windowClosing(WindowEvent arg0) {
		// TODO 自動生成的方法存根
		System.exit(0);
		
	}
	@Override
	public void windowDeactivated(WindowEvent arg0) {
		// TODO 自動生成的方法存根
		
	}
	@Override
	public void windowDeiconified(WindowEvent arg0) {
		// TODO 自動生成的方法存根
		
	}
	@Override
	public void windowIconified(WindowEvent arg0) {
		// TODO 自動生成的方法存根
		
	}
	@Override
	public void windowOpened(WindowEvent arg0) {
		// TODO 自動生成的方法存根
		
	}
	

}
package sgame;
import java.awt.*;
import java.awt.event.*;
public class TextToLabel implements ActionListener {

	TextField txt1;
	Label Lab1;
	TextArea ta;
	//構造方法要將事件源文字框傳過來
	public TextToLabel(TextField txt1,Label Lab1,TextArea ta){
		this.txt1=txt1;
		this.Lab1=Lab1;
		this.ta=ta;
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO 自動生成的方法存根
		String word=txt1.getText();//獲得輸入文字
		Lab1.setText(word);
		ta.append(word+'\n');
		System.out.println(word);
	}

}