zoukankan      html  css  js  c++  java
  • 碰撞检测示例:CollisionDetection



     
    import javax.microedition.lcdui.*;
     
    import javax.microedition.midlet.*;
     
    import java.io.*;
     
    import java.io.IOException;
     
    import java.util.Random;

     
    public class CollisionDetection
     
    extends MIDlet 
         
    implements CommandListener, Runnable {
             
         
    private boolean running;//主循环的判断
         private boolean FirstComet = true;//首次碰撞检测

         
    private int AimingX;//检测线的x轴初始位置
         private int AimingY;//检测线的y轴初始位置
         private int AimingDirX;//检测线的x轴初始方向
         private int AimingDirY;//检测线的y轴初始方向
         
         
    private int Kills = 0;//杀死的次数
         
         
    private int CometX;//彗星的x轴初始位置
         private int CometY;//彗星的y轴初始位置
         private int CometXvec;//彗星的x轴初始方向
         private int CometYvec;//彗星的y轴初始方向
         
         
    private int Count = 30;//
         private long frameTime = 0;//
         private long lastFrameTime = 0;//
             
         
    private static final int SENSITIVITY = 10;//灵敏度
        
         
    private int Side = 0;//
         private long LastSide = 0;//
         
         
    private static final int PLAYER_RADIUS    = 16;//恒星的半径
         private static final int ENEMY_RADIUS    = 8;//彗星的半径
         
         
    private int COLLISION_LENGTH = PLAYER_RADIUS+ENEMY_RADIUS;//碰撞的长度=恒星的半径+彗星的半径
         
         
    private int COLLISION_LIMIT = COLLISION_LENGTH*COLLISION_LENGTH;//碰撞的区间为碰撞长度的平方
         
         
    private MyCanvas myCanvas;//内部画布类
         private Display display;//显示屏幕
         private Graphics myGraphics;//图形参数
         private Random random = new Random();//随机数
         private Command quit;//退出命令
         
         
    class MyCanvas extends Canvas//内部为画布类
         {
             
    protected void paint(Graphics graphics)
             
    {        
                 
    int PlayerVectorX;//检测线的X轴向量
                 int PlayerVectorY;//检测线的Y轴向量
                     
                 
    int EnemyVectorX;//彗星的X轴向量
                 int EnemyVectorY;//彗星的Y轴向量
                 
                 
    //中心位置
                 int CenterX = getWidth()/2;//X轴的中心位置为屏幕宽度的一半
                 int CenterY = getHeight()/2;//Y轴的中心位置为屏幕高度的一半
                 
                 
    int LoopCount = 4;//
                 
                 myGraphics 
    = graphics;//传递图形参数
                 
                 
    if (FirstComet)//第一次的彗星
                 {
                     NewComet();
    //设置新彗星的位置参数
                     FirstComet=false;//
                 }


                 frameTime 
    = System.currentTimeMillis();//当前帧的时间
                 long Duration = frameTime-lastFrameTime;//持续时间为当前帧的时间减去上一帧的时间
     
                 
    while ((Duration > 5&& (LoopCount >0))//
                 {
                     LoopCount
    --;//计算器自减1次
                     myGraphics.setColor(0,0,0);//
                     myGraphics.drawLine (CenterX,CenterY,AimingX,AimingY);//绘制正向检测线
                     PlayerVectorX = (AimingX-CenterX);//检测线的X轴向量=检测线X端点到X轴中心点的矢量
                     PlayerVectorY = (AimingY-CenterY);//检测线的Y轴向量=检测线X端点到Y轴中心点的矢量
                     myGraphics.drawLine (CenterX-PlayerVectorX,CenterY-PlayerVectorY,CenterX,CenterY);//绘制反向检测线
                                     
                     AimingX
    +=AimingDirX;//检测线沿着X轴方向走
                     AimingY+=AimingDirY;//检测线沿着Y轴方向走
                     
                     
    /**   
                     
                     左角   上边   右角
                        (上角) +----+ (上角)
                                    +    +
                         左边  +    +  右边
                                    +    +
                        (下角) +----+ (下角)    
                         左角   下边   右角
                                              
                     
    */

                     
                     
                     
    if ((AimingX>=getWidth()) && (AimingY==0))//检测线超出右边上角
                     {
                         AimingX 
    = getWidth()-1;
                         AimingDirX
    =0;
                         AimingDirY
    =1;
                     }
    ;
                     
                     
    if ((AimingX<0&& (AimingY==0))//检测线超出左边上角
                     {
                         AimingX 
    = 0;
                         AimingDirX
    =0;
                         AimingDirY
    =1;
                     }
    ;
                     
                     
    if ((AimingX>=getWidth()) && (AimingY==(getHeight()-1)))//检测线超出右边下角
                     {
                         AimingX 
    = getWidth()-1;
                         AimingDirX
    =0;
                         AimingDirY
    =-1;
                     }
    ;
                     
                     
    if ((AimingX<0&& (AimingY==(getHeight()-1)))//检测线超出左边下角
                     {
                         AimingX 
    = 0;
                         AimingDirX
    =0;
                         AimingDirY
    =-1;
                     }
    ;
                         
                     
    if ((AimingY>=getHeight()) && (AimingX==0))//检测线超出下边左角
                     {
                         AimingY 
    = getHeight()-1;
                         AimingDirX
    =1;
                         AimingDirY
    =0;
                     }
    ;
                     
                     
    if ((AimingY<0&& (AimingX==0))//检测线超出上边左角
                     {
                         AimingY 
    = 0;
                         AimingDirX
    =1;
                         AimingDirY
    =0;
                     }
    ;
                     
                     
    if ((AimingY>=getHeight()) && (AimingX==(getWidth()-1)))//检测线超出下边右角
                     {
                         AimingY 
    = getHeight()-1;
                         AimingDirX
    =-1;
                         AimingDirY
    =0;
                     }
    ;
                     
                     
    if ((AimingY<0&& (AimingX==(getWidth()-1)))//检测线超出上边右角
                     {
                         AimingY 
    = 0;
                         AimingDirX
    =-1;
                         AimingDirY
    =0;
                     }
    ;
                             
                     Duration
    -=5;//持续时间自减5毫秒
                     
                     
                     
                     
    //<核心检测算法部分>{
                     PlayerVectorX = (AimingX-CenterX);//检测线的X轴向量=检测线X端点到X轴中心点的矢量
                     PlayerVectorY = (AimingY-CenterY);//检测线的Y轴向量=检测线Y端点到Y轴中心点的矢量
                                     
                     EnemyVectorX 
    = (CenterX-CometX);//彗星的X轴向量=X轴中心点到彗星X端点的矢量
                     EnemyVectorY = (CenterY-CometY);//彗星的Y轴向量=Y轴中心点到彗星Y端点的矢量    
                     
                     Side 
    = EnemyVectorX * PlayerVectorY - PlayerVectorX*EnemyVectorY;//边界值=彗星的X轴向量*检测线的Y轴向量-检测线的X轴向量*彗星的Y轴向量    
                         
                     
    if (((Side >=0&& (Side < SENSITIVITY)) || ((Side<=0&& (Side > SENSITIVITY)))//
                     {
                         
    //碰撞检测的边界值在0与灵敏度区间的时候
                         Kills++;
                         NewComet();                    
                     }

                                 
                     
    if (Side<=0)
                     
    {
                         
    if (LastSide > 0)
                         
    {
                             
    //当前边界值为负,而上一个边界值为正时
                             Kills++;
                             NewComet();                    
                         }

                     }
     else {
                         
    if (LastSide < 0)
                         
    {
                             
    //当前边界值为正,而上一个边界值为负时
                             Kills++;
                             NewComet();                    
                         }
                    
                     }

     
                     LastSide 
    = Side;        

                     Count
    --;
                     
                     
    if (Count == 0)
                     
    {    
                         Count 
    = 30;
         
                         CometX
    +=CometXvec;
                         CometY
    +=CometYvec;        
                                             
                         
    int Length = EnemyVectorX*EnemyVectorX + EnemyVectorY*EnemyVectorY;//
                         if (Length <= COLLISION_LIMIT)//当长度在碰撞区间内时
                         {
                             
    //恒星、彗星大碰撞,退出程序
                             destroyApp(true);
                             notifyDestroyed();
                         }
                            
                         
    //绘制彗星    
                         for (int i = 0;i<8;i++)
                         
    {
                             myGraphics.setColor(
    31*i,30*i,24*i);
                             myGraphics.fillArc(CometX
    -CometXvec*(7-i)-8,CometY-CometYvec*(7-i)-8,16,16,0,360);
                         }
        
                     }
                    
                     
    //}<核心检测算法部分>
                     
                     
                     
    //绘制检测线
                     myGraphics.setColor(128,192,255);
                     myGraphics.drawLine (CenterX,CenterY,AimingX,AimingY);
    //绘制正向检测线
                     myGraphics.drawLine (CenterX-PlayerVectorX,CenterY-PlayerVectorY,CenterX,CenterY);//绘制反向检测线
                     lastFrameTime=frameTime;
                         
                 }

                 
    //绘制恒星 
                 myGraphics.setColor(128,160,255);//设置恒星的颜色
                 myGraphics.fillArc(CenterX-16,CenterY-16,32,32,0,360);//在离中心位置偏移x,y长度各为16象素的地方画直径为32的实心圆
                 
                 myGraphics.drawString(
    " "+Kills,0,0,Graphics.LEFT | Graphics.TOP);//碰撞次数显示
             }
        
     
         
    protected void keyPressed(int keyCode)//监听手机按键事件
         {
      
             
    int Key;
             
    try {
                 Key 
    = getGameAction(keyCode);//取键值
             }
     catch (Exception e)
             
    {
                 Key 
    = 0;
             }

     
             
    if (Key ==FIRE)//按fire或者ok键  
             {
                 AimingDirX
    =-AimingDirX;//取x反方向
                 AimingDirY=-AimingDirY;//取y反方向
             }

         }

     }

            

     
    public CollisionDetection() //构造函数
     {
           myCanvas 
    = new MyCanvas();//创建画布对象
           quit = new Command("Quit",Command.EXIT,2);//创建退出命令
           myCanvas.addCommand(quit);//为画布添加退出命令
           myCanvas.setCommandListener(this);//为画布设置命令监听器
         running = true;//主循环判断赋初值
          AimingY = 0;//检测线的y轴初始位置
         AimingX = myCanvas.getWidth() / 2;//检测线的x轴初始位置
         AimingDirX = 1;//检测线的x轴初始方向
         AimingDirY = 0;//检测线的y轴初始方向
             
         lastFrameTime 
    = System.currentTimeMillis();//开始记录为上一帧的时间
         Thread t = new Thread(this);//创建一个新线程
         t.start();//启动线程
     }

          
     
    private void NewComet()//新的彗星产生
     {
         
    //清屏
         myGraphics.setColor(0,0,0);
         myGraphics.fillRect(
    0,0,myCanvas.getWidth(),myCanvas.getHeight());
         
         
    if (rnd(2==0)//随机为偶数
         
             
    //along top or bot
             CometX=rnd(myCanvas.getWidth());
             CometXvec
    =rnd(4);
             
    if (rnd(2)==0)//随机数为偶数
             {
                 
    //along top
                 CometY = 0;
                 CometYvec 
    = 5-CometXvec;
             }
     
             
    else {
                 CometY 
    = myCanvas.getHeight()-1;
                 CometYvec 
    = -(5-CometXvec);
             }

             
    if (CometX> myCanvas.getWidth()/2
                     CometXvec
    =-CometXvec;
         }
     else 
             
    //along left or right
             CometY=rnd( myCanvas.getHeight());
             CometYvec
    =rnd(4);
             
    if (rnd(2)==0)//随机数为偶数
             {
                 
    //along left
                 CometX = 0;
                 CometXvec 
    = 5-CometYvec;
             }
     else {
                 CometX 
    =  myCanvas.getWidth()-1;
                 CometXvec 
    = -(5-CometYvec);
             }

             
    if (CometY> myCanvas.getHeight()/2
                     CometYvec
    =-CometYvec;
         }

     }

          
     
    public void startApp()//启动程序 
     {
         Display.getDisplay(
    this).setCurrent(myCanvas);//当前屏幕显示为画布
         myCanvas.repaint();//画布重绘
     }

          
     
    public void pauseApp() //暂停程序
     {
         myCanvas.repaint();
    //画布重绘
     }

          
     
    public void destroyApp(boolean unconditional) //销毁程序
     {  
           
     }
         
         
     
    public void commandAction(Command c, Displayable s) //命令处理
     {    
             
    if (c==quit)//退出命令
             {
                 destroyApp(
    true);//销毁程序
                 notifyDestroyed();//通知程序服务管理销毁
             }
                    
     }

                   
     
    public void run()//主循环
     {
         
    while (running)
         
    {
             myCanvas.repaint();
    //画布重绘
             myCanvas.serviceRepaints();//使用强制刷屏
         }

     }

          
     
    private int rnd(int bound)
     
    {
         
    return Math.abs(random.nextInt() % bound);//取bound范围内的一个随机正数(绝对值)
     }

    }

  • 相关阅读:
    符号化Symbol(符号)体系
    shp2pgsql
    ArcGIS Flex(9.3)+GP服务完成最短路径分析(1)转载
    安装postgis,使用postgis导入shapefile的步骤总结 转载
    iis .NET的安装顺序反了该怎么办?
    WindowsXP 安装 PostgreSQL 8.4.2 数据库
    Web前端数据缓存处理
    SpringBoot 无Session开发
    Web端子页面iframe出现登录页面处理。
    Mybatis Generator自定义扩展
  • 原文地址:https://www.cnblogs.com/bluespot/p/876795.html
Copyright © 2011-2022 走看看