设为首页收藏本站同能贴吧 切换语言 繁体中文
开启辅助访问 切换到窄版
扫描二维码关注官方公众号
返回列表
+ 发新帖
查看: 91|回复: 0

[转载发布] Multi-Touch Core Support

[复制链接]
累计送礼:
0 个
累计收礼:
1 个
  • TA的每日心情
    开心
    2026-7-12 04:10
  • 签到天数: 209 天

    连续签到: 2 天

    [LV.7]常住居民III

    7959

    主题

    864

    回帖

    3万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    VIP
    7
    卡币
    29925
    OK点
    16
    推广点
    0
    同能卷
    50
    积分
    38778

    灌水之王

    发表于 3 天前 | 显示全部楼层 |阅读模式

    Multi-Touch 1.02




    Author: Michael Morris @Blue Booth Studios




    Introduction


            Separates out multi-touch core support from Map Controls, to facilitate further growth of the plugin, and allows for potential incorporation into core upgrades.  Includes swipe gesture support.


    Features


            - Full (tested) multi-touch support!  WARNING: This required me to redo most of TouchInput core, which may introduce some incompatibilities.


            - Swipe (up/down/left/right) gesture support.


            - Input History tracking.


    Screenshots


            No visual effect by itself.


    How to Use
            - Copy script into your game js/plugins directory. 


            - Import this script into your project and set all parameters.


            - Set up events to use with the plugin.  See demo provided.


    Demo


            See Map Controls plugin demo.


    Script

    Spoiler//=============================================================================
    // Bluebooth Plugins - MultiTouch
    // BBS_MultiTouch.js
    //=============================================================================

    //=============================================================================
    /*:
    * @title MultiTouch Plugin
    * @author Michael Morris (https://www.patreon.com/bluebooth)
    * @date March 4, 2016
    * @filename BBS_MultiTouch.js
    * If you enjoy my work, consider supporting me on Patreon!
    *
    * https://www.patreon.com/bluebooth
    *
    * @plugindesc v1.02 Overrides TouchInput core scripts to provide true multi-touch
    * and gesture support for RPGMaker MV.  Originally developed in conjunction with
    * BBS_MapControls.
    *
    * Special Thanks to Tsukihime for all the help.
    * Special Thanks to 'Ramza' Michael Sweeney and Lakaroth for helping so much with testing.
    * Special Thanks to Jairaks89 for https://github.com/jairajs89/Touchy.js/blob/master/touchy.js
    *  on which the multi-touch structure was loosely based.
    *
    * ============================================================================
    * Terms of Use
    * ============================================================================
    *  - Free for use in non-commercial projects with credits
    *  - Contact me for commercial use
    *
    * ============================================================================
    * Parameters
    * ============================================================================
    * @param Debug Mode
    * @desc Enable to activate console variable logging.  Use for debugging odd behaviour.
    * true to enable console variable logging.
    * @default false
    *
    * @param -----Input History Tracking-----
    * @param Button History Max. Size
    * @desc How many buttons to track at once.  Keep small.  Use value of 1 for single touch, 2+ for multi-touch.
    * @default 2
    *
    * @param -----Gesture Handling-----
    * @param Gesture Distance Threshold
    * @desc Minimum distance touch travels (in pixels) to be considered a swipe gesture.
    * @default 150
    *
    * @param Gesture Distance Restraint
    * @desc Maximum distance touch can travel (in pixels) in perpendicular direction to swipe to be considered a swipe.
    * @default 100
    *
    * @param Gesture Maximum Time
    * @desc Maximum time before a touch times out, and ceases to be considered a gesture (in milliseconds).
    * @default 300
      *
    * @help
    * ============================================================================
    * Description
    * ============================================================================
    *
    * Provides full multi-touch and gesture support to RPGMaker MV, adds input history
    * tracking of MRU input (from keyboard, gamepad, mouse, touch), to allow for custom
    * input handling.
    *
    * ============================================================================
    * Script Commands
    * ============================================================================
    * Script Commands:
    *
    *         TouchInput.wasGestured('swipe left');                        # Returns true if swipe left was gestured most recently.
    *
    * ============================================================================
    * Change Log
    * ============================================================================
    * 1.02 - fixed issue where multi-touch being enabled on its own would fail to accept map touch input.
    * 1.01 - multi-touch fixed to still work with mouse.  Click and touch event handling separated.
    * 1.00 - multi-touch seperated into own script to facilitate further growth.
    */
    //=============================================================================

    //=============================================================================
    var Imported = Imported || {} ;
    var BBS = BBS || {};
    Imported.MultiTouch = 1;
    BBS.MultiTouch = BBS.MultiTouch || {};

    (function() {

               //=============================================================================
            // Parameter Variables
            //=============================================================================
            var parameters = PluginManager.parameters('BBS_MultiTouch');
            var pDebugging                  = eval(String(parameters['Debug Mode'] || 'false'));       
            var pBtnHistoryMaxSize= Number(parameters['Button History Max. Size'] || '2');
            var pThreshold                  = Number(parameters['Gesture Distance Threshold'] || '150');
            var pRestraint                  = Number(parameters['Gesture Distance Restraint'] || '100');
            var pAllowedTime          = Number(parameters['Gesture Maximum Time'] || '300');

            //=============================================================================
            // Input/Button History
            //=============================================================================
            function InputHistory() {
                    this.initialize.apply(this, arguments);
            };

            InputHistory.prototype = Object.create(InputHistory.prototype);
            InputHistory.prototype.constructor = InputHistory;

            InputHistory.prototype.initialize = function() {
                    this._btnHistory = Array();
                    this._swipeHistory = null;
            };

            InputHistory.prototype.wasPressed = function(btn) {               
                    if (this._btnHistory.length < 1) return false;

                    var pressed = false;
                    for (var i = ; i < this._btnHistory.length; i++) {
                            if (this._btnHistory === btn) {
                                    pressed = true;
                                    break;
                            }
                    }

                    return pressed;
            };

            InputHistory.prototype.wasGestured = function(gesture) {
                    return (this._swipeHistory === gesture);
            };

            InputHistory.prototype.addBtn = function(btn) {               
                    // If btn already stored, don't need to store it again.
                    if (!this.wasPressed(btn)) {
                            // Shift if history size exceeded.
                            if (this._btnHistory.length >= pBtnHistoryMaxSize) {
                                    this._btnHistory.shift();
                            }

                            this._btnHistory.push(btn);

                            if (pDebugging) {                               
                                    $gameScreen.showPicture(1, this._btnHistory[], , , , 100, 100, 255, );

                                    if (this._btnHistory.length > 1) {
                                        $gameScreen.showPicture(2, this._btnHistory[1], , 40, , 100, 100, 255, );
                                    }
                            }

                    }
            };

            InputHistory.prototype.addGesture = function(gesture) {
                    this._swipeHistory = gesture;
            };

            InputHistory.prototype.removeBtn = function(btn) {
                    var index = this._btnHistory.indexOf(btn);
                    if (index >= ) {
                            this._btnHistory.splice(index, 1);
                    }
            };

            InputHistory.prototype.removeGesture = function(gesture) {
                    this._swipeHistory = null;
            };

            InputHistory.prototype._clear = function() {
                    if (pDebugging) {                               
                            $gameScreen.erasePicture(1);

                            if (this._btnHistory.length > 1) {
                               $gameScreen.erasePicture(2);
                            }
                    }

                    this._btnHistory = [];
                    this._swipeHistory = null;
            };

            //=============================================================================
            // Finger - Object to manage single-finger touch interactions
            //=============================================================================       
            function Finger(id) {
                    this.id = id;
                    this._x = null;
                    this._y = null;
                    this._startX = null;
                    this._startY = null;
                    this._date = ;

                    // Release not stored, because released fingers are deleted.
            };

            //=============================================================================
            // Touch Input New Functions: https://github.com/jairajs89/Touchy.js/blob/master/touchy.js
            //=============================================================================               

            /* Create a new hand based on the current touches on the screen */
            TouchInput.fingersRestart = function(touches) {
                    if (touches.length <= ) {
                            return;
                    }

                    this.fingers = [];
                    for (var i = ; i < event.touches.length; i++)
                    {
                            var touch = event.touches;
                            var x = Graphics.pageToCanvasX(touch.pageX);
                            var y = Graphics.pageToCanvasY(touch.pageY);

                            if (Graphics.isInsideCanvas(x, y)) {
                                    var finger = new Finger(touch.identifier);       
                                    this.fingers.push(finger);
                                    this._screenPressed = true;

                                    finger._x = x;
                                    finger._startX = x;
                                    finger._y = y;
                                    finger._startY = y;
                                    finger._date = Date.now();
                                    finger._pressedTime = ;

                                    if (pDebugging) {
                                            console.log("Touch trigger activated");
                                            console.log(this.fingers);
                                    }

                                    this._onTrigger(x, y);
                            }
                    }
            };

            TouchInput.fingersUpdate = function() {
                    if (!this.fingers) {
                            return;
                    }

                    for (var i = ; i < this.fingers.length; i++) {
                            var finger = this.fingers;
                            finger._pressedTime++;
                    }
            };

            /* Check a finger just prior to release to detect whether it was a swipe. */
            TouchInput.checkForSwipe = function(finger) {
                    if (!finger) {
                            return;
                    }

                    var elapsedTime = new Date().getTime() - finger._date;        // get time elapsed
                    if (elapsedTime > pAllowedTime) {
                            return;
                    }

                    var distX = finger._x - finger._startX;                                 // get horizontal dist traveled by finger while in contact with surface
                    var distY = finger._y - finger._startY;                                 // get vertical dist traveled by finger while in contact with surface

                    if (pDebugging) {
                            console.log(elapsedTime + " vs. " + pAllowedTime);
                            console.log("X Dist: " + distX + " Y Dist: " + distY);
                            console.log("Threshold: " + pThreshold + " Restraint: " + pRestraint);
                    }

                    if (Math.abs(distX) >= pThreshold && Math.abs(distY) <= pRestraint) { // 2nd condition for horizontal swipe met
                            // If dist traveled is negative, it indicates left swipe
                            if (distX < ) {
                                    this._onSwipedLeft();
                            } else {
                                    this._onSwipedRight();
                            }
                    }
                    else if (Math.abs(distY) >= pThreshold && Math.abs(distX) <= pRestraint) { // 2nd condition for vertical swipe met
                            // If dist traveled is negative, it indicates up swipe
                            if (distY < ) {
                                    this._onSwipedUp();
                            } else {
                                    this._onSwipedDown();
                            }
                    }

                    return;
            };

            /* Destroy the current hand regardless of fingers on the screen */
            TouchInput.fingersDestroy = function() {
                    if (!this.fingers) {
                            return;
                    }

                    for (var i = ; i < this.fingers.length; i++) {
                            var finger = this.fingers;

                            // Gesture handling happens here.
                            this.checkForSwipe(finger);
                            this._onRelease(finger._x, finger._y);
                    }

                    this._screenPressed = false;
                    this.fingers = null;
            };

            /* Get finger by id */
            TouchInput.getFinger = function(id) {
                    var foundFinger = null;

                    if (!this.fingers) return foundFinger;

                    // Direct iteration significantly faster than foreach.
                    for(var i = ; i < this.fingers.length; i++) {
                            if (this.fingers.id === id) {
                                    foundFinger = this.fingers;
                                    break;
                            }
                    }

                    return foundFinger;
            };       

            /* last touch.x and .y will not work with multi-touch.  Need to override. */
            TouchInput.isTouchingArea = function(rect) {
                    if (this.fingers === null) return false;

                    for (var i = ; i < this.fingers.length; i++) {
                            var finger = this.fingers;
                            if (pDebugging) {
                                    var strOut = "Finger at: " + finger._x + "; " + finger._y + " vs. touch area: " + rect.x + "; " + rect.y;
                                    console.log(strOut);
                            }

                            if (rect.contains(finger._x, finger._y)) {
                                    return true;
                            }
                    }

                    return false;
            };

            /* last touch.x and .y used only for mouse click.  Required function, mouse input was non-functional.*/
            TouchInput.isClicked = function(rect) {
                    if ( !this.isPressed() ) return false;

                    if (pDebugging) {
                            var strOut = "Click at: " + this._x + "; " + this._y + " vs. click area: " + rect.x + "; " + rect.y;
                            console.log(strOut);
                    }

                    if (rect.contains(this._x, this._y)) {
                            return true;
                    }

                    return false;
            };

            /* Input check for directional swipe */
            TouchInput.swipedLeft = function() {
                    var swipedLeft = this._history.wasGestured('swipe left');
                    return swipedLeft;
            };

            /* Input check for directional swipe */
            TouchInput.swipedRight = function() {
                    var swipedRight = this._history.wasGestured('swipe right');
                    return swipedRight;
            };

            /* Input check for directional swipe */
            TouchInput.swipedUp = function() {
                    var swipedUp = this._history.wasGestured('swipe up');
                    return swipedUp;
            };

            /* Input check for directional swipe */
            TouchInput.swipedDown = function() {
                    var swipedDown = this._history.wasGestured('swipe down');
                    return swipedDown;
            };

            /**
             * @static
             * @method _onSwipeLeft
             * @private
             */
            TouchInput._onSwipedLeft = function() {
                    this._history.addGesture('swipe left');
                    this._events.swipedLeft = true;
                    if (pDebugging) {
                            console.log("Left swipe detected!");
                    }
            };

            /**
             * @static
             * @method _onSwipeRight
             * @private
             */
            TouchInput._onSwipedRight = function() {
                    this._history.addGesture('swipe right');
                    this._events.swipedRight = true;
                    if (pDebugging) {
                            console.log("Right swipe detected!");
                    }
            };

            /**
             * @static
             * @method _onSwipeUp
             * @private
             */
            TouchInput._onSwipedUp = function() {
                    this._history.addGesture('swipe up');
                    this._events.swipedUp = true;
                    if (pDebugging) {
                            console.log("Up swipe detected!");
                    }
            };

            /**
             * @static
             * @method _onSwipeDown
             * @private
             */
            TouchInput._onSwipedDown = function() {
                    this._history.addGesture('swipe down');
                    this._events.swipedDown = true;
                    if (pDebugging) {
                            console.log("Down swipe detected!");
                    }
            };

            TouchInput.prototype.isGestured = function(gest) {
                    var gestSafe = gest.toLowerCase();
                    var pressed = this._history.wasGestured(gestSafe);
                    if (pressed) {
                            if (pDebugging) console.log(gestSafe);
                            this._history.removeGesture(gestSafe);
                    }

                    return pressed;
            };

            /* Adds button to input history if not already in input history. */
            TouchInput.addLastButton = function(btn) {
                    this._history.addBtn(btn);
            };

            /* Clears input history. */
            TouchInput._clearHistory = function() {
                    this._history._clear();
            };

            //=============================================================================
            // Touch Input Core Overrides
            //=============================================================================       

            /**
             * Initializes the touch system.
             *
             * @static
             * @method initialize
             */
            var BBS_MC_TouchInputInitialize = TouchInput.initialize;
        TouchInput.initialize = function() {
                    BBS_MC_TouchInputInitialize.call(this, arguments);
                    this._history = new InputHistory();
                    this.fingers = null;
            };

            /**
             * @static
             * @method _onTouchStart
             * @param {TouchEvent} event
             * @private
             */
            // Replaces core functionality.  Do not modify!
            TouchInput._onTouchStart = function(event) {
                    this.fingersDestroy();
                    this.fingersRestart(event.touches);
                    if (window.cordova || window.navigator.standalone) {
                            event.preventDefault();
                    }
            };

            /**
             * @static
             * @method _onTouchMove
             * @param {TouchEvent} event
             * @private
             */
            // Replaces core functionality.  Do not modify!
            TouchInput._onTouchMove = function(event) {
                    // Each changed touch for this event represents a moved touch.
                    // Direct iteration significantly faster than foreach.
                    for (var i = ; i < event.changedTouches.length; i++) {
                            var touch = event.changedTouches;
                            var finger = this.getFinger(touch.identifier);
                            if( !finger ) {
                                    return;
                            }

                            var x = Graphics.pageToCanvasX(touch.pageX);
                            var y = Graphics.pageToCanvasY(touch.pageY);
                            finger._x = x;
                            finger._y = y;

                            this._onMove(x, y);
                    }
            };

            /**
             * @static
             * @method _onTouchEnd
             * @param {TouchEvent} event
             * @private
             */
            // Replaces core functionality.  Do not modify!
            TouchInput._onTouchEnd = function(event) {
                    this.fingersDestroy();

                    var remainingTouches = [];
                    // Direct iteration significantly faster than foreach.
                    for (var i = ; i < event.touches.length; i++) {
                            var unChanged = true;

                            // Each changed touch for this event represents a released touch.
                            for (var j = ; j < event.changedTouches.length; j++) {
                                    if (event.changedTouches[j].identifier === event.touches.identifier) {
                                            unChanged = false;
                                            break;
                                    }
                            }

                            if (unChanged) {
                                    remainingTouches.push(event.touches);
                            }
                    }

                    this.fingersRestart(remainingTouches);
                    event.preventDefault();
            };

            /**
             * Clears all the touch data.
             *
             * @static
             * @method clear
             */
            var BBS_MC_TouchInputclear = TouchInput.clear;
            TouchInput.clear = function() {
                    BBS_MC_TouchInputclear.call(this);
                    this._events.swipedLeft = false;
                    this._events.swipedRight = false;
                    this._events.swipedUp = false;
                    this._events.swipedDown = false;
                    this._swipedLeft = false;
                    this._swipedRight = false;
                    this._swipedUp = false;
                    this._swipedDown = false;
                    this.fingersDestroy();
            };

            /**
             * Updates the touch data.
             *
             * @static
             * @method update
             */
            var BBS_MC_TouchInputupdate = TouchInput.update;
            TouchInput.update = function() {
                    BBS_MC_TouchInputupdate.call(this);
                    this._swipedLeft = this._events.swipedLeft;
                    this._swipedRight = this._events.swipedRight;
                    this._swipedUp = this._events.swipedUp;
                    this._swipedDown = this._events.swipedDown;
                    this._events.swipedLeft = false;
                    this._events.swipedRight = false;
                    this._events.swipedUp = false;
                    this._events.swipedDown = false;
            };

    })(BBS.MultiTouch);
    //=============================================================================
    // End of File
    //=============================================================================       








     


    Known Bugs / TODO


    - If feature requested, extend plugin to work with all scenes.


    - If feature requested, extend plugin to work with more gestures (one gesture per version).


    - Checking with major script developers to ensure compatibility with their plugins.


    - Make your suggestions or report bugs here!


     


    History


     

    Spoilerv1.02


      - fixed issue where multi-touch being enabled on its own would fail to accept map touch input.


    v1.01


      - multi-touch fixed to still work with mouse.  Click and touch event handling separated.
    v1.00



      - multi-touch seperated into own script to facilitate further growth.




    Suggestions, bug reports, and feature requests are welcomed!


     


    Compatibility Issues


    None known.  Compatible with Klaus Map Overlays, Terrax Lighting System, and most (if not all) of Yanfly's plugins.


     


    FAQ


    Q: The demo won't open, how to open it?
    A: Download Winrar and try again.


     


    Credit and Thanks
    - Micheal Morris @Blue Booth Studios
    - Credit to Tsukihime for continuing to be so helpful!


    - Jairajs89 - Touchy.js, which serves as basis for some multi-touch functionality.


    - Ramza, Lakaroth and friends for all their help testing multi-touch.


     


    Author's Notes
    Free for non-commercial usage as long as credit is given, contact me for commercial use.


    View attachment BBS_MultiTouch.js



    本贴来自国际rpgmaker官方论坛作者:bluebooth处,因国际论坛即将永久关站,为了存档多年珍贵资料,署名转载到本论坛存档,由于官方帖子为英文原帖,需要中文翻译请点击论坛顶部切换语言为中文就可以将帖子翻译成中文浏览,方便大家随时查看,原文地址:https://forums.rpgmakerweb.com/threads/multi-touch-core-support.58681/
    天天去同能,天天有童年!
    回复 送礼论坛版权

    使用道具 举报

    文明发言,和谐互动
    文明发言,和谐互动
    高级模式
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    简体中文
    繁體中文
    English(英语)
    日本語(日语)
    Deutsch(德语)
    Русский язык(俄语)
    بالعربية(阿拉伯语)
    Türkçe(土耳其语)
    Português(葡萄牙语)
    ภาษาไทย(泰国语)
    한어(朝鲜语/韩语)
    Français(法语)
    关闭

    幸运抽奖

    社区每日抽奖来袭,快来试试你是欧皇还是非酋~

    立即查看

    聊天机器人
    Loading...

    QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

    GMT+8, 2026-8-1 03:42 , Processed in 0.066266 second(s), 51 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表