在2020年过年之前的时候,有着游戏兴趣的我,用了两天的时间搞了一个java版的2048小游戏,并且通过工具生成了exe版,心里美滋滋。附上源码教程。分享给大家。独乐乐不如众乐乐。游戏虽然简单。却也是笔者真实的劳动成果。希望大家珍惜笔者的劳动成果。
1、界面效果
2、贴出源码。大家一起乐乐吧
package com.mage;
import java.awt.Button;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class Demo2048 {
private static JButton b2[]=new JButton[16]; //初始化使用的按钮
public static void main( String args[]) {
framTwo();
}
//初始化游戏表盘
public static void framTwo(){
//Frame 是带有标题和边框的顶层窗口
Frame f = new Frame("2048 GO GO GO !");
//此类创建一个标签按钮。当按下该按钮时,应用程序能执行某项动作。
//Button count = new Button("666");
Button bn = new Button("↑");
Button bs = new Button("↓");
Button bw = new Button("←");
Button be = new Button("→");
JPanel jp3 = centerAll();
//f.add(count, "North");
f.add(bn, "North");
f.add(bs, "South");
f.add(bw, "West");
f.add(be, "East");
f.add(jp3, "Center");
f.setSize(300,300);
//this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //这个很重要!!!设置关闭窗体后虚拟机一同关闭,不设置的
f.setVisible(true);//设置可以显示
// 设置窗体可以关闭
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//退出JVM
}
});
//左移流程
bw.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//as(Arrays.asList(b2));
moveLeft(Arrays.asList(b2));
}
});
//右移流程
be.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//as(Arrays.asList(b2));
moveRight(Arrays.asList(b2));
}
});
//上移流程
bn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//as(Arrays.asList(b2));
moveUP(Arrays.asList(b2));
}
});
//上移流程
bs.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//as(Arrays.asList(b2));
moveDown(Arrays.asList(b2));
}
});
}
/**
* 定义中间面板内容
* @return
*/
public static JPanel centerAll(){
//JPanel 是一般轻量级容器 GridLayout 类是一个布局处理器,它以矩形网格形式对容器的组件进行布置
JPanel jp3 = new JPanel(new GridLayout(4,4,5,5));
//循环遍历给JPanel 添加 按钮控件
//List list = new LinkedList();
for(Integer i=0; i<16; i++) {
b2[i]=new JButton();
b2[i].setName(i.toString());
jp3.add(b2[i]);
//list.add(b2[i]);
//System.out.println(b2[i].getText().equals(""));
}
//获取随机一个位置的按钮
getBtnRandom(Arrays.asList(b2),1);
getBtnRandom(Arrays.asList(b2),0);
return jp3;
}
//===========================================================定义初始化内容完毕=============================================================
/*public static void as(List b2){
for(JButton tem : b2){
System.out.println(tem.getName()+"=============="+tem.getText());
}
}*/
//如果可以向左移动的话,第一步,遍历数字格,每行分别遍历,从左往右分别获取不为0的值,第二步,给每个按钮重新赋值,第三步从左往右对比,如果值相同则相加
public static void moveLeft(List list) {
//第一步,遍历数字格,每行分别遍历,从左往右分别挨着不为空的数值
//0-3 第一行
list = leftAllBtn(list,0);
//4-7 第二行
list = leftAllBtn(list,4);
//8-11 第三行
list = leftAllBtn(list,8);
//12-15 第四行
list = leftAllBtn(list,12);
//在随机位置生成一个数
getBtnRandom(list,0);
return ;
}
//右移和左移相同流程只不过方向相反
public static void moveRight(List list) {
//第一步,遍历数字格,每行分别遍历,从左往右分别挨着不为空的数值
//0-3 第一行
list = rightAllBtn(list,3);
//4-7 第二行
list = rightAllBtn(list,7);
//8-11 第三行
list = rightAllBtn(list,11);
//12-15 第四行
list = rightAllBtn(list,15);
//在随机位置生成一个数
getBtnRandom(list,0);
return ;
}
//上移是按照列进行计算
public static void moveUP(List list) {
//第一步,遍历数字格,每行分别遍历,从左往右分别挨着不为空的数值
//0,4,8,12 第一列
list = upAllBtn(list,0);
//1,5,9,13 第二列
list = upAllBtn(list,1);
//2,6,10,14 第三列
list = upAllBtn(list,2);
//3,7,11,15 第四列
list = upAllBtn(list,3);
//在随机位置生成一个数
getBtnRandom(list,0);
return ;
}
//下移是按照列进行计算
public static void moveDown(List list) {
//第一步,遍历数字格,每行分别遍历,从左往右分别挨着不为空的数值
//0,4,8,12 第一列
list = downAllBtn(list,12);
//1,5,9,13 第二列
list = downAllBtn(list,13);
//2,6,10,14 第三列
list = downAllBtn(list,14);
//3,7,11,15 第四列
list = downAllBtn(list,15);
//在随机位置生成一个数
getBtnRandom(list,0);
return ;
}
//初始化位置随机生成一个位置按钮(带有数字的) == 若没有位置生成则死亡
public static void getBtnRandom(List list,int bt){
//判断是否结束,所有格不能在随机生成了为失败 i为判断是否是初始化
Random random = new Random();
//是否初始值
if(bt != 1 ){
//筛选出空的list,并将空的按钮放入集合
List listTem = new ArrayList();
for(JButton em : list){
if(em.getText().equals("")){
listTem.add(em);
}
}
//判断游戏是否结束
if(listTem.size()==0){
Object[] options ={ "不服,再来一局", "不玩了,哼" };
int m = JOptionPane.showOptionDialog(null, "啊欧,你嗝屁了", "死亡提示",JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
//System.out.println(m);
if(m==0){
framTwo();
return;
}else{
System.exit(0);//退出JVM
}
}
//获取随机数
int n = random.nextInt(listTem.size());
JButton radJB = listTem.get(n);//获取随机按钮
radJB.setText(getRandom());//给随机按钮赋值
//System.out.println("随机生成的位置"+radJB.getName()+" 值为:"+radJB.getText());
//System.out.println(n);
}else{
int n = random.nextInt(list.size());
JButton radJB = list.get(n);//获取随机按钮
radJB.setText(getRandom());//给随机按钮赋值
}
}
//获取随机数 2-4
public static String getRandom(){
Integer res = Math.random() < 0.5 ? 2 : 4;
//System.out.println(res);
return res.toString();
}
/**
* 给按钮重新赋值
* @param list 所有的按钮列表
* @param i 每行的第一个数值
* @return
*/
public static List leftAllBtn(List list,int i) {
//获取按钮的值并清空按钮值
List listTem = getLiftRightListTem(list,i);
//第二步重新赋值,第三步,这些值分别判断相加并赋值
List all = getLisInteger(listTem);
for (Integer b = i; b < all.size()+i; b++) {//每行按钮起始位置,和要重新赋值的list的关系 all.size()最大为4最小为0 因此得到判断关系
list.get(b).setText(all.get(b-i).toString());
}
return list;
}
/**
* 给按钮重新赋值
* @param list 所有的按钮列表
* @param i 每行的最后一个数值
* @return
*/
public static List rightAllBtn(List list,int i) {
//获取按钮的值并清空按钮值 从左往右获取值
List listTem = getLiftRightListTem(list,i-3);
//第二步重新赋值,第三步,这些值分别判断相加并赋值
List all = getLisInteger(listTem);
//将list倒叙
Collections.reverse(all);
for (Integer b = i; b > i-all.size(); b--) {//按钮结束位置,和要重新赋值的list的关系 all.size()最大为4最小为0 因此与遍历次数最大为4
list.get(b).setText(all.get(i-b).toString());
}
return list;
}
/**
* 给按钮重新赋值
* @param list 所有的按钮列表
* @param i 每列的第一个数值
* @return
*/
public static List upAllBtn(List list,int i) {
//获取按钮的值并清空按钮值 从上往下获取值
List listTem = getUpDownListTem(list,i);
//第二步重新赋值,第三步,这些值分别判断相加并赋值
List all = getLisInteger(listTem);
for (Integer b = i; b < all.size()+i; b+=4) {//每列按钮起始位置,和要赋值的list大小关系
list.get(b).setText(all.get(b-i).toString());
i +=3;
}
return list;
}
/**
* 给按钮重新赋值
* @param list 所有的按钮列表
* @param i 每列的最后一个数值
* @return
*/
public static List downAllBtn(List list,int i) {
//获取按钮的值并清空按钮值 从上往下获取值
List listTem = getUpDownListTem(list,i-12);
//第二步重新赋值,第三步,这些值分别判断相加并赋值
List all = getLisInteger(listTem);
int allSize = all.size(); //获取值的位置
int count = all.size(); //遍历次数控制
for (Integer b = i; b > i-count; b-=4) {//每列按钮结束位置,和要赋值的list大小关系
list.get(b).setText(all.get(allSize-1).toString());
allSize -= 1;
count += 3;
}
return list;
}
/**
* 从左往右获取每个按钮的值
* @param list 所有的按钮列表
* @param b 每行的第一个数值
* @return
*/
public static List getLiftRightListTem(List list,Integer b) {
List listTem = new LinkedList();
for (Integer j = b; j < b+4; j++) {
JButton jBti = list.get(j);
if(jBti.getText()!=null && !jBti.getText().equals("")){
listTem.add(Integer.parseInt(jBti.getText()));
list.get(j).setText("");//清空
}
}
return listTem;
}
/**
* 从上往下获取每个按钮的值
* @param list 所有的按钮列表
* @param b 每列的第一个数值
* @return
*/
public static List getUpDownListTem(List list,Integer b) {
List listTem = new LinkedList();
for (Integer j = b; j < b+13; j+=4) {
JButton jBti = list.get(j);
if(jBti.getText()!=null && !jBti.getText().equals("")){
listTem.add(Integer.parseInt(jBti.getText()));
list.get(j).setText("");//清空
}
}
return listTem;
}
/**
* 获取从第一个到最后一个若有从左到右挨着相同的数字,相加并返回
* @param list
* @return
*/
public static List getLisInteger(List list) {
List listTem = new LinkedList();
for(int i = 0; i= list.size()){
listTem.add(list.get(i));
}else{
if(list.get(i).equals(list.get(i+1))){
listTem.add(list.get(i)*2);//一共4个数,有两个合并则i+1跳过
i+=1;
}else{
listTem.add(list.get(i));
}
}
}
return listTem;
}
}
以上就是笔者的2048go go go 小游戏。