基于FPGA的“低级马里奥”游戏设计

一、简述游戏功能

流程1:游戏开始时,即在复位状态下,马里奥向左走;

流程2:在向左走的过程中,可能会发生碰撞,若发生碰撞转为向右走;

流程3:向右走过程中,也可能会发生碰撞,若发生碰撞转为向左走;

流程4:向左走过程中,可能遇到地面空洞,掉下去的话,马里奥被惊吓,大喊“啊!!!”,若在20个时钟周期内,马里奥继续下降。若超过20个时钟周期,马里奥进入生死判决时刻,若地面恢复,马里奥将回不到地面,处于死亡状态,game over,否则,地面恢复,马里奥可以继续向左走。

流程5:同理,向右走过程中,可能遇到地面空洞,掉下去的话,马里奥被惊吓,大喊“啊!!!”,若在20个时钟周期内,马里奥将继续下降。若超过20个时钟周期,马里奥进入生死判决时刻,若地面恢复,马里奥将回不到地面,处于死亡状态,game over,否则,地面恢复,马里奥可以继续向右走。

流程6:此外,马里奥还有挖洞的技能:若向左走的途中挖洞,可能会挖到空洞,马里奥再次被惊吓,大喊“啊!!!”,同时与流程3内容一致。若向右走的途中挖洞,可能会挖到空洞,马里奥再次被惊吓,大喊“啊!!!”,同时与流程4内容一致。

二、状态解读

根据游戏功能,可解读为八个状态,分别为:

Left:向左走

Right:向右走

Dig_left:向左挖洞

Dig_right:向右挖洞

Fall_left:向左走的过程中掉到洞中

Fall_right:向右走的过程中掉到洞中

SP:生死判决时刻

Dead:死亡状态

三、程序源码

module top_module(
    input clk,
    input areset,    // 复位信号,初始状态为向左走
    input bump_left, //向左走发生碰撞
    input bump_right,//向右走发生碰撞
    input ground,    //地面 0:空洞
    input dig,       //是否挖洞
    output walk_left,//向左走
    output walk_right,//向右走
    output aaah,      //大喊“啊!!!”
    output digging ); //正在挖洞
    
    //先来定义8个状态
    parameter 
    Left = 8'b0000_0001,
    Right = 8'b0000_0010,
    Dig_left = 8'b0000_0100,
    Dig_right = 8'b0000_1000,
    Fall_left = 8'b0001_0000,
    Fall_right = 8'b0010_0000,
    SP = 8'b0100_0000,
    Dead = 8'b1000_0000;//掉到坑里,时间长,且地面被封上,死了
    
    //定义用于存储状态的寄存器变量
    reg [7:0] state,next_state;
    reg [4:0] count;
    
    //先来定义一个计数器,用于计算掉到坑里的时间
    initial 
    count = 5'b1;//因为要计算20个周期,所以计数器的位宽定义5位够用了
    always@(posedge clk or posedge areset)//产生要计数的计数器
        begin
            if(areset)
                count <= 5'b1;
            else if((next_state == Fall_left)||(next_state == Fall_right))
                count <= count + 1'b1;
            else
                count <= 5'b1;
        end
    
    //第一个块用于描述状态的初始状态,可以使得将下一状态跳转到当前状态
    always@(posedge clk or posedge areset)
        begin
            if(areset)
                state <= Left;
            else
                state <= next_state;
        end
    
    //第二个块用来描述状态之间的转移
    always@(*)
        begin
            case(state)
                Left:begin
                    if(ground == 1'b0)
                        next_state = Fall_left;
                    else if(dig == 1'b1)
                        next_state = Dig_left;
                    else if(bump_left)
                        next_state = Right;
                    else
                        next_state = Left;
                end
                Right:begin
                    if(ground == 1'b0)
                        next_state = Fall_right;
                    else if(dig == 1'b1)
                        next_state = Dig_right;
                    else if(bump_right == 1'b1)
                        next_state = Left;
                    else
                        next_state = Right;
                end
                Dig_left:begin
                    if(ground == 1'b0)
                        next_state = Fall_left;
                    else
                        next_state = Dig_left;
                end
                Dig_right:begin
                    if(ground == 1'b0)
                        next_state = Fall_right;
                    else
                        next_state = Dig_right;
                end
                Fall_left:begin
                    if((ground == 1'b0)&&(count <= 5'd20))
                        next_state = Fall_left;
                    else if((ground == 1'b0)&&(count > 5'd20))//进入下一个撞击判断状态,如果地面恢复了,则将撞死
                        next_state = SP;
                    else
                        next_state = Left;
                end
                Fall_right:begin
                    if((ground == 1'b0)&&(count <= 5'd20))
                        next_state = Fall_right;
                    else if((ground == 1'b0)&&(count > 5'd20))//进入下一个撞击判断状态,如果地面恢复了,则将撞死
                        next_state = SP;
                    else
                        next_state = Right;
                end                
                SP:begin  //终极判决状态
                    if(ground == 1'b1)
                        next_state = Dead;
                    else
                        next_state = SP;
                    
                	end
                Dead:begin
                    next_state = Dead;
                end
                default:state = 8'bxxxxxxxx;
            endcase
        end
    
    //输出情况
    assign walk_left = (state == Left);
    assign walk_right = (state == Right);
    assign aaah = ((state == Fall_left)||(state == Fall_right)||(state == SP));
    assign digging = ((state == Dig_left)||(state == Dig_right));
    
endmodule

四、仿真波形

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值