Я учил Python только пару недель, и эта проблема поставила меня в тупик. Я пытаюсь создать простую игру в стиле Tower Defense, используя Pygame. Занимался поиском и поиском более 4 часов (на момент публикации веб-сайт Pygame Docs не работал, полагаясь на кэшированную версию). Я уверен, что это в конечном итоге будет легко исправить, но у меня нет идей.
У меня есть класс Tower в одном файле, а основная игра l oop в другом файле. Файлы изображений хранятся в папке с именем «assets», которая находится в том же каталоге, что и класс tower и основная игра l oop. Когда я пытаюсь создать новую башню, в частности загрузить изображение башни, я получаю сообщение об ошибке, указанное в заголовке.
Я понимаю, что каким-то образом передаю «Поверхность» в качестве параметра, но не могу для жизнь меня понять, где это. У меня есть игрок, выбирающий тип башни, которую он строит, используя клавиши 1 или 2, затем ищите соответствующее изображение для этого нажатия клавиши, затем помещайте башню там, где они щелкают по экрану. Оператор print сразу после события pygame для щелчка мыши правильно указывает «elf_tower.png» в качестве имени файла, но оператор печати в init класса говорит «». Класс работает нормально, если я жестко закодирую имя файла для изображения, но я сомневаюсь, что это лучшее решение. Я также попытался установить переменную равной «assets /» + tower_type, но он также сказал, что не может объединить Surface с str.
Основной файл:
"""Homebrew tower defense game using pygame and object oriented programming.
This is a learning project"""
import pygame
from tower import Tower
from scaling import get_scaling_info
get_scaling_info()
def run_game():
"""Runs the game"""
pygame.init()
get_scaling_info()
width, height = get_scaling_info()[1:]
screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN, 32)
pygame.display.set_caption("Tower Defense")
game_surface = screen.copy()
def toggle_fullscreen():
"""Toggles between fullscreen and windowed mode"""
if screen.get_flags() & pygame.FULLSCREEN:
return pygame.display.set_mode((800, 600), pygame.RESIZABLE)
return pygame.display.set_mode((width, height), pygame.FULLSCREEN)
def update_display():
"""Update the game display"""
scaling_info = get_scaling_info()[0]
screen.fill((0, 0, 0))
for tower in Tower.towers:
tower.draw()
screen.blit(pygame.transform.scale(
game_surface, (scaling_info.current_w, scaling_info.current_h)), (0, 0))
pygame.display.update()
run = True
tower_type = 0
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
if event.key == pygame.K_F11:
toggle_fullscreen()
if event.key == pygame.K_1 or event.key == pygame.K_2:
tower_type = Tower.selection_dict[event.key]
if event.type == pygame.MOUSEBUTTONDOWN and tower_type != 0: #to prevent game from breaking if no tower selected.
print(tower_type) #returns elf_tower.png which is the expected result
mouse_x, mouse_y = pygame.mouse.get_pos()
Tower(tower_type, mouse_x, mouse_y).create_tower()
update_display()
pygame.quit()
run_game()
Класс Tower file:
"""Contains the class used to generate towers"""
import os
import pygame
from scaling import get_scaling_info
get_scaling_info()
class Tower:
"""Tower information"""
selection_dict = {49:"elf_tower.png", 50:"dwarf_tower.png"} #pygame keypress of 1 corresponds to value 49, 2 to 50.
towers = []
def __init__(self, img, x, y, display_surface="game_surface"):
x_scale, y_scale = get_scaling_info()[1:]
self.img = pygame.image.load(os.path.join('assets', img))
print(self.img) # returns <Surface(40x40x32 SW)>
self.x_coord = x * x_scale
self.y_coord = y * y_scale
self.display_surface = display_surface
def create_tower(self):
"""Creates a tower of the selected type and scales to the correct size"""
Tower.towers.append(Tower(self.img, self.x_coord, self.y_coord))
print(Tower.towers)
def draw(self):
"""Draws the tower on the screen using the specified image at coordinates x and y"""
pygame.transform.scale(self.img, (32, 32))
self.display_surface.blit(self.img, (self.x_coord, self.y_coord))
print(self.img)
# def attack(self):
# """Causes the tower to attack enemies in range
# Not yet written"""
Файл масштабирования изображения
"""Gets the scaling info used in the other modules of the game"""
import pygame
def get_scaling_info():
"""Gathers display info for scaling elements of the game"""
pygame.init()
display_info = pygame.display.Info()
scaling_info = pygame.display.Info()
x_ratio = display_info.current_w/scaling_info.current_w
y_ratio = display_info.current_h/scaling_info.current_h
return scaling_info, x_ratio, y_ratio