如何使用Java实现经典游戏2048
发表于:2025-01-16 作者:千家信息网编辑
千家信息网最后更新 2025年01月16日,这篇文章主要介绍如何使用Java实现经典游戏2048,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!主要设计1、游戏面板生成显示2、方块设计3、键盘监听,方向键控制数字移动4、数
千家信息网最后更新 2025年01月16日如何使用Java实现经典游戏2048
这篇文章主要介绍如何使用Java实现经典游戏2048,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
主要设计
1、游戏面板生成显示
2、方块设计
3、键盘监听,方向键控制数字移动
4、数字移动逻辑算法处理
5、数字累加到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(); /* * setLayout是对当前组件设置为流式布局.组件在窗体中从左到右依次排列 如果排到行的末尾 换行排列 * GridLayout(int rows, int cols, int hgap, int vgap) 创建具有指定行数和列数的网格布局。 rows - 该 rows 具有表示任意行数的值 cols - 该 cols 具有表示任意列数的值 hgap - 水平间距 vgap - 垂直间距 */ 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; } @Override public 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; } @Override public 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; //清空数组blockarr for (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; //清空数组blockarr for (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; } /** * 反转数组eg:45000 --> 00054 */ 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; } /** * 刷新方块,添加新出现的2或4 */ 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 { } } /** * 判断游戏是否成功,即成功累加至2048 */ 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; } @Override public void keyReleased(KeyEvent e) { // TODO 自动生成的方法存根 } @Override public void keyTyped(KeyEvent e) { // TODO 自动生成的方法存根 }}
以上是"如何使用Java实现经典游戏2048"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!
方块
方法
组件
生成
移动
存根
数字
自动生成
面板
内容
函数
布局
方向
水平
处理
数组
网格
经典
经典游戏
成功
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
儿童网络安全基础知识
惠州市网络技术 培训学校
国家网络安全法中关于邮件
组态王做服务器和数采仪
问道手游高防服务器
如何面试澳洲软件开发
数据库中表之间关系怎么删除
网络安全密钥的意思
韶关市武江区启明星网络技术
数据库取一个一对多联系例子
普陀区正规数据库行业
软件开发方面问题
网络安全招新小问题
管家婆数据库在哪个文件夹
浙江免备案服务器虚拟主机
无法登录ps服务器
新疆电力软件开发
qq留言板怎么看不到服务器
自学服务器
ntp时钟服务器天线安装
珠宝软件开发机构
软件开发企业商业计划书
如何删除已建立的数据库
宝山区正规网络技术服务行业标准
教育软件开发公司倒闭
合肥兆网络技术有限公司
幼儿网络安全主题创意绘画
php中注册时数据库不成功
南通软件开发常见问题
华为云服务器登录怎么是