使用 Pyxel 入门 2D 游戏(第 6 部分):移动角色

发布: (2026年1月9日 GMT+8 23:00)
5 min read
原文: Dev.to

Source: Dev.to

请提供您希望翻译的正文内容,我将为您翻译成简体中文并保持原有的格式、Markdown 语法以及技术术语不变。

Source:

移动角色

现在是时候真正让我们在上一章节创建的精灵移动了。

在本章节中,我们将为精灵引入 速度 的概念,并构建一个简单的移动系统。

完整代码展示在本文末尾。

1. 改进 Sprite 类

首先,我们增强通用基类 BaseSprite

在它的构造函数中,新增两个成员变量:vxvy
这些变量会在 update() 步骤中被加到精灵的坐标 xy 上。
这样,角色的位置会一点点变化,从而在游戏画面上呈现出移动的效果。

我们还添加了一个名为 move() 的新方法。顾名思义,这个方法用于启动移动。它接受速度和角度两个参数:

  • 水平分量(X 方向)使用 math.cos() 计算,并赋值给 vx
  • 垂直分量(Y 方向)使用 math.sin() 计算,并赋值给 vy

(你暂时不需要完全理解背后的数学——没关系!)

# sprite.py (excerpt)

class BaseSprite:

    def __init__(self, x, y, w=8, h=8):
        """ Constructor """
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.vx = 0  # Velocity (X direction)
        self.vy = 0  # Velocity (Y direction)

    def update(self):
        """ Update logic """
        self.x += self.vx  # Move in X direction
        self.y += self.vy  # Move in Y direction

    def draw(self):
        """ Drawing logic (implemented in subclasses) """
        pass

    def move(self, spd, deg):
        """ Start movement """
        rad = deg * math.pi / 180
        self.vx = spd * math.cos(rad)  # X velocity
        self.vy = spd * math.sin(rad)  # Y velocity

2. 定义常量

接下来,在 main.py 中添加一个常量,用来表示玩家的移动速度。将数值定义为常量可以让以后更容易调整。

# main.py (add constants)

SHIP_SPD = 1.4  # Player speed

3. 测试精灵移动

现在让我们检查精灵是否真的会移动。在 Game 类的构造函数中,给玩家下达一个移动指令用于测试。

# main.py (added to the Game class constructor)

# Test movement (toward the upper‑left)
self.ship.move(SHIP_SPD, 220)

尝试更改角度值,确认移动方向也随之改变。

完整代码

以下是截至目前已实现的全部功能的完整代码。

# sprite.py

import pyxel
import math
import random

class BaseSprite:

    def __init__(self, x, y, w=8, h=8):
        """ Constructor """
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.vx = 0  # Velocity (X direction)
        self.vy = 0  # Velocity (Y direction)

    def update(self):
        """ Update logic """
        self.x += self.vx  # Move in X direction
        self.y += self.vy  # Move in Y direction

    def draw(self):
        """ Drawing logic (implemented in subclasses) """
        pass

    def move(self, spd, deg):
        """ Start movement """
        rad = deg * math.pi / 180
        self.vx = spd * math.cos(rad)  # X velocity
        self.vy = spd * math.sin(rad)  # Y velocity

class ShipSprite(BaseSprite):

    def __init__(self, x, y):
        """ Constructor """
        super().__init__(x, y)

    def draw(self):
        """ Drawing logic """
        pyxel.blt(
            self.x, self.y, 0,
            0, 0,
            self.w, self.h, 0
        )  # Ship
# main.py

import pyxel
import math
import random
import sprite

W, H = 160, 120
SHIP_SPD = 1.4  # Player speed

# Game
class Game:
    def __init__(self):
        """ Constructor """

        # Initialize score
        self.score = 0

        # Initialize player
        self.ship = sprite.ShipSprite(W / 2, H - 40)

        # Test movement (toward the upper‑left)
        self.ship.move(SHIP_SPD, 220)

        # Start Pyxel
        pyxel.init(W, H, title="Hello, Pyxel!!")
        pyxel.load("shooter.pyxres")
        pyxel.run(self.update, self.draw)

    def update(self):
        """ Update logic """

        # Update player
        self.ship.update()

    def draw(self):
        """ Drawing logic """
        pyxel.cls(0)

        # Draw score
        pyxel.text(
            10, 10,
            "SCORE:{:04}".format(self.score),
            12
        )

        # Draw player
        self.ship.draw()

def main():
    """ Main entry point """
    Game()

if __name__ == "__main__":
    main()

运行此程序时,结果将如下所示:

演示 GIF

接下来…

感谢您阅读本章节。
下一个标题是 “控制角色”。

下次见!!

Back to Blog

相关文章

阅读更多 »