生命游戏
生命游戏实现代码:
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(j30, 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);
}
}