Matlab实现贪吃蛇小游戏

1.创建游戏窗口

首先,我们需要创建一个窗口来显示游戏界面,可以使用figure函数创建一个图形窗口:

figure('Name', 'Snake Game', 'Units', 'normalized', 'OuterPosition', [0.2 0.2 0.6 0.6], ... 'MenuBar', 'none', 'NumberTitle', 'off', 'Resize', 'off');

其中,Name为窗口标题,Units为窗口单位(normalized表示窗口大小与屏幕比例一致),OuterPosition为窗口位置和大小(这里设为占屏幕60%宽和高,位于屏幕中间),MenuBar为菜单栏(这里不需要,设为none),NumberTitle为窗口标题是否显示数字(不需要,设为off),Resize为窗口是否可缩放(不需要,设为off)。

2.初始化游戏数据

接下来,我们需要初始化一些游戏数据,如蛇的初始位置、长度、方向等。为了方便处理,我们可以用一个结构体来存储这些数据:

snake.head = [5,5]; % 蛇头位置

snake.body = [5,4]; % 蛇身位置

snake.tail = [5,3]; % 蛇尾位置

snake.length = 3; % 蛇的长度 s

nake.direction = 'right'; % 蛇的前进方向

这里我们将蛇头位置设为(5,5),蛇身位置设为(5,4),蛇尾位置设为(5,3),蛇的长度设为3,蛇的前进方向设为右侧。

另外,我们还需要初始化食物的位置,以及游戏结束的标志:

food.position = [randi(20), randi(20)]; % 食物位置随机生成

game_over = false; % 游戏结束标志

3.绘制游戏界面

接下来,我们要在窗口中绘制游戏界面,包括蛇和食物,可以使用rectangle函数绘制矩形:

% 绘制蛇头

snake_head = rectangle('Position', [snake.head-0.5, 1, 1], 'Curvature', [1,1], 'FaceColor', 'r');

% 绘制蛇身

snake_body = rectangle('Position', [snake.body-0.5, 1, 1], 'Curvature', [1,1], 'FaceColor', 'g');

% 绘制蛇尾

snake_tail = rectangle('Position', [snake.tail-0.5, 1, 1], 'Curvature', [1,1], 'FaceColor', 'y');

% 绘制食物

food_item = rectangle('Position', [food.position-0.5, 1, 1], 'Curvature', [1,1], 'FaceColor', 'b');

这里蛇头、蛇身、蛇尾和食物都是一个正方形矩形,其位置和大小都可以通过Position参数来控制。其中,Curvature为矩形四个角的曲率,[1,1]表示圆形,即绘制圆形矩形。

4.监听键盘事件

然后,我们需要监听键盘事件,根据用户按键改变蛇的前进方向,可以使用KeyPressFcn属性来实现:

set(gcf, 'KeyPressFcn', @change_direction);

其中,gcf表示当前窗口,@change_direction表示回调函数名(需要定义一个change_direction函数来接收键盘事件并改变蛇的方向)。

具体实现如下:

function change_direction(~, event)

switch event.Key

case 'uparrow'

if ~strcmp(snake.direction, 'down') snake.direction = 'up';

end

case 'downarrow'

if ~strcmp(snake.direction, 'up') snake.direction = 'down';

end

case 'leftarrow'

if ~strcmp(snake.direction, 'right') snake.direction = 'left';

end

case 'rightarrow'

if ~strcmp(snake.direction, 'left') snake.direction = 'right';

end

end

end

这个函数接收两个参数,第一个参数是不用管的(因为我们不需要使用它),第二个参数是键盘事件,其中event.Key表示按下的键名(如'uparrow'表示上箭头键)。

根据不同的键名,我们可以改变蛇的前进方向。例如,如果按下了'uparrow'键,且当前蛇的方向不是向下,则将蛇的方向改为向上。

5.实现游戏循环

接下来,我们需要实现一个游戏循环,不断更新蛇和食物的位置,并检测游戏结束条件。可以使用while循环来实现:

while ~game_over

% 移动蛇

move_snake();

% 检测游戏是否结束

game_over = is_game_over();

% 更新窗口显示

update_window();

% 等待一段时间,控制游戏速度

pause(0.1);

end

在循环内部,我们依次调用了三个函数:

  • move_snake函数用于根据当前方向移动蛇的位置;
  • is_game_over函数用于检测游戏是否结束;
  • update_window函数用于更新窗口中蛇和食物的位置。

其中,pause(0.1)语句用于等待一段时间,控制游戏速度。

6.实现移动蛇的函数

接下来,我们需要实现move_snake函数来移动蛇的位置。具体实现如下:

function move_snake()

% 根据当前方向移动蛇头

switch snake.direction

case 'up'

snake.head = snake.head + [-1, 0];

case 'down'

snake.head = snake.head + [1, 0];

case 'left'

snake.head = snake.head + [0, -1];

case 'right'

snake.head = snake.head + [0, 1];

end

% 更新蛇身和蛇尾位置

snake.body = [snake.head; snake.body(1:end-1,:)];

snake.tail = snake.body(end,:);

end

这个函数首先根据当前方向移动蛇头的位置,然后更新蛇身和蛇尾的位置。具体来说,我们将蛇头位置加上一个向量,该向量表示当前方向的移动方向。例如,如果当前方向是向上,则将蛇头的行坐标减1,列坐标不变。

接着,我们将蛇身的第一段替换为新的蛇头位置,将蛇尾设置为蛇身的最后一段位置。

7.实现检测游戏是否结束的函数

接下来,我们需要实现is_game_over函数来检测游戏是否结束。具体实现如下:

function game_over = is_game_over()

% 检测是否碰到边界

if any(snake.head < 1) || any(snake.head > 20) game_over = true; return;

end

% 检测是否碰到自己的身体

if any(all(bsxfun(@eq, snake.body, snake.head), 2)) game_over = true; return;

end

% 检测是否吃到食物

if all(snake.head == food.position) game_over = false;

% 更新蛇的长度和食物的位置

snake.length = snake.length + 1;

[food.position(1), food.position(2)] = find(flipud(~ismember(ones(20),[snake.head; snake.body]),1));

return;

end game_over = false;

end

这个函数首先检测蛇是否碰到了边界,如果是则游戏结束。如果蛇头的行坐标或列坐标小于1或大于20,则表示撞到了边界。

接着,我们检测蛇是否碰到了自己的身体。使用bsxfun函数来比较蛇身的每一段是否与蛇头重合。如果有,则表示蛇头碰到了自己的身体,游戏结束。

最后,我们检测是否吃到了食物。如果蛇头的位置与食物位置重合,则表示吃到了食物,游戏继续进行。此时需要更新蛇的长度和食物的位置。蛇的长度加1,食物的位置随机生成(不能在蛇的身体部分)。

8.实现更新窗口显示的函数

接下来,我们需要实现update_window函数来更新窗口中蛇和食物的位置。具体实现如下:

function update_window()

% 更新蛇头位置

set(snake_head, 'Position', [snake.head-0.5, 1, 1]);

% 更新蛇身位置

set(snake_body, 'Position', [snake.body-0.5, 1, 1]);

% 更新蛇尾位置

set(snake_tail, 'Position', [snake.tail-0.5, 1, 1]);

% 更新食物位置

set(food_item, 'Position', [food.position-0.5, 1, 1]);

% 重绘窗口

drawnow;

end

这个函数首先通过set函数更新各个矩形的位置。注意,位置需要减去0.5才能正确显示,因为矩形的中心点坐标为整数(如(1,1)),而不是左上角坐标。然后利用drawnow函数重绘窗口。

  • 6
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值