Python打字小游戏《Alphabet Zoo》

游戏说明:(macOS平台下开发调试)游戏视频

点击屏幕中间的Play按钮。屏幕顶部产生下落的随机字母,敲击键盘上相应的键对应字母消失。字母生成和坠落的速度随着时间由慢变快,难度逐渐增大。坠落到屏幕最下方的字母超过十个,游戏结束。

游戏设置了记分系统,敲对一个键记50分,敲错扣50分。游戏最高分和当前得分分别显示在顶端中间和右边。

另外还添加了背景音乐,敲对、敲错以及字母下落到底部的时候有不同的音效。

由于时间仓促,没有添加注释,这是程序的缺陷。如果以后有时间,会补充完善。

程序用到的字母图案和声音文件无法上传展示。

东抄西问的成果,感谢提供帮助的人。

1. alphabet_zoo.py

import pygame
import time
from pygame.locals import *
from settings import Settings
import game_functions as gf
from game_stats import GameStats
from button import Button
from scoreboard import Scoreboard


def run_game():
    pygame.init()
    az_settings = Settings()
    screen = pygame.display.set_mode((1600, 900))
    pygame.display.set_caption("Alphabet Zoo")
    play_button = Button(screen, "Play")
    stats = GameStats(az_settings)
    sb = Scoreboard(az_settings, screen, stats)
    letters = pygame.sprite.Group()
    start = time.time()
    sleeptime = az_settings.letter_generating_factor
    pygame.mixer.init()
    bg_image1 = pygame.image.load('bg_image.jpg')

    while True:
        screen.blit(bg_image1, (0, 0))
        with open('high_score.txt') as file_object:
            stats.high_score = int(file_object.read())
        sb.prep_high_score()
        now = time.time()
        gf.check_events(az_settings, letters, stats, sb, play_button, screen)
        if stats.game_active:
            gf.update_screen(az_settings, stats, screen, letters, sb, play_button)
            if now - start > sleeptime:
                gf.letter_generator(stats, az_settings, screen, letters)
                start = now
        else:
            gf.update_screen(az_settings, stats, screen, letters, sb, play_button)
            pygame.mixer.music.stop()


run_game()

 

2. game_functions.py

import sys
import pygame
from letter import Letter


def letter_generator(stats, az_settings, screen, letters):
    if stats.lives_left > 0:
        new_letter = Letter(az_settings, screen)
        letters.add(new_letter)
    else:
        letters.empty()
        stats.game_active = False
        pygame.mouse.set_visible(True)


def check_events(az_settings, letters, stats, sb, play_button, screen):
    screen_rect = screen.get_rect()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

        elif event.type == pygame.MOUSEBUTTONDOWN:
            mouse_x, mouse_y = pygame.mouse.get_pos()
            check_play_button(az_settings, stats, play_button, mouse_x, mouse_y, sb)

        elif event.type == pygame.KEYDOWN:
            for ltr in letters:
                if ltr.ascii == event.key and ltr.rect.bottom < screen_rect.bottom:
                    s1 = pygame.mixer.Sound("hit.wav")
                    s1.play()
                    stats.score += az_settings.letter_points
                    sb.prep_score()
                    check_high_score(stats, sb)
                    letters.remove(ltr)
                elif ltr.ascii != event.key and ltr.rect.bottom < screen_rect.bottom and stats.score > 0:
                    s2 = pygame.mixer.Sound("wrong_hit.wav")
                    s2.play()
                    stats.score -= az_settings.letter_points
                    sb.prep_score()


def check_play_button(az_settings, stats, play_button, mouse_x, mouse_y, sb):
    button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
    if button_clicked and not stats.game_active:
        stats.reset_stats()
        sb.prep_score()
        az_settings.initialize_dynamic_settings()
        pygame.mouse.set_visible(False)
        stats.game_active = True
        pygame.mixer.music.load("bg_music.mp3")
        pygame.mixer.music.play(-1)


def letter_fallen(stats):
    if stats.lives_left > 0:
        stats.lives_left -= 1


def check_letter_bottom(screen, letters, stats):
    screen_rect = screen.get_rect()
    for ltr in letters.sprites():
        if ltr.rect.bottom > screen_rect.bottom:
            s3 = pygame.mixer.Sound("oops.wav")
            s3.play()
            ltr.rect.bottom = screen_rect.bottom
            letter_fallen(stats)


def update_screen(az_settings, stats, screen, letters, sb, play_button):
    check_letter_bottom(screen, letters, stats)
    letters.draw(screen)
    letters.update()
    sb.show_score()
    if not stats.game_active:
        play_button.draw_button()
    az_settings.increase_speed()
    pygame.display.flip()


def check_high_score(stats, sb):
    if stats.score > stats.high_score:
        stats.high_score = stats.score
        with open('high_score.txt', 'w') as file_object:
            file_object.write(str(stats.high_score))
        sb.prep_high_score()

3. button.py

import pygame.font


class Button:

    def __init__(self, screen, msg):
        self.screen = screen
        self.screen_rect = screen.get_rect()

        self.width, self.height = 200, 50
        self.button_color = (254, 184, 38)
        self.text_color = (255, 255, 255)
        self.font = pygame.font.SysFont(None, 48)

        self.rect = pygame.Rect(0, 0, self.width, self.height)
        self.rect.center = self.screen_rect.center
        self.prep_msg(msg)

    def prep_msg(self, msg):
        self.msg_image = self.font.render(msg, True, self.text_color,
                                          self.button_color)
        self.msg_image_rect = self.msg_image.get_rect()
        self.msg_image_rect.center = self.rect.center

    def draw_button(self):
        self.screen.fill(self.button_color, self.rect)
        self.screen.blit(self.msg_image, self.msg_image_rect)

4. game_stats.py

class GameStats:
    def __init__(self, az_settings):
        self.az_settings = az_settings
        self.reset_stats()
        self.game_active = False
        self.high_score = 0

    def reset_stats(self):
        self.lives_left = self.az_settings.lives_limit
        self.score = 0

5. scoreboard.py

import pygame.font


class Scoreboard:
    def __init__(self, az_settings, screen, stats):
        self.screen = screen
        self.screen_rect = screen.get_rect()
        self.az_settings = az_settings
        self.stats = stats

        self.text_color = (255, 255, 255)
        self.font = pygame.font.SysFont(None, 48)

        self.prep_score()
        self.prep_high_score()

    def prep_score(self):
        score_str = 'Current Score:' + "{:,}".format(self.stats.score)
        self.score_image = self.font.render(score_str, True, self.text_color,
                                            (14, 111, 108))

        self.score_rect = self.score_image.get_rect()
        self.score_rect.right = self.screen_rect.right - 20
        self.score_rect.top = 20

    def show_score(self):
        self.screen.blit(self.score_image, self.score_rect)
        self.screen.blit(self.high_score_image, self.high_score_rect)

    def prep_high_score(self):
        high_score_str = 'Highest Score: ' + "{:,}".format(self.stats.high_score)
        self.high_score_image = self.font.render(high_score_str, True,
                                                 self.text_color, (14, 111, 108))

        self.high_score_rect = self.high_score_image.get_rect()
        self.high_score_rect.centerx = self.screen_rect.centerx
        self.high_score_rect.top = self.score_rect.top

6. letter.py

import pygame
import random
from pygame.sprite import Sprite


class Letter(Sprite):

    def __init__(self, az_settings, screen):
        super().__init__()
        self.screen = screen
        self.az_settings = az_settings
        a = random.randint(97, 122)
        c = chr(a)
        self.image = pygame.image.load('images/' + c.upper() + '.png')
        self.ascii = a

        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        self.rect.centerx = random.randint(100, self.screen_rect.right - 100)
        self.rect.top = self.screen_rect.top
        self.center = float(self.rect.centerx)

    def update(self):
        if self.rect.bottom < self.screen_rect.bottom:
            self.rect.centery += self.az_settings.letter_speed_factor

7. settings.py

class Settings:
    def __init__(self):
        self.falling_speed_increment = 0.01
        self.letter_generating_increment = 0.1
        self.lives_limit = 10
        self.initialize_dynamic_settings()

    def initialize_dynamic_settings(self):
        self.letter_speed_factor = 5
        self.letter_generating_factor = 3
        self.letter_points = 50

    def increase_speed(self):
        self.letter_speed_factor += self.falling_speed_increment
        self.letter_generating_factor -= self.letter_generating_increment

 

  • 24
    点赞
  • 99
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
好的,以下是一个简单的 Java 多线程实现练习因为打字游戏的代码示例: ```java import java.util.Random; import java.util.Scanner; public class TypingGame { private static final int MAX_THREADS = 5; private static final int MAX_SECONDS = 10; private static final int MAX_SCORE = 100; private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static final Random random = new Random(); private static volatile int score; private static volatile boolean gameOver; public static void main(String[] args) throws InterruptedException { score = 0; gameOver = false; System.out.println("Welcome to Typing Game!"); System.out.println("Type the letter that appears on the screen as fast as possible."); System.out.println("You have " + MAX_SECONDS + " seconds to get the highest score possible."); System.out.println("Let's start!"); Thread[] threads = new Thread[MAX_THREADS]; for (int i = 0; i < MAX_THREADS; i++) { threads[i] = new LetterThread(); threads[i].start(); } Scanner scanner = new Scanner(System.in); long start = System.currentTimeMillis(); while (!gameOver) { System.out.print("Type: "); String input = scanner.nextLine().toUpperCase(); if (input.length() == 1 && ALPHABET.indexOf(input) != -1) { boolean found = false; for (Thread thread : threads) { LetterThread letterThread = (LetterThread) thread; if (letterThread.isRunning() && letterThread.getLetter() == input.charAt(0)) { letterThread.stopRunning(); score += 10; found = true; break; } } if (!found) { score -= 5; } } else { System.out.println("Invalid input."); } if (System.currentTimeMillis() - start >= MAX_SECONDS * 1000) { gameOver = true; } } for (Thread thread : threads) { thread.join(); } System.out.println("Game over!"); System.out.println("Your score is: " + Math.min(score, MAX_SCORE)); } private static class LetterThread extends Thread { private char letter; private volatile boolean running; public LetterThread() { running = true; letter = ALPHABET.charAt(random.nextInt(ALPHABET.length())); } public void run() { while (running) { System.out.print(letter); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.print("\b \b"); } } public char getLetter() { return letter; } public boolean isRunning() { return running; } public void stopRunning() { running = false; } } } ``` 这个实现中,我们创建了一个 `LetterThread` 类来表示每个线程,其中包含了该线程正在输出的字母和一个标识符来表示该线程是否正在运行。我们在 `main` 方法中创建了多个 `LetterThread` 线程并启动它们,同时在用户输入时遍历所有线程查找是否有需要用户输入的字母,如果有则停止该线程的运行并增加用户的得分。当游戏时间到达设定的最大时间时,我们将所有线程停止并统计用户的得分。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值