如何对复杂数据进行建模

9
我需要创建一个模型来存储多个平台上的游戏玩法控制。但我在寻找正确的方法时遇到了一些困难。
  • 不同的系统有不同的控制器按钮(Wii、Xbox 360、PS3都有各自特定的控制器按钮)。
  • 一些游戏实际上是几个游戏打包在一起的;这意味着单个产品可能根据所玩游戏而有几个不同的控制器按钮组合。
  • 很多游戏的游戏玩法控制会根据您在游戏中的活动而改变(驾驶/步行/飞行等)。
  • 仅存储按钮功能是不够的,因为大多数游戏需要按组合键才能进行多个特殊动作。
您会如何解决这个问题?说实话,我不知道从哪里开始!
更新:非常感谢大家的深思熟虑和非常有用的意见。最终我们决定这个特性不值得花费过多精力。再次感谢。

1
这绝对是一个很酷的设计问题。:) 无论如何,优雅地解决它! - Matt
7个回答

2
一些控制器具有相同的布局但面部不同,例如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)。要详细,但保持足够通用以适用于通用控制器风格,而非品牌。
现在每个控制器品牌的按钮及其名称(假设有一个“controllers”表):
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.

(免责声明:我曾为一家游戏工作室创建过类似的数据库。虽然不完全相同,但足够相似以至于我有意留下了很多细节。抱歉!希望这些足以启发您的灵感,这是一个有趣的问题。)


1
你可以先尝试这个(编辑:第二次尝试)
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

嗯,有道理--我没有考虑到那一点。我尝试了第二次,不确定是否满意。 - LittleBobbyTables - Au Revoir
为了允许复杂的按钮组合,添加一个名为“延迟”的虚拟按钮,表示玩家在连击中按下按钮之间应该暂停。可能需要在按钮表中添加“时间”列,以满足“必须长时间按住一个按钮”的要求。在按钮表中添加一个OrderNumber列,以便指定按下按钮的顺序。如果要同时按下多个按钮,请给它们相同的顺序号。 - ulty4life

1

我会试一试 :)


    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)

1
这样怎么样:
/* 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

1

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,请在允许的组合中查找该组合,找到相关操作,并执行该操作。


1

我只是简单地考虑了一下,但我认为你可以使用类似这样的东西(我懒得添加ER“分支”,但顶部表引用底部表):

data model.

  • 按钮 - 是控制器上的一个按钮,我认为您需要通过类型来识别它们,以便您可以识别按下、方向、压力等信息...
  • 游戏机 - 存储Wii、Xbox等...
  • 游戏玩法 - 是您所在的关卡,每个关卡都有一定数量的移动(或操作,如果您愿意),这些操作最终应该执行一段代码,以使得在此游戏关卡中发生某些事情。
  • 控制台移动 - 是在特定游戏机上执行某个动作的按钮组合。如果您需要在Wii上按下按钮组合而不是在Xbox上,则应该是可能的。

可选地,您可以将按钮链接到游戏机。


1

我来试一试 :)

1)您需要一个系统表

2)您需要一个软件包表(具有对父级的可空引用),一个游戏表和一个将游戏与软件包连接起来的表。这确保了游戏可以成为不同软件包的一部分。但它不允许不同的软件包具有相同游戏的“特殊版本”。但这不是必需的 :)

3)如果不是,您需要一个带有对游戏的引用的表,如果是,则请参见2)

4)您需要一个具有对游戏部分的引用的操作(“序列”)表,然后您需要一个具有对序列的引用的键组合表。最后,您需要一个对组合的引用的特定键表。

我认为这样就可以了,尽管我对操纵杆、鼠标等有一些担忧。您可能需要将“键”表拆分为几个表,以避免该表中有太多列,但这取决于您计划如何访问数据库等决定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接