NEC API

    技术2022-05-11  120

    ■ 1. 引言

      在上讲中,我们对网络的相关功能进行了解说。截止上讲以前的讲座,我们讲述的都是关于MIDP的JAVA相关技术的内容,本讲将收尾,介绍NEC扩展API。

    ■ 2. NEC扩展

      NEC扩展API中有如下的类。

     类  AudioClip  处理声音数据类。已在第五讲解说。 AudioListener Audio事务监听器。已在第五讲解说。 ImageEffector  颜色变换类。将在本讲解说。 ImageMap 模拟PCG类。因为能轻松的把多种画面分配在格子里,所以能很容易的制作出背景和版面(ImageMap)。不在本讲解说。 Media  取得媒体数据类。已在第五讲解说。 NxCanvas NEC扩展canvas,支持多重按键。将在本讲解说。 NxGraphics NEC扩展Graphics。描画Sprite、ImageMap。将在本讲解说。 PhoneControl  控制震动、逆光类。不在本讲解说。 Sprite  Sprite类。将在本讲解说。 SpriteSet 管理Sprite类。将在本讲解说。

    关于上表的ImageEffector、NxCanvas、NxGraphics、Sprite、SpriteSet,我们将按顺序展开介绍。

      2.1. 扩展图形类

      NxGraphics 类是Graphics 的扩展类。下面介绍可以实现的Sprite、ImageMap的描画以及矩形区域的复制。NxGraphics 类定义了以下方法。

    void copyArea(int sx, int sy, int width, int height, int dx, int dy)

      把Canvas描画的矩形区域复制后描画。利用此功能能够把描画过一次的东西复制下来进行描画,因此当描画相同内容的拷贝时,可以简化步骤。

    void drawImageMap(ImageMap map, int x, int y)

      对将多种画面分配在格子里的ImageMap进行描画。

    void drawSpriteSet(SpriteSet sprites)

      描画Sprite。后面有Sprite的相关介绍。

    static NxGraphics getNxGraphics(javax.microedition.lcdui.Graphics g)

      取得NxGraphics对象。

      下面展示的是使用copyArea方法的范例。该范例使用copyArea对移动球的一部分进行复制。

    import java.util.Timer;import java.util.TimerTask;

    import javax.microedition.lcdui.Canvas;import javax.microedition.lcdui.Graphics;import javax.microedition.lcdui.Image;

    import com.nec.graphics.NxGraphics;

    /*** copyArea范例动画canvas*/public class CopyAreaMovingBallCanvas extends Canvas {

      private int x; //球的x坐标  private Image img;  private Timer timer;  private TimerTask task;

      /**  * 构造函数  */  public TimerMovingBallCanvas() {    //读取画面    try{      img = Image.createImage("/back.PNG");    }catch(Exception e){      e.printStackTrace();    }     // 设定Timer,TimerTask    timer = new Timer();    task = new TimerMovingBallTask(this);    timer.schedule(task, 100, 100); //从100毫秒后起每100毫秒执行一次任务

      }

      /**  * 描画方法  */  protected void paint(Graphics g) {    //清除画面    g.setColor(255, 255, 255); //白    g.fillRect(0, 0, getWidth(), getHeight());

        //查看球    g.setColor(255, 0, 0);    g.drawString("copyArea Test",0,0,Graphics.TOP|Graphics.LEFT);    g.fillArc(x, 50, 40, 40, 0, 360);    //复制矩形区域    NxGraphics ng = NxGraphics.getNxGraphics(g);    ng.copyArea(x,50,20,20,x,100);  }

      /**  * 改变球的x坐标  */  public void increment() {    x += 3;  }

      /**  * timer task  * 根据计时器设定的时间表执行run()方法。  */  class TimerMovingBallTask extends TimerTask {

        private TimerMovingBallCanvas canvas;

        /**    * 构造函数    * @param canvas    */    public TimerMovingBallTask(TimerMovingBallCanvas canvas) {      this.canvas = canvas;    }

        /**    * 被计时器呼叫时进行的处理    */    public void run() {      canvas.increment();      canvas.repaint();    }  }}

      运行结果如下所示。

      2.2. Sprite

      Sprite是指具有描画位置与大小的对象。Sprite的特征有以下三点。

        1.把SpriteImage分配、移动到任意位置     2.设定SpriteImage中的优先顺序     3.进行SpriteImage同类的碰撞判定

      比如,在Canvas类中,根据描画顺序对画面进行描画,其中重复的部分,需要对描画的处理顺序进行正确的编程,很繁琐。在这种情况下,如果利用Sprite优先顺序,就不用担心描画顺序,很方便。而且,Sprite的碰撞判定,对于经常发生碰撞判定处理的shooting game等应用程序,非常有效。

      为了利用Sprite,在NEC扩展API中准备了以下两类。

        • Sprite

        • SpriteMape

      Sprite类中有以下方法。

     方法 作用 boolean isVisible() 取得Sprite的可视/非可视信息。 Void setImage(javax.microedition.lcdui.Image image) 设定Sprite使用画面。 void setLocation(int x, int y) 设定Sprite查看位置。 void setVisible(boolean b) 设定Sprite的可视/非可视信息。

      SpriteMap 类使用Sprite对象,因此能够进行Sprite对象的同类碰撞判定和设定Sprite对象的描画优先顺序。SpriteMap中有以下方法。

     方法 作用 int getCollisionFlag(int index) 取得由自变量index指定的Sprite碰撞判定flag。 int getCount() 返回保持的Sprite数。 Sprite getSprite(int index) 返回由自变量index指定的索引Sprite。 Sprite[] getSprites()  返回Sprite排列。 boolean isCollision(int index1, int index2) 取得由自变量index1和index2指定的Sprite碰撞判定结果 void setCollisionAll() 进行全体Sprite的相互碰撞判定。 void setCollisionOf(int index) 进行由自变量index指定的Sprite碰撞判定。 void setPriority(int index, int prior) 设定Sprite优先顺序。

      Sprite查看利用上述NxGraphics类的方法drawSpriteSet。利用drawSpriteSet方法,能够在画面上查看在SpriteSet注册的Sprite。但是,visible被false指定的Sprite却不能在画面上查看。

    ng.drawSpriteSet(spriteSet);

      下面是Sprite中两球发生碰撞的演示程序的source code。  该演示中,使球运动发生碰撞,则相撞的球就会消失。

    import javax.microedition.lcdui.Display;import javax.microedition.midlet.MIDlet;import javax.microedition.midlet.MIDletStateChangeException;

    /*** 进行Sprite test的演示程序*/public class SpriteSample extends MIDlet {  Display display;  SpriteCanvas canvas;  /**  * 构造函数  */  public SpriteSample(){    display = Display.getDisplay(this);    canvas = new SpriteCanvas();  }  /**  * 打开程序  */  protected void startApp() throws MIDletStateChangeException {    display.setCurrent(canvas);  }  protected void pauseApp() {  }  protected void destroyApp(boolean arg0) throws MIDletStateChangeException   {  }

    }

    import javax.microedition.lcdui.Canvas;import javax.microedition.lcdui.Graphics;import javax.microedition.lcdui.Image;

    import com.nec.graphics.NxGraphics;import com.nec.graphics.Sprite;import com.nec.graphics.SpriteSet;

    /*** Sprite test用canvas* 球发生碰撞后消失*/public class SpriteCanvas extends Canvas{  private final String IMAGE_PATH = "/ball.png";  private Image img = null;  private Sprite ball1 = null;  private Sprite ball2 = null;  private int ball2X = 100;  private int ball2Y = 100;  private SpriteSet spriteSet;  /**  * 构造函数  */  public SpriteCanvas(){    //读取画面    try {      img = Image.createImage(IMAGE_PATH);    } catch (Exception e) {      e.printStackTrace();    }    //Sprite的初始化    spriteSet = new SpriteSet(2);    ball1 = spriteSet.getSprite(0);    ball2 = spriteSet.getSprite(1);    if(img != null){      //球1的初始化      ball1.setImage(img);      ball1.setLocation(0,0);      ball1.setVisible(true);      //球2的初始化      ball2.setImage(img);      ball2.setLocation(ball2X,ball2Y);      ball2.setVisible(true);    }  }  /**  * 描画方法  */  protected void paint(Graphics g) {    //清除画面    g.setColor(255,255,255);    g.fillRect(0,0,getHeight(),getWidth());    //取得NEC扩展Graphics    NxGraphics ng = NxGraphics.getNxGraphics(g);    ng.drawSpriteSet(spriteSet);  }

      /**  * 按键处理  */  protected void keyPressed(int keycode) {    switch(keycode){      case -1:{        ball2Y -= 3;        break;      }      case -2:{        ball2Y += 3;        break;      }      case -3:{        ball2X -= 3;        break;      }      case -4:{        ball2X += 3;        break;      }      default:{        break;      }    }    //使球运动    ball2.setLocation(ball2X,ball2Y);    ball2.setVisible(true);    //进行球的碰撞判定    spriteSet.setCollisionAll();    if(spriteSet.getCollisionFlag(1) == Integer.parseInt("1",2)){      ball1.setVisible(false);    }    //再次描画    repaint();  }

    }

      实际运行上述演示程序的结果如下所示。

      使移动。

      发生碰撞后画面上部的球消失。

      上述演示程序的碰撞判定如下所示。

    //进行球的碰撞判定spriteSet.setCollisionAll();if(spriteSet.getCollisionFlag(1) == Integer.parseInt("1",2)){  ball1.setVisible(false);}

      进行碰撞判定时,必须使用setCollisionOf和setCollisionAll方法。然后,通过isCollision或者getCollisionFlag方法取得结果。

      getCollisionFlag 方法的返回值是int型。第n项的Sprite和,由指定的自变量索引指定的Sprite发生碰撞,第n项的bit变为1,而不发生碰撞则为0。也就是说,与第三项的Sprite发生碰撞时,由二进数返回“100”的值。第五项和第二项的Sprite发生碰撞时,由二进数返回“10010”的值。

      使用getCollisionFlag方法调查与第n项Sprite发生的碰撞时,使用以下计算式。spriteSet.getCollisionFlag(x) % 2的n次方的值 >= 2的(n-1)次方的值

      下面是判断与第三项Sprite发生碰撞的例子。

    If( spriteSet.getCollisionFlag(2) % 8 >= 4){  System.out.println(“碰撞!!!!!!”);}else{  System.out.println(“不碰撞”);}

    2.3. 颜色变换

      利用ImageEffector类,能够改变图片的颜色,而被指定的颜色可以进行最多两种颜色的变换。例如,在选择时/非选择时描画已改变颜色的图标图片,或者描画只有颜色不同的肖像画时,使用该颜色变换功很方便。

    ImageEffector 类中有以下的方法。

    static javax.microedition.lcdui.Image changeColors(javax.microedition.lcdui.Image image, int[][] colormap, int nelems)

    使用changeColors 方法进行颜色变换。在image中,指定变换前的画面,在colormap中指定colormap来改变颜色。在Nelems中指定进行变换的颜色的数量。

    例如,把某画面图片image的蓝色变为红色时,如下所示书写。

    int[][] colormap= {{ 0,0,255},{255,0,0}};ImageEffector.changeColors(image, colormap, 1);

      颜色变换用的colormap是二次元排列,RGB三要素的值按以下所示进行指定。

        1色调的色替换设定

          colormap[0][0] = 变换对象RGB色1的R値;      colormap[0][1] = 变换对象RGB色1的G值;      colormap[0][2] = 变换对象RGB色1的B值;      colormap[1][0] = 变换结果RGB色1的R值;      colormap[1][1] = 变换结果RGB色1的G值;      colormap[1][2] = 变换结果RGB色1的B值;

        2色调的色替换设定

          colormap[2][0] = 变换对象RGB色2的R値;      colormap[2][1] = 变换对象RGB色2的G值;      colormap[2][2] = 变换对象RGB色2的B值;      colormap[3][0] = 变换结果RGB色2的R值;      colormap[3][1] = 变换结果RGB色2的G值;      colormap[3][2] = 变换结果RGB色2的B值;

      下面展示利用ImageEffector的演示程序。该程序把画面上球的颜色变换后的结果在画面下表示出来。

    import javax.microedition.lcdui.Display;import javax.microedition.midlet.MIDlet;import javax.microedition.midlet.MIDletStateChangeException;

    /*** 进行Sprite test的演示程序*/public class ImageEffectorSample extends MIDlet {  Display display;  ImageEffectorCanvas canvas;  /**  * 构造函数   */  public ImageEffectorSample(){    display = Display.getDisplay(this);    canvas = new ImageEffectorCanvas();  }  /**  * 程序的打开方法  */  protected void startApp() throws MIDletStateChangeException {    display.setCurrent(canvas);  }  protected void pauseApp() {  }  protected void destroyApp(boolean arg0) throws MIDletStateChangeException   {  }}

    import javax.microedition.lcdui.Canvas;import javax.microedition.lcdui.Graphics;import javax.microedition.lcdui.Image;

    import com.nec.graphics.ImageEffector;import com.nec.graphics.ImageMap;import com.nec.graphics.NxGraphics;import com.nec.graphics.Sprite;import com.nec.graphics.SpriteSet;

    /*** 颜色变换test用canvas*/public class ImageEffectorCanvas extends Canvas{  private final String IMAGE_PATH = "/ball.png";  private Image img = null;  private Sprite ball1 = null;  private Sprite ball2 = null;  private SpriteSet spriteSet;  private ImageMap im;  /**  * 构造函数  */  public ImageEffectorCanvas(){    //读取画面    try {      img = Image.createImage(IMAGE_PATH);    } catch (Exception e) {      e.printStackTrace();    }    //Sprite的初始化    spriteSet = new SpriteSet(2);    ball1 = spriteSet.getSprite(0);    ball2 = spriteSet.getSprite(1);    if(img != null){      //球1的初始化      ball1.setImage(img);      ball1.setLocation(0,0);      ball1.setVisible(true);

          //进行画面转换      int colormap[][] = {{0,0,0},          {0,0,255},          {255,255,255},          {0,0,0}};      Image img2 =ImageEffector.changeColors(img,colormap,4);

          ball2.setImage(img2);      ball2.setLocation(100,100);      ball2.setVisible(true);    }

      }  /**  * 描画方法  */  protected void paint(Graphics g) {    //取得NEC扩展Graphics    NxGraphics ng = NxGraphics.getNxGraphics(g);    ng.drawSpriteSet(spriteSet);  }}

      运行上述演示程序后的结果如下所示。

      2.4. 多重按键

      利用NEC扩展Canvas的NxCanvas类,能够判断同时按下两个按键。利用该多重按键功能,例如,人物在画面上活动时,可以实现斜向移动。(例如,按右键+下键,向右下移动等)。NxCanvas 类中有以下方法。

    int getPressedKeys()

      我们可以利用getPressedKeys 方法判断被按的按键。按键信息32bit被分为8bit单位,其中包括由canvas类定义的KEY_NUM1等键座信息。

      也就是说,我们同时按“0”和“1”时,

      例) 【0】按键(Keycode=48)和【1】按键(Keycode=49)同时被按时      00000000 00000000 00110000 00110001      |----未使用 经常0----| 【0】 【1】           getPressedKeys()的返回值变为12337

      由于两个按键被特别指定,值必须被分成8bit单位,如下所示,所以可以取得键座的信息。

    int key1 = getPressedKeys() % 256;int key2 = (getPressedKeys() – key1) / 256

      下面展示演示程序。在该程序中如果同时按按键,画面下的球的颜色将产生变化。

    import javax.microedition.lcdui.Display;import javax.microedition.midlet.MIDlet;import javax.microedition.midlet.MIDletStateChangeException;

    /*** 进行多重按键test的演示程序*/public class MultiplKeySample extends MIDlet {  Display display;  MultiplKeyCanvas canvas;  /**  * 构造函数*/  public MultiplKeySample(){    display = Display.getDisplay(this);    canvas = new MultiplKeyCanvas();  }  protected void startApp() throws MIDletStateChangeException {    display.setCurrent(canvas);  }  protected void pauseApp() {  }  protected void destroyApp(boolean arg0) throws MIDletStateChangeException   {  }

    }

    import javax.microedition.lcdui.Graphics;import javax.microedition.lcdui.Image;

    import com.nec.graphics.ImageEffector;import com.nec.graphics.NxCanvas;import com.nec.graphics.NxGraphics;import com.nec.graphics.Sprite;import com.nec.graphics.SpriteSet;

    /*** 多重按键用canvas*/public class MultiplKeyCanvas extends NxCanvas{  private final String IMAGE_PATH = "/ball.png";  private Image img = null;  private Sprite ball1 = null;  private Sprite ball2 = null;  private SpriteSet spriteSet;  /**  * 构造函数  */  public MultiplKeyCanvas(){    //读取画面    try {      img = Image.createImage(IMAGE_PATH);    } catch (Exception e) {      e.printStackTrace();    }    spriteSet = new SpriteSet(2);    ball1 = spriteSet.getSprite(0);    ball2 = spriteSet.getSprite(1);    if(img != null){

          ball1.setImage(img);      ball1.setLocation(0,0);      ball1.setVisible(true);      ball2.setImage(img);      ball2.setLocation(100,100);      ball2.setVisible(true);    }

      }  /**  * 进行img2的颜色变换  */  public void changeColor(){    //进行画面转换    int colormap[][] = {{0,0,0},        {0,0,255},        {255,255,255},        {0,0,0}};    Image img2 =ImageEffector.changeColors(img,colormap,4);    ball2.setImage(img2);  }  /**  * 描画方法  */  protected void paint(Graphics g) {    //取得NEC扩展Graphics    NxGraphics ng = NxGraphics.getNxGraphics(g);    //描画Sprite    ng.drawSpriteSet(spriteSet);  }

      /**  * 按键处理  */  protected void keyPressed(int keycode) {    if(getPressedKeys() > 255){//如果同时按两个按键      changeColor();    }    repaint();  }

    }

      运行结果如下所示。

    . 制作应用程序

      下面介绍如何利用上面解说的扩展API制作应用程序。本讲我们利用Sprite来对“泡泡龙”游戏进行改写。同时,通过判断按键是否被同时按下也可以调节小棒的速度。

      这里为使source code简单,将与声音相关的功能、使用网络的高分处理省略掉。Source code如下所示。

    block_src.zip

      这里添加的方法有下面两个。

    • 对球、小棒、彩球进行Sprite化。

    • 同时按方向按键和确定按键,改变小棒的速度。

      3.1. Sprite化

      球、小棒、彩球都由Sprite表现并进行碰撞判定。因为由Sprite来进行碰撞判定,所以就不用单独进行碰撞判定处理的书写了。

      3.1.1. 变量的定义

      为了进行Sprite处理,首先定义例子变数。这里按以下所示进行定义。

    //SpriteSpriteSet spriteSet = new SpriteSet(30);Sprite ball = spriteSet.getSprite(0); /* 在排列的第一位设定球的Sprite */Sprite bar = spriteSet.getSprite(1); /* 在排列的第二位设定小棒的Sprite */

      spriteSet 的分配如下所示。    [0] 球    [1] 小棒    [2]~[29] 彩球

    按照上述变量的定义,则Sprite的数为30。球1,小棒1,彩球28,合计30。以前程序的彩球数是35,但因为SpriteSet规定最多不超过32,所以彩球的数量减到了28。改变常量BLOCJ_V,减少彩球纵向的个数。

    private final int BLOCK_V = 4; //彩球纵向的个数

      3.1.2. Sprite的初始化

      接下来进行Sprite的初始化。设定实际的球、小棒、彩球图片和查看坐标。为进行初始化准备了initilizeSprite方法。

    /*** 进行Sprite的初始化*/public void initiliseSpriteSet() {

      //进行球的初始化  ballX = barX;  ballY = barX - BALL_HEIGHT;  ball.setLocation(ballX, ballY);  ball.setImage(ballImg);  ball.setVisible(true);

      //进行小棒的初始化  bar.setLocation(barX, barY);  bar.setImage(barImg);  bar.setVisible(true);

      //进行彩球的初始化  blockCount = BLOCK_H * BLOCK_V;  Sprite block = null;  int index = 2;  for (int i = 0; i < BLOCK_H; i++) {    for (int j = 0; j < BLOCK_V; j++) {      block = spriteSet.getSprite(index++);/* 从SpriteSet 中取得Sprite */      block.setImage(blockImg); /* 设定画面为Sprite */      block.setLocation(i * BLOCK_WIDTH, (j + 1) * BLOCK_HEIGHT);/*       设定查看坐标*/      block.setVisible(true); /* 设定彩球被显示*/    }  }}

      3.1.3. 查看Sprite

      在画面上查看Sprite。利用上述NxGraphics类进行Sprite的查看。在BlockCanvas类的paint方法里记述着以下内容。

    //描画SpriteNxGraphics ng = NxGraphics.getNxGraphics(g);ng.drawSpriteSet(spriteSet);

      在上述情况下,以前必需的球、小棒、彩球的查看不需要在paint方法里讲述了。下面介绍paint方法。

    /*** 描画方法*/protected void paint(Graphics g) {  //清除画面  g.setColor(255, 255, 255);  g.fillRect(0, 0, getWidth(), getHeight());

      if (state == ACTIVE) { //游戏进行中    NxGraphics ng = NxGraphics.getNxGraphics(g);    ng.drawSpriteSet(spriteSet);

      } else if (state == CLEAR) { //清除    g.setColor(0, 0, 0);    g.drawString(    "GAME CLEAR!!!!",    getWidth() / 2,    getHeight() / 2,    Graphics.HCENTER | Graphics.BASELINE);  } else if (state == GAME_OVER) { //游戏结束    g.setColor(0, 0, 0);    g.drawString(    "GAME OVER....",    getWidth() / 2,    getHeight() / 2,    Graphics.HCENTER | Graphics.BASELINE);  }}

     

      3.1.4. 球、小棒的移动和碰撞判定

      接着进行球、小棒的移动和碰撞判定。到目前为止,球、小棒的移动是各自利用moveBall与moveBar方法的,在这里也使用原方法,并对其进行改良。

      在使球移动的moveBALL方法里,添加Sprite同类的碰撞判定处理和球坐标反映处理。

      首先从碰撞判定的处理开始讲述。与球壁的碰撞还沿用原来的方法,与小棒的碰撞判定采用以下处理方法。

    //进行反弹判定spriteSet.setCollisionAll();

    //碰上小棒后反弹if (spriteSet.getCollisionFlag(1) == 1) {  ballMoveY *= -1;  ballY = barY - BALL_HEIGHT-5;}

      因为spriteSet的索引是“1”,所以小棒利用getCollisionFlag(1)进行碰撞判定。若getCollisionFlag的返回值是“1”,那么球与小棒就发生了碰撞。相撞时,球被弹起来,球y轴方向的速度被逆转。另外,为了防止小棒和球相碰,要改变球的y坐标。

      与彩球的碰撞判定如下所示。

    //碰上彩球后反弹for (int i = 2; i < 30; i++) {  if (spriteSet.getCollisionFlag(i) % 2 == 1) {    spriteSet.getSprite(i).setLocation(-100, -100);    spriteSet.getSprite(i).setVisible(false);    blockCount--;    ballMoveY *= -1;

        //游戏清除检查    if (blockCount == 0) {      state = CLEAR;    }  }}

      彩球的Sprite判断是否与球发生了碰撞。若发生了碰撞,彩球被setVisible(false)设为不可视,且发生碰撞的彩球坐标向相反的区域移动。否则,Sprite将继续保持“与球碰撞”状态。通过移动Sprite,清除碰撞状态。因此,发生碰撞彩球的Sprite的坐标即使在画面内移动,若不可视也没有问题,但这里我们为了讲解明白,使之向相反区域的画面外移动。

      球坐标反映处理使用moveBALL方法。如下所示。

    /*** 使球运动*/public void moveBall() {  ballX += ballMoveX;  ballY += ballMoveY;

      //反弹  //碰壁后反弹  if (ballX < 0) {    ballMoveX *= -1;    ballX = 0;  } else if (getWidth() < ballX + BALL_HEIGHT) {    ballX = getWidth() - BALL_HEIGHT;    ballMoveX *= -1;  }  if (ballY < 0) {    ballMoveY *= -1;    ballY = 0;  } else if (ballY > getHeight()) { //若球落下    //游戏结束    state = GAME_OVER;  }

      //判定反弹  spriteSet.setCollisionAll();

      //碰上小棒后反弹  if (spriteSet.getCollisionFlag(1) == 1) {    ballMoveY *= -1;    ballY = barY - BALL_HEIGHT-5;//与小棒之间留出空间(否则就与小棒相撞了)  }

      //碰上彩球后反弹  for (int i = 2; i < 30; i++) {    if (spriteSet.getCollisionFlag(i) % 2 == 1) {      spriteSet.getSprite(i).setLocation(-100, -100);      spriteSet.getSprite(i).setVisible(false);      blockCount--;      ballMoveY *= -1;

          //游戏清除检查      if (blockCount == 0) {        state = CLEAR;      }    }  }

      //反映球移动  ball.setLocation(ballX, ballY);  ball.setVisible(true);}

      如上所述完成球的移动。

      使小棒移动的moveBar方法中,给Sprite添加坐标反映处理。下面添加增加处理的moveBar方法。

    /*** 移动小棒*/public void moveBar() {  barX += barMoveX;

      if (barX < 0) {    barX = 0;  } else if (barX + BAR_WIDTH > getWidth()) {    barX = getWidth() - BAR_WIDTH;  }

      //反映小棒移动  bar.setLocation(barX, barY);  bar.setVisible(true);}

      3.2. 小棒速度的变化

      按确定按键和方向按键,设定为增加小棒的速度。给keyPressed方法增加判断处理,来判断同时按下。

      增加后的方法如下所示。

    /*** 按下按键时*/protected void keyPressed(int key) {  if (state == ACTIVE) {    if (getGameAction(key) == Canvas.RIGHT) {    barMoveX = 6;  } else if (getGameAction(key) == Canvas.LEFT) {    barMoveX = -6;  }

      //按键的同时按下  int multiplKey = getPressedKeys();  if (multiplKey > 255) {    if (multiplKey == 64508) {      barMoveX = 12;    } else if (multiplKey == 65019) {      barMoveX = -12;    }  }

      repaint();  } else {    //再次起动    this.initiliseSpriteSet();    this.start();  }}

      小棒速度变化时,使其颜色也改变。这里使小棒的颜色从红变黄。颜色变换有准备了方法。

    /*** 进行小棒的颜色变换。*/public void changeBarColor() {  int[][] colormap = { { 255, 0, 0 },       {255, 254, 0 },};   bar.setImage(ImageEffector.changeColors(barImg, colormap, 2));  bar.setVisible(true);}

      上述方法在keyPressed方法里讲述。另外,释放按键之后,要想返回原来的图片,如下所述书写keyRelased方法。

    /*** 释放按键时*/protected void keyReleased(int key) {  barMoveX = 0;

      //返回小棒的图片  bar.setImage(barImg);  bar.setVisible(true);}

      3.3. 完成

    介绍就到这里结束了。

    下面是本次所制作应用程序的source code。

    block_sprite.zip

    下面是实际运行的结果。

    4. 总结

      本回解说的Sprite,对于Graphics来说是非常重要的思维方法,请一定复习并加以理解。


    最新回复(0)