mda*_*ani 0 matlab character keypress
我正在用 Matlab 制作游戏(一种太空入侵者射击游戏)图形都在一个图形上,只是用多个情节生成,我知道 matlab 不适合这些东西,这使得向同学们展示特别有趣。对于我目前使用的关键输入:
f = figure(1)
set(f, 'KeyPressFcn', @(x,y)disp(get(f,'CurrentCharacter')));
a = get(f,'CurrentCharacter');
if a=='w' %move up..
if a=='d' %move right..
if a=='2' %switch to weapon 2..
Run Code Online (Sandbox Code Playgroud)
这工作得很好,但每次按下一个键时,它都会显示在控制台上,导致不必要的延迟。
我试过:
f = figure(1)
set(f, 'KeyPressFcn');
a = get(f,'CurrentCharacter');
Run Code Online (Sandbox Code Playgroud)
但每次按下一个键时它都会显示“字符串 - 或 - 函数句柄 - 或 - 单元格数组”。
如何识别按键并将其存储到变量中而不在控制台上弹出任何内容?我也希望不必创建第二个功能,因为目前所有内容都干净地保存在一个 .m 文件中。
谢谢!
小智 5
作为 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
Run Code Online (Sandbox Code Playgroud)
请注意,回调使用“字典”键名来消除对任何 if-else 子句的需要。这样,无论使用多少个按键以及它们的实际用途如何,这两个功能都可以插入任何游戏而无需任何修改。
要了解这个想法在现实生活中是如何运作的,您可以在 MATLAB Central 上查看我的游戏:
http://www.mathworks.com/matlabcentral/fileexchange/authors/111235
那里有一款太空射击游戏“Stellaria”。不过是在我不知道嵌套函数的那天写的,所以代码被拆分成很多小的函数文件,可能很难阅读。请谨慎使用。
| 归档时间: |
|
| 查看次数: |
4571 次 |
| 最近记录: |