码迷,mamicode.com
首页 > 其他好文 > 详细

生命游戏

时间:2018-12-13 01:25:20      阅读:258      评论:0      收藏:0      [点我收藏+]

标签:ber   显示   随机数   listen   init   产生   维数   time   ble   

生命游戏实现代码:

package cn.com.demo.game;

import javax.swing.JLabel;

public class Cell extends JLabel {
private int status = 1;// 1活的 0:死

public int getStatus() {
    return status;
}

public void setStatus(int status) {
    this.status = status;
    if(this.status == 1){
        this.setIcon(Resources.LIVING);
    }else{
        this.setIcon(Resources.DEADED);
    }
}

}
////////
package cn.com.demo.game;

import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.JPanel;

/**

  • 初始化细胞
  • 根据算法改变所有细胞下个状态
  • */
    public class CellController {
    // 行数
    private int rowCount = 0;
    // 列数
    private int columnCount = 0;
    // 二维数组
    // List
    private List<Cell[]> celles = new ArrayList<Cell[]>();
    // 存放所有细胞的新状态
    private List<int[]> newStatus = new ArrayList<int[]>();
    // 定义一个产生随机数的对象
    private Random random = new Random();

    private JPanel container;
    /**
    • 初始化所有的细胞,放到容器显示
    • /
      public void initCells(JPanel container){
      this.container = container;
      // 清除所有的旧细胞
      container.removeAll();
      // 获取容器的高度和宽度
      Rectangle rect = container.getBounds();
      int width = rect.width;
      int height = rect.height;
      // 根据容器的大小,计算出一行可以放多少个细胞(x)
      int xCount = width/30;
      this.columnCount = xCount;
      // 根据容器的大小,计算出一共可以放多少行细胞(y)
      int yCount = height/30;
      this.rowCount = yCount;
      // 根据计算的xCount和yCount初始化存放细胞的容器
      Cell[] row = null;
      for(int i=0;i<yCount;i++){
      row = new Cell[xCount];
      this.celles.add(row);
      this.newStatus.add(new int[xCount]);
      }
      // 在容器空格中添加细胞(状态为随机)
      for(int i=0;i<yCount;i++){
      // 获取i对应行的细胞位置
      row = this.celles.get(i);
      for(int j=0;j<xCount;j++){
      // 随机的产生一个细胞,放在当前的位置
      Cell cell = new Cell();
      // 设置一个随机的状态
      int randomNumber = this.random.nextInt(10000);
      int status = randomNumber%3;//0 1 2
      if(status == 2){
      cell.setStatus(1);// 活
      }else{
      cell.setStatus(0);// 死
      }
      // 设置细胞在容器中的位置
      cell.setBounds(j
      30, i*30, 30, 30);
      // 将细胞放入显示的容器中
      container.add(cell);
      // 将细胞放入自己的数据结构中
      row[j] = cell;
      }
      }
      }
      /**
    • 根据细胞现有的状态,计算下一个状态
    • 计算完后,更新所有细胞状态
    • */
      public void changeCellStatus(){
      // 计算所有细胞的下一个状态
      for(int i=0;i<this.rowCount;i++){
      Cell[] row = this.celles.get(i);
      for(int j=0;j<this.columnCount;j++){
      // 计算周围细胞的生命值
      int liveCount = this.computeLivingCount(j, i);
      // 根据周围细胞的生命值,确定当前细胞下一个状态
      if(liveCount>=3){
      this.newStatus.get(i)[j] = 1;
      }else if(liveCount>=2){// 2或 3
      this.newStatus.get(i)[j] = row[j].getStatus();
      }else{
      this.newStatus.get(i)[j] = 0;
      }
      }
      }

      // 根据前面计算的所有细胞的状态值,更新所有细胞的状态
      for(int i=0;i<this.rowCount;i++){
      for(int j=0;j<this.columnCount;j++){
      this.celles.get(i)[j].setStatus(this.newStatus.get(i)[j]);
      }
      }

      this.container.repaint();
      }
      /**
      计算x,y位置细胞的周围一共有多少活的细胞
    • */
      private int computeLivingCount(int x,int y){
      int count = 0;
      int targetX = 0, targetY =0;
      // 获取当前细胞左上角细胞的状态
      targetX = x-1;
      targetY = y -1;
      count += this.getStatus(targetX, targetY);
      // 获取当前细胞上细胞的状态
      targetX = x;
      targetY = y -1;
      count += this.getStatus(targetX, targetY);
      // 获取当前细胞右上角细胞的状态
      targetX = x + 1;
      targetY = y - 1;
      count += this.getStatus(targetX, targetY);
      // 获取当前细胞右细胞的状态
      targetX = x + 1;
      targetY = y;
      count += this.getStatus(targetX, targetY);
      // 获取当前细胞右下角细胞的状态
      targetX = x + 1;
      targetY = y + 1;
      count += this.getStatus(targetX, targetY);
      // 获取当前细胞下角细胞的状态
      targetX = x;
      targetY = y + 1;
      count += this.getStatus(targetX, targetY);
      // 获取当前细胞左下角细胞的状态
      targetX = x - 1;
      targetY = y + 1;
      count += this.getStatus(targetX, targetY);
      // 获取当前细胞左细胞的状态
      targetX = x - 1;
      targetY = y;
      count += this.getStatus(targetX, targetY);

      return count;
      }

    private int getStatus(int x, int y){
    int status = 0;
    if(x>=0 && x<this.columnCount && y>=0 && y<this.rowCount){
    status = this.celles.get(y)[x].getStatus();
    }
    return status;
    }
    }
    ///////
    package cn.com.demo.game;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainUI extends JFrame {
private CellController cellController = null;
private TimeController timeController = null;
private JPanel sub2;
public MainUI(){
cellController = new CellController();
init();
}

private void init(){
    // 设置窗口的大小
    this.setSize(600, 500);
    // 设置窗口显示的位置(居中)
    this.setLocationRelativeTo(null);
    // 设置窗口的标题
    this.setTitle("细胞游戏");
    // 点击x关闭窗口
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // 设置不允许改变窗口的大小
    this.setResizable(false);
    
    
    // 在窗口中放一个大容器
    // 创建容器对象
    JPanel container = new JPanel();
    // 设置容器的背景颜色
    container.setBackground(Color.green);
    // 设置布局管理器,以便于自己控制容器中其他对象的位置和大小
    container.setLayout(null);
    // 将容器加入窗口
    this.setContentPane(container);
    
    // 操作第一个子容器
    // 创建容器对象
    JPanel sub1 = new JPanel();
    sub1.setBackground(Color.white);
    sub1.setBounds(5, 5, 585, 50);
    sub1.setLayout(null);
    // 将子容器加入大容器
    container.add(sub1);
    
    // 在sub1容器里面,添加2个按钮和一个显示时间的标签
    // 创建开始按钮对象
    JButton btnStart = new JButton("开始游戏");
    btnStart.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            cellController.initCells(sub2);
            if(timeController != null){
                timeController.setStop();
            }
            timeController = new TimeController(cellController);
            // 启动时间控制器
            timeController.start();
        }
    });
    // 设置开始按钮对象的位置
    btnStart.setBounds(10, 10, 110, 30);
    // 将开始按钮添加到sub1容器中
    sub1.add(btnStart);
    // 创建暂停和继续按钮
    JButton btnPause = new JButton("暂停/继续");
    btnPause.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            // 暂停时间控制器
            timeController.changePauseStatus();
        }
    });
    btnPause.setBounds(130, 10, 110, 30);
    sub1.add(btnPause);
    // 创建显示时间的标签对象
    TimeLabel lblTime = new TimeLabel("游戏进行了3分43秒");
    lblTime.setBounds(300, 10, 200, 30);
    sub1.add(lblTime);
    
    // 第二个子容器
    sub2 = new JPanel();
    sub2.setBackground(Color.white);
    sub2.setBounds(5, 60, 585, 405);
    sub2.setLayout(null);
    container.add(sub2);
    
    // 调用细胞控制器的方法,初始容器中的所有细胞
    this.cellController.initCells(sub2);
}

}
/////
package cn.com.demo.game;

import javax.swing.Icon;
import javax.swing.ImageIcon;

public class Resources {
public static Icon LIVING;
public static Icon DEADED;

static{

   LIVING = new ImageIcon(Resources.class.getResource("/images/1.png"));
   DEADED = new ImageIcon(Resources.class.getResource("/images/2.png"));

}
}

////
package cn.com.demo.game;
/
定时器
/
public class TimeController extends Thread {
private CellController cellController;
private boolean isRun = true;
private boolean isPause = false;
public TimeController(CellController c){
this.cellController = c;
}

public void setStop(){
    this.isPause = false;
    this.isRun = false;
}

public void run(){
    while(isRun){
        System.out.println("****************111");
        // 定时更新细胞的状态
        this.cellController.changeCellStatus();
        try {
            // 1.5秒
            sleep(1500);
            // 控制暂停
            while(this.isPause){
                sleep(1000);
            }
        } catch (InterruptedException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }
}
// 改变是否暂停
public void changePauseStatus(){
    this.isPause = !this.isPause;
}

}

/////
package cn.com.demo.game;

import javax.swing.JLabel;

public class TimeLabel extends JLabel {
public TimeLabel(){
super();
}
public TimeLabel(String str){
super(str);
}
}
/////
package cn.com.demo.game;

public class Client {

public static void main(String[] args) {
    MainUI game = new MainUI();
    game.setVisible(true);
}

}

生命游戏

标签:ber   显示   随机数   listen   init   产生   维数   time   ble   

原文地址:https://www.cnblogs.com/panxubin1011703/p/10111575.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!