贪吃蛇游戏(python实现)
前言
最近在整理之前开发过的一些python脚本代码,发现了这个贪吃蛇游戏脚本,所以发到这里来做个记录。
一、button.py实现
import pygame as pg
class button:
def __init__(self,x,y,w,h,color=(150,150,150),color_1=(50,50,50),f=20):
self.text=""
self.rect=[x,y,w,h]
pg.font.init()
self.color=color
self.color_1=color_1
self.font=pg.font.Font('images/font.ttf',f)
self.f=f
self.draw_ui=True
pg.mixer.init()
def draw(self,screen):
if self.draw_ui:
pg.draw.rect(screen,self.color,self.rect)
pg.draw.rect(screen,self.color_1,self.rect,5)
im=self.font.render(self.text, True, (0, 0, 0))
screen.blit(im,(self.rect[0]+(self.rect[2]-im.get_rect().w)//2,self.rect[1]))
def Event(self,ev):
if ev.type==pg.MOUSEBUTTONDOWN:
x,y =ev.pos
r=pg.Rect([x,y,1,1])
rr=pg.Rect(self.rect)
if rr.colliderect(r):
pg.mixer.Sound('images/点.mp3').play()
return True
return False
二、main.py实现
import copy
import random
import sys
import button
import numpy as np
import pygame as pg
class config:
w = 600
h = 400
score = 0
bg = pg.image.load('images/bg.png')
bg = pg.transform.scale(bg, [600, 400])
screen = pg.display.set_mode([600, 400])
pg.display.set_caption('贪吃蛇')
class V:
def __init__(self):
self.isStart = True
self.number = None
self.name = []
self.level = None
self.d = None
self.start()
def start(self):
pg.mixer.music.stop()
bu = button.button(config.w // 2 - 50, config.h // 2 + 0, 100, 30)
bu1 = button.button(config.w // 2 - 50, config.h // 2 + 50, 100, 30)
bu1.text = '退出游戏'
bu.text = '重开游戏'
g = pg.font.Font('images/font.ttf', 60).render('游戏胜利', True, [255, 255, 255])
s = pg.font.Font('images/font.ttf', 60).render('score:' + str(score), True, [255, 255, 255])
while self.isStart:
screen.fill([100, 100, 100])
screen.blit(bg, [0, 0])
for ev in pg.event.get():
if ev.type == pg.QUIT:
pg.quit()
if bu.Event(ev):
Start().start()
elif bu1.Event(ev):
sys.exit(0)
screen.blit(g, [300 - g.get_size()[0] // 2, 60])
screen.blit(s, [300 - s.get_size()[0] // 2, 130])
bu1.draw(screen)
bu.draw(screen)
pg.display.update()
class STOP:
def __init__(self):
self.isStart = True
self.number = None
self.name = []
self.level = None
self.d = None
self.start()
def start(self):
pg.mixer.music.stop()
bu1 = button.button(config.w // 2 - 50, config.h // 2 + 50, 100, 30)
bu1.text = '继续'
g = pg.font.Font('images/font.ttf', 60).render('游戏暂停中', True, [255, 255, 255])
while self.isStart:
screen.fill([100, 100, 100])
screen.blit(bg, [0, 0])
for ev in pg.event.get():
if ev.type == pg.QUIT:
pg.quit()
elif bu1.Event(ev):
return None
screen.blit(g, [300 - g.get_size()[0] // 2, 60])
bu1.draw(screen)
pg.display.update()
class gameover:
def __init__(self):
self.isStart = True
self.number = None
self.name = []
self.level = None
self.d = None
self.start()
def start(self):
pg.mixer.music.stop()
bu = button.button(config.w // 2 - 50, config.h // 2 + 0, 100, 30)
bu1 = button.button(config.w // 2 - 50, config.h // 2 + 50, 100, 30)
bu1.text = '退出游戏'
bu.text = '重开游戏'
s = pg.font.Font('images/font.ttf', 60).render('score:' + str(score), True, [255, 255, 255])
g = pg.image.load('images/gameover.png')
while self.isStart:
screen.fill([100, 100, 100])
screen.blit(bg, [0, 0])
for ev in pg.event.get():
if ev.type == pg.QUIT:
pg.quit()
if bu.Event(ev):
Start().start()
elif bu1.Event(ev):
sys.exit(0)
screen.blit(g, [300 - 86, 80])
screen.blit(s, [300 - s.get_size()[0] // 2, 130])
bu1.draw(screen)
bu.draw(screen)
pg.display.update()
class Start:
def __init__(self):
self.isStart = True
self.number = None
self.name = []
self.level = None
self.d = None
def start(self):
bu = button.button(config.w // 2 - 50, config.h // 2, 100, 30)
bu2 = button.button(config.w // 2 - 50, config.h // 2 + 50, 100, 30)
bu1 = button.button(config.w // 2 - 50, config.h // 2 + 100, 100, 30)
g = pg.font.Font('images/font.ttf', 120).render('Snake', True, [255, 255, 255])
bu1.text = '退出游戏'
bu.text = '开始游戏'
bu2.text = "困难模式"
while self.isStart:
screen.fill([100, 100, 100])
screen.blit(bg, [0, 0])
for ev in pg.event.get():
if ev.type == pg.QUIT:
pg.quit()
if bu.Event(ev):
Game().run()
elif bu2.Event(ev):
g = Game()
for i in range(5):
g.wallList.append([random.randint(0, 24), random.randint(0, 16)])
g.d = True
g.run()
elif bu1.Event(ev):
sys.exit(0)
screen.blit(g, [300 - g.get_size()[0] // 2, 60])
bu1.draw(screen)
bu.draw(screen)
bu2.draw(screen)
pg.display.update()
class Game:
def __init__(self):
self.screen = screen
self.pos = [5, 5]
self.BodyList = [copy.deepcopy(self.pos)]
self.maxfood = 2
self.foodList = []
self.map = None
self.foodimg = None
self.Vlen = 10
self.wallList = []
self.cellSize = 25#是边长
self.mapSize = [24, 16]
self.isStart = False
self.top = None
self.d = False
self.c = pg.time.Clock()
self.movemactime = 250
self.movetime = self.movemactime
self.images = []
self.len = 4
self.f = 0
self.font = None
self.ev = None
self.left = None
self.screenSize = [600, 400]
def Map(self):
w, h = self.mapSize
self.map = np.zeros([w, h]).tolist() # 返回给定形状和类型的新数组,用0填充
self.left = (self.screenSize[0] - (self.cellSize * w)) // 2
self.top = (self.screenSize[1] - (self.cellSize * h)) // 2
def init(self):
pg.mixer.init()
pg.mixer.music.load('images/121.mp3')
pg.font.init()
self.font = pg.font.Font(None, 30)
self.isStart = True
self.Map()
im = pg.image.load('images/Snake.png')
im.set_colorkey((255,255,255))
self.foodimg = pg.image.load('images/food.png')
self.wall = pg.image.load('images/wall.png')
self.foodimg = pg.transform.scale(self.foodimg, [self.cellSize, self.cellSize])
self.wall = pg.transform.scale(self.wall, [self.cellSize, self.cellSize])
for i in range(self.cellSize):
for j in range(self.cellSize):
if np.sum(np.array(self.foodimg.get_at((i, j)))) > 910:#pygame.Surface.get_at() — 获取一个像素的颜色值 pygame.Surface.set_at() — 设置一个像素的颜色值
self.foodimg.set_at((i, j), (255, 255, 255))
self.foodimg.set_colorkey([255, 255, 255])
for i in range(3):
for j in range(3):
s = pg.Surface([42, 42])
s.blit(im, [0, 0], [i * 42, j * 42, 42, 42])
s.set_colorkey([0, 0, 0])
s = pg.transform.scale(s, [self.cellSize, self.cellSize])
self.images.append(s)
def run(self):
self.init()
pg.mixer.music.play(-1)
while self.isStart:
self.event()
self.draw()
self.updata()
def move(self, ev):
global score
if ev != None:
if ev.key == pg.K_d:
self.pos[0] += 1
if self.pos in self.BodyList or self.pos in self.wallList:
score = self.len
gameover()
if not self.pos in self.BodyList and ((self.pos[0] >= 0 and self.pos[0] < self.mapSize[0]) and (
self.pos[1] >= 0 and self.pos[1] < self.mapSize[1])):
self.BodyList.append(copy.deepcopy(self.pos))
else:
gameover()
self.pos[0] -= 1
if ev.key == pg.K_a:
self.pos[0] -= 1
if self.pos in self.BodyList or self.pos in self.wallList:
score = self.len
gameover()
if not self.pos in self.BodyList and ((self.pos[0] >= 0 and self.pos[0] < self.mapSize[0]) and (
self.pos[1] >= 0 and self.pos[1] < self.mapSize[1])):
self.BodyList.append(copy.deepcopy(self.pos))
else:
gameover()
self.pos[0] += 1
if ev.key == pg.K_w:
self.pos[1] -= 1
if self.pos in self.BodyList or self.pos in self.wallList:
score = self.len
gameover()
if not self.pos in self.BodyList and ((self.pos[0] >= 0 and self.pos[0] < self.mapSize[0]) and (
self.pos[1] >= 0 and self.pos[1] < self.mapSize[1])):
self.BodyList.append(copy.deepcopy(self.pos))
else:
gameover()
self.pos[1] += 1
if ev.key == pg.K_s:
self.pos[1] += 1
if self.pos in self.BodyList or self.pos in self.wallList:
score = self.len
gameover()
if not self.pos in self.BodyList and ((self.pos[0] >= 0 and self.pos[0] < self.mapSize[0]) and (
self.pos[1] >= 0 and self.pos[1] < self.mapSize[1])):
self.BodyList.append(copy.deepcopy(self.pos))
else:
gameover()
self.pos[1] -= 1
def event(self):
global score
for ev in pg.event.get():
if ev.type == pg.QUIT:
pg.quit()
elif ev.type == pg.KEYDOWN:
if ev.key == pg.K_q:
if pg.mixer.music.get_busy():
pg.mixer.music.stop()
else:
pg.mixer.music.play(-1)
if ev.key == pg.K_r:
STOP()
self.move(ev)
self.ev = ev
def draw(self):
self.screen.fill([100, 100, 100])
screen.blit(bg, [0, 0])
self.screen.blit(self.font.render('length:' + str(self.len), True, [255, 255, 255]), [5, 5])
for x, i in enumerate(self.map):
for y, j in enumerate(i):
# pg.draw.rect(screen, [200, 200, 200],[self.left + x * self.cellSize, self.top + y * self.cellSize, self.cellSize,self.cellSize], 1)
if [x, y] in self.foodList:
screen.blit(self.foodimg, [self.left + x * self.cellSize, self.top + y * self.cellSize])
if [x, y] in self.BodyList and [x, y] != self.BodyList[0] and [x, y] != self.BodyList[-1]:
try:
screen.blit(self.OrientationBody(self.BodyList.index([x, y])),
[self.left + x * self.cellSize, self.top + y * self.cellSize])
except:
pass
if [x, y] in self.wallList:
screen.blit(self.wall, [self.left + x * self.cellSize, self.top + y * self.cellSize])
if [x, y] == self.BodyList[0]:
screen.blit(self._Draw(0, 1, self.images[5]),
[self.left + x * self.cellSize, self.top + y * self.cellSize])
if [x, y] == self.pos:
screen.blit(self._Draw(self.BodyList.index(self.pos), -1, self.images[0]),
[self.left + x * self.cellSize, self.top + y * self.cellSize])
def updata(self):
global score
score = self.len
if self.pos in self.foodList:
self.len += 1
self.f += 1
pg.mixer.Sound('images/吃.mp3').play()
self.foodList.remove(self.pos)
if len(self.BodyList) > self.len:
self.BodyList.pop(0)
if len(self.foodList) < self.maxfood:
f = [random.randint(0, self.mapSize[0] - 1), random.randint(0, self.mapSize[1] - 1)]
if f not in self.BodyList and f not in self.foodList and f not in self.wallList:
self.foodList.append(f)
if self.f - 2 == 0 and self.d:
self.wallList = []
self.f = 0
for i in range(7):
self.wallList.append([random.randint(0, 24), random.randint(0, 16)])
pg.display.update()
if self.len == self.Vlen:
score = self.len
V()
self.movetime -= self.c.tick()
if self.movetime < 0:
self.move(self.ev)
self.movetime = self.movemactime
def _Draw(self, index, m, im):
try:
o = self.Orientation(index, m=m)
if o == 's':
return im
if o == 'w':
im = pg.transform.rotate(im, 180)
return im
if o == 'd':
im = pg.transform.flip(im, False, False)
im = pg.transform.rotate(im, 90)
return im
if o == 'a':
im = pg.transform.flip(im, False, True)
im = pg.transform.rotate(im, 90)
return im
return im
except:
return im
def Orientation(self, index, m=-1):
i = np.array(self.BodyList[index]) - np.array(self.BodyList[index + m])
i = i.tolist()
if i == [0, 1]:
return 's'
elif i == [1, 0]:
return 'd'
elif i == [0, -1]:
return 'w'
elif i == [-1, 0]:
return 'a'
def OrientationBody(self, index):
i = np.array(self.BodyList[index]) - np.array(self.BodyList[index + 1])
ii = np.array(self.BodyList[index]) - np.array(self.BodyList[index - 1])
l = (i - ii).tolist()
i = i.tolist()
ii = ii.tolist()
# print(np.array(self.BodyList[self.BodyList.index(self.pos) - 1]) - np.array(self.BodyList[self.BodyList.index(self.pos) - 0]),i,ii,l)
if l == [0, 0] or l[0] > 1 or l[1] > 1 or l[0] < -1 or l[1] < -1:
return self._Draw(index, -1, self.images[8])
if l[0] == 0 and l[1] == 0:
return self._Draw(index, -1, self.images[7])
if i == [0, 1] or i == [1, 0]:
if ii == [-1, 0]:
return self.images[4]
if ii == [0, ]:
return self.images[4]
if i == [1, 0]:
if ii == [0, -1]:
return self.images[6]
if ii == [0, 1]:
return pg.transform.rotate(self.images[6], 270)
if i == [0, -1]:
if ii == [-1, 0]:
return pg.transform.rotate(self.images[6], 90)
if ii == [1, 0]:
return pg.transform.flip(self.images[7], False, True)
if i == [-1, 0]:
if ii == [0, -1]:
return pg.transform.rotate(self.images[7], 180)
if ii == [0, 1]:
return pg.transform.rotate(self.images[7], 270)
if i == [0, 1]:
if ii == [1, 0]:
return pg.transform.rotate(self.images[7], 0)
Start().start()
g = Game()
g.run()
总结
main.py里面涉及到图片以及整个工程我放在了云盘(提取码:0zde)
仅供参考。