服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

关于手机游戏中的炮弹轨迹―抛物线

关于手机游戏中的炮弹轨迹――抛物线
  在手机游戏的开发中常常会根据一条抛物线来模拟炮弹的轨迹。在已知炮弹的发射点,射程和射击高度的情况下,完全可由
抛物线方程来模拟出炮弹的运行轨迹,当然,这里的模拟只是理想状态下的,并没有把风力等因素考虑进去。
  根据炮弹的发射点(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;
import javax.microedition.lcdui.graphics;
import javax.microedition.lcdui.image;
import javax.microedition.lcdui.game.gamecanvas;
import javax.microedition.lcdui.game.sprite;
import javax.microedition.lcdui.game.tiledlayer;

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);
    }
   }
  }
 }
}
           

扫描关注微信公众号