`
touchmm
  • 浏览: 1039800 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

j2me学习十一_jsr256的应用

 
阅读更多

jsr256是感应器的api,现在手机中比较常见是中立感应Sensor,有了这个api之后,我们可以多了很多玩法,这次,我要用它来完成一个利用重力感应控制的小球。
开发环境:javaME Platform SDK3.0(Eclipse存在ClassDefNotFound错误,至今未解决。。。。)
四个java文件,
主midlet,画布,小球,辅助向量。下面是每个类得代码:

主midlet,主要用于控制游戏进度,接受传感器信息

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import javax.microedition.io.Connector;
import java.io.IOException;
import java.util.Vector;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.sensor.ChannelInfo;
import javax.microedition.sensor.Data;
import javax.microedition.sensor.DataListener;
import javax.microedition.sensor.SensorConnection;
import javax.microedition.sensor.SensorInfo;
import javax.microedition.sensor.SensorManager;
/**
* @author Administrator
*/
public class BallMidlet extends MIDlet implements DataListener{

private BallCanvas ballCanvas;
private SensorConnection sensor;
private String[] channelNames;
private boolean sensorSelected;
private SensorInfo[] sensorInfos;
public BallMidlet() throws IOException {

if (System.getProperty("microedition.sensor.version") == null) {
Display.getDisplay(this).setCurrent(
new Alert("JSR256 is not supported!"),
new TextBox("ERROR", "JSR256 is not supported!", 255, 0));
return;
// throw new IllegalArgumentException("JSR256 is not supported!");
}
ballCanvas = new BallCanvas();
sensorInfos = getSensorInfos();
System.out.println("sensorInfos.length: "+sensorInfos.length);
if (sensorInfos == null) {
Display.getDisplay(this).setCurrent(
new Alert("Valid accelerometer sensor not found"),
new TextBox("ERROR",
"Valid accelerometer sensor not found", 255, 0));
return;
}

new Thread() {
public void run() {

channelNames =
getSensorInfoChannelsNames(sensorInfos[0]);

try {
sensor =
(SensorConnection) Connector
.open(sensorInfos[0].getUrl());
ballCanvas.start();
sensor.setDataListener(BallMidlet.this, 1);
sensorSelected = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
private SensorInfo[] getSensorInfos() {
// Find all device accelerometers
SensorInfo[] sensorInfos = SensorManager.findSensors("acceleration", null);
Vector validInfos = new Vector();
for (int i = 0; i < sensorInfos.length; i++) {
if (getSensorInfoChannelsNames(sensorInfos[i]).length > 2) {
validInfos.addElement(sensorInfos[i]);
}
}
SensorInfo[] ret = null;
if (validInfos.size() > 0) {
ret = new SensorInfo[validInfos.size()];
validInfos.copyInto(ret);
}
return ret;
}
private String[] getSensorInfoChannelsNames(SensorInfo sensorInfo) {
Vector channelNames = new Vector();
ChannelInfo[] channelInfos = sensorInfo.getChannelInfos();
// Accelerometer must support at least 3 channels
if (channelInfos.length > 2) {
for (int i = 0; i < channelInfos.length; i++) {
// The channel type must be double
if (ChannelInfo.TYPE_DOUBLE == channelInfos[i].getDataType()
|| ChannelInfo.TYPE_INT == channelInfos[i]
.getDataType()) {
channelNames.addElement(channelInfos[i].getName());
}
}
// We found at least 3 double channels
if (channelNames.size() > 2) {
String[] names = new String[3];
names[0] = (String) channelNames.elementAt(0);
names[1] = (String) channelNames.elementAt(1);
names[2] = (String) channelNames.elementAt(2);
return names;
}
}
return new String[0];
}
public void dataReceived(SensorConnection sensor, Data[] data,
boolean isDataLost) {
double[] accel = new double[3];
for (int i = 0; i < data.length; i++) {
for (int c = 0; c < 3; c++) {
if (channelNames[c].equals(data[i].getChannelInfo().getName())) {
double val;
switch (data[i].getChannelInfo().getDataType()) {
case ChannelInfo.TYPE_DOUBLE:
val = data[i].getDoubleValues()[0];
break;
case ChannelInfo.TYPE_INT:
val = data[i].getIntValues()[0];
break;
default:
val = 0;
}
accel[c] =
unscaleValue(val, data[i].getChannelInfo()
.getScale());
break;
}
}

}
ballCanvas.accelerate(accel[0], accel[1], accel[2]);
}
private final double unscaleValue(double scaledValue, int scale) {
double mult = 1.0;
for (int i = 0; i < Math.abs(scale); i++) {
mult *= 10.0;
}
return (scale > 0) ? scaledValue * mult : scaledValue / mult;
}
public void startApp() {
ballCanvas.resetBoard();
Display.getDisplay(BallMidlet.this).setCurrent(ballCanvas);
//sensor.setDataListener(BallMidlet.this, 1);
System.out.println("Come here~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}

public void pauseApp() {
sensor.removeDataListener();
}

public void destroyApp(boolean unconditional) {
if (sensor != null) {
try {
sensor.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
notifyDestroyed();
}

}

小球类:

import java.io.IOException;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
public class Ball {

private Image img;
private Vector lastPos;
private Vector pos;
private Vector speed;
final static double ROLLING_FRICTION = 0.001;
private double bounceFriction;
private double radius;

public Ball() throws IOException {
this(0, 0);
}

public Ball(double x, double y) throws IOException {
img = Image.createImage("/black_marble.png");
pos = new Vector(x, y);
lastPos = new Vector(x, y);
speed = new Vector(0, 0);
radius = img.getWidth() / 2.0;
bounceFriction = 0.5;
}

public void resetPosition(double x, double y) {
speed = new Vector(0, 0);
pos.setX(x - getRadius());
pos.setY(y - getRadius());
}

public void paint(Graphics g) {
lastPos = new Vector(pos);
g.drawImage(img, (int) pos.getX(), (int) pos.getY(),
Graphics.HCENTER | Graphics.VCENTER);
}

public void clear(Graphics g) {
g.setColor(0xbbbbff);
g.fillRect((int) (lastPos.getX() - getRadius()), (int) (lastPos
.getY() - getRadius()), (int) (getRadius() * 2),
(int) (getRadius() * 2));
}

public void accelerate(double accelX, double accelY, double accelZ) {
double frictionF = (Math.max(0, accelZ) * ROLLING_FRICTION * 2);
speed.add(accelX, accelY);
if (frictionF > 0 && speed.getLen2() > 0) {
Vector friction = speed.inv().norm().mul(Math.sqrt(frictionF));
speed.add(friction);
}
}

public void calcNewPosition() {
pos.add(speed);
}

public double getRadius() {
return radius;
}

public void collideBorders(Canvas canvas) {
Vector newPos = Vector.add(pos, speed);
if (newPos.getY() - getRadius() < 0) {
speed.setY(speed.getY() * (bounceFriction - 1));
pos.setY(getRadius());
} else if (newPos.getY() + getRadius() > canvas.getHeight()) {
speed.setY(speed.getY() * (bounceFriction - 1));
pos.setY(canvas.getHeight() - getRadius());
}
if (newPos.getX() - getRadius() < 0) {
speed.setX(speed.getX() * (bounceFriction - 1));
pos.setX(getRadius());
} else if (newPos.getX() + getRadius() > canvas.getWidth()) {
speed.setX(speed.getX() * (bounceFriction - 1));
pos.setX(canvas.getWidth() - getRadius());
}
}

}

主Canvas,继承的是Canvas,实现Runnable接口

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

/**
*
* @author Administrator
*/
import java.io.IOException;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
public class BallCanvas extends Canvas implements Runnable {
private static final double PPCM = 80 * 100; // pixels per meter
public static final long TICK_SLEEP_MILLIS = 5;
/**
* Marble mass in kg. This demo is optimized for marbles with equal masses.
*/
final static double MARBLE_MASS = 0.000742179;

/**
* Multipliers convert m/s^2 to pixel/tick^2.
*/
private final double accelMultX;
private final double accelMultY;
private final double accelMultZ;

private Ball ball;
private volatile boolean stop;

private double accelX;
private double accelY;
private double accelZ;
volatile boolean firstPaint = true;
public BallCanvas() throws IOException {

// Tick cycles per s^2
setFullScreenMode(true);
double d = (1000 / TICK_SLEEP_MILLIS) * (1000 / TICK_SLEEP_MILLIS);
accelMultX = -1.0 * PPCM / d;
accelMultY = 1.0 * PPCM / d;
accelMultZ = -1.0 * PPCM / d;

ball = new Ball();
}
public synchronized void resetBoard() {
accelX = 0;
accelY = 0;
ball.resetPosition(getWidth() * 0.5, getHeight() * 0.5);
firstPaint = true;
}

public void start() {
stop = false;
resetBoard();
System.out.println("this.isDoubleBuffered()~~~~~~~~~~~~~~~~~~~~~~~~~~~~"+this.isDoubleBuffered());
new Thread(this).start();
}

public void stop() {
stop = true;
}

public void run() {
long st=0,et=0,diff=0;
int rate=50;//16-17 frame per second
while (!stop)
{
st=System.currentTimeMillis();
calculatePositions();
repaint();
et=System.currentTimeMillis();
diff=et-st;
if(diff<rate){
//System.out.println("Sleep "+(rate-diff));
try {
Thread.sleep(rate - diff);
}
catch (InterruptedException ex) {}

}
}


}
public void paint(Graphics g) {
if (firstPaint) {
g.setColor(0xbbbbff);
g.fillRect(0, 0, getWidth(), getHeight());
firstPaint = false;
}
ball.clear(g);
ball.paint(g);
}
private static final int SMOOTH_CNT = 2;
double avgX[] = new double[SMOOTH_CNT];
double avgY[] = new double[SMOOTH_CNT];
double avgZ[] = new double[SMOOTH_CNT];
public synchronized void accelerate(double x, double y, double z) {
double xx = x;
double yy = y;
double zz = z;
for (int i = 0; i < avgX.length - 1; i++) {
xx += avgX[i];
yy += avgY[i];
zz += avgZ[i];
avgX[i] = avgX[i + 1];
avgY[i] = avgY[i + 1];
avgZ[i] = avgZ[i + 1];
}
avgX[avgX.length - 1] = x;
avgY[avgY.length - 1] = y;
avgZ[avgZ.length - 1] = z;
xx /= avgX.length + 1;
yy /= avgY.length + 1;
zz /= avgZ.length + 1;

accelX = xx * accelMultX;
accelY = yy * accelMultY;
accelZ = zz * accelMultZ;
}
private synchronized void calculatePositions() {
ball.accelerate(accelX, accelY, accelZ);
System.out.println("calculatePositions~~~~~~~~~~~~~~~~");
ball.collideBorders(this);
ball.calcNewPosition();

}
}

向量类,类似辅助计算:

public class Vector {

private double x;
private double y;

public Vector(double x, double y) {
this.x = x;
this.y = y;
}

public Vector(Vector v) {
this(v.getX(), v.getY());
}

public static Vector add(Vector a, Vector b) {
return new Vector(a.getX() + b.getX(), a.getY() + b.getY());
}

public static Vector mul(Vector v, double d) {
return new Vector(v.getX() * d, v.getY() * d);
}

public static double dot(Vector a, Vector b) {
return a.getX() * b.getX() + a.getY() * b.getY();
}

public static Vector sub(Vector v1, Vector v2) {
return new Vector(v1.getX() - v2.getX(), v1.getY() - v2.getY());
}

public Vector inv() {
return new Vector(getX() * -1.0, getY() * -1.0);
}

public Vector norm() {
double l = Math.sqrt(getX() * getX() + getY() * getY());
return new Vector(getX() / l, getY() / l);
}

public double getY() {
return y;
}

public double getX() {
return x;
}

public Vector mul(double d) {
return new Vector(getX() * d, getY() * d);
}

public void add(Vector vector) {
add(vector.x, vector.y);
}

public void add(double d) {
add(d, d);
}

public void add(double x, double y) {
this.x += x;
this.y += y;
}

public void setX(double x) {
this.x = x;
}

public void setY(double y) {
this.y = y;
}

public double getLen2() {
return getX() * getX() + getY() * getY();
}

public double getLen() {
return Math.sqrt(getLen2());
}

public String toString() {
return "[" + getX() + ";" + getY() + "]";
}
}

分享到:
评论

相关推荐

    JSR-179_Location_API_for_J2ME.zip_j2me 1_j2me gps_j2me gps jsr17

    总结来说,JSR-179 Location API为J2ME应用程序提供了强大的地理位置服务支持,通过其丰富的接口和功能,开发者可以构建各种创新的定位应用,满足移动设备用户的多样化需求。在实际开发中,结合“jsr179_Final_...

    J2ME_M3G_API.rar_M3G API_j2me 3d_j2me m_jsr 184 api c_m3g a

    M3G API是J2ME平台上的一个标准,它允许开发者创建在移动设备上运行的3D图形应用程序。JSR 184(Java Specification Request 184)定义了这个API,旨在为小型设备提供高效且易于使用的3D图形接口。 **M3G API** 是...

    j2me_https.rar_ j2me-https_j2me_j2me htt_j2me htt_j2me https

    在移动开发领域,Java 2 Micro Edition(J2ME)是一种广泛用于创建小型设备和嵌入式系统的应用程序的平台。由于其轻量级和跨平台的特性,J2ME在功能手机时代尤其流行,用于开发各种应用,包括网络通信。在标题"j2me_...

    J2ME APICHM.zip_api j2me_j2me_j2me api c_j2me api chm_java api

    总结,J2ME API CHM技术手册是学习和开发J2ME应用的重要参考资料,涵盖了从基本概念到高级特性的全面内容。通过深入研究,开发者可以利用J2ME的强大功能为各种嵌入式设备创建高效且适应性强的应用程序。

    Java-j2me.rar_J2ME 教程_j2me 入门教程_java j2

    5. **网络编程**:J2ME允许在设备之间进行通信,学习如何使用JSR 82(Java Bluetooth API)或JSR 118(Java Wireless Toolkit for CLDC)进行无线连接。 6. **应用程序打包和部署**:了解如何将编写的代码打包成JAR...

    c++654_j2me_C++_

    在C++中,可以使用ODBC(Open Database Connectivity)或JDBC(Java Database Connectivity)进行数据库操作,而在J2ME中,可能需要使用特定的轻量级库如SQLite或者JSR-184(Mobile Information Device Profile - ...

    [J2ME程序设计_11111083][pdg]

    以上是J2ME程序设计的主要内容,通过学习这些知识点,开发者能够创建能在各种移动设备上运行的Java应用程序。J2ME程序设计_11111083这个教程可能包含了以上所有知识点的详细讲解,帮助读者从零基础到能够熟练开发...

    j2me收發短信.rar_bluetooth chat_j2me_j2me sms_sms_短信 j2me

    总结,J2ME短信收发和蓝牙聊天是移动开发中重要的功能模块,通过学习和实践这些技术,开发者可以构建丰富的移动应用程序,满足各种场景下的通信需求。这个压缩包提供的资源为学习和研究提供了宝贵的素材,值得深入...

    J2ME移动开发平台搭建步骤.rar_J2ME 蓝牙_j2me_java平台_开发平台

    J2ME移动开发平台是开发者创建、测试和部署面向这些设备的应用程序的环境。本篇将详细介绍如何搭建J2ME移动开发平台,以及如何利用它进行蓝牙功能的开发。 首先,你需要安装Java SDK,这是所有Java开发的基础。Java...

    J2ME-API.zip_ME_j2me api_j2me jdk_java me api

    - **JSR**: Java Specification Requests,定义了J2ME的扩展,如JSR-118(MIDP 2.0)和JSR-139(Connected Device Configuration, CDC with Foundation Profile)。 - **KVM**:Kilobyte Virtual Machine,J2ME的...

    j2me-gps.rar_JAVA GPS_gps j2me_gps 平台_j2me g_j2me gps

    Java ME(J2ME)是Java技术在移动设备和嵌入式设备上的应用平台,它为开发小型设备上的应用程序提供了标准化的环境。本压缩包"j2me-gps.rar"聚焦于在J2ME平台上实现GPS(全球定位系统)功能。下面我们将详细探讨J2ME...

    Using_J2ME_Bluetooth_API_For_Mobile_Games_en.pdf

    在探讨《使用J2ME蓝牙API开发移动游戏》这一主题时,我们首先需要理解几个核心概念:J2ME(Java 2 Micro Edition)、蓝牙技术、以及如何利用JSR-82标准来创建支持蓝牙功能的多玩家游戏。本文将深入剖析这些知识点,...

    Sonyericsson.Mobile.Java.3D.rar_j2me_j2me 3d_java 3d_mobile

    《J2ME 3D技术探索:从基础知识到实践应用》 J2ME(Java 2 Micro Edition)作为Java在移动设备上的应用平台,一直以来都是开发者进行移动应用程序开发的重要工具。随着技术的进步,J2ME也开始支持3D图形,使得在...

    j2me手册-webservice_mobile_wtk

    J2ME中的WMA(Wireless Messaging API,JSR-120)允许开发者创建能够接收和发送SMS、MMS消息的应用。理解和使用SMPP(Short Message Peer-to-Peer)协议是实现高效无线消息传递的关键。 七、Java Wireless Toolkit...

    JSR256 API

    通过学习和应用JSR256 API,开发者可以构建创新的移动应用,利用传感器数据实现各种功能,例如健康监测、室内导航、游戏控制等。结合J2ME的便携性,JSR256在物联网和智能设备领域有着广泛的应用前景。

    widget_analyzer_j2me_flutter_flutter代码实现相机_源码

    对于J2ME平台,虽然没有直接的Flutter支持,但你可以使用如Java ME的M3G或JSR-234(Advanced Media Framework)等技术来实现相机功能。不过,由于J2ME的局限性,这些方法通常比Flutter更复杂,且不具跨平台性。 总...

    开发j2me必备api 【jsr系列api】

    在开发J2ME应用时,通常会根据设备特性和需求选择合适的JSR API。例如,如果需要开发一个包含蓝牙功能的应用,JSR 82是必不可少的;如果要创建一个地理位置相关的应用,那么JSR 179将是关键。通过了解和熟练掌握这些...

    J2ME_API.rar_J2ME_API

    **J2ME_API.rar_J2ME_API 知识点详解** Java 2 Micro Edition(简称J2ME)是Java技术的一个重要分支,主要用于嵌入式设备和...通过深入学习和理解这些API,开发者可以创建出适应各种平台的高效、功能丰富的应用程序。

    j2ME+MMS.zip_J2ME MMS_JAVA MMS_MMS_j2me

    对于想要深入理解和开发J2ME MMS应用的开发者来说,这是一个宝贵的学习材料。通过阅读提供的文档,实践代码示例,并利用提供的在线资源,开发者可以掌握J2ME平台上的MMS技术,从而构建出具有多媒体消息功能的移动...

    j2me_3d_demo.rar_J2ME_Java_

    通过研究这个3D demo,开发者不仅可以了解J2ME平台的3D图形实现,还能学习到资源管理、性能优化等技能,对于想要在移动设备上开发3D游戏或其他应用的开发者来说,这是一个宝贵的学习资源。如果你计划探索这个领域,...

Global site tag (gtag.js) - Google Analytics