我制作了一个程序,该程序使用pygame一次包含多条蛇,并不断增加其长度。在其中,我有一个名为playerUpdates的类,应该在其中创建一个方法,该方法返回他们想要蛇走的方向。我的问题是,这里的函数带有“ Person2” 在其中,我使用的是“ Person1”内部几乎完全相同的方法来检查它是否会被击中,但是如果运行它,您会看到一点,它说它是安全的,并返回一个方向然后杀死它。我不明白为什么会发生这种情况,因为我编写了整个程序,所以我觉得我应该知道什么会杀死它或不会杀死它。我已经花了几个小时试图解决这个问题,但似乎没有任何效果。
代码如下:
#SnakeVsRoyale.py
import pygame
import os
import math
from random import randint
from pygame.locals import *
import time
pygame.init()
width = 800
height = 500
size = 10
win = pygame.display.set_mode((width,height))
pygame.display.set_caption("Snake Royale")
PATH = os.path.abspath(__file__)
PATH = PATH[0:-16] #-16 to chop off SnakeVsRoyale.py
font = pygame.font.SysFont('', 24)
bigFont = pygame.font.SysFont('', 30)
clock = pygame.time.Clock()
length = 1
class Snake:
global length
def __init__(self, pos, dir, name):
self.bod = [pos] #Lists [[x,y], [x,y]...]
self.dir = dir #String 'direction'
self.pos = pos.copy() #List [x,y]
self.name = name #Name 'Chris'
self.length = 1
self.kills = 0
self.alive = True
self.color = (randint(100,255),randint(100,255),randint(100,255)) #Start at 100 so it's not black or dark
def getInfo(self):
return [self.bod.copy(), self.dir, self.pos.copy()]
def getEndInfo(self):
return [self.name, self.length, self.kills]
def setDir(self, info):
self.dir = getattr(playerUpdates, self.name)(self.pos.copy(), self.bod.copy(), self.dir, info.copy())
def update(self, win):
if self.alive:
if self.dir == 'right':
self.pos[0]+=size
elif self.dir == 'left':
self.pos[0]-=size
elif self.dir == 'up':
self.pos[1]-=size
elif self.dir == 'down':
self.pos[1]+=size
else:
print("No direction set", self.name)
self.bod.append([self.pos[0], self.pos[1]])
if len(self.bod) > length: #length is global, self.length is the class variable
self.bod.pop(0)
if self.alive:
for i in self.bod:
pygame.draw.rect(win, self.color, pygame.Rect(i[0], i[1], size, size))
pygame.draw.rect(win, (255,255,255), pygame.Rect(self.pos[0], self.pos[1], size, size))
nameText = font.render(self.name, True, (100,100,100))
loc = nameText.get_rect()
loc.center = (self.pos[0]+10, self.pos[1]-14)
w, h = loc.size
pygame.draw.rect(win, (255,255,255), pygame.Rect(loc.x, loc.y, w, h))
win.blit(nameText, loc)
else:
self.bod = []
self.pos =[-100,-100]
def main():
global length
players = ['Person1', 'Person2']
snakeList = []
info = []
tickRate = 5
feed = []
dirs = ['right', 'left', 'up', 'down']
for i in players:
snake = Snake([randint(1,(width/size)-2)*size, randint(1,(height/size)-2)*size], dirs[randint(0,3)], i)
snakeList.append(snake)
end = True
playing = True
tStart = time.time()
while playing:
clock.tick(tickRate)
for event in pygame.event.get():
if event.type == QUIT:
playing = False
end = False
info = []
for i in snakeList:
info.append(i.getInfo())
for i in snakeList:
i.setDir(info.copy())
#Check hit
for i in snakeList:
if i.alive:
inf = i.getInfo()
loc = inf[2]
for x in info:
if loc in x[0]:
if inf[0]==x[0]: #Checks if it is itself
temp = x[0].copy()
temp.remove(loc)
if loc in temp: #Checks to see if the value is in the list twice
i.alive = False
snakeList.remove(i)
feed.append([i.name+' is out (Hit itself)', 0])
else: #Makes sure it isn't current position
i.alive = False
snakeList.remove(i)
feed.append([i.name+' is out (Hit Snake)', 0])
if loc[0] < 0 or loc[0]>=width or loc[1]<0 or loc[1]>=height:
i.alive = False
snakeList.remove(i)
feed.append([i.name+' is out (Border)', 0])
if (time.time()-tStart) > 1:
length += 1
tStart = time.time()
if length > 3:
tickRate = 10
keys = pygame.key.get_pressed()
for i in keys:
if i:
end = False
playing = False
#Draw everything
pygame.draw.rect(win, (0,0,0), pygame.Rect(0,0,width,height)) #black background
for i in snakeList:
i.update(win)
ycounter = 20
for i in feed:
text = bigFont.render(i[0], True, (0,0,0))
loc = text.get_rect()
loc.topleft = (20,ycounter)
w, h = loc.size
pygame.draw.rect(win, (255,255,255), pygame.Rect(loc.x-5, loc.y-5, w+10, h+10))
win.blit(text, loc)
ycounter+=h+15
i[1] += 2
if i[1] > 200:
feed.remove(i)
pygame.draw.rect(win, (255,255,255), pygame.Rect(0,0,width,height), 1) #White border
pygame.display.update()
while end: #This doesn't do anything I think
clock.tick(tickRate)
for event in pygame.event.get():
if event.type == QUIT:
end = False
#Draw everything
pygame.draw.rect(win, (0,0,0), pygame.Rect(0,0,width,height)) #Background
pygame.display.update()
pygame.quit()
class playerUpdates:
#pos is [x,y] bod is [[x,y],[x,y]...]
#info is [[bod, dir, pos], [bod, dir, pos]...]
def Person1(pos, bod, dir, info):
def getDirs(bod):
dirs = []
newBod = []
for i in range(len(bod)-1, len(bod)-12,-1):
newBod.append(bod[i])
for i in range(0,len(newBod)-2):
if newBod[i][0] == newBod[i+1][0]:
if newBod[i][1] > newBod[i+1][1]:
dirs.append('down')
else:
dirs.append('up')
else:
if newBod[i][0] > newBod[i+1][0]:
dirs.append('right')
else:
dirs.append('left')
return dirs
def hit(dirr, info, bod, pos):
newX, newY = pos[0], pos[1]
if dirr == 'right':
newX += size
if dirr == 'left':
newX -= size
if dirr == 'up':
newY -= size
if dirr == 'down':
newY += size
if newX >= width or newX < 0 or newY >= height or newY <= 0: #Attempts to leave a section open on border
return True
for i in info:
badX, badY = i[2][0], i[2][1]
if i[1] == 'right':
badX += size
if i[1] == 'left':
badX -= size
if i[1] == 'up':
badY -= size
if i[1] == 'down':
badY += size
if [newX, newY] in i[0]:
return True
if [newX, newY] == [badX, badY]:
if bod == i[0]:
pass
else:
return True
return False
if (len(bod) > 6):
dirs = getDirs(bod) #pos 0 is the most recent
if (dirs[0] == dirs[1] and dirs[0] == 'up') or (dirs[1] == dirs[2] and dirs[1] == 'up'):
if dirs[0] == dirs[1] and dirs[0] == 'up':
if dirs[2] == 'left':
if not(hit('right', info, bod, pos)):
return 'right'
elif dirs[2] == 'right':
if not(hit('left', info, bod, pos)):
return 'left'
if dirs[0] == 'up' and not(dirs[1] == 'up'):
if not(hit('up', info, bod, pos)):
return 'up'
if dirs[0] == 'left' or dirs[0] == 'right' and pos[0] > 10*size and pos[0] < width-10*size:
if not(hit('up',info, bod, pos)):
return 'up'
if pos[1] > height-5*size and pos[0] > randint(15,30)*size and pos[0] < width-randint(12,30)*size:
if not(hit('up', info, bod, pos)):
return 'up'
if not(hit(dir, info, bod, pos)): #and not(randint(0,20)==1):
return dir
else:
lr = ['left', 'right']
temp = lr.pop(randint(0,1))
if not(hit(temp, info, bod, pos)):
return temp
elif not(hit(lr[0], info, bod, pos)):
return lr[0]
elif not(hit('down', info, bod, pos)):
return 'down'
elif not(hit('up', info, bod, pos)):
return 'up'
'''
dirs = ['right', 'left', 'up', 'down']
for i in range(0,4):
newDir = dirs.pop(randint(0,len(dirs)-1))
if not(hit(newDir, info, bod, pos)):
return newDir
return dir
'''
return dir
def Person(pos, bod, dir, info):
def hit(dirr, info, bod, pos):
if randint(0,20) == 1:
return True
newX, newY = pos[0], pos[1]
if dirr == 'right':
newX += size
if dirr == 'left':
newX -= size
if dirr == 'up':
newY -= size
if dirr == 'down':
newY += size
if newX >= width or newX < 0 or newY >= height or newY < 0:
return True
for i in info:
badX, badY = i[2][0], i[2][1]
if i[1] == 'right':
badX += size
if i[1] == 'left':
badX -= size
if i[1] == 'up':
badY -= size
if i[1] == 'down':
badY += size
if [newX, newY] in i[0]:
return True
if [newX, newY] == [badX, badY]:
if bod == i[0]:
pass
else:
return True
return False
if not(hit(dir, info, bod, pos)):
return dir
else:
dirs = ['right', 'left', 'up', 'down']
for i in range(0,4):
newDir = dirs.pop(randint(0,len(dirs)-1))
if not(hit(newDir, info, bod, pos)):
return newDir
return dir
newX, newY = pos[0], pos[1]
if dir == 'right':
newX += size
if dir == 'left':
newX -= size
if dir == 'up':
newY -= size
if dir == 'down':
newY += size
if newX >= width:
return 'up'
if newX < 0:
return 'down'
if newY >= height:
return 'right'
if newY < 0:
return 'left'
return dir
def Person2(pos, bod, dir, info):
print('--------------------------------------')
def hit(pos, bod, dirr, info):
newX, newY = pos[0], pos[1]
if dirr == 'right':
newX += size
if dirr == 'left':
newX -= size
if dirr == 'up':
newY -= size
if dirr == 'down':
newY += size
if newX >= width or newX < 0 or newY >= height or newY < 0:
print('not safe')
return True
for i in info:
if [newX, newY] in i[0]:
print('not safe')
return True
else:
print(i[0])
print(pos)
print(newX, newY)
print('safe')
return False
if len(bod) > 3:
if pos[0] < bod[0][0] and not(hit(pos, bod, 'right', info)):
print('Moving right to follow')
return 'right'
if pos[0] > bod[0][0] and not(hit(pos, bod, 'left', info)):
print('Moving left to follow')
return 'left'
if pos[1] < bod[0][1] and not(hit(pos, bod, 'down', info)):
print('Moving down to follow')
return 'down'
if pos[1] > bod[0][1] and not(hit(pos, bod, 'up', info)):
print('Moving up to follow')
return 'up'
if len(bod) <= 3:
print('length', len(bod))
if dir == 'up':
print(1)
return 'right'
if dir == 'right':
print(2)
return 'down'
if dir == 'down':
print(3)
return 'left'
if dir == 'left':
print(4)
return 'up'
print('didnt follow')
if not(hit(pos, bod, 'up', info)):
print('up')
return 'up'
if not(hit(pos, bod, 'down', info)):
print('down')
return 'down'
if not(hit(pos, bod, 'left', info)):
print('left')
return 'left'
if not(hit(pos, bod, 'right', info)):
print('right')
return 'right'
print('im dead')
return dir
main()