صخرة كل 800 ms
جزء من قسم قواعد اللعبة في رحلة Pygame على Coddy. الدرس 12 من 29.
لعبة إسقاط صخرة واحدة في كل مرة لعبة هادئة. باستخدام مؤقّت، يمكن أن تسقط صخرة جديدة كل 800 ms بينما لا تزال الصخور الأخرى تسقط. احتفظ بالصخور في قائمة:
SPAWN = pygame.USEREVENT + 2
...
if event.type == SPAWN and state == "play":
rocks.append(pygame.Rect(random.randint(0, 456), -24, 24, 24))لكل حدث رقمه الخاص، لذا فإن SPAWN هو USEREVENT + 2، أي رقم واحد بعد POINT. ابدأ مؤقّته بجوار المؤقّت الآخر، واجعل rocks = [] في reset().
في كل إطار، حرّك جميع الصخور، ثم احتفظ فقط بتلك التي لا تزال داخل النافذة:
for rock in rocks:
rock.y += 4
rocks = [rock for rock in rocks if rock.top <= 360]من دون هذا السطر الثاني، ستبقى كل صخرة سقطت في القائمة. ستحرّك اللعبة آلاف الصخور التي لا يستطيع أحد رؤيتها وتختبرها، وستتباطأ كلما طالت مدة لعبك.
يصبح الرسم واختبار الاصطدام أيضًا حلقتين على rocks.
التحدي
متوسط- استبدل
rockبقائمة اسمهاrocks، واجعلها فارغة فيreset(). - أضف
SPAWN = pygame.USEREVENT + 2ومؤقّتًا له كل 800 ms، وابدأه فيreset(). - عند حدوث
SPAWNأثناء اللعب، أضف صخرة أبعادها 24 في 24 عند y -24، مع قيمة x عشوائية من 0 إلى 456. - في كل إطار، حرّك كل صخرة إلى الأسفل بمقدار 4، واحذف الصخور التي تجاوز أعلاها 360، وارسمها جميعًا واختبر كل واحدة منها للتحقق من حدوث اصطدام.
جرّب بنفسك
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Meteor Dodge")
clock = pygame.time.Clock()
heart = pygame.image.load("assets/images/heart.png").convert_alpha()
heart_empty = pygame.image.load("assets/images/heart_empty.png").convert_alpha()
font = pygame.font.Font("assets/fonts/pixel.ttf", 24)
big_font = pygame.font.Font("assets/fonts/pixel.ttf", 48)
WHITE = (240, 240, 240)
PLATE = (60, 60, 90)
POINT = pygame.USEREVENT + 1
def reset():
global player, rock, score, lives, hit_time
player = pygame.Rect(220, 300, 40, 40)
rock = pygame.Rect(random.randint(0, 456), -24, 24, 24)
score = 0
lives = 3
hit_time = -2000
pygame.time.set_timer(POINT, 1000)
def draw_menu():
screen.fill((30, 30, 46))
title = big_font.render("Meteor Dodge", True, WHITE)
title_rect = title.get_rect(center=(240, 140))
pygame.draw.rect(screen, PLATE, title_rect.inflate(24, 12))
screen.blit(title, title_rect)
hint = font.render("Press Enter to play", True, WHITE)
screen.blit(hint, hint.get_rect(center=(240, 200)))
def draw_game():
screen.fill((30, 30, 46))
safe = pygame.time.get_ticks() - hit_time < 1000
if not safe or pygame.time.get_ticks() // 100 % 2 == 0:
pygame.draw.rect(screen, (255, 196, 0), player)
pygame.draw.rect(screen, (235, 80, 80), rock)
score_text = font.render(f"{score:05}", True, WHITE)
score_rect = score_text.get_rect(topright=(470, 10))
pygame.draw.rect(screen, PLATE, score_rect.inflate(12, 8))
screen.blit(score_text, score_rect)
for i in range(3):
if i < lives:
screen.blit(heart, (10 + i * 40, 10))
else:
screen.blit(heart_empty, (10 + i * 40, 10))
def play_frame():
global score, lives, state, hit_time
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.x -= 6
if keys[pygame.K_RIGHT]:
player.x += 6
player.clamp_ip(screen.get_rect())
rock.y += 4
if rock.top > 360:
rock.y = -24
rock.x = random.randint(0, 456)
now = pygame.time.get_ticks()
if rock.colliderect(player) and now - hit_time > 1000:
hit_time = now
lives -= 1
if lives == 0:
state = "over"
draw_game()
def draw_over():
draw_game()
message = big_font.render("Game over", True, WHITE)
screen.blit(message, message.get_rect(center=(240, 160)))
hint = font.render("Press R to play again", True, WHITE)
screen.blit(hint, hint.get_rect(center=(240, 200)))
reset()
state = "menu"
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == POINT and state == "play":
score += 1
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN and state == "menu":
state = "play"
elif event.key == pygame.K_r and state == "over":
reset()
state = "play"
if state == "menu":
draw_menu()
elif state == "play":
play_frame()
else:
draw_over()
pygame.display.flip()
clock.tick(60)
pygame.quit()
جميع دروس قواعد اللعبة
تدرّب بنفسك: Playground لـ Pygame