您的位置:首页 > 其它

结对实践项目——“五子棋”小游戏

2015-06-04 00:27 218 查看
之前与小组同学合作过一起写代码,那时老师分工明确,写两部分代码,一人负责一部分,剩下一个人做测试代码,在老师详尽的分工下,我们顺利的完成了那次任务。

这次从无范围自主选题,到熟练运用GUI,实现了人人对战。

【功能分析】

(1)程序在设计初就定义黑棋先行,白棋随后。一个玩家通过w,a,s,d键控制落子位置,按Space落子,另一个玩家通过控制方向键up,down,left,right控制位置,按Enter落子,从第一个棋子开始开始相互顺 序落子。

(2)通过坐标索引算出最先在棋盘的横向、竖向、斜向形成连续的相同色五棋子的一方为胜利。

(3)初始界面洁净无子设为游戏固定界面。

(4)在游戏过程中单击重新开局按钮或下完时可选择重新开始。

(5)游戏结束,会出现赢家对话框提示。

(6)游戏实现了基本的人人对战。

【分工情况】

芦畅:GUI设计及代码规范

苏正生:棋子胜负判断

【代码链接】

队友苏正生的报告:/article/5333807.html

源代码链接:http://git.shiyanlou.com/szs20135333/shiyanlou_cs212

【总体设计】

主要包括的类有四个:GameFrame、GamePanel、ChessMan、Player

1、 GamePanel类

GamePanel类是java版五子棋的主框架,程序的启动类。

其中包括游戏界面的创建、按钮的设置、相关的事件监听器设置、游戏的启动

2、GameFrame类

GameFrame类主要实现的是棋盘的绘制、创建数组存放棋子的坐标、设置只能在棋盘内可以落子、实现判断黑白棋的输赢、实现重新游戏。

3、ChessMan类

Point类主要就是实现棋子的功能

4、Player类

Player类主要实验玩家的功能

【过程分析】

这次实验,我主要负责

这次我主要负责的是GUI设计以及代码规范,我来大概说下GUI。

GUI编程规范总结:

1、首先就是建立菜单栏。在GUI控件使用时所有的控件都是层层嵌套的,就是控件依托,最终整合到面板上,进而再添加事件监听器,已响应事件的发生;

①首先要建立主框架:GamePanel Gpanel=new GamePanel();

②取得框架的内容窗格

③在制作复杂的用户界面时,常常需要使用多个JPanel将复杂的界面分解为先对建大的子界面,然后再对每个JPanel进行布局:

package WuZiGame;

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

class GameFrame extends JFrame {

private static final int Width=570;
private static final int Height=470;

GameFrame(){
setTitle("五子棋游戏");
CenteredFrame();
setSize(Width,Height);
GamePanel Gpanel=new GamePanel();
add(Gpanel);
}

void CenteredFrame(){
Toolkit kit=Toolkit.getDefaultToolkit();
Dimension screenSize=kit.getScreenSize();
int screenHeight=screenSize.height;
int screenWidth=screenSize.width;

int Xposition=(screenWidth-Width)/2;
int Yposition=(screenHeight-Height)/2;
setLocation(Xposition,Yposition);
}
}


⑤处理控件的依赖关系,及消息的定义,各种细节的设计

⑥控件的逐级加入

⑦将面板加入到框架的内容窗格中

package WuZiGame;

import javax.swing.*;

public class Game {

public static void main(String[] args) {

GameFrame GFrame=new GameFrame();
GFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GFrame.setVisible(true);
}

}


package WuZiGame;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class GamePanel extends JPanel {

private Point cursor=new Point(40,60); //棋盘坐标
private int[][] ChessState=new int[18][18];//棋盘状态
private int i=0;//横坐标   
private int j=0;//纵坐标
private final static int testnum=5;//五子棋的规定棋子数
private Player Black=new Player(1,Color.BLACK,"黑方");//黑方棋子
private Player White=new Player(2,Color.WHITE,"白方");//白方棋子
private Player Cplayer=null;//当前用户的引用
private JTextField textBlack=new JTextField("",5);//黑方文本提示框对象和文本长度设置
private JTextField textWhite=new JTextField("",5);//白方文本提示框对象和文本长度设置
private String Nothing="";
private String textblack="请黑方下子";//黑方提示文本
private String textwhite="请白方下子";//白方提示文本

GamePanel(){
setLayout(null);
Initialization();
setFocusable(true);

JButton Rutton=new JButton("重新开局");
Rutton.setBounds(20,14,100,26);
RestartListener restart=new RestartListener();
Rutton.addActionListener(restart);
add(Rutton);

textBlack.setHorizontalAlignment(JTextField.CENTER);
textBlack.setBounds(150,14,110,26);
textBlack.setEditable(false);
add(textBlack);

textWhite.setHorizontalAlignment(JTextField.CENTER);
textWhite.setBounds(290,14,110,26);
textWhite.setEditable(false);
add(textWhite);

JTextArea gInstruction=new JTextArea();
gInstruction.setSelectedTextColor(new Color(238,238,238));
String gSInstruction=
"Play1(黑方) Key \nup--------W \ndown----S \nleft--------A   \nright------D \n\n"+
"Play2(白方) Key \nup--------up \ndown----down \nleft--------left \nright------right \n\n"+
"Exit game: \nPress Esc";
gInstruction.setText(gSInstruction);
gInstruction.setEditable(false);
gInstruction.setBounds(440,60,100,340);
add(gInstruction);

ChessManPerformListener Perform=new ChessManPerformListener();
addKeyListener(Perform);

}

//    设置第一个JTextField输出"请黑方下棋",坐标为(40,60)
void Initialization(){
for(int i=0,j;i<18;i++)
for(j=0;j<18;j++){
ChessState[i][j]=0;
}
cursor.setLocation(40,60);
Cplayer=Black;
textBlack.setText(textblack);
textWhite.setText(Nothing);
}

//画棋盘和初始化棋局状态
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2=(Graphics2D) g;

for(int i=60;i<=400;i+=20){
g2.drawLine(40,i,380,i);
}
for(int j=40;j<=380;j+=20){
g2.drawLine(j,60,j,400);
}
g2.drawString("_",cursor.x-6,cursor.y);
g2.drawString("_",cursor.x,cursor.y);

for(i=0;i<18;i++)
for(j=0;j<18;j++){
if(ChessState[i][j]!=0){
if(ChessState[i][j]==1){
g2.setPaint(Black.getplayerChessManColor());
}
if(ChessState[i][j]==2){
g2.setPaint(White.getplayerChessManColor());
}
g2.fillOval(j*20+40-10, i*20+60-10, ChessMan.getChessManSize(), ChessMan.getChessManSize());
}
}
}

//判断棋盘的当前位置是否已有棋子
boolean isChessState(){
this.j=(cursor.x-40)/20;
this.i=(cursor.y-60)/20;
if(ChessState[this.i][this.j]!=0)
return true;
else
return false;
}

//记录落子后棋盘的当前位置的状态
void RecordChessState(){
this.j=(cursor.x-40)/20;
this.i=(cursor.y-60)/20;
ChessState[this.i][this.j]=Cplayer.getCurrentIdentify();
}

//判断当前玩家落子后是否赢了
void JudgeWin(){
for(int i=0;i<4;i++)
if(JudgeWinLine(i)){
//提示当前玩家已经获得胜利
try{
String Ginformation="GameInformation";
String Message="恭喜玩家"+Cplayer.getsIdentify()+"获胜!"+"\n"+"继续游戏还是退出游戏?";
String[] options = {"继续","退出"};
int selection=JOptionPane.showOptionDialog(null,Message,Ginformation,
JOptionPane.YES_NO_OPTION,JOptionPane.INFORMATION_MESSAGE ,null,options,options[0]);//throws HeadlessException
if(selection==JOptionPane.OK_OPTION){
Initialization();
repaint();
return;
}
if(selection==JOptionPane.NO_OPTION){
System.exit(0);//退出程序
}

}catch(HeadlessException e){
e.printStackTrace();
}
}
//如果当前方没有赢棋则双方轮换
ChangeCurrentPlayer();
}

//在当前方向上是否有连续的五只棋子
boolean JudgeWinLine(int direction){
int i,j,di,dj,count;
i=j=di=dj=count=0;
switch(direction){
case 0:
j=this.j-(testnum-1);
i=this.i;
dj=1;
di=0;
break;
case 1:
j=this.j;
i=this.i-(testnum-1);
dj=0;
di=1;
break;
case 2:
j=this.j-(testnum-1);
i=this.i+(testnum-1);
dj=1;
di=-1;
break;
case 3:
j=this.j-(testnum-1);
i=this.i-(testnum-1);
dj=1;
di=1;
break;
}

for(int k=0;k<testnum*2+1;k++){
if(j>=0&&j<18&&i>=0&&i<18){
if(ChessState[i][j]==Cplayer.getCurrentIdentify()){
count++;
if(count>=testnum)
return true;
}
else
count=0;
}
j+=dj;
i+=di;
}
return false;
}

//更换当前玩家
void ChangeCurrentPlayer(){
if(Cplayer==Black){
Cplayer=White;
textBlack.setText(Nothing);
textWhite.setText(textwhite);
}
else{
Cplayer=Black;
textBlack.setText(textblack);
textWhite.setText(Nothing);
}
}

//重新开局监听器
private class RestartListener implements ActionListener{

public void actionPerformed(ActionEvent arg0) {

Initialization();
repaint();
requestFocus();
}
}

//棋盘、棋局状态监听器
private class ChessManPerformListener implements KeyListener{

//玩家2的按键
public void keyPressed(KeyEvent event) {
int keyCode=event.getKeyCode();
if(keyCode==KeyEvent.VK_ESCAPE)
System.exit(0);
if(Cplayer.getCurrentIdentify()==2){//判别当前玩家
if(keyCode==KeyEvent.VK_LEFT){
if(cursor.x>40)
cursor.x-=20;
}
else if(keyCode==KeyEvent.VK_RIGHT){
if(cursor.x<380)
cursor.x+=20;
}
else if(keyCode==KeyEvent.VK_UP){
if(cursor.y>60)
cursor.y-=20;
}
else if(keyCode==KeyEvent.VK_DOWN){
if(cursor.y<400)
cursor.y+=20;
}
else if(keyCode==KeyEvent.VK_ENTER){
if(!isChessState()){
Cplayer.PerformChessMan();
RecordChessState();
repaint();
JudgeWin();//判定当前落子后是否赢棋

}

}
repaint();
}
}

public void keyReleased(KeyEvent event) {}

//玩家1的按键
public void keyTyped(KeyEvent event) {

char keyChar=event.getKeyChar();
if(Cplayer.getCurrentIdentify()==1){//判别当前玩家
if(keyChar=='a'){
if(cursor.x>40)//对移动光标超界现象做判别
cursor.x-=20;
}
else if(keyChar=='d'){
if(cursor.x<380)
cursor.x+=20;
}
else if(keyChar=='w'){
if(cursor.y>60)
cursor.y-=20;
}
else if(keyChar=='s'){
if(cursor.y<400)
cursor.y+=20;
}
else if(keyChar==' '){
if(!isChessState()){      //落子前先判断当前位置上是否已有棋子
Cplayer.PerformChessMan();//落子
RecordChessState();//记录当前落子后棋盘状态
repaint();
JudgeWin();//判定当前落子后是否赢棋

}
}

}
repaint();
}

}

}


package WuZiGame;

import java.awt.Color;

class ChessMan {

private static final int ChessManSize=20;
private Color ChessManColor;

ChessMan(Color c){
ChessManColor=c;
}

static int getChessManSize(){
return ChessManSize;
}

Color getChessManColor(){
return ChessManColor;
}

}


package WuZiGame;

import java.awt.Color;

class Player {

private int identify;
private ChessMan pChessMan;
private String PlayerStringIdentify;

Player(int identify,Color c,String sIdentify){
this.identify=identify;
pChessMan=new ChessMan(c);
this.PlayerStringIdentify=sIdentify;
}

int getCurrentIdentify(){
return identify;
}

String getsIdentify(){
return PlayerStringIdentify;
}

void PerformChessMan(){}

Color getplayerChessManColor(){
return pChessMan.getChessManColor();
}
}


【设计结果】

初始界面



下棋中



结束界面



【统计时间】

步骤

耗时

百分比

需求分析

1.5h

13.6%
设计

2h18.2%
代码实现

3h27.3%
测试

2h18.2%
分析总结

2.5h22.7%

【实验心得】

通过这次对Java的学习,让我渐渐体会到了Java的博大精深。以及怎么学习Java,怎么学习计算机语言,怎样对问题进行解决和运用Java GUI,查找的使用都用了更进一步的理解。而且这次两人团队工作,也让我体会到合作的重要意义,两个人的想法经过商讨,研究总会比一个人的好很多,两个人事先做好分工工作再汇总整合也大大提高了效率。刚开始学习Java时我并不是非常的理解,知道就如何做能实现相应的功能,并没有很深刻的去理解它为什么要这么做。这次实验使我明白,真正的用Java去做一个东西不理解它是不行的,而且这个游戏涉及到了Java 中许多的知识点,如Java图形用户界面设计、Java的异常处理机制、Java中的多线程程序设计、Java输入输出流,要应用这些东西更要求我去好好理解Java的这些规则。这次实验,我还是收获良多。虽然界面也不是很美观,有点功能间的连接做的也不是特别的好,但是我能认识到自己的不足,并且在跟队友的交流中也学到了一些的设计思路,也知道今后要加强哪些方面的知识。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: