基于pygame开发的口红挑战升级游戏
时间: 2020-04-06来源:OSCHINA
前景提要
游戏简介及操作 :
1.游戏分为五关,每关限时60秒。
2.游戏每关难度递增。
3.口红命中一个,增加10分。
4.口红命中重复位置即为失败。
开发工具 :Pycharm
游戏截图 :


游戏制作步骤
一、准备素材
搜集素材以及字体


二、游戏初始设置
1.设置游戏屏幕大小,游戏界面标题 SCREEN_WIDTH = 480 SCREEN_HEIGHT = 800 pygame.init() screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) # 游戏界面标题 pygame.display.set_caption('口红挑战') image_dir = 'image/lipstick/' ttf_dir = 'ttf/' index_background = pygame.image.load(image_dir+'index_background.jpg') index_background = pygame.transform.scale(index_background, (SCREEN_WIDTH, SCREEN_HEIGHT)) lipstick_head = pygame.image.load(image_dir+'lipstick_head.png') lipstick_head = pygame.transform.scale(lipstick_head, (400, 100)) game_begin = pygame.image.load(image_dir+'game_begin.png') game_begin = pygame.transform.scale(game_begin, (400, 200)) process_background = pygame.image.load(image_dir+'process_background.jpg') process_background = pygame.transform.scale(process_background, (SCREEN_WIDTH, SCREEN_HEIGHT)) fail_image = pygame.image.load(image_dir+'fail.png') fail_image = pygame.transform.scale(fail_image, (400, 164)) success_image = pygame.image.load(image_dir+'success.png') success_image = pygame.transform.scale(success_image, (400, 164)) man_image = pygame.image.load(image_dir+'manImg.jpg') man_image = pygame.transform.scale(man_image, (65, 65))
2.60 个 0-59,绘制圆的图片 # 60 个 0-59 circle_img = pygame.image.load(image_dir+'circle.png') circle_pos = [120, 200] # 圆的图片 circle_rect = pygame.Rect(0, 0, 240, 240) # 口红 lipstick_img = pygame.image.load(image_dir + 'lipstick_zhijia.png') # 下一关 next_game_img = pygame.image.load(image_dir + '下一关.png') # 剩余口红 lipstick_remain = pygame.transform.scale(lipstick_img, (lipstick_img.get_width()//2, lipstick_img.get_height()//2)) lipstick_remain = pygame.transform.rotate(lipstick_remain, -140) lipstick_pos = [220, 660] lipstick_group = pygame.sprite.Group() lipstick_hit_group =pygame.sprite.Group()
3.游戏循环帧率设置,旋转速度 度数越大,旋转的却快 # 游戏循环帧率设置 clock = pygame.time.Clock() # 旋转速度 度数越大,旋转的却快 ROLL_SPEED = 6
4.设置口红数量,当前关 # 口红数量 LIPSTICK_COUNT = 6 # 当前关 CURRENT_INDEX = 1
5.创建口红类 class Lipstick(pygame.sprite.Sprite): def __init__(self, init_img, init_pos): pygame.sprite.Sprite.__init__(self) self.image = init_img self.rect = self.image.get_rect() self.rect.topleft = init_pos self.rect.top = self.rect.top-140 self.speed = 30 self.degrees = 0 self.roll_speed = ROLL_SPEED self.is_hit = False self.is_rotate = True def move(self): self.rect.top -= self.speed if self.rect.top < circle.rect.bottom: self.rect.top = circle.rect.bottom-55 def auto_move(self): self.degrees = self.degrees + self.roll_speed if self.degrees >= 360: self.degrees = 0 angle_ = 360 - self.degrees # 旋转角度 x = CENTER[0] + (RADIUS + 35) * math.cos(math.pi * (angle_ - 90) / 180) # 圆上一点横坐标 y = CENTER[1] - (RADIUS + 35) * math.sin(math.pi * (angle_ - 90) / 180) # 圆上一点纵坐标 center = (x, y) self.rect = pygame.transform.rotate(self.image, angle_).get_rect() self.rect.center = center screen.blit(pygame.transform.rotate(self.image, angle_), self.rect)
6.创建转盘类 class Circle(pygame.sprite.Sprite): def __init__(self, init_img, init_rect, init_pos): pygame.sprite.Sprite.__init__(self) self.image = init_img # 图片 self.rect = init_rect # 初始化图片所在的矩形 self.rect.topleft = init_pos # 初始化矩形的左上角坐标 self.speed = ROLL_SPEED # 初始化速度,这里是一个确定的值 self.is_hit = False # 玩家是否被击中 self.degrees = 0 def roll(self): self.degrees = self.degrees+self.speed if self.degrees >= 180: self.degrees = 0 angle_ = 180 - self.degrees # 旋转角度 self.rect = pygame.transform.rotate(self.image, angle_).get_rect() self.rect.center = (240, 320) screen.blit(pygame.transform.rotate(self.image, angle_), self.rect)
7.创建按钮类 class Button(object): def __init__(self, image, position): self.image = image self.position = position def is_click(self): point_x, point_y = pygame.mouse.get_pos() x, y = self.position w, h = self.image.get_size() in_x = x < point_x < x + w in_y = y < point_y < y + h return in_x and in_y def render(self): return self.is_click() begin_button = Button(game_begin, (55, 500)) lipstick_button = Button(lipstick_img, (220, 640)) next_game_button = Button(next_game_img, (140, SCREEN_HEIGHT//2)) is_index = True is_begin = False
8.定义游戏得分、游戏时间,自定义计时事件 # 定义游戏得分 score = 0 # 定义游戏时间 game_time = 60 # 自定义计时事件 COUNT = pygame.USEREVENT + 1 CLICK = pygame.USEREVENT + 2 circle = None
9.判断游戏循环退出的参数,是否生成支架,是否挑战成功 # 判断游戏循环退出的参数 running = True # 是否生成支架 is_produce = False produce_count = 0 direction = pygame.math.Vector2(0, 1) CENTER = (240, 320) RADIUS = 120 # 是否挑战成功 is_success = False is_next_game = False
10.定义下一关,口红数量和时间 def draw_next_game(): screen.blit(process_background, (0, 0)) screen.blit(man_image, (50, 30)) screen.blit(success_image, (40, 80)) score_font = pygame.font.Font(ttf_dir + '楷体GB2312.ttf', 36) score_text = score_font.render('得分:' + str(score), True, (128, 128, 128)) score_text_rect = score_text.get_rect() score_text_rect.topleft = [180, 320] screen.blit(score_text, score_text_rect) screen.blit(next_game_button.image, next_game_button.position) pygame.display.update() # 绘制口红数量 def draw_lipstick_count(): score_font = pygame.font.Font(ttf_dir + '楷体GB2312.ttf', 25) score_text = score_font.render('数量:' + str(LIPSTICK_COUNT-len(lipstick_hit_group)), True, (255, 0, 0)) score_text_rect = score_text.get_rect() score_text_rect.topleft = [SCREEN_WIDTH//10+50, SCREEN_HEIGHT*2//3+30] screen.blit(score_text, score_text_rect) screen.blit(lipstick_remain, [SCREEN_WIDTH//10, SCREEN_HEIGHT*2//3]) # 绘制时间 def draw_time(): time_font = pygame.font.Font(ttf_dir + '楷体GB2312.ttf', 36) time_text = time_font.render(str('时间:') + str(game_time), True, (128, 128, 128)) current_font = pygame.font.Font(ttf_dir + '楷体GB2312.ttf', 30) current_text = current_font.render(str('第') + str(CURRENT_INDEX)+'关', True, (0, 0, 255)) time_text_rect = time_text.get_rect() time_text_rect.topleft = [190, 30] current_text_rect = current_text.get_rect() current_text_rect.topleft = [360, 32] screen.blit(time_text, time_text_rect) screen.blit(current_text, current_text_rect)
三、设置游戏主循环
1.控制游戏最大帧率为60,首页展示, 绘制背景,中心点坐标,屏幕填充,绘制背景和头像,时间 while running: # 控制游戏最大帧率为60 clock.tick(60) # 首页展示 if is_index: # 绘制背景 screen.blit(index_background, (0, 0)) screen.blit(lipstick_head, (40, 50)) screen.blit(game_begin, (55, 500)) pygame.display.flip() # 游戏开始 if is_begin: direction.rotate_ip(6) # By 4 degrees. # 中心点坐标 ball_pos = [int(i) for i in CENTER + direction * (RADIUS + 50)] # 屏幕填充 screen.fill((0, 0, 0)) # 绘制背景和头像 screen.blit(process_background, (0, 0)) screen.blit(man_image, (25, 15)) # 绘制时间 draw_time()
2.口红按钮,击中的位置集 # 口红按钮 screen.blit(lipstick_button.image, lipstick_button.position) # 击中的位置集 degrees_list = [] for lip in lipstick_hit_group: degrees_list.append(lip.degrees)
3.支架,显示口红列表 # 支架 for lip in lipstick_group: # 支架移动 lip.move() # # 是否击中 if pygame.sprite.collide_rect(lip, circle): # 移除生成group lipstick_group.remove(lip) lip.is_hit = True # 判断是不是击中点是否重复 if 0 in degrees_list: running = False break else: score += 10 # 添加到击中group lipstick_hit_group.add(lip) # 显示口红列表 lipstick_group.draw(screen) for lip in lipstick_hit_group: lip.auto_move()
4.绘制得分、口红数量 # 绘制得分 score_font = pygame.font.Font(None, 36) score_text = score_font.render(str(score), True, (128, 128, 128)) score_text_rect = score_text.get_rect() score_text_rect.topleft = [100, 40] screen.blit(score_text, score_text_rect) # 绘制口红数量 放在这里有讲究 draw_lipstick_count() # 圆 if circle is None: circle = Circle(circle_img, circle_rect, circle_pos)
5.更换图片索引使有动画效果 circle.roll() roll_frequency += 2 if roll_frequency >= 60: roll_frequency = 0 pygame.display.update()
6.检测 KEYDOWN 事件: KEYDOWN 是 pygame.locals 中定义的常量,pygame.locals文件开始已经导入
(如果按下 Esc 那么主循环终止
检测 QUIT : 如果 QUIT, 终止主循环
每隔1秒发送一次自定义事件
重新设定时间
设置速度 是之前的1.5倍) for event in pygame.event.get(): # 检测 KEYDOWN 事件: KEYDOWN 是 pygame.locals 中定义的常量,pygame.locals文件开始已经导入 if event.type == pygame.KEYDOWN: # 如果按下 Esc 那么主循环终止 if event.key == pygame.K_ESCAPE: running = False # 检测 QUIT : 如果 QUIT, 终止主循环 elif event.type == pygame.QUIT: running = False pygame.quit() exit() elif event.type == pygame.MOUSEBUTTONDOWN and is_index: point_x, point_y = pygame.mouse.get_pos() is_begin = begin_button.render() if is_begin: is_index = False # 每隔1秒发送一次自定义事件 pygame.time.set_timer(COUNT, 1000) elif event.type == pygame.MOUSEBUTTONDOWN: if lipstick_button.render() and is_begin: lipstick = Lipstick(lipstick_img, lipstick_pos) lipstick_group.add(lipstick) if is_next_game and next_game_button.render(): is_begin = True # 重新设定时间 game_time = 60 # 设置速度 是之前的1.5倍 ROLL_SPEED = ROLL_SPEED * 1.5 CURRENT_INDEX += 1 LIPSTICK_COUNT += 2 circle = None elif event.type == COUNT: if game_time > 0: game_time -= 1
7.时间到游戏结束,判断是否挑战成功、口红数量是否全部点击完成 if game_time <= 0: # 时间到游戏结束 running = False # 判断是否挑战成功 if CURRENT_INDEX == 3 and len(lipstick_hit_group) == LIPSTICK_COUNT: # 稍微停顿一下 time.sleep(0.3) is_success = True running = False # 判断口红数量是否全部点击完成 if len(lipstick_hit_group) == LIPSTICK_COUNT: # 稍微停顿一下 time.sleep(0.3) is_begin = False is_next_game = True draw_next_game() for lip in lipstick_hit_group: lipstick_hit_group.remove(lip) print('-----over------') # screen.fill((0, 0, 0)) screen.blit(process_background, (0, 0)) screen.blit(man_image, (50, 30)) if is_success: screen.blit(success_image, (40, 80)) else: screen.blit(fail_image, (40, 80))
8.绘制得分,显示得分并处理游戏退出 score_font = pygame.font.Font(ttf_dir+'楷体GB2312.ttf', 36) score_text = score_font.render('得分:'+str(score), True, (128, 128, 128)) score_text_rect = score_text.get_rect() score_text_rect.topleft = [180, 320] screen.blit(score_text, score_text_rect) # 显示得分并处理游戏退出 while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() pygame.display.update()
四、运行并测试
鼠标点击口红命中中间旋转的西瓜,若命中重复位置的口红,则失败,成功即进入下一关

科技资讯:

科技学院:

科技百科:

科技书籍:

网站大全:

软件大全:

热门排行