Pygame:使用滚动级别更新矩形
我目前正在 PyGame 中制作 2D 横向卷轴 run'n'jump 平台游戏。事实上,大多数东西都工作正常并且非常好 - 我正在利用快速的 pyGame Sprite 对象和 pyGame Sprite 对象。组。
我感兴趣的是人们通常如何处理滚动游戏中的矩形。显然,我有一个比可见区域大得多的关卡,并且玩家、敌人、子弹等都有自己的 (x,y) 坐标,用于描述它们在关卡中的位置。
但现在,由于我们使用“spriteGroup.draw(surface)”调用,它不会将它们显示在正确的位置,除非每个对象的矩形都已调整,以便正确的部分显示在屏幕上。换句话说,每次更新玩家/敌人/子弹/其他任何东西时,都需要传递Camera信息,以便更新它们的Rect。
这是最好的使用方法吗?它有效,但我真的不喜欢在每次更新时将相机信息传递给每个对象以偏移矩形。
显然,理想的方法(我认为)是使用具有“真实”坐标的矩形,将所有内容blit到与关卡一样大的缓冲区,然后将可见部分blit到屏幕,但实际上这会减慢游戏速度。
任何评论/见解将不胜感激。
谢谢
I'm currently making a 2D side-scrolling run'n'jump platform game in PyGame. Most of the stuff is working OK and very well in fact - I am exploiting the fast pyGame Sprite objects & groups.
What I'm interested to know is how people usually deal with Rects for scrolling games. I obviously have a level that is much bigger than visible area, and the player, enemies, bullets etc each have their own (x,y) coordinates which describe where they are in the level.
But now, since we use the "spriteGroup.draw(surface)" call, it will not display them in the right spot unless each objects Rects have been adjusted so that the right part displays on the screen. In other words, everytime a player/enemy/bullet/whatever else is updated, the Camera information needs to be passed, so that their Rect can be updated.
Is this the best method to use? It works but I don't really like passing the camera information to every single object at every update to offset the Rects.
Obviously the ideal method (I think) is to use Rects with "real" coordinates, blit everything to a buffer as big as the level, and then just blit the visible part to the screen, but in practice that slows the game down A LOT.
Any comments/insight would be appreciated.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以扩展 de Sprite.Group,以便它接收相机信息。
然后执行以下选项之一:
A. 重写 update 方法,以便更新每个精灵的屏幕坐标。
B. 重写绘制方法,以便更新每个精灵的屏幕坐标,然后调用其父绘制方法。
我认为 A 更容易、更干净。
You could extend de Sprite.Group so it recives the camera information.
Then do one of these options:
A. Override the update method so it updates the on-screen coordinates of every sprite.
B. Override the draw method so it updates the on-screen coordinates of every sprite and then calls its parent draw method.
I think A it's easier and cleaner.
相机可以是全局的,或者是全局 Game() 类实例的成员。那么你的精灵类的绘制方法不需要参数。
您可以自己覆盖绘制,所以它确实如此:
这使子弹的矩形保持在世界坐标中,但使用屏幕坐标进行位图传输。
Camera may be global, or, a member of a global Game() class instance. Then your sprite class's draw method doesn't need an argument.
You can override draw yourself, so it does:
This keeps the bullet's rect in world-coordinates, yet blits using screen-coordinates.
我发现的一种方法是跟踪scrollx 和scrolly。然后,只需将滚动x和滚动y添加到移动矩形时的坐标即可。
One method I found is to keep track of a scrollx and a scrolly. Then, just add scrollx and scroll y to the coordinates when you move the rectangles.
您可以使用 2 个变量
level_l
和level_d
来查看您在关卡中的位置,然后检查哪些精灵位于可见区域level_d+height
和level_l+width
,并将它们绘制在屏幕上。
You can have a 2 variables
level_l
andlevel_d
which see where you are in the level, Then check which sprites are in the visible arealevel_d+height
andlevel_l+width
,and draw them on the screen.
简单的方法是这样的:
创建一个 CameraX 和 CameraY 变量,当你在屏幕上位图传输对象时使用这个:
任何受相机影响的对象都应该像这样绘制,但请记住有对象您可能希望保持不受影响(例如健康栏或状态窗口),
请记住每次您想要移动相机时执行此操作
请记住,如果它们得到负值,它们可能无法正常工作,您还必须定义一些限制(你不希望你的相机移动超过地图的限制
The simple way to do it is like that:
Create a CameraX and CameraY variables, and when you blit objects on the screen use this:
any object that gets affected by the camera should be drawn like that, but keep in mind that there are objects that you may want to remain uneffected (like health bars or status windows)
just keep in mind everytime you want to move camera do this
Just keep in mind that if they get negative values they may not work correctly, also you must probably define some limits (you dont want your camera to move over the limits of your map