如何使用Java实现经典游戏2048

如何使用Java实现经典游戏2048

这篇文章主要介绍如何使用Java实现经典游戏2048,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

    主要设计

    1、游戏面板生成显示

    2、方块设计

    3、键盘监听,方向键控制数字移动

    4、数字移动逻辑算法处理

    5、数字累加到2048,游戏胜利

    功能截图

    游戏开始

    移动效果

    代码实现

    界面布局类

    publicclassGame2048ViewimplementsActionListener{Block[]blocks;//方块JPanelmyJPanel;//主面板JPaneljp1,jp2;//子面板//intmoveFlag;//用于累计移动的次数booleannumFlag;//用于判断是否还能加入新的数字JLabelscroeValue;//显示分数publicGame2048View(JFramemyJFrame){blocks=newBlock[16];//moveFlag=0;numFlag=true;this.myJPanel=(JPanel)myJFrame.getContentPane();///获取内容面板setJp1();myJPanel.add(jp1,BorderLayout.NORTH);setJp2();myJPanel.add(jp2,BorderLayout.CENTER);myJFrame.addKeyListener(newGame2048Logic(this,myJFrame,blocks,numFlag,scroeValue));}publicvoidaddc(JPaneljp1,Componentcomponent,GridBagConstraintsgbc,intgridwidth,intgridheight,intweightx,intweighty,intgridx,intgridy){//此方法用来添加控件到容器中gbc.gridwidth=gridwidth;//该方法是设置组件水平所占用的格子数,如果为0,就说明该组件是该行的最后一个gbc.gridheight=gridheight;//该方法是设置组件垂直所占用的格子数gbc.weightx=weightx;//该方法设置组件水平的拉伸幅度,如果为0就说明不拉伸,不为0就随着窗口增大进行拉伸,0到1之间gbc.weighty=weighty;//该方法设置组件垂直的拉伸幅度,如果为0就说明不拉伸,不为0就随着窗口增大进行拉伸,0到1之间gbc.gridx=gridx;gbc.gridy=gridy;gbc.fill=GridBagConstraints.BOTH;jp1.add(component,gbc);}publicvoidsetJp1(){GridBagLayoutgbLayout=newGridBagLayout();jp1=newJPanel(gbLayout);JPanelJtitle=newJPanel();JLabeltitle=newJLabel("2048");title.setFont(newFont("font",Font.PLAIN,45));//类型、风格、大小title.setHorizontalAlignment(JLabel.LEFT);//jLabel的文本左右对齐属性设置方法,对齐方式Jtitle.add(title);jp1.add(Jtitle);JPanelJscroe=newJPanel(newGridLayout(2,1));//newGridLayout(2,1)为网格布局样式。其中的参数“2”“1”分别为网格的“行数”和“列数”。JLabelscroe=newJLabel("Scroe");scroe.setFont(newFont("font",Font.PLAIN,16));scroe.setHorizontalAlignment(JLabel.CENTER);scroeValue=newJLabel("0");scroeValue.setFont(newFont("font",Font.PLAIN,16));scroeValue.setHorizontalAlignment(JLabel.CENTER);Jscroe.add(scroe);Jscroe.add(scroeValue);jp1.add(Jscroe);JPanelJnoite=newJPanel();JLabelnoite=newJLabel("方向键移动数字累加至2048");noite.setFont(newFont("font",Font.PLAIN,14));noite.setHorizontalAlignment(JLabel.LEFT);Jnoite.add(noite);jp1.add(Jnoite);JPanelJnewGame=newJPanel();JButtonnewGame=newJButton("NewGame");newGame.setHorizontalAlignment(JButton.CENTER);newGame.addActionListener(this);JnewGame.add(newGame);jp1.add(JnewGame);GridBagConstraintsgbc=newGridBagConstraints();addc(jp1,Jtitle,gbc,3,2,60,60,0,0);addc(jp1,Jscroe,gbc,0,2,40,60,3,0);addc(jp1,Jnoite,gbc,3,1,60,40,0,2);addc(jp1,JnewGame,gbc,0,1,40,40,3,2);}publicvoidsetJp2(){addBlock();initBlock();initBlock();}/***添加方块*/publicvoidaddBlock(){jp2=newJPanel();/**setLayout是对当前组件设置为流式布局.组件在窗体中从左到右依次排列如果排到行的末尾换行排列*GridLayout(introws,intcols,inthgap,intvgap)创建具有指定行数和列数的网格布局。rows-该rows具有表示任意行数的值cols-该cols具有表示任意列数的值hgap-水平间距vgap-垂直间距*/jp2.setLayout(newGridLayout(4,4,5,5));for(inti=0;i<blocks.length;i++){blocks[i]=newBlock();blocks[i].setHorizontalAlignment(JLabel.CENTER);//不透明的标签blocks[i].setOpaque(true);//设置控件不透明jp2.add(blocks[i]);}}/***初始化方块*/publicvoidinitBlock(){while(numFlag){intindex=(int)(Math.random()*16);if(blocks[index].getText().trim().equals("")){blocks[index].setValue("2");break;}else{continue;}}}/***获得第一个子面板的高度*/publicintgetMyJPanelHeidth(){returnjp1.getSize().height;}@OverridepublicvoidactionPerformed(ActionEvente){//TODO自动生成的方法存根newGame();}/***重新开始游戏*/publicvoidnewGame(){for(inti=0;i<blocks.length;i++){blocks[i].setValue("");}numFlag=true;scroeValue.setText("0");initBlock();initBlock();}}

    业务逻辑类

    publicclassGame2048LogicimplementsKeyListener{Block[]blocks;booleannumFlag;//用于判断是否还能加入新的数字JLabelscroeValue;//显示分数intblocksarr[]=newint[4];//保存一行/列方块中的数值JFramemyJFrame;intscroe=0;Game2048Viewgame2048View;//初始化键盘事件publicGame2048Logic(Game2048Viewgame2048View,JFramemyJFrame,Block[]blocks,booleannumFlag,JLabelscroeValue){//TODO自动生成的构造函数存根this.blocks=blocks;this.numFlag=numFlag;this.scroeValue=scroeValue;this.myJFrame=myJFrame;this.game2048View=game2048View;}//初始化按钮事件publicGame2048Logic(){//TODO自动生成的构造函数存根}publicbooleangetnumFlag(){returnnumFlag;}@OverridepublicvoidkeyPressed(KeyEvente){//TODO自动生成的方法存根int[]blocksarr=getBlock();switch(e.getKeyCode()){caseKeyEvent.VK_UP:colBlock("up");hasEmptyBlock();if(Arrays.equals(blocksarr,getBlock())){}else{refershBlock();}isGameFail("up");break;caseKeyEvent.VK_DOWN:colBlock("down");hasEmptyBlock();if(Arrays.equals(blocksarr,getBlock())){}else{refershBlock();}isGameFail("down");break;caseKeyEvent.VK_LEFT:rowBlock("left");hasEmptyBlock();if(Arrays.equals(blocksarr,getBlock())){}else{refershBlock();}isGameFail("left");break;caseKeyEvent.VK_RIGHT:rowBlock("right");hasEmptyBlock();if(Arrays.equals(blocksarr,getBlock())){}else{refershBlock();}isGameFail("right");break;default:break;}scroeValue.setText(""+scroe);win();}/***垂直方向方块移动处理函数*/publicvoidcolBlock(Stringdirection){inttmp1=0;inttmp2=0;intindex=0;for(inti=0;i<4;i++){for(intj=0;j<4;j++){if(blocks[tmp1].getText().trim().equals("")){tmp1+=4;if(tmp1>=16){break;}else{continue;}}else{blocksarr[index]=Integer.parseInt(blocks[tmp1].getText().trim());index+=1;tmp1+=4;if(tmp1>=16||index>=4){break;}else{continue;}}}switch(direction){case"up":blocksarr=handleBlocksarr(blocksarr);break;case"down":blocksarr=reverseArr(handleBlocksarr(reverseArr(blocksarr)));break;default:break;}for(intn=0;n<blocksarr.length;n++){if(blocksarr[n]==0){blocks[tmp2].setText("");blocks[tmp2].setBackground(Color.gray);}else{blocks[tmp2].setValue(blocksarr[n]+"");}tmp2+=4;}index=0;tmp1=i+1;tmp2=i+1;//清空数组blockarrfor(intn=0;n<blocksarr.length;n++){blocksarr[n]=0;}}}/***水平方向方块移动处理函数*/publicvoidrowBlock(Stringdirection){inttmp1=0;inttmp2=0;intindex=0;for(inti=0;i<4;i++){for(intj=0;j<4;j++){if(blocks[tmp1].getText().trim().equals("")){tmp1+=1;if(tmp1>=16){break;}else{continue;}}else{blocksarr[index]=Integer.parseInt(blocks[tmp1].getText().trim());index+=1;tmp1+=1;if(tmp1>=16||index>=4){break;}else{continue;}}}switch(direction){case"left":blocksarr=handleBlocksarr(blocksarr);break;case"right":blocksarr=reverseArr(handleBlocksarr(reverseArr(blocksarr)));break;default:break;}for(intn=0;n<blocksarr.length;n++){if(blocksarr[n]==0){blocks[tmp2].setText("");blocks[tmp2].setBackground(Color.gray);}else{blocks[tmp2].setValue(blocksarr[n]+"");}tmp2+=1;}index=0;//清空数组blockarrfor(intn=0;n<blocksarr.length;n++){blocksarr[n]=0;}}}/***处理并返回一个数组*/publicint[]handleBlocksarr(int[]blocksarr){intindex=0;int[]result=newint[4];for(inti=0;i<blocksarr.length;i++){//排序if(blocksarr[i]!=0){result[index]=blocksarr[i];index++;}}if(index==0||index==1){for(inti=index;i<result.length;i++){result[i]=0;}}else{for(inti=0;i<blocksarr.length;i++){blocksarr[i]=0;}switch(index){case2:if(result[0]==result[1]){blocksarr[0]=result[0]+result[1];scroe+=result[0]*2;}else{blocksarr=result;}break;case3:if(result[0]==result[1]){blocksarr[0]=result[0]+result[1];scroe+=result[0]*2;blocksarr[1]=result[2];}else{if(result[1]==result[2]){blocksarr[0]=result[0];blocksarr[1]=result[1]+result[2];scroe+=result[1]*2;}else{blocksarr=result;}}break;case4:if(result[0]==result[1]){blocksarr[0]=result[0]+result[1];scroe+=result[0]*2;if(result[2]==result[3]){blocksarr[1]=result[2]+result[3];scroe+=result[2]*2;}else{blocksarr[1]=result[2];blocksarr[2]=result[3];}}else{if(result[1]==result[2]){blocksarr[0]=result[0];blocksarr[1]=result[1]+result[2];scroe+=result[1]*2;blocksarr[2]=result[3];}else{blocksarr[0]=result[0];blocksarr[1]=result[1];if(result[2]==result[3]){blocksarr[2]=result[2]+result[3];scroe+=result[2]*2;}else{blocksarr=result;}}}break;default:break;}result=blocksarr;}returnresult;}/***反转数组eg:45000-->00054*/publicint[]reverseArr(int[]arr){int[]tmp=newint[arr.length];intindex=arr.length-1;for(inti=0;i<arr.length;i++){tmp[index]=arr[i];index--;}returntmp;}/***刷新方块,添加新出现的2或4*/publicvoidrefershBlock(){if(numFlag==false){}while(numFlag){intindex=(int)(Math.random()*16);if(blocks[index].getText().trim().equals("")){if(Math.random()<0.8){blocks[index].setValue("2");}else{blocks[index].setValue("4");}break;}else{continue;}}}/***判断是否有空的方块*/publicvoidhasEmptyBlock(){for(inti=0;i<blocks.length;i++){if(blocks[i].getText().trim().equals("")){this.numFlag=true;break;}else{this.numFlag=false;}}}/***判断游戏是否失败*/publicvoidisGameFail(Stringdirection){booleanresult=true;//true代表失败false代表没有失败inttmp=0;if(numFlag==false){//表示没有空的方块switch(direction){case"up":case"down":for(inti=0;i<4;i++){tmp=i*4;for(intj=0;j<3;j++){if(blocks[tmp].getText().trim().equals(blocks[tmp+1].getText().trim())){result=false;//游戏未失败break;}else{tmp++;}}if(result==false){break;}}break;case"left":case"right":for(inti=0;i<4;i++){for(intj=0;j<3;j++){if(blocks[tmp].getText().trim().equals(blocks[tmp+4].getText().trim())){result=false;//游戏未失败break;}else{tmp+=4;if(tmp>=16){break;}else{continue;}}}tmp=i+1;if(result==false){break;}}break;default:break;}}else{result=false;}if(result==true){JOptionPane.showMessageDialog(null,"GameOver",null,JOptionPane.ERROR_MESSAGE);game2048View.newGame();}else{}}/***判断游戏是否成功,即成功累加至2048*/publicvoidwin(){for(inti=0;i<blocks.length;i++){if(blocks[i].getText().trim().equals("2048")){JOptionPane.showMessageDialog(null,"YOUAREWIN",null,JOptionPane.ERROR_MESSAGE);game2048View.newGame();break;}}}/***获得全部方块内容,用于对比*/publicint[]getBlock(){int[]blocksarr=newint[16];for(inti=0;i<blocks.length;i++){if(blocks[i].getText().trim().equals("")){blocksarr[i]=0;}else{blocksarr[i]=Integer.parseInt(blocks[i].getText().trim());}}returnblocksarr;}@OverridepublicvoidkeyReleased(KeyEvente){//TODO自动生成的方法存根}@OverridepublicvoidkeyTyped(KeyEvente){//TODO自动生成的方法存根}}

    以上是“如何使用Java实现经典游戏2048”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注恰卡编程网行业资讯频道!

    发布于 2022-02-15 20:43:04
    收藏
    分享
    海报
    0 条评论
    106
    上一篇:java中有没有参数和返回值 下一篇:python中的return有什么用
    目录

      0 条评论

      本站已关闭游客评论,请登录或者注册后再评论吧~

      忘记密码?

      图形验证码