`
nbtlxx
  • 浏览: 253247 次
  • 性别: Icon_minigender_1
  • 来自: 宁波
社区版块
存档分类
最新评论

手机网络象棋开发(5):客户端Game类、网络通讯类NetClient介绍

阅读更多
Game.java
继承midlet

* 游戏程序的入口
* 展示玩家列表playerList
* 初始化NetClient网络通信类
* 发送相关的命令:坐下、开始、结束等命令
* 更新玩家列表
* 启动mygameCanvas, 启动游戏的画布和逻辑处理

package newclient;

import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.List;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;


/**
 * 
 * @author sean
 * 游戏程序的入口
 * 展示玩家列表playerList
 * 初始化NetClient网络通信类
 * 发送相关的命令:坐下、开始、结束等命令
 * 更新玩家列表
 * 启动mygameCanvas, 启动游戏的画布和逻辑处理
 */
public class Game extends MIDlet implements CommandListener {
	private NetClient client;
	public static Display display;
	private MyGameCanvas canvas;
	private List playerList;
	private int[][] desks;
	private int trySeat, tryDesk;
	private Command okCommand;
	
	public static int playerId = 0;
	
	/**
	 * 构造方法
	 * 画出第一个界面,玩家列表
	 * 初始化网络通信对象
	 */
	public Game() {
		display = Display.getDisplay(this);
		playerList = new List("桌面列表", Choice.EXCLUSIVE);
		Command exitCommand = new Command("退出", Command.EXIT, 0);
		playerList.addCommand(exitCommand);
		okCommand = new Command("落座", Command.OK, 0);
		playerList.addCommand(okCommand);
		playerList.setCommandListener(this);
		display.setCurrent(playerList);
		client = new NetClient(this);
	}

	protected void startApp() throws MIDletStateChangeException {
	}

	protected void pauseApp() {
	}

	protected void destroyApp(boolean p0) throws MIDletStateChangeException {
		//玩家结束游戏,当前客户端销毁
		client.sendMessage(Message.EXIT_REQ, "exit");
		display.setCurrent(null);
	}

	/**
	 * 命令判断和执行
	 * 退出时发送退出消息,执行销毁
	 * 确定按键,获得具体的桌子和座位号,发送消息
	 */
	public void commandAction(Command c, Displayable s) {
		if (c.getCommandType() == Command.EXIT) {
			client.sendMessage(Message.EXIT_REQ,"exit");
			try {
				destroyApp(false);
				notifyDestroyed();
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if (c == okCommand) {			
			if (playerList.getSelectedIndex() >= 0) {
				try {
					String info = playerList.getString(playerList
							.getSelectedIndex());
					int index1 = info.indexOf("-");
					int d = Integer.parseInt(info.substring(0, index1));
					int index2 = info.indexOf("-", index1 + 1);

					int d1 = Integer.parseInt(info
							.substring(index1 + 1, index2));
					int d2 = Integer.parseInt(info.substring(index2 + 1));
					if (d1 == 0 || d2 == 0) {
						if (d1 == 0)
							trySeat = 0;
						else
							trySeat = 1;

						tryDesk = d;
						if (canvas == null){
							canvas = new MyGameCanvas(this, client);
						}						
						else
							canvas.init();
						//发送坐下命令和内容服务器端
						client.sendMessage(Message.TAKE_REQ, "take," + d + "," + trySeat);
					}
				} catch (Exception exc) {
					System.out.println("Error parseInt");
					exc.printStackTrace();
				}
			}
		}
	}
	public MyGameCanvas getCanvas() {
		return canvas;
	}
	public void initialize() {
		canvas = null;
	}
	
	/**
	 * 座位坐下动作
	 */
	public void takeSeat() {				// 处理落座信息的方法		
		if( canvas == null){
			canvas = new MyGameCanvas(this, client);
		}
		else{
			canvas.init();
		}
		
		canvas.setSeatPos(trySeat);
		canvas.setDeskIndex(tryDesk);
		
		//界面切换到游戏界面,等待开始指令
		display.setCurrent(canvas);
	}
	
	/**
	 * 解析服务器的座位信息,更新当前的座位界面
	 * 更新桌面
	 * @param str
	 */
	public void updateDesk(String str) {	// 更新桌面
		System.out.println("更新桌面: " + str);
		int index1 = str.indexOf(",");
		int index2 = str.indexOf(":", index1 + 1);
		int index3 = str.indexOf(",", index2 + 1);
		try {
			int d = Integer.parseInt(str.substring(index1 + 1, index2));
			desks[d][0] = Integer.parseInt(str.substring(index2 + 1, index3));
			desks[d][1] = Integer.parseInt(str.substring(index3 + 1));

			playerList.set(d, d + "-" + desks[d][0] + "-" + desks[d][1], null);
		} catch (Exception exc) {
		}
	}
	
	/**
	 * 获得playerList的列表
	 * @return
	 */
	public List getPlayerList() {
		return playerList;
	}
	
	/**
	 * 根据接收消息设置座位
	 * 
	 * @param string
	 */
	public void setDesks(String string) {
		System.out.println("setDesks: " + string);
		for (int i = 0; i < playerList.size(); i++)
			playerList.delete(i);

		int index1, index2, index3, index4, index0;
		index1 = string.indexOf(",");
		index2 = string.indexOf(":", index1 + 1);

		int desknum = Integer.parseInt(string.substring(index1 + 1, index2));
		desks = new int[desknum][4];

		index0 = index2;
		int counter = 0;

		while (counter < desknum) {
			index1 = string.indexOf(",", index0 + 1);
			index4 = string.indexOf(":", index1 + 1);

			desks[counter][0] = Integer.parseInt(string.substring(index0 + 1,
					index1));
			if (index4 > 0)
				desks[counter][1] = Integer.parseInt(string.substring(
						index1 + 1, index4));
			else {
				string = string.trim();
				desks[counter][1] = Integer.parseInt(string
						.substring(index1 + 1));
			}
			playerList.append(counter + "-" + desks[counter][0] + "-"
					+ desks[counter][1], null);
			index0 = index4;
			counter++;
		}
	}
}





NetClient.java

负责:
* 手机客户端的连接通信模块
* 负责发送数据到服务端
* 接收服务端的消息
* 解析接收到的消息
* 调用相应方法进行业务处理

/**
 * 
 */
package newclient;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import javax.microedition.io.Connector;
import javax.microedition.io.SocketConnection;

/**
 * @author sean
 * 手机客户端的连接通信模块
 * 负责发送数据到服务端
 * 接收服务端的消息
 * 解析接收到的消息
 * 调用相应方法进行业务处理
 * 
 * 
 */
public class NetClient implements Runnable {
	Game game;
	SocketConnection conn;
	public static int playerId = 0;
	public static Queue inDataList = new Queue(); // 输入消息队列
	public static Queue outDataList = new Queue(); // 输出消息队列


	/**
	 * 构造函数 清空输入流队列 网络连接 发送注册消息,通知服务器客户端的连接
	 * 
	 * @param game
	 */
	public NetClient(Game game) {
		// TODO Auto-generated constructor stub
		this.game = game;

		// 消息输入流的初始化
		inDataList.clear();
		outDataList.clear();
		

		// 连接服务器端
		connect();

		// TODO 此处的发送消息,有些问题,发送消息的内容需要修改, 修改为:发送空消息
		sendMessage(Message.REGISTER_REQ, "");
		System.out.println("发送注册数据成功");

		new Thread(this).start();
	}

	String serverAddr = "socket://127.0.0.1:9999";
	private DataInputStream dis;
	private DataOutputStream dos;

	/**
	 * 连接服务器端 获得输入输出输入流
	 * 
	 * @return
	 */
	private boolean connect() {
		// TODO Auto-generated method stub
		try {
			conn = (SocketConnection) Connector.open(serverAddr,
					Connector.READ_WRITE);

			if (conn != null) {
				dis = new DataInputStream(conn.openInputStream());
				dos = new DataOutputStream(conn.openOutputStream());
				return true;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	int count = 0;

	/**
	 * 负责消息的组织
	 * 放入outdatalist
	 * 1. 打包msg到输出队列 
	 * 2. 启动线程发送队列中的数据 
	 * 3. 线程是否会自动关闭,长时间玩下来是否导致内存溢出?
	 * @param cmdType
	 * @param msg
	 */
	public void sendMessage(int cmdType, String msg) {
		// TODO 1. 打包msg到输出队列 2. 启动线程发送队列中的数据 3. 线程是否会自动关闭,长时间玩下来是否导致内存溢出

		System.out.println(count + "client ready to send msg: " + cmdType);
		Message message = new Message(cmdType,playerId, msg);
		outDataList.push(message);
		
		System.out.println(count + "client ready to send msg: " + msg);
		System.out.println(count + "outDataList size: " + outDataList.size());
		
		new Thread(new Runnable(){

			public void run() {
				// TODO Auto-generated method stub
				sendData();
			}
			
		}).start();
	}
	
	
	/**
	 * 发送数据到客户端
	 * 去除队列中的第一个元素,发送数据
	 */
	private void sendData() {
		// TODO Auto-generated method stub
		System.out.println("outdatalist size: " + outDataList.size());
		if(outDataList.isEmpty()){
			return;
		}
		
		int size = outDataList.size();
		
		//循环遍历消息
		for(int i=0; i<size; i++){
			Message msg = (Message) outDataList.pop();
			
			try {
				dos.writeInt(msg.getCmdType());
				System.out.println("发送消息cmdType: " + msg.getCmdType());
				dos.writeInt(msg.getPlayerId());
				System.out.println("发送消息playerId: " + msg.getPlayerId());
				dos.writeInt(msg.getMessage().getBytes().length);		
				dos.write(msg.getMessage().getBytes());
				System.out.println("发送消息: " + msg.getMessage());
				System.out.println("发送消息完成************************");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}	
	}
	
	/**
	 * 线程体
	 * 负责客户端数据接收
	 * 逻辑处理
	 */
	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			
			// 读取服务器端数据
			recieveData();

			// 逻辑处理
			handleLogic();			

			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}	

	/**
	 * 读取来自服务器的数据 首先判断是否有
	 * 
	 * @return
	 */
	private void recieveData() {
		// TODO Auto-generated method stub
		if (dis == null) {
			return;
		}

		int cmdType = 0;
		try {

			// 死循环,不停读取输入流的内容,分析包头,然后分发到不同方法去处理
			if (dis.available() == -1) {
				return;
			}

			// 读取数据流,打包成message对象,放入队列
			cmdType = dis.readInt();
			System.out.println("client: cmdType is" + cmdType);
			playerId = dis.readInt();

			// 读取消息的长度,构建byte[], 读取消息内容
			int len = dis.readInt();
			byte[] tempData = new byte[len];
			dis.read(tempData);
			String str = new String(tempData);

			Message msg = new Message(cmdType, playerId, str);

			if (msg != null) {
				inDataList.push(msg);
			}

		} catch (Exception e) {
			// TODO: 读取数据流错误处理
		}

	}

	/**
	 * 读取消息队列的内容,根据cmdType,进行逻辑处理
	 */
	private void handleLogic() {
		// TODO 判断消息队列是否为空,得到最新的消息,解析后处理
		if (inDataList.isEmpty()) {
			return;
		}

		Message msg = (Message) inDataList.pop();

		if (msg == null) {
			return;
		}

		int cmdType = msg.getCmdType();

		switch (cmdType) {
		// 桌子反馈信息,玩家第一次注册成功后返回信息
		case Message.DESKS_RESP:
			handleDesksInfo(msg);
			break;

		// 坐下之后的逻辑处理
		case Message.UPDATEDESK_RESP:
			handleUpdateDesk(msg);
			break;

		case Message.GAME_RESP:
			handleGameResp(msg);
			break;
		
		case Message.EXIT_REQ:
			
			break;
			
		default:
			break;
		}

	}

	/**
	 * 处理桌子的信息
	 * 
	 * @param msg
	 */
	private void handleDesksInfo(Message msg) {
		// TODO 处理服务器端返回的桌子信息
		String data = msg.getMessage();
		System.out.println("client recieved desks: " + data);
		game.setDesks(data);
	}

	/**
	 * 
	 * @param msg
	 */
	private void handleUpdateDesk(Message msg) {
		// TODO 读取玩家id
		int playerId = msg.getPlayerId();
		System.out.println("client playerId: " + playerId);
		game.takeSeat();
	}

	/**
	 * 处理游戏过程中的命令交互
	 * move等
	 * @param msg
	 */
	private void handleGameResp(Message msg) {
		// TODO 得到具体的消息,

		String str = msg.getMessage();
		System.out.println("client recieve game message " + str
				+ System.currentTimeMillis());
		if (game.getCanvas() != null) {
			game.getCanvas().receiveMessage(str);
		}
	}	
}


分享到:
评论

相关推荐

    基于Socket手机网络象棋开发

    在基于Socket的手机网络象棋开发中,Socket被用来建立服务器与客户端(即玩家的手机)之间的连接,使得两者能够实时地交换数据,包括象棋游戏的走子信息、状态更新以及聊天消息等。 #### 二、服务器端设计与实现 ...

    java 网络 象棋 服务器 客户端 socket tcp

    在本项目中,我们主要探讨的是使用Java编程语言构建一个基于TCP协议的网络象棋游戏,包括服务器端和客户端的实现。TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,...

    中国象棋网络智能客户端源码

    5. **人工智能(AI)算法**:网络智能客户端的核心部分是实现象棋的AI,让计算机能够自主决策。这可能涉及到搜索算法,如Minimax、Alpha-Beta剪枝,以及更高级的评估函数设计,如棋局评估、威胁识别、棋型识别等。...

    基于socket手机网络象棋开发

    ### 基于Socket手机网络象棋开发的关键技术与实现 #### 一、项目概述 本文档基于一个具体的案例——“基于socket手机网络象棋开发”来深入探讨其设计思路和技术实现细节。该项目旨在通过Socket通信技术搭建一个...

    手机网络象棋源码

    手机网络象棋源码是一种专为移动设备设计的在线对弈平台,允许用户通过网络进行象棋游戏。源码是程序开发的基础,包含了所有必要的代码、注释和资源,为开发者提供了一个理解软件工作原理和进行二次开发的窗口。这款...

    VB开发象棋游戏(服务器端与客户端)

    【标题】"VB开发象棋游戏(服务器端与客户端)"揭示了这是一个使用Visual Basic(VB)编程语言开发的项目,旨在创建一个完整的网络象棋游戏。游戏包含两个主要组成部分:服务器端和客户端。服务器端作为游戏的中枢,...

    c#网络游戏象棋客户端

    在C#编程语言中开发网络游戏象棋客户端是一项技术密集型的任务,涉及到多个关键知识点。C#是Microsoft推出的一种面向对象的、类型安全的编程语言,常用于构建Windows应用程序和游戏。在这个项目中,我们将深入探讨...

    手机网络游戏 服务器端配置 客户端发布与运行 配置源程序.docx

    《手机网络游戏 服务器端配置 客户端发布与运行 配置源程序》这份文档主要介绍了手机网络游戏在服务器端和客户端的配置与发布过程。以下是详细的解析: 1. **服务器端配置** - 首先,需要将包含服务器端程序的...

    网络象棋对战C#源码

    网络象棋对战C#源码是一个用于开发网络象棋游戏的应用程序,它基于C#编程语言,提供了实现在线对战功能的完整代码基础。在深入理解这一源码之前,我们需要先了解一些基本的背景知识。 1. **C#语言**: C#是由微软...

    象棋源码H5开发设计的象棋 AI在线对弈网页页面象棋源码【全新經典版+内嵌ai算法】

    象棋源码H5开发设计的象棋 AI在线对弈网页页面象棋源码【全新經典版+内嵌ai算法】 效果演示https://www.a5ymg.cn/571.html 【象棋源码】全新經典版H5开发设计的象棋完整篇AI在线对弈网页页面象棋源码 經典版H5开发...

    C#TCP/IP网络象棋

    【C# TCP/IP网络象棋】是一个利用C#编程语言实现的基于TCP/IP协议的网络游戏,它允许玩家通过互联网进行在线对弈。在这款游戏中,C#被用来创建服务器和客户端应用程序,使得用户能够通过TCP连接进行实时的棋局交互。...

    局域网象棋软件 客户端和服务器端一体

    局域网象棋软件是一款专为局域网用户设计的在线对弈平台,它集客户端和服务器端于一体,简化了传统网络对战的复杂性,让玩家在同一个局域网内轻松实现棋艺交流。该软件特别适合于公司休息室、学校机房或家庭聚会等...

    asp net 网络版中国象棋源码

    【标题】"asp net 网络版中国象棋源码"所涉及的知识点主要集中在ASP.NET技术在构建网络象棋游戏中的应用。ASP.NET是由微软公司开发的一种Web应用程序框架,用于构建动态网站、Web应用和服务。在这个项目中,开发者...

    中国象棋开发资料

    综上所述,虽然提供的代码片段没有直接展示中国象棋软件的具体实现细节,但我们可以通过分析整个开发流程和技术要点来更全面地理解这类软件的开发过程。希望以上内容能够帮助您更好地理解和掌握中国象棋软件开发的...

    vs网络版象棋

    【标题】"vs网络版象棋"是一款使用Visual Studio(VS)开发平台构建的网络象棋游戏。这款游戏设计的核心目标是实现多人在线对弈的功能,让玩家能够在互联网上与他人实时进行象棋对战。 【描述】在VS开发环境下,这...

    JAVA编写的网络中国象棋对战(附原代码)

    【标题】"JAVA编写的网络中国象棋对战"是一个基于JAVA编程语言开发的网络棋类游戏项目,它实现了让玩家能够在线上进行实时的中国象棋对决。这个项目的核心功能包括创建游戏主机、客户端连接、棋局同步以及棋子移动的...

    python象棋项目客户端.rar

    【Python象棋项目客户端】是一个基于Python编程语言和Pygame库开发的桌面应用程序,它提供了用户友好的界面,使得玩家可以在线或离线体验中国象棋的乐趣。Pygame是Python中一个广泛使用的游戏开发框架,它包含了一...

    Online-Chess-Game:在 24 小时直播中创建的国际象棋游戏

    在线多人国际象棋描述:一个在线多人国际象棋游戏。 支持无限玩家在不同网络的不同机器上与随机对手对战。 这个项目是使用 python 3.7、pygame 和 python3 的 sockets 模块创建的。 它运行在一个基本的客户端服务器...

    手机网络游戏象棋java源代码

    手机版象棋游戏采用MIDP1.0开发,在低端手机上运行的同时,保证了高端手机的兼容性,其市场发展空间巨大。伴随着中国移动GPRS和中国联通CDMA1X数据业务的开展,手机游戏将是3G数据业务的一个重要的应用领域。 根据...

Global site tag (gtag.js) - Google Analytics