返回列表 回复 发帖

初涉游戏开发:J2ME RPG游戏边学边做之三

<P>初涉游戏开发:J2ME RPG游戏边学边做之三(1)</P>
<P>&nbsp;</P>
<P>在前两次的连载文章<A href="http://tech.ccidnet.com/art/1128/20050901/323359_1.html"><FONT color=#42495b>初涉游戏开发</FONT></A>中,我们已经成功的完成地图和英雄的编写。这次我们将为英雄加入碰撞检测和人物对话。<BR><BR>在开始前,我们需要确定在地图中哪些地方不允许走动,那些地方可以触发对话,这就需要在地图中事先把这些事件定义好。我们改变先前的Scene类。利用二维数组为地图加入事件。<BR><BR><BR><BR><BR><BR></P><CCID_NOBR>
<CENTER>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6>
<DIV align=left><PRE><CCID_CODE>Scene.java

//这次的代码和上次有点出入,这次我们利用getMap()方法来读取地图数组,这样方便以后改为
//从外部文件读取
package brave;

import javax.microedition.lcdui.game.TiledLayer;
import javax.microedition.lcdui.Image;

public class Scene
{
public static TiledLayer createTiledLayerByBackground(Image image)
{
TiledLayer tiledLayer = new TiledLayer(10, 8, image, 48, 64);
tiledLayer.fillCells(0, 0, 10, 8, 2);
return tiledLayer;
}

public static int[][] getMap()
{
//生成地图数组,在原来的每个地图元素后面都加了一个事件。
//事件id为99是不允许通过
//事件id为98是激活对话
//其实在这里定义二维数组并不是很方便,个人感觉还是三维比较直观和方便,
//这里为了方便,只定义二维数组
int[][] maplist =
{
//30*32
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,1}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0},
   {0 ,0}, {28,99}, {29,99}, {29,99}, {29,99},
   {29,99}, {29,99}, {29,99},

{29,99}, {29,99}, {29,99}, {29,99}, {29,99},
{29,99}, {29,99}, {29,99}, {29,99}, {29,99},

{29,99}, {29,99}, {29,99}, {29,99}, {29,99},
{29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {30,0},

{0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0},
   {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {1 ,99}, {2 ,99},
   {3 ,99}, {4 ,99}, {5 ,99}, {0

,0}, {0 ,0}, {0 ,0}, {1 ,99}, {2 ,99}, {3 ,99},
{3 ,99}, {26,99}, {3 ,99}, {3 ,99}, {4 ,99}, {5

,99}, {0 ,0}, {0 ,0}, {1 ,0}, {2 ,0}, {3 ,0},
{4 ,0}, {5 ,0}, {0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {7 ,99}, {8 ,99},
   {46,99}, {10,99}, {11,99}, {0

,0}, {0 ,0}, {0 ,0}, {7 ,99}, {8 ,99}, {47,99},
{31,99}, {32,99}, {33,99}, {47,99}, {10,99},

{11,99}, {0 ,0}, {0 ,0}, {7 ,0}, {8 ,0}, {46,0},
{10,0}, {11,0}, {0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {13,99}, {14,99},
   {15,99}, {16,99}, {17,99}, {0

,0}, {0 ,0}, {0 ,0}, {13,99}, {14,99}, {14,99},
{37,99}, {38,99}, {39,99}, {14,99}, {16,99},

{17,99}, {0 ,0}, {0 ,0}, {13,0}, {14,0}, {15,0},
{16,0}, {17,0}, {0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {19,99}, {20,99}, {21,99},
   {22,99}, {23,99}, {6

,99}, {0 ,0}, {0 ,0}, {19,99}, {20,99}, {20,99},
{43,99}, {44,99}, {45,99}, {20,99}, {20,99},

{23,99}, {0 ,0}, {0 ,0}, {19,0}, {20,0}, {21,0},
{22,0}, {23,0}, {0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
   {0 ,0}, {0 ,0}, {0 ,0},

{0 ,0}, {0 ,0}, {24,99}, {24,99}, {24,99}, {13,99},
{15,99}, {17,99}, {24,99}, {24,99}, {24,99},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0},
{0 ,0}, {0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
   {0 ,0}, {0 ,0}, {0 ,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {19,99},
{21,99}, {23,99}, {0 ,0}, {0 ,0}, {0 ,0}, {0

,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
   {0 ,0}, {0 ,0}, {0 ,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},

{0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
   {12,0}, {12,0}, {12,0},

{12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0},
{12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0},

{12,0}, {12,0}, {12,0}, {12,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
   {0 ,0}, {0 ,0}, {0 ,0},

{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0},
{25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {1 ,0}, {2 ,0}, {3 ,0},
   {4 ,0}, {5 ,0}, {0 ,0},

{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0},
{25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},

{0 ,0}, {1 ,0}, {2 ,0}, {3 ,0}, {4 ,0}, {5 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {7 ,0}, {8 ,0}, {46,0},
   {10,0}, {11,0}, {0 ,0},

{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0},
{25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},

{0 ,0}, {7 ,0}, {8 ,0}, {46,0}, {10,0}, {11,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {13,0}, {14,0}, {15,0},
   {16,0}, {17,0}, {0 ,0},

{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0},
{25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},

{0 ,0}, {13,0}, {14,0}, {15,0}, {16,0}, {17,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {19,0}, {20,0}, {21,0},
   {22,0}, {23,0}, {0 ,0},

{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0},
{25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},

{0 ,0}, {19,0}, {20,0}, {21,0}, {22,0}, {23,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
   {0 ,0}, {0 ,0}, {0 ,0},

{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0},
{25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},

{0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
   {0 ,0}, {0 ,0}, {0 ,0},

{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0},
{25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},

{0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
   {0 ,0}, {0 ,0}, {0 ,0},

{12,0}, {25,0}, {25,0}, {25,0}, {25,0}, {25,0},
{25,0}, {25,0}, {25,0}, {25,0}, {25,0}, {12,0},

{0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
   {12,0}, {12,0}, {12,0},

{12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0},
{12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0},

{12,0}, {12,0}, {12,0}, {12,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
   {0 ,0}, {0 ,0}, {0 ,0},

{12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
   {0 ,0}, {0 ,0}, {0 ,0},

{12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {1 ,0}, {2 ,0}, {3 ,0},
   {4 ,0}, {5 ,0}, {0 ,0},

{12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {1 ,0}, {3 ,0},
{5 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},

{0 ,0}, {1 ,0}, {2 ,0}, {3 ,0}, {4 ,0}, {5 ,0}, {0 ,0},
{36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {7 ,0}, {8 ,0}, {46,0},
   {10,0}, {11,0}, {0 ,0},

{12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {7 ,0},
{48,0}, {11,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},

{0 ,0}, {7 ,0}, {8 ,0}, {46,0}, {10,0}, {11,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {13,0}, {14,0}, {15,0},
   {16,0}, {17,0}, {0 ,0},

{12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {6 ,0}, {13,0},
{15,0}, {17,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},

{0 ,0}, {13,0}, {14,0}, {15,0}, {16,0}, {17,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {19,0}, {20,0}, {21,0},
   {22,0}, {23,0}, {0 ,0},

{12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {6 ,0}, {19,0},
{21,0}, {23,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},

{0 ,0}, {19,0}, {20,0}, {21,0}, {22,0}, {23,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
   {0 ,0}, {0 ,0}, {0 ,0},

{12,0}, {18,98}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},

{0 ,0}, {0 ,0}, {0 ,0}, {12,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
   {12,0}, {12,0}, {12,0},

{12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0},
{12,0}, {12,0}, {12,0}, {12,0}, {12,0}, {12,0},

{12,0}, {12,0}, {12,0}, {12,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
   {0 ,0}, {0 ,0}, {0 ,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
{12,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {34,99}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
   {0 ,0}, {0 ,0}, {0 ,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {12,0},
{12,0}, {12,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {36,99}, {0 ,0},
   {0 ,0}, {40,99}, {29,99}, {29,99}, {29,99},
   {29,99}, {29,99}, {29,99},

{29,99}, {29,99}, {29,99}, {29,99}, {29,99},
{29,99}, {12,0}, {12,0}, {12,0}, {29,99}, {29,99},

{29,99}, {29,99}, {29,99}, {29,99}, {29,99}, {29,99},
{29,99}, {29,99}, {29,99}, {42,99}, {0 ,0},
   {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
   {0 ,0}, {0 ,0}, {0 ,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},

{0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0}, {0 ,0},
{0 ,0}, {0 ,0}
};
return maplist;
}

public static TiledLayer createTiledLayerByForeground(Image image)
{
//生成地图
int[][] maplist = Scene.getMap();
TiledLayer tiledLayer = new TiledLayer(30, 32, image, 16, 16);
for(int i = 0 ; i &lt; maplist.length ; i++)
{
int col = i % 30;
int row = (i - col) / 30;
tiledLayer.setCell(col, row, maplist<I>[0]);
}
return tiledLayer;
}

public static int getEvent(int x, int y)
{
//根据地图单元格的x和y得到该单元格的事件,这里的30应该根据地图的实际大小来确定
return Scene.getMap()[x + (y * 30)][1];
}
}</CCID_CODE></PRE></DIV></I></TD></TR></TBODY></TABLE></CENTER></CCID_NOBR>
<P style="TEXT-INDENT: 2em"></CCID_NOBR></P>
┏^ǒ^*★*^ǒ^*☆*^ǒ^*☆*^ ┓
┃  ┏┯┓┏┯┓ ┏┯┓┏┯┓      ┃
┃  ┠无┨┠线┨ ┠空┨┠间┨      ┃
┃  ┗┷┛┗┷┛ ┗┷┛┗┷┛      ┃
┗^ǒ^*★*^ǒ^*☆*^ǒ^**^ǒ^┛

初涉游戏开发:J2ME RPG游戏边学边做之三 (2)

地图完成!下面是检测上面定义的事件。<BR><BR>我们知道在Sprite类中已经有了一个检测Sprite(人物)和TiledLayer(地图)的方法:collidesWith()。可是该检测方法必须在Sprite和TiledLayer交错时才能检测出来,个人感觉使用不是很方便,所以我决定重新写一检测碰撞的方法,该方法可以检测出当前Sprite在四个方向时下一个将要移动的地图单元是什么。<BR><BR>基本如下:<BR><BR><CCID_NOBR>
<CENTER>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6>
<DIV align=left><PRE><CCID_CODE>int xmax = (getX() + getWidth()) / 16;
int ymax = (getY() + getHeight()) / 16;
int xmin = getX() / 16;
int ymin = getY() / 16;
//如果当前的人物方向等于上,并且在地图单元之间的交错处,开始判断他的下一个将要移动的
//地图单元是什么
if(BraveCanvas.way == BraveCanvas.UP_PRESSED &amp;&amp; getY() % 16 == 0)
{
if((getX() + getWidth()) % 16 == 0)
xmax -= 1;
for(int i = xmin ; i &lt;= xmax ; i++)
{
//这里的i,ymin-1即表示人物将要移动的地图单元。而且并不是一个,是由他的
//getX()和getWidth()来决定
System.out.print(i+","+ymin-1)
}
}</CCID_CODE></PRE></DIV></TD></TR></TBODY></TABLE></CENTER></CCID_NOBR>
<P style="TEXT-INDENT: 2em" align=left>其他的几个方向实现原理是一样的。
<P style="TEXT-INDENT: 2em" align=left>该方法置于Hero类中,代码如下:
<P style="TEXT-INDENT: 2em" align=left></P><CCID_NOBR>
<CENTER>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6>
<DIV align=left><PRE><CCID_CODE>Hero.java

package brave;

import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.Image;
import java.io.IOException;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.TiledLayer;

public class Hero extends Sprite
{
private int x;
private int y;

private BraveCanvas braveCanvas;
private BraveManager braveManager;

public Hero(Image image, int frameWidth, int frameHeight)
{
  super(image, frameWidth, frameHeight);
}

public void setBraveCanvas(BraveCanvas braveCanvas)
{
  this.braveCanvas = braveCanvas;
}

public void setBraveManager(BraveManager braveManager)
{
  this.braveManager = braveManager;
}

public void setManager(BraveCanvas braveCanvas)
{
  this.braveCanvas = braveCanvas;
}

public void init(int x, int y)
{
  this.x = x;
  this.y = y;
}

public void afresh()
{
  setPosition(this.x, this.y);
}

public void moveUp(Image image) throws IOException
{
  setImage(image, 17, 26);
  nextFrame();
  //如果事件不为99,98才允许移动
  //(随着事件的增加,这里的的条件也会增加,如果采取3维数组则不会出现该问题)
  if(!eventActionExist(99) &amp;&amp; !eventActionExist(98))
   this.y = Math.max(0, y - 1);
}

public void moveDown(Image image) throws IOException
{
  setImage(image, 17, 26);
  nextFrame();
  //如果事件不为99,98才允许移动
  //(随着事件的增加,这里的的条件也会增加,如果采取3维数组则不会出现该问题)
  if(!eventActionExist(99) &amp;&amp; !eventActionExist(98))
  this.y = Math.min(braveManager.getLayerAt(1).getHeight(), y + 1);
}

public void moveLeft(Image image) throws IOException
{
  setImage(image, 17, 26);
  nextFrame();
  //如果事件不为99,98才允许移动
  //(随着事件的增加,这里的的条件也会增加,如果采取3维数组则不会出现该问题)
  if(!eventActionExist(99) &amp;&amp; !eventActionExist(98))
  this.x = Math.max(0, x - 1);
}

public void moveRight(Image image) throws IOException
{
  setImage(image, 17, 26);
  nextFrame();
  //如果事件不为99,98才允许移动
  //(随着事件的增加,这里的的条件也会增加,如果采取3维数组则不会出现该问题)
  if(!eventActionExist(99) &amp;&amp; !eventActionExist(98))
  this.x = Math.min(braveManager.getLayerAt(1).getWidth(), x + 1);
}
/**
* 根据事件id得到当前人物将要移动的位置能否触发该事件
* @param eventID 时间id
* @return 存在:true 不存在:false
*/
public boolean eventActionExist(int eventID)
{
  int xmax = (getX() + getWidth()) / 16;
  int ymax = (getY() + getHeight()) / 16;
  int xmin = getX() / 16;
  int ymin = getY() / 16;
  if(BraveCanvas.way == BraveCanvas.UP_PRESSED &amp;&amp; getY()
  % 16 == 0)
  {
  if((getX() + getWidth()) % 16 == 0)
    xmax -= 1;
  for(int i = xmin ; i &lt;= xmax ; i++)
   {
  if(Scene.getEvent(i, ymin-1) == eventID)
    return true;
   }
  }
  else if(BraveCanvas.way == BraveCanvas.DOWN_PRESSED &amp;&amp;
  (getY()+getHeight()) % 16

  == 0)
  {
  if((getX() + getWidth()) % 16 == 0)
   xmax -= 1;
  for(int i = xmin ; i &lt;= xmax ; i++)
  {
   if(Scene.getEvent(i, ymax) == eventID)
   return true;
   }
  }
  else if(BraveCanvas.way == BraveCanvas.LEFT_PRESSED &amp;&amp;
  getX() % 16 == 0)
  {
  if((getY() + getHeight()) % 16 == 0)
  ymax -= 1;
  for(int i = ymin ; i &lt;= ymax ; i++)
  {
  if(Scene.getEvent(xmin-1, i) == eventID)
  return true;
   }
  }
  else if(BraveCanvas.way == BraveCanvas.RIGHT_PRESSED &amp;&amp;
  (getX()+getWidth()) % 16

  == 0)
  {
   if((getY() + getHeight()) % 16 == 0)
    ymax -= 1;
   for(int i = ymin ; i &lt;= ymax ; i++)
   {
    if(Scene.getEvent(xmax, i) == eventID)
     return true;
   }
  }
  return false;
}
}</CCID_CODE></PRE></DIV></TD></TR></TBODY></TABLE></CENTER></CCID_NOBR>
<P style="TEXT-INDENT: 2em" align=left></CCID_NOBR></P>
┏^ǒ^*★*^ǒ^*☆*^ǒ^*☆*^ ┓
┃  ┏┯┓┏┯┓ ┏┯┓┏┯┓      ┃
┃  ┠无┨┠线┨ ┠空┨┠间┨      ┃
┃  ┗┷┛┗┷┛ ┗┷┛┗┷┛      ┃
┗^ǒ^*★*^ǒ^*☆*^ǒ^**^ǒ^┛

初涉游戏开发:J2ME RPG游戏边学边做之三 (3)

<P>BraveCanvas类需要增加一个静态变量,这里为了篇幅,暂不给出原码,大家可以在下面看到。<BR><BR>运行后,只有左上角、中间的房子和栅栏,可以正常检测,这是因为其他的单元格为了方便都没有加上事件。<BR><BR>一点缺陷:<BR><BR>其实这里的地图并不是很完善,比如说人物如果在房子上面的话,屋顶应该会把人物遮住一部分,而人物在房子下面的话,人物应该把房子遮住一点。大家如果感兴趣的话可以用图层来解决这问题。<BR><BR>下面说说人物的对话实现。<BR><BR>在实现人物对话的时候,我想实现对话的打字机效果,这就需要一个循环来实现它。循环结束后,打字机的效果结束,对话并没有结束。应该显示对话内容并进入等待状态直到用户再次按键,才真正的结束对话。流程图如下:<BR><BR></P>
<CENTER><IMG style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" src="http://tech.ccidnet.com/col/attachment/2005/9/495605.jpg"></CENTER>
<P><BR>&nbsp;</P>
┏^ǒ^*★*^ǒ^*☆*^ǒ^*☆*^ ┓
┃  ┏┯┓┏┯┓ ┏┯┓┏┯┓      ┃
┃  ┠无┨┠线┨ ┠空┨┠间┨      ┃
┃  ┗┷┛┗┷┛ ┗┷┛┗┷┛      ┃
┗^ǒ^*★*^ǒ^*☆*^ǒ^**^ǒ^┛

初涉游戏开发:J2ME RPG游戏边学边做之三 (4)

代码如下: <CCID_NOBR>
<CENTER>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code style="FONT-SIZE: 9pt" bgColor=#e6e6e6>
<DIV align=left><PRE><CCID_CODE>Hero.java

package brave;

import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.Image;
import java.io.IOException;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.TiledLayer;

public class Hero extends Sprite
{
private int x;
private int y;

private BraveCanvas braveCanvas;
private BraveManager braveManager;

public Hero(Image image, int frameWidth, int frameHeight)
{
  super(image, frameWidth, frameHeight);
}

public void setBraveCanvas(BraveCanvas braveCanvas)
{
  this.braveCanvas = braveCanvas;
}

public void setBraveManager(BraveManager braveManager)
{
  this.braveManager = braveManager;
}

public void setManager(BraveCanvas braveCanvas)
{
  this.braveCanvas = braveCanvas;
}

public void init(int x, int y)
{
  this.x = x;
  this.y = y;
}

public void afresh()
{
  setPosition(this.x, this.y);
}

public void moveUp(Image image) throws IOException
{
  setImage(image, 17, 26);
  nextFrame();
  if(!eventActionExist(99) &amp;&amp; !eventActionExist(98))
   this.y = Math.max(0, y - 1);
}

public void moveDown(Image image) throws IOException
{
  setImage(image, 17, 26);
  nextFrame();
  if(!eventActionExist(99) &amp;&amp; !eventActionExist(98))
   this.y = Math.min(braveManager.getLayerAt(1).getHeight(), y + 1);
}

public void moveLeft(Image image) throws IOException
{
  setImage(image, 17, 26);
  nextFrame();
  if(!eventActionExist(99) &amp;&amp; !eventActionExist(98))
   this.x = Math.max(0, x - 1);
}

public void moveRight(Image image) throws IOException
{
  setImage(image, 17, 26);
  nextFrame();
  if(!eventActionExist(99) &amp;&amp; !eventActionExist(98))
   this.x = Math.min(braveManager.getLayerAt(1).getWidth(), x + 1);
}

//实现人物的对话
public void talk(String addressor,Image talkImage, String s, Graphics g)
{
  g.drawImage(talkImage, 0, 0, Graphics.TOP|Graphics.LEFT);
  g.drawString(addressor+":", 7, 6, Graphics.TOP|Graphics.LEFT);
  for(int i = 0 ; i &lt; s.length() ; i++)
  {
   g.drawString(s.substring(i, i+1), (i*12)+12, 21,

Graphics.TOP|Graphics.LEFT);
   try
   {
    Thread.sleep(100);
   }
   catch(Exception e)
   {
    e.printStackTrace();
   }
   braveCanvas.flushGraphics();
  }
  //对话的文字形式结束,进入等待状态,直到
  //再次按下对话键
  while(BraveCanvas.isTalk)
  {
   try
   {
    int keystates = braveCanvas.getKeyStates();
    //再次按下对话键
    if(keystates == BraveCanvas.FIRE_PRESSED)
    {
     //是否对话标志位置为false
     BraveCanvas.isTalk = false;
     //是否可以重新开始对话标志位置为false
     //之所以这样做是保证在在下一次检测按键时,不重新开始对话
     BraveCanvas.isTalkSign = false;
     break;
    }
    Thread.sleep(50);
   }
   catch(Exception e)
   {
    e.printStackTrace();
   }
  }
}

public boolean eventActionExist(int eventID)
{
  …………
}

}

修改BraveCanvas.java 如下

BraveCanvas.java

package brave;

import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.Graphics;
import java.io.IOException;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.TiledLayer;


public class BraveCanvas extends GameCanvas implements Runnable
{
private boolean sign;
private Graphics g;
private Hero hero;
private Image upimage;
private Image downimage;
private Image leftimage;
private Image rightimage;
private Image talkImage;
private TiledLayer backgroundMap;
private TiledLayer foregroundMap;
private BraveManager braveManager;
//该标志位判断对话是否开始
public static boolean isTalk;
//该标志为判断对话是否可以重新开始,默认可以重新开始
public static boolean isTalkSign = true;
//当前的人物方向(碰撞检测用)
public static int way = 0;

public BraveCanvas()
{
  super(true);
  try
  {
   backgroundMap = Scene.createTiledLayerByBackground(
    Image.createImage("/background.png"));
   foregroundMap = Scene.createTiledLayerByForeground(
    Image.createImage("/foreground.png"));
   upimage = Image.createImage("/hero_up.png");
   downimage = Image.createImage("/hero_down.png");
   leftimage = Image.createImage("/hero_left.png");
   rightimage = Image.createImage("/hero_right.png");
   talkImage = Image.createImage("/talk.png");
   braveManager = new BraveManager();
   braveManager.setBraveCanvas(this);
   hero = new Hero(upimage, 17, 26);
   //hero.setFrameSequence(new int[]{1, 1, 0, 0, 1, 1, 2, 2});
   hero.setBraveCanvas(this);
   hero.setBraveManager(braveManager);
   hero.init(120, 120);
  }
  catch(Exception e)
  {
   e.printStackTrace();
  }
}

public void startup()
{
  this.sign = true;
  Thread thread = new Thread(this);
  thread.start();
}

public void run()
{
  g = getGraphics();
  braveManager.insert(hero, 0);
  braveManager.insert(foregroundMap, 1);
  braveManager.insert(backgroundMap, 2);
  while(sign)
  {
   try
   {
    input(g);
    BraveCanvas.isTalkSign = true;
    paint(g);
    Thread.sleep(15);
   }
   catch(Exception e)
   {
    e.printStackTrace();
   }
  }
}

public void input(Graphics g) throws IOException
{
  int keystates = getKeyStates();
  switch(keystates)
  {
   case UP_PRESSED:
    BraveCanvas.way = UP_PRESSED;
    hero.moveUp(upimage);
    break;
   case DOWN_PRESSED:
    BraveCanvas.way = DOWN_PRESSED;
    hero.moveDown(downimage);
    break;
   case LEFT_PRESSED:
    BraveCanvas.way = LEFT_PRESSED;
    hero.moveLeft(leftimage);
    break;
   case RIGHT_PRESSED:
    BraveCanvas.way = RIGHT_PRESSED;
    hero.moveRight(rightimage);
    break;
   case FIRE_PRESSED:
    //当用户按下对话键时候,首先判断对话是否可以重新开始
    //只有对话可以重新开始后才能再次开始对话
    if(hero.eventActionExist(98))
    {
     if(BraveCanvas.isTalkSign)
     {
      BraveCanvas.isTalk = true;
     }
    }
    break;
  }
  hero.afresh();
  braveManager.afresh();
}

public void paint(Graphics g)
{
  g.setColor(0x000000);
  g.fillRect(0, 0, getWidth(), getHeight());
  g.setColor(0x000000);
  braveManager.paint(g, 0, 0);
  if(BraveCanvas.isTalk)
  {
   //加入对话,这里只是简单做个例子。应该给对话规定编号,然后从文件中相应的编号中读取
   hero.talk("英雄", talkImage, "这是一个小镇", g);
  }
  else
  {
   flushGraphics();
  }
}

}</CCID_CODE></PRE></DIV></TD></TR></TBODY></TABLE></CENTER></CCID_NOBR>
<P style="TEXT-INDENT: 2em">运行后,可以在小镇开始的小木牌处按[射击键]实现对话。
<P style="TEXT-INDENT: 2em">这一篇就写到这,在下一篇中,我将实现地图的场景转换。 </P>
┏^ǒ^*★*^ǒ^*☆*^ǒ^*☆*^ ┓
┃  ┏┯┓┏┯┓ ┏┯┓┏┯┓      ┃
┃  ┠无┨┠线┨ ┠空┨┠间┨      ┃
┃  ┗┷┛┗┷┛ ┗┷┛┗┷┛      ┃
┗^ǒ^*★*^ǒ^*☆*^ǒ^**^ǒ^┛

太好了 顶顶

太好了 顶顶 太好了 顶顶
之一和之二呢?
还不错,来学习学习
全世界飘,问候他人谁有J2ME--API中文版啊
尊重LZ劳动成果,,继续飘~~
一和二呢?楼主?迫切需要,谢谢
不会贴对不起自己!
1 和 2的贴是不是删掉了,我想看了,可否发多次上来,或者直接发给我!
THANKS!
老大!以后打成包怎么样!整个页面显的太乱了!
有梦想谁都了不起
排版不怎么好看啊
眼睛痛
就是你
好乱啊!
看都看花了
还是打包下载吧、。。。
看着很乱..而且程序代码和论坛代码混杂在一起,又没有显著标识,很难认啊..

楼主以后发帖稍微编辑一下吧...
看着确实比较乱 哎 ,看着头疼哦
看不懂啊,好乱
看着好乱啊- -
过来学习一下吧~
努力学习  加油加油
一和二呢???急需啊!!!!!!
返回列表