#python #oop
#python #ооп
Вопрос:
Я пытаюсь создать простую игру на Python, используя стиль ООП. Родительский класс настроен, и в нем есть два подкласса: один для героя и один для орка.
В основном, когда герой атакует орка (или наоборот) Я хочу, чтобы здоровье обновлялось в зависимости от нанесенного урона (урон — это количество энергии, которой обладает атакующий персонаж). В настоящее время каждый раз, когда он выполняет цикл, он сбрасывает значения работоспособности обратно к исходному значению 100.
Каков наилучший способ сделать это с помощью ООП? Я могу понять, как это сделать своим собственным процедурным и беспорядочным способом, но я хотел бы посмотреть, как это должно быть сделано.
class Character:
'''Blueprint for game characters'''
def __init__(self):
#default values
self.character = ""
self.speed = 0
self.power = 0
self.health = 100
def attack(self, attackObj):
self.attacker = self.character
self.attackerPower = self.power
self.victim = attackObj.character
self.victimHealth = attackObj.health
self.newHealth = self.victimHealth - self.attackerPower
print(self.character, "you have chosen to attack", self.victim)
print(self.victim, "you have suffered", self.attackerPower, "damage and your health is now", self.newHealth)
class Hero(Character):
'''Inherits from character to create hero'''
def __init__(self):
Character.__init__(self)
self.character = "Hero"
self.speed = 8
self.power = 9
print(self.character, "you have",self.speed, "speed,", self.power, "power and", self.health, "health.")
class Ork(Character):
'''Inherits from character to create ork'''
def __init__(self):
Character.__init__(self)
self.character = "Ork"
self.speed = 2
self.power = 8
print(self.character, "you have",self.speed, "speed,", self.power, "power and", self.health, "health.")
def main():
charclass = Character()
hero = Hero()
ork = Ork()
endLoop = False
while endLoop == False:
print("Please choose your character by typing the corresponding key: ")
print("H for hero")
print("O for ork")
charChoice = input()
if charChoice in ("H", "h", "hero", "Hero"):
charChoice = hero
enemy = ork
hero = Hero()
elif charChoice in ("O", "o", "ork", "Ork"):
charChoice = ork
enemy = hero
print("Please choose an action by typing the corresponding key: ")
print("A to attack")
actionChoice = input()
if actionChoice in ("A", "a"):
charChoice.attack(enemy)
else:
print("Nothing chosen!")
finishedYN = input("Have you finished? Y/N ")
if finishedYN in ("Y", "y", "Yes", "yes", "YES"):
print("You have chosen to end the game...")
endloop = True
break
else:
pass
if __name__ == "__main__":
main()
Комментарии:
1. Я не запускал ваш код, но похоже, что вы создаете новый
Hero
объект на каждой итерации цикла :hero = Hero()
.2. Кроме того, почему вы это делаете:
self.victimHealth = attackObj.health
? Вы просто добавляетеself
ко всему в своем классе?3. Я только что удалил эту строку (должно быть, это был пережиток прошлого), но это никак не влияет на остальную часть программы. Он по-прежнему просто возвращается к оригиналу. Мне нужен какой-то способ отправить свойство power злоумышленника жертве и вычесть это из работоспособности, а затем каким-то образом запомнить это на следующей итерации. Как я уже сказал, я мог бы сделать это грязным и процедурным способом, но хотел бы, чтобы кто-нибудь подсказал мне правильный способ ООП для этого.
4. Вы никогда не изменяете
health
атрибут, просто создаете новый вызываемый атрибутnewHealth
. Вы также никогда не влияете наattackObject
health
атрибут ‘s.5. Да, я только что добавил self ко всему. Эта строка должна была получить доступ к атрибуту мощности злоумышленника и вычесть его из состояния здоровья жертвы. Ранее у меня была строка кода, которая была примерно такой: newHealth = self.attackerPower — self.victimHealth затем я пытался получить к нему доступ и заставить его обновить соответствующий класс, но это просто не сработало. Я перепробовал много вариантов, прежде чем спрашивать здесь.
Ответ №1:
Быстрое исправление вашего кода. Удалите все эти ненужные атрибуты, например self.attacker
(это просто self
), self.attackPower
(это просто self.power
). self.victim = attackObj.character
просто дает вашему объекту новый атрибут, который является той же строкой, что и все, что attackObj.character
есть. Аналогично, это: self.newHealth = self.victimHealth - self.attackerPower
просто создает новый атрибут при каждом вызове метода, который всегда будет равен 100 — self.attack
def attack(self, attackObj):
attackObj.health -= self.power
print(self.character, "you have chosen to attack", attackObj.character)
print(attackObj.character, "you have suffered", self.power, "damage and your health is now", attackObj.health)
На самом деле, еще лучший способ — добавить методы, которые изменяют ваш объект, которые будут использоваться в качестве интерфейса с тем, как ваш объект взаимодействует с другими объектами. Так, например:
class Character:
'''Blueprint for game characters'''
def __init__(self):
#default values
self.character = ""
self.speed = 0
self.power = 0
self.health = 100
def attack(self, victim):
victim.receive_damage(self.power)
def receive_damage(raw_damage):
self.health -= raw_damage
Это улучшает расширяемость вашего кода. Вы могли бы более легко реализовать систему «баффов» или добавить элемент «брони», который влияет на то, как вы получаете урон, без необходимости изменять код attack
. Вы можете переопределить эти методы в подклассах. Итак, возможно, вы хотите, чтобы у всех орков была «толстая кожа», а в Ork
:
def receive_damage(raw_damage):
self.health -= raw_damage*self.thickskin_modifier
Где self.thickskin_modifier
было задано в Ork
классе __init__
. Это может быть что-то вроде 0.9.
Комментарии:
1. Хорошо, я посмотрю, поиграю и немного отвечу с окончательным рабочим кодом (надеюсь).
2. Эй, это работает! Спасибо за это. Я новичок в ООП, и я не могу выразить вам, как я благодарен за помощь.