Я делаю свою первую игру в pygame, но когда я сгенерировал свой мир и пытаюсь переместить своего персонажа, его спрайт все еще остается в старом положении. Я не могу стирать свой фон в каждом кадре, так как он слишком велик и снижает производительность pygame.
Я пытался бликать каждый кадр, но это также замедляло работу pygame. Затем я попытался сделать его бликом вокруг персонажа, чтобы он закрывал старую фотографию моего персонажа, но у меня тоже не получилось заставить это работать.
def MakeTerrain():
TempY = 0
for o in range(51):
for i in range(51):
TempX = 16 * i
if TempX >= 800:
TempY = 16 * o
TempX = 0
rnd = random.randrange(10)
if rnd <= 8:
tile = Tile("Grass",[TempX,TempY])
else:
tile = Tile("Stone",[TempX,TempY])
Tiles.append(tile)
tile.BlitTile(Display)
Функция для создания моего ландшафта [он же мир/фон]
class Player():
def __init__(self,MovementSpeed=1):
self.DirectionX = 0
self.DirectionY = 0
self.PlayerPos = [0,0]
self.MovementSpeed = MovementSpeed
self.PlayerSprite = pygame.image.load("Jeffrey.png")
def BlitPlayer(self,display):
display.blit(self.PlayerSprite,(self.PlayerPos[0],self.PlayerPos[1]))
Класс моего игрока с моей блит-функцией
class Tile():
def __init__(self,sprite,Position):
self.TilePosition = Position
self.TileSprite = pygame.image.load(sprite+".png")
def BlitTile(self,display):
display.blit(self.TileSprite,(self.TilePosition[0],self.TilePosition[1]))
Класс плитки
Вот что происходит
Я пытался использовать функцию BlitTile для каждого объекта Tile в каждом кадре, но это просто слишком сильно снижает частоту кадров pygame.
Я думаю, что понял проблему. Вы рисуете более 2500 тайлов в каждом кадре. Блит не дорогая функция, но при таком количестве объектов она начинает складываться. Я попытаюсь сделать ответ, чтобы оптимизировать его.
Я знаю, что блит 2500 плиток в каждом кадре, но я не знаю, как это сделать иначе. Спасибо! :)
Я думаю, что идея перерисовывать только тайлы рядом с игроком может сработать, но ее нужно немного переработать.
Это потребует изменения значений вашей позиции на pygame.math.Vector2
, поэтому сделайте это в первую очередь, я также рекомендую изменить все экземпляры этих значений на self.pos
, чтобы цикл, который я вам покажу, было проще сделать.
self.pos = pygame.math.Vector2(Position)
Чтобы получить значения x и y, они просто self.pos.x
или self.pos.y
В коде отрисовки вы можете сначала изменить его, чтобы он перебирал каждый спрайт:
for sprite in my_sprites:
pass
Внутри этого цикла вы можете проверить расстояние от спрайта до игрока, используя эти новые векторы:
deltaVec = player.pos - sprite.pos # Find delta [difference] between player position and sprite position
len = deltaVec.length() # Find the length between those two points through the distance formula
Затем, в конце, проверьте, находится ли новое расстояние ниже определенного порога:
if len < 100: # 100 being the distance, change if needed
sprite.draw()
В итоге новый код отрисовки будет выглядеть так:
for sprite in my_sprites:
deltaVec = player.pos - sprite.pos
len = deltaVec.length()
if len < 100: # 100 being the distance, change if needed
sprite.draw()
Это должно перерисовывать только ближайшие к игроку плитки, и все, без необходимости управлять каждой плиткой.
Я не совсем понимаю, что вы здесь хотите, похоже, вам просто нужно заполнять экран на каждой итерации, чтобы предотвратить перекрытие. Но, если все, что вы делаете, — это мигание фона перед игроком, это не должно перегружать возможности pygames. Вы уверены, что не регенерируете всю карту на каждой итерации цикла?