APP下载

Java语言的桌面程序开发—以推箱子为例

2018-05-23吴锦涛薛益鸽

智能计算机与应用 2018年2期
关键词:三段式

吴锦涛 薛益鸽

摘 要: 作为全世界使用率最高的语言,Java以其独特的魅力吸引了众多程序员。Java虽然在大型游戏的制作上并非最方便的选择,但是在经典小游戏上的制作上却有着独一无二的技术优势。考虑到当前许多网上的小游戏模型代码不是那么简洁,对于初学者并不友好,所以本文在基于一些网络代码的研究后进行了Java语言桌面小程序的探讨开发,使得Java语言方便,简洁的优点得到了更好的体现。

关键词: Java;栈;三段式;推箱子

Abstract:As the world's most-used language Java has attracted many programmers with its unique charm. Although Java is not the most convenient choice for the production of large-scale games the production of classic mini-games has the outstanding technologyical advantages. Considering that many current online game models are not so simple and not friendly to beginners after studying some network code this paper discusses and develops the Java language desktop applet making the convenience and conciseness of Java language can be better reflected.

Key words: Java;stack;Triade;box

1 Java語言概述

Java语言自问世以来,即已经历了长期的发展演变过程。发展至今,Java语言对于专业程序员而言,如果不能精熟运用,这里可打个通俗比喻,即如一名音乐家不识乐谱。Java是一门面向对象编程语言,不仅吸收了C++语言的许多优点,而且摒弃了C++中晦涩高深的部分,因而正在当今的软件开发领域发挥着至关重要的基础模式作用。

分析可知,Java语言获得了大范围的广泛应用。究其原因,可阐释论述如下:

(1) Java语言的简易性。Java语言在语法上都与C语言以及C++语言非常接近,因此对于大多数程序员来说,学习Java将更加容易。同时,Java舍弃了C++中少用、难懂的部分,并且Java语言中的数组和串都是对象,因而就不再需要指针方面的设计。

(2)Java语言面向对象的特点。Java语言中使用类、继承、接口等多种原语。当然,在使用过程中,类的继承是单一的,而接口之间是多继承。Java中还包括各种package,用户在面对各种需求时可以在头部加入扩展包,例如javax-mail-1.3.jar 等。

(3)Java语言的安全性。Java语言多用于网络环境,所以Java提供了一种可以防止恶意代码的安全机制。就Java未设指针这一特点,他人将无法探知程序背后的详情内幕和伪造指针去指向存储器。

(4)Java语言的动态性。Java语言设计的重要目的之一就是可以适应动态的环境变化。Java的类是基于设计需要而灵活载入环境中的,甚至某些时候是通过网络来获取。

2 Java的应用领域

作为广受欢迎的编程语言之一,Java语言在生活和科技领域中有着不可估量的作用与影响。在许多方面,诸如从电子商务网站到Android应用,从各类游戏到桌面的应用程序,即如人们熟悉的Eclipse,IntelliJ等等。接下来,将会针对一些相对重要的领域应用,给出概述如下。

2.1 Android应用

Java距离大众最近的应用是什么?这个问题的答案触手可及,那就是每天都在使用的安卓手机,几乎其中的所有应用都使用了Java汇编。

2.2 应用程序服务

不论在金融服务行业的服务器应用程序,或是Java Web应用程序,亦或是其它软件工具,对当今的社会运行都具有重大的推动作用。尤需一提的就是广泛的软件开发工具,如Eclipse、InetelliJ Idea和Netbans IDE。

3 Java在游戏领域的开发

近年来,游戏产业的蓬勃发展给计算机行业掀起了一股更新热潮。如果说前10年的游戏设计初衷是为了娱乐和休闲,但经过这一时期的萃取演练,现在的游戏则日趋职业化,不论是游戏制作者、或者是游戏玩家,都在对游戏提出更高层次的发布需求。作为游戏服务器中的王者,Java在游戏编译中也占据着举足轻重的地位。特别是目前手机已经成为人类社交中不可或缺的一部分,手机游戏随即大行其道,例如近期知名流行的王者荣耀以及吃鸡。所以无论手游、端游,亦或是页游,都离不开Java的模式参与。

暂且不谈那些大型游戏,这里先将研究视角切换到都玩俄罗斯方块的时期。这也是用Java语言编写的最早期爆款游戏了。巨大的潜在市场,促进了行业的发展,此后则陆续出现了多款到现在都仍耳熟能详的游戏,诸如:贪吃蛇(WORM)、泡泡龙、魂斗罗、超级马里奥等。接下来,即将以经典游戏之一的推箱子来解析并展示Java类游戏的设计和实现。

4 Box的发展设计

在借阅参考了前人[1]的一些观点和试玩了几款推箱子(Push Box)游戏后,研究发现最初推箱子游戏的功能清晰简单,只有最基本的游戏体验,所以就有人提出了一定改进,添加了一些功能选择,比如选关、计分;而后又陆续加入了音乐或者动态的人物,以致将其做成2D[2]或者3D等等。版本在不断地变化,算法和设计也在创新升级之中[3]。近期很火的AI想法也正在渗透并融入其中[4]。为此,本文设计提出了如下的基于三段式的推箱子游戏研发过程,对其内容可详述如下。

在游戏的编译之前,首先要进行游戏的需求分析。分析的理念很简单:一是需要让游戏如何运行,二是该游戏需要满足玩家何种需求,三是如何实现游戏和玩家的互动。

为此,就要提供菜单栏的规划设计。顾名思义,菜单栏是指游戏进行多样化功能或选择帮助的区域。当然,考虑到游戏的娱乐性,本文的推箱子还具备一个特殊的功能—炸掉挡住前进道路的墙。菜单栏的属性可以根据用户需求来依序排布,本文中只定制了3种属性,分别是:选项、帮助和开挂。二级菜单为:选项(重新开始、上一关、下一关、关卡选择、退一步、退出)、帮助(请求帮助)、开启外挂(启用、关于外挂)。菜单栏简洁,则因为这是单机版,从而不需要配设很多数据与互联网之间的传输。帮助选项的选择性信息就丰富许多,既可以包括游戏的玩法,也可以写入游戏设计者的一些信息。至此,就是关于外挂,设计初衷是因为绘制一些复杂地图时发现有些道路不一定能走得通,因而就编写一个功能可以把挡道的墙炸掉。

在菜单栏的分析效果描述后,下一步就是主面板设计。本文设计为将主界面分为两部分,一块(主界面)占据全界面,另一块(游戏界面)则被包含在前一块中,位置居于靠近左下;而在主界面右侧,设计了9个按钮(Button),分别是:开始、退一步、第一关、上一关、下一关、最终关、选关,音乐开关以及炸弹按钮。如此配置后,游戏玩家就不再需要通过菜单进行一些操作,例如退一步或者选关等等。并且,这些按钮也改善了界面的美观性,使游戏体验趋于良好、以致最佳。这里,将研究给出游戏设计的整体流程如图1所示。

5 Push Box的实现

Push Box的实现过程中,首先要创建一个基于JFrame的類mainframe,主要用于设计撰写菜单和页面布局的代码,包括按钮、声音等。接下来,将开启本次研究的主题设计,即如何实现推箱子的行动,包括:行动、退一步和炸弹。研发过程可详见如下。

5.1 地图的生成

考察分析可知,现在多数这一类游戏的地图都使用图片与数字结合,使用数字图片一一对应的关系,用数字来描绘地图。研究中,数字化地图的设计示例如图2所示。

由图2可知,这是一张20×20的地图,图2中的每个数字都代表了不同的图片。

其中,鸭子的图片为5、6、7、8,分别对应着正面、左面、右面、背面。但是在制作地图时,默认状态下的鸭子是以正面出现的,所以只写了5代表鸭子,其实无论将哪种状态当做鸭子并无大碍。总地来说,0为背景,1为地图的边界以及不可通过障碍,2为可移动草地,3为箱子,4为箱子指定到达的地点,9为当鸭子将箱子推至目的地后变为一只小章鱼。而图2的数字,通过代码的调用运行即可呈现出地图效果。研发可得代码如下:

public class Readmap{

private int level mx my;

private int [][] mymap=new int[20][20];

FileReader r;

BufferedReader re;

String bb=""

int[] x;

int c=0;

Readmap(int k)

{

level=k;

String s;

try{

File f=new File(pathname:"maps\\"+level+".map")

r=new FileReader(f);

re=new BufferedReader(r);

try{

while((s=re.readLine())!=null){

bb=bb+s;

}

}

catch(IOException g)

{

System.out.println(g);

}

byte[] d=bb.getBytes();

int len=bb.length();

int[] x=new int[len];

for(int i=0;i

x[i]=d[i]-48;

}

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

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

mymap[i][j]=x[c];

if(mymap[i][j]==5){

mx=j;

my=i;

}

c++;

}

}

public void paint(Graphics g){

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

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

g.drawImage(myImage[map[j][i]],x:i*len,y:j*len,observer:this)

}

}}

由上述代码段可知,其中定义了一个二维数组来存储20×20的地图数字,通过File的方式查询到对应的地图编码后使用Filereader方式进行读取,并存入BufferedReader。同时,定义一个空字符串,使用while循环来判断是否有内容。若为有内容,则将内容存入这一空字符串bb中,这样就获取了整张地图的信息,再通过byte与String的转换,将bb中的内容转换为字节。而且,通过创建一个与bb相同长度的空数组,采用for循环将b字节数组中的内容存放于x数组中。此后,又通过另一个类中的方式调用图片,就完成了地图的读取。人物的读取相对来说要较为简捷。综上代码中,涉及的是一个二维数组地图,为此就使用了二重for循环,遍历地图每一个数字,如果有等于5的,即为本次研究的目标对象—小黄鸭。

5.2 目标的运动

本次研发中,目标对象小黄鸭运动的部分代码设计可见如下:

public void moveup(){

if(map[manY-1][manX]==2||map[manY-1][manX]==4)

{

if(maptmp[manY][manX]==4||maptmp[manY][manX]==9)

map[manY][manX]=4;

else map[manY][manX]=2;

map[manY-1][manX]=8;

repaint( );manY--;mystack.push (item:10);

}

else if(map[manY-1][manX]==3)

{

if(map[manY-2][manX]==4)

{

if(maptmp[manY][manX]==4||maptmp[manY][manX]==9)

map[manY][manX]=4;

else map[manY][manX]=2;

map[manY-1][manX]=8;

map[manY-2][manX]=9;

repaint();manY--;mystack.push(item:11);

}

}

}

如上即是小黃鸭前进的代码,向左、向右和向后只是改变了manY,manX的数值,在逻辑方面未见明显变化,为此这里仅给出向前的代码作为演绎实例。尤需指出的是,其中蕴含着许多假设逻辑,如果设计上出现缺失,就会导致游戏存在漏洞,甚至无法正常运行。

在上述代码中,map就是地图,manY与manX为目标在二维数组构成的地图中的坐标,manY-1在manY的上方一格,其数值就是在之前提过的地图组成元素。在前进中的一种基础行为逻辑设计就是小黄鸭往上走一步,其本身下面并不存在箱子,箱子指定的位子,仅仅是草坪,其上面一格也是同样。那么这代码需要处理的就是将小黄鸭身处的位子变为草坪,代号为2,上面一格原本为草坪2,变为小黄鸭的背面8,然后使用repaint();将地图重画即可。而其它方面的行为逻辑设计也将以同样的改变和重画作为后续的推演依据。

5.3 悔步和退步功能设计

当需要使用悔步功能时,就要用到栈的概念。栈先进后出的特点可恰当妥帖地应用于悔步设计中。当小黄鸭开始行动时,常常会向栈里输入一个数字。比如,前进时输入10,推着箱子前进时输入11,向左时输入20,向左推箱子时输入21,以此类推。使用这种方法,不但可以区分上一步的方向,也能甄别其是否有推动箱子。如此,就使得研究中的退一步操作更容易实现。这里即以后退一步作为例示(与向前进一步形成对比),关键代码可展现如下:

public void backup(int t){

int n=t;

if(n==10)

{

if(maptmp[manY][manX]==4||maptmp[manY][manX]==9)

{

map[manY][manX]=4;

}

else map[manY][manX]=2;

}

else if(n==11)

{

if(maptmp[manY][manX]==4||maptmp[manY][manX]==9)

{

map[manY][manX]=9;

}

else map[manY][manX]=3;

if(maptmp[manY-1][manX]==4||maptmp[manY-1][manX]==9)

{

map[manY-1][manX]=4;

}

else map[manY-1][manX]=2;

}

map[manY+1][manX]=8;

repaint();manY++;

}

后退一步的执行机制和前进一步较为相似。但需要细加考虑的是,在进行后退一步前,要分类判断从栈中提取的数字是什么。如果是10,那么就启用没有推动箱子向前走了一步需要退回的操作;如果是11,则判断已发生的前进一步是有箱子的。因为研究中的箱子从草坪移动到指定位子的图案是会改变成小章鱼的,故而需要特别的关注。

5.4 炸弹功能设计

本次研究增加的炸弹功能,是为了提供一定的娱乐性。部分研发代码可见如下:

public void zhadan(){

if(map[manY][manX]==5){

if(map[manY+1][manX]==1){

if(map[manY+2][manX]==1&&map;[manY+2][manX-1]!=0 &&map;[manY+2][manX+1]!=0){

runup();

mic.Music_buff();

}else if(map[manY+2][manX]==2||map[manY+2][manX]==3||map[manY+2][manX]==4){

runup();

mic.Music_buff();

}

}

}

}

public void runup(){

new Thread(new Runnable){

@Override

public void run(){

for(int i=10;i<16;i++){

map[manY+1][manX]=i;

try{

Thread.sleep(millis:100);

}catch(Exception e){

e.printStackTrace();

}

repaint();

}

map[manY+1][manX]=2;

repaint();

}

}).start();

}

炸彈功能即先判断小黄鸭的朝向,继而判断小黄鸭朝向的不可通过障碍是否为边界墙,虽然地图中间的墙和地图外围的墙组成部分是一样的,但是在使用炸弹时却不能炸掉最外圈的墙,所以需要确定判断小黄鸭面对墙的再前面一格两侧是否存在0,即背景。如果有,就不能删除,反之可以。特别地,Runup()这4个类插入的是逐帧动画,即炸弹爆炸的动画。

6 结束语

不论是应用开发还是游戏开发都在无止境的升级发展中,设计者需要做的就是不断寻求臻至完美、以及更贴近人性化的设计。本文提出的基于三段式的推箱子的研发设计即是基于Java应用于小游戏的大胆尝试,同时也将为未来后续的创新深入研究提供一个坚实有益的良好基础。

参考文献

[1] 秦涛. 跨平台手机游戏推箱子的设计与实现[D]. 重庆:重庆大学 2015.

[2] 潘惠勇 夏敏捷. Java实现2.5D推箱子游戏[J]. 电脑编程技巧与维护 2014(19):28-31,56.

[3] 谢玉庚. 用间接递归法判断推箱子游戏的死锁情况[J]. 电脑开发与应用 2014 (9):30-34.

[4] 陈建气 邝广朋 梁均杰,等. 推箱子游戏中人工智能的进一步应用[J]. 珠海教育学院学报 2003(4):111-112.

猜你喜欢

三段式
用“三段式”学徒制模式培养区域产业应用型人才
游戏教学法在“三段式”体育教学模式中的运用
浅谈如何提高预科班基础汉语课堂教学效率
《西游记之大圣归来》的编剧艺术