如何使用Java实现经典游戏2048
短信预约 -IT技能 免费直播动态提醒
这篇文章主要介绍如何使用Java实现经典游戏2048,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
主要设计
游戏面板生成显示
方块设计
键盘监听,方向键控制数字移动
数字移动逻辑算法处理
数字累加到2048,游戏胜利
功能截图
游戏开始
移动效果
代码实现
界面布局类
public class Game2048View implements ActionListener{Block[] blocks;//方块JPanel myJPanel;//主面板JPanel jp1,jp2;//子面板//int moveFlag;// 用于累计移动的次数boolean numFlag;// 用于判断是否还能加入新的数字JLabel scroeValue;//显示分数public Game2048View(JFrame myJFrame){blocks=new Block[16];//moveFlag=0;numFlag=true;this.myJPanel=(JPanel)myJFrame.getContentPane();///获取内容面板setJp1();myJPanel.add(jp1,BorderLayout.NORTH);setJp2();myJPanel.add(jp2, BorderLayout.CENTER);myJFrame.addKeyListener(new Game2048Logic(this,myJFrame,blocks,numFlag,scroeValue));}public void addc(JPanel jp1,Component component, GridBagConstraints gbc,int gridwidth,int gridheight, int weightx,int weighty,int gridx,int gridy) {//此方法用来添加控件到容器中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);}public void setJp1() {GridBagLayout gbLayout=new GridBagLayout();jp1=new JPanel(gbLayout);JPanel Jtitle=new JPanel();JLabel title=new JLabel("2048");title.setFont(new Font("font", Font.PLAIN, 45));//类型、风格、大小title.setHorizontalAlignment(JLabel.LEFT);//jLabel的文本左右对齐属性设置方法,对齐方式Jtitle.add(title);jp1.add(Jtitle);JPanel Jscroe=new JPanel(new GridLayout(2, 1));//new GridLayout(2, 1)为网格布局样式。其中的参数“2”“1”分别为网格的“行数”和“列数”。JLabel scroe=new JLabel("Scroe");scroe.setFont(new Font("font", Font.PLAIN, 16));scroe.setHorizontalAlignment(JLabel.CENTER);scroeValue=new JLabel("0");scroeValue.setFont(new Font("font", Font.PLAIN, 16));scroeValue.setHorizontalAlignment(JLabel.CENTER);Jscroe.add(scroe);Jscroe.add(scroeValue);jp1.add(Jscroe);JPanel Jnoite=new JPanel();JLabel noite=new JLabel("方向键移动数字累加至2048");noite.setFont(new Font("font", Font.PLAIN, 14));noite.setHorizontalAlignment(JLabel.LEFT);Jnoite.add(noite);jp1.add(Jnoite);JPanel JnewGame=new JPanel();JButton newGame=new JButton("New Game");newGame.setHorizontalAlignment(JButton.CENTER);newGame.addActionListener(this);JnewGame.add(newGame);jp1.add(JnewGame);GridBagConstraints gbc=new GridBagConstraints();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);}public void setJp2() {addBlock();initBlock();initBlock();}public void addBlock(){jp2=new JPanel();jp2.setLayout(new GridLayout(4, 4, 5, 5));for (int i = 0; i < blocks.length; i++) {blocks[i]=new Block();blocks[i].setHorizontalAlignment(JLabel.CENTER);// 不透明的标签blocks[i].setOpaque(true);// 设置控件不透明jp2.add(blocks[i]);}}public void initBlock(){while (numFlag) {int index=(int) (Math.random()*16);if (blocks[index].getText().trim().equals("")) {blocks[index].setValue("2");break;} else {continue;}}}public int getMyJPanelHeidth() {return jp1.getSize().height;}@Overridepublic void actionPerformed(ActionEvent e) {// TODO 自动生成的方法存根newGame();}public void newGame() {for (int i = 0; i < blocks.length; i++) {blocks[i].setValue("");}numFlag=true;scroeValue.setText("0");initBlock();initBlock();}}
业务逻辑类
public class Game2048Logic implements KeyListener{Block[] blocks;boolean numFlag;// 用于判断是否还能加入新的数字JLabel scroeValue;//显示分数int blocksarr[]=new int[4];//保存一行/列方块中的数值JFrame myJFrame;int scroe=0;Game2048View game2048View;//初始化键盘事件public Game2048Logic(Game2048View game2048View, JFrame myJFrame, Block[] blocks,boolean numFlag,JLabel scroeValue) {// TODO 自动生成的构造函数存根this.blocks=blocks;this.numFlag=numFlag;this.scroeValue=scroeValue;this.myJFrame=myJFrame;this.game2048View=game2048View;}//初始化按钮事件public Game2048Logic() {// TODO 自动生成的构造函数存根}public boolean getnumFlag() {return numFlag;}@Overridepublic void keyPressed(KeyEvent e) {// TODO 自动生成的方法存根int[] blocksarr=getBlock();switch (e.getKeyCode()) {case KeyEvent.VK_UP:colBlock("up");hasEmptyBlock();if (Arrays.equals(blocksarr, getBlock())) {} else {refershBlock();}isGameFail("up");break;case KeyEvent.VK_DOWN:colBlock("down");hasEmptyBlock();if (Arrays.equals(blocksarr, getBlock())) {} else {refershBlock();}isGameFail("down");break;case KeyEvent.VK_LEFT:rowBlock("left");hasEmptyBlock();if (Arrays.equals(blocksarr, getBlock())) {} else {refershBlock();}isGameFail("left");break;case KeyEvent.VK_RIGHT:rowBlock("right");hasEmptyBlock();if (Arrays.equals(blocksarr, getBlock())) {} else {refershBlock();}isGameFail("right");break;default:break;}scroeValue.setText(""+scroe);win();}public void colBlock(String direction){int tmp1=0;int tmp2=0;int index=0;for (int i = 0; i < 4; i++) {for (int j = 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 (int n = 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 (int n = 0; n < blocksarr.length; n++) {blocksarr[n]=0;}}}public void rowBlock(String direction) {int tmp1=0;int tmp2=0;int index=0;for (int i = 0; i < 4; i++) {for (int j = 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 (int n = 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 (int n = 0; n < blocksarr.length; n++) {blocksarr[n]=0;}}}public int[] handleBlocksarr(int[] blocksarr) {int index=0;int[] result=new int[4];for (int i = 0; i < blocksarr.length; i++) {//排序if (blocksarr[i]!=0) {result[index]=blocksarr[i];index++;} }if (index==0 || index==1) {for (int i = index; i < result.length; i++) {result[i]=0;}} else {for (int i = 0; i < blocksarr.length; i++) {blocksarr[i]=0;}switch (index) {case 2:if (result[0]==result[1]) {blocksarr[0]=result[0]+result[1];scroe+=result[0]*2;} else {blocksarr=result;}break;case 3: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;case 4: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;}return result;}public int[] reverseArr(int[] arr) {int[] tmp=new int[arr.length];int index=arr.length-1;for (int i = 0; i < arr.length; i++) {tmp[index]=arr[i];index--;}return tmp;}public void refershBlock(){if (numFlag==false) {}while (numFlag) {int index=(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;}}}public void hasEmptyBlock() {for (int i = 0; i < blocks.length; i++) {if (blocks[i].getText().trim().equals("")) {this.numFlag=true;break;} else {this.numFlag=false;}}}public void isGameFail(String direction) {boolean result=true;//true代表失败 false代表没有失败int tmp=0;if (numFlag == false) { // 表示没有空的方块switch (direction) {case "up":case "down":for (int i = 0; i < 4; i++) {tmp=i*4;for (int j = 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 (int i = 0; i < 4; i++) {for (int j = 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 , "Game Over",null , JOptionPane.ERROR_MESSAGE) ;game2048View.newGame();} else {}}public void win() {for (int i = 0; i < blocks.length; i++) {if (blocks[i].getText().trim().equals("2048")) {JOptionPane.showMessageDialog( null , "YOU ARE WIN",null , JOptionPane.ERROR_MESSAGE) ;game2048View.newGame();break;} }}public int[] getBlock() {int[] blocksarr=new int[16];for (int i = 0; i < blocks.length; i++) {if (blocks[i].getText().trim().equals("")) {blocksarr[i]=0;} else {blocksarr[i]=Integer.parseInt(blocks[i].getText().trim());}}return blocksarr;}@Overridepublic void keyReleased(KeyEvent e) {// TODO 自动生成的方法存根}@Overridepublic void keyTyped(KeyEvent e) {// TODO 自动生成的方法存根}}
以上是“如何使用Java实现经典游戏2048”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网行业资讯频道!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341