利用java cavas开发生命游戏

本文介绍了使用JavaCanvas开发的康威生命游戏,包括Space、Cell和Group类的设计,展示了如何模拟二维格子中细胞的存活与死亡规则,以及如何通过线程实现动态更新显示。
摘要由CSDN通过智能技术生成

生命游戏(Conway's Game of Life),又称为康威生命游戏、生命棋、康威生命棋,是一款零玩家游戏,由英国数学家约翰·霍顿·康威在1970年发明。这个游戏模拟了一个二维的格子世界,每个格子居住着一个生命细胞,每个细胞在下一个时间点只能处于两种状态之一:存活或死亡。

游戏规则如下:

  1. 任何有三个邻居的死细胞将会复活。
  2. 任何有两个邻居的细胞状态保持不变。
  3. 其他所有情况,细胞将会死亡。

其中,“邻居”是指一个细胞上下左右以及对角线方向的八个相邻细胞。

下面开始设计:

  1. 生命空间Space
  2. 生命细胞Cell
  3. 生命细胞组合在一起的时候,会有一些表现,Group

这里利用java的cavas开发,代码如下

1、Space类

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

import static Constant.*;


public class Space extends JFrame {

    public void launch() {
        this.setSize(1920, 1080);
        this.setLocation(0, 0);
        this.setVisible(true);
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    //画出分割线
    private void paintLine(Graphics g){
        for(int i=0;i< width;i++){
            g.drawLine(LENGTH*i,0,LENGTH*i,1080);
        }

        for(int j=0;j<height;j++){
            g.drawLine(0,LENGTH*j,1920,LENGTH*j);
        }
    }

    /**
     * 继承gui方法,画出gui界面
     * @param g
     */
    @Override
    public void paint(Graphics g){
        g.setColor(new Color(42,17,21));
        g.fillRect(0,0,1920,1080);
        super.paint(g);
        g.setColor(new Color(147,147,147));
        paintLine(g);
    }

    //双缓冲
    private Image offScreenImage = null;
    @Override
    public void update(Graphics g){
        System.out.println(1);
        if(offScreenImage == null){
            System.out.println(2);
            offScreenImage = this.createImage(1920,1080);
        }
        System.out.println(3);
        Graphics gOff = offScreenImage.getGraphics();
        paint(gOff);
        g.drawImage(offScreenImage,0,0,null);
        System.out.println(4);
    }


}

2、Cell类

import java.awt.*;
import static Constant.*;

public class Cell {
    private int x=0;
    private int y=0;
    private boolean status=false;//true:存活;false:死亡

    public Cell(int x, int y){
        this.x=x;
        this.y=y;
    }

    public void setStatus(boolean status){
        this.status = status;
    }

    public boolean isStatus() {
        return status;
    }

    /**
     * 在gui上画的方法
     */

    public void paint(Graphics2D g){
        //如果存活,则画图
        if(status)
            g.fillRect(x* LENGTH-6,y*LENGTH-3,LENGTH-5,LENGTH-5);
    }


}

3、Group类

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


import static Constant.*;

public class Group extends JPanel {

    //定义细胞数组,对应相应格子的生命
    public Cell[][] cellArray;


    /**
     * 构造方法
     */
    public Group(){
        //初始化细胞
        cellArray= new Cell[width][height];
        for(int i=0;i<width;i++){
            for(int j=0;j<height;j++){
                cellArray[i][j]=new Cell(i,j);
            }
        }
    }

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        //转换为2d获得更高级的功能
        Graphics2D g2d = (Graphics2D)g;
        g2d.setColor(new Color(28,159,32));
        //更新页面
        refreshCellArray(g2d);

    }

    /**
     * 返回对应位置的细胞
     * @param x
     * @param y
     * @return
     */
    public Cell getCellxy(int x,int y){
        if(x<0||x>=width||y<0||y>=height){
            return null;
        }
        return cellArray[x][y];
    }



    /**
     * 刷新细胞状态
     */
    public void refreshCellArray(Graphics2D g){
        Cell[][] nextCellArray = new Cell[width][height];
        //赋值
        for(int i=0;i<width;i++){
            for(int j=0;j<height;j++){
                nextCellArray[i][j]=new Cell(i,j);
                nextCellArray[i][j].setStatus(cellArray[i][j].isStatus());
            }
        }

        //刷新页面
        for(int i=0;i<width;i++){
            for(int j=0;j<height;j++){
                boolean nextStatus = NumUtils.nextGenerationStatus(i,j,width,height,nextCellArray);
                cellArray[i][j].setStatus(nextStatus);
                cellArray[i][j].paint(g);
            }
        }
    }



}

4、Main方法

import static Constant.FREQUENCY;

public class Main {
    Space space = null;
    Group  group = null;
    public static void main(String[] args) {
        Main run = new Main();
    }

    public Main(){
        //生成空间
        space = new Space();
        //生成细胞群
        group = new Group();
        //初始化细胞
        this.initCellArray(group);

        space.getContentPane().add(group);
        space.launch();
        //线程
        new PaintThread().start();
    }

    //构造初始生命
    public void initCellArray(Group group){
        //滑翔机
        group.getCellxy(10,10).setStatus(true);
        group.getCellxy(11,11).setStatus(true);
        group.getCellxy(9,12).setStatus(true);
        group.getCellxy(10,12).setStatus(true);
        group.getCellxy(11,12).setStatus(true);

    }

    //线程
    class PaintThread extends Thread{
        @Override
        public void run(){
            while (true){
                space.repaint();
                try{
                    Thread.sleep(FREQUENCY);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

5、工具类NumUtils

public class NumUtils {
    /**
     * 判断x,y是否超出二维数组范围
     * @param x
     * @param y
     * @param width
     * @param length
     * @return
     */
    public static boolean isOut(int x,int y,int width,int length){
        if(x<0||x>=width||y<0||y>=length){
            return false;
        }
        return true;
    }

    /**
     * 判断下一代状态
     * 如果周围3个细胞生存,则它为生
     * 如果周围2个细胞生存,则不变
     * 其他情况,则为死
     * @return
     */
    public static boolean nextGenerationStatus(int x, int y, int width, int length, Cell[][] cellArray){
        int number = 0;//计算周围生存细胞的数量
        //计算周边存活数量
        int[][] matrix = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
        for(int i=0;i<matrix.length;i++){
            if(NumUtils.isOut(x+matrix[i][0],y+matrix[i][1],width,length)&&cellArray[x+matrix[i][0]][y+matrix[i][1]].isStatus()){
                number++;
            }
        }

        //判断状态
        if(number==3){
            return true;
        }else if(number==2){
            return cellArray[x][y].isStatus();
        }
        return false;
    }
}

6、参数Constant

public class Constant {
    public static int LENGTH = 15;//每格生命所占屏幕项目的长度
    public static long FREQUENCY = 200;//页面刷新频率200ms/次
    public static int width = 1920 / LENGTH;//从左往右
    public static int height = 1080 / LENGTH;//从上往下
}

运行Main方法后即在界面上看到细胞的演化情况。

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CDKingHang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值