总结—2048

总结——2048

 

第一次做成的小游戏

 

1.实现2048游戏界面,需要使用哪些组件?

JButton

JFrame

FlowLayout

Graphics

Color

Font

扫描二维码关注公众号,回复: 1139632 查看本文章

 

2.绘制2048游戏界面

游戏界面要一直存在

   将绘制2048游戏界面的代码放在窗体的paint方法中

 

3.点击按钮,在界面上绘制两个数字

事件

事件源:开始按钮

监听器方法:addActionListener(ActionListener l);

事件接口:ActionListener

 

绘制两个数字

传递Graphics参数

生成2,4的数据

生成2,4放置的位置 

 

4.任务:

1.绘制出界面,能随机两个数

2.每点击一次开始游戏,要重新生成两个数

3.让数据一直保持在界面上(除非点击了开始游戏)

4.按下键盘的上下左右键时,移动数字。

 

 

界面

/**

 * 2048游戏主界面

 * @author HOU

 *

 */

public class Game2048 extends JFrame {

 

/**

 * @param args

 */

public static void main(String[] args) {

Game2048 game = new Game2048();

game.initUI();

}

    //定义一个数组对象,用来储存数据

private int [][] numbers = new int[4][4] ;

 

/**

 * 初始化界面的方法

 */

public void initUI(){

this.setSize(550, 580);

this.setTitle("2048");

this.setDefaultCloseOperation(3);

this.setLocationRelativeTo(null);//居中设置

this.setResizable(false);

this.setLayout(new FlowLayout());

 

JLabel jl = new JLabel("Score");

jl.setPreferredSize(new Dimension(100,50));

 

JButton jb= new JButton("开始游戏");

//让按钮得不到焦点

jb.setFocusable(false);

 

this.add(jb);

this.add(jl);

 

this.setVisible(true);

 

 

//创建事件处理类StartListener的对象sl

StartListener sl = new StartListener(this,numbers, jl);

//给事件源jb按钮添加动作监听器方法,指定事件接口的对象sl

jb.addActionListener(sl);

//给事件源Game2048窗体添加键盘监听器方法,指定事件处理对象sl

this.addKeyListener(sl);

 

}

 

/**

 * 重写窗体的paint方法

 */

 

public void paint(Graphics g){

super.paint(g);//调用父类的方法

//绘制大的背景框

g.setColor(Color.LIGHT_GRAY);

g.fillRoundRect(50, 80, 450, 450,15,15);

//绘制小矩形框颜色

g.setColor(new Color(234,232,232));

//绘制小的格子大小

for(int i=0;i<4;i++){

for(int j=0;j<4;j++){

 g.fillRoundRect(60+i*110, 90+j*110, 100, 100,15,15);

}

}

 

 

 

 

g.setFont(new Font("行书",Font.BOLD,42));

 

//循环数组,判断相应位置是否存在数组,若有,则重绘,若无,则储存

for(int i=0;i<4;i++){

for(int j=0;j<4;j++){

if(numbers[i][j]!=0){

//绘制每个数字的框的颜色

if(numbers[i][j]==2  ){

//绘制数字2的框的颜色和大小

g.setColor(Color.pink);

g.fillRoundRect(60+j*110, 90+i*110, 100, 100,15,15);

//绘制数字颜色和大小

g.setColor(Color.black);

g.drawString(numbers[i][j]+"", 60+j*110+35, 90+i*110+60);

 

 

}

if(numbers[i][j]==4  ){

//绘制数字4的框的颜色和大小

g.setColor(Color.magenta);

g.fillRoundRect(60+j*110, 90+i*110, 100, 100,15,15);

//绘制数字

g.setColor(Color.black);

g.drawString(numbers[i][j]+"", 60+j*110+35, 90+i*110+60);

 

 

}

else if(numbers[i][j]==8 ){

//绘制数字8的框的颜色和大小

g.setColor(Color.CYAN);

g.fillRoundRect(60+j*110, 90+i*110, 100, 100,15,15);

//绘制数字

g.setColor(Color.white);

g.drawString(numbers[i][j]+"", 60+j*110+35, 90+i*110+60);

 

}

else if(numbers[i][j]==16){

//绘制数字16的框的颜色和大小

g.setColor(Color.green);

g.fillRoundRect(60+j*110, 90+i*110, 100, 100,15,15);

g.setColor(Color.white);

g.drawString(numbers[i][j]+"", 60+j*110+25, 90+i*110+65);

}

 

else if(numbers[i][j]==32){

//绘制数字32的框的颜色和大小

g.setColor(Color.yellow);

g.fillRoundRect(60+j*110, 90+i*110, 100, 100,15,15);

//绘制数字大小和颜色

g.setColor(Color.white);

g.drawString(numbers[i][j]+"", 60+j*110+25, 90+i*110+65);

}

 

else if(numbers[i][j]==64){

//绘制数字64的框的颜色和大小

g.setColor(new Color(55,145,43));

g.fillRoundRect(60+j*110, 90+i*110, 100, 100,15,15);

//绘制数字大小和颜色

g.setColor(Color.white);

g.drawString(numbers[i][j]+"", 60+j*110+25, 90+i*110+65);

}

 

else if (numbers[i][j]==128){ 

//绘制数字128的框的颜色和大小

g.setColor(Color.orange);

g.fillRoundRect(60+j*110, 90+i*110, 100, 100,15,15);

//绘制数字大小和颜色

g.setColor(Color.white);

g.drawString(numbers[i][j]+"", 60+j*110+15, 90+i*110+70);

}

else if (numbers[i][j]==256){ 

//绘制数字256的框的颜色和大小

g.setColor(new Color(157,141,30));

g.fillRoundRect(60+j*110, 90+i*110, 100, 100,15,15);

//绘制数字大小和颜色

g.setColor(Color.white);

g.drawString(numbers[i][j]+"", 60+j*110+15, 90+i*110+70);

}

else if (numbers[i][j]==512){

//绘制数字512的框的颜色和大小

g.setColor(new Color(159,61,28));

g.fillRoundRect(60+j*110, 90+i*110, 100, 100,15,15);

//绘制数字大小和颜色

g.setColor(Color.white);

g.drawString(numbers[i][j]+"", 60+j*110+15, 90+i*110+70);

}

 

else if (numbers[i][j]==1024) {

//绘制数字1024的框的颜色和大小

g.setColor(new Color(184,3,3));

g.fillRoundRect(60+j*110, 90+i*110, 100, 100,15,15);

//绘制数字大小和颜色

g.setColor(Color.white);

g.drawString(numbers[i][j]+"", 60+j*110+7, 90+i*110+75);

}

else if (numbers[i][j]==2048) {

//绘制数字2048的框的颜色和大小

g.setColor(Color.RED);

g.fillRoundRect(60+j*110, 90+i*110, 100, 100,15,15);

//绘制数字大小和颜色

g.setColor(Color.white);

g.drawString(numbers[i][j]+"", 60+j*110+7, 90+i*110+75);

}

 

 }

}

}

}

}

界面效果图



 

 

 

监听器

/**

 * 点击开始游戏按钮的事件处理类,该类实现ActionListener接口

 * @author HOU

 *

 */

public class StartListener extends KeyAdapter implements ActionListener {

 

private Graphics g;//声明一个Graphics对象名

private int r1,c1,r2,c2;//声明四个int属性,用来存储数字要绘制的位置

private Random rand = new Random();//创建一个随机数类的对象

private Game2048 game ;//声明game

private int[] [] numbers;//声明数组

private boolean flag;//声明布尔函数

private JLabel jl;

private int score ;

 

 

 

/**

 * 构造方法

 * game界面类的对象

 * numbers储存数据的数组

 */

public StartListener(Game2048 game, int[] [] numbers,JLabel jl){

this.game=game;

this.numbers=numbers;

this.jl = jl;

 

}

 

 

/**

 * 重写接口中的方法,作为事件处理类

 */

@Override

    public void actionPerformed(ActionEvent e){

//清除数组中所有的数据

for(int i=0;i<4;i++){

for(int j=0;j<4;j++){

numbers[i][j]=0;

}

}

flag = true;//初始化flag

score = 0; //初始化score

//生成随机数组的行和列

r1 = rand.nextInt(4);

c1 = rand.nextInt(4);

r2 = rand.nextInt(4);

c2 = rand.nextInt(4);

while(r1==r2 && c1 == c2){

//防止出现在同一个位置

r2 = rand.nextInt(4);

c2 = rand.nextInt(4);

}

//生成两个2或者4

 

int value1 =rand.nextInt(2)*2+2;

int value2 =rand.nextInt(2)*2+2;

 

//将数组储存到对应的数组中

numbers[r1][c1] = value1;

numbers[r2][c2] = value1;

 

//调用paint方法将数字进行重绘

game.paint(game.getGraphics());

 

}

 

 

/*

 * 键盘的释放事件处理方法

 */

 public void keyReleased(KeyEvent e) {

 int count = 0; //计数器,如果计数器不为0,则表示有移动数据

// System.out.println("   "+e.getKeyCode());

 switch(e.getKeyCode()){

 case 37://左

 //循环数组

 for(int i=0;i<4;i++){

 for(int j=0;j<4;j++){

 if(numbers[i][j]!=0){//判断该位置不为0

 int temp = numbers[i][j];//存储该位置的数据

 int c =j-1;

 while(c>=0 && numbers[i][c]==0){

 numbers[i][c]=temp;

 numbers[i][c+1]=0;

 c--;

 count++;//计数器加1,表示移动了一次数据

 

 }

 }

 } 

 } 

 

 

 for(int i=0;i<4;i++){

 for(int j=0;j<4;j++){

 //排除数组都是0的情况   (在没有数组时,默认是0)

if(j+1<4 && numbers[i][j]== numbers[i][j+1] && numbers[i][j]!=0){

 numbers[i][j]=numbers[i][j]+numbers[i][j+1];

 numbers[i][j+1]=0;

 count++;

 score+= numbers[i][j];//设置得分为两数相加

 }

 }

 }

//加完之后要在运行一下移动 否则会出现bug

 for(int i=0;i<4;i++){

 for(int j=0;j<4;j++){

 if(numbers[i][j]!=0){//判断该位置不为0

 int temp = numbers[i][j];//存储该位置的数据

 int c =j-1;

 while(c>=0 && numbers[i][c]==0){

 numbers[i][c]=temp;

 numbers[i][c+1]=0;

 c--;

 count++;

 

 }

 }

 } 

 } 

 

 

 break;

 case 39://右

 //循环数组

 for(int i=0;i<4;i++){

 for(int j=2;j>=0;j--){

 if(numbers[i][j]!=0){//判断该位置不为0

 int temp = numbers[i][j];//存储该位置的数据

 int c =j+1;

 while(c<4 && numbers[i][c]==0){

 numbers[i][c]=temp;

 numbers[i][c-1]=0;

 c++;

 count++;

 

 }

 }

 }

 }

 

 for(int i=0;i<4;i++){

 for(int j=3;j>=0;j--){

 if(j-1>=0 && numbers[i][j]== numbers[i][j-1] && numbers[i][j]!=0){

 numbers[i][j]=numbers[i][j]+numbers[i][j-1];

 numbers[i][j-1]=0;

 count++;

 score+= numbers[i][j];

 }

 }

 }

 for(int i=0;i<4;i++){

 for(int j=2;j>=0;j--){

 if(numbers[i][j]!=0){//判断该位置不为0

 int temp = numbers[i][j];//存储该位置的数据

 int c =j+1;

 while(c<4 && numbers[i][c]==0){

 numbers[i][c]=temp;

 numbers[i][c-1]=0;

 c++;

 count++;

 

 }

 }

 }

 }

 

 break;

 case 38://上

 //循环数组

 for(int i=0;i<4;i++){

 for(int j=0;j<4;j++){

 if(numbers[i][j]!=0){//判断该位置不为0

 int temp = numbers[i][j];//存储该位置的数据

 int r =i-1;

 while(r>=0 && numbers[r][j]==0){

 numbers[r][j]=temp;

 numbers[r+1][j]=0;

 r--;

 count++;

 

 }

 }

 }

 }

 

 for(int i=0;i<4;i++){

 for(int j=0;j<4;j++){

 if(i+1<4 && numbers[i][j]== numbers[i+1][j] && numbers[i][j]!=0){

 numbers[i][j]=numbers[i][j]+numbers[i+1][j];

 numbers[i+1][j]=0;

 count++;

 score+= numbers[i][j];

 }

 }

 }

 for(int i=0;i<4;i++){

 for(int j=0;j<4;j++){

 if(numbers[i][j]!=0){//判断该位置不为0

 int temp = numbers[i][j];//存储该位置的数据

 int r =i-1;

 while(r>=0 && numbers[r][j]==0){

 numbers[r][j]=temp;

 numbers[r+1][j]=0;

 r--;

 count++;

 

 }

 }

 }

 }

 

 

 break;

 case 40://下

 //循环数组

 for(int i=2 ;i>=0;i--){

 for(int j=0;j<4;j++){

 if(numbers[i][j]!=0){//判断该位置不为0

 int temp = numbers[i][j];//存储该位置的数据

 int r =i+1;

 while(r<4 && numbers[r][j]==0){

 numbers[r][j]=temp;

 numbers[r-1][j]=0;

 r++;

 count++;

 

 }

 }

 }

 }

 

 for(int i=0;i<4;i++){

 for(int j=0;j<4;j++){

 if(i-1>=0 && numbers[i][j]== numbers[i-1][j] && numbers[i][j]!=0){

 numbers[i][j]=numbers[i][j]+numbers[i-1][j];

 numbers[i-1][j]=0;

 count++;

 score+= numbers[i][j];

 }

 }

 }

 for(int i=2 ;i>=0;i--){

 for(int j=0;j<4;j++){

 if(numbers[i][j]!=0){//判断该位置不为0

 int temp = numbers[i][j];//存储该位置的数据

 int r =i+1;

 while(r<4 && numbers[r][j]==0){

 numbers[r][j]=temp;

 numbers[r-1][j]=0;

 r++;

 count++;

 

 }

 }

 }

 }

 

 

 break;

 }

 int numbercount =0;//计数  数组的个数(0——16)

 int numbercount2=0;//计数  有数组相同的时候

 for(int i=0 ;i<3 ;i++){

 for(int j=0;j<3;j++){//考虑16个格左上角的9个格

 if(numbers[i][j]==numbers[i][j+1] && numbers[i][j]!=0){

 numbercount2++;

 }

 if(numbers[i][j]==numbers[i+1][j] && numbers[i][j]!=0){

 numbercount2++;

 }

 //考虑剩下的格

 if(numbers[3][j]==numbers[3][j+1] && numbers[3][j]!=0){

 numbercount2++;

 }

 if(numbers[i][3]==numbers[i+1][3] && numbers[i][3]!=0){

 numbercount2++;

 }

 

 }

 }

 for(int i=0 ;i<4 ;i++){

 for(int j=0;j<4;j++){

 if(flag && numbers[i][j]==2048){

 //输出框 

 JOptionPane.showMessageDialog(null"win!");

 //在2048之后还可以运行

 flag = false;

 }

 if (numbers[i][j]!=0 ){

 numbercount++;

 //数组全部布满 并且没有相等的时候

 if(numbercount==16 && numbercount2==0){

 JOptionPane.showMessageDialog(null"lose!");

 }

 }

 }

 }

 if(count>0){//有移动数据的时候

 jl.setText("Score:"+score);

 //生成单元格所在的行和列

 r1 = rand.nextInt(4);

 c1 = rand.nextInt(4);

 while(numbers[r1][c1]!=0){

//防止该位置已经存在值了

r1 = rand.nextInt(4);

c1 = rand.nextInt(4);

 }

 

//生成1个2或者4

int value1 =rand.nextInt(2)*2+2;

//将数组储存到对应的数组中

numbers[r1][c1] = value1;

//调用paint方法将数字进行重绘数字

game.paint(game.getGraphics());

 

 }

 }

 

}

 

测试结果

 

 

 

 

 

失败的时候

 

 

 

 

P.s

代码还不完善,当两个1024出现在一起并且合并的时候,在合并之前就会显示你赢了,而不是生成2048的时候显示

猜你喜欢

转载自what-about-melon.iteye.com/blog/2156649