界面小游戏--五子棋

用到的知识

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;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值