📄 clientapplet.java
字号:
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Color;
import javax.swing.JLabel;
import java.awt.Image;
import javax.swing.ImageIcon;
import java.awt.Toolkit;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.MediaTracker;
import java.net.Socket;
import java.io.PrintStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.net.UnknownHostException;
import java.io.IOException;
import java.util.StringTokenizer;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import javax.swing.JOptionPane;
import java.awt.GridLayout;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JScrollBar;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.net.URL;
public class ClientApplet extends JApplet{
JPanel jPane=new JPanel();
//
Image tableImage,manImage,meImage;
Cursor meCursor; //主人光标
LoginPane[] loginPane=new LoginPane[2]; //初始化两张台,台号从0开始编号.
//
int win_w;
int win_h;
//
int serverInPort=6817; //服务器的输入端口号
int serverOutPort=6818; //服务器的输出端口号
String serverName; //服务器名字
Socket outSocket; //客户端用于输出的socket套接字
Socket inSocket; //客户端用于输入的socket套接字
PrintStream writer; //客户端输出流
BufferedReader reader; //客户端输入缓冲流
//
ReadThread readThread; //客户端读数据线程
RefreshThread refreshThread; //客户端台面刷新线程
//
int currentTable=-1; //当前台号
int currentChair=-1; //当前坐椅号
//
int registerTable=-1; //正申请的台号
int registerChair=-1; //正申请的椅子号
//
PlayPane playPane; //对弈面板
public void init(){
win_w=getSize().width;
win_h=getSize().height;
//
MediaTracker tracker=new MediaTracker(this);
tableImage=getImage(getCodeBase(),"image/table.jpg");
tracker.addImage(tableImage,1);
manImage=getImage(getCodeBase(),"image/man.gif");
tracker.addImage(manImage,2);
meImage=getImage(getCodeBase(),"image/me.gif");
tracker.addImage(meImage,3);
Image curImage=getImage(getCodeBase(),"image/mecursor.jpg"); //光标图标
tracker.addImage(curImage,4);
try{
tracker.waitForAll(); //启动和等待图象加载完毕.
}catch(InterruptedException e){
System.out.println("加载图象文件失败");
}
//光标设置
meCursor=Toolkit.getDefaultToolkit().createCustomCursor(curImage,new Point(0,0),"me");
//
GridLayout gLayout=new GridLayout(2,1,0,5); //2行1列网格布局(垂直间隙为5)
jPane.setLayout(gLayout);
jPane.setBackground(Color.blue); //蓝色背景(实际使棋台之间的间隙为蓝色)
//
loginPane[0]=new LoginPane(0); //创建第1张棋台(索引号0)
jPane.add(loginPane[0]);
//
loginPane[1]=new LoginPane(1); //创建第2张棋台(索引号1)
jPane.add(loginPane[1]);
//
getContentPane().add(jPane);
//
serverName=getCodeBase().getHost();
try{
outSocket=new Socket(serverName,serverInPort); //注意客户端的out相当于服务器的in。
inSocket=new Socket(serverName,serverOutPort);
writer=new PrintStream(outSocket.getOutputStream());
reader=new BufferedReader(new InputStreamReader(inSocket.getInputStream()));
}catch(UnknownHostException e){
System.out.println("创建客户端socket失败.");
}catch(IOException e){
System.out.println("创建客户端输入输出流失败.");
}
//
readThread=new ReadThread(); //启动读数据线程
readThread.start();
//
refreshThread=new RefreshThread(); //启动刷新台面线程
refreshThread.start();
}
public void destroy(){ //applet被摧毁
writer.println("exit:"+currentTable+","+currentChair); //向服务器发送退出信息
refreshThread.refreshStop=true; //使刷新线程的内部循环立即终止
refreshThread=null; //停止刷新线程
try{
reader.close();
writer.close();
inSocket.close();
outSocket.close();
}catch(IOException e){}
readThread=null; //停止读数据线程
}
//游戏台类
class LoginPane extends JPanel implements ActionListener{
ChairButton[] chairButton=new ChairButton[2]; //充当椅子的按钮
JLabel[] imageLabel=new JLabel[2]; //显示人员坐姿的图片标签
JButton playButton=new JButton("开始对弈");
JLabel tableLabel=new JLabel(new ImageIcon(tableImage)); //显示棋桌的图片标签
LoginPane(int tableNum){
setBackground(Color.green); //绿色背景
setLayout(null);
chairButton[0]=new ChairButton(tableNum,0); //从0开始编号
chairButton[0].setText("上方座位");
chairButton[1]=new ChairButton(tableNum,1);
chairButton[1].setText("下方座位");
//
imageLabel[0]=new JLabel();
imageLabel[1]=new JLabel();
//
add(chairButton[0]);
add(imageLabel[0]);
add(chairButton[1]);
add(imageLabel[1]);
add(playButton);
add(tableLabel);
//
chairButton[0].setBounds(52,10,85,40);
imageLabel[0].setBounds(50,10,85,40);
chairButton[1].setBounds(52,160,85,40);
imageLabel[1].setBounds(50,160,85,40);
playButton.setBounds(154,70,85,40);
tableLabel.setBounds(40,58,105,93);
//
chairButton[0].setVisible(false);
chairButton[1].setVisible(false);
playButton.setEnabled(false);
//添加按钮鼠标单击事件监听器
chairButton[0].addActionListener(this);
chairButton[1].addActionListener(this);
playButton.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
Object srcObject=e.getSource();
if(srcObject==chairButton[0]){
registerTable=chairButton[0].tableNum; //记录申请的台号
registerChair=chairButton[0].chairNum; //记录申请的椅子号
writer.println("logout:"+currentTable+","+currentChair); //先注销上次占用的座位
writer.println("login:"+chairButton[0].tableNum+","+chairButton[0].chairNum); //申请该座位入坐
}
else if(srcObject==chairButton[1]){
registerTable=chairButton[1].tableNum; //记录申请的台号
registerChair=chairButton[1].chairNum; //记录申请的椅子号
writer.println("logout:"+currentTable+","+currentChair); //先注销上次占用的座位
writer.println("login:"+chairButton[1].tableNum+","+chairButton[1].chairNum); //申请该座位入坐
}
else if(srcObject==playButton){
writer.println("play!"); //向对方请求对弈
}
}
}
//椅子类
class ChairButton extends JButton{
int tableNum; //台号
int chairNum; //椅子号
ChairButton(int tNum,int cNum){
tableNum=tNum;
chairNum=cNum;
}
}
//游戏面板类
class PlayPane extends JPanel{
ChessPane chessPane=new ChessPane(); //棋盘面板
MsgPane msgPane=new MsgPane(); //聊天消息面板
ControlPane controlPane=new ControlPane(); //游戏控制面板
GridBagLayout gridBagLayout=new GridBagLayout(); //3行1列的网格包布局
GridBagConstraints gbc=new GridBagConstraints();
PlayPane(){
setLayout(gridBagLayout);
//添加棋盘面板
gbc.gridx=0;
gbc.gridy=0;
gbc.weightx=100;
gbc.weighty=60;
gbc.fill=GridBagConstraints.BOTH;
gridBagLayout.setConstraints(chessPane,gbc);
add(chessPane);
//添加聊天消息面板
gbc.gridx=0;
gbc.gridy=1;
gbc.weightx=100;
gbc.weighty=30;
gbc.fill=GridBagConstraints.BOTH;
gridBagLayout.setConstraints(msgPane,gbc);
add(msgPane);
//添加游戏控制面板
gbc.gridx=0;
gbc.gridy=2;
gbc.weightx=100;
gbc.weighty=10;
gbc.fill=GridBagConstraints.BOTH;
gridBagLayout.setConstraints(controlPane,gbc);
add(controlPane);
}
}
//棋盘面板类
class ChessPane extends JPanel implements MouseListener{ //棋盘面板
int chessBoard_w; //正方形棋盘宽度
int chessBoard_x; //棋盘的左上角位置坐标
int chessBoard_y;
int cell_w; //正方形棋盘方格宽度
boolean canGo=false; //可否走棋的标志
int[] chessOn=new int[9]; //记录棋盘9个格子落子情况(0--未落子,1自己落子,2对方落子).数组元素初始化后均为0.
//
Image ovalImage,crossImage; //显示在棋盘格中的圆形和交叉图象
ChessPane(){
chessBoard_w=160;
chessBoard_x=(win_w-chessBoard_w)/2;
chessBoard_y=30;
cell_w=chessBoard_w/3;
//
MediaTracker tracker=new MediaTracker(this);
ovalImage=getImage(getCodeBase(),"image/oval.gif");
tracker.addImage(ovalImage,1);
crossImage=getImage(getCodeBase(),"image/cross.gif");
tracker.addImage(crossImage,2);
try{
tracker.waitForAll(); //启动和等待图象加载完毕.
}catch(InterruptedException e){
System.out.println("加载图象文件失败");
}
//
addMouseListener(this);
}
public void paint(Graphics g){
Graphics2D g2D=(Graphics2D)g;
g2D.setBackground(Color.black); //只有Graphics2D提供了setBackground方法
g2D.clearRect(0,0,win_w,win_h);
g.setColor(Color.yellow);
g.drawRect(chessBoard_x,chessBoard_y,chessBoard_w,chessBoard_w);
for(int i=1;i<=2;i++){ //画棋盘中间的两条横线
g.drawLine(chessBoard_x,chessBoard_y+i*cell_w,chessBoard_x+chessBoard_w,chessBoard_y+i*cell_w);
}
for(int j=1;j<=2;j++){ //画棋盘中间的两条竖线
g.drawLine(chessBoard_x+j*cell_w,chessBoard_y,chessBoard_x+j*cell_w,chessBoard_y+chessBoard_w);
}
for(int m=1;m<=3;m++){ //判断是否绘制棋子
for(int n=1;n<=3;n++){ //第m行、第n列的棋格
if(chessOn[3*(m-1)+n-1]==1){ //自己落了棋子,显示一个圆形。
g.drawImage(ovalImage,chessBoard_x+(n-1)*cell_w,chessBoard_y+(m-1)*cell_w,this);
}
else if(chessOn[3*(m-1)+n-1]==2){ //对方落了棋子,显示一个交叉。
g.drawImage(crossImage,chessBoard_x+(n-1)*cell_w,chessBoard_y+(m-1)*cell_w,this);
}
}
}
}
public void mouseReleased(MouseEvent e){
if(canGo){ //是否可走棋
int x=e.getX();
int y=e.getY();
int cellIndex; //单击的棋格索引
cellIndex=inWhatCell(x,y); //取得落下的棋格
if(cellIndex!=-1 ){ //棋子落在棋盘内
if(chessOn[cellIndex]==0){ //该格还没有落子
canGo=false; //等待对方下子
chessOn[cellIndex]=1; //设置该棋格已落子(1表示自己落子,2表示对方落子.)
writer.println("go:"+cellIndex); //将该步棋发给对方显示出来
repaint(); //刷新棋盘面板
if(isChessOnLine()){ //3子同一线,自己嬴了.
writer.println("win:"+cellIndex); //发送自己嬴棋信息给服务器(转对弈方)
JOptionPane.showMessageDialog(null,"恭喜您,您嬴了对方!","系统提示",JOptionPane.INFORMATION_MESSAGE); //弹出提示对话框
playPane.controlPane.restartButton.setEnabled(true); //设置"重新对弈"按钮有效
}
else{ //当前并没有3子处于一条直线上(和或负)
if(isChessFull()){ //棋盘满了(双方都不能再下棋子),可断定双方打和.
writer.println("peace:"+cellIndex); //通知对方打和
JOptionPane.showMessageDialog(null,"双方打和,未分胜负.","系统提示",JOptionPane.INFORMATION_MESSAGE); //弹出提示对话框
playPane.controlPane.restartButton.setEnabled(true); //设置"重新对弈"按钮有效
}
}
}
}
}
}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mousePressed(MouseEvent e){}
public int inWhatCell(int x,int y){
int cell_x,cell_y; //第i行、第j列棋格的右下角坐标
for(int i=1;i<=3;i++){
for(int j=1;j<=3;j++){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -