📄 华容道游戏j2me实现(2).htm
字号:
<DIV style="FONT-SIZE: 18pt; COLOR: #990000; FONT-FAMILY: 楷体_GB2312"
align=center><B>Java手机游戏开发实例</B></DIV><BR>
<DIV style="FONT-SIZE: 18px; COLOR: #990000; FONT-FAMILY: ; 宋体: "
align=center>华容道游戏J2ME实现(2)</DIV>
<DIV
style="PADDING-RIGHT: 10px; PADDING-LEFT: 10px; FONT-SIZE: 10.5pt; COLOR: black; LINE-HEIGHT: 180%"
align=left><BR>
<P> 跳过J2ME,我们先来讲点游戏的理论.具体到华容道这个游戏,主要有三个方面,贴图.游戏操作.逻辑判断.这里讲讲贴图,其他两方面放在概要设计和详细设计里讲.所谓的贴图,其实就是画图,就是在要显示图形的位置上输出一副图片,(要是牵扯到动画就要麻烦一些,可以使用TimerTask.Thread或Rannable之类的技术),这副图片可以是事先准备好的也可以是临时处理的.在J2ME中有一个Image类,专门用于管理图片,它有createImage()方法,可以直接读取图片文件(J2ME只支持PNG格式的图片),也可以截取已有的图片的一部分(这样我们可以把很多图片放在一起,然后一张一张的截下来,好处是节省存储空间和文件读取时间,对于手机这两者都是性能的瓶颈).J2ME还有一个Graphics类,专门用于绘图,它有drawImage()方法,可以把一副图片在指定的位置上显示出来,它还有drawRect()方法和setColor()方法,这两个方法在后面我们进行游戏操作时就会用到,这里先交代一下.有了图片和绘图的方法,还需要知道把图画到谁身上,J2ME提供了一个Canvas类,字面意思就是画布,它有一个paint()方法用于刷新页面,还有一个repaint()方法用于调用paint()方法.听着有些糊涂是吧,不要紧,我来结合具体程序讲解一下.为了今后编程的方便,我们创建两个类Images和Draw,Images用于保存一些常量值和图片,Draw主要是用于画图,这两个类的源代码如下。<BR><BR> Images类的源代码如下:<BR><BR></P>
<TABLE width="100%" bgColor=#ffffff>
<TBODY>
<TR>
<TD>package huarongroad;
<P>import javax.microedition.lcdui.*;<BR>import
javax.microedition.lcdui.game.*;</P>
<P>public class Images {//保存常量<BR>//绘图位置常量<BR>public static final
int UNIT = 32;//方块的单位长度<BR>public static final int LEFT =
10;//画图的左边界顶点<BR>public static final int TOP =
9;//画图的上边界顶点<BR>//地图位置常量<BR>public static final int WIDTH =
4;//地图的宽度<BR>public static final int HEIGHT =
5;//地图的高度<BR>//地图标记常量<BR>public static final byte CAOCAO = (byte)
'a'; <A href="file://曹">file://曹</A>操的地图标记<BR>public static final
byte MACHAO = (byte) 'b';//马超的地图标记<BR>public static final byte
HUANGZHONG = (byte) 'c';//黄忠的地图标记<BR>public static final byte GUANYU
= (byte) 'd';//关羽的地图标记<BR>public static final byte ZHANGFEI = (byte)
'e';//张飞的地图标记<BR>public static final byte ZHAOYUN = (byte)
'f';//赵云的地图标记<BR>public static final byte ZU = (byte)
'g';//卒的地图标记<BR>public static final byte BLANK = (byte)
'h';//空白的地图标记<BR>public static final byte CURSOR = (byte)
'i';//光标的地图标记<BR>//地图组合标记常量<BR>public static final byte DLEFT =
(byte) '1'; <A href="file://组">file://组</A>合图形左边标记<BR>public static
final byte DUP = (byte) '2'; <A
href="file://组">file://组</A>合图形上边标记<BR>public static final byte
DLEFTUP = (byte) '3'; <A
href="file://组">file://组</A>合图形左上标记<BR>//图片常量<BR>public static Image
image_base;//基本图片<BR>public static Image
image_Zhaoyun;//赵云的图片<BR>public static Image
image_Caocao;//曹操的图片<BR>public static Image
image_Huangzhong;//黄忠的图片<BR>public static Image
image_Machao;//马超的图片<BR>public static Image
image_Guanyu;//关羽的图片<BR>public static Image
image_Zhangfei;//张飞的图片<BR>public static Image
image_Zu;//卒的图片<BR>public static Image image_Blank;//空白的图片<BR>public
static Image image_Frame;//游戏框架的图片</P>
<P>public Images() {//构造函数<BR>}</P>
<P>public static boolean init() {//初始化游戏中用到的图片<BR>try
{<BR>image_base =
Image.createImage("/huarongroad/BITBACK.png");<BR>image_Frame =
Image.createImage(image_base, 126, 0, 145,
177,<BR>Sprite.TRANS_NONE);<BR>//Sprite类是用来翻转图片的,是MIDP2.0新新增加的支持游戏的特性<BR>image_Zhaoyun
= Image.createImage(image_base, 0, 0, UNIT, 2 *
UNIT,<BR>Sprite.TRANS_NONE);<BR>image_Caocao =
Image.createImage(image_base, UNIT, 0, 2 * UNIT,<BR>2 * UNIT,
Sprite.TRANS_NONE);<BR>image_Huangzhong =
Image.createImage(image_base, 3 * UNIT, 0, UNIT,<BR>2 *
UNIT,<BR>Sprite.TRANS_NONE);<BR>image_Machao =
Image.createImage(image_base, 0, 2 * UNIT, UNIT,<BR>2 *
UNIT,<BR>Sprite.TRANS_NONE);<BR>image_Guanyu =
Image.createImage(image_base, UNIT, 2 * UNIT,<BR>2 * UNIT,
UNIT,<BR>Sprite.TRANS_NONE);<BR>image_Zhangfei =
Image.createImage(image_base, 3 * UNIT, 2 * UNIT,<BR>UNIT, 2 *
UNIT,<BR>Sprite.TRANS_NONE);<BR>image_Zu =
Image.createImage(image_base, 0, 4 * UNIT, UNIT,
UNIT,<BR>Sprite.TRANS_NONE);<BR>image_Blank =
Image.createImage(image_base, 1 * UNIT, 4 *
UNIT,UNIT,<BR>UNIT,<BR>Sprite.TRANS_NONE);</P>
<P>return true;<BR>}catch (Exception ex) {<BR>return
false;<BR>}<BR>}<BR>}</P></TD></TR></TBODY></TABLE>
<P> Draw类的源代码如下:<BR></P>
<TABLE width="100%" bgColor=#ffffff>
<TBODY>
<TR>
<TD>
<P>package huarongroad;</P>
<P>import javax.microedition.lcdui.*;</P>
<P>public class Draw {<BR>//绘制游戏中的图片<BR>public Draw(Canvas canvas)
{//构造函数<BR>}</P>
<P>public static boolean paint(Graphics g, byte img, int x, int y)
{<BR>//在地图的x,y点绘制img指定的图片<BR>try {<BR>paint(g, img, x, y,
Images.UNIT);//把地图x,y点转化成画布的绝对坐标,绘图<BR>return true;<BR>}<BR>catch
(Exception ex) {<BR>return false;<BR>}<BR>}</P>
<P>public static boolean paint(Graphics g, byte img, int x, int y,
int unit) {<BR>try {<BR>switch (img) {<BR>case
Images.CAOCAO://画曹操<BR>//变成绝对坐标,并做调整<BR>g.drawImage(Images.image_Caocao,
Images.LEFT + x * unit,<BR>Images.TOP + y * unit,<BR>Graphics.TOP |
Graphics.LEFT);<BR>break;<BR>case
Images.GUANYU://画关羽<BR>g.drawImage(Images.image_Guanyu, Images.LEFT
+ x * unit,<BR>Images.TOP + y * unit,<BR>Graphics.TOP |
Graphics.LEFT);<BR>break;<BR>case
Images.HUANGZHONG://画黄忠<BR>g.drawImage(Images.image_Huangzhong,
Images.LEFT + x * unit,<BR>Images.TOP + y * unit,<BR>Graphics.TOP |
Graphics.LEFT);<BR>break;<BR>case
Images.MACHAO://画马超<BR>g.drawImage(Images.image_Machao, Images.LEFT
+ x * unit,<BR>Images.TOP + y * unit,<BR>Graphics.TOP |
Graphics.LEFT);<BR>break;<BR>case
Images.ZHANGFEI://画张飞<BR>g.drawImage(Images.image_Zhangfei,
Images.LEFT + x * unit,<BR>Images.TOP + y * unit,<BR>Graphics.TOP |
Graphics.LEFT);<BR>break;<BR>case
Images.ZHAOYUN://画赵云<BR>g.drawImage(Images.image_Zhaoyun,
Images.LEFT + x * unit,<BR>Images.TOP + y * unit,<BR>Graphics.TOP |
Graphics.LEFT);<BR>break;<BR>case
Images.ZU://画卒<BR>g.drawImage(Images.image_Zu, Images.LEFT + x *
unit,<BR>Images.TOP + y * unit,<BR>Graphics.TOP |
Graphics.LEFT);<BR>break;<BR>case
Images.BLANK://画空白<BR>g.drawImage(Images.image_Blank, Images.LEFT +
x * unit,<BR>Images.TOP + y * unit,<BR>Graphics.TOP |
Graphics.LEFT);<BR>break;<BR>case
Images.CURSOR://画光标<BR>g.drawRect(Images.LEFT + x *
unit,<BR>Images.TOP + y *
unit,Images.UNIT,Images.UNIT);<BR>break;<BR>}<BR>return
true;<BR>}catch (Exception ex) {<BR>return false;<BR>}<BR>}<BR>}
</P></TD></TR></TBODY></TABLE>
<P> 其中Images类存的是绘图位置常量(也就是在画图时每个格子的长度和相对坐标原点位置要进行的调整)、地图位置常量(地图的长、宽),地图标记常量(人物对应的记号),地图组合标记常量(后面会细说),图片常量(存放人物的图片);Draw类主要负责在制定的位置画出人物图片。下面我来说说Images类中的地图标记常量和地图组合标记常量。为了能够灵活的安排各个关面的布局,我们决定把游戏布局的信息存储在外部文件中,然后程序启动后把它读进来。这样我们制定了一套存储图片的代码,这就是地图标记常量,如上面Images类中定义的Caocao(曹操)用a字符来表示,当程序读到a字符时就能将它转化成曹操对应的图片,并在读到a字符的位置上进行显示。但是从实际观察中我们发现所有的图片并不是统一大小的,有的占4个格子,有的占2个格子,还有的占1个格子,而且即便同是占两个格子的图片还有横、竖之分。有鉴于此,我们引入了地图组合标记常量,就是说在遇到占有多个格子的时候,值1(也就是Images.LEFT)表示它的左边是一个真正的地图标记,值2(也就是Images.UP)表示它的上边是一个真正的地图标记,值1(也就是Images.LEFTUP)表示它的左上边是一个真正的地图标记。地图组合标记常量其实就是用来占位置的,与实际显示无关,当后面我们将到移动时还会再来分析组合标记的使用。<BR><BR> Draw类主要是用来在画布上画出图形,它有两个paint方法,这是很常见的函数重载。但是程序中实际上只用到了4个参数的paint方法,它直接获得要画图片的相对坐标位置信息,然后调用5个参数的paint方法。5个参数的paint方法将相对坐标位置信息转换成绝对位置,并实际调用Graphics.drawImage()方法,将Images中的图片画了出来。这种实现方法的好处是灵活和便于扩展,但你需要画图的位置并不能够对应到格子中的相对坐标位置时,你就可以直接调用5个参数的paint方法,而不必再去修改这各类;但你添加新的图片时,只要在Images中增加对应的常量,然后向Draw中5个参数的paint方法添加一条处理就可以了。写到这里,两天的时间刚好用完。</P><BR><BR></DIV></TD></TR>
<TR>
<TD class=center01>
<DIV align=center>来源:天极网 作者:
<DIV></DIV></DIV></TD>
<TD class=center01 width=280>
<DIV align=center><FONT color=#0000ff><A
href="http://act.it.sohu.com/book/chapter.php?id=461&volume=4&chapter=1">上一页</A></FONT>
<FONT color=#0000ff><A
href="http://act.it.sohu.com/book/serialize.php?id=461">回书目</A></FONT>
<FONT color=#0000ff><A
href="http://act.it.sohu.com/book/chapter.php?id=461&volume=4&chapter=3">下一页</A></FONT>
</DIV></TD></TR></TBODY></TABLE>
<TABLE>
<TBODY>
<TR>
<TD width=760>
<TABLE height=10 cellSpacing=0 cellPadding=0 width=760 border=0>
<TBODY>
<TR>
<TD></TD></TR></TBODY></TABLE><!------------ 评论 ---------------->
<TABLE cellSpacing=0 cellPadding=0 width=760 border=0>
<TBODY>
<TR>
<TD><IFRAME id=vs src="华容道游戏J2ME实现(2).files/comment_list1.htm"
frameBorder=0 width="100%"
scrolling=no></IFRAME></TD></TR></TBODY></TABLE><BR>
<SCRIPT language=javascript>function CheckNetwordForm(theForm){ if("" == theForm.content.value) { alert("写两句吧~~"); theForm.content.focus(); return false; } var index; for(index=0;index<theForm.content.value.length;index++) { if(" " != theForm.content.value.charAt(index)) break; } if(index == theForm.content.value.length) { alert("写两句吧~~"); theForm.content.focus(); return false; } if (theForm.content.value.length>100){ alert("评论字数不能超过100哦"); theForm.content.focus(); return false; } return true;}</SCRIPT>
<!------------------ 评论 --------------->
<FORM name=netword onsubmit="javascript: return CheckNetwordForm(this);"
action=insertnetword.php method=post>
<TABLE cellSpacing=0 cellPadding=0 width=760 border=0>
<TBODY>
<TR>
<TD class=text6 height=25> 给此书打分:<A name=1></A> <SELECT
name=score> <OPTION value=5 selected>非常好</OPTION> <OPTION
value=4>还凑合</OPTION> <OPTION value=3>一般吧</OPTION> <OPTION
value=2>不太行</OPTION> <OPTION value=1>太差了</OPTION></SELECT>
用户名: <INPUT id=id type=hidden value=461 name=id> <INPUT type=hidden
value=/book/chapter.php?id=461&volume=4&chapter=2
name=backurl> <INPUT id=username maxLength=20 name=username> <FONT
color=#666666>*评论字数请控制在一百字以内</FONT> </TD></TR></TBODY></TABLE><BR> <TEXTAREA id=description name=content rows=4 wrap=off cols=80></TEXTAREA>
<INPUT type=submit value=提交 name=Submit>
</FORM></TD></TR></TBODY></TABLE></TD></TR></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=760 border=0>
<TBODY>
<TR>
<TD width=1003 background=华容道游戏J2ME实现(2).files/t_bj01.gif height=9><IMG
height=1 src="" width=1></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=760 bgColor=#ffffff border=0>
<TBODY>
<TR>
<TD>
<HR width=760 noShade SIZE=1>
</TD></TR>
<TR>
<TD align=middle><A class=black href="http://www.chinaren.com/"
target=_blank>ChinaRen</A> - <A class=black
href="http://big5.www.sohu.com/" target=_blank>繁体版</A> - <A class=black
href="http://hr.sohu.com/hrm.html" target=_blank>搜狐招聘</A> - <A class=black
href="http://add.sohu.com/" target=_blank>网站登录</A> - <A class=black
href="http://help.sohu.com/" target=_blank>帮助中心</A> - <A class=black
href="http://book.news.sohu.com/onClick=this.style.behavior='url(#default#homepage)';this.setHomePage('http://www.sohu.com');return"
target=_blank false;>设置首页</A> - <A class=black
href="http://adinfo.sohu.com/" target=_blank>广告服务</A> - <A class=black
href="http://www.sohu.com/about/lianxi.htm" target=_blank>联系方式</A> - <A
class=black href="http://www.sohu.com/about/privacy.html"
target=_blank>保护隐私权</A> - <A class=black href="http://www.sohu.com/about/"
target=_blank>About SOHU</A> - <A class=black
href="http://www.sohu.com/about/" target=_blank>公司介绍</A><BR><SPAN
class=eng>Copyright © 2004 Sohu.com Inc. All rights reserved. 搜狐公司
版权所有</SPAN> </TD></TR></TBODY></TABLE></CENTER><!-- START NNR Site Census V5.1 --><!-- COPYRIGHT 2004 Nielsen // Netratings -->
<SCRIPT language=JavaScript type=text/javascript>
<!--
var _rsCI="cn-sohu";
var _rsCG="0";
var _rsDT=0;
var _rsDU=0;
var _rsDO=0;
var _rsX6=0;
var _rsSI=escape(window.location);
var _rsLP=location.protocol.indexOf('https')>-1?'https:':'http:';
var _rsRP=escape(document.referrer);
var _rsND=_rsLP+'//secure-cn.imrworldwide.com/';
if (parseInt(navigator.appVersion)>=4)
{
var _rsRD=(new Date()).getTime();
var _rsSE=1;
var _rsSV="";
var _rsSM=0.01;
_rsCL='<scr'+'ipt language="JavaScript" type="text/javascript" src="'+_rsND+'v51.js"><\/scr'+'ipt>';
}
else
{
_rsCL='<img src="'+_rsND+'cgi-bin/m?ci='+_rsCI+'&cg='+_rsCG+'&si='+_rsSI+'&rp='+_rsRP+'">';
}
document.write(_rsCL);
//-->
</SCRIPT>
<NOSCRIPT><IMG alt="" src="华容道游戏J2ME实现(2).files/m.gif"> </NOSCRIPT><!-- END NNR Site Census V5.1 -->
<SCRIPT language=JavaScript src="华容道游戏J2ME实现(2).files/nnselect.js"></SCRIPT>
<NOSCRIPT><IMG height=1 src="" width=1> </NOSCRIPT></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -