这边想再单独和大家分享一下有关虚拟摇杆的开发经验,因为觉得这个功能还是很实用和用途广泛的!

效果:

在这里插入图片描述

运行地址:
http://h5demo.yyfuncdn.com/res/gameDemo/Pokemon/game.html

摇杆显示:

因为制作该游戏使用了 pixi 框架,所以需要利用 PIXI.Graphics() 方法绘制两个圆就可以了,一大一小,大圆为移动背景,给与一个颜色和透明度,默认隐藏即可,下面是绘制一个按钮移动背景圆的代码:

	var rockerbg = new PIXI.Graphics();//绘制摇杆背景
    rockerbg.lineStyle(0);//外边框宽度为0
    rockerbg.beginFill(0x000000, 0.3);//背景色 透明度
    var radius = 0;//半径
    if(phoneWidth > phoneHeight)radius = phoneWidth/10;
    else radius = phoneHeight/10;
    rockerbg.drawCircle(0,0,radius);//设置半径
    rockerbg.endFill();//结束绘画
    parent.addChild(rockerbg);//添加到舞台,parent为传进来的舞台参数

控制按钮同理,只不过小一点就可以了。当然如果小伙伴们图省事或不使用框架,找两个圆的图片也可以,但是要注意设置锚点为中心

摇杆功能:

接下来就要具体说明一下他是如何将被操作的人或物捆绑到一起的了,在该宝可梦游戏中主要为了提供给角色一个速度,这个速度是一个 json 数据,里面存放了 x 轴与 y 轴的速度

var speed = {x:0,y:0};

如何实现触摸屏幕给与速度相应数据呢,这就要用到开启舞台交互事件中的“鼠标按下”、“鼠标抬起”、“鼠标移动”三个事件

其中“鼠标按下”事件中控制获取当前鼠标位置,以及按钮的显示

    app.stage.on("pointerdown",function(event){//在鼠标按下位置显示控制器
        var pos = event.data.getLocalPosition(app.stage);
        rockerbg.x = pos.x;
        rockerbg.y = pos.y;
        rockerbg.visible = true;
    })

“鼠标抬起”事件中控制控制器隐藏以及速度归零

    app.stage.on("pointerup",function(){//鼠标抬起时控制器隐藏,速度归零
        rocker.x = 0;
        rocker.y = 0;
        rockerbg.visible = false;
        speed = {x:0,y:0};
    })

“鼠标移动”事件是整个控制的关键,他将控制按钮的移动,利用大圆与小圆的圆心位置获得角色所需的移动方向,因为角色只能四个方向移动,所以只需要先判断小圆圆心据原点的X轴与Y轴绝对值的最大值,再判断最大值为正值或负值即可得出角色的移动方向
在这里插入图片描述

    rocker.on("pointermove",function(event){//利用判断控制器在控制器背景原点的方向进行设置角色移动方向
        var pos = event.data.getLocalPosition(app.stage);
        var A = rockerbg.x-pos.x;//摇杆起始点与鼠标X轴距离
        var B = rockerbg.y-pos.y;//摇杆起始点与鼠标Y轴距离
        var Z = radius;//控制器背景的半径
        var X = pos.x-rockerbg.x;//获取鼠标X轴位置
        var Y = pos.y-rockerbg.y;//获取鼠标Y轴位置
        if(Z*Z<A*A+B*B){//判断鼠标位置是否超出摇杆移动范围
            var angle = Math.atan((pos.y-rockerbg.y)/(pos.x-rockerbg.x));//计算鼠标与摇杆起始点角度
            if(pos.x<rockerbg.x){//判断鼠标是否在摇杆左侧
                X = -Z*Math.cos(angle);
                Y = -Z*Math.sin(angle);
            }else{//判断鼠标是否在摇杆右侧
                X = Z*Math.cos(angle);
                Y = Z*Math.sin(angle);
            }
        }
        speed = {x:0,y:0};
        var movescope = rockerbg.width/6;//设置控制器移动的最小范围(当超过这个值时则可设置方向与速度)
        if(Math.abs(X) > Math.abs(Y) && Math.abs(X) > movescope){
            if(X < 0){
                obj.moveState = true;
                obj.direction = "a";//人物动画
                speed.x = -3;//设置x轴速度
            }else if(X > 0){
                obj.moveState = true;
                obj.direction = "d";//人物动画
                speed.x = 3;//设置x轴速度
            }
        }else if(Math.abs(X) < Math.abs(Y) && Math.abs(Y) > movescope){
            if(Y < 0){
                obj.moveState = true;
                obj.direction = "w";//人物动画
                speed.y = -3;//设置y轴速度
            }else if(Y > 0){
                obj.moveState = true;
                obj.direction = "s";//人物动画
                speed.y = 3;//设置y轴速度
            }
        }
        rocker.x = X;//设置按钮x坐标
        rocker.y = Y;//设置按钮y坐标
    })

上面代码中各行都有详细的功能注释说明,希望对大家的理解有所帮助,最后的最后是调用当前对象中的 getSpeed 方法即可获取该对象中的 json 数据 speed

    this.getSpeed = function(){
        return speed;
    }

下面的是整个虚拟控制器的完整代码

function Fsvjoy(parent){//虚拟控制器
    var self = this;
    var rockerbg = new PIXI.Graphics();//绘制摇杆背景
    rockerbg.lineStyle(0);
    rockerbg.beginFill(0x000000, 0.3);
    var radius = 0;
    if(phoneWidth > phoneHeight)radius = phoneWidth/10;
    else radius = phoneHeight/10;
    rockerbg.drawCircle(0,0,radius);
    rockerbg.endFill();
    parent.addChild(rockerbg);
    var rocker = new PIXI.Graphics();//绘制摇杆
    rocker.lineStyle(0);
    rocker.beginFill(0xf0f0f0,0.7);
    rocker.drawCircle(0,0,rockerbg.height/8);
    rocker.endFill();
    rockerbg.addChild(rocker);
    rockerbg.visible = false;

    var obj = null;
    this.setobj = function(role){
        obj = role;
    }
    var speed = {x:0,y:0};

    app.stage.interactive = true;//开启舞台交互
    app.stage.on("pointerdown",function(event){//在鼠标按下位置显示控制器
        var pos = event.data.getLocalPosition(app.stage);
        rockerbg.x = pos.x;
        rockerbg.y = pos.y;
        rockerbg.visible = true;
    })

    app.stage.on("pointerup",function(){//鼠标抬起时控制器隐藏,速度归零
        rocker.x = 0;
        rocker.y = 0;
        rockerbg.visible = false;
        speed = {x:0,y:0};
    })
    rocker.interactive = true;//开启摇杆交互
    rocker.on("pointermove",function(event){//利用判断控制器在控制器背景原点的方向进行设置角色移动方向
        var pos = event.data.getLocalPosition(app.stage);
        var A = rockerbg.x-pos.x;//摇杆起始点与鼠标X轴距离
        var B = rockerbg.y-pos.y;//摇杆起始点与鼠标Y轴距离
        var Z = radius;//控制器背景的半径
        var X = pos.x-rockerbg.x;//获取鼠标X轴位置
        var Y = pos.y-rockerbg.y;//获取鼠标Y轴位置
        if(Z*Z<A*A+B*B){//判断鼠标位置是否超出摇杆移动范围
            var angle = Math.atan((pos.y-rockerbg.y)/(pos.x-rockerbg.x));//计算鼠标与摇杆起始点角度
            if(pos.x<rockerbg.x){//判断鼠标是否在摇杆左侧
                X = -Z*Math.cos(angle);
                Y = -Z*Math.sin(angle);
            }else{//判断鼠标是否在摇杆左侧
                X = Z*Math.cos(angle);
                Y = Z*Math.sin(angle);
            }
        }
        speed = {x:0,y:0};
        var movescope = rockerbg.width/6;//设置控制器移动的最小范围(当超过这个值时则可设置方向与速度)
        if(Math.abs(X) > Math.abs(Y) && Math.abs(X) > movescope){
            if(X < 0){
                obj.moveState = true;
                obj.direction = "a";
                speed.x = -3;
            }else if(X > 0){
                obj.moveState = true;
                obj.direction = "d";
                speed.x = 3;
            }
        }else if(Math.abs(X) < Math.abs(Y) && Math.abs(Y) > movescope){
            if(Y < 0){
                obj.moveState = true;
                obj.direction = "w";
                speed.y = -3;
            }else if(Y > 0){
                obj.moveState = true;
                obj.direction = "s";
                speed.y = 3;
            }
        }
        rocker.x = X;
        rocker.y = Y;
    })

    this.getSpeed = function(){
        return speed;
    }
}

版权声明:本文为dayouyu001原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/dayouyu001/article/details/115947597