如何创建 Cocoa 库并在 python 中使用它

发布于 2024-09-08 12:56:16 字数 756 浏览 12 评论 0原文

我一直在制作一个游戏,但我使用的 python 库(Pyglet)很糟糕。我想尝试在 OSX 版本中使用 Cocoa。

我将能够弄清楚如何使用 NSWindow 和 NSOpenGLView 等类中的对象,然后将这些对象放入我自己的类中以进行游戏循环。

我不知道如何使用 PyObjC 加载我可以制作的动态 Objective-C 库,然后使用我将在 python 中制作的类来设置我认为可以由 NSTimer 循环的游戏。

但是,循环方法还需要从许多 python 类之一调用 python 方法。我的游戏由许多 python 类组成,这些类用于游戏的不同部分(Mapmaker、GameSession、AnacondaGame 等)。游戏循环需要根据当前部分调用任何这些类中的循环方法并传递信息。

PyObjC 显然是“双向”的,那么这是如何完成的呢?

或者,我可以创建两个由 py​​thon 调用的方法,并在中间添加 python 代码,其中循环由 python 控制。

PyObjC 网站上的“文档”似乎只解释了如何在 python 中使用 Cocoa 而没有其他内容。

我不能做的是使用界面生成器制作一个固定的 GUI,因为库需要根据我的类的初始化方法的 python 输入创建窗口。

了解 Objective-C 的语法并不是一个大问题,我可以参考 Cocoa 文档来制作我需要的对象。

感谢您的帮助。我们将非常感激。我厌倦了使用 pygame 和 pyglet 等损坏的库,使用特定于平台的操作系统 API 似乎是确保质量的最佳方法。

I've been making a game and the python library I was used is terrible (Pyglet). I want to try using Cocoa for the OSX version.

I'll be able to figure out using the objects from classes like NSWindow and NSOpenGLView and then put these objects in my own class for the game loop.

I have no idea how I can use PyObjC to load a dynamic Objective-C library I can make and then use the class I will make in python to setup the game which I suppose can be looped by NSTimer.

However, the loop method will also need to call a python method from one of many python classes. My game consists of many python classes which are used for different sections of the game (Mapmaker,GameSession,AnacondaGame etc.). The game loop will need to call a loop method in any of these classes depending on the current section and pass even information.

PyObjC is "bi-directional" apparently so how is that done?

Alternatively I could create two methods to be called by python and I add the python code in-between, where the loop is controlled by python.

The "documentation" on the PyObjC website only seem to explain how to use Cocoa in python and nothing else.

What I can't do is make a fixed GUI with the interface builder because the library will need to create windows based on the python input to an initialisation method of my class.

Knowing the syntax of Objective-C isn't a big problem and I can reefer to the Cocoa documentation to make the objects I require.

Thank you for any help. It will be appreciated very much. I'm sick of using broken libraries like pygame and pyglet, using the platform specific OS APIs seems to be the best method to ensure quality.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你与昨日 2024-09-15 12:56:16

PyObjC 将 Python 与 Objective-C 运行时桥接起来,因此,如果您在 Python 中创建 NSObject 子类,则可以从同一进程中运行的 Objective-C 代码访问它们。这意味着您需要将所有 Python 功能封装在 NSObject 的子类中,您可以通过桥访问该子类。

我这样做的方法是在 Objective-C 端有一个单例控制器类,它有一个类似 -(void)pythonReady:(PythonClass *)pythonObject 的方法,并且还处理加载Python 代码(确保加载 Python 代码时控制器类存在)。然后,在 Python 代码中,创建 PythonClass 的实例后,您可以在控制器单例上调用 pythonReady:。然后,在 Objective-C 端的 pythonReady: 中,您可以调用 pythonObject 上所需的任何方法,这将在 Python 端运行代码。

要从控制器类加载 Python 代码,您可以执行以下操作:

#import <Python/Python.h>

@implementation PythonController (Loading)
- (void)loadPython {
    NSString *pathToScript = @"/some/path/to/script.py";
    setenv("PYTHONPATH", [@"/some/path/to/" UTF8String], 1);
    Py_SetProgramName("/usr/bin/python");
    Py_Initialize();
    FILE *pyScript = fopen([pathToScript UTF8String], "r");
    int result = PyRun_SimpleFile(pyScript, [[pathToScript lastPathComponent] UTF8String]);
    if (result != 0) { NSLog(@"Loading Python Failed!"); }
}
@end

基本上,我们只需使用 Python C API 在当前进程内运行脚本。该脚本本身启动了当前进程中运行时的桥梁,然后您可以在其中使用 Cocoa API 访问您的控制器单例。

PyObjC bridges Python to the Objective-C runtime, so if you create NSObject subclasses in Python, they'll be accessible from Objective-C code running in the same process. What this means is that you'll need to encapsulate all of your Python functionality in a subclass of NSObject that you can access over the bridge.

The way I'd do this is by having a singleton controller class on the Objective-C side that has a method like -(void)pythonReady:(PythonClass *)pythonObject, and also handles the loading of the Python code (which ensures that the controller class exists when your Python code is loaded). Then, in your Python code, after creating an instance of your PythonClass, you can call pythonReady: on your controller singleton. Then, in pythonReady: on the Objective-C side, you can call whatever methods you need on pythonObject, which will run the code on the Python side.

To load the Python code from your controller class, you can do something like this:

#import <Python/Python.h>

@implementation PythonController (Loading)
- (void)loadPython {
    NSString *pathToScript = @"/some/path/to/script.py";
    setenv("PYTHONPATH", [@"/some/path/to/" UTF8String], 1);
    Py_SetProgramName("/usr/bin/python");
    Py_Initialize();
    FILE *pyScript = fopen([pathToScript UTF8String], "r");
    int result = PyRun_SimpleFile(pyScript, [[pathToScript lastPathComponent] UTF8String]);
    if (result != 0) { NSLog(@"Loading Python Failed!"); }
}
@end

Basically, we simply use the Python C API to run the script inside the current process. The script itself starts the bridge to the runtime in the current process, where you can then use the Cocoa API to access your controller singleton.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文