python 贪吃蛇
#!/usr/bin/python3 '''
项目分析:
-构成
-蛇Snake
-实物Food
-世界World
-蛇和食物属于整个世界
class world:
self.snake
self.food
-上面代码不太友好
-我们用另外一个思路来分析
-我们的分析思路:
-食物是一个独立的事物
-蛇也是一个独立的事物
-世界也是,但世界负责显示
''' import random
import time
import threading
from tkinter import *
import queue class Food():
'''
功能:
1.出现在画面的某一个地方
2.一旦被吃则增加蛇的分数
'''
def __init__(self,queue):
'''
自动产生一个食物
'''
self.queue = queue
self.new_food() def new_food(self):
'''
功能:产生一个食物
产生一个食物的过程也就是随机产生一个食物坐标的过程
'''
#注意横坐标产生的位置
x = random.randrange(10,490,10)
#同理产生y坐标
y = random.randrange(10,290,10)
#需要注意的是,我们的正规游戏屏幕一般不需要把他设置成正方形
self.position = x,y #position存放食物的位置 #队列,就是一个不能随意访问内部元素,只能从头弹出一个元素,并只能从队尾追加一个元素的list
#把一个食物产生的消息放入队列
#消息的格式,自己定义
#我的定义是:消息是一个dict,k代表消息类型,v代表此类型的数据
self.queue.put({"food":self.position}) #queue.put方法中有两个参数,第一个为item必填,第二个为block,默认为1 class Snake(threading.Thread):
'''
蛇的功能:
1.蛇能动,由我们上下左右按键控制
2.蛇每次动都需要重新计算蛇头的位置
3.检测游戏是否完事的功能
'''
def __init__(self,world,queue):
threading.Thread.__init__(self)
self.world = world
self.queue = queue
self.direction = "Up"
self.points_earned = 0 #游戏分数
self.food = Food(self.queue)
self.snake_points = [(490,50),(480,50),(470,50),(460,50)] #蛇身各点
self.start() def run(self):
'''
一旦启用多线程,调用此函数
要要蛇一直在跑
'''
if self.world.is_game_over:
self._delete()
while not self.world.is_game_over:
self.queue.put({"move":self.snake_points})
if self.points_earned < 10:
time.sleep(0.3)
elif 10 <= self.points_earned < 15:
time.sleep(0.2)
elif 15 <= self.points_earned < 20:
time.sleep(0.1)
elif 20 <= self.points_earned < 25:
time.sleep(0.05)
elif 25 <= self.points_earned < 100:
time.sleep(0.04)
else :
time.sleep(0.03)
self.move()
def move(self):
'''
负责蛇的移动:
1.重新计算蛇头的坐标
2.当蛇头跟食物相遇,则加分,重新生成食物,通知world,加分
3.否则,蛇需要动
'''
new_snake_point = self.cal_new_position() #重新计算蛇头位置
#蛇头位置跟食物位置相同
if self.food.position == new_snake_point:
self.points_earned+=1
self.queue.put({"points_earned":self.points_earned})
self.food.new_food() #旧的食物被吃掉产生新的食物
self.snake_points.append(new_snake_point)
else :
#需要注意蛇的信息的保存方式
#每次移动是删除蛇的最前位置,并在后面追加
self.snake_points.pop(0)
#判断程序是否退出,因为新的蛇可能撞墙
self.check_game_over(new_snake_point)
self.snake_points.append(new_snake_point) def cal_new_position(self):
'''
计算新的蛇头位置
'''
last_x,last_y = self.snake_points[-1]
if self.direction == "Up": #direction负责存储蛇移动的方向
new_snake_point = last_x,last_y - 10 #每次移动的跨度是10像素
elif self.direction == "Down":
new_snake_point = last_x,last_y + 10
elif self.direction == "Left":
new_snake_point = last_x - 10,last_y
else :
#self.direction == "Right":
new_snake_point = last_x + 10,last_y
return(new_snake_point) def key_pressed(self,event):
#keysym是按键名称
self.direction = event.keysym def check_game_over(self,snake_point):
'''
判断的依据是蛇是否撞墙
把蛇头的坐标拿出来跟墙判断
'''
x,y = snake_point[0],snake_point[1]
if not 0<x<500 or not 0<y<300 or snake_point in self.snake_points:
self.queue.put({"game_over":True}) class World(Tk):
'''
用来模拟整个游戏画板
'''
def __init__(self,queue):
Tk.__init__(self)
self.queue = queue
self.is_game_over = False
#定义画板
self.canvas = Canvas(self,width = 500,height = 300,bg = 'gray')
self.canvas.pack() #画出蛇和食物
self.snake = self.canvas.create_line((0,0),(0,0),fill = 'black',width = 10)
self.food = self.canvas.create_rectangle(0,0,0,0,fill = '#FFCC4C',width = 10)
self.points_earned = self.canvas.create_text(450,20,fill = 'white',text = 'SCORE: 0')
self.queue_handler() def queue_handler(self):
try:
#需要不断从消息队列拿到消息,所以使用死循环
while True:
task = self.queue.get(block = False)
if task.get("game_over"):
self.game_over()
if task.get('move'):
points = [x for point in task["move"] for x in point]
#重新绘制蛇
self.canvas.coords(self.snake,*points)
#同样道理,还需要处理食物、得分
if task.get('food'):
self.canvas.coords(self.food,*task['food'],*task['food'])
if task.get('points_earned'):
self.canvas.itemconfigure(self.points_earned,text = 'SCORE: {}'.format(task['points_earned']))
except queue.Empty: #爆出队列为空异常
if not self.is_game_over:
#after的含义是,在多少毫秒后调用后面的函数
self.canvas.after(100,self.queue_handler) def game_over(self):
'''
游戏结束,清理现场
'''
self.is_game_over = True
self.canvas.create_text(250,150,fill = 'red',text = "Game Over !!!")
qb = Button(self,text = 'Quit',command = self.destroy)
rb = Button(self,text = 'Again',command = self.__init__) if __name__ == "__main__":
q = queue.Queue()
world = World(q)
world.title("^_^john家的贪吃蛇* _ *")
snake = Snake(world,q) world.bind('<Key-Left>',snake.key_pressed)
#同样绑定右、上、下键
world.bind('<Key-Right>',snake.key_pressed)
world.bind('<Key-Up>',snake.key_pressed)
world.bind('<Key-Down>',snake.key_pressed) world.mainloop() #消息循环
python 贪吃蛇的更多相关文章
- python贪吃蛇
代码地址如下:http://www.demodashi.com/demo/13335.html 一.先展示python贪吃蛇效果 二.操作说明 按键 功能 UP 向上移动 DOWN 向下移动 LEFT ...
- 【python】10分钟教你用python打造贪吃蛇超详细教程
10分钟教你用python打造贪吃蛇超详细教程 在家闲着没妹子约, 刚好最近又学了一下python,听说pygame挺好玩的.今天就在家研究一下, 弄了个贪吃蛇出来.希望大家喜欢. 先看程序效果: 0 ...
- 多线程的Python 教程--“贪吃蛇”
本指南的里代码可以在这里下载: threadworms.py ,或者从 GitHub.代码需要 Python 3 或 Python 2 ,同时也需要安装 Pygame . 点击查看大版本图片 ...
- 用Python写一个贪吃蛇
最近在学Python,想做点什么来练练手,命令行的贪吃蛇一般是C的练手项目,但是一时之间找不到别的,就先做个贪吃蛇来练练简单的语法. 由于Python监听键盘很麻烦,没有C语言的kbhit(),所以这 ...
- Python制作AI贪吃蛇
前提:本文实现AI贪吃蛇自行对战,加上人机对战,文章末尾附上源代码以及各位大佬的链接,还有一些实现步骤,读者可再次基础上自行添加电脑VS电脑和玩家VS玩家(其实把人机对战写完,这2个都没什么了,思路都 ...
- 如何用Python写一个贪吃蛇AI
前言 这两天在网上看到一张让人涨姿势的图片,图片中展示的是贪吃蛇游戏, 估计大部分人都玩过.但如果仅仅是贪吃蛇游戏,那么它就没有什么让人涨姿势的地方了. 问题的关键在于,图片中的贪吃蛇真的很贪吃XD, ...
- python学习笔记05:贪吃蛇游戏代码
贪吃蛇游戏截图: 首先安装pygame,可以使用pip安装pygame: pip install pygame 运行以下代码即可: #!/usr/bin/env python import pygam ...
- Python写的贪吃蛇游戏例子
第一次用Python写这种比较实用且好玩的东西,权当练手吧 游戏说明: * P键控制“暂停/开始”* 方向键控制贪吃蛇的方向 源代码如下: 复制代码代码如下: from Tkinter import ...
- 初级练手项目——用Python一步一步实现“智能”贪吃蛇!
贪吃蛇作为一款经典的小游戏,想必大家一定并不陌生,今天我们就来用Python来设计与实现贪吃蛇游戏,回味一下童年的快乐.快跟着小编来看看吧! 基本环境配置 ●版本:Python3 ●系统:Wind ...
随机推荐
- C#基础零碎知识点摘录
1.类分为静态类个非静态类(实例类) 静态类不能创建对象,使用方法时,直接类名.方法名(),常用的静态类有Console类 实例类:创建对象时通过对象调用类的方法 2.当我们声明一个类成员为静态时,意 ...
- 第十一篇:Mysql系列
Python开发基础之路 第十一篇:Mysql系列 Python-数据库 基本SQL语句 Python-数据类型 主键auto_increment Python-多表关联 外键 级联 Python-s ...
- Flask开发微电影网站(十)
1.后台管理之角色管理 1.1 角色管理之定义角色表单 在app的admin目录的forms.py文件中,定义角色表单 # 角色表单 class RoleForm(FlaskForm): name = ...
- cf55D 数位dp记忆化搜索+状态离散
/* 漂亮数定义:可以整除任意数位上的数 求出区间[l,r]之间的漂亮数个数 因为 dp[i][j][k]:i位前模lcm的值是j,i位前lcm是k的漂亮数个数 */ #include<bits ...
- 方法的覆盖(override)
- 14.并发与异步 - 3.C#5.0的异步函数 -《果壳中的c#》
14.5.2 编写异步函数 private static readonly Stopwatch Watch = new Stopwatch(); static void Main(string[] a ...
- [BZOJ4913][SDOI2017]遗忘的集合
题解: 首先先弄出$f(x)$的生成函数$$f(x)=\prod_{i=1}^{n} {{(\frac{1}{1-x^i})}}^{a[i]}$$因为$f(x)$已知,我们考虑利用这个式子取推出$a[ ...
- HTML 中的预留字符(如标签的小于号 < )必须被替换为字符实体( < )。 不间断空格( )
1. 参考 HTML 字符实体 Python处理HTML转义字符 比方说一个从网页中抓到的字符串 html = '<abc>' 用Python可以这样处理: import HTMLPars ...
- labview使用了报表模块,在生成exe时需要添加以下内容,否则打包后不能开启excel功能
1.在你的安装目录下找到文件夹(D:\Program Files (x86)\National Instruments\LabVIEW 2016\vi.lib\Utility\NIReport.llb ...
- Python学习(三十三)—— Django之ORM
Object Relational Mapping(ORM) 一.ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系 ...