展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > java如何实现联机五子棋

java如何实现联机五子棋

下面是客户端运行的效果:这里是代码包的结构:接着我来依次说下这些类所完成的功能Media包Media包:主要是放了五子棋的背景图片和播放音乐的类以及音乐内容播放音乐这个类是我从室友那拿的,所以我也不是很懂,瞄了一眼是用Applet完成的,只能处理.wav后缀的音乐Net包Net包:包含两个类,细心的小伙伴应该注意到客户端是没有主方法的。客户端中其实是包含与服务端进行通信的socket的,其中包含一些读和写的方法。服务端我采用的是线程池的方法来处理客户端的请求(线程池这部分我也不是特别了解,用起来和多线程感

本文目录

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

    java如何实现联机五子棋

    这里是代码包的结构:

    java如何实现联机五子棋

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

    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 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 list; // 客户端线程集合
        private ObjectOutputStream oos;
        private ObjectInputStream ois;
        private boolean flag = true;// 标记
     
        public UserThread(Socket socket, ArrayList list) {
            this.socket = socket;
            this.list = list;
            list.add(this); // 把当前线程加入list中
        }
     
        @Override
        public void run() {
            UserThread user = null;
            try {
                System.out.println("客户端:" + socket.getInetAddress().getHostAddress() + "已经连接");
                ois = new ObjectInputStream(socket.getInputStream());
                oos = new ObjectOutputStream(socket.getOutputStream());
                while(true){
                    Pieces pieces = (Pieces) ois.readObject(); // 客户端发给服务端的消息,把他写到其它套接字中去
                    int size = list.size();
                    for (int i = 0; i < size; i++) {
                        user = list.get(i);
                        if (user.socket != socket) {
                            user.oos.writeObject(pieces);
                            System.out.println("从"+socket+"向"+user.socket+"发送消息");
                        }
                    }
                }
            } catch(SocketException e){ //  todo 客户端掉线后,移除客户端。没想好{1.从客户端列表移除当前元素,关闭当前:socket,通知另一方:这一方已经掉线,然后关闭这一方的socket}
                try {
                    int i = list.size();
                    if (i ==2){
                        list.remove(user);
                        System.out.println("已经删除了一个客户端");
                        list.get(0).oos.writeObject(new Pieces("对方掉线"));
                    }else if (i==1){
                        list.remove(0);
                        System.out.println("又移除了另一个客户端");
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    ChessBoard:

    /*
    * 1.变量值不变的问题
    * 2.输入输出流先后顺序的问题(socket阻塞)
    * 3.socket 短连接不关闭输入输出流,为何看起来就像长连接一样(长短连接的区别是什么)
    * */
    // todo 一个提示框
    package view;
    import Media.Music.PlayMusic;
    import javax.sound.sampled.LineUnavailableException;
    import javax.sound.sampled.UnsupportedAudioFileException;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    public class ChessBoard extends JFrame implements ActionListener {
        private JButton PlayMusic = new JButton("播放音乐");
        private ChessPanel chessPanel;
        private Panel CommandPanel = new Panel();
        private JButton reStart = new JButton("重新开始");
        private JButton fail = new JButton("认输");
        private JButton Regret = new JButton("悔棋");
        private String command=null; // 触发按钮后发送的命令
        private PlayMusic music = null;
        private int count = 1;
        //  todo 静态语句块
        {
            try {
                music = new PlayMusic("./src/Media/Music/bg3.wav");
            } catch (LineUnavailableException e) {
                e.printStackTrace();
            } catch (UnsupportedAudioFileException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     
        public ChessBoard() {
            this.setTitle("欢乐五子棋");
            chessPanel = new ChessPanel();
            this.add(chessPanel,BorderLayout.CENTER);
            reStart.addActionListener(this);
            fail .addActionListener(this);
            Regret.addActionListener(this);
            PlayMusic.addActionListener(this);
            CommandPanel.add(reStart);
            CommandPanel.add(fail);
            CommandPanel.add(Regret);
            CommandPanel.add(PlayMusic);
            this.add(CommandPanel,BorderLayout.SOUTH);
            this.setBounds(10, 10, 800, 800);
            this.setVisible(true);
            this.setResizable(false);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
        public static void main(String[] args) {
            ChessBoard Board = new ChessBoard();
     
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            if(e.getSource()==reStart){
                command ="重新开始";
                chessPanel.canPlay = true;
            }else if(e.getSource()==fail){
                command ="认输";
                JOptionPane.showMessageDialog(chessPanel,"It's a pity,you have fail the game!");
                chessPanel.canPlay = false;
            }else if (e.getSource()==Regret){
                command ="悔棋";
            }else if (e.getSource()==PlayMusic){
                // todo 播放音乐,单数次播放;
                if (count%2==1){
                    music.play();
                }else {
                    music.stop();
                }
                count++;
                command = null;
            }
            if(command!=null){
                Pieces pieces = new Pieces(command);
                try {
                    this.chessPanel.client.send(pieces);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
     
        }
    }

    ChessPanel:

    package view;
    // 五子棋面板,就是在这里面画图。
    // todo 背景图片 ,也许一个背景音乐
    import net.TcpClient;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.ConnectException;
    import java.net.Socket;
    import java.util.ArrayList;
    import java.util.Iterator;
    public class ChessPanel extends JPanel implements MouseListener{
        // TODO 从服务器接收来的棋子 ,值不变有问题
    //   Pieces accept_pieces = new Pieces();
    //   Pieces send_pieces = new Pieces();
        whoWin ifWin =new whoWin() ; // 是否胜利
        TcpClient client = null; // 客户端
        boolean canPlay = true; // 是否能继续玩
        boolean isBlack = true; // 是否黑子,黑1,白2
        ArrayList allPieces = new ArrayList<>(); // 存储棋子对象,就是通过这个画图的
        int [][] allChess = new int[19][19];
        int PanelWidth;
        int PanelHeight;
        int width = 600;
        int height = 600;
        int temp = width / 18;
        int xbase,ybase;
        Image image = Toolkit.getDefaultToolkit().getImage("./src/Media/bg.jpeg"); // "./"表示当前项目下
        public ChessPanel(){
            this.addMouseListener(this);
            try {
                Socket socket = new Socket("172.27.29.190", 10086);
                //TODO 构建输出输入流,输入输出流问题,先输出后输入
                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                client = new TcpClient(socket,ois,oos);
                new Thread(new getMessage()).start(); // 开启读取的线程
            } catch (ConnectException e){
                System.out.println("服务器拒绝连接!");
            } catch (IOException e) {
                e.printStackTrace();
            }catch(Exception e ){
                e.printStackTrace();
            }
        }
        // 画图部分
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            PanelWidth = this.getSize().width; // 这两步骤
            PanelHeight = this.getSize().height;
            xbase = (PanelWidth - width) / 2;
            ybase = (PanelHeight - height) / 2;
            Graphics2D g2d = (Graphics2D) g;
    //        this.setBackground(new Color(246, 186, 114));
            g2d.drawImage(image,0,0,this.getWidth(),this.getHeight(),this);
            int x1, y1, x2, y2;
            // 画线
            for (int i = 0; i < 19; i++) {
                if (i == 0 || i == 18) {
                    g2d.setStroke(new BasicStroke(3.0f));
                } else g2d.setStroke(new BasicStroke(1.0f));
                x1 = xbase + temp * i;
                y1 = ybase;
                y2 = ybase + 18 * temp;
                g2d.drawLine(x1, y1, x1, y2);
                x1 = xbase;
                y1 = ybase + temp * i;
                x2 = xbase + temp * 18;
                g2d.drawLine(x1, y1, x2, y1);
            }
            // 开始画棋子
            int radius ;
            int xPos,yPos;
            Iterator it = allPieces.iterator(); // 迭代器遍历arraylist
            while(it.hasNext()){
                Pieces pieces = (Pieces) it.next();
                radius  = pieces.getRadius();
                xPos = pieces.getxPos();
                yPos = pieces.getyPos();
                System.out.println(pieces.getColor()+","+pieces.getxPos()+","+pieces.getyPos());
                if (pieces.getColor() == 1){
                    g2d.setColor(Color.black);
                    g2d.fillOval(xPos*temp+xbase-radius/2,yPos*temp+ybase-radius/2,radius,radius);
                }
                else if (pieces.getColor() == 2) {
                    g2d.setColor(Color.white);
                    g2d.fillOval(xPos * temp + xbase - radius / 2, yPos * temp + ybase - radius / 2, radius, radius);
                }
            }
     
        }
     
        @Override
        public void mousePressed(MouseEvent e) {
            int x ,y ;
            if (canPlay) {
                x = e.getX();
                y = e.getY();
                //  判断鼠标点击位置
                if (x >= xbase & x <= (xbase + 18 * temp) & y >= ybase & y < (ybase + 18 * temp)) {
                    // 判断是不是下在空的位置
                    int tempX = (x - xbase) / temp, tempY = (y - ybase) / temp;
                    // todo 这里是关键判断这点坐标的数组下标是什么
                    if ((x - xbase) % temp > temp / 2) {
                        x = tempX + 1;
                    } else
                        x = tempX;
                    if ((y - ybase) % temp > temp / 2)
                        y = tempY + 1;
                    else
                        y = tempY;
                    // 先判断有没有棋子,处理没有棋子的情况
                    if (allChess[x][y] != 0) {
                           JOptionPane.showMessageDialog(this, "这里有棋子了");
                    } else {
                        Pieces send_pieces = new Pieces();
                        send_pieces.setxPos(x);
                        send_pieces.setyPos(y);
                        if (isBlack){
                            send_pieces.setColor(1);
                            allChess[x][y] = 1;
                            isBlack = false;
                        }
                        else{
                            send_pieces.setColor(2);
                            allChess[x][y]=2;
                            isBlack = true;
                        }
                        allPieces.add(send_pieces); // 向棋子队列加入当前棋子
                        canPlay = false;// canPlay在true情况下, 点击一次后不能点击了
                        this.repaint();
                        ifWin = new whoWin(allChess,x,y);
                        // 如果赢了,就不能玩了,并且给出提示消息,你赢了;
                        if(ifWin.isWin()){
                            canPlay = false;
                            JOptionPane.showMessageDialog(this,"Congratulations you have won tha game !");
                        }
                        try {
                            if (client!=null){
                                client.send(send_pieces);
                            }
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }
                    }
                }
     
            }
        }
     
        // 读取来自服务器端的信息
        class getMessage implements Runnable{
            private boolean flag = true;
            public void setFlag(boolean flag) {
                this.flag = flag;
            }
     
            @Override
            public void run() {
                // 循环读
                while(flag){
                    if(client!=null){
                        try {
                            Pieces accept_pieces = client.accept();
                            String command = accept_pieces.getCommand();
                            int color = accept_pieces.getColor();
                            switch (command){
                                case "发送":{
                                    canPlay = true;
                                    if (color == 1){
                                        isBlack = false;//对方为黑我为白
                                    }else{
                                        isBlack = true;
                                    }
                                    allPieces.add(accept_pieces);
                                    allChess[accept_pieces.getxPos()][accept_pieces.getyPos()]= accept_pieces.getColor();
                                    ChessPanel.this.repaint();
                                    ifWin.setY(accept_pieces.getyPos());
                                    ifWin.setX(accept_pieces.getxPos());
                                    ifWin.setAllChess(allChess);
                                    if(ifWin.isWin()){
                                        canPlay = false;
                                        JOptionPane.showMessageDialog(ChessPanel.this,"It's a pity you have fail the game!");
                                    }
                                    break;
                                }
                                case "悔棋":{
                                    int i = JOptionPane.showConfirmDialog(ChessPanel.this,"对方请求悔棋,是否同意!");
                                    // yes 0,no 1,cancel 2,closed -1
                                    Pieces pieces = new Pieces();
                                    if (i == 0){
                                        // 同意悔棋:1.同意对方悔棋
                                        pieces.setCommand("同意悔棋");
                                        // arraylist 去除末尾的两个值,对应allChess置0
                                        int size = allPieces.size();
                                        for (int j = 1;j<=2;j++){
                                            allChess[allPieces.get(size-j).getxPos()][allPieces.get(size-j).getyPos()]=0;
                                            allPieces.remove(size-j);
                                        }
                                        ChessPanel.this.repaint();
                                    }else if(i==1){
                                        pieces.setCommand("不同意悔棋");
                                    }
                                    client.send(pieces);
                                    break;
                                }
                                case "认输":{ // 不能继续玩下去,你已经胜利
                                    JOptionPane.showMessageDialog(ChessPanel.this,"对方认输");
                                    canPlay = false;
                                    JOptionPane.showMessageDialog(ChessPanel.this,"Congratulations you have won tha game !");
                                    break;
                                }
                                case "重新开始":{ // 是否同意重新开始
                                   int i = JOptionPane.showConfirmDialog(ChessPanel.this,"对方请求重新开始,是否同意");
                                    Pieces pieces = new Pieces();
                                    if(i == 0){// allChess 和 allPieces全部置0;
                                        pieces.setCommand("同意重新开始");
                                        int size = allPieces.size();
                                        System.out.println("arraylist 长度:"+size);
                                        for (int j = 0;j

    Pieces:

    package view;
     
    import java.io.Serializable;
    // 存储棋子的相关信息
    public class Pieces implements Serializable {
        private int radius = 16;
        private int color = 0;
        private int xPos ;
        private int yPos;
        private String command = "发送";
        public String getCommand() {
            return command;
        }
     
        public void setCommand(String command) {
            this.command = command;
        }
     
        public Pieces(int color, int xPos, int yPos){
            this.color = color;
            this.xPos = xPos;
            this.yPos = yPos;
        }
        public Pieces(){
     
        }
        public Pieces(String command){
            this.command = command;
        }
        public int getRadius() {
            return radius;
        }
     
        public void setRadius(int radius) {
            this.radius = radius;
        }
     
        public int getColor() {
            return color;
        }
     
        public void setColor(int color) {
            this.color = color;
        }
     
        public int getxPos() {
            return xPos;
        }
     
        public void setxPos(int xPos) {
            this.xPos = xPos;
        }
     
        public int getyPos() {
            return yPos;
        }
     
        public void setyPos(int yPos) {
            this.yPos = yPos;
        }
    }

    WhoWin:

    package view;
    public class whoWin { // 判断是谁赢了
        private int allChess[][] = new int[19][19];
        private int x = 0;
        private int y = 0;
        public whoWin(){
     
        }
        public whoWin(int allChess[][],int x,int y){
            this.allChess = allChess;
            this.x = x;
            this.y = y;
        }
     
        public void setAllChess(int allChess[][]){
            this.allChess = allChess;
        }
        public void setX(int x){
            this.x = x;
        }
        public void setY(int y ){
            this.y = y;
        }
        public boolean isWin() {
            int color = allChess[x][y];
            int count;
            count = this.Count(1, 0, color); // 对横方向的判断
            if (count >= 5) {
                return true;
            } else {
                count = this.Count(0, 1, color); // 对竖方向的判断
                if (count >= 5) {
                    return true;
                } else {
                    count = this.Count(1, 1, color); // 对左上方向的判断
                    if (count >= 5)
                        return true;
                    else {
                        count = this.Count(1, -1, color); // 对右上方向的判断
                        if (count >= 5)
                            return true;
                    }
                }
            }
            return false;
        }
        private int Count(int xChange, int yChange, int color) {
            int count = 1;
            int tempX = xChange, tempY = yChange;
            while (color == allChess[x + xChange][y + yChange]) {
                count++;
                if (xChange != 0) {
                    xChange++;
                }
                if (yChange != 0) {
                    if (yChange > 0)
                        yChange++;
                    else
                        yChange--;
                }
            }
            xChange = tempX;
            yChange = tempY;
            while (color == allChess[x - xChange][y - yChange]) {
                count++;
                if (xChange != 0)
                    xChange++;
                if (yChange != 0) {
                    if (yChange > 0)
                        yChange++;
                    else
                        yChange--;
                }
            }
            return count;
        }
    }
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirServer Windows版
    AirServer Windows版

    AirServer Windows版可把电脑变成AirPlay、Google Cast和Miracast无线投屏接收端,适合会议演示、课堂教学及家庭大屏分享。发送设备通常无需另装客户端,并可同时接收和智能排列多个镜像会话。