如何在 Kivy 中实现鼠标驱动的部件旋转(使矩形始终朝向鼠标位置)

落晨小哥_5941

落晨小哥_5941

2026-04-15

314人浏览

原创

如何在 Kivy 中实现鼠标驱动的部件旋转(使矩形始终朝向鼠标位置)

本文详解如何使用 Kivy 的 PushMatrix/PopMatrix 与 Rotate 指令,结合鼠标坐标实时计算旋转角度,让一个矩形始终以其短边垂直指向鼠标位置,实现动态瞄准效果。

本文详解如何使用 kivy 的 `pushmatrix`/`popmatrix` 与 `rotate` 指令,结合鼠标坐标实时计算旋转角度,让一个矩形始终以其短边垂直指向鼠标位置,实现动态瞄准效果。

在 Kivy 中实现“鼠标跟随旋转”的核心逻辑并非直接修改 Widget 的 rotation 属性(该属性不支持局部坐标系下的精确锚点旋转),而是借助 OpenGL 绘图指令,在画布(canvas)中动态重绘:每次鼠标移动时,清除旧图形,重新应用旋转变换,并以指定锚点(如矩形中心或某角点)为原点执行 Rotate。

以下是一个完整、可运行的实现方案:

✅ 关键步骤解析

  1. 定义旋转锚点(origin):为使矩形“指向”鼠标,需选择一个固定参考点(如矩形中心或一端中点)。示例中采用 fixed_point = (x, y + height/2) —— 即矩形底边中点,模拟“炮管基座”,确保旋转后顶部自然朝向鼠标。
  2. 实时计算角度:使用 math.atan2(dy, dx) 计算从锚点到鼠标的极角(弧度),再转为角度(math.degrees())。注意:Kivy 的 Rotate.angle 是逆时针为正,且 Y 轴向上,与屏幕坐标系一致,无需额外翻转。
  3. 安全重绘机制:每次调用 self.canvas.clear() 清除上一帧,再在 with self.canvas: 块中重建图形。务必包裹 PushMatrix 和 PopMatrix,避免变换污染后续绘图。

? 完整代码(精简优化版)

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.graphics import Color, Rectangle, PushMatrix, PopMatrix, Rotate
import math

class MenuScreen(Screen):
    pass

class Game(Screen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # 矩形尺寸与初始位置
        self.cannon_size = (150, 50)
        self.cannon_pos = (300, 200)  # 初始左下角坐标
        # 旋转锚点:取矩形底边中点(模拟炮座)
        self.fixed_point = (
            self.cannon_pos[0] + self.cannon_size[0] / 2,
            self.cannon_pos[1]
        )
        # 绑定鼠标移动事件
        Window.bind(mouse_pos=self.update_rotation)

    def update_rotation(self, *args):
        mouse_x, mouse_y = Window.mouse_pos
        # 计算相对位移
        dx = mouse_x - self.fixed_point[0]
        dy = mouse_y - self.fixed_point[1]
        # 计算角度(atan2 自动处理象限)
        angle = math.degrees(math.atan2(dy, dx))

        # 清空并重绘
        self.canvas.clear()
        with self.canvas:
            PushMatrix()
            # 以 fixed_point 为原点旋转
            Rotate(angle=angle, origin=self.fixed_point)
            Color(0.2, 0.6, 0.8, 1)  # 蓝色矩形
            Rectangle(pos=self.cannon_pos, size=self.cannon_size)
            PopMatrix()

class Myapp(ScreenManager):
    pass

class MyApp(App):
    def build(self):
        return Myapp()

if __name__ == '__main__':
    MyApp().run()

? 对应 my.kv 文件(最小化配置)

<myapp>:
    MenuScreen:
        name: "home"
    Game:
        name: "game"

<menuscreen>:
    BoxLayout:
        Button:
            text: "I'M READY."
            font_size: 48
            on_release: root.current = 'game'

<game>:
    # 可选:添加背景色便于观察
    canvas.before:
        Color:
            rgba: 0.1, 0.1, 0.1, 1
        Rectangle:
            pos: self.pos
            size: self.size</game></menuscreen></myapp>

⚠️ 注意事项与进阶建议

  • 性能提示:高频 canvas.clear() + 重绘适用于简单图形;若需高性能(如大量旋转对象),应改用 InstructionGroup 或 Canvas.add() 动态管理指令。
  • 坐标系陷阱:Window.mouse_pos 返回的是窗口绝对坐标(左下为原点),而 Rectangle.pos 默认也是窗口坐标系,二者单位一致,可直接运算。
  • 平滑优化:如需缓动效果,可用 kivy.clock.Clock.schedule_interval 替代实时绑定,配合插值算法(如 angle = lerp(old_angle, target_angle, 0.1))。
  • 交互扩展:可进一步结合 on_touch_down 实现点击发射、拖拽调整位置等逻辑。

通过本方案,你已掌握 Kivy 中基于画布的动态旋转核心技术——它灵活、精准,是构建游戏瞄准、仪表盘指针、旋转 UI 元素等场景的基石。

驱动精灵
驱动精灵

驱动精灵基于驱动之家十余年的专业数据积累,驱动支持度高,已经为数亿用户解决了各种电脑驱动问题、系统故障,是目前有效的驱动软件,有需要的小伙伴快来保存下载体验吧!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1751

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4504

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1729

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

26497

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3207

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3227

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1183

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2503

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.7万人学习