更改同一类的所有对象的单个参数



我之前问过一个比较微笑的问题,但过于概括,无法得到有用的答案。我对Python,pygame和编程很陌生。我想用python做一个游戏,在游戏中,你可以通过地牢控制玩家。我已经创建了一个播放器并对其进行了动画处理。我还设置了比游戏窗口更大的地图,并实现了移动背景,以创建一种"探索"效果。如果我的玩家到达游戏窗口内的边界,较大的背景图像将向与速度值相同的玩家相反的方向移动。现在我创建了一个类 Obstacle((,并希望将此类的对象放置在我的地图上,以便稍后添加碰撞。显然,障碍物对象应该停留在地图背景上的位置,意味着,随之移动。将背景移动 if 语句转换为障碍物移动语句没有大问题,但我计划创建更多障碍,并且不想为每个障碍添加这堆 if 语句。这里有人知道我如何实现我的计划吗?因为我是编程新手,所以我感谢与我的编程风格相关的所有其他技巧。这是我的整个代码。提前谢谢你。

import pygame
import pygame.event
pygame.init()
# sets the width and hight of the window
window_width = 800
window_height = 600
# sets the area, the hero is allowed to move without changing background
window_visible_x = 150
window_visible_y = 150
# creates the window and gives it a title
window = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("Dungeon")
# sets images or creates a list of images for animation
hero_image_walking_right = [pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/hero_right_1.png"), pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/hero_right_2.png"), pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/hero_right_3.png"), pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/hero_right_4.png"), pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/hero_right_3.png"), pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/hero_right_2.png")]
hero_image_walking_left = [pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/hero_left_1.png"), pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/hero_left_2.png"), pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/hero_left_3.png"), pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/hero_left_4.png"), pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/hero_left_3.png"), pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/hero_left_2.png")]
hero_image_facing_right = pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/hero_facing_right.png")
hero_image_facing_left = pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/hero_facing_left.png")
background_image = pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/test_background.png")
obstacle_1_image = pygame.image.load(r"/Users/myname123/Documents/Python Docs/Dungeon/pics_ready/png/obstacle_1.png")
# creates a clock
clock = pygame.time.Clock()
# redrawas the whole window every tick
def redraw_window():
# sets background
window.blit(background_image, (background.x, background.y))
# sets obstacle
window.blit(obstacle_1_image, (obstacle_1.x, obstacle_1.y))
# sets walk counter for animation to 0 in case it reaches 60
if hero.walk_count + 1 >= 60:
hero.walk_count = 0
# animates the hero while moving
if hero.walking_left:
window.blit(hero_image_walking_left[hero.walk_count//10], (hero.x, hero.y))
hero.walk_count += 1
elif hero.walking_right:
window.blit(hero_image_walking_right[hero.walk_count//10], (hero.x, hero.y))
hero.walk_count += 1
elif hero.walking_up:
if hero.facing_left:
window.blit(hero_image_walking_left[hero.walk_count//10], (hero.x, hero.y))
hero.walk_count += 1
elif hero.facing_right:
window.blit(hero_image_walking_right[hero.walk_count//10], (hero.x, hero.y))
hero.walk_count += 1
elif hero.walking_down:
if hero.facing_left:
window.blit(hero_image_walking_left[hero.walk_count//10], (hero.x, hero.y))
hero.walk_count += 1
elif hero.facing_right:
window.blit(hero_image_walking_right[hero.walk_count//10], (hero.x, hero.y))
hero.walk_count += 1

# sets a standing picture for hero while not moving depneding on last moved direction
else:
if hero.facing_left:
window.blit(hero_image_facing_left, (hero.x, hero.y))
else:
window.blit(hero_image_facing_right, (hero.x, hero.y))
hero.hitbox = (hero.x, hero.y, hero.width, hero.height)
pygame.draw.rect(window, (255, 0, 0), hero.hitbox, 2)
obstacle_1.hitbox = (obstacle_1.x, obstacle_1.y, obstacle_1.width, obstacle_1.height)
pygame.draw.rect(window, (255, 0, 0), obstacle_1.hitbox, 2)
print(background.x, background.y)
# updates the window
pygame.display.update()
def moving_hero():
# start of testing for inputs
keys = pygame.key.get_pressed()
if keys[pygame.K_a] or keys[pygame.K_d] or keys[pygame.K_w] or keys[pygame.K_s]:
if keys[pygame.K_a] and hero.x > window_visible_x - hero.width:
hero.x -= hero.velocity
hero.walking_left = True
hero.walking_right = False
hero.walinkg_up = False
hero.walking_down = False
hero.facing_left = True
hero.facing_right = False
elif keys[pygame.K_a] and hero.x <= window_visible_x - hero.width and background.x < 0:
background.x += hero.velocity
Obstacle.x += hero.velocity
if keys[pygame.K_d] and hero.x < window_width - window_visible_x:
hero.x += hero.velocity
hero.walking_left = False
hero.walking_right = True
hero.walinkg_up = False
hero.walking_down = False
hero.facing_left = False
hero.facing_right = True
elif keys[pygame.K_d] and hero.x >= window_width - window_visible_x and background.x > window_width - background.width:
background.x -= hero.velocity
Obstacle.x -= hero.velocity
if keys[pygame.K_w] and hero.y > window_visible_y - hero.height:
hero.y -= hero.velocity
hero.walking_left = False
hero.walking_right = False
hero.walking_up = True
hero.walking_down = False
elif keys[pygame.K_w] and hero.y <= window_visible_y - hero.height and background.y < 0:
background.y += hero.velocity
Obstacle.y += hero.velocity
if keys[pygame.K_s] and hero.y < window_height - window_visible_y:
hero.y += hero.velocity
hero.walking_left = False
hero.walking_right = False
hero.walinkg_up = False
hero.walking_down = True
elif keys[pygame.K_s] and hero.y >= window_height - window_visible_y and background.y > window_height - background.heigth:
background.y -= hero.velocity
Obstacle.y -= hero.velocity
else:
hero.walking_left = False
hero.walking_right = False
hero.walking_up = False
hero.walking_down = False
hero.walk_count = 0

# class Living for all moveable objects. Every object is given a x- and y- coordiante, a width and a height, health and velocity as well as a parameter to indicat in which directions its moving and facing
class Living():
def __init__(self, x, y, width, height, health, velocity):
self.x = x
self.y = y
self.width = width
self.height = height
self.health = health
self.velocity = velocity
self.walk_count = 0
self.walking_left = False
self.walking_right = False
self.walking_up = False
self.walking_down = False
self.facing_left = False
self.facing_right = True
self.hitbox = (self.x, self.y, 64, 64)
# class Background for different backgrounds. Every background is given a x- and y- coordinate as well as a width and height
class Background():
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.heigth = height
class Obstacle():
def __init__(self, x, y, width, height):
self.x
self.y
self.width = width
self.height = height
self.hitbox = (self.x, self.y, self.width, self.height)

# creates a objects of class Living
hero = Living(200, 200, 64, 64, 100, 3)
# creates objects of class Background
background = Background(0, 0, 2000, 2000)
# creates an obstacle of class Obstacle
obstacle_1 = Obstacle(500, 500, 50, 60)
# run variable is set to True
run = True
# as long as run = True the following things are getting executet every clock tick
while run:
# sets clock tick
clock.tick(60)
# allows the user to close the game by pressing the X button above the gamewindow
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
moving_hero()
redraw_window()
pygame.quit()

很难理解你想做什么。 但是您可以将所有障碍添加到列表、字典或一些可迭代对象中,并迭代它以更改其属性。

您还可以使用类变量和属性,如下所示:

class Obstacle:
reference_x = 0
def __init__(self, x):
self._x = x
@property
def x(self):
return self.reference_x + self._x
@x.setter
def x(self, x):
self._x = x

如果您对其进行测试:

a = Obstacle(1)
print(a.x)
>> 1
Obstacle.reference_x = 12
print(a.x)
>> 13

解释

reference_x是一个类属性。它可以从类的所有实例以及类对象本身访问,并且对于类的每个实例都是相同的。

属性允许您定义访问、更改或删除属性的方式。 所以在这里我使用一个"private"属性_x(_是将属性标识为私有的常见约定,因为在python中实际上不存在这样的东西(。 然后我定义一个属性x,带有返回self.reference_x + self._xgetter。每次您尝试访问变量时都会调用此函数,因此它的工作原理:当您更改reference_x并再次调用属性 x 时,它会使用新值 reference_x 计算 x。我还定义了一个 setter 以确保用户相对于 reference_x 更改 x(通过更改 _x(

请记住,每次要访问 x 属性时都会执行self.reference_x + self._x,即使reference_x属性没有更改也是如此。如果您真的对性能感到绝望,这可能是一个问题。

我建议您在线查看免费的python课程,以更清晰,更深入地解释属性和python对象。

最新更新