nec手机java中级知识专题讲座_第1页
nec手机java中级知识专题讲座_第2页
nec手机java中级知识专题讲座_第3页
nec手机java中级知识专题讲座_第4页
nec手机java中级知识专题讲座_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第八讲 NEC扩展API1. 引言在上讲中,我们对网络的相关功能进行了解说。截止上讲以前的讲座,我们讲述的都是关于MIDP的JAVA相关技术的内容,本讲将收尾,介绍NEC扩展API。2. NEC扩展NEC扩展API中有如下的类。类AudioClip 处理声音数据类。已在第五讲解说。AudioListenerAudio事务监听器。已在第五讲解说。ImageEffector 颜色变换类。将在本讲解说。ImageMap模拟PCG()类。因为能轻松的把多种画面分配在格子里,所以能很容易的制作出背景和棋面(ImageMap)。不在本讲解说。Media 取得媒体数据类。已在第五讲解说。NxCanvasNEC扩展canvas,支持多重按键。将在本讲解说。NxGraphicsNEC扩展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() /读取画面tryimg = Image.createImage(/back.PNG);catch(Exception e)e.printStackTrace();/ 设定Timer,TimerTasktimer = 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. SpriteSprite是指具有描画位置与大小的对象。Sprite的特征有以下三点。把SpriteImage分配、移动到任意位置设定SpriteImage中的优先顺序进行SpriteImage同类的碰撞判定比如,在Canvas类中,根据描画顺序对画面进行描画,其中重复的部分,需要对描画的处理顺序进行正确的编程,很繁琐。在这种情况下,如果利用Sprite优先顺序,就不用担心描画顺序,很方便。而且,Sprite的碰撞判定,对于经常发生碰撞判定处理的shooting game等应用程序,非常有效。为了利用Sprite,在NEC扩展API中准备了以下两类。 Sprite SpriteMapSprite类中有以下方法。方法作用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中有以下方法。intgetCollisionFlag(int index) 取得由自变量index指定的Sprite碰撞判定flag。intgetCount() 返回保持的Sprite数。SpritegetSprite(int index)返回由自变量index指定的索引Sprite。SpritegetSprites() 返回Sprite排列。booleanisCollision(int index1, int index2)取得由自变量index1和index2指定的Sprite碰撞判定结果。voidsetCollisionAll() 进行全体Sprite的相互碰撞判定。voidsetCollisionOf(int index)进行由自变量index指定的Sprite碰撞判定。voidsetPriority(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 Canvasprivate 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扩展GraphicsNxGraphics 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) % 的n次方的值= 的(n-1)次方的值下面是判断与第三项Sprite发生碰撞的例子。If( spriteSet.getCollisionFlag(2) % 8 = 4)System.out.println(“碰撞!”);elseSystem.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色调的色替换设定colormap00 = 变换对象RGB色1的R値; colormap01 = 变换对象RGB色1的G值; colormap02 = 变换对象RGB色1的B值; colormap10 = 变换结果RGB色1的R值; colormap11 = 变换结果RGB色1的G值; colormap12 = 变换结果RGB色1的B值; 2色调的色替换设定colormap20 = 变换对象RGB色2的R値; colormap21 = 变换对象RGB色2的G值; colormap22 = 变换对象RGB色2的B值; colormap30 = 变换结果RGB色2的R值; colormap31 = 变换结果RGB色2的G值; colormap32 = 变换结果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 Canvasprivate 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扩展GraphicsNxGraphics 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)同时被按时 |-未使用 经常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 NxCanvasprivate 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扩展GraphicsNxGraphics ng = NxGraphics.getNxGraphics(g);/描画Spriteng.drawSpriteSet(spriteSet);/* * 按键处理 */protected void keyPressed(int keycode) if(getPressedKeys() 255)/如果同时按两个按键changeColor();repaint();运行结果如下所示。 3. 制作应用程序下面介绍如何利用上面解说的扩展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 小棒229 彩球按照上述变量的定义,则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 getHeight() /若球落下/游戏结束state = GAME_OVER;/判定反弹spriteSet.setCollisionAll();/碰上小棒后反弹if (spriteSet.g

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论