【问题标题】:Event based editor like in StarCraft 2 Editor (algorithm)基于事件的编辑器,如星际争霸 2 编辑器(算法)
【发布时间】:2013-06-30 10:05:59
【问题描述】:

我正在尝试为 event based editor 创建一个算法,例如在星际争霸 2 编辑器中可以支持:

  • 创建用户界面
  • 播放声音
  • 处理键盘/鼠标输入
  • 显示消息
  • 按钮(或一些引用的 UI 对象)被按下等。

与星际争霸 2 编辑器中的内容几乎相同(当然也不是 3D 内容)


到目前为止,我正在考虑使用 JSON ,将每个事件添加到对象中,然后循环遍历它们并使用 addEventListener() 方法创建事件。

JSON 事件对象(当然它会由用户在编辑器中创建,无需编程):

var Events={
    //your event's names here
    onReady:{ //on page ready to manipulate
        displayMessage:{//just a simple popup
            text:"Hello user!",
            title:"Welcome!",
            type:"normal",
            },
        createButton:{ //creates a buton on the screen
            text:"Click me!",
            id:"myButton"
        }
    },
    onClick:{
        id:"myButton" ,//the id of the button we just created
        actions:{ //the actions applied after we click the button
            displayMessage:{//just a simple popup
                text:"You pressed me!",
                title:"Button",
                type:"error",//show the message as an error
            }
        }
    }
}

我发现了一些软件 (GameMaker,Construct 2,GameDevelop),如果你想了解一下我说的是(如果你还不知道星际争霸 2 编辑器)

我的问题是: 我可以使用什么算法来实现这一点?

【问题讨论】:

  • 这样做的问题是你不能将多个回调绑定到 1 个事件,它还会导致大量配置和无休止的缩进级别。

标签: javascript jquery json events editor


【解决方案1】:

听起来像是jQuery UI 的工作。

当用户在您的编辑器中创建自定义区域时,它的所有属性都存储在一个对象中(您可以将其保存为 JSON),然后在加载地图时将其作为参数应用于 div(使用html-attributes

function create_areas(areas){
    var map = $('#map_area');
    for(var i=0;i<areas.length;i++){
        map.append($('<div>', area[i].params));
    }
}

而参数看起来像这样:

params = {
    width: 100,
    height: 200,
    ....
    mousedown: function(){ play_music('hello'); },
    keydown: function(e){ alert('you pressed ' + e.keyCode; }
}

draggableresizeable 这样的 jQuery UI 工具应该可以简化你的编辑器的构建。

【讨论】:

    【解决方案2】:

    我会在主干的事件系统之后对其进行更多建模:

    events: {
      'click selector': handler,
      'mouseover selector': handler2,
      ...
    }
    

    处理程序可以是任何 javascript 函数,这将允许您创建一堆预定义的函数,例如 displayMessage

    然后,您可以 curry 您自己的处理程序,这将允许您的用户在需要时指定配置。

    例子:

    var events = {
       'click element': displayMessage({
            text:"Hello user!",
            title:"Welcome!",
            type:"normal",
        }),
       'mouseover pizza': createButton({...}) 
    }
    
    function displayMessage(options) {
       var options = options;
    
       return function() {
          //display message logic
       }
    }
    

    然后你可以在其他助手中提供一个compose 函数(也许是查找承诺?)将你的函数组合在一起:

    var events = {
       'click element': compose(
            displayMessage({
                text:"Hello user!",
                title:"Welcome!",
                type:"normal",
            }),
            createButton({})
        ),
       'mouseover pizza': createButton({...}) 
    }
    

    这可以解决吗?

    警告:如果 events 是一个包含对象的数组可能会更好。这样你就可以在一些选择器上拥有多个点击处理程序而不会发生冲突。

    【讨论】:

    • 对不起。我忘了说我不想使用框架(1.我不喜欢它们,2.我想从头开始制作一切)
    • @boyd 我不是提倡使用骨干,而是从中汲取灵感。您展示的示例看起来很像主干。
    【解决方案3】:

    在我看来,您确实需要做出多种选择。我会,尽管我更喜欢 JSON 作为数据结构,但我不会将自己局限于实际编程语言的这个子集。反之亦然。

    您有事件、处理程序和选项。其中一个选项,或者更好的选项列表是用户输入的数据,处理程序是实际操作,事件是设置某些操作的触发器。

    如果您仔细阅读本文,您会注意到这是对大多数 jQuery 脚本或事件驱动软件的基本结构的准确描述。只有 jQuery 中的用户选项(因为它是一个 DOM 框架)通常是单个 DOM 元素的上下文。所以,我们到了这里,我建议简单地借用这背后的理论并使用promisses,这是一种非常clear 和生成代码的好方法!

    所以我对任何事件链的调用都是这样的。

    ...when(chainObject['event'])
    .then(function(event) {
          //call handler
          handlers[chainObject[selectedHandler]].call(event.context, chainObject['options']); 
          //apply next element(s) in chain, this is the current promise
          appendNextElement(chainObject['followingHandlers'], this);
    })...
    

    请注意apply 如何让您轻松更改环境,进而根据用户和事件所做的任何处理程序的行为。 Promises 让错误处理变得非常容易!

    这当然只适用于链中的一个节点。那么数据结构应该是什么样子才能让你生成这种代码呢?

    结构中的一个节点如下所示:

       {
          event: 'click',
          selectedHandler: 'sohwText',
          options: {
              'text': 'helloWorld'
          },
          followingChain: {...OTHER HANDLERS....}
       }
    

    需要注意的重要一点是,就像一个良好的结构化函数式程序一样,您正在查看一棵树,而不是查看一个简单的事件列表。所以每个实际的 DOM 元素都包含许多这些

    var eventTree = {
       '.someButton': [..Handlers of this button...],'
       '.someOtherButton': [..Handlers of the other button...],
    }
    

    然后我们开始了。你有一个上下文(按钮)、一个事件、用户输入和一个处理程序。

    生成的应用程序不仅应该可以工作,而且可以为任何有经验的 JavaScript 程序员扩展或修改样式。

    【讨论】:

    • 我很难理解这个“承诺”的东西,因为我没有使用它。你能做一个简单的 jsfiddle:当我点击一个 div 时,将它移动到 500px 顶部,然后 500 px 离开{event:click,element:div,action:moveTo(500,500)} 使用你的算法?
    • 我已经提到了这个承诺,因为它会给你在大多数现代 javascript 库中事件处理背后的中心思想 -> 从而给你掌握你的任务的理论背景。问题是,在您的领域中向您展示一个示例肯定会是您问题的完整解决方案 - 这将意味着相当多的代码行......我将无法很快产生。对不起
    猜你喜欢
    • 1970-01-01
    • 2016-12-21
    • 2023-04-03
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    • 2017-08-29
    • 1970-01-01
    相关资源
    最近更新 更多