滨江学院
Java程序设计实习
课程设计
题目 小游戏五子棋
学生姓名 bb
学 号 20112346002
院 系 滨江学院计算机系
专业年级 网络工程一班
指导教师 方忠进
二O一三 年 6 月 20 日
引言 1
1.需求分析 1
1.1 基本需求分析 1
1.2 高级需求分析 2
2 开发环境 2
2.1 开发环境及运行环境 2
2.1.1 开发环境 2
2.1.2 运行环境 2
3 总体设计 2
3.1 系统设计思想 2
3.2 系统总体设计 3
3.3 功能模块及流程 4
3.3.1 系统主要模块 4
3.3.2 服务器端作用 5
3.3.3 客户端作用 6
3.3.4 系统主流程 7
4 详细设计 7
4.1 客户端界面设计 8
4.2 客户端网络设计 9
4.3 棋盘类设计 9
4.4 系统各模块之间的关系 10
5 软件展示 10
5.1 游戏界面展示 10
5.2关键代码......................................................................11
6 总结语 20
参考文献 24
基于Java的“网络五子棋”游戏的设计和实现——网络版客户端
引言
随着经济社会的迅速发展,人们生活水平有了很大的提高,人们的生活观念也发生了巨大的改变。高品质的生活、现代化得生活方式成为人们共同追求的目标;休闲、娱乐性活动作为时尚生活中的一部分,而被大多数的人所追捧。棋类项目作为一种智力型项目,可以益智健心、修身养性,也可以满足人们对于娱乐和休闲的新需求。一些项目比如五子棋等等,由于项目本身互动的特点,一直被人们所喜爱,因此得以生存和发展,成为许多人喜爱的休闲娱乐性棋类项目。
而今,以网络技术为核心和计算机技术的现代网络技术已经在现实生活得到了十分的广泛的使用。休闲类网络游戏集合了益智性、趣味性、互动性、娱乐性于一体,已经成为多数人群的选择的休闲方式。
借此,本论文在分析了当前计算机网络的蓬勃发展和人们对于休闲娱乐性生活方式的追求,以java为工具,以精美的界面,以常规安全的socket建立连接,设计更为益智的网络五子棋游戏,增强了趣味性和益智性。
1 需求分析
需求分析作用
软件需求分析是软件开发周期的第一个阶段,也是关系到软件开发成败的最关键一步。只有通过了软件需求分析,才能把软件的功能和性能由总体的概念性和理论性描述转化为具体的规格说明,从而建立软件开发的基础。实践证明,需求分析工作进行得准确程度,在很大程度上决定了软件开发的成败。
软件需求分析的任务就是让用户与开发者明确开发的是一个什么软件。具体的说,就是通过对问题及其环境的理解、分析与综合把握,建立逻辑模型,完成软件的逻辑
方案
气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载
设计。
1.1 基本需求分析
软件的界面简洁明了而不失精美,操作简单容易,功能按钮名称简单易懂,棋盘的大小,棋子的样式。
1.2 高级需求分析
现有的网络编程模式主要分成两类:一种是基于C/S(Client/Server)模式,另一种是B/S (Browser/Server)模式。网络五子棋系统应用于局域网,对交互性要求很高,本系统选用了C/S 模式进行实现,网络内部使用TCP/IP 方式利用Socket提供的服务,使用Java Graphics类进行用户图形界面的搭建。系统分成两个部分,分别为服务端程序以及客户端程序[7]。结合实际情况,将服务器端的程序和客户端的程序放在一起,便可以更为方便的建立游戏和参与游戏,有效解决了在局域网中服务器未开启,则无法进行游戏的缺陷。
五子棋网络游戏主要分为两个部分,游戏服务端和游戏客户端。游戏服务端主要存储所有连线客户的相关信息及各种状态,并负责游戏客户之间数据的传递,具有创建服务器、系统设置、连接服务器、我要参赛等等功能;游戏客户端提供客户连接服务器,并能与联网玩家进行游戏。由于将服务器端和客户端程序放在一起,所以可以减少界面绘制的冗余代码,使得客户端和服务器端使用相同的界面。故客服端也具有创建服务器、系统设置、连接服务器、我要参赛等功能。
2 开发环境及运行环境
2.1. 开发环境
★ AMD Athlon(tm) 2.10GHz,2G内存,80G硬盘
★ Microsoft Windows 7
★ JDK 1.60
★ Eclipse
2.2 运行环境
★ Intel Pentium core及以上处理器,128M以上内存,20G以上硬盘
★ Microsoft Windows 9X/NT操作系统
★ 1024*768或以上的屏幕分辨率
3..总体设计
总体设计是软件开发过程中的另一个重要阶段,在这一阶段中将根据需求分析中提出的逻辑模型,合理地完成物理模型的设计。这个阶段的主要目标是将反映了用户信息需求的逻辑方案转换成物理方案,并为下一阶段提供必须的技术
资料
新概念英语资料下载李居明饿命改运学pdf成本会计期末资料社会工作导论资料工程结算所需资料清单
。
总体设计应遵循以下原则:
★ 整体性:软件是作为统一整体而存在的。因此,在总体设计中要从整个软件的角度去考虑。
★ 灵活性:为保持软件长久的生命力,要求该软件具有很强的环境适应性。为此,该软件必须具有较好的开放性与结构的可变性。
★ 可靠性:可靠性是指软件抵御外界干扰的能力及受外界干扰时的恢复能力。
★ 经济性:经济性是指在满足游戏软件需求的前提下,尽可能地减少对游戏的开销。
3.1 系统设计思想
通过服务器的连接,不同的玩家可以连接到各自想参加比赛的服务器地址,并开始各自的游戏。通过安全的SOCKET连接交换数据。通过多线程,使得每个对战的双方不会受到第三方数据的干扰。本系统的功能能够实现一个在网络上供客户进行对战的五子棋网络游戏,因为是C/S 模式的网络游戏,客户只要连接到服务器上,就能选择任何其它用户已创建好的游戏进行对战游戏。在C/S模式游戏中,Server一般提供所有用户的全部信息,并能提供客户之间的信息转发。客户之间的通讯必须通过Server进行,因为多个客户能够连接到同一台Server上,所以Server必须用Thread 负责每个用户的通讯和消息处理。
客户连接成功,Server利用特定的客户Thread连接不断从客户读取数据,实现客户和服务器或者客户与客户之间的信息的交互。客户端同样采用的是线程控制的思想,在每一个客户端连接上服务器后,就为此客户端启动一个网络收发数据线程。
系统设计设计框架如下图所示:
用户通过TCP与服务器建立连接,通过SOCKET与服务器交互数据
图3.2.1-1 网络五子棋设计框架图
3.2 系统总体设计
系统使用Socket 技术以及java 多线程机制进行客户与服务端之间信息的交互,但一个真正实用程序必须针对具体应用定制一套
协议
离婚协议模板下载合伙人协议 下载渠道分销协议免费下载敬业协议下载授课协议下载
用于用户程序之间进行交互,而该协议的定制往往是编写程序的关键也是核心内容,该协议的完善决定程序是否能够正常运行。
所谓协议就[8]是程序之间交互的信息的格式规定, 服务端和客户端都遵循该协议才能够进行对话, 通俗讲是人类之间的语言。
本网络游戏可以分为两个部分:服务器和客户端。服务器主要存储所有连线客户的相关信息及各种状态,并负责游戏客户之间数据的传递,具有创建服务器、系统设置、连接服务器、我要参赛等等功能;客户端提供客户连接服务器,并能与联网玩家进行游戏。
信息交换如图所示:
服务器端转发其他客户端信息
图3.2.2-1 客户端与服务器端的信息交换图
3.3 功能模块及流程
3.3.1 系统主要模块
根据上面的系统的设计要求,可以将此网络五子棋游戏分为以下五个模块:
初始化模块:建立棋盘数组并清零;初始化界面并在屏幕上画出棋盘,加载音乐等。
主循环控制模块:负责控制下棋顺序,当轮到某方下子时,负责将程序流程转到相应的模块中。
玩家落子模块:即用户在指定落子区域单击后,程序就会得到该棋子的坐标,并且将棋盘数组中坐标处
记录
混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载
棋子的颜色,1代表白色,2代表黑色,以说明是哪一方下的棋子。
胜负判断模块:根据预先设定的五子棋规则,判断游戏输赢。
网络模块[9]:网络功能的实现,使两台不同计算机的用户通过网络连接,实现网络对弈的功能。
3.3.2 服务器端作用
服务器端[10]主要通过建立流连接来连接客户端,与客户端进行相互通信、转发信息。接收客户端的信息,接收信息后按照此客户端的要求将信息发送到相应的客户端,服务器端起到了中转的作用。
玩家进入游戏界面时,如果玩家不想进入别人已经建立好的游戏中,那也可以自己从界面中建立一个自己的游戏,等待其他玩家的进入。首先输入你要建立游戏的IP地址,输入自己的名字,这样一个自己的游戏就建立了,如果有玩家加入游戏,系统会提示某某玩家进入,这时你可以选择开始游戏或者继续等待。游戏各模块功能跟客服端的模块相同。
3.3.3 客户端作用
玩家进入游戏界面时,首先提示用户连接服务器,当玩家连接上服务器后,就会在界面右上角给出用户的初始玩家名,在聊天内容框中会给出用户提示,玩家可以创建游戏或者加入建立好的游戏。
游戏各模块功能如下表3.3.3-1:
表3.3.3-1 客户端模块功能
模块名称
功能
UserPad
用于显示服务器发送过来的当前连接上服务器的用户,即活动玩家的玩家名称。
chatPad
用于显示服务器发送过来的提示信息以及用户公聊或私聊的内容。
chessPad
用于绘制棋盘及棋子,以及当前的提示信息。
inputPad
用于用户选择要公聊或私聊的对象,即所有人或某一具体的玩家,输入要发送的消息,发送给服务器,通过服务器转发出去。
controlPad
用于对当前的游戏界面进行实时的控制,包括:创建服务器、系统设置、连接 服务器、我要参赛等。
以上功能模块在界面中的展示如下图所示:
inputpad
usrpad
controlpad
Chatpad
chesspad
图3.3.3-1 用户操作界面
3.3.4 系统主流程
玩家进入游戏,选择是否为服务器,是则等待其他玩家加入,否则等待其他玩家建立服务器。进入服务器后点参赛,进入对弈阶段。对弈结束,从新开始。
系统主流程如下图:
一方胜利
图3.3.4-1 网络五子棋游戏流程图
4 详细设计
4.1 客户端界面设计
游戏客户端主要用于玩家信息的初始化,玩家的操作状态的定义,包括结构组织游戏客户端的界面,实现定义游戏控制按钮,完成定义键盘的事件。
主要方法:
★ launchFrame()方法 用在启动玩家客户端时,为用户发送连接服务器信息,并且加载背景音乐等。
★ actionPerformed(ActionEvent e)方法 用于客户端玩家单击控制按钮的功能的实现。该方法主要用来实现玩家修改名字、创建游戏、我要参赛、系统设置等各个按钮的功能。
★ keyPressed(KeyEvent e)方法 用于实现聊天功能,当玩家输入聊天信息到输入框中后,按回车键可以发送消息。此事件中主要处理了两个行为,一是当玩家选择某玩家进行私聊时的处理,二是当用户选择所有人进行公聊时的处理。
.4.2 客户端网络设计
网络客户端主要用于接收和发送服务器消息。
主要方法如下:
★ connect(String,int)用于服务器的连接。第一个参数是要连接的服务器的IP地址,第二个参数是连该服务器的端口号。玩家用此方法连接上服务器,玩家启动一个线程用来接收服务器发送过来的消息。
★ restart() 用于游戏重新开始,在此方法中要求将重新初始化信息,并且进行棋盘清理操作。
★ send(int,String)用于发送此玩家的消息状态给服务器。第一个参数是消息类型,第二个参数是消息内容。消息类型有如下几种如表5.3-1:
表4.2-1 消息类型
类型
发送消息类型
0
代表修改客户端名字
1
代表客户端建立游戏
2
代表客户端加入游戏
3
代表向游戏对方通告客户端已加入
4
代表客户端放弃游戏
5
代表客户端对游戏对方发送过来的放弃操作进行断开
6
代表游戏一方向另一方发送棋盘状态
7
代表游戏一方向另一方发送时间信息
★ doMessage(DatagramPacket)用于接收从服务器端发送过来的消息。
4.3 棋盘类设计
棋盘类主要用于绘制棋盘的。
★ paint(Graphics) 方法用来绘制棋盘、棋盘的背景图片和棋子位置。因为采用了双缓冲技术,有效的消除加载图片时的窗口闪烁。
★ clearBoard()方法用于初始棋盘和一些变量的操作。
★ select()方法设置其按钮状态的。
★ isFull()方法用于判断当前棋盘是否已无法落子。如果当前棋盘已满,则通知玩家此局游戏流局。
★ judge(int,int,int) 方法用于判断当前棋子落下时是否游戏胜负已分。如果游戏获胜,则方法返回真值;否则返回假值。
4.4 系统各模块之间的关系
ChessServer类,ChessClient类,NetClient类,ChessPad类等类之间的交互实现了系统的主要功能。服务器端模块的实现,主要的类是ChessPad类和ChessClient类。ChessClient类实现了玩家单击按钮功能及界面的组织;ChessPad类用于绘制棋盘和玩家的落子位置。客户端主要用到的是这三个类:ChessServer类、ChessClient类和NetClient类。服务器类和客户端类用Socket编程实现的信息交换。其他功能都是在用户连接服务器后由游戏客户端类自动调用其类来实现的。
5. 游戏界面展示
★ 游戏开始的界面,能够看到上面的各个不同的功能按钮,界面如下图:
图6.3-1 游戏开始界面
★ 输入玩家昵称,同时建立服务器,服务器按钮变成灰色,如下图:
图6.3-2 建立服务器
有玩家加入服务器,但是还没有参赛,如下图:
图6.3-3 加入服务器
两个玩家都参赛,“我要参赛”变成灰色,显示玩家名字,如下图:
图6.3-4 加入游戏
★ 游戏一方获胜,系统提示,如下图:
图6.3-5 游戏一方获胜
★ 玩家在相互对话,如下图:
图6.3-6 玩家对话
5.1关键代码
import java.net.*;
import java.io.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
import java.awt.Color;
public class wuziqi extends Applet implements ActionListener,MouseListener,MouseMotionListener,ItemListener{
int color_Qizi=0;//旗子的颜色标识 0:白子 1:黑子
int intGame_Start=0;//游戏开始标志 0未开始 1游戏中
int intGame_Body[][]=new int[16][16]; //设置棋盘棋子状态
int m=-1;
Button b1=new Button("开始");
Button b2=new Button("重新开始");
Label lblWin=new Label(" ");
Checkbox ckbHB[]=new Checkbox[3];
Button exist = new Button("退出");
CheckboxGroup ckgHB=new CheckboxGroup();
public void init(){
setLayout(null);
addMouseListener(this);
add(b1);
b1.setBounds(330,50,80,30);
b1.addActionListener(this);
add(b2);
b2.setBounds(330,90,80,30);
b2.addActionListener(this);
ckbHB[0]=new Checkbox("执白",ckgHB,false);
ckbHB[0].setBounds(320,20,60,30);
ckbHB[1]=new Checkbox("执黑",ckgHB,false);
ckbHB[1].setBounds(380,20,60,30);
ckbHB[2]=new Checkbox("观看",ckgHB, false);
add(ckbHB[0]);
add(ckbHB[1]);
add(ckbHB[2]);
ckbHB[0].addItemListener(this);
ckbHB[1].addItemListener(this);
add(lblWin);
lblWin.setBounds(330,180,80,30);
lblWin.setBackground(Color.red);
lblWin.setText("胜利者!");//没有显示?
ckbHB[2].setBounds(440, 20,60, 30);
add(exist);
exist.setBounds(330,130,80,30);
exist.addActionListener(this);
Game_start_csh();
setSize(500,600);
setVisible(true);
}
public void itemStateChanged(ItemEvent e){
if (ckbHB[0].getState()) //选择黑子还是白子
{
color_Qizi=0;
}
else
{
color_Qizi=1;
}
}
public void mousePressed(MouseEvent e){}
public void mouseClicked(MouseEvent e){
Graphics g=getGraphics();
int x1,y1;
x1=e.getX();
y1=e.getY();
if (e.getX()<20 || e.getX()>300 || e.getY()<20 || e.getY()>300){
return;
}
if (x1%20>10){
x1+=10;
}
if(y1%20>10){
y1+=10;
}
x1=x1/20*20;
y1=y1/20*20;
set_Qizi(x1,y1);
m*=(-1)
}
public void actionPerformed(ActionEvent e){
Graphics g=getGraphics();
if (e.getSource()==b1){
Game_start();
}
else{
Game_re();
}
if(e.getSource()==exist){
Game_re();
// color_Qizi=m;
lblWin.setText(Get_qizi_color(color_Qizi)+"输了!");
intGame_Start=0;
}
}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseDragged(MouseEvent e){}
public void mouseMoved(MouseEvent e){}
public void paint(Graphics g){
draw_qipan(g);
}
public void set_Qizi(int x,int y){ //落子
if (intGame_Start==0) {//判断游戏未开始
return;
}
if (intGame_Body[x/20][y/20]!=0){
return;
}
Graphics g=getGraphics();
if (color_Qizi==1){//判断黑子还是白子
g.setColor(Color.black);
color_Qizi=0;
}
else{
g.setColor(Color.white);
color_Qizi=1;
}
g.fillOval(x-10,y-10,20,20);
intGame_Body[x/20][y/20]=color_Qizi+1;
if (Game_win_1(x/20,y/20)){ //判断输赢1
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
intGame_Start=0;
}
if (Game_win_2(x/20,y/20)){ //判断输赢2{
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
intGame_Start=0;
}
if (Game_win_3(x/20,y/20)){ //判断输赢3
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
intGame_Start=0;
}
if (Game_win_4(x/20,y/20)){ //判断输赢4
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
intGame_Start=0;
}
}
public String Get_qizi_color(int x)
{
if (x==0)
{
return "黑子";
}
else
{
return "白子";
}
}
public void draw_qipan(Graphics G){ //画棋盘 15*15
G.setColor(Color.lightGray);
G.fill3DRect(10,10,300,300,true);
G.setColor(Color.black);
for(int i=1;i<16;i++){
G.drawLine(20,20*i,300,20*i);
G.drawLine(20*i,20,20*i,300);
}
}
public void Game_start(){ //游戏开始
intGame_Start=1;
Game_btn_enable(false);
b2.setEnabled(true);
}
public void Game_start_csh() {//游戏开始初始化
intGame_Start=0;
Game_btn_enable(true);
b2.setEnabled(false);
ckbHB[0].setState(true);
for (int i=0;i<16 ;i++ ){
for (int j=0;j<16 ;j++ ){
intGame_Body[i][j]=0;
}
}
lblWin.setText("");
}
public void Game_re(){ //重新开始游戏
repaint();
Game_start_csh();
}
public void Game_btn_enable(boolean e){ //设置组件状态
b1.setEnabled(e);
b2.setEnabled(e);
ckbHB[0].setEnabled(e);
ckbHB[1].setEnabled(e);
}
public boolean Game_win_1(int x,int y){ //横向判断输赢
int x1,y1,t=1;
x1=x;
y1=y;
for (int i=1;i<5 ;i++ ){
if (x1>15){
break;
}
if (intGame_Body[x1+i][y1]==intGame_Body[x][y]){
t+=1;
}
else{
break;
}
}
for (int i=1;i<5 ;i++ ){
if (x1<1){
break;
}
if(intGame_Body[x1-i][y1]==intGame_Body[x][y]){
t+=1;
}
else{
break;
}
}
if (t>4){
return true;
}
else{
return false;
}
}
public boolean Game_win_2(int x,int y){ //纵向判断输赢
int x1,y1,t=1;
x1=x;
y1=y;
for (int i=1;i<5 ;i++ ){
if (x1>15){
break;
}
if (intGame_Body[x1][y1+i]==intGame_Body[x][y]){
t+=1;
}
else{
break;
}
}
for (int i=1;i<5 ;i++ ){
if (x1<1){
break;
}
if(intGame_Body[x1][y1-i]==intGame_Body[x][y]){
t+=1;
}
else{
break;
}
}
if (t>4){
return true;
}
else{
return false;
}
}
public boolean Game_win_3(int x,int y){ //左斜判断输赢
int x1,y1,t=1;
x1=x;
y1=y;
for (int i=1;i<5 ;i++ ){
if (x1>15){
break;
}
if (intGame_Body[x1+i][y1-i]==intGame_Body[x][y]){
t+=1;
}
else{
break;
}
}
for (int i=1;i<5 ;i++ ){
if (x1<1){
break;
}
if(intGame_Body[x1-i][y1+i]==intGame_Body[x][y]){
t+=1;
}
else{
break;
}
}
if (t>4){
return true;
}
else{
return false;
}
}
public boolean Game_win_4(int x,int y){ //左斜判断输赢
int x1,y1,t=1;
x1=x;
y1=y;
for (int i=1;i<5 ;i++ ){
if (x1>15){
break;
}
if (intGame_Body[x1+i][y1+i]==intGame_Body[x][y]){
t+=1;
}
else{
break;
}
}
for (int i=1;i<5 ;i++ ){
if (x1<1){
break;
}
if(intGame_Body[x1-i][y1-i]==intGame_Body[x][y]){
t+=1;
}
else{
break;
}
}
if (t>4){
return true;
}
else{
return false;
}
}
}