【发布时间】:2020-03-29 06:23:25
【问题描述】:
我学习 Python 才几周,这个问题让我很困惑。我正在尝试使用 Pygame 创建一个简单的塔防风格游戏。谷歌搜索和研究超过 4 小时(pygame 文档网站在发布时已关闭,依赖于缓存版本)。我相信它最终会变得很容易修复,但我没有想法。
我将 Tower 类放在一个文件中,而将主游戏循环放在另一个文件中。图像文件存储在名为“assets”的文件夹中,该文件夹与塔类和主游戏循环位于同一目录中。当我尝试创建一个新塔时,特别是加载塔的图像,我得到标题中列出的错误。
我知道我以某种方式传递了“表面”作为参数,但我终其一生都无法弄清楚它在哪里。我让玩家使用 1 或 2 键选择他们正在建造的塔的类型,然后查找该按键的相应图像,然后将塔放置在他们在屏幕上单击的位置。在点击鼠标的 pygame 事件之后的 print 语句正确地将“elf_tower.png”列为文件名,但类的 init 中的 print 语句显示为“”。如果我为图像硬编码文件名,该类将正常运行,但我怀疑这是最好的解决方案。我还尝试将变量设置为“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()
塔类文件:
"""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
【问题讨论】:
标签: python python-3.x pygame