【问题标题】:How to model complex data如何对复杂数据进行建模
【发布时间】:2011-04-26 05:36:13
【问题描述】:

我必须创建一个模型来存储多个平台上游戏的游戏控制。我很难找到正确的方法。

  1. 不同系统上的控制器按钮不同(Wii、Xbox 360、PS3 有自己特定的控制器按钮。)
  2. 有些游戏实际上是几个游戏打包为一个;这意味着根据正在玩的游戏,单个产品可以有多个控件。
  3. 许多游戏的游戏控制会根据您的游戏内活动(驾驶/步行/飞行等...)而变化
  4. 仅存储按钮功能是不够的,因为大多数游戏都有几个需要组合按钮的特殊动作。

您将如何解决这个问题?老实说,我不知道从哪里开始!

更新:非常感谢大家的周到和非常有帮助的意见。我还没有选择和回答,因为最终决定这个功能不值得努力。再次感谢。

【问题讨论】:

  • 这是一个非常酷的设计问题。 :) 无论如何都要优雅地做这件事!

标签: sql database-design data-modeling


【解决方案1】:

我会试试看的:)

1) 您需要一个系统表

2) 您需要一个用于包的表(对父级的引用可以为空)、一个包含游戏的表以及一个用于将游戏与包链接的表。这确保了一个游戏可以是不同包的一部分。但是,它不允许不同的软件包拥有同一游戏的不同“特殊版本”。但这不是必需的:)

3) 我不确定这是否与 2) 相同,如果不是:参考游戏的表格,如果:请参阅 2)

4) 您需要一个用于引用游戏部分的动作(“序列”)表格,然后您需要一个用于组合键的表格,并引用序列。最后,您需要一个特定键的表,并引用一个组合。

我认为这将涵盖它,尽管我对操纵杆、鼠标等有一些担忧。您可能希望将“键”表拆分为多个表以避免该表中的许多列,但这是您的决定取决于您计划如何访问您的数据库等。

【讨论】:

    【解决方案2】:

    我只是想了一下,但我认为你可以使用这样的东西(我懒得添加 ER 'forks',但顶表引用底表):

    .

    • 按钮 - 是控制器上的按钮,我假设您还需要使用类型来识别这些按钮,以便您可以识别按下、方向、压力等内容...
    • 控制台 - 商店 wii、xbox、...
    • gameplay - 是你所在的关卡,每个关卡都有许多动作(或你喜欢的动作),这些动作最终应该执行一段代码,以在这个游戏关卡中发生一些事情。
    • console-move - 是在特定控制台上执行特定移动的按钮组合。如果你需要在wii而不是xbox上按下按钮组合,那么应该可以

    您可以选择将按钮链接到控制台

    【讨论】:

      【解决方案3】:

      一些控制器共享相同的布局,但具有不同的面,即 360 和 PS3(X 是 A,三角形是 Y,等等)。带有额外的外围设备,如战斗棒、飞行棒、吉他等 - 它们只是映射到控制台期望的不同面孔。由于按钮通常是在任何控制器成型之前定义的,因此您也可以这样做。

      每个映射并非都适用于每个控制器,因此可能并不理想 - 考虑到现代控制台控制器,应该没问题。如果添加 Intellivision 控制器和键盘/鼠标,事情可能会开始变得奇怪。

      // using CHAR(8) for absolutely no good reason. change at will.
      CREATE TABLE button_maps (
      id tinyint unsigned not null auto_increment,
      map_id char(8) not null,
      primary key (id),
      unique key map_id (map_id)
      );
      
      INSERT INTO button_maps (map_id)
      VALUES
      // dual analog, any direction
      ('ANA_LFT'), ('ANA_RT'),
      // 4-button compass face
      ('BT_N'), ('BT_S'), ('BT_E'), ('BT_W'),
      // shoulder buttons
      ('BT_LT1'), ('BT_LT2'), ('BT_RT1'), ('BT_RT2'),
      // system buttons
      ('BT_START'), ('BT_SEL'), ('BT_MENU'),
      // analog stick click-in, usually called "L/R 3"
      ('ANA_L3'), ('ANA_R3'),
      // 8-direction d-pad - add clockface points for both analogs too
      ('DPAD_N'), ('DPAD_S'), ('DPAD_E'), ('DPAD_W'),
      ('DPAD_NW'), ('DPAD_NE'), ('DPAD_SW'), ('DPAD_SE'),
      // and DS stylus so it's not obvious what I'm looking at right now
      ('STL_TAP'), ('STL_DTAP'), ('STL_DRAG'),
      // and so on
      

      注意:我不知道那些全身运动控制的东西是如何在内部处理的,如果你不得不处理它们,祝你好运。 LFOOT_HOKEYPOKEY 什么的。

      注意 2:说真的,不要在那里使用 char(8)。获取详细信息,但要保持足够通用以适用于通用控制器样式而不是品牌。

      现在每个品牌的控制器的按钮及其名称(假设是“控制器”表):

      CREATE TABLE buttons (
      id tinyint unsigned not null auto_increment,
      controller_id tinyint unsigned not null references controllers.id,
      map_id tinyint unsigned not null references button_maps.id,
      button_name varchar(32) not null,
      primary key (id),
      unique key controller_map (controller_id, map_id)
      );
      
      INSERT INTO buttons (controller_id, map_id, button_name)
      VALUES
      (2, 1, 'Left Analog'), (2, 2, 'Right Analog'),
      (2, 3, 'Y'), (2, 4, 'A'), (2, 5, 'B'), (2, 6, 'X'),
      (2, 7, 'Left Trigger (LT)'), (2, 8, 'Right Trigger (RT)'),
      (2, 9, 'Left Bumper (LB)'), (2, 10, 'Right Bumper (RB)')
      // and so on.  PS3 with button shapes and R1/2, L1/2 instead of trigger/bumper
      

      现在,对于一个按钮按下(或多个按钮,或一个序列)代表游戏的动作。这不考虑上下文(原始问题的 2 和 3),例如游戏模式或备用按钮配置,但 Josh Smeaton 和 littlegreen 已经介绍过。

      这定义了每个单独游戏的操作,这不是很有效。通过添加游戏“类型”的通用层,您可能能够显着压缩事物。某种类型/视角中的许多游戏都有共同的控制,而且它只会变得越来越普遍(控制台 FPS 添加了预定义的 Halo 和 CoD 风格的按钮配置,因为玩家知道它们,等等)。因此,如果您可以为每种类型定义一组通用操作,并仅根据需要使用它来覆盖/扩展这些默认值,那么您可能会获得一个更简洁的解决方案。

      首先,定义每个动作:

      CREATE TABLE game_actions (
      id int unsigned not null auto_increment,
      game_id int unsigned not null references games.id,
      action varchar(32) not null,
      primary key (id)
      );
      
      INSERT INTO game_actions (game_id, action)
      VALUES (1, 'Shoot'), (1, 'Reload'), (1, 'Turn Left'), (1, 'Turn Right')
      // and so on
      

      最后,定义与每个操作关联的按钮按下。 “序数”字段用于组合序列,例如格斗游戏组合 - 单个动作是第 0 个序数,序列从 1 开始计数,只是为了使它们易于区分。它不考虑时间,因此对于一些更复杂的组合游戏(Soul Caliber 等),您可能需要一个“无”按钮作为休息。

      CREATE TABLE game_action_buttons (
      id int unsigned not null auto_increment,
      game_action_id int unsigned not null references game_actions.id,
      ordinal tinyint unsigned not null,
      button_map_id tinyint unsigned not null references button_maps.id,
      primary key (id)
      );
      
      INSERT INTO game_action_buttons (game_action_id, ordinal, button_map_id)
      VALUES
      (1, 0, 8), // right trigger to shoot
      (2, 0, 6), // west face button (X/square) to reload
      (3, 0, 7), (3, 0, 9) // combo: both bumpers for rear view look-back while driving
      // and a Street Fighter shoryuken on the d-pad to show a sequence:
      (4, 1, 21), // DPAD_E: right
      (4, 2, 20), // DPAD_S: down
      (4, 3, 26), (4, 3, 4) // DPAD_SE + BT_S: down/right + fierce... i think.
      

      (免责声明:我为我工作的游戏工作室创建了一个类似的数据库。不完全相同,但足够相似,以至于我有意遗漏了很多内容。抱歉!希望这足以启动一些想法,这是一个有趣的问题。)

      【讨论】:

        【解决方案4】:
        
        Console
            int id
            string name
        
        Controller
            int id
            string name
            int console_id fk
        
        Button
            int id
            string name
            int controller_id fk
        
        Game
            int id 
            string name
            int parent_id fk -- game within a game
        
        -- context within a game (default, driving, swimming)
        Context
            int id
            string name
            int game_id fk
        
        -- applicable actions within a context of a game
        Action
            int id
            string name
            id context_id int
        
        -- a set of buttons that map to an action, whether it is one button or multiple
        Combination
            int id
            int action_id fk
            int button_id fk
        

        使用上述结构的一个例子:

        主机:PS3 游戏:MAG ...

        当前游戏状态:
        背景:驾驶
        允许的操作:方向(向前、向左等)、刹车、烟雾
        允许的组合:每个操作的每个组合的列表

        当按下一系列按钮时,例如:L1 + DirectionRight,在允许的组合中查找该组合,找到相关操作,并执行该操作。

        【讨论】:

          【解决方案5】:

          这个怎么样:

          /* PRODUCTS: Each product has one title and runs on one gamesystem */
          (PK) ProductID int
          ProductTitle varchar(100)
          (FK) GameSystemID int
          
          /* GAMES: Each game has one title and belongs to one product */
          (PK) GameID int
          GameTitle varchar(100)
          (FK) ProductID int
          
          /* GAMESYSTEMS: Each gamesystem has one name */
          (PK) GameSystemID int
          GameSystemName varchar(100)
          
          /* GAMEACTIVITIES: Each game has one or more activities (flying, running, ..) */
          (PK) GameActivityID int
          (FK) GameID int
          GameActivityDescription VARCHAR(100)
          
          /* BUTTONS: Each gamesystem has certain buttons with names */
          (PK) ButtonID int
          (FK) GameSystemID int
          ButtonName VARCHAR(100)
          
          /* GAMEACTIONS: Each game activity provides certain game actions (fly left, fly right, ..) */
          (PK) ActionID int
          (FK) GameActivityID int
          ActionDescription VARCHAR(100)
          
          /* BUTTONCOMBINATIONS: Each game action is associated with a certain button or combination of buttons */
          (FK) ActionID int
          (FK) ButtonID int
          

          【讨论】:

            【解决方案6】:

            我会试一试:)


                controller [table] 
            // list of controllers - Wii Mote etc.
                controller_id (int, PK) | title (varchar)
            
                game_buttons [table] 
            // list of buttons on a controller A/B/X/Y/...
                button_id (int, PK) | title (varchar) | controller_id (int, FK)
            
                game [table] 
            // game details - you could, if you want, differentiate the games by console here as well as they may have different titles even though they are similar in nature
                game_id (int, PK) | title (varchar)
            
                controls [table] 
            // this is the main table that will combine the buttons with the games. combo_id is a foreign key to the control_combo table. So if you have a sequence of keys that calls for buttons A and then B, you would call in the same number for combo_id and ord table will tell us in what order they should be placed. If they're not part of a combo, you can leave the default combo_id to 0.
            
                game_id (int, PK) | button_id (int, FK) | title (varchar) | description (text) | combo_id (int) | ord
            
                control_combo [table]
            // control_combo - the master table for button combos
                combo_id (int, PK) | title (varchar) | ord (tinyint)
            

            【讨论】:

              【解决方案7】:

              初学者可以试试这个(编辑:第二次尝试)

              Game
              ----------
              (PK) GameID integer
              GameTitle varchar(100)
              
              Controller
              ----------
              (PK) ControllerID integer
              ControllerDescription varchar(100)
              (FK) GameID integer
              
              Effect
              ----------
              (PK) EffectID integer
              EffectDescription varchar(100)
              (FK) ControllerID integer
              
              Buttons
              ----------
              (PK) ButtonID integer
              ButtonKey varchar(25)
              (FK) EffectID integer
              

              例如:

              GameID  GameTitle
              ----------------------------------------------
              1       Super Mario Bros.
              
              ControllerID ControllerDescription GameID
              ----------------------------------------------
              1            Main Controller       1
              
              EffectID EffectDescription ControllerID
              ----------------------------------------------
              1        Run               1
              2        Jump              1
              3        Pause             1
              4        Move Left         1
              5        Move Right        1
              
              ButtonID ButtonKey      EffectID
              ----------------------------------------------
              1        B              1
              2        Direction Pad  1
              3        A              2
              4        Start          3
              5        Left Pad       4
              6        Right Pad      5
              

              【讨论】:

              • Hrm,有效点——没有考虑到这一点。我已经尝试了第二次,不知道我是否满意。
              • 为了允许复杂的按钮组合,添加一个名为“延迟”的假按钮,表示玩家应该在按下组合按钮之间暂停。也许在按钮表中添加一个“时间”列,以允许“一个按钮必须保持一定时间”的要求。将 OrderNumber 列添加到 Button 表以允许指定应按下的订单按钮。如果要同时按下按钮,请给它们相同的订单号。
              猜你喜欢
              • 2015-12-22
              • 1970-01-01
              • 2013-02-04
              • 1970-01-01
              • 2018-12-07
              • 2020-03-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多