上面是實現的截圖,廢話不說,直接開始說一下代碼
pos = { 'UP': (-1,0), 'DOWN':(+1,0), 'LEFT':(0,-1), 'RIGHT':(0,+1), } current = 'RIGHT' snake = [[1,1],[1,2],[1,3],[1,4],[1,5]] #ex: [[1,1],[1,2],[1,3]] [y,x] head = snake[-1] snake_speed = 0.1 rany, ranx = -1, -1
來一些數據的初始化,蛇用列表表示,蛇的頭的是列表的最后一項,速度用time.sleep()表示,速度越小,越快
def isover(head): if snake.count(head) > 1: #碰到自己身體 return True if (head[0] == y-1) or (head[1] == x-1) or (head[0] == 0) or (head[1] == 0): #碰到牆 return True return False
判定游戲是否結束,碰到自己身體結束或者碰到牆結束
def randomyx(): ranflag = False while ranflag is False: rany, ranx = random.randint(1,y-2) , random.randint(1,x-2) if [rany,ranx] not in snake: ranflag = True
隨機生成貪吃蛇的點,注意:生成的點:需在框內而且不能在蛇的身上
while isover(head) is False: draw() head = [ head[0] + pos[current][0] , head[1] + pos[current][1]] snake.append(head) if head[0] == rany and head[1] == ranx: randomyx() snake_speed = snake_speed - 0.01 else: snake.pop(0) time.sleep(snake_speed)
上面是核心的邏輯代碼,主要思想是:
1.只要蛇沒有吃到東西,就頭加入進去,尾掉(形成蛇走步的感覺);只要蛇吃到了東西,就頭加進來,尾不出去(形成蛇長大的感覺) <--- 典型隊列
2.然后考慮current <-- 當前蛇走的方向,如何去改變
這里首先就考慮是一個異步的情形!利用異步監聽鼠標時間!
t1 = threading.Thread(target=listening, args=(head,), name='listenkeyboard') t1.start()
def listening(head): while True: c = stdscr.getch() if c == curses.KEY_UP and current != 'DOWN': current = 'UP' elif c == curses.KEY_DOWN and current != 'UP': current = 'DOWN' elif c == curses.KEY_LEFT and current != 'RIGHT': current = 'LEFT' elif c == curses.KEY_RIGHT and current != 'LEFT': current = 'RIGHT'
這里需要注意的是: 在當前方向為上的時候,不能按下---> 按了蛇不就自己撞自己了嘛~
寫完主要邏輯,之后 美化以下界面->
curses.start_color() #開啟顏色 curses.init_pair(1, curses.COLOR_RED, curses.COLOR_RED)#定義點的顏色 curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_BLUE) #定義蛇的顏色
for si in snake:
stdscr.addstr(si[0],si[1],'@',curses.color_pair(2))
stdscr.addstr(rany,ranx,' ',curses.color_pair(1))
這樣,一個貪吃蛇小游戲就完成了,下面是實現的全部代碼,python3 snake.py,自己玩一下吧~~
import time,curses,random,threading pos = { 'UP': (-1,0), 'DOWN':(+1,0), 'LEFT':(0,-1), 'RIGHT':(0,+1), } current = 'RIGHT' snake = [[1,1],[1,2],[1,3],[1,4],[1,5]] #ex: [[1,1],[1,2],[1,3]] [y,x] head = snake[-1] snake_speed = 0.1 rany, ranx = -1, -1 def isover(head): if snake.count(head) > 1: #碰到自己身體 return True if (head[0] == y-1) or (head[1] == x-1) or (head[0] == 0) or (head[1] == 0): #碰到牆 return True return False def randomyx(): global rany,ranx ranflag = False while ranflag is False: rany, ranx = random.randint(1,y-2) , random.randint(1,x-2) if [rany,ranx] not in snake: ranflag = True def draw(): stdscr.erase() stdscr.border() for si in snake: stdscr.addstr(si[0],si[1],'@',curses.color_pair(2)) stdscr.addstr(rany,ranx,' ',curses.color_pair(1)) stdscr.refresh() def listening(head): global current while True: c = stdscr.getch() if c == curses.KEY_UP and current != 'DOWN': current = 'UP' elif c == curses.KEY_DOWN and current != 'UP': current = 'DOWN' elif c == curses.KEY_LEFT and current != 'RIGHT': current = 'LEFT' elif c == curses.KEY_RIGHT and current != 'LEFT': current = 'RIGHT' def loop(stdscr): global head,snake_speed randomyx() t1 = threading.Thread(target=listening, args=(head,), name='listenkeyboard') t1.start() while isover(head) is False: draw() head = [ head[0] + pos[current][0] , head[1] + pos[current][1]] snake.append(head) if head[0] == rany and head[1] == ranx: randomyx() snake_speed = snake_speed - 0.01 else: snake.pop(0) time.sleep(snake_speed) stdscr = curses.initscr() curses.noecho() #不輸出- - curses.cbreak() #立刻讀取:暫不清楚- - curses.start_color() #開啟顏色 curses.init_pair(1, curses.COLOR_RED, curses.COLOR_RED)#定義點的顏色 curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_BLUE) #定義蛇的顏色 #init_pair(n,f,b)修改顏色對n,讓f為前景色,b為背景色。顏色對0天生的黑白色,不允許改。 stdscr.keypad(1) #開啟keypad stdscr.border() curses.curs_set(0) (y,x) = stdscr.getmaxyx() curses.wrapper(loop) curses.endwin()