先上一张界面图:
棋盘类:
package com.dhee.checkerboard;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
public class Checkerboard extends Frame {
//白棋玩家代号
public static final int WIITH_PERFORMER = 1;
//黑棋玩家代号
public static final int BLACK_PERFORMER = 2;
/**
*
*/
private static final long serialVersionUID = 1L;
//游戏结束标识
private boolean over = false;
//当前下子权归属
private int presentPerformer = WIITH_PERFORMER;
//15*15 棋盘位置是否有棋子
// 0: 无棋子
// WIITH_PERFORMER: 白色棋子
// BLACK_PERFORMER: 黑色棋子
private int hasChess[][] = new int[15][15];
private int chessR = 19;
public Checkerboard(){
//将棋盘15*15个位置全部设置为无棋子
for(int i=0;i<15;i++){
for(int j=0;j<15;j++){
hasChess[i][j] = 0;
}
}
}
//画棋盘
public void drawCheckerboard(){
this.setTitle("Eviler's Checkerboard");
ImageIcon icon = new ImageIcon("resource/images/peppa_icon.png");
this.setIconImage(icon.getImage());//更改图标
this.setLayout(new FlowLayout());
this.setBounds(100,100,640,660);
this.setVisible(true);
this.setResizable(false);
this.setBackground(new Color(189,154,101));
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
clickEventListener();
}
//棋盘点击绑定
private void clickEventListener(){
this.addMouseListener(new MouseAdapter(){
//鼠标点击绑定
public void mouseReleased(MouseEvent e){
paintChess(new Point(e.getX(),e.getY()),chessR);
}
});
}
//画棋盘-横线
private void drawRowLine(Graphics g) {
g.setColor(Color.LIGHT_GRAY);
for(int i=40;i<640;i+=40){
g.drawLine(0,i+20,640,i+20);
}
}
//画棋盘-竖线
private void drawColumnLine(Graphics g) {
g.setColor(Color.LIGHT_GRAY);
for(int i=40;i<640;i+=40){
g.drawLine(i,0,i,660);
}
}
//画棋盘-五个点
private void drawFiveSpot(Graphics g) {
int soptR = 12;
g.setColor(Color.BLACK);
g.fillOval(160-soptR/2, 160+20-soptR/2, soptR, soptR);
g.fillOval(480-soptR/2, 160+20-soptR/2, soptR, soptR);
g.fillOval(320-soptR/2, 320+20-soptR/2, soptR, soptR);
g.fillOval(160-soptR/2, 480+20-soptR/2, soptR, soptR);
g.fillOval(480-soptR/2, 480+20-soptR/2, soptR, soptR);
}
//绘画函数
public void paint(Graphics g) {
drawRowLine(g);
drawColumnLine(g);
drawFiveSpot(g);
repaintChess(g);
}
//重绘(最小化后重新打开前面的棋子会消失,加上重绘防止)
public void repaintChess(Graphics g ){
System.out.println("repint");
for(int i=0;i<15;i++){
for(int j=0;j<15;j++){
if(hasChess[i][j] == WIITH_PERFORMER){
//重绘-画棋子
g.setColor(Color.WHITE);
g.fillOval((i+1)*40-chessR, (j+1)*40+20-chessR, chessR*2, chessR*2);
}
if(hasChess[i][j] == BLACK_PERFORMER){
//重绘-画棋子
g.setColor(Color.BLACK);
g.fillOval((i+1)*40-chessR, (j+1)*40+20-chessR, chessR*2, chessR*2);
}
}
}
}
//画棋子
// center: 棋子中点
// r: 棋子半径
public void paintChess(Point center,int r){
//调整中心点,使之变成棋盘横竖线交叉点
center = pointAdjust(center);
//如果超出棋盘范围
if(center.x < 40 ||center.y < 60 || center.x > 600||center.y > 620){
return;
}
//判断该位置是否已有棋子
if(hasChess[center.x / 40 - 1][center.y / 40 - 1] > 0){
return;
}
//获取绘图环境
Graphics g = this.getGraphics();
if(presentPerformer == WIITH_PERFORMER){
//绘图-画棋子
g.setColor(Color.WHITE);
g.fillOval(center.x-r, center.y-r, r*2, r*2);
//将所在位置hasChess标识赋相应的值
hasChess[center.x/40-1][center.y/40-1] = WIITH_PERFORMER;
//将下子权交给另一位玩家
presentPerformer = BLACK_PERFORMER;
}
else{
getGraphics().setColor(Color.BLACK);
g.fillOval(center.x-r, center.y-r, r*2, r*2);
hasChess[center.x/40-1][center.y/40-1] = BLACK_PERFORMER;
presentPerformer = WIITH_PERFORMER;
}
//判断是否有玩家获胜
int hasSomeonePlayerWon = hasSomeonePlayerWon(center.x/40-1,center.y/40-1);
if(hasSomeonePlayerWon != 0){
setOver(true);
String message = hasSomeonePlayerWon == WIITH_PERFORMER?"白棋获胜":"黑棋获胜";
//通知玩家游戏结束,告知玩家获胜方
showMessageBox("已有玩家获胜", message);
//重新开始游戏
restart();
};
}
//棋子中心调整函数,将某个点调整为棋盘上横竖线交叉的点
public Point pointAdjust(Point oldPoint){
int newX = oldPoint.x;
int newY = oldPoint.y;
if(newX % 40 < 20){
newX = newX -newX % 40;
}
else{
newX = newX -newX % 40 +40;
}
if(newY % 40 < 20){
newY = newY - newY % 40 +20;
}
else{
newY = newY - newY % 40 + 20;
}
return new Point(newX, newY);
}
//重新开始
public void restart(){
setOver(false);
presentPerformer = WIITH_PERFORMER;
for(int i=0;i<15;i++){
for(int j=0;j<15;j++){
hasChess[i][j] = 0;
}
}
this.repaint();
}
//判断是否有玩家获胜
public int hasSomeonePlayerWon(int i,int j) {
int winner = 0;
if(hasChess[i][j] == WIITH_PERFORMER){
if(judgeIsWon(i,j,WIITH_PERFORMER)){
winner =WIITH_PERFORMER;
}
}
if(hasChess[i][j] == BLACK_PERFORMER){
if(judgeIsWon(i,j,BLACK_PERFORMER)){
winner = BLACK_PERFORMER;
}
}
return winner;
}
//判断代号为player的玩家是否获胜,获胜返回true,否则返回false
public boolean judgeIsWon(int i,int j, int player){
int sameColorNum = 0;
int sameColorLeft = 0;
int sameColorRight = 0;
//判断刚下完的棋子左右是否能连成5个
sameColorLeft = 0;
sameColorRight = 0;
for(int l=i-1; l>=0; l--){
if(hasChess[l][j] == player){
sameColorLeft++;
}
else{
break;
}
}
for(int l=i; l<15; l++){
if(hasChess[l][j] == player){
sameColorRight++;
}
else{
break;
}
}
sameColorNum = sameColorLeft + sameColorRight;
if(sameColorNum >= 5){
return true;
}
//判断刚下完的棋子上下是否能连成5个
sameColorLeft = 0;
sameColorRight = 0;
for(int l=j-1; l>=0; l--){
if(hasChess[i][l] == player){
sameColorLeft++;
}
else{
break;
}
}
for(int l=j; l<15; l++){
if(hasChess[i][l] == player){
sameColorRight++;
}
else{
break;
}
}
sameColorNum = sameColorLeft + sameColorRight;
if(sameColorNum >= 5){
return true;
}
//判断刚下完的棋子左上到右下是否能连成5个
sameColorLeft = 0;
sameColorRight = 0;
for(int m=i-1,n=j-1; m>=0 && n>=0; m--,n--){
if(hasChess[m][n] == player){
sameColorLeft++;
}
else{
break;
}
}
for(int m=i,n=j; m<15 && n<15; m++,n++){
if(hasChess[m][n] == player){
sameColorRight++;
}
else{
break;
}
}
sameColorNum = sameColorLeft + sameColorRight;
if(sameColorNum >= 5){
return true;
}
//判断刚下完的棋子左下到右上是否能连成5个
sameColorLeft = 0;
sameColorRight = 0;
for(int m=i-1,n=j+1; m>=0 && n<15; m--,n++){
if(hasChess[m][n] == player){
sameColorLeft++;
}
else{
break;
}
}
for(int m=i,n=j; m<15 && n>=0; m++,n--){
if(hasChess[m][n] == player){
sameColorRight++;
}
else{
break;
}
}
sameColorNum = sameColorLeft + sameColorRight;
if(sameColorNum >= 5){
return true;
}
return false;
}
//调用库函数弹窗,以方便告知用户一些游戏信息
public void showMessageBox(String title,String description){
JOptionPane.showMessageDialog(null,description,title,JOptionPane.PLAIN_MESSAGE);
}
public boolean isOver() {
return over;
}
public void setOver(boolean over) {
this.over = over;
}
}
main类:
package com.dhee.checkerboard;
public class Main {
public static void main(String[] args) {
Checkerboard cb = new Checkerboard();
cb.drawCheckerboard();
}
}
将两个的Java类文件放在同一包下运行主就可以,我的包名是com.dhee.checkerboard,实现原理都在注释里面,初次使用AWT,水平有限,还请大佬多多指教!