基于事件的编辑器,如星际争霸2编辑器(算法)

时间:2013-06-30 10:06:00

标签: javascript jquery json events editor

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

  • 创建用户界面
  • 播放声音
  • 处理键盘/鼠标输入
  • 显示消息
  • 按下按钮(或某些引用的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
            }
        }
    }
}

我找到了一些GameMakerConstruct 2GameDevelop的软件,如果你有 event based editor 我想知道我在说什么(如果你还不知道星际争霸2编辑器)

我的问题是: 我可以用来实现此目的的最佳算法是什么?

3 个答案:

答案 0 :(得分:5)

听起来像是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看起来像这样:

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

jQuery UI工具(如draggableresizeable)也可以轻松构建您的编辑器。

答案 1 :(得分:3)

我会在骨干事件系统之后对此进行更多建模:

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

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

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

示例:

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({...}) 
}

这可能有用吗?

警告:如果事件是包含对象的数组可能会更好。这样,您可以在某些选择器上使用多个单击处理程序而不会发生冲突。

答案 2 :(得分:3)

我看到这种方式,你需要做出几个选择。我愿意,虽然我更喜欢JSON作为数据结构而不是限制自己使用这种实际编程语言的子集。反过来说,这是另一种方式。

您有活动,处理程序和选项。如果选项或更好的选项列表是用户输入数据,则处理程序是实际操作,事件是触发器以设置某些操作。

如果您仔细阅读,您会发现这是对大多数jQuery-Scripts或事件驱动软件的基本结构的准确描述。只有jQuery中的用户选项(因为它是一个DOM框架)通常是单个DOM-Element的上下文。所以,我们在这里,我建议简单地借用这背后的理论,并利用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如何让您根据用户和事件的内容轻松更改环境以及任何hanlder的行为。并且promisses使错误处理变得非常容易!

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

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

   {
      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程序员进行扩展或修改。