作为 MATLAB Central 上一些流行游戏的作者,我可以告诉您如何在 MATLAB 中正确执行此操作。我不能保证我的方法不是最优化的,但这是我多年思考这个问题后得出的最佳解决方案。首先,我在编写游戏时通常遵循一些原则:
使用“CurrentKey”代替“CurrentCharacter”,因为前者可以识别更多未被归类为“字符”的键。
您可能还需要“KeyReleaseFcn”,因为这是射击游戏。通常您希望飞行器在按住按键时保持飞行,在松开按键时停止;您不想重复按下和释放一个键以使飞机继续移动。它的工作原理是:当玩家按下'w'时,我们调用一次KeyPressedFcn,其中我们将标志变量'w_status'设置为true;当播放器释放'w'时,调用一次KeyReleasedFcn,并将标志设置为flase。在游戏的主循环中,反复检查'w_status'是否为真。如果是,则将飞行器上移一步,否则不更新位置。
如果要将所有内容保存在一个文件中,请尝试将 KeyPressFcn 和 KeyReleaseFcn 实现为 嵌套 函数。这比把所有的代码都压缩到一个单行里要好。
避免在 if-else 子句中使用硬编码的键名。您稍后可能希望允许用户重新分配键,因此最好将键名称保留在一个数组中,您可以对其进行修改。
所以整个游戏会是这样的:
function MainGame()
KeyStatus = false(1,6); % Suppose you are using 6 keys in the game
KeyNames = {'w', 'a','s', 'd', 'j', 'k'};
KEY.UP = 1;
KEY.DOWN = 2;
KEY.LEFT = 3;
KEY.RIGHT = 4;
KEY.BULLET = 5;
KEY.BOMB = 6;
...
gameWin = figure(..., 'KeyPressFcn', @MyKeyDown, 'KeyReleaseFcn', @MyKeyUp)
...
% Main game loop
while GameNotOver
if KeyStatus(KEY.UP) % If left key is pressed
player.y = player.y - ystep;
end
if KeyStatus(KEY.LEFT) % If left key is pressed
player.x = player.x - xstep;
end
if KeyStatus(KEY.RIGHT) % If left key is pressed
%..
end
%...
end
% Nested callbacks...
function MyKeyDown(hObject, event, handles)
key = get(hObject,'CurrentKey');
% e.g., If 'd' and 'j' are already held down, and key == 's'is
% pressed now
% then KeyStatus == [0, 0, 0, 1, 1, 0] initially
% strcmp(key, KeyNames) -> [0, 0, 1, 0, 0, 0, 0]
% strcmp(key, KeyNames) | KeyStatus -> [0, 0, 1, 1, 1, 0]
KeyStatus = (strcmp(key, KeyNames) | KeyStatus);
end
function MyKeyUp(hObject, event, handles)
key = get(hObject,'CurrentKey');
% e.g., If 'd', 'j' and 's' are already held down, and key == 's'is
% released now
% then KeyStatus == [0, 0, 1, 1, 1, 0] initially
% strcmp(key, KeyNames) -> [0, 0, 1, 0, 0, 0]
% ~strcmp(key, KeyNames) -> [1, 1, 0, 1, 1, 1]
% ~strcmp(key, KeyNames) & KeyStatus -> [0, 0, 0, 1, 1, 0]
KeyStatus = (~strcmp(key, KeyNames) & KeyStatus);
end
end
请注意,回调使用“字典”键名来消除对任何 if-else 子句的需要。这样,无论使用多少个按键,以及它们的实际用途如何,这两个功能都可以插入到任何游戏中而无需任何修改。
要了解这个想法在现实生活中如何发挥作用,您可以在 MATLAB Central 上查看我的游戏:
http://www.mathworks.com/matlabcentral/fileexchange/authors/111235
那里有一款太空射击游戏“Stellaria”。但是,它是在我不知道嵌套函数的时候写的,所以代码被分割成许多小的函数文件,可能很难阅读。请谨慎使用。