⽣命游戏(Java,带GUI界⾯)软件⼯程基础实验
⽣命游戏概述:
⽣命游戏是英国数学家约翰·何顿·康威在 1970 年发明的细胞⾃动机,它包括⼀个⼆维矩形世界,这个世界中的每个⽅格居住着⼀个活着的或死亡的细胞。⼀个细胞在下⼀个时刻⽣死取决于相邻⼋个⽅格中活着的或死了的细胞的数量。如果相邻⽅格活着的细胞数量过多,这个细胞会因为资源匮乏⽽在下⼀个时刻死去;相反,如果周围活细胞过少,这个细胞会因太孤单⽽死去。游戏在⼀个类似于围棋棋盘⼀样的,可以⽆限延伸的⼆维⽅格⽹中进⾏。例如,设想每个⽅格中都可放置⼀个⽣命细胞,⽣命细胞只有两种状态:“⽣”或“死”。图中,⽤⿊⾊的⽅格表⽰该细胞为“死”, 其它颜⾊表⽰该细胞为“⽣” 。游戏开始时, 每个细胞可以随机地(或给定地)被设定
为“⽣”或“死”之⼀的某个状态, 然后,再根据如下⽣存定律计算下⼀代每个细胞的状态:
1.每个细胞的状态由该细胞及周围 8 个细胞上⼀次的状态所决定;
2.如果⼀个细胞周围有 3 个细胞为⽣,则该细胞为⽣,即该细胞若原先为死则转为⽣,若原先为⽣则保持不变;
3.如果⼀个细胞周围有 2 个细胞为⽣,则该细胞的⽣死状态保持不变;
4.在其它情况下,该细胞为死,即该细胞若原先为⽣则转为死,若原先为死则保持不变
设计思路:
⾸先通过⽣命游戏概述不难分析出游戏中的两个类(即细胞Cell和⼆维世界World),然后该游戏游戏规则也较为简单,游戏主要逻辑实现不难(主要也就是细胞繁衍换代,代码实现是⽐较简单的)。对于我这个Java⼩⽩来说,最困难的地⽅就在于GUI界⾯的设计,Java的GUI设计,⾸先想到的肯定是javax.swing.*包。然后像“开始游戏”、“结束游戏”等按钮的设计也不⽤多说,游戏的常规套路。重点在于⽤什么控件来表⽰⼀个个细胞,我⾸先想到的是⽤Jtable(表格),我想⽤⼀个⼀个单元格来表⽰细胞,然后通过设置每⼀个单元格的填充颜⾊来表⽰细胞⽣死的状态,但是尝试写了后才发现,Jtable要实现对⼀个单元格格式进⾏设置是不太容易的,⽽且要让整个表格不能编辑也有点复杂(我是Java⼩⽩,⼤佬勿喷),然后就放弃了这个想法。(⼤佬们可以去尝试⼀下这个⽅法,然后教教我)。
灵感来源与最终设计:
⾸先在这⾥感谢这个⼤佬()的⽂章,在这⾥给⼤家分享出来:
该作者是⽤JButton来表⽰⼀个个细胞,其他和上述差不多,对于像我这样的⼩⽩来说,这篇⽂章算是很友好了,作者给出了完整的源代码,感兴趣的⼩伙伴也可以去看看,参考学习⼀下。
然后我仿造该作者的代码,最终还是把这个实验写出来了。为了符合我们的实验要求,我设计了如下四个类:(连我都觉得很牵强)细胞类(Cell)
属性:位置(x,y)、状态(isLive)
⽅法:构造⽅法,x、y、isLive的访问及设置⽅法
⼆维矩形世界(World)
属性:世界⼤⼩(lx,ly)、当前繁衍代数(nowGeneration)、细胞(cell)
⽅法:构造⽅法,lx、ly、nowGeneration、cell[x][y].isLive的访问⽅法,随机初始化细胞(randonInitCell())⽅法,细胞清零(deleteAllCell())⽅法,繁衍换代(updateOfCell())⽅法
GUI界⾯类(GameGUI)
属性:世界界⾯⼤⼩(lx,ly)、⼆维矩形世界(world)、世界界⾯(TWorld)、当前繁衍代数显⽰(NowGeneration)、随机⽣成第⼀代与重新⽣成、开始游戏与结束游戏、暂停游戏与继续游戏、下⼀代、退出按钮(randomInit,BeginAndOver,StopAndContinue,Next,Exit)、游戏进程控制(isRunning)、游戏线程(thread)
⽅法:构造⽅法,初始化界⾯⽅法(initGameGUI()),事件处理⽅法(actionPerformed()),⽣成下⼀代界⾯⽅法(Change()),显⽰世界界⾯⽅法(showWorld())
Main类
属性:游戏GUI界⾯(Game)(表现层),矩形⼆维世界(world)(业务逻辑层)
⽅法:main⽅法
完整源代码:
1.Cell.java
public class Cell {
private int x,y; //细胞位置
private boolean isLive; //细胞状态(true:存活 false:死亡)
public Cell(int x,int y){
this.x=x;
this.y=y;
isLive=false;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public boolean getIsLive() {
return isLive;
}
public void setIsLive(boolean live) {
isLive = live;
}
}
2.World.java
public class World {
private int lx,ly;
private int nowGeneration;
private Cell[][] cell=new Cell[80][80];
public World(int lx,int ly){
this.lx=lx;
this.ly=ly;
nowGeneration=0;
for(int x=0;x<lx;x++)
for(int y=0;y<ly;y++){
for(int y=0;y<ly;y++){
cell[x][y]=new Cell(x,y);
cell[x][y].setIsLive(false);
}
}
public int getLx() {
return lx;
}
public int getLy() {
return ly;
}
public boolean getCellXY(int x, int y){
return cell[x][y].getIsLive();
}
public int getNowGeneration() {
return nowGeneration;
}
//随机初始化细胞
public void randonInitCell(){
for(int x=0;x<lx;x++)
for(int y=0;y<ly;y++)
cell[x][y].setIsLive(Math.random()>0.5?true:false);
}
//细胞清零
public void deleteAllCell(){
for(int x=0;x<lx;x++)
for(int y=0;y<ly;y++)
cell[x][y].setIsLive(false);
nowGeneration=0;
}
//繁衍换代
public void updateOfCell(){
Cell[][] ce=new Cell[lx][ly];
/
/Cell[][] ce=cell;
for(int x=0;x<lx;x++) {
for (int y = 0; y < ly; y++) {
ce[x][y]=new Cell(x,y);
}
}
for(int x=0;x<lx;x++) {
for (int y = 0; y < ly; y++){
int c=0;
for(int i=x-1;i<=x+1;i++){
for(int j=y-1;j<=y+1;j++){
if(i>=0&&i<lx&&j>=0&&j<ly&&cell[i][j].getIsLive())c++; }
}
if(cell[x][y].getIsLive())c--;
if(c==3)ce[x][y].setIsLive(true);
else if(c==2)ce[x][y].setIsLive(cell[x][y].getIsLive());
else ce[x][y].setIsLive(false);
}
}
for(int x=0;x<lx;x++) {
for (int y = 0; y < ly; y++) {
cell[x][y]=ce[x][y];
}
}
nowGeneration++;
nowGeneration++;
}
}
3.GameGUI.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GameGUI extends JFrame implements ActionListener {
int lx,ly;
private World world;
private JButton[][] TWorld;
private JLabel NowGeneration;
private JButton randomInit,BeginAndOver,StopAndContinue,Next,Exit; private boolean isRunning;
private Thread thread;
public GameGUI(String name,World world){
super(name);
this.Lx();
this.Ly();
this.world=world;
initGameGUI();
}
public void initGameGUI(){
JPanel backPanel,bottomPanel,centerPanel;
backPanel= new JPanel(new BorderLayout());
bottomPanel=new JPanel();
centerPanel=new JPanel(new GridLayout(lx,ly));
this.setContentPane(backPanel);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
backPanel.add(centerPanel,"Center");
backPanel.add(bottomPanel,"South");
TWorld=new JButton[lx][ly];
NowGeneration=new JLabel("当前代数:0");
randomInit=new JButton("随机⽣成细胞");
BeginAndOver=new JButton("开始游戏");
StopAndContinue=new JButton("暂停游戏");
Next=new JButton("下⼀代");
Exit=new JButton("退出");
for(int x=0;x<lx;x++){
for(int y=0;y<ly;y++){
TWorld[x][y]=new JButton("");
TWorld[x][y].setBackground(Color.white);
centerPanel.add(TWorld[x][y]);
}
}
bottomPanel.add(randomInit);
bottomPanel.add(BeginAndOver);
bottomPanel.add(StopAndContinue);
bottomPanel.add(Next);
bottomPanel.add(NowGeneration);
bottomPanel.add(Exit);
//设置窗⼝
int sizelx,sizely;
sizelx=Math.min((lx+1)*40,800);
sizely=Math.min(ly*40,1500);
sizely=Math.max(ly*40,500);
this.setSize(sizely,sizelx);
this.setResizable(true);
this.setLocationRelativeTo(null);//让窗⼝居中显⽰
this.setVisible(true);
//注册
this.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e){
}
});
randomInit.addActionListener(this);
BeginAndOver.addActionListener(this);
StopAndContinue.addActionListener(this);
Next.addActionListener(this);
Exit.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == randomInit&&Text()=="开始游戏") {//随机⽣成第⼀代
world.randonInitCell();
showWorld();
isRunning = false;
thread = null;
randomInit.setText("重新⽣成");
} else if (e.getSource() == BeginAndOver && Text() == "开始游戏"&&Text()=="重新⽣成") {//开始游戏 isRunning = true;
thread = new Thread(new Runnable() {
@Override
public void run() {
while (isRunning) {
Change();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
});
thread.start();
BeginAndOver.setText("结束游戏");
} else if (e.getSource() == BeginAndOver && Text() == "结束游戏") {//结束游戏
isRunning = false;
thread = null;
world.deleteAllCell();
showWorld();
BeginAndOver.setText("开始游戏");
StopAndContinue.setText("暂停游戏");
randomInit.setText("随机⽣成细胞");
NowGeneration.setText("当前代数:0");
} else if (e.getSource() == StopAndContinue && Text() == "暂停游戏") {//暂停
isRunning = false;
thread = null;
StopAndContinue.setText("继续游戏");
简单的java游戏代码
} else if (e.getSource() == StopAndContinue && Text() == "继续游戏") {//继续
isRunning = true;
thread = new Thread(new Runnable() {
@Override
public void run() {
while (isRunning) {
Change();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论