#python #pygame
#python #pygame
Вопрос:
Мне было интересно, могу ли я использовать карты с картинками для создания сплошных стен в моей игре, пример приведен ниже:
Как бы я приступил к созданию программы, которая генерирует карту на основе местоположений черной стены на моем изображении
Я уже некоторое время рассматривал возможность сделать это, хотя до сих пор я просто рисовал линии с помощью python.draw. Iv также рассмотрел использование turtles, но я не думаю, что это то, что я хочу для своей программы в настоящее время.
Комментарии:
1. Вы могли бы попробовать использовать Pillow для анализа областей пикселей на изображении, но я бы лично рекомендовал вместо этого использовать PyTMX и Tiled для создания карты, поскольку их намного проще реализовать, чем пытаться анализировать файл изображения по частям.
Ответ №1:
Вы можете прочитать значение цвета каждого пикселя.
Самый простой способ — использовать get_at
функцию для Surface
класса, но для большего количества функций и производительности вы также можете использовать PixelArray
или surfarray
модуль.
Другим способом было бы создать Mask
из изображений и использовать это для обнаружения столкновений.
Вот простой, хакерский, но работающий пример:
import pygame
class Player(pygame.sprite.Sprite):
def __init__(self, image, pos, background):
super().__init__()
self.image = image
self.pos = pygame.Vector2(pos)
self.rect = self.image.get_rect(center=self.pos)
self.background = background
def update(self, events, dt):
pressed = pygame.key.get_pressed()
move = pygame.Vector2((0, 0))
if pressed[pygame.K_w]: move = (0, -1)
if pressed[pygame.K_a]: move = (-1, 0)
if pressed[pygame.K_s]: move = (0, 1)
if pressed[pygame.K_d]: move = (1, 0)
if move.length() > 0: move.normalize_ip()
new_pos = self.pos move*(dt/5)
new_rect = self.rect.copy()
new_rect.center = new_pos
new_rect.clamp_ip(self.background.get_rect())
new_pos = new_rect.center
hit_box = self.background.subsurface(new_rect)
for x in range(new_rect.width):
for y in range(new_rect.height):
if sum(hit_box.get_at((x, y))) < 500:
return
self.pos = new_pos
self.rect.center = self.pos
def main():
pygame.init()
screen = pygame.display.set_mode((284, 384))
screen_rect = screen.get_rect()
clock = pygame.time.Clock()
sprites = pygame.sprite.Group()
background = pygame.transform.scale2x(pygame.image.load('maze.jpg'))
pimg = pygame.Surface((10, 10))
pimg.fill((200, 20, 20))
sprites.add(Player(pimg, (50, 50), background))
dt = 0
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
return
sprites.update(events, dt)
screen.fill(pygame.Color('grey'))
screen.blit(background, (0, 0))
sprites.draw(screen)
pygame.display.flip()
dt = clock.tick(60)
if __name__ == '__main__':
main()
Конечно, это можно улучшить, например, используя изображение с альфа-значениями, чтобы вы могли легко создавать маски; но вы поймете идею: просто «посмотрите» на пиксели вашей поверхности…
Комментарии:
1. Масштабируется ли это для добавления большего количества лабиринтов? Я думал о том, чтобы заставить интерфейс получать pos спрайта, а затем определять, когда он достигает -15 и 815, когда он проходит через пробелы, ведущие к новому уровню
2. @KallumHancox Конечно, почему бы и нет. Вы также могли бы удалить
new_rect.clamp_ip
часть, а затем проверить, есть лиnot background.get_rect().contains(new_rect)
или что-то в этом роде. Просто почитайте немного в документах pygame, если вы еще этого не сделали. Вероятно, вы найдете много полезного.