如何对复杂数据建模

发布于 2024-09-27 20:55:41 字数 391 浏览 6 评论 0原文

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

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

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

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

I have to create a model that stores gameplay controls for games on several platforms. I am having trouble finding the right approach.

  1. Controller buttons are different on different systems (Wii, Xbox 360, PS3 have their own specific controller buttons.)
  2. Some games are actually several games packaged as one; this means a single product can have several controls depending on the game being played.
  3. Gameplay controls for many games change depending on your in-game activity (driving/walking/flying, etc...)
  4. It's not sufficient to just store button functions since most games have several special moves that require a combination of buttons.

How would you approach this problem? Honestly, I don't know where to start!

Update: Many thanks to everyone for your thoughtful, and very helpful input. I am yet to choose and answer because, in the end, it was decided that this feature is not worth the effort. Many thanks again.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

南风起 2024-10-04 20:55:41

一些控制器共享共同的布局,但具有不同的面,即 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 Calibre 等)。

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.

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

Some controllers share common layouts but with different faces, i.e. 360 and PS3 (X is A, triangle is Y, etc). With extra peripherals like fight sticks, flight sticks, guitars, etc - they're just different faces mapping to the console's expectations as well. Since the buttons are usually defined before any controller is even molded, you can do the same.

Each mapping won't all apply to every controller, so it may not be ideal - considering modern console controllers, it should be fine. If you add in Intellivision controllers and keyboard/mouse, things might start to get weird.

// 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

Note: I have no clue how those full-body motion control things are handled internally, good luck if you ever have to deal with them. LFOOT_HOKEYPOKEY or something.

Note 2: Seriously, don't use a char(8) there. Get detailed, but keep it general enough to apply to a generic controller style and not brand.

Now the buttons per each brand of controller, with their name (assumes a "controllers" table):

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

Now, for the actions a button press (or multiple buttons, or a sequence) represents to a game. This doesn't account for the context (2 & 3 of the original question), e.g. game mode or alternate button configurations, but Josh Smeaton and littlegreen already covered that.

This defines actions per each individual game, which isn't very efficient. You might be able to condense things significantly by adding a generic layer of game "types." Many games within a certain genre/perspective have common controls, and it's only becoming more common (console FPSes adding predefined Halo and CoD-style button configurations since players know them, and such). So, if you can define a set of common actions per each genre and use this only to override/extend those defaults as needed, you might be able to pull off a much cleaner solution.

First, define each action:

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

And finally, define the button presses associated with each action. The "ordinal" field is for combo sequences, like fighting game combos - single actions are 0th ordinal and sequences count up from 1, just to make them easy to differentiate. It doesn't account for timing, so you might need a "nothing" button as a rest for some of the more complex combo games (Soul Caliber et al).

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.

(Disclaimer: I created a similar database for a game studio I worked at. Not quite the same, but similar enough that I'm kind of intentionally leaving a lot out. Sorry! Hopefully that's enough to kickstart some ideas though, and it's a fun problem.)

意中人 2024-10-04 20:55:41

对于初学者,您可以尝试一下(编辑:第二次尝试)

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

You can try this for starters (EDIT: second try):

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

For example:

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
童话里做英雄 2024-10-04 20:55:41

我会尝试一下:)


    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)

I'll give this a whirl :)


    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)
幻梦 2024-10-04 20:55:41

这个怎么样:

/* 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

How about this:

/* 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
戴着白色围巾的女孩 2024-10-04 20:55:41

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


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

An example of using the above structure:

Console: PS3
Game: MAG
...

Current Game State:
Context: Driving
Allowed Actions: Directionals (forward, left etc), Brake, Smoke
Allowed Combinations: List of each combination for each action

When a series of buttons are pressed, eg: L1 + DirectionRight, look up that combination in allowed combinations, find the relevant action, and execute that action.

舞袖。长 2024-10-04 20:55:41

我只简单思考一下,但我认为你可以使用这样的东西(我懒得添加 ER“叉子”,但顶部表格引用底部表格):

数据模型

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

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

I only give it a short thought but I think you can use something like this (I was to lazy to add ER 'forks' but top table references bottom table(s)):

data model.

  • button - is a button on a controller, I assume you need to identify these also with a type so you could identify things like pressed, direction, pressure etc...
  • consle - stores wii, xbox, ...
  • gameplay - is the level your in and each level has a number of moves (or actions if you prefer) these actions should execute a piece of code in the end to make something happen in this game level.
  • console-move - is the combination of buttons to execute a certain move on a specific console. If you need to press a button combination in the wii and not on the xbox, then should be possible

optionally you could link button to console

人│生佛魔见 2024-10-04 20:55:41

我会尝试一下:)

1)您需要一个系统表

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

3) 我不确定这是否与 2) 相同,如果不是:一个引用游戏的表格,如果:参见 2)

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

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

I'll give it a try :)

1) You'll need a table for systems

2) You'll need a table for packages (with a nullable reference to a parent), a table with games and a table to link games with packages. This ensures that a game can be part of different packages. It's not allowing different packages to have different "specialversions" of the same game, though. But that wasn't a requirement :)

3) I'm not sure if this is the same as 2), if not: a table with a reference to a game, if: see 2)

4) You'll need a table for an action ("sequence") with a reference to a gamepart, then you'll need a table for a key-combination, with a reference to the sequence. Finally, you'll need a table for a particular key, with a reference to a combination.

I think this will cover it, though I have som concerns regarding joysticks, mouse etc. You might want to split the "key"-table into several tables to avoid to many columns in that table, but that's a decision you have to take depending on how you are planning to access your database etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文