用到的知识
1.窗体界面
JFrame窗体的基本设置
2.事件机制
给窗体位置坐标加监听器,实现下棋的功能
3.图形的重绘,由于窗体显示,窗体会重绘两次,而画上去图像如果不加重绘方法,图像就不会显现,如最小化界面,移动界面等等,每移动一次,界面都是有系统调用重绘方法重新画界面,而上面的图像如果不定义重绘方法就不会再出现
4.数组你还没学过数组
神奇的数组,此小游戏中,用数组储存下过的旗子,黑白棋有标志分开,可以用于判断该交叉点是否有下过棋子,判断是否五子相连,数组用在此处很恰当,
package chess;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
public class ChessFrame extends JFrame{
/**
* @param args
*/
//入口函数
public static void main(String[] args) {
// TODO Auto-generated method stub
ChessFrame frame=new ChessFrame();
frame.initGUI();
}
//定义初始化界面方法
public void initGUI(){
this.setSize(new Dimension(580,600));
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
this.setVisible(true);
//再创体显现之后,取得窗体画布图像
Graphics g=this.getGraphics();
//实例化处理器类
ChessMouseListener cml=new ChessMouseListener(g);
//给窗体加上监听器
this.addMouseListener(cml);
}
//棋盘的重绘
public void paint(Graphics g){
//横线
for(int i=0;i<Fig.LINE_H;i++){
g.drawLine(Fig.X, Fig.Y+i*Fig.SIZE, Fig.X+Fig.SIZE*(Fig.LINE_H-1), Fig.Y+i*Fig.SIZE);
}
//竖线
for(int i=0;i<Fig.LINE_V;i++){
g.drawLine(Fig.X+i*Fig.SIZE, Fig.Y, Fig.X+i*Fig.SIZE, Fig.Y+Fig.SIZE*(Fig.LINE_V-1));
}
/****************旗子的重绘************************/
for(int n=0;n<Fig.arr.length;n++){
for(int m=0;m<Fig.arr[n].length;m++){
//计算交叉点坐标
int x=Fig.X+n*Fig.SIZE;
int y=Fig.Y+m*Fig.SIZE;
if(Fig.arr[n][m]==1){
g.setColor(Color.BLACK);
g.fillOval(x-Fig.SIZE/2, y-Fig.SIZE/2, Fig.SIZE, Fig.SIZE);
}else if(Fig.arr[n][m]==-1){
g.setColor(Color.WHITE);
g.fillOval(x-Fig.SIZE/2, y-Fig.SIZE/2, Fig.SIZE, Fig.SIZE);
}
}
}
}
}
package chess;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ChessMouseListener extends MouseAdapter{
//定义整形属性获取鼠标点击坐标
private int x,y;
//定义绘制棋子的属性
private Graphics g;
//定义黑白棋的标志值
private int state=1;
/**
*
* 构造方法,赋给属性的参数名
*/
//覆写父类方法
public void mouseClicked(MouseEvent e){
//取得点击的坐标值
x=e.getX();
y=e.getY();
//循环进行下棋
for(int i=0;i<Fig.LINE_H;i++){
for(int j=0;j<Fig.LINE_V;j++){
if(Fig.arr[i][j]==0){
//判断交叉点的坐标
int r=Fig.X+Fig.SIZE*i;
int c=Fig.Y+Fig.SIZE*j;
//计算出鼠标点击位置与交叉点的绝对值
int tempX=Math.abs(r-x);
int tempY=Math.abs(c-y);
if(tempX<Fig.SIZE/2&&tempY<Fig.SIZE/2){
x=r;
y=c;
// }else if(tempX<Fig.SIZE/2&&tempY>Fig.SIZE/2){
// x=r;
// y=c+Fig.SIZE;
// }else if(tempX>Fig.SIZE/2&&tempY<Fig.SIZE/2){
// x=r+Fig.SIZE;
// y=c;
// }else if(tempX>Fig.SIZE/2&&tempY>Fig.SIZE/2){
// x=r+Fig.SIZE;
// y=c+Fig.SIZE;
// }
//将旗子储存在数组中
Fig.arr[i][j]=state;
//判断是否下过棋子
if(state==1){
g.setColor(Color.BLACK);
g.fillOval(x-Fig.SIZE/2, y-Fig.SIZE/2, Fig.SIZE, Fig.SIZE);
state=-1;
}else {
g.setColor(Color.WHITE);
g.fillOval(x-Fig.SIZE/2, y-Fig.SIZE/2, Fig.SIZE, Fig.SIZE);
state=1;
}
Win win=new Win();
boolean bool=win.validate(i, j);
if(bool){
if(state==1)
System.out.println("白棋胜利");
if(state==-1)
System.out.println("黑棋胜利");
}
return;
}
}
}
}
}
public ChessMouseListener(Graphics g){
this.g=g;
}
}
package chess;
public interface Fig {
//起始位置X
public static final int X=35;
//起始位置Y
public static final int Y=50;
//横线
public static final int LINE_H=15;
//竖线
public static final int LINE_V=15;
//棋子大小
public static final int CHESS=35;
//网格大小
public static final int SIZE=35;
//存储棋子的数组
public static final int arr[][]=new int[LINE_H][LINE_V];
}
package chess;
public class Win {
int count=1;
public boolean validate(int r,int c){
boolean state=false;
//是否五子相连
// if(winH(r,c)>=5){
// //如相连,返回真值
// state=true;
// }else{
// state=false;
// }
// return state;
//
if(winH(r,c)>=5||winV(r,c)>=5||winR(r,c)>=5||winL(r,c)>=5){
state=true;
}
return state;
}
//横向相连的个数
public int winH(int r,int c){
for(int i=r+1;i<Fig.arr.length;i++){
if(Fig.arr[i][c]==Fig.arr[r][c]){
count++;
}else {
break;
}
}
for(int i1=r-1;i1>=0;i1--){
if(Fig.arr[i1][c]==Fig.arr[r][c]){
count++;
}else {
break;
}
}
// System.out.println("棋相连个数"+count);
return count;
}
//竖行相连的个数
public int winV(int r,int c){
// int count=1;
for(int i=c+1;i<Fig.arr.length;i++){
if(Fig.arr[r][i]==Fig.arr[r][c]){
count++;
}else {
break;
}
}
for(int i1=c-1;i1>=0;i1--){
if(Fig.arr[r][i1]==Fig.arr[r][c]){
count++;
}else {
break;
}
}
return count;
}
//斜右
public int winR(int r,int c){
// int count=1;
// int i,j;
for(int i=r+1, j=c+1;i<Fig.arr.length&&j<Fig.arr[i].length;i++,j++){
if(Fig.arr[i][j]==Fig.arr[r][c]){
count++;
}else {
break;
}
}
for(int i=r-1,j=c-1;i>=0&&j>=0;i--,j--){
if(Fig.arr[i][j]==Fig.arr[r][c]){
count++;
}else {
break;
}
}
return count;
}
public int winL(int r,int c){
// int count=1;
int i,j;
for( i=r+1, j=c-1;i<Fig.arr.length&&j>=0;i++,j--){
if(Fig.arr[i][j]==Fig.arr[r][c]){
count++;
}else {
break;
}
}
for(i=r-1,j=c+1;i>=0&&j<Fig.arr[i].length;i--,j++){
if(Fig.arr[i][j]==Fig.arr[r][c]){
count++;
}else {
break;
}
}
return count;
}
}