当前位置: 首页 > news >正文

easyx图形库基础4:贪吃蛇

贪吃蛇

  • 一实现贪吃蛇:
    • 1.绘制网格:
    • 1.绘制蛇:
    • 3.控制蛇的默认移动向右:
    • 4.控制蛇的移动方向:
    • 5.生成食物
    • 6.判断蛇吃到食物并且长大。
    • 7.判断游戏结束:
    • 8.重置函数:
  • 二整体代码:

一实现贪吃蛇:

1.绘制网格:

请添加图片描述

#define wide 800
#define high 600#define Frame 20//1.绘制边框
void DrawFrame()
{setlinecolor(BLACK);setlinestyle(PS_SOLID, 1);for (int i = 1; i < wide / Frame; i++){line(Frame * i, 0, Frame * i, 600);}for (int i = 1; i < high / Frame; i++){line(0, Frame * i,800 , Frame * i);}
}

1.绘制蛇:

请添加图片描述

int main()
{initgraph(wide,high);setbkcolor(RGB(188, 227, 245));cleardevice();//初始化蛇的长度int length = 5;//初始化蛇的坐标:sn snake[5] = { {7,6} ,{6,6}, {5,6},{4,6},{3,6} };while (1){cleardevice();BeginBatchDraw();//1.绘制边框DrawFrame();//2.绘制蛇DrawSnake(snake,length);FlushBatchDraw();Sleep(40);}EndBatchDraw();getchar();closegraph();return 0;
}
//2.绘制蛇
void DrawSnake(sn* snake,int length)
{setfillcolor(GREEN);for (int i = 0; i < length; i++){//先绘制头int x1 = snake[i].x;int y1 = snake[i].y;solidrectangle(x1 * Frame, y1 * Frame, (x1 + 1) * Frame, (y1 + 1) * Frame);}
}

3.控制蛇的默认移动向右:

请添加图片描述

void SnakeMove(sn* snake, int length)
{//默认蛇一开始是一直向右移动的;sn newsnake = { (snake->x)+1,(snake->y)};//2.绘制蛇DrawSnake(snake, length);FlushBatchDraw();//进行蛇的移动;for (int i = length - 1; i >= 1; i--){snake[i] = snake[i - 1];}snake[0] = newsnake;
}

4.控制蛇的移动方向:

void SnakeMove(sn* snake, int length,int* vx,int* vy)
{//默认蛇一开始是一直向右移动的;//2.绘制蛇DrawSnake(snake, length);FlushBatchDraw();//进行蛇的移动;if (_kbhit()){char ch = _getch();//蛇是不可以直接走回头路的:switch (ch){case'A':case'a':if (*vx == 1 && vy == 0)break;*vx = -1;*vy = 0;break;case'W':case'w':if (*vx == 0 && *vy == 1)break;*vx = 0;*vy = -1;break;case'D':case'd':if (*vx == -1 && *vy == 0)break;*vx = 1;*vy = 0;break;case'S':case's':if (*vx == 0 && *vy == -1)break;*vx = 0;*vy = 1;break;}}//控制蛇节点变化sn newsnake = { (snake->x)+(*vx) ,(snake->y)+(*vy)};for (int i = length - 1; i >= 1; i--){snake[i] = snake[i - 1];}snake[0] = newsnake;
}

5.生成食物

1.食物不可以生成到画布的外面;
2.不可以生成在蛇的身体上面;
3.食物是随机生成的;

//4.生成食物:
void DrawFeeFood(sn* snake, int length, FD* food)
{		int fx = 0;int fy = 0;int flag = 0;while (1){//食物坐标的随机生成:food->x = rand() % (wide / Frame);food->y= rand() % (high / Frame);//2.不可以生成在蛇的身体上面,遍历蛇的身体。for (int i = 0; i < length; i++){if (((food->x) == (snake[i].x)) && ((food->y) == (snake[i].y))){flag++;}}if (flag == 0){break;}}
}
//3.控制蛇的移动
void SnakeMove(sn* snake, int length,FD* food,int* vx,int* vy)
{//默认蛇一开始是一直向右移动的;//2.绘制蛇DrawSnake(snake, length);//2.绘制食物:if (food->x == 0 && food->y == 0){DrawFeeFood(snake, length, food);}setfillcolor(YELLOW);solidrectangle((food->x) * Frame, (food->y) * Frame, (food->x+1) * Frame, (food->y+1) * Frame);FlushBatchDraw();//进行蛇的移动;if (_kbhit()){char ch = _getch();//蛇是不可以直接走回头路的:switch (ch){case'A':case'a':if (*vx == 1 && vy == 0)break;*vx = -1;*vy = 0;break;case'W':case'w':if (*vx == 0 && *vy == 1)break;*vx = 0;*vy = -1;break;case'D':case'd':if (*vx == -1 && *vy == 0)break;*vx = 1;*vy = 0;break;case'S':case's':if (*vx == 0 && *vy == -1)break;*vx = 0;*vy = 1;break;}}//控制蛇节点变化sn newsnake = { (snake->x)+(*vx) ,(snake->y)+(*vy)};for (int i = length - 1; i >= 1; i--){snake[i] = snake[i - 1];}snake[0] = newsnake;
}

6.判断蛇吃到食物并且长大。

请添加图片描述

//3.控制蛇的移动
void SnakeMove(sn* snake, int* length,FD* food,int* vx,int* vy)
{//默认蛇一开始是一直向右移动的;//2.绘制蛇DrawSnake(snake, *length);//3.绘制食物:if (food->x == 0 && food->y == 0){DrawFeeFood(snake, length, food);}setfillcolor(YELLOW);solidrectangle((food->x) * Frame, (food->y) * Frame, (food->x+1) * Frame, (food->y+1) * Frame);FlushBatchDraw();//进行蛇的移动;if (_kbhit()){char ch = _getch();//蛇是不可以直接走回头路的:switch (ch){case'A':case'a':if (*vx == 1 && vy == 0)break;*vx = -1;*vy = 0;break;case'W':case'w':if (*vx == 0 && *vy == 1)break;*vx = 0;*vy = -1;break;case'D':case'd':if (*vx == -1 && *vy == 0)break;*vx = 1;*vy = 0;break;case'S':case's':if (*vx == 0 && *vy == -1)break;*vx = 0;*vy = 1;break;}}//控制蛇节点变化sn newsnake = { (snake->x)+(*vx) ,(snake->y)+(*vy)};for (int i = *length - 1; i >= 1; i--){snake[i] = snake[i - 1];}snake[0] = newsnake;//判断蛇是否吃到了食物和生长:Grow(snake, length, food);
}
void Grow(sn* snake, int* length, FD* food)
{//保存一下尾的数值sn end = snake[(*length) - 1];if ((snake[0].x == food->x) && (snake[0].y == food->y)){//重置食物数值food->x = 0;food->y = 0;//添加尾节点;*length = (*length) + 1;snake[*length] = end;}
}

7.判断游戏结束:

1.蛇头碰到墙壁:
2.蛇头碰到蛇身体:

//5.判断游戏结束
bool Gameover(sn* snake, int* length)
{//1.碰到墙壁if ((snake[0].x >= wide / Frame) || (snake[0].x < 0) || (snake[0].y >= high / Frame) || (snake[0].y < 0)){return true;}else{//2.碰到身体for (int i = 1; i < (*length); i++){if (((snake[0].x)==(snake[i].x))&&((snake[0].y) == (snake[i].y)))return true;}}return false;
}

8.重置函数:

//初始化函数
void initgame(int* length,int* vx,int* vy,sn* snake,FD* food)
{//初始化蛇的长度*length = 5;//初始化蛇的水平初始速度*vx = 1;*vy = 0;//初始化蛇的坐标:snake[0] = { 7,6 };snake[0] = { 6,6 };snake[0] = { 5,6 };snake[0] = { 4,6 };snake[0] = { 3,6 };//初始化食物的坐标;*food = { 0,0 };
}

二整体代码:

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>
#include<easyx.h>
#include<math.h>
#include<stdbool.h>
#include<conio.h>
#include<time.h>#define wide 800
#define high 600
#define Frame 20typedef struct snake {int x;int y;
}sn;
typedef struct Food {int x;int y;
}FD;
//1.绘制边框
void DrawFrame()
{setlinecolor(BLACK);setlinestyle(PS_SOLID, 1);for (int i = 1; i < wide / Frame; i++){line(Frame * i, 0, Frame * i, 600);}for (int i = 1; i < high / Frame; i++){line(0, Frame * i,800 , Frame * i);}
}//2.绘制蛇
void DrawSnake(sn* snake,int length)
{setfillcolor(GREEN);for (int i = 0; i < length; i++){//先绘制头int x1 = snake[i].x;int y1 = snake[i].y;solidrectangle(x1 * Frame, y1 * Frame, (x1 + 1) * Frame, (y1 + 1) * Frame);}
}//3.生成食物:
void DrawFeeFood(sn* snake, int *length, FD* food)
{		int fx = 0;int fy = 0;int flag = 0;while (1){//食物坐标的随机生成:food->x = rand() % (wide / Frame);food->y= rand() % (high / Frame);//2.不可以生成在蛇的身体上面,遍历蛇的身体。for (int i = 0; i < *length; i++){if (((food->x) == (snake[i].x)) && ((food->y) == (snake[i].y))){flag++;}}if (flag == 0){break;}}
}//4判断蛇吃到食物并且长大。
void Grow(sn* snake, int* length, FD* food)
{//保存一下尾的数值sn end = snake[(*length) - 1];if ((snake[0].x == food->x) && (snake[0].y == food->y)){//重置食物数值food->x = 0;food->y = 0;//添加尾节点;*length = (*length) + 1;snake[*length] = end;}
}//初始化函数
void initgame(int* length,int* vx,int* vy,sn* snake,FD* food)
{//初始化蛇的长度*length = 5;//初始化蛇的水平初始速度*vx = 1;*vy = 0;//初始化蛇的坐标:snake[0] = { 7,6 };snake[0] = { 6,6 };snake[0] = { 5,6 };snake[0] = { 4,6 };snake[0] = { 3,6 };//初始化食物的坐标;*food = { 0,0 };
}
//5.判断游戏结束
bool Gameover(sn* snake, int* length)
{//1.碰到墙壁if ((snake[0].x >= wide / Frame) || (snake[0].x < 0) || (snake[0].y >= high / Frame) || (snake[0].y < 0)){return true;}else{//2.碰到身体for (int i = 1; i < (*length); i++){if (((snake[0].x)==(snake[i].x))&&((snake[0].y) == (snake[i].y)))return true;}}return false;
}//6.控制蛇的移动
void SnakeMove(sn* snake, int* length,FD* food,int* vx,int* vy)
{//默认蛇一开始是一直向右移动的;//2.绘制蛇DrawSnake(snake, *length);//3.绘制食物:if (food->x == 0 && food->y == 0){DrawFeeFood(snake, length, food);}setfillcolor(YELLOW);solidrectangle((food->x) * Frame, (food->y) * Frame, (food->x+1) * Frame, (food->y+1) * Frame);FlushBatchDraw();//进行蛇的移动;if (_kbhit()){char ch = _getch();//蛇是不可以直接走回头路的:switch (ch){case'A':case'a':if (*vx == 1 && vy == 0)break;*vx = -1;*vy = 0;break;case'W':case'w':if (*vx == 0 && *vy == 1)break;*vx = 0;*vy = -1;break;case'D':case'd':if (*vx == -1 && *vy == 0)break;*vx = 1;*vy = 0;break;case'S':case's':if (*vx == 0 && *vy == -1)break;*vx = 0;*vy = 1;break;}}//控制蛇节点变化sn newsnake = { (snake->x)+(*vx) ,(snake->y)+(*vy)};for (int i = *length - 1; i >= 1; i--){snake[i] = snake[i - 1];}snake[0] = newsnake;//判断蛇是否吃到了食物和生长:Grow(snake, length, food);//判断蛇是否碰到了墙壁和自己if (Gameover(snake, length)){initgame(length, vx, vy, snake, food);//Sleep(100);}}int main()
{initgraph(wide,high);setbkcolor(RGB(188, 227, 245));//获取当前时间作为随机数种子:srand((unsigned int)time(NULL));cleardevice();//初始化蛇的长度int length = 5;//初始化蛇的水平初始速度int vx = 1;int vy = 0;//初始化蛇的坐标:sn snake[100] = { {7,6} ,{6,6}, {5,6},{4,6},{3,6} };//初始化食物的坐标;FD food = {0,0};while (1){cleardevice();BeginBatchDraw();//1.绘制边框DrawFrame();//2.控制蛇的移动和节点的变化;SnakeMove(snake, &length,&food,&vx,&vy);Sleep(150);}EndBatchDraw();getchar();closegraph();return 0;
}

相关文章:

easyx图形库基础4:贪吃蛇

贪吃蛇 一实现贪吃蛇&#xff1a;1.绘制网格&#xff1a;1.绘制蛇&#xff1a;3.控制蛇的默认移动向右&#xff1a;4.控制蛇的移动方向&#xff1a;5.生成食物6.判断蛇吃到食物并且长大。7.判断游戏结束&#xff1a;8.重置函数&#xff1a; 二整体代码&#xff1a; 一实现贪吃蛇…...

哈夫曼树(赫夫曼树、最优树)详解

目录 哈夫曼树&#xff08;赫夫曼树、最优树&#xff09;详解 哈夫曼树相关的几个名词 什么是哈夫曼树 构建哈夫曼树的过程 哈弗曼树中结点结构 构建哈弗曼树的算法实现 哈夫曼树&#xff08;赫夫曼树、最优树&#xff09;详解 哈夫曼树相关的几个名词 路径&#xff1a;…...

智慧建筑工地平台,通过信息化技术、物联网、人工智能技术,实现对施工全过程的实时监控、数据分析、智能管理和优化调控

智慧工地是指通过信息化技术、物联网、人工智能技术等手段&#xff0c;对建筑工地进行数字化、智能化、网络化升级&#xff0c;实现对施工全过程的实时监控、数据分析、智能管理和优化调控。智慧工地的建设可以提高工地的安全性、效率性和质量&#xff0c;降低施工成本&#xf…...

Springboot 实践(8)springboot集成Oauth2.0授权包,对接spring security接口

此文之前&#xff0c;项目已经添加了数据库DAO服务接口、资源访问目录、以及数据访问的html页面&#xff0c;同时项目集成了spring security&#xff0c;并替换了登录授权页面&#xff1b;但是&#xff0c;系统用户存储代码之中&#xff0c;而且只注册了admin和user两个用户。在…...

OpenCV-Python中的图像处理-GrabCut算法交互式前景提取

OpenCV-Python中的图像处理-GrabCut算法交互式前景提取 Python-OpenCV中的图像处理-GrabCut算法交互式前景提取 Python-OpenCV中的图像处理-GrabCut算法交互式前景提取 cv2.grabCut(img: Mat, mask: typing.Optional[Mat], rect, bgdModel, fgdModel, iterCount, mode…) img…...

leetcode原题 后继者:找出二叉搜索树中指定节点的“下一个”节点

题目&#xff1a; 设计一个算法&#xff0c;找出二叉搜索树中指定节点的“下一个”节点&#xff08;也即中序后继&#xff09;。 如果指定节点没有对应的“下一个”节点&#xff0c;则返回null。 示例&#xff1a; 输入: root [2,1,3], p 1 2 / \ 1 3 输出: 2 解题思路…...

pyqt5 QlineEdit 如何设置只能输入数字

在 PyQt&#xff08;Python中的一个GUI库&#xff09;中&#xff0c;可以使用QLineEdit小部件的setValidator()方法来限制用户输入的内容。要让QLineEdit只能输入数字&#xff0c;你可以使用QIntValidator或QDoubleValidator。下面是一个示例代码&#xff0c;展示如何设置只能输…...

ubuntu中安装python

最简单方便的是 apt 使用第三方的 ppa 源&#xff0c;然后直接 apt 安装 python3.9 安装 software-properties-common 获取add-apt-repository命令&#xff1a;apt install -y software-properties-common添加第三方的 ppa 源&#xff1a;add-apt-repository ppa:deadsnakes/p…...

LeetCode150道面试经典题-- 快乐数(简单)

1.题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1&am…...

科研论文配图----第一章笔记

第一章笔记 科研论文的绘制基础 科研论文配图的分类与构成 根据呈现方式&#xff0c;科研论文配图可分为线性图、灰度图、照片彩图和综合配图 4 种类型。 其中&#xff0c;线性图是主要和常用的配图类型&#xff0c;也是本书重点介绍的配图类型。 科研论文配图的格式和尺寸 格…...

OpenHarmony Meetup 广州站 OpenHarmony正当时—技术开源

招募令 OpenHarmony Meetup 广州站 火热招募中&#xff0c;等待激情四射的开发者&#xff0c;线下参与OpenHarmonyMeetup线下交流 展示前沿技术、探讨未来可能、让你了解更多专属OpenHarmony的魅力 线下参与&#xff0c;先到先得,仅限20个名额&#xff01; 报名截止时间8月23日…...

如何使用PHP Smarty模板实现静态页面生成

首先&#xff0c;你需要从Smarty官网下载这个神奇的文件。然后&#xff0c;你需要在你的PHP文件中引入Smarty类。就像这样&#xff1a; require_once(Smarty.class.php);现在&#xff0c;我们要创建一个Smarty实例。这就像打开一个新的文件&#xff0c;只不过这个文件是可以和…...

【 Cocos Creator 项目实战】益智游戏《2048》(附带完整源码工程)

本文乃Siliphen原创&#xff0c;转载请注明出处 目录 游戏介绍 概述 游戏整体流程 游戏框架设计 主要流程控制类 本文项目的代码组织结构 构建游戏世界 数字方块 地图 触摸手势识别 防触摸抖动 判断用户输入的方向 地图 任意大小的地图 初始化地图大小 地图绘制…...

剑指Offer68-II.二叉树的最近公共祖先 C++

1、题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表示为一个结点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以…...

【JAVA】我们该如何规避代码中可能出现的错误?(一)

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️初识JAVA】 文章目录 前言三种类型的异常异常处理JAVA内置异常类Exception 类的层次 前言 异常是程序中的一些错误&#xff0c;但并不是所有的错误都是异常&#xff0c;并且错误有时候是可以避免的&…...

openLayers实战(八):坐标系及其转换

坐标系介绍 EPSG: 3857 --web地图&#xff0c;基于球体的、web墨卡托投影&#xff08;伪墨卡托投影Pseudo-Mercator&#xff09;的投影坐标系&#xff0c;范围为纬度85度以下&#xff0c;由于google地图最先使用而成为事实标准。至今&#xff0c;大多互联网地图都使用EPSG3857&…...

DAY06_SpringBoot—简介基础配置yaml多环境开发配置整合第三方技术

目录 一 SpringBoot简介1. 入门案例问题导入1.1 入门案例开发步骤1.2 基于SpringBoot官网创建项目1.3 SpringBoot项目快速启动 2. SpringBoot概述问题导入2.1 起步依赖2.2 辅助功能 二 基础配置1. 配置文件格式问题导入1.1 修改服务器端口1.2 自动提示功能消失解决方案1.3 Spri…...

无涯教程-Perl - setpwent函数

描述 此功能将枚举设置(或重置)到密码条目集的开头。应该在第一次调用getpwent之前调用此函数。 语法 以下是此函数的简单语法- setpwent返回值 此函数不返回任何值。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perlwhile(($name, $passwd, $uid, $gid, $quota, …...

代码随想录-数组篇

2-二分查找 方法一&#xff1a; 左闭右闭&#xff0c;[left, right] class Solution { public:int search(vector<int>& nums, int target) {//[left, right]int left 0;int right nums.size() - 1 ;while(left < right){int middle left ((right - left)…...

vue3+element-plus表格默认排序default-sort失效问题

场景 在使用动态数据渲染的场景&#xff0c;el-table设置默认属性default-sort失效。 原因 el-table的default-sort属性是针对静态数据的&#xff0c;如果是动态数据&#xff0c;default-sort则无法监听到。 案例&#xff1a;静态数据 <template><el-table:data&…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...