在我使用 pygame 制作的这个蛇游戏中,我很难弄清楚速度的物理特性。问题是,一旦我将 fps 设置为 15 以上,蛇的速度也会增加。我知道这与我发现可以工作的毫秒等有关,高 fps 和慢速。但是那时,我无法让 X 和 Y 正确,这样我就可以吃苹果了。在这一点上,我几乎迷路了。这是我的整个蛇游戏。我不介意分享它,因为我想在它完成后立即开源它。
import pygame
import random
from pygame.locals import (
K_UP,
K_DOWN,
K_LEFT,
K_RIGHT,
K_ESCAPE,
KEYDOWN,
K_n,
K_o,
K_w,
K_a,
K_s,
K_d,
K_RETURN,
QUIT,
)
pygame.init()
pygame.display.set_caption("Le jeu snake !")
class Game:
def __init__(self):
self.white = (255, 255, 255)
self.black = (0, 0, 0)
self.red = (255, 0, 0)
self.blue = (0, 0, 255)
self.green = (0, 255, 0)
self.background = pygame.image.load("snake_bg.png")
self.SCREEN_WIDTH = 600
self.SCREEN_HEIGHT = 400
self.screen = pygame.display.set_mode([self.SCREEN_WIDTH, self. SCREEN_HEIGHT])
self.running = True
self.paused = False
self.agreed = False
self.snake_block = 25
self.apple_block = 25
self.snake_x = 0
self.snake_y = 0
self.apple_x = 0
self.apple_y = 0
self.center = (self.SCREEN_WIDTH // 2, self.SCREEN_HEIGHT // 2)
self.width_grid = 0
self.height_grid = 0
self.snake_x_change = 0
self.snake_y_change = 0
self.snake_list = list()
self.snake_head = list()
self.snake_length = 1
self.score = 0
self.clock = pygame.time.Clock()
self.velocity = 25
def draw_grid(self):
self.width_grid = [x * 25 for x in range(0, self.SCREEN_WIDTH)]
self.height_grid = [y * 25 for y in range(0, self.SCREEN_WIDTH)]
"""for grid_x in self.width_grid:
pygame.draw.line(self.screen, self.white, [0, grid_x], [self.SCREEN_WIDTH, grid_x], 2)
if grid_x >= 600:
break
for grid_y in self.height_grid:
pygame.draw.line(self.screen, self.white, [grid_y, 0], [grid_y, self.SCREEN_WIDTH], 2)
if grid_y >= 600:
break"""
def set_position(self, thing):
if thing == "snake":
self.snake_x = self.SCREEN_WIDTH / 2
self.snake_y = self.SCREEN_HEIGHT / 2
if thing == "apple":
self.apple_x = random.choice(self.width_grid[0:24])
self.apple_y = random.choice(self.height_grid[0:16])
def draw(self, obj):
if obj == "snake":
for XnY in self.snake_list:
pygame.draw.rect(self.screen, self.green, (XnY[0], XnY[1], self.snake_block, self.snake_block), 2)
elif obj == "apple":
pygame.draw.rect(self.screen, self.red, (self.apple_x, self.apple_y, self.apple_block, self.apple_block))
def set_keys_direction(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
if event.type == KEYDOWN:
if event.key == K_DOWN:
self.snake_y_change = self.velocity
self.snake_x_change = 0
if event.key == K_RIGHT:
self.snake_x_change = self.velocity
self.snake_y_change = 0
if event.key == K_UP:
self.snake_y_change = -self.velocity
self.snake_x_change = 0
if event.key == K_LEFT:
self.snake_x_change = -self.velocity
self.snake_y_change = 0
if event.key == K_s:
self.snake_y_change = self.velocity
self.snake_x_change = 0
if event.key == K_w:
self.snake_y_change = -self.velocity
self.snake_x_change = 0
if event.key == K_d:
self.snake_x_change = self.velocity
self.snake_y_change = 0
if event.key == K_a:
print("Q works")
self.snake_x_change = -self.velocity
self.snake_y_change = 0
if not self.agreed:
if event.key == K_ESCAPE:
pygame.quit()
if event.key == K_RETURN:
self.agreed = True
if self.agreed:
if event.key == K_n:
pygame.quit()
if event.key == K_o:
self.paused = False
self.score = 0
if event.key == K_ESCAPE:
self.snake_length += 1
self.elapsed = self.clock.tick(30)
def build_snake(self):
snake_head = list()
snake_head.append(self.snake_x)
snake_head.append(self.snake_y)
self.snake_list.append(snake_head)
if len(self.snake_list) > self.snake_length:
del self.snake_list[0]
for snake in self.snake_list[:-1]:
if snake == snake_head:
self.snake_reset()
self.draw("snake")
def check_apple_eaten(self):
if self.snake_x == self.apple_x and self.snake_y == self.apple_y:
self.set_position("apple")
self.snake_length += 1
self.score += 1
def snake_borders_check(self):
if self.snake_x < 0 or self.snake_x > self.SCREEN_WIDTH - 25:
self.snake_reset()
if self.snake_y < 0 or self.snake_y > self.SCREEN_HEIGHT - 25:
self.snake_reset()
def snake_reset(self):
self.paused = True
self.set_position("snake")
self.set_position("apple")
del self.snake_list[1:]
self.snake_length = 1
def snake_bit_check(self):
pass
"""if len(self.snake_list) >= 6:
for snake in self.snake_list[2:]:
if self.snake_list[0][0] == snake[0] and self.snake_list[0][1] == snake[1]:
print("SnakeList[0][0]: {0} || SnakeList[0][1]: {0}".format(self.snake_list[0][0],
self.snake_list[0][1]))
print("snake: {0}".format(snake))
self.snake_reset()"""
def show_text(self, message, position, font_name="fonts/arial_narrow_7.ttf", font_size=32):
font = pygame.font.Font(font_name, font_size)
text = font.render(message, True, self.white, self.black)
text_rect = text.get_rect(center=position)
self.screen.blit(text, text_rect)
def game_over(self):
self.screen.blit(self.background, (0, 0))
self.show_text("Ton score: {0}".format(self.score), (100, 20))
self.show_text("Tu as perdu ! Veux-tu recommencer ?",
(self.SCREEN_WIDTH // 2, self.SCREEN_HEIGHT // 2 - 100))
self.show_text("Appuie sur O (oui) ou sur N (non)",
(self.SCREEN_WIDTH // 2, self.SCREEN_HEIGHT // 2))
self.show_text("Sinon, Echap pour quitter",
(self.SCREEN_WIDTH // 2, self.SCREEN_HEIGHT // 2 + 100))
def check_agreement(self):
self.show_text("Ceci est une réplique du jeu snake faite",
(self.SCREEN_WIDTH // 2, self.SCREEN_HEIGHT // 2 - 100))
self.show_text("par Kevin pour un simple projet personnel.",
(self.SCREEN_WIDTH // 2 + 1, self.SCREEN_HEIGHT // 2 - 70))
self.show_text("Si vous voulez jouer au jeu, appuyez sur la",
(self.SCREEN_WIDTH // 2 + 5, self.SCREEN_HEIGHT // 2 - 20))
self.show_text("touche Entrée, sinon Echap pour quitter !",
(self.SCREEN_WIDTH // 2 - 11, self.SCREEN_HEIGHT // 2 + 10))
self.show_text("- Utilise les touches flèches pour changer de direction",
(self.SCREEN_WIDTH // 2 - 10, self.SCREEN_HEIGHT // 2 + 55), font_size=24)
self.show_text("- Ne te mord pas toi-même",
(self.SCREEN_WIDTH // 2 - 144, self.SCREEN_HEIGHT // 2 + 75), font_size=24)
self.show_text("- Ne rentre pas dans les bords",
(self.SCREEN_WIDTH // 2 - 128, self.SCREEN_HEIGHT // 2 + 95), font_size=24)
def game(self):
self.draw_grid()
self.set_position("snake")
self.set_position("apple")
while self.running:
self.screen.blit(self.background, (0, 0))
self.set_keys_direction()
if self.agreed:
self.draw_grid()
self.draw("apple")
self.build_snake()
self.check_apple_eaten()
self.snake_bit_check()
self.snake_borders_check()
else:
self.check_agreement()
if not self.paused:
self.snake_x += self.snake_x_change
self.snake_y += self.snake_y_change
else:
self.game_over()
self.clock.tick(30)
pygame.display.flip()
game = Game()
game.game()
pygame.quit()