Java联机五子棋

在完成java单机五子棋后,我开始尝试写联机五子棋(局域网内,因为没有公网IP)。上次的五子棋写的很乱,全部写在一个类中,这次我采用面向对象的思想,把特定的功能和属性都写成一个类。代码分为两部分,客户端和服务端。客户端是用AWT写的,主要由一个五子棋面板和一个功能键面板构成。网络通信使用的是TCP,通过序列化和反序列化完成消息的读和写。运行的时候先运行服务端程序,接着运行两个客户端。代码放在了文章的最后

下面是客户端运行的效果: 

这里是代码包的结构:

接着我来依次说下这些类所完成的功能

Media包

Media包:主要是放了五子棋的背景图片和播放音乐的类以及音乐内容

播放音乐这个类是我从室友那拿的,所以我也不是很懂,瞄了一眼是用Applet完成的,只能处理.wav后缀的音乐

Net包

Net包:包含两个类,细心的小伙伴应该注意到客户端是没有主方法的。客户端中其实是包含与服务端进行通信的socket的,其中包含一些读和写的方法。服务端我采用的是线程池的方法来处理客户端的请求(线程池这部分我也不是特别了解,用起来和多线程感觉差不多)。

View包

View包:包含四个类,分别是ChessBoard,ChessPanel,Pieces和WhoWin 类

ChessBoard是一个包含Main方法的JFrame,命令面板和棋盘面板都是添加到这个JFrame中的。

ChessPanel是一个棋盘面板,里面完成了如:画19*19的棋盘线条,加载背景图片,不停的接收来自服务端的消息并处理(把棋子加到面板),处理每次点击后添加棋子到面板并发送棋子到服务器,判断胜负并且给出提示消息。

Pieces是一个棋子,其中有包含如颜色,棋子半径,棋子位置和命令(和前面的命令面板配合使用,默认是发送)等属性。

WhoWin就是五子棋中判断谁输谁赢的部分。每下一步就需要判断。


播放音乐的类:

package Media.Music;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class PlayMusic {
    private Clip clip;
    public PlayMusic(String filePath) throws LineUnavailableException, UnsupportedAudioFileException, IOException {
        File file = new File(filePath);
        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);
        clip = AudioSystem.getClip();
        clip.open(audioInputStream);
    }

    public void play() {
        clip.setFramePosition(1);
        clip.start();
    }

    public void loop() {
        clip.loop(Clip.LOOP_CONTINUOUSLY);
    }
    public void stop() {
        clip.stop();
    }
}

TcpClient:

package net;
import view.Pieces;
import java.io.*;
import java.net.Socket;
public class TcpClient{
    private Socket socket;
    private ObjectInputStream ois;
    private ObjectOutputStream oos;
    public TcpClient(Socket socket,ObjectInputStream ois,ObjectOutputStream oos){
        this.socket= socket;
        this.ois = ois;
        this.oos = oos;
    }
    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    public ObjectInputStream getOis() {
        return ois;
    }

    public void setOis(ObjectInputStream ois) {
        this.ois = ois;
    }

    public ObjectOutputStream getOos() {
        return oos;
    }

    public void setOos(ObjectOutputStream oos) {
        this.oos = oos;
    }

    public void send(Pieces pieces) throws IOException {
        oos.writeObject(pieces);
        System.out.println(socket+"向服务器发送消息");
    }
    public Pieces accept() throws IOException, ClassNotFoundException {
        Pieces pieces = (Pieces) ois.readObject();
        System.out.println(socket+"从服务器读取消息");
        return pieces;
    }
    public void close(){
        ;
    }
}

TcpServer:

package net;
import view.Pieces;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TcpServer {
    public static void main(String[] args) {
        // 保存客户端处理的线程
        ArrayList<UserThread> userList = new ArrayList<>();
        // 固定大小的线程池只支持两个线程,用来处理客户端
        ExecutorService es = Executors.newFixedThreadPool(2);
        try {
            ServerSocket server = new ServerSocket(10086);
            System.out.println("服务器已经启动,正在等待客户端连接......");
            while (true) {
                //接收客户端的Socket,如果没有客户端连接就一直卡在这里
                Socket socket = server.accept();
                // 每来一个用户就创建一个线程
                UserThread user = new UserThread(socket, userList);
                // 开启线程
                es.execute(user);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class UserThread implements Runnable {
    private Socket socket = null;
    private static ArrayList<UserThread> list; // 客户端线程集合
    private ObjectOutputStream oos;
    private ObjectInputStream ois;
    private boolean flag = true;// 标记

    public UserThread(Socket socket, ArrayList<UserThread> list) {
        this.socket = socket;
        this.list = list;
        list.add(this); // 把当前线程加入l
  • 11
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值