讲解 http://java.e800.com.cn/articles/2007/126/1169755227655353977_1.html
J2ME开发手机游戏物理模型之抛物线
物体做抛物线运动是游戏中基本运动物理模型之一! 在PC游戏中可以由重力公式轻易模拟,但在手机游戏中
,由于多数手机不支持浮点运算因此不能用sin
,cos,来分解初速度。所以只能用近似模拟的方法!我所采用的是:先放大后缩小的模拟方式,并且为了更精确加入了一定的偏移量。
先用哈希表列出0-90度的正弦值,并且把值放大100000倍,例如:
Hashtable anglevalue;
public void loadAnglevalue()
{
anglevalue = new Hashtable();
anglevalue.put(String.valueOf(0),new Integer(0));
anglevalue.put(String.valueOf(30),newInteger(50000));
anglevalue.put(String.valueOf(60),new Integer(86603));
anglevalue.put(String.valueOf(90),new Integer(100000));
……
} |
这样就可以得出各种角度的正余弦值。
设初速度为V0 物体当前坐标为x=0,y=0; t为时间 g重力=10;
根剧力学公式
再根据重力公式:
由于cos& sin&都是放大了100000倍的所以 再得到手机屏幕坐标的时候应该缩小100000倍
x=Vx*t/100000;
y=(Vy*t –5*t*t)/100000; |
现在公式中除了t之外都解决了! 现在来解决时间t;
我们可以在游戏主循环的 中有不断增加t的值 但是因为主循环非常快!以毫秒计算,所以我们应该加入缓冲:
while (true){
thisThread.sleep(10);
if(bFire){
tTemp++;
if (tTemp >10) {
t+=1;
tTemp = 0;
}
} |
代
码中的if (tTemp >10) 这个值的判断就调整了时间的增长频率!你也可以用if (tTemp
>2)来使时间增长加快 或则用其他数值让时间变慢。注意的一点就是我们的时间也要放大!至于放大多少倍则要看游戏的节奏!我这里暂且放大
20000倍,因此公式为:
x=Vx*t/100000;
y=(Vy*t –5*t*t*20000)/100000; |
还有我们需要把 物体初始位置放在 屏幕的下放那就需要加个初始位置常量,公式变为:
x=Vx*t/100000;
y=(100000*(getHeight()-20))-(Vy*t –5*t*t*20000)/100000; |
getHeight()在手机中为得到手机屏幕的高度。好了,来看看用了这个公式后的运行效果(NOKIA 7650模拟器 或则uniJava模拟器)
图1
|
这是45度角情况下的抛物线轨迹。
是不是觉得高度不够呢!运算不够精确!那么我们在Y上加个偏移量来增加高度,公式改为:
x= (vx+windSpeed )*t /100000; ;
int pianyi=(t*400000);
if(vy==0){
pianyi=0;
}
y=(100000*(getHeight()-imgWu.getHeight())-(vy*t-100000*t*t+pianyi))/100000; |
这里的X轴还加了风速 windSpeed 现实中物体定受风速影响!当然这里的风速也是放大的了;
这个代码是在平抛的时候就不需要加入高度偏移了。现在再看45度角的 抛物线
图2
|
如果你还不满意还可以改动偏移数值来让模拟更精确。下面来看一些角度在不同力度和风速下的轨迹快照:
package paowuxian;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2005</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/
public class MIDlet1 extends MIDlet {
static MIDlet1 instance;
Displayable1 displayable = new Displayable1();
public MIDlet1() {
instance = this;
}
public void startApp() {
Display.getDisplay(this).setCurrent(displayable);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public static void quitApp() {
instance.destroyApp(true);
instance.notifyDestroyed();
instance = null;
}
}
package paowuxian;
import javax.microedition.lcdui.*;
import java.io.*;
import java.util.Hashtable;
/**
* <p>
* Title:
* </p>
* <p>
* Description:
* </p>
* <p>
* Copyright: Copyright (c) 2005
* </p>
* <p>
* Company:
* </p>
*
* @author not attributable
* @version 1.0
*/
public class Displayable1 extends Canvas implements Runnable {
private Image imgWu = null;
private int x, y;
private boolean bFire = false;
Thread thisThread;
private int angle = 45;
private int v0 = 8;
private boolean bShowline = true;
private int t;
private static Hashtable angleValue;
public Displayable1() {
// loadAngleValue();
try {
imgWu = Image.createImage("/images/paodan.png");
y = getHeight() - 8;
} catch (IOException ex) {
}
thisThread = new Thread(this);
thisThread.start();
}
private static int[] getPostion(int _v0, int t, int _angle) {
int vx = getCosAngleValue(_angle) * _v0;
int vy = getSinAngleValue(_angle) * _v0;
int dX = vx / 100000;
int dY = -(vy - 100000 * t) / 100000;
return new int[] { dX, dY };
}
private void gameRun() {
if (bFire) {
int[] pos = getPostion(v0, t, angle);
System.out.println(pos[0]+""+" "+pos[1]);
x += pos[0];
y+= pos[1];
}
repaint();
}
protected void paint(Graphics g) {
g.setColor(0xffffffff);
g.fillRect(50, 10, 80, 40);
if (bShowline) {
g.setColor(0xffffffff);
g.fillRect(0, 0, getWidth(), getHeight());
}
g.setColor(0x0000ff);
g.drawString("角度" + angle + "(按8/2键调整)", 50, 0, 0);
g.drawString("力度" + v0 + "(按1/4)", 50, 10, 0);
g.drawString("是否留下轨迹" + (bShowline ? " 否" : " 是") + "(按3)", 50, 20, 0);
// g.drawString("风力" + windSpeed / 100000 + "(按7/9)", 50, 30, 0);
g.drawString("按5发射",50,30,0);
g.drawImage(imgWu, x, y, 0);
}
public void run() {
while (true) {
try {
thisThread.sleep(10);
if (bFire) {
t += 1;
if (y > getHeight() || x > getWidth()) {
x = 0;
y = getHeight() - 8;
bFire = false;
t = 0;
}
}
} catch (InterruptedException ex) {
}
gameRun();
}
}
/**
* keyPressed
*
* @param keyCode
* int
* @todo Implement this javax.microedition.lcdui.Canvas method
*/
protected void keyPressed(int keyCode) {
if (keyCode == KEY_NUM5) {
bFire = true;
// vx = Resource.getCosAngleValue(angle) * v0;
// vy = Resource.getSinAngleValue(angle) * v0;
} else if (keyCode == KEY_NUM8) {
if (angle > 0) {
angle -= 3;
}
} else if (keyCode == KEY_NUM2) {
if (angle < 90) {
angle += 3;
}
} else if (keyCode == KEY_NUM1) {
v0++;
} else if (keyCode == KEY_NUM4) {
v0--;
} else if (keyCode == KEY_NUM3) {
bShowline = !bShowline;
}
// else if (keyCode == KEY_NUM7) {
// windSpeed += 100000;
// } else if (keyCode == KEY_NUM9) {
// windSpeed -= 100000;
// }
}
/**放大了10000倍的角度值*/
static {
angleValue = new Hashtable();
angleValue.put(String.valueOf(0), new Integer(0));
angleValue.put(String.valueOf(3), new Integer(5236));
angleValue.put(String.valueOf(6), new Integer(10453));
angleValue.put(String.valueOf(9), new Integer(15643));
angleValue.put(String.valueOf(12), new Integer(20791));
angleValue.put(String.valueOf(15), new Integer(25882));
angleValue.put(String.valueOf(18), new Integer(30902));
angleValue.put(String.valueOf(21), new Integer(35837));
angleValue.put(String.valueOf(24), new Integer(40674));
angleValue.put(String.valueOf(27), new Integer(45400));
angleValue.put(String.valueOf(30), new Integer(50000));
angleValue.put(String.valueOf(33), new Integer(54464));
angleValue.put(String.valueOf(36), new Integer(58779));
angleValue.put(String.valueOf(39), new Integer(62932));
angleValue.put(String.valueOf(42), new Integer(66913));
angleValue.put(String.valueOf(45), new Integer(70711));
angleValue.put(String.valueOf(48), new Integer(74314));
angleValue.put(String.valueOf(51), new Integer(77715));
angleValue.put(String.valueOf(54), new Integer(80902));
angleValue.put(String.valueOf(57), new Integer(83867));
angleValue.put(String.valueOf(60), new Integer(86603));
angleValue.put(String.valueOf(63), new Integer(89101));
angleValue.put(String.valueOf(66), new Integer(91355));
angleValue.put(String.valueOf(69), new Integer(93358));
angleValue.put(String.valueOf(72), new Integer(95106));
angleValue.put(String.valueOf(75), new Integer(96593));
angleValue.put(String.valueOf(78), new Integer(97815));
angleValue.put(String.valueOf(81), new Integer(98769));
angleValue.put(String.valueOf(84), new Integer(99452));
angleValue.put(String.valueOf(87), new Integer(99863));
angleValue.put(String.valueOf(90), new Integer(100000));
}
public static int getSinAngleValue(int angle) {
int tempAngle = (angle > 90 ? (180 - angle) : angle);
int tempValue = ((Integer) (angleValue.get(String.valueOf(tempAngle))))
.intValue();
return tempValue;
}
public static int getCosAngleValue(int angle) {
int tempAngle = (angle > 90 ? angle - 90 : 90 - angle);
int tempValue = ((Integer) (angleValue.get(String.valueOf(tempAngle))))
.intValue();
return (angle <= 90 ? tempValue : (-tempValue));
}
}
分享到:
相关推荐
在J2ME(Java 2 Micro ...总的来说,J2ME实现抛物线的关键在于理解物理模型,选择合适的计算方法,并结合Canvas的绘图功能将计算结果展示出来。开发者需要根据实际情况灵活运用,才能在有限的资源条件下实现最佳效果。
总的来说,虽然J2ME MIDP的限制使得模拟抛物线轨迹变得复杂,但通过巧妙的数值方法和编程技巧,我们仍然可以在移动设备上实现这种动态效果。这个过程不仅展示了编程的灵活性,也加深了对抛物线运动规律的理解。对于...
J2ME 实现的 UrlEncode编码 J2ME 实现的 UrlEncode编码 J2ME 实现的 UrlEncode编码
在这个J2ME实现的画图程序中,我们主要关注的是如何在移动设备上利用Java Micro Edition(J2ME)框架创建一个简单的画图应用。J2ME是Java平台的一个子集,专门用于嵌入式设备,如手机和PDA。在这个程序中,核心功能...
**J2ME实现手机QQ源代码详解** J2ME(Java 2 Micro Edition)是Java平台的一个子集,主要用于开发移动设备和嵌入式设备的应用程序。在这个项目中,我们探讨的是如何使用J2ME技术来实现手机上的QQ应用程序。手机QQ...
标题"j2me实现mvc的框架源码"指出,这是一个基于Java 2 Micro Edition (J2ME)平台实现Model-View-Controller (MVC)设计模式的框架源代码。MVC是一种广泛应用的软件设计模式,尤其在开发用户界面时,它将业务逻辑...
《J2ME实现超级玛丽源码解析》 在IT领域,游戏开发一直是吸引众多开发者的重要方向,而经典游戏“超级玛丽”更是许多程序员热衷于复刻的对象。本篇文章将详细解析利用Java Micro Edition(J2ME)实现的超级玛丽源...
"j2me实现视频播放"这一主题涉及到利用J2ME技术实现在这些设备上播放视频的功能。下面将详细讨论实现这个功能所需的关键知识点。 1. **J2ME基础知识**: - J2ME由KVM(Java虚拟机)和几个配置及 profiles 组成,如...
用J2ME实现简单电子邮件发送功能 用J2ME实现简单电子邮件发送功能
《J2ME实现坦克大战工程包详解》 Java 2 Micro Edition(J2ME)是Java平台的一个子集,主要用于嵌入式设备和移动设备,如手机、智能手表等。在移动游戏领域,J2ME因其跨平台特性和相对较低的资源需求而被广泛采用。...
在本文中,我们将深入探讨如何使用Java 2 Micro Edition (J2ME) 实现一个拼图游戏。这个项目由三个核心类组成,旨在为移动设备提供一个简单的拼图游戏体验。J2ME 是一种轻量级的Java平台,主要用于开发在嵌入式设备...
《J2ME实现俄罗斯方块:深入解析与技术实践》 俄罗斯方块,作为一款经典的游戏,自诞生以来就深受全球玩家的喜爱。它简单易懂,却又充满挑战性,是休闲娱乐与锻炼思维的绝佳选择。本文将探讨如何使用Java Micro ...
在Java ME(J2ME)平台上开发移动应用时,实现视频播放功能可能是一个挑战,因为它的资源和性能限制相比桌面或现代移动平台更为有限。不过,通过合理的编程和利用特定库,这一目标是可以达成的。以下是你需要知道的...
在本“J2ME实现范例”中,我们将深入探讨J2ME的基础知识及其在实际应用中的运用,帮助你在后续的开发工作中更加得心应手。 1. **J2ME架构**: J2ME包含配置(Configurations)和框架(Profiles),如MIDP(Mobile ...
当我们谈论“j2me实现3D效果”时,这意味着我们要在这些小型设备上创建具有三维视觉效果的游戏或应用。3D编程对于任何平台来说都是一项复杂的技术,但在资源受限的J2ME环境中,这更是一个挑战。 首先,要理解J2ME中...
总结起来,J2ME实现打电话功能涉及到对MIDP API的深入理解和使用,尤其是`Midlet`和`Connector`类。开发者需要具备J2ME编程基础,并了解目标设备的限制和要求。源代码文件将提供具体实现细节,帮助我们更好地理解和...
j2me实现的LRC歌词解析.可以解析标准LRC歌词,方便大家实现歌词同步播放
用J2ME实现的小程序,很实用!代码不算长!但是功能还算不错!
根据提供的文件信息,我们可以深入探讨A*算法在J2ME平台上的实现方法和技术要点。首先,需要明确的是,A*算法是一种广泛应用于路径查找和图遍历中的算法,它能够找到从起点到终点的最短路径。而在本例中,我们关注的...
《J2ME实现手机名片夹》 在移动通信领域,J2ME(Java 2 Platform, Micro Edition)是一种广泛应用于手机和其他小型设备的Java编程环境,它允许开发者创建能够在不同设备上运行的应用程序。本文将深入探讨如何利用...