Python实现的儿童数数字游戏源代码,数出屏幕里出现的水果个数,并选择对应的数字
核心代码
'''
游戏名 :水果秀(fruit show)
游戏作者:Python代码大全
微信公众号:Python代码大全
'''
import pygame, sys, random
from pygame.locals import *
class ScoreShow:
# def __init__()是ScoreShow的构造函数,每次实例化时,都会先执行def这个构造函数,完成生成对象时的初始化工作
def __init__(self, x, y, image_name, energy_file_name):
self.x = x
self.y = y
self.image_name = "./images/" + image_name
self.energy_name = "./images/" + energy_file_name
self.image = pygame.image.load(self.image_name)
self.energy = pygame.image.load(self.energy_name)
self.display = True
self.show_score = 0
self.MAX_SCORE_BAR_WIDTH = 160
# 设置得分进度条中每一分的宽度
def set_width_per_score(self, max_right_score):
self.DWIDTH = self.MAX_SCORE_BAR_WIDTH // max_right_score
# 进度条的初始位置
def set_dx(self, dx):
self.blood_x = self.x + dx
# 通过得分,来控制进度条的显示长度
def set_score_bar(self, score):
self.show_score = score
if self.show_score > 0:
width = self.energy.get_width()
if width <= self.MAX_SCORE_BAR_WIDTH:
width = self.show_score * self.DWIDTH
height = self.energy.get_height()
self.energy = pygame.transform.scale(self.energy, (width, height))
# 更新得分进度条的长度显示
def update(self):
if self.display:
screen.blit(self.image, (self.x, self.y))
# 当得分大于0时,才需要将分数进度显示出来
if self.show_score > 0:
screen.blit(self.energy, (self.blood_x, self.y+3))
# 定义一个水果类
class Fruit:
def __init__(self, filename):
self.image = self.load_images(filename)
self.apple_floor = False
self.display = True
# 设置水果的位置
def set_pos(self, x, y):
self.x = x
self.y = y
# 加载水果图片
def load_images(self, filename):
real_filename = "./images/"+filename + ".png"
image = pygame.image.load(real_filename)
return image
# 水果显示更新函数
def update(self):
if self.display:
screen.blit(self.image, (self.x, self.y))
def set_display(self, display):
self.display = display
# 定义一个Button类
class Button:
def __init__(self, filename):
self.x = 24
self.y = 500
self.white_image = self.load_image(filename)
self.green_image = self.load_image("green_button")
self.rect = pygame.Rect(self.x, self.y, 90, 90)
self.white = True
# 点击Button时,将Button反色,代表正在被点击
def flip(self):
self.white = not self.white
# 加载Button图片
def load_image(self, filename):
real_filename = "./images/buttons/" + filename + ".png"
image = pygame.image.load(real_filename)
return image
# 将Button展开到不同的位置
def set_dx(self, dx):
self.x += dx
# Button显示更新的函数
def update(self):
if self.white:
screen.blit(self.white_image, (self.x, self.y))
else:
screen.blit(self.green_image, (self.x, self.y))
# 定义一个数字类
class Num(pygame.sprite.Sprite):
def __init__(self, i):
super(Num, self).__init__()
self.x = 40
self.y = 508
self.num = i + 1
self.display = True
self.image = self.load_image(i)
def load_image(self, digit):
real_filename = "./images/nums/" + "num" + str(digit) + ".png"
image = pygame.image.load(real_filename)
return image
def set_dx(self, dx):
self.x += dx
self.rect = pygame.Rect(self.x-1, self.y-1, 80, 80)
def set_display(self, display):
self.display = display
def update(self):
screen.blit(self.image, (self.x, self.y))
# 将知识融入游戏的类
class Slogan:
# slogan对象初始化
def __init__(self, text_image_name_list):
self.text_image_list = []
for text_image in text_image_name_list:
self.text_image_list.append(pygame.image.load("./images/" + text_image))
self.pos_x = [1060, 1090, 1150, 1210]
self.pos_end_y = 560
self.pos_y = 0
self.dy = 50
self.image_index = 0
self.slogan_sound_play = True
self.slogan_sound = pygame.mixer.Sound("./sounds/water_hit.wav")
index = 0
self.always_show_index = []
for text_image in self.text_image_list:
screen.blit(text_image, (self.pos_x[index], self.pos_y))
index += 1
# 在特定位置显示特定slogan图片
def draw_text_index(self, index, pos_x, pos_y):
screen.blit(self.text_image_list[index], (pos_x, pos_y))
# 实现slogan(将知识融入游戏落地的动态效果)
def update(self):
if self.image_index < 4:
self.draw_text_index(self.image_index, self.pos_x[self.image_index], self.pos_y)
self.pos_y += self.dy
if self.pos_y >= self.pos_end_y:
if self.slogan_sound_play:
self.slogan_sound_play = False
self.slogan_sound.play()
self.always_show_index.append(self.image_index)
self.image_index += 1
self.pos_y = 50
self.slogan_sound_play = True
for index in self.always_show_index:
self.draw_text_index(index, self.pos_x[index], self.pos_end_y)
# 以特定字体,颜色,在特定位置显示字符
def display_text(font, text, pos, color):
display_text = font.render(text, True, color)
screen.blit(display_text, pos)
width = 1280
height = 600
FPS = 10
stage = 0
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((width, height), NOFRAME)
back_image = pygame.image.load("./images/back_image.png")
boot_image = pygame.image.load("./images/boot_image.png")
start_image = pygame.image.load("images/start_game.png")
game_win_image = pygame.image.load("./images/game_win.png")
game_fail_image = pygame.image.load("./images/game_lose.png")
game_success_sound = pygame.mixer.Sound("./sounds/game_win.wav")
you_great_sound = pygame.mixer.Sound("./sounds/you_great.wav")
come_on_sound = pygame.mixer.Sound("./sounds/comeon.wav")
game_fail_sound = pygame.mixer.Sound("sounds/game_fail.wav")
clock = pygame.time.Clock()
# 定义水果在树上显示的位置
pans_position =[[240, 80], [240, 160], [340, 80], [340, 160], [557, 85], [669,69], [566, 167],\
[687, 158], [889, 82], [1008, 82], [902, 171], [1022, 164]]
temp_position = pans_position
# 将水果显示的位置打乱
random.shuffle(temp_position)
user_choose = False
RIGHT_SCORE_DOEN = 20
WRONG_SCONE_DONE = 20
right_score = 0
wrong_score = 0
r_color = 'red'
w_color = (0, 97, 10)
r_pos = (195, 15)
w_pos = (195, 35)
score_font = pygame.font.Font(None, 30)
filename = ["white_button", "green_button"]
slogan_text_obj = Slogan(["jiang.png", "zhishi.png", "rongru.png", "youxi.png"])
start_button_rect = pygame.Rect(686,331,158,63)
game_over_home_rect = pygame.Rect(360, 430, 130, 110)
game_over_start_rect = pygame.Rect(575, 430, 130, 110)
game_over_exit_rect = pygame.Rect(790, 430, 122, 110)
game_before_exit_rect = pygame.Rect(1200, 17, 55, 45)
game_running_start_rect= pygame.Rect(1145, 17, 55, 45)
game_running_exit_rect= pygame.Rect(1210, 17, 55, 45)
# 答对进度条
right_score_bar = ScoreShow(10, 15, "right_score_show.png", "red_energy.png")
right_score_bar.set_dx(24)
right_score_bar.set_width_per_score(RIGHT_SCORE_DOEN)
right_score_bar.set_score_bar(right_score)
# 答错进度条
wrong_score_bar = ScoreShow(10, 35, "wrong_score_show.png", "green_energy.png")
wrong_score_bar.set_dx(24)
wrong_score_bar.set_width_per_score(WRONG_SCONE_DONE)
wrong_score_bar.set_score_bar(wrong_score)
FRUIT_SHOW_TIME_INTERVAL = 5000 # 3S
FACE_SHOW_TIME_INTERVAL = 1500 # 2S
FIRST_ENTER = True
user_choose = False # 用户没有点数字
image_index = 0
display_begin = True
start_button_switch_time = 0
slogan_sound_play = True
while True:
for event in pygame.event.get():
if event.type == MOUSEBUTTONDOWN:
if stage >= 2:
x, y = event.pos
# 判断x,y是不是点击到了某个数字
for num_obj in num_objs:
flag = num_obj.rect.collidepoint(x, y)
# 如果鼠标点击了数字
if flag:
button_objs[num_obj.num - 1].flip() # Button反色
break
if event.type == MOUSEBUTTONUP:
if 1 < stage < 5:
x, y = event.pos
# 判断x,y是不是点击到了某个数字
for num_obj in num_objs:
flag = num_obj.rect.collidepoint(x, y)
if flag and not user_choose:
user_choose = True
stage = 3
user_num_obj = num_obj
button_objs[num_obj.num - 1].flip() # 数字Button反色
break
# 判断鼠标是否点击了replay button和exit button
if not flag:
# 鼠标点击了replay button,返回到stage 1阶段,重新产生水果,得分清零
if game_running_start_rect.collidepoint(x, y):
stage = 1
FIRST_ENTER = True
right_score = 0
wrong_score = 0
right_score_bar.set_score_bar(right_score)
wrong_score_bar.set_score_bar(wrong_score)
# 鼠标点击了exit button,退出游戏
if game_running_exit_rect.collidepoint(x, y):
sys.exit()
# 在stage=5游戏结束画面,判断鼠标是否点击了home button,replay button,exit button
if stage == 5:
x, y = event.pos
if game_over_home_rect.collidepoint(x, y):
user_choose = False
stage = 0
right_score = 0
wrong_score = 0
right_score_bar.set_score_bar(right_score)
wrong_score_bar.set_score_bar(wrong_score)
if game_over_start_rect.collidepoint(x, y):
user_choose = False
stage = 1
right_score = 0
wrong_score = 0
right_score_bar.set_score_bar(right_score)
wrong_score_bar.set_score_bar(wrong_score)
slogan_sound_play = True
if game_over_exit_rect.collidepoint(x, y):
sys.exit()
if stage == 0:
# 显示游戏的主界面,让用户点游戏开始
screen.blit(boot_image, (0, 0))
start_button_switch_time += 1
if display_begin:
screen.blit(start_image, (690, 342))
if start_button_switch_time > 5:
start_button_switch_time = 0
display_begin = not display_begin
# 显示slogan“知识融入游戏”落地的效果
slogan_text_obj.update()
is_pressed = pygame.mouse.get_pressed()
if is_pressed[0]:
x, y = pygame.mouse.get_pos()
# 鼠标点击了start button
if start_button_rect.collidepoint(x, y):
stage = 1
# 鼠标点击了exit button
if game_before_exit_rect.collidepoint(x, y):
sys.exit()
pygame.display.update()
clock.tick(FPS)
continue
screen.blit(back_image, (0, 0))
if stage == 1:
# 产生水果,并把水果放在随机产生的位置
# 记住水果产生的时间点,进入stage 2
fruit_cnt = random.randint(1, 10)
fruit_type_index = random.randint(0, 4)
fruit_type_map = {0:"apple", 1:"pitaya", 2:"pear", 3:"banana", 4:"mango"}
fruit_sound = pygame.mixer.Sound("./sounds/" + fruit_type_map[fruit_type_index] + ".wav")
fruit_objs = []
for i in range(fruit_cnt):
fruit = Fruit(fruit_type_map[fruit_type_index])
fruit_objs.append(fruit)
pan_index = 0
real_postions = temp_position[:fruit_cnt]
for fruit in fruit_objs:
fruit.set_pos(real_postions[pan_index][0], real_postions[pan_index][1])
pan_index += 1
# 生成button对象
button_objs = []
for i in range(0, 10):
button_obj = Button(filename[0])
button_obj.set_dx(i*128)
button_objs.append(button_obj)
# 生成数字对象
num_objs = []
for i in range(0, 10):
num_obj = Num(i)
num_obj.set_dx(i*128)
num_objs.append(num_obj)
fruit_show_start_time = pygame.time.get_ticks()
stage = 2
fruit_sound.play()
fruit_sound.set_volume(0.1)
if stage == 2:
# 判断水果显示时长已到,将水果设置为不可见,进入stage 3
fruit_show_end_time = pygame.time.get_ticks()
if fruit_show_end_time - fruit_show_start_time > FRUIT_SHOW_TIME_INTERVAL:
if FIRST_ENTER:
FIRST_ENTER = False
FRUIT_SHOW_TIME_INTERVAL = 3000
for fruit in fruit_objs:
fruit.set_display(False)
stage = 3
if stage == 3:
# 获取用户点击数字
if user_choose:
# if 正确,加分,语音表扬
# if 如果积累分数到达目标值 ,进行stage 5,显示游戏结束画面
# else 进入 stage 4,让你真棒和加油的图片显示3s
# else ,错误,加分,语音鼓励, 进入stage 1
if user_num_obj.num == fruit_cnt:
user_answer = 1 # 用户回答正确
right_score += 1
right_score_bar.set_score_bar(right_score)
if right_score < RIGHT_SCORE_DOEN:
if slogan_sound_play:
slogan_sound_play = False
you_great_sound.play()
you_great_sound.set_volume(0.1)
if right_score >= RIGHT_SCORE_DOEN:
game_success_sound.play()
game_success_sound.set_volume(0.1)
stage = 5
else:
face_show_start_time = pygame.time.get_ticks()
stage = 4
else:
user_answer = 0 # 用户回答错误
wrong_score += 1
wrong_score_bar.set_score_bar(wrong_score)
if wrong_score < WRONG_SCONE_DONE:
if slogan_sound_play:
slogan_sound_play = False
come_on_sound.play()
come_on_sound.set_volume(0.1)
if wrong_score >= WRONG_SCONE_DONE:
game_fail_sound.play()
game_fail_sound.set_volume(0.1)
stage = 5
else:
# 记录“要加油”,“你真棒”图片开始显示的时间点
face_show_start_time = pygame.time.get_ticks()
stage = 4
image_cnt = random.randint(0, 1)
if stage == 4:
# 得到图片显示的结束时间点
face_show_end_time = pygame.time.get_ticks()
great_boy = ["you_great_boys", "you_great_boyb"]
great_girl = ["you_great_girls", "you_great_girlb"]
image_map_great = {0: great_boy, 1:great_girl}
comeon_boy = ["boy_comeon1", "boy_comeon2"]
comeon_girl = ["girl_comeon1", "girl_comeon2"]
image_map_comeon = {0: comeon_boy, 1: comeon_girl}
if user_answer == 1:
if image_index > 1:
image_index = 0
great_image = pygame.image.load("./images/" + image_map_great[image_cnt][image_index] + ".png")
screen.blit(great_image, (350, 300))
image_index += 1
else:
if image_index > 1:
image_index = 0
hard_image = pygame.image.load("./images/" + image_map_comeon[image_cnt][image_index] + ".png")
screen.blit(hard_image, (350, 250))
image_index += 1
# 等待3s
if face_show_end_time - face_show_start_time >= FACE_SHOW_TIME_INTERVAL:
stage = 1
user_choose = False # 响应用户的数字点击
image_index = 0
slogan_sound_play = True
if stage == 5:
if right_score == RIGHT_SCORE_DOEN:
screen.blit(game_win_image, (0, 0))
if wrong_score == WRONG_SCONE_DONE:
screen.blit(game_fail_image, (0, 0))
if stage != 5 and stage != 0:
right_score_bar.update()
wrong_score_bar.update()
for fruit in fruit_objs:
fruit.update()
for button_obj in button_objs:
button_obj.update()
for num_obj in num_objs:
num_obj.update()
display_text(score_font, str(right_score), r_pos, r_color)
display_text(score_font, str(wrong_score), w_pos, w_color)
pygame.display.update()
clock.tick(FPS)