写在前面的话:
本系列教程仅有一些在本机调试通过的代码(如代码中发现bug,恳请包涵)。除代码中出现的一些主要注释外,不会出现太多其他文字解释,但是,文章中会给出主要模块的官方文档地址。再次:该系列文章的目的主要是抛砖,看‘玉’的同志们请移步官方文档。希望同志们,多多尝试,共同进步,谢谢!!!
贪吃蛇改进
import pygame,sys
from pygame.locals import *
import random
from Vector2 import Vector2
import copy
FPS = 10 #刷帧率
fpsClock = pygame.time.Clock() #确保程序以一个最大的FPS运行
SIZE = (400,400)
class snake:#蛇体结构
def __init__(self,x,y):
self.x = x
self.y = y
def init(displaysur,snakes):
x,y,x1,y1 = 0,0,0,0
x = random.randint(50, SIZE[0] - 20)
y = random.randint(50, SIZE[0] - 20)
s = snake(x,y)
snakes.append(s)
f = True
while f:
x1 = random.randint(20, SIZE[0] - 20)
y1 = random.randint(20, SIZE[0] - 20)
if x1 != x or y1 != y:
f = False
pygame.draw.circle(displaysur, (255,0,0), [x,y], 20, 0)
# pygame.draw.rect(displaysur,(255,0,0),(x,y,10,10))
return x1,y1
def faileCheck(snakes):
headSnake = snakes[0]
if headSnake.x < 0 or headSnake.x > 399 or headSnake.y < 0 or headSnake.y > 399 :
return True
def eatCheck(displaysur,snakes,fx,fy):
flag = False
x = fx
y = fy
headSnake = snakes[0]
h_rect = pygame.Rect( headSnake.x, headSnake.y,30,30)
f_rect = pygame.Rect(fx,fy,30,30)
if h_rect.colliderect(f_rect):#碰撞检测
flag = True
if flag:#生成新的食物位置
x = random.randint(0, SIZE[0] - 1)
y = random.randint(0, SIZE[0] - 1)
return flag ,x , y
def main():
global DisplaySurface, snakes, foodx, foody
snakes = []
pygame.init()
DisplaySurface = pygame.display.set_mode(SIZE)
pygame.display.set_caption("贪吃蛇")
foodx,foody = init(DisplaySurface,snakes)#游戏初始化
position = Vector2(snakes[0].x,snakes[0].y) #蛇的头部位置转换为向量
direction = Vector2()
while True:
DisplaySurface.fill((255,255,255))
if faileCheck(snakes):
pygame.quit()
sys.exit()
F, foodx, foody= eatCheck(DisplaySurface,snakes,foodx,foody) #是否吃到食物,并返回食物坐标
pygame.draw.circle(DisplaySurface, (0, 0, 128), [foodx, foody], 20, 0)#绘制食物
if F:
sna = snake(0,0)
snakes.append(sna)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == MOUSEBUTTONDOWN:
destination = Vector2(*event.pos) - Vector2(20,20) / 2
direction = Vector2.from_points(position, destination)
direction .normalize()#移动的方向
time_passed = fpsClock.tick()
time_passed_seconds = time_passed / 1000.0
distance_moved = time_passed_seconds * 20 #移动的速度
snakes_copy = copy.deepcopy(snakes)
for i in range(len(snakes)):
posx , posy = snakes[i].x,snakes[i].y
x ,y = posx,posy
if i == 0:
position += direction * distance_moved
posx ,posy= position[0],position[1]
else:
posx,posy = snakes_copy[i-1].x,snakes_copy[i-1].y
snakes[i].x , snakes[i].y = posx,posy #更新位置
pygame.draw.circle(DisplaySurface, (255,0,0), [posx,posy], 20, 0)
pygame.display.update()
# fpsClock.tick(10)
main()
Vector2.py
import math
class Vector2(tuple):
def __new__(typ, x=1.0, y=1.0):
n = tuple.__new__(typ, (int(x), int(y)))
n.x = x
n.y = y
return n
"""
向量相乘
"""
def __mul__(self, other):
return self.__new__(type(self), self.x*other, self.y*other)
"""
向量相减
"""
def __sub__(self, other):
return self.__new__(type(self), self.x - other.x, self.y - other.y)
"""
向量相加
"""
def __add__(self , other):
return self.__new__(type(self), self.x+other.x, self.y+other.y)
"""
向量相除
"""
def __truediv__(self, scalar):
return self.__new__(type(self), self.x/scalar, self.y/scalar)
def __str__(self):
return "(%s, %s)"%(self.x, self.y)
@staticmethod
def from_points(P1, P2):
return Vector2( P2[0] - P1[0], P2[1] - P1[1] )
def get_magnitude(self):
return math.sqrt( self.x**2 + self.y**2 )
"""
单位向量
"""
def normalize(self):
magnitude = self.get_magnitude()
self.x /= magnitude
self.y /= magnitude
参考文档:https://eyehere.net/2011/python-pygame-novice-professional-11/
挖个坑,下面会搞个大的,要一些时间