如何使用Python和街机库创建2D游戏

哈Ha! 我向您介绍Paul Vincent Craven撰写的文章如何使用Python和Arcade库创建2D游戏的翻译


如何使用Python和街机库创建2D游戏


了解如何开始使用Arcade,这是一个易于使用的Python库,用于创建2D视频游戏。


图片


Phython对人们来说是一门学习编程的好语言,对于那些想要“做某事”而不花大量时间在样板代码上的人来说, Phython是理想的选择。 Arcade是一个用于创建2D视频游戏的Python库,当您获得经验时,该库易于使用且非常有效。 在本文中,我将解释如何开始使用Python和Arcade对视频游戏进行编程。


在使用PyGame库教了学生之后,我开始在Arcade上进行开发。 我亲自使用PyGame教了将近10年,并开发了ProgramArcadeGames.com进行在线教学。 PyGame很棒,但是最后我觉得我在浪费时间来掩盖从未修复过的错误
我担心教诸如事件循环之类的事情 ,而这不再是我们编写代码的方式。 在整个章节中,我解释了为什么翻转Y坐标。 由于PyGame很少更新,它基于旧的SDL 1库,而不是基于更现代的库(如OpenGL) ,因此我对未来没有太大的希望。


我想创建一个更易于使用,功能更强大的库,并使用了一些Python 3新功能,例如装饰器和类型提示。 这是一个街机。 这是入门方法。


安装方式


像许多其他软件包一样,Arcade可以通过PyPi使用 ,这意味着您可以使用pip命令(或pipenv命令)安装Arcade。 如果您已经安装了Python,则可能只需在Windows上打开命令提示符并键入:


pip install arcade 

或在MacOS和Linux上输入:


 pip3 install arcade 

有关更详细的安装说明,您可以参考Arcade安装文档


简单绘图


您可以打开窗口并仅需几行代码即可创建简单的工程图。 让我们创建一个绘制笑脸的示例,如下图所示:


图片


以下算法显示了如何使用Arcade绘图命令执行此操作。 请注意,您不需要知道如何使用类,甚至不需要定义函数。 具有快速视觉反馈的编程非常适合那些想开始学习编程的人。


 import arcade # Set constants for the screen size SCREEN_WIDTH = 600 SCREEN_HEIGHT = 600 # Open the window. Set the window title and dimensions (width and height) arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Drawing Example") # Set the background color to white. # For a list of named colors see: # http://arcade.academy/arcade.color.html # Colors can also be specified in (red, green, blue) format and # (red, green, blue, alpha) format. arcade.set_background_color( arcade.color.WHITE) # Start the render process. This must be done before any drawing commands. arcade.start_render() # Draw the face x = 300 y = 300 radius = 200 arcade.draw_circle_filled( x, y, radius, arcade.color.YELLOW) # Draw the right eye x = 370 y = 350 radius = 20 arcade.draw_circle_filled( x, y, radius, arcade.color.BLACK) # Draw the left eye x = 230 y = 350 radius = 20 arcade.draw_circle_filled( x, y, radius, arcade.color.BLACK) # Draw the smile x = 300 y = 280 width = 120 height = 100 start_angle = 190 end_angle = 350 arcade.draw_arc_outline( x, y, width, height, arcade.color.BLACK, start_angle, end_angle, 10) # Finish drawing and display the result arcade.finish_render() # Keep the window open until the user hits the 'close' button arcade.run() 

功能用途


当然,在全局上下文中编写代码不是一个好的形式。 幸运的是,使用功能改进程序很容易。 在这里,我们可以看到使用函数在特定(x,y)位置绘制松树的示例:


 def draw_pine_tree(x, y) : """ This function draws a pine tree at the specified location. """ # Draw the triangle on top of the trunk. # We need three x, y points for the triangle. arcade.draw_triangle_filled( x + 40, y, # Point 1 x, y - 100, # Point 2 x + 80, y - 100, # Point 3 arcade.color.DARK_GREEN) # Draw the trunk arcade.draw_lrtb_rectangle_filled( x + 30, x + 50, y - 100, y - 140 , arcade.color.DARK_BROWN) 

有关完整示例,请参见带有功能的图纸


图片


经验更丰富的程序员会知道现代图形程序会先将图形信息上载到视频卡,然后再要求视频卡以包装的形式进行绘制。 Arcade也支持这一点。 分别绘制10,000个矩形大约需要0.800秒。 将它们作为包装绘制只需不到0.001秒。


窗口类


较大的程序通常从Window类继承或使用装饰器 。 这使程序员可以编写代码来处理绘图,更新和处理用户输入。 启动窗口程序的模板如下所示。


 import arcade SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 class MyGame( arcade.Window): """ Main application class. """ def __init__(self, width, height) : super( ) .__init__(width, height) arcade.set_background_color( arcade.color.AMAZON) def setup( self) : # Set up your game here pass def on_draw(self) : """ Render the screen. """ arcade.start_render() # Your drawing code goes here def update(self, delta_time) : """ All the logic to move, and the game logic goes here. """ pass def main( ) : game = MyGame( SCREEN_WIDTH, SCREEN_HEIGHT) game.setup( ) arcade.run() if __name__ = = "__main__": main() 

Window类具有几种方法,您的程序可以覆盖这些方法以提供程序功能。 以下是一些最常用的方法:


on_draw:所有用于绘制屏幕的代码都在这里。
更新:所有用于移动物品并执行游戏逻辑的代码都在这里。 每秒大约称为60次。
on_key_press:处理按键按下时的事件,例如,提高播放器的速度。
on_key_release:在释放键时进行处理,您可以在此处停止玩家的移动。
on_mouse_motion:每次鼠标移动时调用。
on_mouse_press:单击鼠标按钮时调用。
set_viewport:当您的世界远大于在一个屏幕上看到的世界时,此功能可用于滚动游戏。 使用set_viewport调用,程序员可以设置当前可见的哪个部分。


精灵


精灵是在Arcade中创建二维栅格对象简单方法。 Arcade的方法可以简化绘制,移动和设置精灵动画的过程。 您还可以轻松地使用精灵检测对象之间的碰撞。


精灵创建


从图形创建Sprite Arcade类的实例很容易。 程序员只需要图像文件的名称,以使子画面基于图像,还可以选择一个数字来按比例放大或缩小图像。 例如:


 SPRITE_SCALING_COIN = 0,2 coin = arcade.Sprite("coin_01.png", SPRITE_SCALING_COIN) 

这段代码将使用存储在coin_01.png中的图像创建一个精灵。 图像将缩小为原始高度和宽度的20%。
图片


精灵列表


精灵通常组织成列表。 这些列表有助于精灵的管理。 列表中的精灵将使用OpenGL批量绘制精灵。 下面的代码用一个玩家和一个玩家收集的一堆硬币来设置一个游戏。 我们使用两个列表,一个用于玩家,一个用于硬币。


 def setup(self): """ Set up the game and initialize the variables. """ # Create the sprite lists self.player_list = arcade.SpriteList() self.coin_list = arcade.SpriteList() # Score self.score = 0 # Set up the player # Character image from kenney.nl self. player_sprite = arcade.Sprite("images/character.png", SPRITE_SCALING_PLAYER) self.player_sprite.center_x = 50 # Starting position self.player_sprite.center_y = 50 self.player_list.append(self.player_sprite) # Create the coins for i in range( COIN_COUNT): # Create the coin instance # Coin image from kenney.nl coin = arcade.Sprite("images/coin_01.png", SPRITE_SCALING_COIN) # Position the coin coin.center_x = random.randrange(SCREEN_WIDTH) coin.center_y = random.randrange(SCREEN_HEIGHT) # Add the coin to the lists self.coin_list.append(coin) 

我们可以轻松地绘制硬币列表中的所有硬币:


 def on_draw(self): """ Draw everything """ arcade.start_render() self.coin_list.draw() self.player_list.draw() 

精灵碰撞检测


精灵碰撞检测
使用check_for_collision_with_list函数,我们可以查看一个精灵是否满足列表中的另一个精灵。 我们可以使用它来查看玩家的精灵与之接触的所有硬币。 使用简单的for循环,我们可以摆脱游戏中的硬币并提高得分。


 def update(self, delta_time): # Generate a list of all coin sprites that collided with the player. coins_hit_list = arcade.check_for_collision_with_list(self.player_sprite, self.coin_list) # Loop through each colliding sprite, remove it, and add to the score. for coin in coins_hit_list: coin.kill() self.score += 1 

有关完整示例,请参见collect_coins.py


游戏物理


许多游戏都包含某种物理学。 最简单的是自顶向下的程序,可以防止播放器穿过墙壁。 平台开发人员为重力和移动平台增加了更多的复杂性。 有些游戏使用具有质量,摩擦,弹簧等功能的成熟2D物理引擎。


自上而下的游戏


图片


对于简单的自上而下游戏,街机程序需要玩家(或其他任何人)无法通过的墙壁列表。 我通常将其称为wall_list。 然后,使用以下代码在Window类的安装代码中创建物理引擎:


 self.physics_engine = arcade.PhysicsEngineSimple(self.player_sprite, self.wall_list) 

Player_sprite接收具​​有两个属性的运动矢量:change_x和change_y。 一个简单的例子是使用键盘移动播放器。 例如,这可以在Window类的自定义子级中:


 MOVEMENT_SPEED = 5 def on_key_press(self, key, modifiers) : """Called whenever a key is pressed. """ if key = = arcade.key.UP: self.player_sprite.change_y = MOVEMENT_SPEED elif key = = arcade.key.DOWN: self.player_sprite.change_y = -MOVEMENT_SPEED elif key = = arcade.key.LEFT: self.player_sprite.change_x = -MOVEMENT_SPEED elif key = = arcade.key.RIGHT: self.player_sprite.change_x = MOVEMENT_SPEED def on_key_release(self, key, modifiers) : """Called when the user releases a key. """ if key = = arcade.key.UP or key = = arcade.key.DOWN: self.player_sprite.change_y = 0 elif key = = arcade.key.LEFT or key = = arcade.key.RIGHT: selfplayer_sprite.change_x = 0 

尽管此代码设置播放器的速度,但它不会移动播放器。 在更新Window类的方法中,调用Physics_engine.update()时,播放器将移动,但不能穿过墙壁。


 def update(self, delta_time): """ Movement and game logic """ self.physics_engine.update() 

有关完整的示例,请参见sprite_move_walls.py


平台游戏


图片


切换到侧视图的平台游戏机非常简单。 程序员只需要将物理引擎切换到PhysicsEnginePlatformer并添加重力常数即可。


 self.physics_engine = arcade.PhysicsEnginePlatformer(self.player_sprite, self.wall_list, gravity_constant= GRAVITY) 

您可以使用Tiled之类的程序来放置组成关卡的图块/块。


有关示例,请参见sprite_tiled_map.py


对于完整的2D物理,您可以集成PyMunk库。


从例子中学习


最好的学习方法之一就是一个例子。 Arcade图书馆提供了很多示例示例 ,人们可以用来创建游戏。 这些示例均显示了多年来学生在我的课程中或在Internet上要求的游戏概念。


安装Arcade后,运行这些演示程序很容易。 每个示例在程序的开头都有注释,您可以在命令行上输入一个命令来运行该示例,例如:


 python -m arcade.examples.sprite_moving_platforms 

简要信息


Arcade使您可以使用易于理解的代码开始对图形和游戏进行编程。 刚开始不久,许多新程序员就创造了出色的游戏。 试试看!

Source: https://habr.com/ru/post/zh-CN477544/


All Articles