"""
游戏介绍封面制作示例,本程序会教你如何制作游戏封面与游戏结束,充许重启游戏
"""
import arcade
import random
import os
SPRITE_SCALING = 0.5
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "游戏介绍封面制作示例,注释:李兴球"
# 这些常量代表游戏的状态
INSTRUCTIONS_PAGE_0 = 0
INSTRUCTIONS_PAGE_1 = 1
GAME_RUNNING = 2
GAME_OVER = 3
class MyGame(arcade.Window):
"""
Main application class.
"""
def __init__(self, screen_width, screen_height, title):
""" 构造方法 """
# 调用父类方法创建窗口
super().__init__(screen_width, screen_height, title)
# 设置工作目录,为用python -m 启动游戏而设
file_path = os.path.dirname(os.path.abspath(__file__))
os.chdir(file_path)
# 设置背景颜色
arcade.set_background_color(arcade.color.AMAZON)
# 起动游戏将会显示第一页,这就是一个列表的索引号
self.current_state = INSTRUCTIONS_PAGE_0
self.player_list = None
self.coin_list = None
# Set up the player
self.score = 0
self.player_sprite = None
# 第一步:把每页指令图像放到列表,大小要和屏幕一样,否则会被拉伸而变得难看。
# STEP 1: Put each instruction page in an image. Make sure the image
# matches the dimensions of the window, or it will stretch and look
# ugly. You can also do something similar if you want a page between
# each level.
self.instructions = [] # 这个列表存放每个介绍页
texture = arcade.load_texture("images/instructions_0.png")
self.instructions.append(texture)
texture = arcade.load_texture("images/instructions_1.png")
self.instructions.append(texture)
def setup(self):
"""
设置游戏
"""
# 新建玩家角色列表
self.player_list = arcade.SpriteList()
self.coin_list = arcade.SpriteList()
# 设置玩家
self.score = 0
self.player_sprite = arcade.Sprite("images/character.png", SPRITE_SCALING)
self.player_sprite.center_x = 50
self.player_sprite.center_y = 50
self.player_list.append(self.player_sprite)
for i in range(50):
# 创建金币实例
coin = arcade.Sprite("images/coin_01.png", SPRITE_SCALING / 3)
# 随机放置
coin.center_x = random.randrange(SCREEN_WIDTH)
coin.center_y = random.randrange(SCREEN_HEIGHT)
# 增加到金币列表
self.coin_list.append(coin)
# 不显示鼠标
self.set_mouse_visible(False)
# 第2步: 增加此函数
def draw_instructions_page(self, page_number):
"""根据索引号取纹理图,画纹理图
Draw an instruction page. Load the page as an image.
"""
page_texture = self.instructions[page_number]
arcade.draw_texture_rectangle(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2,
page_texture.width,
page_texture.height, page_texture, 0)
# 第3步: 增加此函数
def draw_game_over(self):
"""在屏幕上画 游戏结束 和 单击重启
Draw "Game over" across the screen.
"""
output = "Game Over"
arcade.draw_text(output, 240, 400, arcade.color.WHITE, 54)
output = "Click to restart"
arcade.draw_text(output, 310, 300, arcade.color.WHITE, 24)
# 第4步: 定义画游戏中的角色的函数。
# Take the drawing code you currently have in your
# on_draw method AFTER the start_render call and MOVE to a new
# method called draw_game.
def draw_game(self):
"""
画所有的角色和在得分文本
"""
# 画所有的角色
self.player_list.draw()
self.coin_list.draw()
# 把得分放在屏幕上
output = f"Score: {self.score}"
arcade.draw_text(output, 10, 20, arcade.color.WHITE, 14)
# 第5步: 根据current_state索引号画不同的画面
def on_draw(self):
"""
Render the screen.
"""
# 开始画
arcade.start_render()
# 如果是第一页,则画第一张纹理图
if self.current_state == INSTRUCTIONS_PAGE_0:
self.draw_instructions_page(0)
elif self.current_state == INSTRUCTIONS_PAGE_1:
self.draw_instructions_page(1)
elif self.current_state == GAME_RUNNING:
self.draw_game()
else:
self.draw_game()
self.draw_game_over()
# 第6步: Do something like adding this to your on_mouse_press to flip
# between instruction pages.
def on_mouse_press(self, x, y, button, modifiers):
"""
单击事件,游戏启动时显示第一页,单击后显示第二页,再单击显示游戏画面。
"""
# 单击后,如果索引号为0,则把它的值设为.INSTRUCTIONS_PAGE_1
if self.current_state == INSTRUCTIONS_PAGE_0:
self.current_state = INSTRUCTIONS_PAGE_1
elif self.current_state == INSTRUCTIONS_PAGE_1:
# 启动游戏
self.setup()
self.current_state = GAME_RUNNING
elif self.current_state == GAME_OVER:
# 重启游戏
self.setup()
self.current_state = GAME_RUNNING
def on_mouse_motion(self, x, y, dx, dy):
"""
当鼠标移动时调用此函数
"""
# 角色跟随鼠标
if self.current_state == GAME_RUNNING:
self.player_sprite.center_x = x
self.player_sprite.center_y = y
# 第7步: 只有当currrent_state这个索引号为GAME_RUNNING时才更新
def update(self, delta_time):
""" Movement and game logic """
# 如果current_state的值等于GAME_RUNNING
if self.current_state == GAME_RUNNING:
# 更新角色组
self.coin_list.update()
self.player_list.update()
# 玩家和金币组的碰撞检测,返回列表
hit_list = arcade.check_for_collision_with_list(self.player_sprite, self.coin_list)
# 遍历碰到的金币,删除它们并加分
for coin in hit_list:
coin.kill()
self.score += 1
# 金币组长度为0,重启游戏
if len(self.coin_list) == 0:
self.current_state = GAME_OVER
self.set_mouse_visible(True)
def main():
MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
arcade.run()
if __name__ == "__main__":
main()