Recently playing Touhou, I tried mimicking a similar game in Python, loading some textures and music assets from the game. Overall, it wasn’t particularly difficult, but creating dazzling bullet patterns like those in the Touhou series proved quite brain-burning, with layer upon layer of mathematical functions.
One noteworthy point:
Two years ago, I worked on a similar project. Back then, I had just started with Java and GUI, so I made a Java version. However, since Java variables aren’t as flexible as Python’s, a rather serious bug emerged.
In the game, enemy planes should be able to fire bullet patterns in various directions—most classically, bullets that automatically track the player’s position. But at the time, the refresh rate was set to 60 FPS, and the game logic also updated at 60 FPS. Additionally, the display panel and bullet data shared the exact same coordinate system, meaning bullets could only move in whole-pixel increments. Visually, it seemed like bullets could pass through any pixel, but in reality, their trajectories were restricted to integer multiples of pixels.
In other words, when bullet movement speed was too slow, bullets could only fly in fixed directions like 180°, 135°, 90°, 45°, or 0°, making smooth, precise trajectories impossible.
In the new Python version, I fixed this issue. By separating the bullet’s actual coordinates from its display coordinates—rounding the display coordinates without involving them in calculations—I resolved the problem of imprecise bullet guidance.
最近在玩东方,尝试着用Python模仿了一个类似的,加载了游戏的一些贴图和音乐素材。总的来说没有什么难度,但是如果要做到像东方系列那样精彩的弹幕的话,还是比较烧脑的,函数公式一层又一层。
一个值得注意的地方:
我在两年前也做过类似的项目,当时刚接触JAVA和GUI,做了一个JAVA版的,但是由于JAVA的变量不像python可以随意更改,导致了一个比较严重的bug。
游戏中敌机应该是可以发送各种方向的弹幕,最为经典的莫过于可以自动跟踪玩家位置的弹幕。但是由于当时的设置刷新率为60fps,游戏逻辑代码也按照60fps的速度刷新,而且显示面板与弹幕的数据位置使用了完全相同的坐标系,导致弹幕每次只能在整数位置移动。显示上似乎是每个像素都可能经过,没什么问题,但是弹幕的实际飞行轨迹就只能按照整数倍像素点移动。
也就是说,当弹幕运动速度过慢时,弹幕只能按照180,135,90,45,0,这几种固定的方向飞行,无法实现精致的移动轨迹。
在新的python版本中,我解决了这个问题。将弹幕的实际坐标和显示坐标分开,显示坐标通过实际坐标取整,不参与计算,这样就解决了弹幕无法精确制导的问题。
