| 关于手机游戏中的炮弹轨迹――抛物线 |
在手机游戏的开发中常常会根据一条抛物线来模拟炮弹的轨迹。在已知炮弹的发射点,射程和射击高度的情况下,完全可由 抛物线方程来模拟出炮弹的运行轨迹,当然,这里的模拟只是理想状态下的,并没有把风力等因素考虑进去。 根据炮弹的发射点(x1,y1),射程(cs)和射击高度(h)可得出抛物线的三个点: p1:(x1,y1) p2:(x2,y2) x2=x1+cs/2, y2=y1+h p3:(x3,y3) x3=x1+cs, y3=y1 根据这三个点可列出抛物线方程 ax1^2+bx1+c=y1 ax2^2+bx2+c=y2 ax3^2+bx3+c=y3 计算方程得到该抛物线的系数a,b,c 得到a,b,c后,即可根据a,b,c计算出抛物线每点的轨迹。 下面的例子将说明如何绘制轨迹: 例子源码及图片下载 我的msn是zhagy_1981@hotmail.com,欢迎指出不足之处。 例子运行效果如下: 例子canvas中的代码 import java.io.ioexception; public class mycanvas extends gamecanvas implements runnable { //小船的位置 int x,y; //小船精灵 sprite ship; //地图 tiledlayer background; //图片 image ship_img, sea_img, bullet_img; //炮弹 bullets bullets; public mycanvas() { super(true); //初始化船的位置 x = 10; y = 60; try { ship_img = image.createimage("/ship.png"); sea_img = image.createimage("/sea.png"); bullet_img = image.createimage("/bullet.png"); } catch (ioexception e) { e.printstacktrace(); } //初始化炮弹 bullets = new bullets(bullet_img); //初始化小船 ship = new sprite(ship_img, 24, 30); ship.setposition(x, y); //初始化地图 background = new tiledlayer(20, 6, sea_img, 32, 32); background.createanimatedtile(1); int[][] map = new int[][] { { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }, { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 } }; //绘制地图 for(int i = 0 ; i < map.length ; i ++) { for(int j = 0 ; j < map[i].length ; j++) { background.setcell(j, i, map[i][j]); } } thread th = new thread(this); th.start(); } private int k = 0; public void run() { graphics g = getgraphics(); while(true) { //显示出水的流动 k++; if(k==10) { if(background.getanimatedtile(-1) == 1) { background.setanimatedtile(-1, 2); } else if(background.getanimatedtile(-1) == 2) { background.setanimatedtile(-1, 1); } k = 0; } //主控制 support(g); //绘制 draw(g); try { thread.sleep(35); } catch (interruptedexception e) { e.printstacktrace(); } } } public void support(graphics g) { //控制船的移动及发射 int keycode = getkeystates(); switch(keycode) { case up_pressed: y = math.max(0, y - 2); if(ship.getframe() >= 2) ship.setframe(0); else ship.nextframe(); break; case down_pressed: y = math.min(getheight(), y + 2); if(ship.getframe() <= 2 || ship.getframe() >= 5) ship.setframe(3); else ship.nextframe(); break; case left_pressed: x = math.max(0, x - 2); if(ship.getframe() <= 5 || ship.getframe() >= 8) ship.setframe(6); else ship.nextframe(); break; case right_pressed: x = math.min(getwidth(), x + 2); if(ship.getframe() <= 8 || ship.getframe() >= 11) ship.setframe(9); else ship.nextframe(); break; case fire_pressed: if(!bullets.isfire) { bullets.isfire = true; bullets.setpoint(x+13,y); } break; } ship.setposition(this.x, this.y); } /** * 绘制 * @param g */ public void draw(graphics g) { g.setcolor(0xffffff); g.fillrect(0,0,this.getwidth(),this.getheight()); g.setcolor(0x000000); background.paint(g); bullets.drawbullets(g); ship.paint(g); flushgraphics(); } } /** * 炮弹 * <p>title: bullets</p> * <p>description: </p> * <p>copyright: copyright (c) 2005</p> * <p>date: 2006-3-2</p> * @author zgy * @version 1.0 */ class bullets extends sprite { boolean isfire = false; //炮弹的发射点 int bulletx, bullety; //炮弹的射程 int shotwidth = 50; //炮弹的射程高度 int shotheight = shotwidth/2-10; //炮弹的速度 int shotspeed = 3; //炮弹抛物线的系数 double a,b,c; public bullets(image image) { super(image, 15, 15); } /** * 初始化炮弹 * @param x * @param y */ public void setpoint(int x, int y) { //初始化炮弹的发射点 this.bulletx = x; this.bullety = y; //根据炮弹的发射点、高度、射程计算出炮弹抛物线的三点 int x1 = bulletx; int y1 = bullety; int x2 = bulletx+shotwidth/2; int y2 = bullety-shotheight; int x3 = bulletx+shotwidth; int y3 = bullety; //根据抛物线方程ax^2+bx+c=y,得方程组 //ax1^2+bx1+c=y1 //ax2^2+bx2+c=y2 //ax3^2+bx3+c=y3 //解方程组得抛物线的a,b,c b = ((y1-y3)*(x1*x1-x2*x2)-(y1-y2)*(x1*x1-x3*x3))/((x1-x3)*(x1*x1-x2*x2)-(x1-x2)*(x1*x1-x3*x3)); a = ((y1-y2)-b*(x1-x2))/(x1*x1-x2*x2); c = y1-a*x1*x1-b*x1; } /** * 绘出炮弹 * @param g */ public void drawbullets(graphics g) { if(isfire) { int k = (int)(a*bulletx*bulletx+b*bulletx+c); setposition(bulletx, k); paint(g); //炮弹的速度 bulletx += shotspeed; //炮弹将消失于小船的水平线 if(k > bullety) { nextframe(); if(getframe() == 2) { isfire = false; setframe(0); } } } } } |
闽公网安备 35060202000074号