【html5手游开发】虚拟摇杆及虚拟按键的开发

来源:互联网 发布:文字特效软件下载 编辑:程序博客网 时间:2024/04/29 09:29

前言

现在很多手游都有虚拟按钮–尤其是那些需要操作高的。那么我们也要紧跟时代步伐,开发一个虚拟按钮插件。

难点解释

1、首先绝对要先熟悉一下pixi。
2、要计算一下手指触摸拖动摇杆的角度–小学数学要过关,假如是小学连续留级十几年的话,会有点麻烦。
3、pixi有一些小bug,就是touch end会无缘无故由其他物体触发,代码里面已经有解决方案了。想知道原委就看看上一篇文章。

实际运行界面

这里写图片描述

这里写图片描述

核心代码

<%@ page import="java.util.Date" %><%@ page contentType="text/html;charset=UTF-8" language="java" %><%  String  _js_version="7";%><!DOCTYPE html><html><head>  <meta charset="UTF-8">  <meta name="viewport" content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"/>  <meta name="apple-mobile-web-app-capable" content="yes"/>  <meta name="apple-mobile-web-app-status-bar-style" content="black">  <meta content="telephone=no,email=no" name="format-detection">  <meta name="full-screen" content="true"/>  <%--竖屏--%>  <%--<meta name="screen-orientation" content="portrait"/>--%>  <%--横屏--%>  <meta name="screen-orientation" content="landscape"/>  <meta name="x5-fullscreen" content="true"/>  <meta name="360-fullscreen" content="true"/>  <script type="text/javascript" src="../js/jquery-1.11.0.min.js"></script>  <script type="text/javascript" src="../js/jquery-migrate-1.2.1.min.js"></script>  <script src="../js/box2dWeb/Box2dWeb-2.1.a.3.min.js"></script>  <script src="../js/pixi.min.js"></script>  <script src="../js/pixi-spine.min.js"></script>  <style>    body{      padding: 0;      margin: 0;    }  </style></head><body><div id="game" style=""></div><script>  var GameOptions={    width:800 //游戏屏幕的高度。    ,height:600 //游戏屏幕的宽度。    ,ground_y:400-65 //地面y坐标    ,fps:10    ,actorWidth:57*2*0.8    ,actorHeight:61*2*0.8    //--hero的行走向量速度。    ,hero_run_x_speed:15    ,hero_run_y_speed:30 //hero跳跃时候向上的速度。  };</script><script>  //--虚拟手柄控件。  function GameJoyPad(parent_container,_opts){    var me=this;    this.settings={      joy_pad_background:"assets/joystick/Backgrounds/Back_08.png"//摇杆的背景。      ,joy_pad_joystick:"assets/joystick/Joystick/Joystick_08.png" //摇杆正体。      ,joy_pad_x:100 //摇杆的坐标      ,joy_pad_y:220 //摇杆的y坐标      //--注意,所有缩放的尺寸都是按照unitiy3d获得的这些摇杆素材来设置的,假如替换了texture,请重新设置缩放尺寸。      ,joy_pad_background_scale:{        x:0.4        ,y:0.4      }//摇杆背景需要缩放的比例,默认是x和y上面都是1      ,joy_pad_joystick_scale:{        x:0.4        ,y:0.4      }//摇杆主体需要缩放的比例,默认x、y都是1      ,buttons:[        {          button_name:"shoot"          ,normal_texture:"assets/joystick/Buttons/Button_08_Normal_Shoot.png"          ,pressed_texture:"assets/joystick/Buttons/Button_08_Pressed_Shoot.png"          ,x:300          ,y:250          ,scale:{x:0.4,y:0.4}        }        ,{          button_name:"gun"          ,normal_texture:"assets/joystick/Buttons/Button_08_Normal_Shoot_B.png"          ,pressed_texture:"assets/joystick/Buttons/Button_08_Pressed_Shoot_B.png"          ,x:400          ,y:250          ,scale:{x:0.4,y:0.4}        }        , {          button_name:"blank"          ,normal_texture:"assets/joystick/Buttons/Button_08_Normal_Virgin.png"          ,pressed_texture:"assets/joystick/Buttons/Button_08_Pressed_Virgin.png"          ,x:500          ,y:250          ,scale:{x:0.4,y:0.4}        }      ] //虚拟手柄的其他按钮。      //--摇杆摇动角度变换时候的回调函数。      ,onJoyStickMove:function(now_stick_angle){      }      //--点击了控制按钮的回调事件。      ,onButtonClick:function(event,button_name){      }    };    $.extend(this.settings,_opts);    //--基本赋值。    this.parent_container=parent_container;    this.joy_pad_container={};    this.joy_pad_background={};    this.joy_pad_joystick={};    this.joy_pad_radius=0;//这是背景大圈子的半径。    this.joy_pad_stickRadius=0;//这是摇杆小圈子的半径。    //--生成一个随机的joy container id。    this.joy_pad_container_id=new Date().getTime()+"_"+parseInt(Math.random()*1000);    //--好了,加载相关资源    me.__loadResources(function(){      me.__init_stick();    });    //--新建按钮。    for(var i=0;i< me.settings.buttons.length;i++){      var buttonItemInfo=me.settings.buttons[i];      me.__createButton(buttonItemInfo);    }  }  GameJoyPad.prototype.__loadResources=function(callback){    var me=this;    PIXI.loader.add('joy_pad_background',me.settings.joy_pad_background);    PIXI.loader.add('joy_pad_joystick',me.settings.joy_pad_joystick);    PIXI.loader.once('complete',function(){      if(callback){        callback();      }    });    PIXI.loader.load();  }  //--初始化摇杆。  GameJoyPad.prototype.__init_stick=function(){    var child=this;    var texture_bg=PIXI.Texture.fromImage(this.settings.joy_pad_background);    var texture_joystick=PIXI.Texture.fromImage(this.settings.joy_pad_joystick);    this.joy_pad_container=new PIXI.Container();    this.joy_pad_background=new PIXI.Sprite(texture_bg);    this.joy_pad_joystick=new PIXI.Sprite(texture_joystick);    this.joy_pad_background.scale=this.settings.joy_pad_background_scale;    this.joy_pad_joystick.scale=this.settings.joy_pad_joystick_scale;    this.joy_pad_background.anchor={x:0.5,y:0.5};    this.joy_pad_joystick.anchor={x:0.5,y:0.5};    this.joy_pad_container.anchor={x:0.5,y:0.5};    this.joy_pad_container.addChild(this.joy_pad_background);    this.joy_pad_container.addChild(this.joy_pad_joystick);    this.joy_pad_radius=this.joy_pad_container.width/2;    this.joy_pad_stickRadius=this.joy_pad_joystick.width/2;    window.joy_container=this.joy_pad_container;    this.joy_pad_container.position={      x:this.settings.joy_pad_x      ,y:this.settings.joy_pad_y    };    this.parent_container.addChild(this.joy_pad_container);    this.joy_pad_container.random_id=this.joy_pad_container_id;    this.__init_stick_events();  }  GameJoyPad.prototype.__init_stick_events=function(){    var me=this;    this.joy_pad_container.interactive=true;    var _on_drag=false;    var _event_data={};    var _touch_event_id=0;    /******pixi bug1:当两个手指其中一个,譬如摇杆,另一个手指点击按钮,摇杆会接收到touch end事件。醉了。******/    function onDragStart(event){      //--注意,pc端的identifier是undefined。      _event_data = event.data;      var startPosition = _event_data.getLocalPosition(this.parent);      _touch_event_id=event.data.identifier;      _on_drag=true;    }    function onDragEnd(event){      if(_on_drag==false){        return;      }      if(_touch_event_id!=event.data.identifier){        return;      }      _on_drag=false;      window.end_event=event;      me.joy_pad_joystick.position={        x:0        ,y:0      };    }    function onDragMove(event){      if(_touch_event_id!=event.data.identifier){        return;      }      if(_on_drag==false){        return;      }      var newPosition = _event_data.getLocalPosition(this.parent);      var _side_length_y=newPosition.y-me.settings.joy_pad_y;      var _side_length_x=newPosition.x-me.settings.joy_pad_x;      var _center_point={        x:0        ,y:0      };//--中心点。      var _stick_angle=0; //当前摇杆的角度      if(_side_length_x==0&&_side_length_y==0){        return;      }      //--好了,现在判断执行计算的半径。      var _cal_radius=0;      if(_side_length_x*_side_length_x+_side_length_y*_side_length_y>=me.joy_pad_radius*me.joy_pad_radius){        _cal_radius=me.joy_pad_radius;        //--假如大于的话,那么就按照圆弧计算坐标。      }      else{        _cal_radius=me.joy_pad_radius-me.joy_pad_stickRadius;      }      if(_side_length_x==0){        if(_side_length_y>0){          _center_point={            x:0            ,y:_side_length_y>me.joy_pad_radius?me.joy_pad_radius:_side_length_y          };          _stick_angle=270;//180度。        }        else{          _center_point={            x:0            ,y:-(Math.abs(_side_length_y)>me.joy_pad_radius?me.joy_pad_radius:Math.abs(_side_length_y))          };          _stick_angle=90;//901度        }        me.joy_pad_joystick.position=_center_point;        me.settings.onJoyStickMove(_stick_angle);        return;      }      else if(_side_length_y==0){        if(_side_length_x>0){          _center_point={            x:(Math.abs(_side_length_x)>me.joy_pad_radius?me.joy_pad_radius:Math.abs(_side_length_x))            ,y:0          };          _stick_angle=0;//0度        }        else{          _center_point={            x:-(Math.abs(_side_length_x)>me.joy_pad_radius?me.joy_pad_radius:Math.abs(_side_length_x))            ,y:0          };          _stick_angle=180;//180度        }        me.joy_pad_joystick.position=_center_point;        me.settings.onJoyStickMove(_stick_angle);        return;      }      var _tan_val=Math.abs(_side_length_y/_side_length_x);      var _radian=Math.atan(_tan_val);      var _angle=_radian*180/Math.PI;      _stick_angle=_angle;      //--好了,计算现在摇杆的中心点主坐标了。      var _center_x= 0;      var _center_y=0;      if(_side_length_x*_side_length_x+_side_length_y*_side_length_y>=me.joy_pad_radius*me.joy_pad_radius){        _center_x= me.joy_pad_radius*Math.cos(_radian);        _center_y=me.joy_pad_radius*Math.sin(_radian);      }      else{        _center_x= Math.abs(_side_length_x)>me.joy_pad_radius?me.joy_pad_radius:Math.abs(_side_length_x);        _center_y=Math.abs(_side_length_y)>me.joy_pad_radius?me.joy_pad_radius:Math.abs(_side_length_y);      }      if(_side_length_y<0){        _center_y=-Math.abs(_center_y);      }      if(_side_length_x<0){        _center_x=-Math.abs(_center_x);      }      if(_side_length_x>0&&_side_length_y<0){        //--锐角。      }      else if(_side_length_x<0&&_side_length_y<0){        //--好了,钝角。        _stick_angle=180-_stick_angle;      }      else if(_side_length_x<0&&_side_length_y>0){        _stick_angle=_stick_angle+180;      }      else if(_side_length_x>0&&_side_length_y>0){        _stick_angle=360-_stick_angle;      }      _center_point={        x:_center_x        ,y:_center_y      };      me.joy_pad_joystick.position=_center_point;      me.settings.onJoyStickMove(_stick_angle);    };      // events for drag start            this.joy_pad_container.on('mousedown', onDragStart)            .on('touchstart', onDragStart)      // events for drag end            .on('mouseup', onDragEnd)            .on('mouseupoutside', onDragEnd)            .on('touchend', onDragEnd)            .on('touchendoutside', onDragEnd)      // events for drag move            .on('mousemove', onDragMove)            .on('touchmove', onDragMove);  }  GameJoyPad.prototype.__createButton=function(buttonItemInfo){    var me=this;    var textureButton = PIXI.Texture.fromImage(buttonItemInfo.normal_texture);    var textureButtonDown = PIXI.Texture.fromImage(buttonItemInfo.pressed_texture);    var textureButtonOver = PIXI.Texture.fromImage(buttonItemInfo.normal_texture);    var button = new PIXI.Sprite(textureButton);    button.buttonMode = true;    button.anchor.set(0.5);    button.position.x = buttonItemInfo.x;    button.position.y = buttonItemInfo.y;    button.interactive = true;    if(buttonItemInfo.scale){      button.scale=buttonItemInfo.scale;    }    var _event_data_identifier=0;    function onButtonDown(event)    {      this.isdown = true;      this.texture = textureButtonDown;      this.alpha = 1;      _event_data_identifier=event.data.identifier;    }    function onButtonUp(event)    {      if(_event_data_identifier!=event.data.identifier){        return;      }      this.isdown = false;      if (this.isOver)      {        this.texture = textureButtonOver;      }      else      {        this.texture = textureButton;      }    }    function onButtonOver()    {      this.isOver = true;      if (this.isdown)      {        return;      }      this.texture = textureButtonOver;    }    function onButtonOut()    {      this.isOver = false;      if (this.isdown)      {        return;      }      this.texture = textureButton;    }    button.on('mousedown', onButtonDown)          .on('touchstart', onButtonDown)      // set the mouseup and touchend callback...            .on('mouseup', onButtonUp)            .on('touchend', onButtonUp)            .on('mouseupoutside', onButtonUp)            .on('touchendoutside', onButtonUp)      // set the mouseover callback...            .on('mouseover', onButtonOver)      // set the mouseout callback...            .on('mouseout', onButtonOut);    // you can also listen to click and tap events :    //.on('click', noop)    var noop = function (_event) {      me.settings.onButtonClick(_event,buttonItemInfo.button_name);    };    button.tap = noop;    button.click = noop;    this.parent_container.addChild(button);    return button;  }</script><script>  var game_renderer = PIXI.autoDetectRenderer(GameOptions.width, GameOptions.height,{backgroundColor : 0x1099bb});  var game_stage = new PIXI.Container(0x66FF99);  $("#game").append(game_renderer.view);  var _joy_pad=new GameJoyPad(game_stage,{          //--摇杆摇动角度变换时候的回调函数。          onJoyStickMove:function(now_stick_angle){            _showMsg("摇杆角度为:"+now_stick_angle);          }  //--点击了控制按钮的回调事件。        ,onButtonClick:function(event,button_name){            _showMsg("点击的按钮名称是:"+button_name);        }  });  var style = {    font : 'bold italic 20px Arial',    fill : '#F7EDCA',    stroke : '#4a1850',//    strokeThickness : 5,//    dropShadow : true,//    dropShadowColor : '#000000',//    dropShadowAngle : Math.PI / 6,//    dropShadowDistance : 6,    wordWrap : true,    wordWrapWidth : 300  };  var richText = new PIXI.Text('Rich text with a lot of options and across multiple lines',style);  richText.x = 0;  richText.y = 0;  game_stage.addChild(richText);  function game_animate(){    requestAnimationFrame(game_animate);    game_renderer.render(game_stage);  }  requestAnimationFrame(game_animate);</script><script>  function _debug(msg){    var _str=richText.text;    richText.text=_str+"\n"+msg;  }  function _showMsg(msg){    richText.text=msg;  }</script></body></html>

资源下载打包

下载

0 0
原创粉丝点击