最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - I cannot find a way of resetting player positions once health is lower than or equal to 0 using OOP in pygame - Stack O

programmeradmin2浏览0评论

I am creating a 2 player same-screen game which uses both players playing on the same computer, both using the keyboard. I am struggling to find a way to code it in OOP so that once one of the player's health is below or equal to 0, both player positions are reset back to the starting position (standard x and y coordinate) and score being incremented by 1 for the player which was left standing. Instead, the players' health reaches 0 and the character disappears off screen but can still shoot, run, jump etc. I intend on this being an instantaneous change to the next round, with perhaps a second delay between the health reaching 0 and the next round starting. Here is the code relevant to my problem:

class Player: 
    def __init__(self, x, y, width, height, speed, images_right, images_left, idle_image):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.speed = speed
        self.left = False
        self.right = False
        self.jump_status = False
        self.jump_time = 10
        self.anim_num = 0
        self.images_right = images_right
        self.images_left = images_left
        self.idle_image = idle_image
        self.hitbox = (self.x + 17, self.y + 11, 29, 52)
        self.health = 10
        self.visible = True
        self.maxhealth = 10
        self.score = 0
        self.start = (x,y)
 
    def hit(self):
        if self.health > 0:
            self.health -= 1
        else:
            self.visible = False
        print('hit')

class ResettableSprite:
        def __init__(self, idle_image, x, y):
            self.idle_image = idle_image
            self.rect = self.image.get_rect()
            self.start_x = x
            self.start_y = y
            self.reset()

        def reset(self):
            self.rect.x = self.start_x
            self.rect.y = self.start_y
            self.health = Player.maxhealth

player1 = Player(200, 317, 64, 64, 10, walkRight, walkLeft, char)
player2 = Player(500, 285, 92, 85, 10, walkRight2, walkLeft2, dragon)

I have tried to create a 'ResettableSprite' class and then allow self.start coordinates to equal the original x coordinates used when loading in the players as soon as the program is run. However, this does not proivde an error message, but rather continues to allow both players' health to reach 0, allow their character to disappear off the screen, but still allowing them to run, jump and shoot as if they still had health remaining.

I am creating a 2 player same-screen game which uses both players playing on the same computer, both using the keyboard. I am struggling to find a way to code it in OOP so that once one of the player's health is below or equal to 0, both player positions are reset back to the starting position (standard x and y coordinate) and score being incremented by 1 for the player which was left standing. Instead, the players' health reaches 0 and the character disappears off screen but can still shoot, run, jump etc. I intend on this being an instantaneous change to the next round, with perhaps a second delay between the health reaching 0 and the next round starting. Here is the code relevant to my problem:

class Player: 
    def __init__(self, x, y, width, height, speed, images_right, images_left, idle_image):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.speed = speed
        self.left = False
        self.right = False
        self.jump_status = False
        self.jump_time = 10
        self.anim_num = 0
        self.images_right = images_right
        self.images_left = images_left
        self.idle_image = idle_image
        self.hitbox = (self.x + 17, self.y + 11, 29, 52)
        self.health = 10
        self.visible = True
        self.maxhealth = 10
        self.score = 0
        self.start = (x,y)
 
    def hit(self):
        if self.health > 0:
            self.health -= 1
        else:
            self.visible = False
        print('hit')

class ResettableSprite:
        def __init__(self, idle_image, x, y):
            self.idle_image = idle_image
            self.rect = self.image.get_rect()
            self.start_x = x
            self.start_y = y
            self.reset()

        def reset(self):
            self.rect.x = self.start_x
            self.rect.y = self.start_y
            self.health = Player.maxhealth

player1 = Player(200, 317, 64, 64, 10, walkRight, walkLeft, char)
player2 = Player(500, 285, 92, 85, 10, walkRight2, walkLeft2, dragon)

I have tried to create a 'ResettableSprite' class and then allow self.start coordinates to equal the original x coordinates used when loading in the players as soon as the program is run. However, this does not proivde an error message, but rather continues to allow both players' health to reach 0, allow their character to disappear off the screen, but still allowing them to run, jump and shoot as if they still had health remaining.

Share Improve this question edited Mar 11 at 5:41 Rabbid76 211k30 gold badges159 silver badges200 bronze badges asked Mar 10 at 19:18 user29961654user29961654 132 bronze badges 2
  • 2 What you need is a "game" object that owns both players. The "game" object can monitor the player states, and send "resets" if the need arises. You could even use callbacks, to have the player objects send a message to the game when health reached 0, but monitoring is probably OK. – Tim Roberts Commented Mar 10 at 19:22
  • Thanks, I will attempt this now @TimRoberts – user29961654 Commented Mar 10 at 19:28
Add a comment  | 

2 Answers 2

Reset to default -1

When a player's health reaches 0, you set visible = False but don't trigger a reset

What I think you can do in hit function is something like this:

    def hit(self):
        if self.health > 0:
            self.health -= 1
        else:
            self.visible = False
            if self == player1 and player2.health > 0:
                player2.score += 1
                self.reset()
                player2.reset()
            elif self == player2 and player1.health > 0:
                player1.score += 1
                self.reset()
                player1.reset()
        print('hit')

There's not the controlling code in the question, so this answer is based on what's presented, and is thus speaking in ignorance.

Based on what's provided, the Player object does not encapsulate all the operations on the Player data. I expect that later on in the code, the Player.x and Player.y (etc.) are modified without the control of the object. By this I mean, the main loop changes Player.x directly. Whereas this code should be part of the Player object, and updated indirectly. It's basically what you're doing in Player.hit() but for everything involving a Player object.

For example, moving the player:

class Player: 
    def __init__(self, x, y, width, height, speed, images_right, images_left, idle_image):
        self.x = x
        self.y = y
        self.width = width
        # [...]

    def move( self, dx, dy ):
        self.x += dx
        self.y += dy
        # TODO add screen constraints to movement

Not just for Player.move() but for all the player functions.

Once all this functionality is encapsulated, the Player object itself can decide what to do when "dead", and ignore handling of inputs:

class Player:
    # [...]
    def isAlive( self ):
        return ( self.health > 0 )

    def move( self, dx, dy ):
        if ( self.isAlive() ):
            self.x += dx
            self.y += dy
            # TODO add screen constraints to movement

    def fire( self ):
        if ( self.isAlive() ):
            # TODO create bullet

    def draw( self, screen ):
        if ( self.isAlive() ):
            screen.blit( self.image, self.rect )
        else:
            screen.blit( self.tombstone_image, self.rect )

The point of Object Oriented programming is to encapsulate the operations on the Object's data inside the object itself. So no-where except inside the object does the data get used or modified. The code doesn't draw( player1.image ) , it calls player1.draw( screen ), and then the Player object can look at its situation, and draw (or not) the appropriate image; accept or not-accept movement input, etc. etc.

This allows your main loop to test if ( player1.isAlive() and player2.isAlive() ) acting accordingly.

So to reset the health of the player, add a function for that:

    def setHealth( self, hp:10 ):
        self.health = hp

But maybe a "reset" would be better:

    def reset( self, x=Player.STARTX, y=Player.STARTY, hp=10 ):
        self.health = hp
        self.x = x
        self.y = y

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论