Python命令行小游戏—贪吃蛇

  • 前言
  • 一、贪吃蛇游戏初始界面及地图
    • 1.游戏初始界面
    • 2.游戏地图
  • 二、命令符的设置、输出刷新和按键检测
    • 1.库支持
    • 2.c语言代码
    • 3.Python代码(变量初始化及游戏初始化)
  • 三、蛇的移动
  • 四、蛇的方向控制
  • 五、食物的设置
  • 六、游戏结束
  • 七、主程序
  • 八、演示效果
  • 总结

前言

为了初步学习Python更有兴趣,决定做个学编程大多都会做的小游戏—贪吃蛇,因为是刚刚开始学习,不足之处,希望大家多多指正。


一、贪吃蛇游戏初始界面及地图

1.游戏初始界面

def mune():os.system("color 0a")dll.set_cmd(0, 2);print("□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□")dll.set_cmd(0, 3);print("□□□□□■■■■□□□□□□□贪吃蛇□□□□□□□□□■□□□    操作指南    □□□□")#7dll.set_cmd(0, 4);print("□□□□■■□□■■□□□□□□□□□□□□□□□□□□■□□□方向键  改变方向□□□□")#5dll.set_cmd(0, 5);print("□□□■■□□□□□□□□□□2021.05.06□□□□□□□□■□□□ESC     退出游戏□□□□□□")dll.set_cmd(0, 6);print("□□□□■■□□□□□□□□□□□□□□□□□□□□□□■□□□SPACE   暂停游戏□□□□□□□□□")dll.set_cmd(0, 7);print("□□□□□■■■■□□□□■■■■□□□□■■■□□□□■□□■■□□□□■■■■■□□")dll.set_cmd(0, 8);print("□■□□□□□■■■□□■□□□□■□□■□□□■□□□■■□□□□□□■□□□□□■□")dll.set_cmd(0, 9);print("□□■□□□□□■■■□■□□□□■□■□□□□■□□□■■□□□□□■□□■■■■□□")dll.set_cmd(0,10);print("□□□■■□□■■■□□■□□□□■□□■□□■□■□□■□■□□□□□■□□□□□□□")dll.set_cmd(0,11);print("□□□□■■■■□□□□■□□□□■□□□■■□□■■□■□□■■■□□□■■■■■□□")#24dll.set_cmd(0,12);print("□□□□□□□□□□□□□□□□□□按空格开始游戏□□□□□□□□□□□□□□□□□□□")

这里使用了os库ctypes库以及调用的.dll自建动态库,第二节会详细说明

2.游戏地图

def wall(x,y):#绘制围墙i=0;j=0while i<=x:print('■',end="")for j in range(y):if i==0:print('■', end="")elif i==20:print('■', end="")else:print("  ",end="")j+=1print('■')i+=1j=0

简单的使用Python的输出函数print()做一个围墙,默认情况下函数内的 end=“/n”

二、命令符的设置、输出刷新和按键检测

1.库支持

  • os库中的os.system(“命令行指令”) 函数可执行命令行中的指令,具体指令可在命令行中输入help回车获得相关信息
  • c语言能够更好的对命令行的输出进行刷新,这里通过调用.dll的方式调用c语言,具体的使用可观看此视频python和C语言混合编程

2.c语言代码

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>
//命令行光标显示(1)隐藏(0)
_declspec(dllexport) void _stdcall init_cmd(int x)
{HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息CursorInfo.bVisible = x; //控制台光标状态,x=1显示,x=0隐藏SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态
}
//命令行光标移动函数
_declspec(dllexport) void _stdcall set_cmd(int x, int y)
{COORD pos;pos.X = x;pos.Y = y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
//获取键盘输入
_declspec(dllexport) int _stdcall c_getch()
{int key;if (_kbhit()) {//_kbhit()为按键检测,有按键输出1,没有输出0key = _getch();Sleep(10);return key;}else;}

3.Python代码(变量初始化及游戏初始化)

import os,time,ctypes,randomwall_x,wall_y ,eat_flag= 20,21,1
move_up,move_down,move_left,move_right,esc,space = 72,80,75,77,27,32def init_game():#游戏界面初始化global getkey, key, snake_x, snake_y, snake_list#全局变量声明os.system("mode con cols=48 lines=22")  # 设置命令符窗口大小os.system("cls")os.system("color 2b")  # 设置字体和背景颜色wall(wall_x, wall_y)  # 绘制围墙dll.set_cmd(0, 1)print("■□□□□○")snake_list = [[2, 1], [4, 1], [6, 1], [8, 1], [10, 1]]snake_x, snake_y ,getkey,key= 10, 1,0,0
def init():#命令符及游戏初始化ctypes.windll.kernel32.SetConsoleTitleW("贪吃蛇")  # 修改命令符标题os.system("mode con cols=88 lines=15")  # 设置命令符窗口大小dll.init_cmd(0)  # 设置光标状态

当定义函数内有全局变量的值发生变化时,需要进行全局变量声明

三、蛇的移动

def snake_move(*lis):#蛇移动dll.set_cmd(snake_list[0][0], snake_list[0][1])print("  ")snake_list.append(lis[0])if eat_flag==0:snake_list.pop(0)dll.set_cmd(snake_list[-1][0], snake_list[-1][1])print("○")n = 0for n in range(len(snake_list)-2):dll.set_cmd(snake_list[-2-n][0], snake_list[-2-n][1])print("□")n += 1
def move():#蛇移动防倒走global snake_x, snake_yif [snake_x, snake_y] in snake_list[-2:]:snake_x = snake_list[-1][0]snake_y = snake_list[-1][1]else:snake_move([snake_x, snake_y])
  • 蛇的身体的每个小块对应列表内的一个坐标,头的位置处于列表最后一项
  • 当移动时消除第一个坐标所在的位置,使用pop(0)方法弹出第一项
  • 将下一个头的位置(由 snake_ctrl 函数提供)使用append()方法添加到列表最后
  • 通过检测位置坐标(x in y)是否为靠近头的一段来防止蛇倒走。

四、蛇的方向控制

def get_key():#获得键盘输入global getkey,keya = dll.c_getch()if a in [esc,space]:getkey = aif a in [move_up,move_down,move_left,move_right]:if ((key == move_up) and (a != move_down))or ((key == move_down) and (a != move_up)) \or(key == 0) or((key == move_left) and (a != move_right)) \or ((key == move_right) and (a != move_left)):key = aelse:passelse:pass
def snake_ctrl():#根据键盘输入判断方向已经功能操作global getkey, key, snake_x, snake_yif key == move_down:snake_y += 1elif key == move_up:snake_y -= 1elif key == move_right:snake_x += 2elif key == move_left:snake_x -= 2else:passif getkey == space:time.sleep(1)getkey = 0while 1:getkey = dll.c_getch()if getkey == space:getkey = 0breakelif getkey == esc:breakelse:passelse:pass

检测按键输入 get_key() 以及设置相应按键实现的功能 snake_ctrl()

五、食物的设置

def putfood():#放置食物global food_x,food_y,eat_flagif eat_flag==1:food_x = snake_xfood_y = snake_ywhile [food_x,food_y] in snake_list:food_x = random.randint(1, 20) * 2food_y = random.randint(1, 19)eat_flag = 0dll.set_cmd(food_x,food_y)print("●")else :pass
def eatfood():#吃掉食物判断global eat_flag,snake_list,snake_x, snake_yif ([food_x,food_y] in snake_list)and(eat_flag==0) :eat_flag = 1else:pass

不得不说Python中成员判断真的很好用。

  • 通过食物坐标点点是否已经包含到蛇身体的列表中来判断是否吃到食物
  • 食物的产生通过随机函数(random.randint(x,y))来提供坐标
  • 是否放置食物由是否吃掉的标志(eat_flag)来判断

六、游戏结束

def gameover():#游戏结束判断if (snake_x>42)|(snake_y>19)\|(snake_x<2)|(snake_y==0):return 1elif snake_list.count(snake_list[-1])>1:return 1else :return 0
def over_next():#结束后的操作global getkey,eat_flagif gameover():dll.set_cmd(16, 9)print("得分:{}分".format(len(snake_list)-5))dll.set_cmd(6, 10)print("游戏结束,esc退出,space重新开始")while 1:getkey = dll.c_getch()if getkey == esc:os.system("cls")dll.init_cmd(1)os.system("exit")breakelif getkey == space:init_game()eat_flag = 1breakelse:passelse:pass
  • 贪吃蛇撞墙的判断就简单粗暴的坐标判断,如果地图复杂可能需要使用列表将每部分墙体的起始坐标录入进行判断,贪吃蛇只需要判断头的位置就能够判断是否撞到了墙。
  • 使用列表的count方法能够很简单的判断序列中有没有两相同的元素,来检测蛇有没有吃到自己。

七、主程序

if __name__ == '__main__':#主函数maindll = ctypes.windll.LoadLibrary("set_cmd.dll")  # 调用c语言程序init()mune()while 1:getkey = dll.c_getch()if getkey == space:breakelse:passinit_game()while 1:get_key()putfood()eatfood()snake_ctrl()move()over_next()if getkey == esc:os.system("cls")dll.init_cmd(1)os.system("exit")breakelse:passget_key()time.sleep(0.15)
  • 通过两次按键 get_key() 检测来减少按键的检测缺失
  • 可以通过调整循环等待时间 time.sleep(0.15) 来调整游戏内蛇的速度

八、演示效果

生成.exe文件需要用到pyinstaller,没有的话需要进行以下步骤

  1. 运行命令符输入 pip install pyinstaller
  2. 等待安装完成,输入 pyinstaller -F xxx.py (文件位置)

以下是演示效果


评价:能玩

总结

虽然最后成品比较简陋,但还是有些成就感的,比之前光看书感觉效率提高很多。
下面是所有文件的网盘链接点击下载
提取码:6v5o


Python命令行小游戏—贪吃蛇相关推荐

  1. python界面小游戏贪吃蛇_用Python实现童年小游戏贪吃蛇

    贪吃蛇作为一款经典小游戏,早在 1976 年就面世了,我最早接触它还是在家长的诺基亚手机中. 尽管贪吃蛇的历史相对比较久远,但它却有着十分顽强的生命力,保持经久不衰,其中很重要的原因便是游戏厂家不断的 ...

  2. python 贪吃蛇 turtle_关于python:用Python实现童年小游戏贪吃蛇

    贪吃蛇作为一款经典小游戏,早在 1976 年就面世了,我最早接触它还是在家长的诺基亚手机中. 只管贪吃蛇的历史绝对比拟长远,但它却有着非常倔强的生命力,放弃经久不衰,其中很重要的起因便是游戏厂家一直的 ...

  3. 不会吧?不会吧?还有人不知道用Python实现 童年小游戏贪吃蛇 吗

    源码在Python白嫖q群:733089476 获取. 贪吃蛇作为一款经典小游戏,早在 1976 年就面世了,我最早接触它还是在家长的诺基亚手机中. 尽管贪吃蛇的历史相对比较久远,但它却有着十分顽强的 ...

  4. 用pygame做一个简单的python小游戏---贪吃蛇

    用pygame做一个简单的python小游戏-贪吃蛇 贪吃蛇游戏博客链接:(方法一样,语言不一样) c++贪吃蛇:https://blog.csdn.net/weixin_46791942/artic ...

  5. 【python小游戏】用python写一款小游戏--贪吃蛇

    大家好,我是爱吃饼干的小白鼠,今天给大家分享一款自制小游戏.如何用python编写贪吃蛇. 今天,突发奇想的想用python写一款小游戏--贪吃蛇.相信大家都玩过,那么玩一款自己写的是一种什么样的体验 ...

  6. Java经典小游戏——贪吃蛇简单实现(附源码)

    文章目录 一.使用知识 二.使用工具 三.开发过程 3.1素材准备 3.2 开发过程 3.2.1 创建项目 3.2.2 页面设计 3.23 画蛇 3.24创建蛇的食物 3.2.5增加蛇的存活状态 3. ...

  7. JAVA课程设计(小游戏贪吃蛇)完整源码附素材(二)

    目录 JAVA课程设计(小游戏贪吃蛇)完整源码附素材(一) JAVA课程设计(小游戏贪吃蛇)完整源码附素材(二) JAVA课程设计(小游戏贪吃蛇)完整源码附素材(三) 前言 1. 任务描述 1.1  ...

  8. GUI编程详解:小游戏贪吃蛇

    GUI编程 1.简介 Gui的核心技术:Swing.AWT 界面不美观 需要jre环境 为什么要学习? 可以写出自己想要的小工具 工作时候,也可能需要维护到swing界面 了解MVC架构,了解监听 ( ...

  9. 做一个简单的java小游戏--贪吃蛇

    做一个简单的java小游戏–贪吃蛇 贪吃蛇游戏博客链接:(方法一样,语言不一样) c++贪吃蛇:https://blog.csdn.net/weixin_46791942/article/detail ...

最新文章

  1. java基础--日期--练习集锦
  2. python多线程代码_Python多线程代码求改错
  3. clear session on close of browser jsp
  4. 编写高质量代码改善C#程序的157个建议——建议127:用形容词组给接口命名
  5. Funny:还是程序猿会玩——弹幕炸天学AI和区块链,玩起来!弹慕君,你也值得拥有!
  6. 一维的Haar小波变换
  7. CiberCut_5.6 标牌制作
  8. [css] 如何解决IE6浮动时产生双倍边距的BUG?
  9. centos7 复制移动删除
  10. Dart 1(环境安装)
  11. 今天执行grep命令差点把服务器搞崩
  12. ssh密钥登录 改密码登录_如何使用密钥对通过SSH登录而不使用密码
  13. kafka面试题简答
  14. GitLab community edition
  15. 结合element-ui封装的一个分页函数
  16. spring学习笔记二(基于注解)
  17. 认识每一个“你”:微博中的用户模型
  18. 小程序、APP、企业网站开发工具有哪些?如何使用软件开发工具?
  19. 工业互联网与高端装备健康管理解决方案
  20. 支付宝面试:什么是序列化,怎么序列化,为什么序列化,反序列化会遇到什么问题,如何解决?...

热门文章

  1. 微信 @chatroom 信息:
  2. 孪生质数——孤独的质数
  3. Kali应用——(一)信息收集
  4. The server time zone value '?й???????' is unrecognized or represents more than one time zone
  5. 好用的自定义Okhttp日志拦截器
  6. 电脑磁盘使用率很容易100%的解决办法
  7. Console线的对应关系
  8. javaFx 通过fxml自定义界面,实现桌面侧边悬浮工具栏
  9. 移动端调试神器——vconsole
  10. K8s secret配置