posts - 495,comments - 227,trackbacks - 0
public   class   Core   extends   Canvas  
  implements   Runnable   ,   RecordFilter   {  
   
   
  //////////////////////////////////////////////////////////////////  
  //Game   core  
  //////////////////////////////////////////////////////////////////  
   
   
  //#ifndef   Core.GameCanvas  
   
  //define   constant   to   handle   game   key   states  
  public   static   final   int   UP_PRESSED   =   1   <<   UP;  
  public   static   final   int   DOWN_PRESSED   =   1   <<   DOWN;  
  public   static   final   int   LEFT_PRESSED   =   1   <<   LEFT;  
  public   static   final   int   RIGHT_PRESSED   =   1   <<   RIGHT;  
  public   static   final   int   FIRE_PRESSED   =   1   <<   FIRE;  
  public   static   final   int   GAME_A_PRESSED   =   1   <<   GAME_A;  
  public   static   final   int   GAME_B_PRESSED   =   1   <<   GAME_B;  
  public   static   final   int   GAME_C_PRESSED   =   1   <<   GAME_C;  
  public   static   final   int   GAME_D_PRESSED   =   1   <<   GAME_D;  
  //double   buffer  
  private   Image   __bufferedImage;  
  //clip  
  private   boolean   __setClip;  
  private   int   __clipX,   __clipY,   __clipWidth,   __clipHeight;  
   
  public   void   paint(Graphics   g)  
  {  
  if   (this.__setClip)   {  
  g.clipRect(   this.__clipX,   this.__clipY,   this.__clipWidth,   this.__clipHeight);  
  this.__setClip   =   false;  
  }  
  g.drawImage(this.__bufferedImage,   0,   0,   Graphics.TOP   |   Graphics.LEFT   );  
  }  
   
  public   void   flushGraphics()  
  {  
  repaint();  
  serviceRepaints();  
  }  
   
  public   void   flushGraphics(int   x,   int   y,   int   width,   int   height)  
  {  
  this.__setClip   =   true;  
  this.__clipX   =   x;  
  this.__clipY   =   y;  
  this.__clipWidth   =   width;  
  this.__clipHeight   =   height;  
  repaint();  
  serviceRepaints();  
  }  
   
  //#endif  
   
   
  //define   constant   to   handle   soft   key   states  
  public   static   final   int   SOFT_FIRST_PRESSED   =   GAME_A_PRESSED;  
  public   static   final   int   SOFT_LAST_PRESSED   =   GAME_B_PRESSED;  
  //MIDlet   object  
          private   MIDlet   __midlet;  
  //key   states   and   soft   key   states  
  private   int   __keyStates,   __currentKeyStates,   __lastKeyStates,   __softKeyStates,   __currentSoftKeyStates,   __lastSoftKeyStates;  
          //used   for   sleep  
          private   long   __lastSystemTime,   __elapsedTime;  
   
  //canvas   Graphics   object  
  private   Graphics   g;  
  //view   window  
  private   int   viewX,   viewY,   viewWidth,   viewHeight;  
          //running   and   pause   flags  
          public   boolean   running   =   true;  
          public   boolean   pause;  
          //clock  
  private   boolean   clockRunning   =   true;  
          public   long   virtualTime;  
          //frame   delay  
          private   long   frameDelay   =   120;  
  //auto   flushGraphics  
   
  public   Core(MIDlet   m)   {  
  //#ifndef   Core.GameCanvas  
  super();  
  //#else  
  //#   super(false);  
  //#   setFullScreenMode(true);  
  //#endif  
   
   
  //#ifdef   Core.GameCanvas  
  this.viewWidth   =   getWidth();  
  this.viewHeight   =   getHeight();  
  //#else  
  //#if   polish.FullCanvasSize:defined  
  //#=   this.viewWidth   =   ${polish.FullCanvasWidth};  
  //#=   this.viewHeight   =   ${polish.FullCanvasHeight};  
  //#else  
  //#     this.viewWidth   =   getWidth();  
  //#     this.viewHeight   =   getHeight();  
  //#endif  
  //#endif  
   
   
  //#ifndef   Core.GameCanvas  
  this.__bufferedImage   =   Image.createImage(this.viewWidth,   this.viewHeight   );  
  this.g   =   this.__bufferedImage.getGraphics();  
  //#else  
  //#   this.g   =   getGraphics();  
  //#endif  
   
   
  //midlet  
          this.__midlet   =   m;  
  }  
   
  protected   void   keyPressed(int   keyCode)   {  
   
  //#ifndef   Core.GameCanvas  
  this.__keyStates   |=   1   <<   getGameAction(keyCode);  
  //#endif  
   
   
   
  switch   (keyCode)   {  
  //#ifdef   polish.key.LeftSoftKey  
  //#   case   ${polish.key.LeftSoftKey}:  
  //#else  
  case   -6:  
  //#endif  
  this.__softKeyStates   |=   SOFT_FIRST_PRESSED;  
  break;  
  //#ifdef   polish.key.RightSoftKey  
  //#   case   ${polish.key.RightSoftKey}:  
  //#else  
  case   -7:  
  //#endif  
  this.__softKeyStates   |=   SOFT_LAST_PRESSED;  
  break;  
  }  
   
  }  
   
  protected   void   keyReleased(int   keyCode)   {  
   
  //#ifndef   Core.GameCanvas  
  this.__keyStates   &=   ~(1   <<   getGameAction(keyCode));  
  //#endif  
   
   
   
  switch   (keyCode)   {  
  //#ifdef   polish.key.LeftSoftKey  
  //#   case   ${polish.key.LeftSoftKey}:  
  //#else  
  case   -6:  
  //#endif  
  this.__softKeyStates   &=   ~SOFT_FIRST_PRESSED;  
  break;  
  //#ifdef   polish.key.RightSoftKey  
  //#   case   ${polish.key.RightSoftKey}:  
  //#else  
  case   -7:  
  //#endif  
  this.__softKeyStates   &=   ~SOFT_LAST_PRESSED;  
  break;  
  }  
   
  }  
   
  /**  
    *   detect   user   input  
    *    
    *   @param   keyPressedConstant  
    *                         XXX_PRESSED   constant   like   FIRE_PRESSED  
    *   @param   detectsStroke  
    *                         set   true   to   detect   stroke   action,false   to   detect   key   pressed  
    *                         state  
    *   @param   soft  
    *                         set   true   to   detect   soft   key,false   to   detect   game   key.  
    *   @param   update  
    *                         set   true   to   update   key(soft   key)   state  
    *   @return  
    */  
  private   final   boolean   detectInput(int   keyPressedConstant,   boolean   detectsStroke,boolean   soft,boolean   update){  
          if(soft){        
          if(update){  
          this.__lastSoftKeyStates   =   this.__currentSoftKeyStates;  
          this.__currentSoftKeyStates   =   this.__softKeyStates;  
          }  
           
          if(detectsStroke){  
                          return   ((this.__lastSoftKeyStates   &   keyPressedConstant)   !=   0)   &&   ((this.__softKeyStates   &   keyPressedConstant)   ==   0);    
                  }else{  
                  return   ((this.__softKeyStates   &   keyPressedConstant)   !=   0);  
                  }  
          }else{          
          if(update){  
          //#ifdef   Core.GameCanvas  
  //#   this.__keyStates   =   getKeyStates();  
          //#endif  
          this.__lastKeyStates   =   this.__currentKeyStates;  
          this.__currentKeyStates   =   this.__keyStates;  
          }  
           
          if(detectsStroke){  
                          return   ((this.__lastKeyStates   &   keyPressedConstant)   !=   0)   &&   ((this.__keyStates   &   keyPressedConstant)   ==   0);    
                  }else{  
                  return   ((this.__keyStates   &   keyPressedConstant)   !=   0);  
                  }  
          }  
  }  
   
  //implements   interface   Runnable  
  public   void   run(){  
  try{  
  initialize();  
   
  while   (running)   {  
  this.__lastSystemTime   =   System.currentTimeMillis();  
   
  if(!pause){  
  //#ifndef   Core.GameCanvas  
  this.g   =   this.__bufferedImage.getGraphics();  
  //#else  
  //#   this.g   =   getGraphics();  
  //#endif  
  executeFrameTask();  
  if(clockRunning){  
  this.virtualTime   +=   this.frameDelay;  
  }  
  }  
   
  this.__elapsedTime   =   System.currentTimeMillis()   -   this.__lastSystemTime;  
  if   (this.__elapsedTime>0   &&   this.__elapsedTime   <   this.frameDelay)   {  
  try{  
  Thread.sleep(this.frameDelay   -   this.__elapsedTime);  
  }catch(InterruptedException   ie){}  
  }  
   
  //#mdebug   benchmark  
  //#   System.out.println("elapsed   time:   "   +   String.valueOf(this.__elapsedTime)   +    
  //#                                         "     ("   +   String.valueOf(this.__elapsedTime*100/this.frameDelay)   +   "%)");  
  //#enddebug  
  }  
   
  this.__midlet.notifyDestroyed();  
                  //#mdebug   info  
          //#   System.out.println("game   stop   normally.");  
  //#enddebug  
          }catch(Exception   e){  
                  //#mdebug   fatal  
          //#   System.out.println("a   fatal   error   occured.");  
                  //#   e.printStackTrace();  
  //#enddebug  
                   
          showSystemHint(Locale.get("Game.SystemError"));  
           
          this.__midlet.notifyDestroyed();  
          }  
  }  
                  //略……  
  }   


        上面的代码在MIDP1.0接口的基础上模拟了MIDP2.0   GameCanvas的功能,并对用户输入作了增强。  
        paint(Graphics   g)实现了父类的抽象方法。  
        flushGraphics()和flushGraphics(int   x,   int   y,   int   width,   int   height)是对GameCanvas相应方法的模拟,方便调用。  
        keyPressed(int   keyCode)和keyReleased(int   keyCode)用来捕获用户输入,并记录按键的状态。  
        detectInput(int   keyPressedConstant,   boolean   detectsStroke,boolean   soft,boolean   update)用于根据案件状态来判断,用户(玩家)是否将某个键(包括左右系统键)按下一次,或按下没有松开。  
        run()实现了Runnable接口的方法,其中,游戏初始化在initialize()中进行,游戏循环在executeFrameTask()中实现。每一帧如果不到预定的帧延迟时间就让当前线程睡眠一会。  
   
        这只是一小部分,为了阅读方便有些改动。另外,在我的游戏内核里还有  
        Temporary   Memory部分             用于方便的把数据按照数据流DataInputStream和DataOutputStream来操作。  
        General部分                               定义了8个方向,高效产生随机数,对矩形进行碰撞判断,byte[]和int的相互转换。  
        Device   Feature部分                 包括设备相关特性的操作:声音、振动和灯光  
        UI部分                                         包括在屏幕上书写特效文字,在一个区域内分页显示大段文字(比如人物对话),系统信息提示和进度条。  
        Map部分                                       对游戏中地图的解析和显示  
        Game   Menu部分                           游戏菜单,绘制菜单和获取用户对菜单项的选择。  
        Resource   and   storage部分     用于获取打包资源(为了使压缩比更大)和按文件名方式管理RMS内容,还有从网上下载资源。  
        Path部分                                     产生完美的圆弧和直线路径,用于子弹敌人飞行等  
        上面各部分为了使字节码尽可能少,我没有做类封装,而是写到了一起。另外,如果有哪些部分没有被调用到,那么在作绕码(混淆)时,会被自动去掉,所以不必担心。  
   
          我还写了对MIDP2.0   Sprite类的模拟类,以便使用。  
   
          内核部分之外,就是具体游戏逻辑的实现了。其实,有了上面工具的帮助,游戏逻辑的实现是就容易多了。  
   
          除了j2me的程序,在开发中还需要一些工具,如:资源打包工具,地图编辑器和图像优化工具。  
          资源打包工具——把多个资源文件(如png图片等)打包为一个文件,这样在jar包中会有更大的压缩比。  
          地图编辑器——编辑游戏地图,共类似TiledLayer使用。  
          图像优化工具——将png图片进一步压缩,节约空间。  
   
          以上内容我正在使用。  
   
   
  二、商业运作  
          这方面问题如果没有深入进去,是比较难了解的。在国内,j2me应用是通过sp(Service   Provider,开发者是cp   content   provider之一)来进行发布,通过移动审批后供用户下载使用。通常的商业模式为:预付款+按比例分成。具体数字和比例看CP的名气、东西的品质和谈判的技巧等。  
          如果东西好,还可以销售到国外。除了通过运营商销售以外,还可以放在独立的销售网站上销售。好东西,价格都很高的。像gameloft的单机游戏几十港元一个。通过运营商的,通常可以买到4-5欧元一个下载。  
          所以,新兴的手机游戏市场,是个大馅饼,有很多机会。尤其是对于我们这种没有资金的个人或小型团队来说,是淘金千载难逢的机遇。  
          更详细的以后再谈。  
  三、demo  
          这个demo是我目前尚未发布的作品,MIDP2   is   required.具体我不多谈了,CSDN不能上传,有兴趣可以给我发邮件,我用附件发送。  
   
  四、关于我和我寻求的帮助  
          先说我个人。我2000年考入国防科技大学,2年后不能忍受压抑的环境要求退学未受批准,于是不告而别被开除。后来研究技术,没有找到合适的市场机会。几个月前和像素点工作室的朋友在四川合作开发手机游戏,现在拥有1个完整产品和完善内核、周边工具。  
   
          也许最理智的程序员也会在爱情面前陷入死循环,直到资源耗尽系统崩溃!  
          我寻求的帮助。去年我和北京一个女孩有个为期5个月的浪漫约定,于是我就走入移动开发领域。可是,时间到了,我的东西还没出来,我失约了。约定又超过了2个月,我不想絮叨情感上的纠缠不清,可的确发生了很多事情。今天我和她聊天,我不能再等了。我不能等到我的游戏谈判完卖出去以后再去找她,因为她要毁了自己,绝无玩笑。  
   
   
          对具体的技术和商业细节感兴趣,可以和我面谈。如果你愿意善意的帮助一个同行,交一个真诚的朋友或者共同开发手机游戏市场,请尽快联系我。  
http://topic.csdn.net/t/20050308/05/3832358.html

posted on 2007-02-03 19:15 SIMONE 阅读(359) 评论(0)  编辑  收藏 所属分类: JAVA

只有注册用户登录后才能发表评论。


网站导航: