Bootstrap

Python Arcade库基础教程Window类的使用(二)

arcade.Window类的使用

Arcade的所有界面最终都是绘制在Window窗体之中,所以最开始我们要创建一个Window窗体容器,其实Arcade是基于Pyglet包的上层封装,那么在介绍Arcade的使用时我也会介绍Pyglet对应的使用方式。Window类构成了使用Arcade的大多数高级游戏的基础。它代表屏幕上的一个窗口,并管理事件。

基类pyglet.window.BaseWindow

构造函数

def __init__(self, width=800, height=600, title='Arcade Window', fullscreen=False, resizable=False,
update_rate=1/60, antialiasing=True, gl_version=(3,3), screen=None, visible=True):
	pass
	'''
	width(int): 窗口宽度
	height(int): 窗口高度
	title(str): 标题(出现在窗口上)
	fullscreen(bool): 是否一开始就全屏显示
	resizable(bool): 是否允许调整窗口大小
	update_rate(float): 窗口的刷新率(帧率)
	antialiasing(bool): 是否应启用OpenGL的抗锯齿功能
	gl_version(Tuple[int,int]): 请求的OpenGL版本。这是默认设置,使用更高级的OpenGL功能时可以覆盖(3,3)
	screen(pyglet.canvas.base.Screen): 可选参数
	visible(bool): 窗口是否立即可见
	'''

接下来用几种方式来打开一个简单的窗体

  1. 直接通过创建基类pyglet.window.BaseWindow对象作为参数打开一个窗体
import arcade
import pyglet
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
def main():
    win = pyglet.window.Window(WIDTH, HEIGHT, TITLE)
    arcade.set_window(win) # 通过将窗体作为参数传入set_window打开窗体(将句柄设置为当前窗口)
    arcade.run() # 程序主循环
    # pyglet.app.run() # 与arcade.run()一样
if __name__ == "__main__":
    main()
  1. 通过继承基类pyglet.window.BaseWindow的字类对象作为参数打开窗体
import arcade
import pyglet
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(pyglet.window.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.set_window(game) # 通过将窗体作为参数传入set_window打开窗体(将句柄设置为当前窗口)
    arcade.run() # 程序主循环
    # pyglet.app.run() # 与arcade.run()一样
if __name__ == "__main__":
    main()
  1. 通过直接创建arcade.Window对象或者继承arcade.Window的字类对象作为参数传入打开窗体
# 方式一
import arcade
import pyglet
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
def main():
    win = arcade.Window(WIDTH, HEIGHT, TITLE)
    arcade.set_window(win) # 通过将窗体作为参数传入set_window打开窗体(将句柄设置为当前窗口)
    arcade.run() # 程序主循环
    # pyglet.app.run() # 与arcade.run()一样
if __name__ == "__main__":
    main()

# 方式二
import arcade
import pyglet
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.set_window(game) # 通过将窗体作为参数传入set_window打开窗体(将句柄设置为当前窗口)
    arcade.run() # 程序主循环
    # pyglet.app.run() # 与arcade.run()一样
if __name__ == "__main__":
    main()
  1. 以上两种方式不通过参数传入也可以打开窗体
# 方式一
import arcade
import pyglet
WIDTH = 300
HEIGHT = 200
TITLE = "窗体测试标题"
def main():
    win = pyglet.window.Window(WIDTH, HEIGHT, TITLE)
    # win = arcade.Window(WIDTH, HEIGHT, TITLE)
    arcade.run() # 程序主循环
    # pyglet.app.run() # 与arcade.run()一样
if __name__ == "__main__":
    main()

# 方式二
import arcade
import pyglet
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
# class MyGame(arcade.Window):
class MyGame(pyglet.window.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run() # 程序主循环
    # pyglet.app.run() # 与arcade.run()一样
if __name__ == "__main__":
    main()
  1. 设置窗体背景颜色(主要以继承的方式实现)
# 继承基类设置背景颜色
import arcade
import pyglet
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(pyglet.window.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        # pyglet.gl.glClearColor(255, 0, 0, 1) # 通过pyglet方式设置背景颜色(放在这里也可以)
    def on_draw(self):
        '''
        每次渲染屏幕时内部自动调用
        start_render方法每次重新设置屏幕为背景色
        '''
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    pyglet.gl.glClearColor(255, 0, 0, 1) # 通过pyglet方式设置背景颜色(也可以放在set_window之后)
    arcade.set_window(game)
    # pyglet.gl.glClearColor(255, 255, 0, 1) # 通过pyglet方式设置背景颜色
    arcade.run() # 程序主循环
    # pyglet.app.run() # 与arcade.run()一样
if __name__ == "__main__":
    main()
# 通过继承arcade.Window类的设置背景颜色
import arcade
import pyglet
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED) # 通过set_background_color设置背景颜色
    def on_draw(self):
        '''
        每次渲染屏幕时内部自动调用
        start_render方法每次重新设置屏幕为背景色
        '''
        arcade.start_render() # 将屏幕设置为背景色

def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    # arcade.set_background_color(arcade.color.WHEAT) # 通过set_background_color设置背景颜色
    # arcade.set_window(game) # 可以不用将对象作为参数传入打开窗体
    # arcade.set_background_color(arcade.color.BLUE) # 通过set_background_color设置背景颜色
    arcade.run() # 程序主循环
if __name__ == "__main__":
    main()

arcade.Window 属性

  • caption

窗口标题,只读。
类型: str

  • config

描述此窗口上下文的OpenGL配置,只读。
类型: pyglet.gl.Config

  • context

附加到此窗口的OpenGL上下文,只读。
类型:pyglet.gl.Context

  • display

该窗口所属的显示,只读。
类型:Display

  • fullscreen

如果窗口当前为全屏,则为True,只读。
类型:bool

  • has_exit=False

  • width

窗口的宽度,以像素为单位,读写。
类型:int

  • height

窗口的高度,以像素为单位,读写。
类型:int

  • invalid=True

  • resizeable

如果窗口可调整大小,则为True,只读。
类型:bool

  • screen

此窗口的屏幕为全屏显示,只读。
类型:Screen

  • style

窗口样式;在一个WINDOW_STYLE_*常数,只读。
类型:int

  • visible

如果窗口当前可见,则为True。只读。
类型:bool

  • vsync

如果缓冲区翻转同步到屏幕的垂直回扫,则为True,只读。
类型:bool

  • background_color

获取或设置此窗口的背景色
类型:arcade.Color

  • ctx

当前窗口的OpenGL上下文
类型:arcade.ArcadeContext

  • current_view

返回当前正在显示的视图,如需要设置其他视图时请调用 arcade.Window.show_view方法或者arcade.Window的对象访问show_view方法
类型:arcade.View

arcade.Window 类属性

  • Class attributes: cursor names

  • CURSOR_NO= 'no'
  • CURSOR_SIZE= 'size'
  • CURSOR_TEXT= 'text'
  • CURSOR_WAIT= 'wait'
  • CURSOR_HELP= 'help'
  • CURSOR_HAND= 'hand'
  • CURSOR_DEFAULT= None
  • CURSOR_SIZE_UP= 'size_up'
  • CURSOR_SIZE_LEFT= 'size_left'
  • CURSOR_CROSSHAIR= 'crosshair'
  • CURSOR_SIZE_RIGHT= 'size_right'
  • CURSOR_SIZE_DOWN= 'size_down'
  • CURSOR_WAIT_ARROW= 'wait_arrow'
  • CURSOR_SIZE_UP_LEFT= 'size_up_left'
  • CURSOR_SIZE_UP_RIGHT= 'size_up_right'
  • CURSOR_SIZE_UP_DOWN= 'size_up_down'
  • CURSOR_SIZE_LEFT_RIGHT= 'size_left_right'
  • CURSOR_SIZE_DOWN_LEFT= 'size_down_left'
  • CURSOR_SIZE_DOWN_RIGHT= 'size_down_right'
  • Class attributes: window styles

  • WINDOW_STYLE_TOOL= 'tool'
  • WINDOW_STYLE_DEFAULT= None
  • WINDOW_STYLE_DIALOG= 'dialog'
  • WINDOW_STYLE_BORDERLESS= 'borderless'

arcade.Window 方法

  • activate

会激活当前调用的窗体,尝试将键盘焦点恢复到窗口,取决于窗口管理器或操作系统。例如,在Windows XP上,不允许应用程序“窃取”另一个应用程序的焦点,而是窗口任务栏图标闪烁。

import arcade
WIDTH = 800
HEIGHT = 600
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, '窗口编号1')
    game1 = MyGame(WIDTH, HEIGHT, '窗口编号2')
    game.activate() # 会发现窗口编号1位于最上层
    arcade.run()
if __name__ == "__main__":
    main()
  • center_window

试窗体居中在屏幕上显示。

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    game.center_window() # 会发现窗体位于中心位置显示
    arcade.run()
if __name__ == "__main__":
    main()
  • clear

使用设置的背景颜色清除窗口arcade.Window.background_color,清除颜色和深度缓冲区的便捷方法。

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    game.clear() # 使用设置的背景颜色清除窗口,在多个视图时有用
    arcade.run()
if __name__ == "__main__":
    main()
  • close

关闭窗口,关闭窗口后,OpenGL上下文将无效,窗口实例一旦关闭就无法重用。

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    game.close() # 窗体打开后关闭
    arcade.run()
if __name__ == "__main__":
    main()
  • dispatch_events

调度事件,轮询操作系统事件队列以获取新事件,并调用附加的事件处理程序。

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    print(game.dispatch_events()) # 输出为None,因为没有事件
    arcade.run()
if __name__ == "__main__":
    main()
  • flip

交换OpenGL和后备缓冲区以获取双缓冲窗口,在双缓冲窗口上调用此方法,以使用后缓冲区更新可见显示。此操作后,后缓冲区的内容未定义。先是在一个缓冲区中完毕渲染,然后再把渲染结果交换到屏幕上,Windows默认为双缓冲。事件发生后,内部自动调用on_draw方法。

  • get_location

返回窗口的X / Y坐标,类型为:Tuple[int, int],返回左边缘和上边缘与其在虚拟桌面上的相应边缘的距离,以像素为单位。

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    print(game.get_location()) # 输出为(112, 135)
    arcade.run()
if __name__ == "__main__":
    main()

以左上角为起始点

  • get_size

获取窗口的大小,类型为:Tuple[int, int],窗口大小不包括边框或标题栏,以像素为单位。

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    print(game.get_size()) # 输出为(800, 600)
    arcade.run()
if __name__ == "__main__":
    main()
  • get_system_mouse_cursor

获取窗口的大小,返回类型为:pyglet.window.win32.Win32MouseCursor,该方法接受的名称是CURSOR_* 在arcade.Window类上定义的常量,例如, CURSOR_WAIT,CURSOR_HELP等,可以与set_mouse_cursor一起使用的鼠标光标。

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色

def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    print(game.get_system_mouse_cursor(game.CURSOR_WAIT)) # 输出为pyglet.window.win32.Win32MouseCursor对象
    arcade.run()
if __name__ == "__main__":
    main()
  • get_viewport

获取窗口视口,(我们可以看到什么坐标),返回类型为:Tuple[float, float, float, float]

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    print(game.get_viewport()) # 输出为(0, 799, 0, 599)
    arcade.run()
if __name__ == "__main__":
    main()
  • maximize

最大化窗口,该方法在某种程度上取决于用户的显示设置。在多显示器系统上,窗口可以最大化到单个屏幕或整个虚拟桌面。

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    game.maximize()
    arcade.run()
if __name__ == "__main__":
    main()
  • minimize

最小化窗口。

  • set_caption

设置窗口的标题,该标题显示在窗口的标题栏中以及Windows和许多X11窗口管理器的任务栏中,所需参数类型为:str |unicode

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    game.set_caption("测试") # 窗体标题变成测试
    arcade.run()
if __name__ == "__main__":
    main()
  • set_exclusive_keyboard

启用后,此功能将禁用某些特定于操作系统的按键组合,例如Alt + Tab,所需参数类型为布尔值,如果为True,则启用专用键盘,否则为禁用

  • set_exclusive_mouse

隐藏鼠标光标并将所有鼠标事件定向到此窗口,启用后,此功能可防止鼠标离开窗口。对于某些需要完全控制鼠标的样式的游戏而言,它很有用。启用独占鼠标后,在后续事件中报告的鼠标位置将毫无意义。所需参数类型为布尔值,如果为True,则启用专用鼠标,否则为禁用。

  • set_fullscreen

在全屏之间切换,切换全屏后,OpenGL上下文应保留其状态和对象,但是需要清除并重新绘制缓冲区。如果指定了宽度和高度,并且全屏为True,则屏幕可能会切换为最接近给定尺寸的其他分辨率。如果分辨率不完全匹配,则选择更高的分辨率,并且窗口将居中覆盖整个屏幕的黑色边框内。
参数:

  • fullscreen (bool)True时为全屏,否在False
  • screen (Screen):如果不为NonefullscreenTrue时,窗口将移至给定的屏幕,屏幕必须与窗口属于同一显示器。
  • mode (ScreenMode):屏幕将切换到给定模式,该模式必须已经通过枚举Screen.get_modes获得,如果为None,将从给定的widthheight中选择适当的模式 。
  • width (int):窗口的可选宽度。如果未指定,则在窗口默认为先前的窗口大小,或者在全屏时默认为屏幕大小。
  • height (int):窗口的可选高度。如果未指定,则在窗口默认为先前的窗口大小,或者在全屏时默认为屏幕大小。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    # game.set_fullscreen() # 打开全屏,包括关闭、最小化、最大化图标都不显示
    # game.set_fullscreen(True) # 打开全屏,包括关闭、最小化、最大化图标都不显示
    # game.set_fullscreen(False) # 由全屏变回全屏之前的大小,没有全屏时不变
    # game.set_fullscreen(False, arcade.get_screens()[0]) # 窗口移动至指定屏幕,这里我只有一个屏幕,所以只能试0
    # game.set_fullscreen(False, mode=game.screen.get_modes()[25]) # 随机设置一种模式
    # game.set_fullscreen(True, width=300, height=200) # 此时窗口会变成最大,分辨率会变小
    game.set_fullscreen(False, width=300, height=200) # 变成指定大小300 * 200的大小
    arcade.run()
if __name__ == "__main__":
    main()
  • set_icon

设置窗口图标,如果提供了多张图像,则将选择一个具有适当尺寸的图像(如果未提供正确的尺寸,则将缩放图像)。
参数:

  • images (sequence of pyglet.image.AbstractImage):用于窗口图标的图像列表。
import arcade
import pyglet
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    game.set_icon(pyglet.image.load('1.png'), pyglet.image.load('2.png'))
    arcade.run()
if __name__ == "__main__":
    main()

自定义图标

  • set_location

设置窗口的位置。
参数:

  • x(int):窗口左边缘与虚拟桌面左边缘的距离,以像素为单位。
  • y(int): 窗口的上边缘到虚拟桌面的上边缘的距离,以像素为单位。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    game.set_location(0, 30) # 窗体会靠近最左上角显示
    arcade.run()
if __name__ == "__main__":
    main()
  • set_max_size

包装Pyglet窗口调用以设置最大大小,窗口构造时resizable必须设置为True注意:窗口大小不包括边框或标题栏,set_fullscreen方法不受限制。
参数:

  • width (float):宽度,以像素为单位。
  • height (float):高度,以像素为单位。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True) # resizable必须设置为True
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    game.set_max_size(900, 600)#调用此方法时,在构造窗口对象时resizable必须设置为True,代表窗口可变形最大值为900*600
    arcade.run()
if __name__ == "__main__":
    main()
  • set_maximum_size

set_max_size方法功能一样,设置窗口的最大大小,但是可以不用设置resizableTrue,如果resizable没有设置为True将没有意义,因为resizableFalse时不能改变窗口大小。set_maximum_size其实是直接调用Pygletset_maximum_size方法,所以不受resizable值的影响。设置后,用户将无法将窗口调整为大于给定尺寸的大小。无法删除窗口上的最大大小约束,如果最大大小设置为小于窗口的当前大小,则该行为未定义,注意:窗口大小不包括边框或标题栏,set_fullscreen方法不受限制。
参数:

  • width (int):窗口的最大宽度,以像素为单位。
  • height (int):窗口的最大高度,以像素为单位。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    game.set_maximum_size(900, 600)#调用此方法时
    arcade.run()
if __name__ == "__main__":
    main()
  • set_min_size

set_max_size方法使用完全相同,只是是设置最小窗口的大小。

  • set_minimum_size

set_maximum_size方法使用完全相同,只是是设置最小窗口的大小。

  • set_mouse_platform_visible

设置平台绘制的鼠标光标可见性。更改鼠标光标或排他模式后,将自动调用此方法,应用程序通常不需要调用此方法,请参阅 set_mouse_visible
参数:

  • platform_visible (bool或None):如果为None,则将平台可见性设置为当前排他模式和光标类型所需的可见性。否则,布尔值将覆盖并强制显示。
  • set_mouse_cursor

更改鼠标光标的外观,鼠标光标的外观仅在其在此窗口内时才会更改
参数:

  • cursor (MouseCursor):要设置的光标。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"

class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    cursor = game.get_system_mouse_cursor(game.CURSOR_HAND)
    game.set_mouse_cursor(cursor) # 鼠标变成手型
    arcade.run()
if __name__ == "__main__":
    main()
  • set_mouse_visible

显示或隐藏鼠标光标,仅当鼠标光标位于此窗口中时,它才会被隐藏。鼠标事件仍将照常处理。
参数:

  • visible (bool):如果为True,则鼠标光标将可见,否则将被隐藏。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    game.set_mouse_visible(False) # 鼠标进入窗口隐藏
    arcade.run()
if __name__ == "__main__":
    main()
  • set_size

调整窗口大小,如果窗口不可调整大小,或者当前为全屏显示,则该行为未定义。注意:窗口大小不包括边框或标题栏。
参数:

  • width (int):窗口的新宽度,以像素为单位。
  • height (int):窗口的新高度,以像素为单位。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    game.set_size(300, 200) # 窗口将变为300 * 200
    arcade.run()
if __name__ == "__main__":
    main()
  • set_update_rate

设置屏幕更新频率。例如:self.set_update_rate(1/60)会将更新速率设置为60 fps
参数:

  • rate(float):更新频率,以秒为单位
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    game.set_update_rate(1/30) # 帧率变为30
    arcade.run()
if __name__ == "__main__":
    main()
  • set_viewport

设置视口,我们可以看到什么坐标。用于缩放和/或滚动屏幕。
参数:

  • left (float):左边
  • right (float):右边
  • bottom (float):下
  • top (float):上
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    game.set_viewport(10, 20, 30, 10) # 只能看到指定视图内的内容
    arcade.run()
if __name__ == "__main__":
    main()
  • set_visible

显示或隐藏窗口。
参数:

  • visible (bool):如果为True,将显示窗口;否则它将被隐藏
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    game.set_visible(False) # 隐藏窗口
    arcade.run()
if __name__ == "__main__":
    main()
  • set_vsync

设置是否将绘制同步到显示器的垂直同步速率
参数:

  • vsync(bool):为True时代表同步速率
  • switch_to

切换此窗口。

  • update

移动一切。为了更好地命名,请on_update改用。
参数:

  • delta_time (float):自上次调用该函数以来的时间间隔,以秒为单位。
  • draw_mouse_cursor

绘制自定义鼠标光标,如果当前鼠标光标已drawable设置,则在翻转缓冲区以呈现它之前调用此方法,此方法始终使GL_MODELVIEW矩阵保持当前状态,而与先前设置的值无关。没有其他OpenGL状态受影响, 几乎不需要重写此方法,而是子类化 pyglet.window.MouseCursor并提供您自己的 draw方法。

arcade.Window 事件

  • on_activate

窗口被激活时触发,可以通过单击标题栏将其置于前台来触发此事件。或通过某些特定于平台的方法,当窗口处于“活动”状态时,它具有键盘焦点。

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
    def on_activate(self):
        print('窗口已被激活')
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_close

关闭窗口时触发,可以通过单击窗口标题栏中的“ X”控制框或其他依赖于平台的方式来触发此事件,默认处理程序将has_exit设置为True。

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
    def on_close(self):
        print('窗口已关闭')
        self.close()
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_deactivate

该窗口已停用,单击另一个应用程序窗口可以触发此事件,关闭或者最小化或者失去焦点都会触发。

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
    def on_deactivate(self):
        print('窗口已停用')
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_draw

窗口内容必须重新绘制,事件循环将分派此事件时,窗口应该重新绘制,这将在任何窗口事件之后和调用任何计划的函数之后的空闲时间发生,覆盖此功能以添加您的自定义工程图代码。

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色,将该句注释过后发现背景颜色没有设置成功,这就说明on_draw事件是重新绘制画面
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_hide

当窗口最小化或由用户隐藏(在Mac OS X上)时,触发此事件,窗口关闭不触发。

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render() # 将屏幕设置为背景色
    def on_hide(self):
        print('窗口已隐藏')

def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_key_press

覆盖此功能以添加按键功能,按下(并按住)键盘上的一个键,按下或者按住键盘某个键时触发该事件。
参数:

  • symbol (int):按下的按键符号
  • modifiers (int):激活的键修饰符的按位组合
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render()
    def on_key_press(self, symbol, modifiers):
        if arcade.key.DOWN == symbol:
            print('按了键盘下键')
        if arcade.key.C == symbol and modifiers == 18:
            print('按了Ctrl+C')
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_key_release

覆盖此功能以添加键盘释放功能,释放了键盘上的键,当键盘弹起时触发。
参数:

  • symbol (int):按下的按键符号
  • modifiers (int):激活的键修饰符的按位组合
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render()
    def on_key_release(self, symbol, modifiers):
        if arcade.key.DOWN == symbol:
            print('键盘下键弹起了')
        if arcade.key.C == symbol and modifiers == 18:
            print('按了Ctrl+C过后C键弹起')
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_mouse_drag

覆盖此功能以添加鼠标按钮功能,在按下一个或多个鼠标按钮的情况下移动了鼠标,即使鼠标离开窗口,只要连续按住拖动按钮,此事件将继续被触发。
参数:

  • x (int):距窗口左边缘的距离,以像素为单位。
  • y (int):距窗口底部边缘的距离,以像素为单位。
  • dx (int):上一个鼠标位置的相对X位置。
  • dy (int):上一个鼠标位置的相对Y位置。
  • buttons (int):按下哪个按钮。
  • modifiers (int):当前活动的任何键盘修饰符的按位组合。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render()
    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        if dx < -1:
            print('鼠标往左拖动了')
        if dx > 1:
            print('鼠标往右拖动了')
        if dy < -1:
            print('鼠标往下拖动了')
        if dy > 1:
            print('鼠标往上拖动了')
        if buttons == arcade.MOUSE_BUTTON_LEFT and modifiers == 16:
            print('你按住鼠标左键拖动')
        if buttons == arcade.MOUSE_BUTTON_RIGHT and modifiers == 16:
            print('你按住鼠标右键拖动')
        if buttons == 5 and modifiers == 16:
            print('你按住鼠标左右键拖动')
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_mouse_enter

鼠标移到窗口中,如果当前正在拖动鼠标,则不会触发此事件,鼠标进入窗口时触发。
参数:

  • x(int):距窗口左边缘的距离,以像素为单位。
  • y(int):距窗口底部边缘的距离,以像素为单位。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render()
    def on_mouse_enter(self, x, y):
        if x < 10:
            print('鼠标从左边进入窗口')
            return
        if y > 590:
            print('鼠标从上边进入窗口')
            return
        if x > 790:
            print('鼠标从右边进入窗口')
            return
        if y < 10:
            print('鼠标从下边进入窗口')
            return
        return
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_mouse_leave

鼠标移到窗口外面,如果当前正在拖动鼠标,则不会触发此事件。请注意,鼠标指针的坐标将在窗口矩形的外部,鼠标离开窗口时触发。
参数:

  • x (int):距窗口左边缘的距离,以像素为单位。
  • y (int):距窗口底部边缘的距离,以像素为单位。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render()
    def on_mouse_leave(self, x, y):
        if x < 10:
            print('鼠标从左边离开窗口')
            return
        if y > 590:
            print('鼠标从上边离开窗口')
            return
        if x > 790:
            print('鼠标从右边离开窗口')
            return
        if y < 10:
            print('鼠标从下边离开窗口')
            return
        return
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_mouse_motion

没有按下任何按钮的情况下移动了鼠标,鼠标移动时触发。
参数:

  • x (int):距窗口左边缘的距离,以像素为单位。
  • y (int):距窗口底部边缘的距离,以像素为单位。
  • dx (int):从上一个鼠标位置开始的相对X位置。
  • dy (int):上一个鼠标位置的相对Y位置。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render()
    def on_mouse_motion(self, x, y, dx, dy):
        if dx < -1:
            print('鼠标往左移动了')
        if dx > 1:
            print('鼠标往右移动了')
        if dy < -1:
            print('鼠标往下移动了')
        if dy > 1:
            print('鼠标往上移动了')
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_mouse_press

按下鼠标键(并保持不放),按下一个鼠标键时触发。
参数:

  • x (int):距窗口左边缘的距离,以像素为单位。
  • y (int):距窗口底部边缘的距离,以像素为单位。
  • button (int):按下的鼠标按钮。
  • modifiers (int):当前活动的任何键盘修饰符的按位组合。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render()
    def on_mouse_press(self, x, y, button, modifiers):
        if button == arcade.MOUSE_BUTTON_LEFT and modifiers == 16:
            print('按下了鼠标左键')
        if button == arcade.MOUSE_BUTTON_RIGHT and modifiers == 16:
            print('按下了鼠标右键')
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_mouse_release

弹起了一个鼠标按钮,弹起鼠标键时触发。
参数:

  • x (int):距窗口左边缘的距离,以像素为单位。
  • y (int):距窗口底部边缘的距离,以像素为单位。
  • button (int):释放的鼠标按钮。
  • modifiers (int):当前活动的任何键盘修饰符的按位组合。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render()
    def on_mouse_release(self, x, y, button, modifiers):
        if button == arcade.MOUSE_BUTTON_LEFT and modifiers == 16:
            print('释放了鼠标左键')
        if button == arcade.MOUSE_BUTTON_RIGHT and modifiers == 16:
            print('释放了鼠标右键')
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_mouse_scroll

滚动鼠标滚轮,注意:大多数鼠标只有一个垂直滚轮,因此 scroll_x通常为0,AppleMighty Mouse例外,它有一个鼠标球代替滚轮,可以同时滚动和滚动scroll_y,鼠标滚轮滚动时触发。
参数:

  • x (int):距窗口左边缘的距离,以像素为单位。
  • y (int):距窗口底部边缘的距离,以像素为单位。
  • scroll_x (float):水平轴上的移动量。
  • scroll_y (float):垂直轴上的移动量。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render()
    def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
        if scroll_y > 0:
            print('鼠标滚轮向前滚动了')
        if scroll_y < 0:
            print('鼠标滚轮向后滚动了')
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_move

窗口已移动,窗口移动时触发。
参数:

  • x (int):从屏幕左边缘到窗口左边缘的距离。
  • y (int):从屏幕顶部到窗口顶部的距离。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
        self.old_x, self.old_y = self.get_location() 
    def on_draw(self):
        arcade.start_render()
    def on_move(self, x, y):
        if x > self.old_x:
            print('窗口右移动了')
        if x < self.old_x:
            print('窗口左移动了')
        if y > self.old_y:
            print('窗口下移动了')
        if y < self.old_y:
            print('窗口上移动了')
        self.old_x, self.old_y = self.get_location() 
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_resize

窗口已调整大小,重写此函数可在每次调整窗口大小时添加要调用的自定义代码,这里的唯一责任是更新视口,窗口大小变化时触发。
参数:

  • width (int):窗口的新宽度,以像素为单位。
  • height (int):窗口的新高度,以像素为单位。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
        self.old_width, self.old_height = self.get_size() 
    def on_draw(self):
        arcade.start_render()
    def on_resize(self, width , height):
        if width > self.old_width:
            print('窗口变宽了')
        if width < self.old_width:
            print('窗口变窄了')
        if height > self.old_height:
            print('窗口变高了')
        if height < self.old_height:
            print('窗口变低了')
        self.old_width, self.old_height = self.get_size() 
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_show

显示了窗口,在最小化窗口后或第一次显示窗口后还原窗口时,将触发此事件。

import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        arcade.set_background_color(arcade.color.RED)
    def on_draw(self):
        arcade.start_render()
    def on_show(self):
        print('显示')
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
  • on_update

在这里执行所有游戏逻辑,比如精灵的移动,图形的变化等逻辑都在该事件中实现。
参量:

  • delta_time (float):自上次调用该函数以来的时间间隔。
import arcade
WIDTH = 800
HEIGHT = 600
TITLE = "窗体测试标题"
class MyGame(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        arcade.set_background_color(arcade.color.BLACK)
        self.x = 395
        self.y = 595
    def on_draw(self):
        arcade.start_render()
        arcade.draw_circle_filled(
            center_x=self.x,
            center_y=self.y,
            radius=5,
            color=arcade.color.RED,
            num_segments=-1)
    def on_update(self, delta_time): # 这里能看到红色的圆从上往下移动
        self.x -= 0
        self.y -= 1
def main():
    game = MyGame(WIDTH, HEIGHT, TITLE)
    arcade.run()
if __name__ == "__main__":
    main()
;