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

2023-12-16 02:59

本文主要是介绍【html5手游开发】虚拟摇杆及虚拟按键的开发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

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

难点解释

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 startthis.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>

资源下载打包

下载

这篇关于【html5手游开发】虚拟摇杆及虚拟按键的开发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/498856

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能