需要实现的几个基本功能 # 1.随机出生点, 随机果实 # 2.死亡判断 # 3.速度变快 # 4.吃果实增长 # 5.监听上下左右按键, 改变运动方向 代码实现 # -*- coding: utf-8 -*- # @Date : 2019-12-22 11:02:27 # @Link : http://www.flyinghu.cn # @name : 贪吃蛇 # @Version : 0.1 from pynput import keyboard from pynput.keyboard import Key from random import randint import threading import time import os r = threading.Lock() class Win(object): '''窗口类''' # 单例设计 __instance = None def __new__(cls, width=20, height=20): '''判断是否已经实例化''' if cls.__instance is None: obj = super().__new__(cls) obj.char = '█' obj.width = width obj.height = height obj.current_win = [ [obj.char for col in range(width)] for row in range(height)] obj.stop = False # 用来停止线程 cls.__instance = obj return cls.__instance def show(self): '''显示''' # print(self.win) while True: if self.stop: # 停止 break r.acquire() self.cls() for i in self.current_win: for j in i: print(j, end='') print() r.release() time.sleep(1/60) def show_win(self): self.cls() for i in self.current_win: for j in i: print(j, end='') print() def refresh(self): self.current_win = [[self.char for col in range( def cls(self): '''清空控制台输出''' os.system('cls') class Snake(object): '''贪吃蛇类''' # 单例设计 __instance = None def __new__(cls, win, de_speed=5): '''判断是否已经实例化''' if cls.__instance is None: obj = super().__new__(cls) obj.char = '●' obj.fruit_char = '★' obj.win = win obj.direction = randint(0, 3) # 方向 上:0 左:1 下:2 右:3 obj.de_speed = de_speed obj.statu = True # 随机生成初始位置, 为避免初始为边框周围 obj.current_snake = [ [ randint(int(1/4 * (obj.win.height - 1)), int(3/4 * (obj.win.height - 1))), randint(int(1/4 * (obj.win.width - 1)), int(3/4 * (obj.win.width - 1))) cls.__instance = obj return cls.__instance def load(self): '''加载蛇到地图中''' # 加载果实 self.win.refresh() row, col = self.fruit self.win.current_win[row][col] = self.fruit_char for row, col in self.current_snake: self.win.current_win[row][col] = self.char def gen_fruit(self): '''生成果实''' while True: self.fruit = [randint(0, self.win.height - 1), # 避免果实在蛇身体里面 if self.fruit not in self.current_snake: break def move(self): # if (self.current_snake[0][0] == self.fruit[0]) and (self.current_snake[0][1] == self.fruit[1]): if self.current_snake[0] == self.fruit: function(){ //Axitrader返佣 http://www.fx61.com/brokerlist/axitrader.html # 吃果实 if self.direction == 0: self.current_snake.append( [self.current_snake[-1][0] + 1, self.current_snake[-1][1]]) elif self.direction == 1: self.current_snake.append( [self.current_snake[-1][0], self.current_snake[-1][1] + 1]) elif self.direction == 2: self.current_snake.append( [self.current_snake[-1][0] - 1, self.current_snake[-1][1]]) else: self.current_snake.append( [self.current_snake[-1][0], self.current_snake[-1][1] - 1]) self.gen_fruit() self.current_snake[1:] = self.current_snake[:-1] if self.direction == 0: self.current_snake[0] = [self.current_snake[0] [0] - 1, self.current_snake[0][1]] elif self.direction == 1: self.current_snake[0] = [self.current_snake[0] [0], self.current_snake[0][1] - 1] elif self.direction == 2: self.current_snake[0] = [self.current_snake[0] [0] + 1, self.current_snake[0][1]] else: self.current_snake[0] = [self.current_snake[0] [0], self.current_snake[0][1] + 1] def press(self, key): '''监听上下左右键盘事件''' if self.statu: # 防止按键过快 if key == Key.up and self.direction != 2: self.direction = 0 self.statu = False elif key == Key.left and self.direction != 3: self.direction = 1 self.statu = False elif key == Key.down and self.direction != 0: self.direction = 2 self.statu = False elif key == Key.right and self.direction != 1: self.direction = 3 self.statu = False else: pass def run(self): try: # 开启监听键盘 keyboard.Listener(on_press=self.press).start() # 开启单独屏幕刷新线程, 两种刷新方式, 运动完刷新和单独线程刷新 # t = threading.Thread(target=self.win.show) # t.setDaemon(True) # t.start() self.gen_fruit() while True: self.move() self.statu = True # 运动后判断当前是否死亡 if self.current_snake[0][0] < 0 or self.current_snake[0][0] >= self.win.height or self.current_snake[0][1] < 0 or self.current_snake[0][1] > self.win.width: # 超出上下左右边界 self.win.stop = True break elif self.current_snake[0] in self.current_snake[1:]: # 咬到身体死亡 self.win.stop = True break self.load() # 根据当前蛇的长度来提高速度 改变初始速度就相当于改变难度 self.speed = self.de_speed * \ (1 + len(self.current_snake) ** 2 / (self.win.width * self.win.height)) # 移动完刷新屏幕 self.win.show_win() time.sleep(1/self.speed) time.sleep(0.5) print('Game over') print('得分:', len(self.current_snake)) except Exception as e: print(repr(e)) Snake(Win(width=20, height=20)).run() 运行环境 使用cmd终端运行, 本人使用powershell和编辑器直接终端运行总会有点问题
|