admin管理员组

文章数量:1532750

2024年6月22日发(作者:)

Java语言程序设计

课程设计

题 目 2048游戏的设计与实现

目 录

Java语言程序设计 .................................................................................................................................................................... 1

课程设计...................................................................................................................................................................................... 1

//绘图方法 .................................................................................................................................................................................. 4

//判断是否已经失败,若失败则返回true,否则返回 4

//在游戏区空闲处随机生成2或4 .......................................................................................................................................... 5

Color background = new Color(190, 173, 160);// 背景色 ....................................................................................... 7

Color wordColor = new Color(232, 216, 203);// 单词色 .......................................................................................... 7

Random random=new Random();//随机数发生器 ....................................................................................................... 7

//若是初次运行游戏,则从文件中读入最高分 .................................................................................................................... 10

}catch(Exception e){ ............................................................................................................................................................ 11

}else if(score<1000){ .......................................................................................................................................................... 13

}else if(score<10000){ ........................................................................................................................................................ 13

}else if(score<100000){ ..................................................................................................................................................... 14

}else if(score<1000000){ ................................................................................................................................................... 14

}else{ ......................................................................................................................................................................................... 14

//画分数数字 ............................................................................................................................................................................ 14

//画分数数字 ............................................................................................................................................................................ 15

//画分数数字 ............................................................................................................................................................................ 15

//画分数数字 ............................................................................................................................................................................ 15

//画分数数字 ............................................................................................................................................................................ 15

//画分数数字 ............................................................................................................................................................................ 15

//画分数数字 ............................................................................................................................................................................ 16

}else if(Code()==_DOWN){ .................................................................................................... 26

}else if(Code()==_LEFT){ ......................................................................................................... 27

}else if(Code()==_RIGHT){ ..................................................................................................... 27

}else{ ......................................................................................................................................................................................... 28

}else{ ......................................................................................................................................................................................... 29

Override .................................................................................................................................................................................. 30

Override .................................................................................................................................................................................. 30

}else{ ......................................................................................................................................................................................... 44

}else{ ......................................................................................................................................................................................... 46

一、 需求分析

《2048》是比较流行的一款数字游戏。原版2048首先在github上发布,原作者是

Gabriele Cirulli。它是基于《1024》和《小3传奇》的玩法开发而成的新型数字游戏[1] 。

随后2048便出现各种版本,走各大平台。由Ketchapp公司移植到IOS的版本最为

火热,现在约有1000万下载,其名字跟原版一模一样。衍生版中最 出名的是《2048六

边形》版本,先后在全球81个国家中的board game中排进了前200。安卓版非常火爆

的有《挑战2048》,其2.0.0版以后还加入了双人对战。其次比较特别的有2048中国朝

代版。更有 2048自定义版,可以自己定义文字和图片。《2048》是IOS中流行的一款。

本课程设计通过设计与开发JVM平台上的2048游戏,进一步掌握所学Java课程的

知识,体验Java的跨平台性,同时将Java设计方面的知识拓展应用

二、 系统运行环境

1、硬件环境:

2、软件环境:

操作系统:WindowsXP/Windows7

软件:集成开发环境Eclipse

三、 功能需求描述

1、图形用户界面:2048的最大特点就是玩家对图形界面里的数字进行操作,也就是

是玩家与游戏的互动

2、当前分数SCORE与最高分数的显示:在我们设计的2048游戏中当前分数取了页

面所有数字相加的值为分数,对玩家玩游戏的进展有直接性、客观性的展现;同时,最高

分数取了以往玩家退出游戏时所保存分数的最高分

3、数字颜色:游戏中数字的颜色以2为首项的等比数列变化,即2、4、8、16、32、

64、128、256、512、1024、对应的数字卡片变色

4、游戏的退出:游戏退出时,我们采用弹出对话框的确认玩家是否真的要退出游戏,

当然这样做更符合游戏人性化设计的观念。

功能图如下:

四、 总体设计

简要设计流程:

2048游戏

游戏算法画图监听器

程序结构说明:

//重新开始,若是初次运行游戏,则从文件中读入最高分

void restart()

//控制方法

public void keyPressed(KeyEvent e)

//绘图方法

public void paint(Graphics g)

//判断是否已经失败,若失败则返回true,否则返回false

public boolean judgeFail()

//向下滑动,若各列均没有方块相消或移动,则返回false,否则返回true;

public void moveDown()

//向左滑动,若各行均没有方块相消或移动,则返回false,否则返回true;

public void moveLeft()

//向右滑动,若各行均没有方块相消或移动,则返回false,否则返回true;

public void moveRight()

//向上滑动,若各行均没有方块相消或移动,则返回false,否则返回true;

Public void moveUp()

//在游戏区空闲处随机生成2或4

public void generateRandom2or4()

五、 程序模块设计

源码如下:

Main类:

import ;

public class Main {

public static void main(String[] args){

JFrame frame=new Java2048();

le("Java2048");

e(455,610);

ationRelativeTo(null);

aultCloseOperation(JFrame.

EXIT_ON_CLOSE

);

ible(true);

}

}

Java2048类:

import .*;

import .*;

import .*;

import .*;

import .*;

public class Java2048 extends JFrame implements KeyListener{

private static final long

serialVersionUID

= 1L;

Color background = new Color(190, 173, 160);// 背景色

Color foreground = new Color(204, 192, 178);// 前景色

Color wordColor = new Color(232, 216, 203);// 单词色

Font wordFont = new Font("微软雅黑", Font.

PLAIN

, 20);// 单词字体

Font numberFont = new Font("微软雅黑", Font.

BOLD

, 40);// 数字字体

Random random=new Random();//随机数发生器

int[][] array;//游戏用2维数组

//逐行或逐列处理数组,第一个参数为实际数字,第二个为判断值,用来判断是否

应该消除相同的数字

int[][] process=new int [4][2];

int score;//分数,初始化为零

int highestScore;//游戏中最高分

int highestScore2=0;//文件中最高分

int biggestNumber=0;

boolean ifGenerate2or4;

int[] rd=new int[16];//生成随机2或4的位置

private Graphics gBuffer;

//构造方法

public Java2048(){

addKeyListener(this);

addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){

if(JOptionPane.

showConfirmDialog

(null, "确定退出?", "提示",

JOptionPane.

YES_NO_OPTION

)==JOptionPane.

YES_NO_OPTION

){

if(highestScore>highestScore2){//若在本次游戏中破了纪录,则更新文件中的最高

highestScore2=highestScore;

File file=new File("");

BufferedWriter bw;

try{

bw=new BufferedWriter(new FileWriter(file));

(String.

valueOf

(highestScore2),0,String.

valueOf

(highestScore2).length

());

();

}catch(Exception e1){ JOptionPane.

showMessageDialog

(null,"找不到同目录下

文件或文件已损坏!", "提示",

JOptionPane.

INFORMATION_MESSAGE

);

};

}

System.

exit

(0);

}

}

});

restart();

}

void restart(){//重新开始

//若是初次运行游戏,则从文件中读入最高分

if(highestScore==0){}

File file=new File("");

BufferedReader br;

try{

br=new BufferedReader(new FileReader(file));

highestScore2=Integer.

valueOf

(ne());

();

}catch(Exception e){

JOptionPane.

showMessageDialog

(this,"找不到同目录下文

件或文件已损坏!", "提示", JOptionPane.

INFORMATION_MESSAGE

);

System.

exit

(0);

};

highestScore=highestScore2;

array=new int[4][4];//清空游戏用2维数组

score=0;//重置分数为零

biggestNumber=0;//重置最大数字为零

//在游戏区随机生成两个2或4

generateRandom2or4();

generateRandom2or4();

}

//绘图方法

public void paint(Graphics g) {

gBuffer=g;

or(background);

undRect(30, 40, 185, 90, 20, 20);// 画分数显示区

undRect(30, 40, 185, 90, 20, 20);

undRect(245, 40, 185, 90, 20, 20);// 画最高分显示区

undRect(245, 40, 185, 90, 20, 20);

undRect(0, 150, 454, 460, 10, 10);// 画主游戏区

undRect(0, 150, 454, 460, 10, 10);

t(wordFont);

or(wordColor);

ring("SCORE", 90, 70);// 画SCORE

ring("BEST", 315, 70); // 画BEST

t(numberFont);

or(Color.

white

);

if(score<10){

ring(String.

valueOf

(score), 110, 115);//画分数数字

if(score<100){

ring(String.

valueOf

(score), 100, 115);//画分数数字

}else if(score<1000){

ring(String.

valueOf

(score), 85, 115);//画分数数字

}else if(score<10000){

}else

ring(String.

valueOf

(score), 73, 115);//画分数数字

}else if(score<100000){

ring(String.

valueOf

(score), 60, 115);//画分数数字

}else if(score<1000000){

ring(String.

valueOf

(score), 50, 115);//画分数数字

}else{

ring(String.

valueOf

(score), 37, 115);//画分数数字

}

if(highestScore<10){

ring(String.

valueOf

(highestScore), 325, 115);

//画分数数字

}else if(highestScore<100){

ring(String.

valueOf

(highestScore), 315, 115);

//画分数数字

}else if(highestScore<1000){

ring(String.

valueOf

(highestScore), 300, 115);

//画分数数字

}else if(highestScore<10000){

ring(String.

valueOf

(highestScore), 288, 115);

//画分数数字

}else if(highestScore<100000){

ring(String.

valueOf

(highestScore), 275, 115);

//画分数数字

}else if(highestScore<1000000){

ring(String.

valueOf

(highestScore), 265, 115);

//画分数数字

}else{

ring(String.

valueOf

(highestScore), 252, 115);

//画分数数字

}

or(foreground);

for (int i = 0; i < 4; i++) {

for (int j = 0; j < 4; j++) {

undRect(10 + j * 112, 160 + i * 112, 100,

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

}

}

for(int i=0;i<4;i++){

for(int j=0;j<4;j++){

switch (array[i][j]) {

10, 100, 10);

case 2: {

or(new Color(238, 228, 218));

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

or(new Color(122, 113, 104));

t(new Font("微软雅黑", Font.

BOLD

, 50));

ring("2", 45 + j * 112, 230 + i * 113);

break;

}

case 4: {

or(new Color(236, 224, 200));

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

or(new Color(119, 110, 103));

t(new Font("微软雅黑", Font.

BOLD

, 50));

ring("4", 45 + j * 112, 230 + i * 113);

break;

}

case 8: {

or(new Color(242, 177, 121));

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

or(new Color(250, 248, 235));

t(new Font("微软雅黑", Font.

BOLD

, 50));

ring("8", 45 + j * 112, 230 + i * 113);

break;

}

case 16: {

or(new Color(245, 149, 101));

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

or(new Color(252, 244, 242));

t(new Font("微软雅黑", Font.

BOLD

, 45));

ring("16", 33 + j * 112, 230 + i * 111);

break;

}

case 32: {

or(new Color(245, 124, 95));

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

or(new Color(255, 241, 249));

t(new Font("微软雅黑", Font.

BOLD

, 45));

ring("32", 33 + j * 112, 230 + i * 111);

break;

}

case 64: {

or(new Color(246, 93, 59));

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

or(new Color(247, 249, 235));

t(new Font("微软雅黑", Font.

BOLD

, 45));

ring("64", 33 + j * 112, 230 + i * 111);

break;

}

case 128: {

or(new Color(237, 206, 113));

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

or(new Color(248, 246, 255));

t(new Font("微软雅黑", Font.

BOLD

, 40));

ring("128", 23 + j * 112, 228 + i * 111);

break;

}

case 256: {

or(new Color(237, 204, 97));

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

or(new Color(245, 244, 249));

t(new Font("微软雅黑", Font.

BOLD

, 40));

ring("256", 23 + j * 112, 228 + i * 111);

break;

}

case 512: {

or(new Color(235, 201, 78));

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

or(new Color(255, 241, 248));

t(new Font("微软雅黑", Font.

BOLD

, 40));

ring("512", 23 + j * 112, 228 +i * 111);

break;

}

case 1024: {

or(new Color(237, 197, 63));

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

or(new Color(240, 246, 244));

t(new Font("微软雅黑", Font.

BOLD

, 35));

ring("1024", 17 + j * 112, 225 + i * 113);

break;

}

case 2048: {

or(new Color(238, 194, 46));

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

or(new Color(250, 249, 255));

t(new Font("微软雅黑", Font.

BOLD

, 35));

ring("2048", 17 + j * 112, 225 + i * 113);

break;

}

case 4096: {

or(new Color(242, 193, 28));

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

or(new Color(248, 246, 255));

t(new Font("微软雅黑", Font.

BOLD

, 35));

ring("4096", 17 + j * 112, 225 + i * 113);

break;

}

case 8192: {

or(new Color(236, 173, 57));

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

or(new Color(248, 246, 255));

t(new Font("微软雅黑", Font.

BOLD

, 35));

ring("8192", 17 + j * 112, 225 + i * 113);

break;

}

default: {

or(foreground);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

undRect(10 + j * 112, 160 + i * 112, 100, 100, 10, 10);

}

}

}

}

}

public void keyPressed(KeyEvent e) {

if(Code()==KeyEvent.

VK_UP

){

moveUp();

}else if(Code()==_DOWN){

moveDown();

}else if(Code()==_LEFT){

moveLeft();

}else if(Code()==_RIGHT){

moveRight();

}

if(biggestNumber>1024){

switch(biggestNumber){

case 2048:{

if(JOptionPane.

showConfirmDialog

(this, "挑战2048成功!n是否继续挑战?", "

提示", JOptionPane.

YES_NO_OPTION

)==JOptionPane.

YES_OPTION

){

biggestNumber++;//防止2048重复判断

}else{

restart();

repaint();

}

break;

}

case 4096:{

if(JOptionPane.

showConfirmDialog

(this, "挑战4096成功!n是否继续挑战?", "

提示", JOptionPane.

YES_NO_OPTION

)==JOptionPane.

YES_OPTION

){

biggestNumber++;//防止4096重复判断

}else{

restart();

repaint();

}

break;

}

case 8192:{

if(JOptionPane.

showConfirmDialog

(this, "挑战8192成功!n是否继续挑战?", "

提示", JOptionPane.

YES_NO_OPTION

)==JOptionPane.

YES_OPTION

){

biggestNumber++;//防止8192重复判断

}else{

restart();

repaint();

}

break;

}

default:;

}

}

if(judgeFail()){

JOptionPane.

showMessageDialog

(this,"

JOptionPane.

INFORMATION_MESSAGE

);

挑战失败!", "提示",

restart();

repaint();

}

}

Override

public void keyReleased(KeyEvent e) {

}

Override

public void keyTyped(KeyEvent e) {

}

//判断是否已经失败,若失败则返回true,否则返回false

public boolean judgeFail(){

for(int j=0;j<4;j++){

for(int i=0;i<4;i++){

process[i][0]=array[i][j];

process[i][1]=1;

}

for(int i=1;i<4;i++){

int k=i;

while(k>0){

if(process[k][0]==0){

return false;

}else if(process[k-1][0]==0){

return false;

}else if(process[k-1][0]==process[k][0]){

return false;

}else{

break;

}

}

}

}

for(int j=0;j<4;j++){

for(int i=3;i>-1;i--){

process[3-i][0]=array[i][j];

process[3-i][1]=1;

}

for(int i=1;i<4;i++){

int k=i;

while(k>0){

if(process[k][0]==0){

return false;

}else if(process[k-1][0]==0){

return false;

}else if(process[k-1][0]==process[k][0]){

return false;

}else{

break;

}

}

}

}

for(int i=0;i<4;i++){

for(int j=0;j<4;j++){

process[j][0]=array[i][j];

process[j][1]=1;

}

for(int l=1;l<4;l++){

int k=l;

while(k>0){

if(process[k][0]==0){

return false;

}else if(process[k-1][0]==0){

return false;

}else if(process[k-1][0]==process[k][0]){

return false;

}else{

break;

}

}

}

}

for(int i=0;i<4;i++){

for(int j=3;j>-1;j--){

process[3-j][0]=array[i][j];

process[3-j][1]=1;

}

for(int l=1;l<4;l++){

int k=l;

while(k>0){

if(process[k][0]==0){

return false;

}else if(process[k-1][0]==0){

return false;

}else if(process[k-1][0]==process[k][0]){

return false;

}else{

break;

}

}

}

}

for(int i=0;i<4;i++){

for(int j=0;j<4;j++){

if(array[i][j]==0){

return false;

}

}

}

return true;

}

public void moveUp(){

ifGenerate2or4=false;

for(int j=0;j<4;j++){

for(int i=0;i<4;i++){

process[i][0]=array[i][j];

process[i][1]=1;

}

processProcess();

for(int i=0;i<4;i++){

array[i][j]=process[i][0];

}

}

if(ifGenerate2or4){

generateRandom2or4();

repaint();

}

}

//向下滑动,若各列均没有方块相消或移动,则返回false,否则返回true;

public void moveDown(){

ifGenerate2or4=false;

for(int j=0;j<4;j++){

for(int i=3;i>-1;i--){

process[3-i][0]=array[i][j];

process[3-i][1]=1;

}

processProcess();

for(int i=3;i>-1;i--){

array[i][j]=process[3-i][0];

}

}

if(ifGenerate2or4){

generateRandom2or4();

repaint();

}

}

//向左滑动,若各行均没有方块相消或移动,则返回false,否则返回true;

public void moveLeft(){

ifGenerate2or4=false;

for(int i=0;i<4;i++){

for(int j=0;j<4;j++){

process[j][0]=array[i][j];

process[j][1]=1;

}

processProcess();

for(int j=0;j<4;j++){

array[i][j]=process[j][0];

}

}

if(ifGenerate2or4){

generateRandom2or4();

repaint();

}

}

//向右滑动,若各行均没有方块相消或移动,则返回false,否则返回true;

public void moveRight(){

ifGenerate2or4=false;

for(int i=0;i<4;i++){

for(int j=3;j>-1;j--){

process[3-j][0]=array[i][j];

process[3-j][1]=1;

}

processProcess();

for(int j=3;j>-1;j--){

array[i][j]=process[3-j][0];

}

}

if(ifGenerate2or4){

generateRandom2or4();

repaint();

}

}

//在游戏区空闲处随机生成2或4

public void generateRandom2or4(){

int rdCount=-1;//记录需要生成2或4的位置的数量

for(int i=0;i<4;i++){

for(int j=0;j<4;j++){

if(array[i][j]==0){

rd[++rdCount]=i*10+j;

}

}

}

int tempI=rd[t(rdCount+1)];

if(uble()<0.1){//随机生成2和4,其比例大致为9:1

array[tempI/10][tempI%10]=4;

}else{

array[tempI/10][tempI%10]=2;

}

}

//单行或单列处理方法,若该行或列没有方块相消或移动,则返回false,否则返回

true;

public void processProcess(){

for(int i=1;i<4;i++){

int k=i;

while(k>0){

if(process[k][0]==0){

break;

}else if(process[k-1][0]==0){

process[k-1][0]=process[k][0];

process[k][0]=0;

k--;

ifGenerate2or4=true;

}else if(process[k-1][0]==process[k][0]){

if(process[k-1][1]==1){

ifGenerate2or4=true;

process[k-1][0]=2*process[k][0];

process[k][0]=0;

score+=process[k-1][0];

if(process[k-1][0]>biggestNumber){

biggestNumber=process[k-1][0];

}

if(score>highestScore){

highestScore=score;

}

process[k-1][1]=0;

}

break;

}else{

break;

}

}

}

}

}

运行结果:

挑战失败:

退出游戏:

六、 总结

通过此次课程设计,使我更加扎实的掌握了有关Java设计方面的知识,在设计过程中

虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,

也暴露出了前期我在这方面的知识欠缺和经验不足。实践出真知,通过亲自动手制作,使

我们掌握的知识不再是纸上谈兵。过而能改,善莫大焉。在课程设计过程中,我们不断发

现错误,不断改正,不断领悟,不断获取。最终的检测调试环节,本身就是在践行“过而

能改,善莫大焉”的知行观。这次课程设计终于顺利完成了,在今后社会的发展和学习实

践过程中,一定要不懈努力,不能遇到问题就想到要退缩。Java课程设计诚然是一门专业

课,给我很多专业知识以及专业技能上的提升,同时又是一门讲道课,一门辩思课,给了

我许多道,给了我很多思,给了我莫大的空间。同时,设计让我感触很深。使我对抽象的

理论有了具体的认识。我认为,在这学期的实验中,不仅培养了独立思考、动手操作的能

力,在各种其它能力上也都有了提高。更重要的是,在实验课上,我们学会了很多学习的

方法。而这是日后最实用的,真的是受益匪浅。要面对社会的挑战,只有不断的学习、实

践,再学习、再实践。

本文标签: 游戏数字设计分数知识