Python贪吃蛇小游戏_Python贪吃蛇代码

Python贪吃蛇小游戏_Python贪吃蛇代码Python命令行小游戏—贪吃蛇前言一、贪吃蛇游戏初始界面及地图1.游戏初始界面2.游戏地图二、命令符的设置、输出刷新和按键检测1.库支持2.c语言代码3.Python代码(变量初始化及游戏初始化)三、蛇的移动四、蛇的方向控制五、食物的设置六、游戏结束总结前言为了初步学习Python更有兴趣,决定做个学编程大多都会做的小游戏—贪吃蛇,因为是刚刚开始学习,不足之处,希望大家多多指正。一、贪吃蛇游戏初始界面及地图1.游戏初始界面defmune():os.system(“color0a

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺


前言

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


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

1.游戏初始界面

def mune():
    os.system("color 0a")
    dll.set_cmd(0, 2);print("□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□")
    dll.set_cmd(0, 3);print("□□□□□■■■■□□□□□□□贪吃蛇□□□□□□□□□■□□□ 操作指南 □□□□")#7
    dll.set_cmd(0, 4);print("□□□□■■□□■■□□□□□□□□□□□□□□□□□□■□□□方向键 改变方向□□□□")#5
    dll.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("□□□□■■■■□□□□■□□□□■□□□■■□□■■□■□□■■■□□□■■■■■□□")#24
    dll.set_cmd(0,12);print("□□□□□□□□□□□□□□□□□□按空格开始游戏□□□□□□□□□□□□□□□□□□□")

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

2.游戏地图

def wall(x,y):#绘制围墙
    i=0;j=0
    while i<=x:
        print('■',end="")
        for j in range(y):
            if i==0:
                print('■', end="")
            elif i==20:
                print('■', end="")
            else:
                print(" ",end="")
            j+=1
        print('■')
        i+=1
        j=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,没有输出0
	key = _getch();
	Sleep(10);
	return key;
      }
	else;
	
}

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

import os,time,ctypes,random

wall_x,wall_y ,eat_flag= 20,21,1
move_up,move_down,move_left,move_right,esc,space = 72,80,75,77,27,32

def 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 = 0
    for 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_y
    if [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,key
    a = dll.c_getch()
    if a in [esc,space]:
        getkey = a
    if 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 = a
        else:
            pass
    else:
        pass
def snake_ctrl():#根据键盘输入判断方向已经功能操作
    global getkey, key, snake_x, snake_y
    if key == move_down:
        snake_y += 1
    elif key == move_up:
        snake_y -= 1
    elif key == move_right:
        snake_x += 2
    elif key == move_left:
        snake_x -= 2
    else:
        pass
    if getkey == space:
        time.sleep(1)
        getkey = 0
        while 1:
            getkey = dll.c_getch()
            if getkey == space:
                getkey = 0
                break
            elif getkey == esc:
                break
            else:
                pass
    else:
        pass

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

五、食物的设置

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

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

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

六、游戏结束

def gameover():#游戏结束判断
    if (snake_x>42)|(snake_y>19)\
        |(snake_x<2)|(snake_y==0):
        return 1
    elif snake_list.count(snake_list[-1])>1:
        return 1
    else :
        return 0
def over_next():#结束后的操作
    global getkey,eat_flag
    if 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")
                break
            elif getkey == space:
                init_game()
                eat_flag = 1
                break
            else:
                pass
    else:
        pass
  • 贪吃蛇撞墙的判断就简单粗暴的坐标判断,如果地图复杂可能需要使用列表将每部分墙体的起始坐标录入进行判断,贪吃蛇只需要判断头的位置就能够判断是否撞到了墙。
  • 使用列表的count方法能够很简单的判断序列中有没有两相同的元素,来检测蛇有没有吃到自己。

七、主程序

if __name__ == '__main__':#主函数main
  dll = ctypes.windll.LoadLibrary("set_cmd.dll")  # 调用c语言程序
  init()
  mune()
  while 1:
      getkey = dll.c_getch()
      if getkey == space:
          break
      else:
          pass
  init_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")
          break
      else:
          pass
      get_key()
      time.sleep(0.15)
  • 通过两次按键 get_key() 检测来减少按键的检测缺失
  • 可以通过调整循环等待时间 time.sleep(0.15) 来调整游戏内蛇的速度

八、演示效果

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

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

以下是演示效果
初始界面
在这里插入图片描述
评价:能玩

总结

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


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/197075.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 一问彻底理解dubbo主流程

    一问彻底理解dubbo主流程

  • Alex 的 Hadoop 菜鸟教程: 第3课 Hadoop 安装教程 – 非HA方式 (一台server)

    Alex 的 Hadoop 菜鸟教程: 第3课 Hadoop 安装教程 – 非HA方式 (一台server)原帖地址:http://blog.csdn.net/nsrainbow/article/details/36629741接上一个教程:http://blog.csdn.net/nsrainbow/article/details/36629339本教程是在Centos6下使用yum来安装CDH5…

  • trim函数去掉字符串首尾空格

    trim函数去掉字符串首尾空格trim():去掉字符串首尾的空格。public class trimDemo{ public static void main(String arg[]){ String a=" hello "; // 前后均有空格 String b="hello"; // 前后均无空格 System.out.println(b.equals(a)); /…

  • 华为的OD,值得去吗?「建议收藏」

    华为的OD,值得去吗?「建议收藏」最近有不少小伙伴接到了华为OD的面试邀约,但搞不清楚OD到底怎么回事儿,要不要去。所以今天来说说华为的OD到底是怎么回事儿,怎么判断是否值得去。1、华为的OD是怎么回事儿OD,是OutsourcingDispacth的缩写,简单粗暴地讲,就是外包派遣,劳务派遣。基本模式是这样的: A公司是外包公司(或劳务派遣公司,或人力资源公司); A公司签了一堆人,程序…

  • oracle number类型 p、s参数说明[通俗易懂]

    oracle number类型 p、s参数说明[通俗易懂] oraclenumber类型采用科学计数法表示,p表示有效数字的个数,s表示精度;如果定义字段类型为number(p,s)则该字段所能表示的最大正数是(10p-1)*10-s最小负数-(10p-1)*10-s;所有该范围之间的数字均可根据精度四舍五入后插入该字段;否则将会报错。  

  • 肝了一晚帮她搭建完个人网站——利用Docker在单节点上实现内外网隔离网站部署(Nginx、WordPress、MySQL)

    肝了一晚帮她搭建完个人网站——利用Docker在单节点上实现内外网隔离网站部署(Nginx、Wordpress、MySQL)目录1、前言2、注册3、重置服务器实例密码4、配置安全规则5、登录服务器6、更新系统7、安装Docker8、创建Docker子网络9、创建子网内的MySQL实例10、创建子网内的WordPress实例11、创建Nginx反向代理实例12、查看状态13、配置WordPress14、发布站点15、访问站点16、Docker命令行日常更新18、总结1、前言  同事小姐姐琦琦毕业后就应聘来到我们公司做项目助理,跟我分在一个项目组。琦琦自身先天条件就很好,长得耐看,身高1.65,偏瘦,整体算中等偏上的水平吧。她平

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号