如何实现围绕动态枢轴点的轨道视角切换?(仿OSRS视角)
复刻OSRS视角效果的代码问题排查
我正在尝试复刻《Old School Runescape》(OSRS)的视角效果,采用精灵堆叠来模拟3D环境而非使用真正的3D对象。核心逻辑是:玩家在世界中移动时,新的枢轴点应基于当前所在的瓦片,已定义位置的对象需要根据当前枢轴点调整自身位置。
对比效果:

我的实现代码:
import math import pygame from math import * from pygame import Vector2 import shader class DrawingObject: def __init__(self, mainWindow, modMapSurface, mapCenter, worldPosX, worldPosY, playerPosX, playerPosY, camRotAngle, camTiltAngle): self.mainWindow = mainWindow self.modMapSurface = modMapSurface self.mapCenter = mapCenter self.worldPosX = worldPosX self.worldPosY = worldPosY self.playerPosX = playerPosX self.playerPosY = playerPosY self.camRotAngle = camRotAngle self.camTiltAngle = camTiltAngle DrawingObject.draw(self) def draw(self): objectImageList = [] imageScale = 4 # worldPosX, worldPosY, imageFilePath worldObjectList = \ [ [512, 512, "Graphics\\person.png"], [640, 512, "Graphics\\testBlock3.png"], [768, 512, "Graphics\\testBlock2.png"], [896, 896, "Graphics\\frog.png"], ] for i in range(len(worldObjectList)): currentObjectImage = pygame.image.load(worldObjectList[i][2]).convert_alpha() # Scale imageWdith = currentObjectImage.get_width() imageHeight = currentObjectImage.get_height() scaledWidth = imageWdith * imageScale scaledHeight = imageHeight * imageScale currentObjectImage = pygame.transform.scale(currentObjectImage, (scaledWidth, scaledHeight)) cellCount = currentObjectImage.get_width() // currentObjectImage.get_height() print(cellCount) objPosX = worldObjectList[i][0] objPosY = worldObjectList[i][1] for i in range(cellCount): imageObjectRect = pygame.Rect(scaledHeight * i, 0, scaledHeight, scaledHeight) objectImageList.append(imageObjectRect) objectSurface = pygame.Surface((scaledHeight, scaledHeight)) objectSurface.blit(currentObjectImage, (0, 0), objectImageList[i]) objectSurface.set_colorkey([0, 0, 0]) # Call shader function #shader.shader(objectSurface, cellCount, i) objectSurfaceRot = pygame.transform.rotate(objectSurface, self.camRotAngle) objectRotWidth, objectRotHeight = objectSurfaceRot.get_size() # Object drawing modObjectSurface = pygame.transform.scale(objectSurfaceRot, (objectRotWidth, objectRotHeight / 90 * self.camTiltAngle)) #objectCenter = modObjectSurface.get_rect(center=(originPosX + self.worldPosX, originPosY + self.worldPosY - imageScale * i)) # Orbit #distance = math.sqrt((objPosX - objPosY)**2 + (self.worldPosX - self.worldPosY)**2) distance = Vector2(self.worldPosX, self.worldPosY).distance_to((objPosX, objPosY)) pivot = (self.worldPosX, self.worldPosY - imageScale * i) orbOffset = Vector2() # Need distance from player to obj orbOffset.from_polar((distance, -self.camRotAngle)) newPos = pivot + orbOffset orbRect = modObjectSurface.get_rect(center = newPos) self.mainWindow.blit(modObjectSurface, orbRect)
当前遇到的问题:
- 世界对象无法随世界位置进行正确调整
- 旋转相机时对象会出现上下“弹跳”的现象,相机倾斜度越低,该“弹跳”表现得越明显
我尝试过多种方式计算世界对象与玩家世界位置的距离,但最终的移动效果仍偏差很大。
内容的提问来源于stack exchange,提问作者PyGuy
相关产品推荐
相关产品推荐

