由于离散老师放假了还不放过我们,本来昨天就应该完成的事拖到了今天现在,经过今天数个小时的学习和实践,2048小游戏成功制作完成,明天就可以把这个给妹妹玩。
太累了,今天先把代码给放出来,明天再把代码的注释和其他内容完善一下,这篇博客应该会长期修改,以最终完成所有功能的解释为最终版,加油!加油!
以下是源代码
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
//创建子类继承JFrame类,目的是方便添加左移、右移等方法
public class MainFrame extends JFrame implements KeyListener {
//制造二维数组对象来保存16个位置的图片编号
int[][] dates = new int[4][4];
//score用来记录得分
int score = 0;
//构造函数用于初始化一个Mainframe对象
public MainFrame() {
setframe();
initdates();
paintframe();
this.addKeyListener(this);
setVisible(true);
}
//setframe()用于窗口的初始化
private void setframe() {
//定义窗口宽度、高度
setSize(500, 500);
//设置窗口名
setTitle("2048小游戏");
//设置窗口居中
setLocationRelativeTo(null);
//设置窗口置顶
setAlwaysOnTop(true);
//设置窗口关闭程序运行结束,否则关闭窗口程序运行不会结束,需要手动结束
setDefaultCloseOperation(3);
//通过窗口对象,取消窗体内默认布局
setLayout(null);
}
//initdates()用于数组初始化
public void initdates(){
addnum();
addnum();
}
//paintframe()用于将窗体初始状况进行绘制
private void paintframe() {
//移除窗口所有图片
getContentPane().removeAll();
//检查是否还可以移动,不可以的话则显示失败的图片
if(CheckMove() == false){
JLabel loseJlabel = new JLabel(new ImageIcon("image\\A-lose.png"));
loseJlabel.setBounds(83,130,334,228);
getContentPane().add(loseJlabel);
}
//遍历二维数组将图片添加
for (int i = 0; i < dates.length; i++) {
for (int j = 0; j < dates[0].length; j++) {
ImageIcon II = new ImageIcon("image\\A-" + dates[i][j] + ".png");
JLabel jl = new JLabel(II);
jl.setBounds(50 + 100 * j, 35 + 100 * i, 100, 100);
getContentPane().add(jl);
}
}
//添加背景图
ImageIcon IBack = new ImageIcon("image\\A-Background.jpg");
JLabel jlback = new JLabel(IBack);
jlback.setBounds(50, 35, 400, 400);
getContentPane().add(jlback);
getContentPane().repaint();
JLabel scorelabel = new JLabel("得分"+ score);
scorelabel.setBounds(50,15,100,20);
getContentPane().add(scorelabel);
}
@Override
//根据按键进行相关操作
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == 37 || key == 65) {
MoveToLeft();
addnum();
} else if (key == 38 || key == 87) {
MoveToUp();
addnum();
} else if (key == 39 || key == 68) {
MoveToRight();
addnum();
} else if (key == 40 || key == 83) {
MoveToDown();
addnum();
}
paintframe();
}
//此方法用于实现数据左移
public void MoveToLeft() {
for (int x = 0; x < dates.length; x++) {
//完成0号后置
int[] arr = new int[4];
int index = 0;
for (int i = 0; i < dates[0].length; i++) {
if (dates[x][i] != 0) {
arr[index] = dates[x][i];
index++;
}
}
dates[x] = arr;
//完成一次左移操作
for (int n = 0; n < 3; n++) {
if (dates[x][n] == dates[x][n + 1]) {
dates[x][n] *= 2;
score += dates[x][n];
for (int j = n + 1; j < 3; j++) {
dates[x][j] = dates[x][j + 1];
}
dates[x][3] = 0;
}
}
}
}
//一维数组翻转
public void reverseArray(int[] arr) {
for (int start = 0, end = arr.length - 1; start < end; start++, end--) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
}
//二维数组翻转
public void re2DArray() {
for (int i = 0; i < dates.length; i++) {
reverseArray(dates[i]);
}
}
//实现数据右移
public void MoveToRight() {
re2DArray();
MoveToLeft();
re2DArray();
}
//实现二维数组逆时针翻转
public void ArrayCounterclockwise() {
int[][] newarr = new int[4][4];
for (int i = 0; i < dates.length; i++) {
for (int j = 0; j < dates[0].length; j++) {
newarr[3 - j][i] = dates[i][j];
}
}
dates = newarr;
}
//实现数组顺时针翻转
public void ArrayClockwise() {
int[][] newarr = new int[4][4];
for (int i = 0; i < dates.length; i++) {
for (int j = 0; j < dates[0].length; j++) {
newarr[j][3 - i] = dates[i][j];
}
}
dates = newarr;
}
//实现数据上移动
public void MoveToUp() {
ArrayCounterclockwise();
MoveToLeft();
ArrayClockwise();
}
//实现数据下移动
public void MoveToDown() {
ArrayClockwise();
MoveToLeft();
ArrayCounterclockwise();
}
//判断是否可以移动
public boolean CheckMove(){
boolean bool = true;
if(CheckLeft() == false && CheckRight() == false && CheckUp() == false && CheckDown() == false){
bool = false;
}
return bool;
}
//判断是否则可以左移动
public boolean CheckLeft(){
int[][] newarr = new int[4][4];
copyArray(dates,newarr);
MoveToLeft();
boolean bool = CompareArray(dates,newarr);
copyArray(newarr,dates);
return bool;
}
//判断是否则可以右移动
public boolean CheckRight(){
int[][] newarr = new int[4][4];
copyArray(dates,newarr);
MoveToRight();
boolean bool = CompareArray(dates,newarr);
copyArray(newarr,dates);
return bool;
}
//判断是否则可以上移动
public boolean CheckUp(){
int[][] newarr = new int[4][4];
copyArray(dates,newarr);
MoveToUp();
boolean bool = CompareArray(dates,newarr);
copyArray(newarr,dates);
return bool;
}
//判断是否则可以下移动
public boolean CheckDown(){
int[][] newarr = new int[4][4];
copyArray(dates,newarr);
MoveToDown();
boolean bool = CompareArray(dates,newarr);
copyArray(newarr,dates);
return bool;
}
//复制源数组从原数组到新数组
public void copyArray(int[][] src, int[][] newarr ) {
for (int i = 0; i < src.length; i++) {
for (int j = 0; j < src[0].length; j++) {
newarr[i][j] = src[i][j];
}
}
}
//比较两数组所有元素是否相同
public boolean CompareArray(int[][] dates, int[][] newarr) {
boolean bool = false;
loop1:
for (int i = 0; i < dates.length; i++) {
for (int j = 0; j < dates[0].length; j++) {
if(newarr[i][j] != dates[i][j]){
bool = true;
break loop1;
};
}
}
return bool;
}
//实现每次移动之后添加一个2号数字块
public void addnum(){
int[] arrayi = new int[16];
int[] arrayj = new int[16];
int count = 0;
//将两个数组所有元素初始化为-1
for (int i = 0; i < arrayi.length; i++) {
arrayi[i] = -1;
arrayj[i] = -1;
}
for (int i = 0; i < dates.length; i++) {
for (int j = 0; j < dates[i].length; j++) {
if(dates[i][j] == 0){
arrayi[count] = i;
arrayj[count] = j;
count++;
}
}
}
if(count != 0){
Random r = new Random();
int index = r.nextInt(count);
int x = arrayi[index];
int y = arrayj[index];
dates[x][y] = 2;
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
初始界面如图
昨天没有看电影,今晚好累也没力气看了。
明日目标:1、完善这个2048小游戏
2、观看电影《辛德勒的名单》
冲冲冲!