cmd代码玩贪吃蛇_Simulink玩转贪吃蛇

本文介绍了如何利用S-Function在Simulink中实现贪吃蛇游戏。通过Level-1 S-Function实现游戏,探讨了游戏制作的难点,如键盘识别,并分享了解决思路。游戏改进部分提出利用定时器提高用户体验,同时讨论了S-Function在该案例中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

681c2ffd4ac18c02417ba40cf98f3baa.png

利用S-Function,在simulink中实现了贪吃蛇。

前言

先看看实现的效果吧。

fe50182a63a43731ceff7f2b5a84c145.png
simulink实现贪吃蛇游戏https://www.zhihu.com/video/1218961016639741952

从视频中可以看到,仿真开始后,贪吃蛇开始运动,这是S-Function在发挥作用。

原谅我游戏画面的制作太过敷衍之后,也算得上是S-Function的又一个成功的应用范例了。

关于S-Function,前面已经花了两篇文章进行阐述举例。

土人:S-Function 实现红绿灯''实时仿真''​zhuanlan.zhihu.com
ba6e3bfec24f80b865632c4a2796faf2.png
土人:Unit Delay and his brothers​zhuanlan.zhihu.com
fc7d865d684e2c6e2050a1b20c178d44.png

上述两篇文章,均使用了Level-1 S-Function,其好处是简单,容易掌握,适合入门,可以调用matlab函数,对于基本的需求应该是够用了。比如这篇,我首先用level-2 S-Function实现了该游戏,后来又用Level-1 S-Function进行了实现,效果一样。但是,不得不指出,相比于Level-2 S-Function,Level-1 S-Function有很多缺陷,比如仅仅支持单个输入输出端口(port),虽然单个端口可以包含多个信号,然而信号不支持多维度;仅支持double数据类型,也就没必要支持代码生成了;不支持DWork向量等等。如果你觉得Level-1 S-Function可能无法助你实现你的策略,可以考虑转向Level-2 S-Function。

游戏制作几点总结:

1,游戏难点

游戏制作中大部分心血并非是码了200多行代码,而花在了比较关键性的地方,比如simulink对键盘的识别。

玩贪吃蛇游戏,需要四个方向,up/down/left/right,当按下键盘时,如何保证simulink识别到方向操控信息呢?

一度被这个问题难倒了。

去google上搜索,发现一种方案是,需要先创建一个figure,然后利用这个figure识别键盘输入。想了想,加入figure后,游戏画面太难看,一点也不简洁,就没有考虑采纳。记不清在google上搜索了几个小时了,无意间搜到了一段代码,对其稍加改动,我觉得很好用,如下所示:

function key=keyboard_check  
    % key=1 means left ;key=2 means up ;key=3 means right ;key=4 means down
    NET.addAssembly('PresentationCore');
    akey = System.Windows.Input.Key.A; %use any key to get the enum type
    keys = System.Enum.GetValues(akey.GetType);  %get all members of enumeration
    %keynames = cell(System.Enum.GetNames(akey.GetType))';%right 32 Down 33 Up 31 Left30
    iskeyvalid = true(4, 1);
    iskeydown  = false(4, 1);
    for keyidx = 1:4
       try
           iskeydown(keyidx) = System.Windows.Input.Keyboard.IsKeyDown(keys(keyidx+29));
       catch
           iskeyvalid(keyidx) = false;
       end
    end
    if iskeydown(1)==1
        key=1;
    elseif iskeydown(2)==1
        key=2;
    elseif iskeydown(3)==1
        key=3;
    elseif iskeydown(4)==1
        key=4;
    else
        key=0;
    end 
end

2,游戏思路

游戏思路应该很简单了。主要就是利用了set_param和get_param这对好兄弟。

控制贪吃蛇关键在于控制蛇头,而控制蛇头,在于实现转弯。

其实不用管蛇身拐了几个弯啊,蛇头控制好了,那么第二节跟随蛇头就好了,第三节跟随第二节就好了.......对,就是用前一个模块上一个时间步长时位置更新当前时刻后一个模块位置。

3, 游戏改进

使用S-Function的缺陷是,必须在simulink仿真时才能执行,然而仿真进行中,无法使用add_block 向simulink中添加模块。所以,你可以注意到上一个视频左下角,我在初始化的时候,已经添加了一部分的outport模块。这就带来一个问题,如果添加模块较多,可能会导致初始化过程很慢,最终导致游戏体检变差。

后来想到了可以利用定时器timer,定时调用贪吃蛇函数。这样就可以避免上述问题。

mytimer = timer('TimerFcn','GreedySnakeForTimer',...
'StartDelay',0.2,'Period',0.01,'TasksToExecute',50000,'ExecutionMode','fixedSpacing');
start(mytimer);%开启定时器

那么模型不用开启仿真,游戏就可以跑起来了。看下画面,是不是简约了一些呢。

c66312f6af6772f9d4b8020e48fa256e.png
利用定时器timer改进游戏https://www.zhihu.com/video/1219683621747081216

4,总结

这个例子,其实并不是用来说明S-Function有多强大,其实S-Function在这个例子中只是一个“空壳”或者"晶振"罢了,控制算法和S-Function没有什么关系。但是很多时候,就是需要利用S-Function这层壳帮我们做一些事情。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值