我正在尝试为我的蛇添加尾巴(最后使用三角形图像而不是方形填充)。虽然我认为我的代码大部分都在工作,但我看到如果我改变了方向,那么最后几秒尾巴会与身体“断开”。 (尾巴指向右侧和身体向下留下间隙)。我试图通过提高我的FPS来解决这个问题,这似乎有用;但是我希望蛇的速度与以前相同,因为我将FPS加倍,我的速度将提高1/2。然而,当我这样做时,我的碰撞检测不同步,如果我放慢速度,我的身体就会掠过我的脸,如果我加速,我会让我的身体断开(阻挡,空间,阻挡)。我尝试了几种不同的方式,所以任何帮助都会受到赞赏。
请注意block_speed = 10,如果我手动输入10就可以了,但如果我改为5或20,或者我改为值为5或20的变量(比如说速度),代码不起作用。
代码:
import pygame, sys
from pygame.locals import*
import time
import random
import os
pygame.init()
#GUI Settings
display_Width = 800
display_Height = 600
gameDisplay = pygame.display.set_mode((display_Width,display_Height))
pygame.display.set_caption("Gluttonous Snake")
gameicon = pygame.image.load('icon.png')
potatoimg = pygame.image.load('potato.png')
pygame.display.set_icon(gameicon)
FPS = 15
direction = "up"
#set path to where to .py/.exe is
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)
print(dname)
snakeheadimg = pygame.image.load('snakehead.png')
snaketailimg = pygame.image.load('snaketail.png')
appleimg = pygame.image.load('apple.png')
#define colors
white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
yellow = (255,255,0)
eggwhite = (255,255,204)
lightgrey = (242,242,242)
#Game Variables
block_size = 10
clock = pygame.time.Clock()
def game_intro():
intro = True
x = 500
y = 400
x_dir = "left"
while intro:
gameDisplay.fill(eggwhite)
gameDisplay.blit(potatoimg, (50, 25))
message_to_screen("Potato Productions Presents...", black, -100, size=45)
message_to_screen("Gluttonous Snake", green, -25, size=75)
message_to_screen("A game made by a potato to run on a potato", black, 50, size=25)
message_to_screen("Press C to Start!", red, 75, size=25)
gameDisplay.blit(gameicon, (x, y))
if x_dir == "left":
if x > 0:
x -= 10
else:
x_dir = "right"
else:
if x < 500:
x += 10
else:
x_dir = "left"
if x < 125 or x > 375:
y -= 9.66
else:
y += 10
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
intro = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_c:
intro = False
if event.key == pygame.K_q:
pygame.quit()
quit()
def pickFont(name,size):
font = pygame.font.SysFont(name, size, bold=False)
return font
#font size = 25
#font = pygame.font.SysFont("comicsansms",size=25)
def snake(snakelist):
# faster GPU method is
# gameDisplay.fill(red, rect=[200,200,50,50])
if direction == "left":
head = pygame.transform.rotate(snakeheadimg,90)
if direction == "right":
head = pygame.transform.rotate(snakeheadimg,270)
if direction == "down":
head = pygame.transform.rotate(snakeheadimg,180)
if direction == "up":
head = pygame.transform.rotate(snakeheadimg,0)
gameDisplay.blit(head,(snakelist[-1][0],snakelist[-1][1]))
#-1 because we are drawing that above
# for XnY in snakelist[:-1]:
# #gameDisplay.fill(green, rect=[lead_x, lead_y, block_size, block_size])
# gameDisplay.fill(green, rect=[XnY[0], XnY[1], block_size, block_size])
# -1 because we are drawing that above
if len(snakelist) >= 2:
for XnY in snakelist[1:-1]:
gameDisplay.fill(green, rect=[XnY[0], XnY[1], block_size, block_size])
if direction == "up":
tail = pygame.transform.rotate(snaketailimg, 180)
if snakelist[1][0] > snakelist[0][0]:
tail = pygame.transform.rotate(snaketailimg, 90)
elif snakelist[1][0] < snakelist[0][0]:
tail = pygame.transform.rotate(snaketailimg, 270)
elif snakelist[1][1] > snakelist[0][1]:
tail = pygame.transform.rotate(snaketailimg, 0)
elif snakelist[1][1] < snakelist[0][1]:
tail = pygame.transform.rotate(snaketailimg, 180)
gameDisplay.blit(tail, (snakelist[-len(snakelist)][0], snakelist[-len(snakelist)][1]))
def text_objects(text, color,size):
font = pickFont("comicsansms", size)
textSurface = font.render(text,True,color,size)
return textSurface, textSurface.get_rect()
def message_to_screen(msg,color,y_displace=0, size=25):
#True is anti-aliasing
textSurf, textRect = text_objects(msg, color, size)
textRect.center = (display_Width/2),(display_Height/2) + y_displace
gameDisplay.blit(textSurf,textRect)
def gameLoop():
# set up variables
global direction
gameExit = False
gameOver = False
lead_x = display_Width / 2
lead_y = display_Height / 2
coinflip = random.randint(0, 1)
if coinflip == 0:
coinflip = random.randint(0, 1)
if coinflip == 0:
lead_x_change = **10**
lead_y_change = 0
direction = "right"
else:
lead_x_change = -**10**
lead_y_change = 0
direction = "left"
else:
coinflip = random.randint(0, 1)
if coinflip == 0:
lead_x_change = 0
lead_y_change = **10**
direction = "down"
else:
lead_x_change = 0
lead_y_change = -**10**
direction = "up"
#lead_x_change = 0
#lead_y_change = 0
#the 10 is round to 10
randAppleX = random.randrange(0, display_Width - block_size, 10)
randAppleY = random.randrange(0, display_Height - block_size, 10)
snakelist = []
snakelength = 1
while not gameExit:
while gameOver == True:
gameDisplay.fill(white)
#message_to_screen("Game over \n Press C to play again or Q to quit", red)
message_to_screen("Game Over", red, y_displace=-50, size=75)
message_to_screen("Press C to play again or Q to quit",black,y_displace=50,size=25)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
gameExit = True
gameOver = False
if event.key == pygame.K_c:
gameLoop()
#gameOver = False
for event in pygame.event.get():
#shows every mouse move and key pressed
#print(event)
if event.type == pygame.QUIT:
gameExit = True
gameOver = False
#check for single depress of keys
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
#lead_x -= 10
#this is so they can't back over themselves
if lead_x_change != **block_size**:
lead_x_change = - **block_size**
lead_y_change = 0
direction = "left"
#elif is only tested if the ifs and elifs above it are not true
elif event.key == pygame.K_RIGHT:
#lead_x += 10
if lead_x_change != -**block_size**:
lead_x_change = **block_size**
lead_y_change = 0
direction = "right"
elif event.key == pygame.K_UP:
if lead_y_change != **block_size**:
lead_x_change = 0
lead_y_change = -**block_size**
direction = "up"
elif event.key == pygame.K_DOWN:
if lead_y_change != -**block_size**:
lead_x_change = 0
lead_y_change = **block_size**
direction = "down"
# user releases key
# if event.type == pygame.KEYUP:
# if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
# lead_x_change = 0
#Ends the game once the square has left the window
if lead_x >= (display_Width - block_size) or lead_x <= 0 or lead_y >= (display_Height - block_size) or lead_y <= 0:
print("snake left at " + str(lead_x)+","+str(lead_y))
lead_x_change = 0
lead_y_change = 0
gameOver = True
lead_x += lead_x_change
lead_y += lead_y_change
gameDisplay.fill(lightgrey)
snakehead = []
snakehead.append(lead_x)
snakehead.append(lead_y)
snakelist.append(snakehead)
if len(snakelist) > snakelength:
del snakelist[0]
#-1 because last element is the head
for eachSegement in snakelist[:-1]:
if eachSegement == snakehead:
print("snake eats itself")
gameOver = True
#draw snake first so if apple spawns on it I can still see it
snake(snakelist)
#gameDisplay.fill(red, rect=[randAppleX, randAppleY, block_size, block_size])
gameDisplay.blit(appleimg,(randAppleX, randAppleY))
pygame.display.update()
#better collison detection as part of the snake can go over part of the apple
# if lead_x >= randAppleX and lead_x + block_size < randAppleX + block_size or lead_x + block_size >= randAppleX and lead_x + block_size < randAppleX + block_size:
# if lead_y >= randAppleY and lead_y < randAppleY + block_size or lead_y + block_size >= randAppleY and lead_y + block_size < randAppleY + block_size:
if lead_x >= randAppleX:
if lead_x + block_size <= randAppleX + block_size:
if lead_y >= randAppleY:
if lead_y + block_size <= randAppleY + block_size:
print("nom nom nom")
randAppleX = random.randrange(0, display_Width - block_size, 10)
randAppleY = random.randrange(0, display_Height - block_size, 10)
snakelength += 1
#used to make FPS
clock.tick(FPS)
pygame.quit()
quit()
game_intro()
gameLoop()
回复提供的答案:
非常感谢我会调查此事。你能弄清楚为什么我不能调整速度吗?如果我减慢速度,它会将身体吸过头部似乎很奇怪,或者如果我加快它会留下空隙。部分是我正在调整速度是粗体
答案 0 :(得分:0)
您可以通过执行以下操作来平滑一些事情(并使代码更清晰):
1 - 存储尾部(头部)旋转图像:
tail_left = pygame.transform.rotate(snaketailimg, 180) # choose appropriate rotation
tail_right = ...
tail_up = ...
tail_down = ...
2 - 确定蛇走向哪个方向,并从字典中查找图像(例如)
tail_oriented_images = {'left': tail_left, 'right': tail_right, ...}
...
tail_direction = get_tail_direction() # to be extracted
3-然后将snake(snakelist)
中的if cascade替换为:
tail = tail_oriented_images[tail_direction]
4-为头部方向做同样的事情