【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

相关文章

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

CSS place-items: center解析与用法详解

《CSSplace-items:center解析与用法详解》place-items:center;是一个强大的CSS简写属性,用于同时控制网格(Grid)和弹性盒(Flexbox)... place-items: center; 是一个强大的 css 简写属性,用于同时控制 网格(Grid) 和 弹性盒(F

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求

CSS Anchor Positioning重新定义锚点定位的时代来临(最新推荐)

《CSSAnchorPositioning重新定义锚点定位的时代来临(最新推荐)》CSSAnchorPositioning是一项仍在草案中的新特性,由Chrome125开始提供原生支持需... 目录 css Anchor Positioning:重新定义「锚定定位」的时代来了! 什么是 Anchor Pos

CSS中的Static、Relative、Absolute、Fixed、Sticky的应用与详细对比

《CSS中的Static、Relative、Absolute、Fixed、Sticky的应用与详细对比》CSS中的position属性用于控制元素的定位方式,不同的定位方式会影响元素在页面中的布... css 中的 position 属性用于控制元素的定位方式,不同的定位方式会影响元素在页面中的布局和层叠关

HTML5 getUserMedia API网页录音实现指南示例小结

《HTML5getUserMediaAPI网页录音实现指南示例小结》本教程将指导你如何利用这一API,结合WebAudioAPI,实现网页录音功能,从获取音频流到处理和保存录音,整个过程将逐步... 目录1. html5 getUserMedia API简介1.1 API概念与历史1.2 功能与优势1.3

全面解析HTML5中Checkbox标签

《全面解析HTML5中Checkbox标签》Checkbox是HTML5中非常重要的表单元素之一,通过合理使用其属性和样式自定义方法,可以为用户提供丰富多样的交互体验,这篇文章给大家介绍HTML5中C... 在html5中,Checkbox(复选框)是一种常用的表单元素,允许用户在一组选项中选择多个项目。本

HTML5 搜索框Search Box详解

《HTML5搜索框SearchBox详解》HTML5的搜索框是一个强大的工具,能够有效提升用户体验,通过结合自动补全功能和适当的样式,可以创建出既美观又实用的搜索界面,这篇文章给大家介绍HTML5... html5 搜索框(Search Box)详解搜索框是一个用于输入查询内容的控件,通常用于网站或应用程

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.