代码结构
app.png是游戏运行主界面的图片(可以加载自己喜欢的主界面图片)
Assets文件夹里面装的是一些需要用到的游戏图片
全部都可以替换为自己喜欢的图片
Fonts里面装的是
Sounds文件夹里面装的是
一 . 主程序代码
1.运行这个代码使得游戏开始
2.主界面的图片可以自己下载一些喜欢的图片 修改路径即可
3.报错就是缺少必要文件 有需要的可以联系我 (我把整个代码给你)
# 导入必要的包
import json
import random
import pygame
from threading import Thread
from objects import Tile, Square, Text, Button, Counter
pygame.init()
SCREEN = WIDTH, HEIGHT = 288, 512
TILE_WIDTH = WIDTH // 4
TILE_HEIGHT = 130
info = pygame.display.Info()
width = info.current_w
height = info.current_h
if width >= height:
win = pygame.display.set_mode(SCREEN, pygame.NOFRAME)
else:
win = pygame.display.set_mode(SCREEN, pygame.NOFRAME | pygame.SCALED | pygame.FULLSCREEN)
clock = pygame.time.Clock()
FPS = 30
# COLORS *********************************************************************
WHITE = (255, 255, 255)
GRAY = (75, 75, 75)
BLUE = (30, 144, 255)
# IMAGES *********************************************************************
bg_img = pygame.image.load('Assets/bg.png')
bg_img = pygame.transform.scale(bg_img, (WIDTH, HEIGHT))
piano_img = pygame.image.load('Assets/piano.png')
piano_img = pygame.transform.scale(piano_img, (212, 212))
title_img = pygame.image.load('Assets/title.png')
title_img = pygame.transform.scale(title_img, (200, 50))
start_img = pygame.image.load('Assets/start.png')
start_img = pygame.transform.scale(start_img, (120, 40))
start_rect = start_img.get_rect(center=(WIDTH//2, HEIGHT-80))
overlay = pygame.image.load('Assets/red overlay.png')
overlay = pygame.transform.scale(overlay, (WIDTH, HEIGHT))
# MUSIC **********************************************************************
buzzer_fx = pygame.mixer.Sound('Sounds/piano-buzzer.mp3')
pygame.mixer.music.load('Sounds/piano-bgmusic.mp3')
pygame.mixer.music.set_volume(0.8)
pygame.mixer.music.play(loops=-1)
# FONTS **********************************************************************
score_font = pygame.font.Font('Fonts/Futura condensed.ttf', 32)
title_font = pygame.font.Font('Fonts/Alternity-8w7J.ttf', 30)
gameover_font = pygame.font.Font('Fonts/Alternity-8w7J.ttf', 40)
title_img = title_font.render('Piano Tiles', True, WHITE)
# BUTTONS ********************************************************************
close_img = pygame.image.load('Assets/closeBtn.png')
replay_img = pygame.image.load('Assets/replay.png')
sound_off_img = pygame.image.load("Assets/soundOffBtn.png")
sound_on_img = pygame.image.load("Assets/soundOnBtn.png")
close_btn = Button(close_img, (24, 24), WIDTH // 4 - 18, HEIGHT//2 + 120)
replay_btn = Button(replay_img, (36,36), WIDTH // 2 - 18, HEIGHT//2 + 115)
sound_btn = Button(sound_on_img, (24, 24), WIDTH - WIDTH // 4 - 18, HEIGHT//2 + 120)
# GROUPS & OBJECTS ***********************************************************
tile_group = pygame.sprite.Group()
square_group = pygame.sprite.Group()
text_group = pygame.sprite.Group()
time_counter = Counter(win, gameover_font)
# FUNCTIONS ******************************************************************
def get_speed(score):
return 200 + 5 * score
def play_notes(notePath):
pygame.mixer.Sound(notePath).play()
# NOTES **********************************************************************
with open('notes.json') as file:
notes_dict = json.load(file)
# VARIABLES ******************************************************************
score = 0
high_score = 0
speed = 0
clicked = False
pos = None
home_page = True
game_page = False
game_over = False
sound_on = True
count = 0
overlay_index = 0
running = True
while running:
pos = None
count += 1
if count % 100 == 0:
square = Square(win)
square_group.add(square)
counter = 0
win.blit(bg_img, (0,0))
square_group.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE or \
event.key == pygame.K_q:
running = False
if event.type == pygame.MOUSEBUTTONDOWN and not game_over:
pos = event.pos
if home_page:
win.blit(piano_img, (WIDTH//8, HEIGHT//8))
win.blit(start_img, start_rect)
win.blit(title_img, (WIDTH // 2 - title_img.get_width() / 2 + 10, 300))
if pos and start_rect.collidepoint(pos):
home_page = False
game_page = True
x = random.randint(0, 3)
t = Tile(x * TILE_WIDTH, -TILE_HEIGHT, win)
tile_group.add(t)
pos = None
notes_list = notes_dict['2']
note_count = 0
pygame.mixer.set_num_channels(len(notes_list))
if game_page:
time_counter.update()
if time_counter.count <= 0:
for tile in tile_group:
tile.update(speed)
if pos:
if tile.rect.collidepoint(pos):
if tile.alive:
tile.alive = False
score += 1
if score >= high_score:
high_score = score
note = notes_list[note_count].strip()
th = Thread(target=play_notes, args=(f'Sounds/{note}.ogg', ))
th.start()
th.join()
note_count = (note_count + 1) % len(notes_list)
tpos = tile.rect.centerx - 10, tile.rect.y
text = Text('+1', score_font, tpos, win)
text_group.add(text)
pos = None
if tile.rect.bottom >= HEIGHT and tile.alive:
if not game_over:
tile.color = (255, 0, 0)
buzzer_fx.play()
game_over = True
if pos:
buzzer_fx.play()
game_over = True
if len(tile_group) > 0:
t = tile_group.sprites()[-1]
if t.rect.top + speed >= 0:
x = random.randint(0, 3)
y = -TILE_HEIGHT - (0 - t.rect.top)
t = Tile(x * TILE_WIDTH, y, win)
tile_group.add(t)
text_group.update(speed)
img1 = score_font.render(f'Score : {score}', True, WHITE)
win.blit(img1, (70 - img1.get_width() / 2, 10))
img2 = score_font.render(f'High : {high_score}', True, WHITE)
win.blit(img2, (200 - img2.get_width() / 2, 10))
for i in range(4):
pygame.draw.line(win, WHITE, (TILE_WIDTH * i, 0), (TILE_WIDTH*i, HEIGHT), 1)
speed = int(get_speed(score) * (FPS / 1000))
if game_over:
speed = 0
if overlay_index > 20:
win.blit(overlay, (0,0))
img1 = gameover_font.render('Game over', True, WHITE)
img2 = score_font.render(f'Score : {score}', True, WHITE)
win.blit(img1, (WIDTH // 2 - img1.get_width() / 2, 180))
win.blit(img2, (WIDTH // 2 - img2.get_width() / 2, 250))
if close_btn.draw(win):
running = False
if replay_btn.draw(win):
index = random.randint(1, len(notes_dict))
notes_list = notes_dict[str(index)]
note_count = 0
pygame.mixer.set_num_channels(len(notes_list))
text_group.empty()
tile_group.empty()
score = 0
speed = 0
overlay_index = 0
game_over = False
time_counter = Counter(win, gameover_font)
x = random.randint(0, 3)
t = Tile(x * TILE_WIDTH, -TILE_HEIGHT, win)
tile_group.add(t)
if sound_btn.draw(win):
sound_on = not sound_on
if sound_on:
sound_btn.update_image(sound_on_img)
pygame.mixer.music.play(loops=-1)
else:
sound_btn.update_image(sound_off_img)
pygame.mixer.music.stop()
else:
overlay_index += 1
if overlay_index % 3 == 0:
win.blit(overlay, (0,0))
pygame.draw.rect(win, BLUE, (0,0, WIDTH, HEIGHT), 2)
clock.tick(FPS)
pygame.display.update()
pygame.quit()
二.note_editor.py代码
# 导入josn文件
import json
twinkle_twinkle = ['c4','c4','g4','g4','a4','a4','g4',\
'f4','f4','e4','e4','d4','d4','c4',\
'g5','g5','f4','f4','e4','e4','d4',\
'g5','g5','f4','f4','e4','e4','d4',\
'c4','c4','g4','g4','a4','a4','g4',\
'f4','f4','e4','e4','d4','d4','c4',\
]
happy_birthday = ["g4", "g4", "a4", "g4", "c5", "b4",\
"g4", "g4", "a4", "g4", "d5", "c5",\
"g4", "g4", "g5", "e5", "c5", "b4", "a4",\
"f5", "f5", "e5", "c5", "d5", "c5"]
jan_gan_man = ['c5', 'd5', 'e5', 'e5', 'e5', 'e5', 'e5',\
'e5', 'e5', 'e5', 'e5', 'd5', 'e5', 'f5',\
'e5', 'e5', 'e5', 'd5', 'd5', 'd5', 'b4',\
'd5', 'c5', 'c5', 'g5', 'g5', 'g5', 'g5',\
'g5', 'f-5', 'g5', 'g5', 'g5', 'f-5', 'a5',\
'g5', 'f5', 'f5', 'f5', 'e5', 'e5', 'f5',\
'd5', 'f5', 'e5', 'e5', 'e5', 'e5', 'e5',\
'd5', 'g5', 'g5', 'g5', 'f5', 'f5', 'e5',\
'e5', 'e5', 'd5', 'd5', 'd5', 'd5', 'b4',\
'd5', 'c5', 'c5', 'd5', 'e5', 'e5', 'e5',\
'e5', 'd5', 'e5', 'f5', 'e5', 'f5', 'g5',\
'g5', 'g5', 'f5', 'e5', 'd5', 'f5', 'e5',\
'e5', 'e5', 'd5', 'd5', 'd5', 'd5', 'b4',\
'd5', 'c5', 'g5', 'g5', 'g5', 'g5', 'g5',\
'g5', 'f-5', 'g5', 'g5', 'g5', 'f-5', 'a5',\
'g5', 'f5', 'f5', 'f5', 'e5', 'e5', 'f5',\
'df', 'e5', 'c5', 'b4', 'c5', 'b4', 'a5',\
'b4', 'a5', 'g5', 'a5', 'c5', 'c5', 'd5',\
'd5', 'e5', 'e5', 'd5', 'e5', 'f5']
o_mere_dil_ke_chain = ['a4', 'g4', 'a4', 'a4', 'g4', 'a4',\
'g4', 'e4', 'b4', 'g4', 'a4', 'a4',\
'g4', 'a4', 'g4', 'e4', 'g4', 'e4',\
'd4', 'd4', 'e4', 'e4', 'g4', 'g4',\
'a4', 'a4', 'b4', 'b4', 'g4', 'a4',\
'b4', 'b4', 'g4', 'a4', 'c5', 'b4',\
'a4', 'c5', 'b4', 'a4', 'c5', 'b4', 'a4']
naruto_theme = ['a4', 'b4', 'a4', 'g4', 'e4', 'g4', 'a4', 'd4',\
'c4', 'd4', 'c4', 'a3', 'b3', 'a4', 'b4', 'a4',\
'g4', 'e4', 'g4', 'a4', 'd4', 'c4', 'd4', 'c4',\
'a3', 'a3', 'e4', 'd4', 'c4', 'a3', 'e4', 'd4',\
'e4', 'a4', 'c5', 'b4', 'a4', 'g4', 'a4', 'e4',\
'd4', 'e4', 'd4', 'b3', 'a3', 'a3', 'e4', 'd4',\
'c4', 'a3', 'e4', 'd4', 'e4', 'a4', 'c5', 'b4',\
'a4', 'g4', 'a4', 'e4', 'g4', 'a4', 'a4', 'b4',\
'a4', 'g4', 'e4', 'g4', 'a4', 'd4', 'c4', 'd4',\
'c4', 'a3', 'b3', 'g3', 'a4', 'b4', 'a4', 'g4',\
'e4', 'g4', 'a4', 'd4', 'c4', 'd4', 'c4', 'a3',\
'a3', 'e4', 'd4', 'c4', 'a3', 'e4', 'd4', 'e4',\
'a4', 'c5', 'b4', 'a4', 'g4', 'a4', 'e4', 'd4',\
'e4', 'd4', 'b3', 'a3', 'a3', 'e4', 'd4', 'c4',\
'a3', 'e4', 'd4', 'e4', 'a4', 'c5', 'b4', 'a4',\
'g4', 'a4', 'e4', 'g4', 'a4', 'a4', 'b4', 'a4',\
'g4', 'e4', 'g4', 'a4', 'd4', 'c4', 'd4', 'c4',\
'a3', 'b3', 'g3', 'a4', 'b4', 'a4', 'g4', 'e4',\
'g4', 'a4', 'd4', 'c4', 'd4', 'c4', 'a3']
notes = {
'1' : twinkle_twinkle,
'2' : happy_birthday,
'3' : jan_gan_man,
'4' : o_mere_dil_ke_chain,
'5' : naruto_theme
}
with open('notes.json', 'w') as file:
json.dump(notes, file)
三.objects.py代码
import pygame
import random
SCREEN = WIDTH, HEIGHT = 288, 512
TILE_WIDTH = WIDTH // 4
TILE_HEIGHT = 130
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (30, 144, 255)
BLUE2 = (2, 239, 239)
PURPLE = (191, 64, 191)
class Tile(pygame.sprite.Sprite):
def __init__(self, x, y, win):
super(Tile, self).__init__()
self.win = win
self.x, self.y = x, y
self.color = BLACK
self.alive = True
self.surface = pygame.Surface((TILE_WIDTH, TILE_HEIGHT), pygame.SRCALPHA)
self.rect = self.surface.get_rect()
self.rect.x = x
self.rect.y = y
self.center = TILE_WIDTH//2, TILE_HEIGHT//2 + 15
self.line_start = self.center[0], self.center[1]-18
self.line_end = self.center[0], 20
def update(self, speed):
self.rect.y += speed
if self.rect.y >= HEIGHT:
self.kill()
if self.alive:
pygame.draw.rect(self.surface, self.color, (0,0, TILE_WIDTH, TILE_HEIGHT))
pygame.draw.rect(self.surface, PURPLE, (0,0, TILE_WIDTH, TILE_HEIGHT), 4)
pygame.draw.rect(self.surface, BLUE2, (0,0, TILE_WIDTH, TILE_HEIGHT), 2)
pygame.draw.line(self.surface, BLUE, self.line_start, self.line_end, 3)
pygame.draw.circle(self.surface, BLUE, self.center, 15, 3)
else:
pygame.draw.rect(self.surface, (0,0,0, 90), (0,0, TILE_WIDTH, TILE_HEIGHT))
self.win.blit(self.surface, self.rect)
class Text(pygame.sprite.Sprite):
def __init__(self, text, font, pos, win):
super(Text, self).__init__()
self.win = win
self.x,self.y = pos
self.initial = self.y
self.image = font.render(text, True, (255, 255, 255))
def update(self, speed):
self.y += speed
if self.y - self.initial >= 100:
self.kill()
self.win.blit(self.image, (self.x, self.y))
class Counter(pygame.sprite.Sprite):
def __init__(self, win, font):
super(Counter, self).__init__()
self.win = win
self.font = font
self.index = 1
self.count = 3
def update(self):
if self.index % 30 == 0:
self.count -= 1
self.index += 1
if self.count > 0:
self.image = self.font.render(f'{self.count}', True, (255, 255, 255))
self.win.blit(self.image, (WIDTH//2-16, HEIGHT//2-25))
class Square(pygame.sprite.Sprite):
def __init__(self, win):
super(Square, self).__init__()
self.win = win
self.color = (255, 255, 255)
self.speed = 3
self.angle = 0
self.side = random.randint(15, 40)
x = random.randint(self.side, WIDTH-self.side)
y = 0
self.surface = pygame.Surface((self.side, self.side), pygame.SRCALPHA)
self.rect = self.surface.get_rect(center=(x, y))
def update(self):
center = self.rect.center
self.angle = (self.angle + self.speed) % 360
image = pygame.transform.rotate(self.surface , self.angle)
self.rect = image.get_rect()
self.rect.center = center
self.rect.y += 1.5
if self.rect.top >= HEIGHT:
self.kill()
pygame.draw.rect(self.surface, self.color, (0,0, self.side, self.side), 4)
pygame.draw.rect(self.surface, (30, 144, 255, 128), (2,2, self.side-4, self.side-4), 2)
self.win.blit(image, self.rect)
class Button(pygame.sprite.Sprite):
def __init__(self, img, scale, x, y):
super(Button, self).__init__()
self.scale = scale
self.image = pygame.transform.scale(img, self.scale)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.clicked = False
def update_image(self, img):
self.image = pygame.transform.scale(img, self.scale)
def draw(self, win):
action = False
pos = pygame.mouse.get_pos()
if self.rect.collidepoint(pos):
if pygame.mouse.get_pressed()[0] and not self.clicked:
action = True
self.clicked = True
if not pygame.mouse.get_pressed()[0]:
self.clicked = False
win.blit(self.image, self.rect)
return action
四.notes.json代码
{"1": ["c4", "c4", "g4", "g4", "a4", "a4", "g4", "f4", "f4", "e4", "e4", "d4", "d4", "c4", "g5", "g5", "f4", "f4", "e4", "e4", "d4", "g5", "g5", "f4", "f4", "e4", "e4", "d4", "c4", "c4", "g4", "g4", "a4", "a4", "g4", "f4", "f4", "e4", "e4", "d4", "d4", "c4"], "2": ["g4", "g4", "a4", "g4", "c5", "b4", "g4", "g4", "a4", "g4", "d5", "c5", "g4", "g4", "g5", "e5", "c5", "b4", "a4", "f5", "f5", "e5", "c5", "d5", "c5"], "3": ["c5", "d5", "e5", "e5", "e5", "e5", "e5", "e5", "e5", "e5", "e5", "d5", "e5", "f5", "e5", "e5", "e5", "d5", "d5", "d5", "b4", "d5", "c5", "c5", "g5", "g5", "g5", "g5", "g5", "f-5", "g5", "g5", "g5", "f-5", "a5", "g5", "f5", "f5", "f5", "e5", "e5", "f5", "d5", "f5", "e5", "e5", "e5", "e5", "e5", "d5", "g5", "g5", "g5", "f5", "f5", "e5", "e5", "e5", "d5", "d5", "d5", "d5", "b4", "d5", "c5", "c5", "d5", "e5", "e5", "e5", "e5", "d5", "e5", "f5", "e5", "f5", "g5", "g5", "g5", "f5", "e5", "d5", "f5", "e5", "e5", "e5", "d5", "d5", "d5", "d5", "b4", "d5", "c5", "g5", "g5", "g5", "g5", "g5", "g5", "f-5", "g5", "g5", "g5", "f-5", "a5", "g5", "f5", "f5", "f5", "e5", "e5", "f5", "df", "e5", "c5", "b4", "c5", "b4", "a5", "b4", "a5", "g5", "a5", "c5", "c5", "d5", "d5", "e5", "e5", "d5", "e5", "f5"], "4": ["a4", "g4", "a4", "a4", "g4", "a4", "g4", "e4", "b4", "g4", "a4", "a4", "g4", "a4", "g4", "e4", "g4", "e4", "d4", "d4", "e4", "e4", "g4", "g4", "a4", "a4", "b4", "b4", "g4", "a4", "b4", "b4", "g4", "a4", "c5", "b4", "a4", "c5", "b4", "a4", "c5", "b4", "a4"], "5": ["a4", "b4", "a4", "g4", "e4", "g4", "a4", "d4", "c4", "d4", "c4", "a3", "b3", "a4", "b4", "a4", "g4", "e4", "g4", "a4", "d4", "c4", "d4", "c4", "a3", "a3", "e4", "d4", "c4", "a3", "e4", "d4", "e4", "a4", "c5", "b4", "a4", "g4", "a4", "e4", "d4", "e4", "d4", "b3", "a3", "a3", "e4", "d4", "c4", "a3", "e4", "d4", "e4", "a4", "c5", "b4", "a4", "g4", "a4", "e4", "g4", "a4", "a4", "b4", "a4", "g4", "e4", "g4", "a4", "d4", "c4", "d4", "c4", "a3", "b3", "g3", "a4", "b4", "a4", "g4", "e4", "g4", "a4", "d4", "c4", "d4", "c4", "a3", "a3", "e4", "d4", "c4", "a3", "e4", "d4", "e4", "a4", "c5", "b4", "a4", "g4", "a4", "e4", "d4", "e4", "d4", "b3", "a3", "a3", "e4", "d4", "c4", "a3", "e4", "d4", "e4", "a4", "c5", "b4", "a4", "g4", "a4", "e4", "g4", "a4", "a4", "b4", "a4", "g4", "e4", "g4", "a4", "d4", "c4", "d4", "c4", "a3", "b3", "g3", "a4", "b4", "a4", "g4", "e4", "g4", "a4", "d4", "c4", "d4", "c4", "a3"]}
游戏效果展示
喜欢的话点个赞呗~
源代码来自:Github上面的一位大佬