基于FPGA的贪吃蛇游戏设计(6)苹果随机生成模块generate_apple

1.块场划分

苹果的大小为1616个像素,和后面要讲的一节蛇身/蛇头是一样的。
在640480的分辨率下,可以看做是40*30的块场,坐标范围为[39:0],[29:0];因为墙壁厚度的原因,苹果可产生的坐标范围为:[38:1],[28:1]。

parameter APPLE_X_MAX = 38 ;
parameter APPLE_Y_MAX = 28 ;

在这里插入图片描述
在这里插入图片描述

2. 随机数产生

根据复位结束开始游戏的总运动时间+一段由蛇的运动情况产生的随机时间 来设计产生新苹果坐标的算法,具有很好的随机性。

//利用加法产生随机数,蛇吃苹果的时刻不同,随机数就不一样,所以给人随机的感觉
//cnt0为苹果x坐标的随机数
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt0 <= 0;
    end
    else if(add_cnt0)begin
        if(end_cnt0)
            cnt0 <= 0;
        else
            cnt0 <= cnt0 + 1;
    end
end

assign  add_cnt0        =       1'b1;
assign  end_cnt0        =       add_cnt0 && cnt0 == APPLE_X_MAX-1;

//cnt1为苹果y坐标的随机数
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        cnt1 <= 0;
    end
    else if(add_cnt1)begin
        if(end_cnt1)
            cnt1 <= 0;
        else
            cnt1 <= cnt1 + 1;
    end
end

assign  add_cnt1        =       1'b1;
assign  end_cnt1        =       add_cnt1 && cnt1 == APPLE_Y_MAX-1;

/*这部分的意思是:复位后cnt3和detection_time设置为1MS并保持,让cnt2开始逐1累加至1MS,
其间end_cnt2保持为0,add_cnt3保持为0,end_cnt3保持为0,
等到cnt2==1MS-1了,end_cnt2和add_cnt3拉高一个脉冲,cnt3自加20赋给新的detection_time(1MS+20)
以此类推,直到detection_time超过5MS,这点时间里苹果生成稍微有一点点滞后,但不妨碍观感
后面只要(end_cnt2 && head_x == apple_x && head_y == apple_y)
则将此时的计时(cnt0,cnt1)赋给(apple_x,apple_y)用以生成新的苹果
*/
//cnt2
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt2 <= 0;
    end
    else if(add_cnt2)begin
        if(end_cnt2)
            cnt2 <= 0;
        else
            cnt2 <= cnt2 + 1;
    end
end

assign  add_cnt2        =       1'b1;
assign  end_cnt2        =       add_cnt2 && cnt2 == detection_time-1; 

//cnt3范围在1ms到5ms之间,为的就是让苹果产生的地址更加随机一点,这部分不太好理解,但也比较重要
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt3 <= TIME_1MS;
    end
    else if(add_cnt3)begin
        if(end_cnt3)
            cnt3 <= TIME_1MS;
        else
            cnt3 <= cnt3 + 20;
    end
end

assign  add_cnt3        =       end_cnt2;       
assign  end_cnt3        =       add_cnt3 && cnt3 >= TIME_5MS-1;
assign  detection_time  =       cnt3;

//apple_x,apple_y 
//当蛇头吃到苹果时,就将随机产生一个新的苹果坐标
always  @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        apple_x <=  6'd10;//苹果默认出现的位置
        apple_y <=  5'd13;
    end
    else if(end_cnt2 && head_x == apple_x && head_y == apple_y)begin
        apple_x <=  cnt0 + 1;//墙的厚度为1个苹果宽度
        apple_y <=  cnt1 + 1;
    end
end

/*这部分的意思是:复位后cnt3和detection_time设置为1MS并保持,让cnt2开始逐1累加至1MS,
其间end_cnt2保持为0,add_cnt3保持为0,end_cnt3保持为0,
等到cnt2==1MS-1了,end_cnt2和add_cnt3拉高一个脉冲,cnt3自加20赋给新的detection_time(1MS+20)
以此类推,直到detection_time超过5MS,这点时间里苹果生成稍微有一点点滞后,但不妨碍观感
后面只要(end_cnt2 && head_x == apple_x && head_y == apple_y),则将此时的计时(cnt0,cnt1)赋给(apple_x,apple_y)用以生成新的苹果

也可以采用伪随机码生成器来实现
https://blog.csdn.net/limanjihe/article/details/52400969?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-1
如果追求完美可以使用M序列、Gold序列等近乎完全随机的序列

最后是吃到苹果后下一个上升沿立刻生成标志信号让蛇身加长,即flag_body_add


//flag_body_add
always  @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        flag_body_add   <=  1'b0;
    end
    else if(end_cnt2 && head_x == apple_x && head_y == apple_y)begin
        flag_body_add   <=  1'b1;
    end
    else begin
        flag_body_add   <=  1'b0;
    end
end
  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值