How do I collide and reduce player health in pygam

2019-07-24 18:51发布

问题:

I am coding a 2D game in python with the modules pygame and random, and I am having some problems with the code. One problem, is that neither of the players are taking any damage, which should be 10 damage for every bullet that hits out of 100 health for each of the players(The bullets and the players are sprites). The second problem, is that instead of a stabbed function, I want a way for the two players to collide, and not overlap each other, maybe using pygame.sprite.collide_rect(), so if you can help with this problem I can get rid of the stabbed function and can leave out the third problem.The third problem, is my stabbed function is repeating "Player 1 wins" and "Player 2 wins," when the two players touch each other. Thank You!`

import OpenGL
import panda3d
import pygame
import pyglet
import tkinter
import time
import random

pygame.init()
display_width = 1200
display_height = 600

green = (0, 255, 0)
yellow = (255, 255, 0)
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
blue = (0, 0, 255)

person_height = 113
person_width = 150
person2_width = 150
person2_height = 113


gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('Wert')
clock = pygame.time.Clock()

personImg = pygame.image.load('Untitled.png').convert_alpha()
personImg2 = pygame.image.load('Untitled2.png').convert_alpha()
bulletImg = pygame.image.load('Untitled1.png').convert_alpha()

player_health = 100
player2_health = 100
x = (0)
y = (display_height * 0.37)
ny = (display_height * 0.37)
nx = (display_width * 0.87)
#ny1 = (display_height * 0.87)
#thing_startx = display_width/2
#thing_starty = display_height/2
#thing_width = 100
#thing_height = 100





class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = personImg
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.player_health = 100
        self.x_change = 0
        self.y_change = 0


    def update(self):
        self.x_change = 0
        self.y_change = 0
        keystate = pygame.key.get_pressed()
        if keystate[pygame.K_w]:
            self.y_change = -5
        if keystate[pygame.K_s]:
            self.y_change = 5
        if keystate[pygame.K_d] and pygame.key.get_mods() and pygame.KMOD_LSHIFT:
            self.x_change = 10
        elif keystate[pygame.K_d]:
            self.x_change = 5
        if keystate[pygame.K_a]:
            self.x_change = -5
        self.rect.x += self.x_change
        self.rect.y +=self.y_change
        if self.rect.right > display_width:
            self.rect.right = display_width
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.top < 0:
            self.rect.top = 0
        if self.rect.bottom > display_height:
            self.rect.bottom = display_height

    def shoot(self):
        bullet = Bullet1(self.rect.x, self.rect.y)
        all_sprites.add(bullet)
        bullets.add(bullet)





class Player2(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = personImg2
        self.rect = self.image.get_rect()
        self.rect.x = nx
        self.rect.y = ny
        self.player2_health = 100
        self.x_change1 = 0
        self.y_change1 = 0

    def update(self):
        self.x_change1 = 0
        self.y_change1 = 0
        keystate = pygame.key.get_pressed()
        if keystate[pygame.K_UP]:
            self.y_change1 = -5
        if keystate[pygame.K_DOWN]:
            self.y_change1 = 5
        if keystate[pygame.K_LEFT] and pygame.key.get_mods() and pygame.KMOD_RSHIFT:
            self.x_change1 = -10
        elif keystate[pygame.K_LEFT]:
            self.x_change1 = -5
        if keystate[pygame.K_RIGHT]:
            self.x_change1 = 5
        self.rect.x += self.x_change1
        self.rect.y += self.y_change1
        if self.rect.right > display_width:
            self.rect.right = display_width
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.top < 0:
            self.rect.top = 0
        if self.rect.bottom > display_height:
            self.rect.bottom = display_height

    def shoot(self):
        bullet = Bullet(self.rect.x, self.rect.y)
        all_sprites.add(bullet)
        bullets1.add(bullet)



all_sprites = pygame.sprite.Group()
player = Player()
player2 = Player2()
bullets = pygame.sprite.Group()
bullets1 = pygame.sprite.Group()


class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((20, 10))
        self.mask = pygame.mask.from_surface(gameDisplay)
        self.image.fill(black)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.x_change = -10


    def update(self):
        self.rect.x += self.x_change
        if self.rect.bottom > display_width:
            self.kill()
        if self.rect.bottom < 0:
            self.kill()

class Bullet1(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((20, 10))
        self.mask = pygame.mask.from_surface(gameDisplay)
        self.image.fill(black)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.x_change1 = 10

    def update(self):
        self.rect.x += self.x_change1
        if self.rect.bottom > display_width:
            self.kill()
        if self.rect.bottom < 0:
            self.kill()


bullets = pygame.sprite.Group()
players1 = pygame.sprite.Group()
players2 = pygame.sprite.Group()
bullet1 = Bullet1(x, y)
players1.add(player)
players2.add(player2)
bullet = Bullet(x, y)
all_sprites.add(bullet1)
all_sprites.add(bullet)
all_sprites.add(player)
all_sprites.add(player2)


def person(x, y):
    gameDisplay.blit(personImg, (x, y))



def person2(nx,ny):
    gameDisplay.blit(personImg2, (nx, ny))


#def boundary():
    #if x > thing_startx and x < thing_startx + thing_width or x + person_width > thing_startx and x + person_width < thing_startx + thing_width:
    #if x > display_width - person_width or x < 0:

def button(msg,x,y,w,h,ic,ac,action=None):
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    if x+w > mouse[0] > x and y+h > mouse[1] > y:
        pygame.draw.rect(gameDisplay, ac,(x,y,w,h))

        if click[0] == 1 and action != None:
            action()
    else:
        pygame.draw.rect(gameDisplay, ic,(x,y,w,h))

    smallText = pygame.font.SysFont("timesnewromanms",20)
    textSurf, textRect = text_objects(msg, smallText)
    textRect.center = ( (x+(w/2)), (y+(h/2)) )
    gameDisplay.blit(textSurf, textRect)

def died():

    GameOver = True

    while GameOver:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        gameDisplay.fill(white)
        largeText = pygame.font.SysFont("timesnewromanms", 115)
        TextSurf, TextRect = text_objects("Player 2 wins", largeText)
        TextRect.center = ((display_width / 2), (display_height / 2))
        gameDisplay.blit(TextSurf, TextRect)

        button("Play Again", 450, 450, 100, 50, blue, blue, game_loop)
        button("Quit", 650, 450, 100, 50, red, red, quitgame)

        pygame.display.update()
        clock.tick(15)

def died1():


    GameOver = True

    while GameOver:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        gameDisplay.fill(white)
        largeText = pygame.font.SysFont("timesnewromanms", 115)
        TextSurf, TextRect = text_objects("Player 1 wins", largeText)
        TextRect.center = ((display_width / 2), (display_height / 2))
        gameDisplay.blit(TextSurf, TextRect)

        button("Play Again", 450, 450, 100, 50, blue, blue, game_loop)
        button("Quit", 650, 450, 100, 50, red, red, quitgame)

        pygame.display.update()
        clock.tick(15)



def health_bars(player_health, player2_health):

    if player_health > 75:
        player_health_color = green
    elif player_health > 50:
        player_health_color = yellow
    else:
        player_health_color = red
    if player2_health > 75:
        player2_health_color = green
    elif player2_health > 50:
        player2_health_color = yellow
    else:
        player2_health_color = red
    pygame.draw.rect(gameDisplay, player_health_color, (1080, 25, player2_health, 25))
    pygame.draw.rect(gameDisplay, player2_health_color, (20, 25, player_health, 25))





def redrawgame():
    player.rect.x = x
    player.rect.y = y
    player2.rect.x = nx
    player2.rect.y = ny

def stabbed ():
    stabbed = True
    a = ["Player 1 wins", "Player 2 wins"]
    b = []

    while stabbed:
        for event in pygame.event.get():
            a = ["Player 1 wins", "Player 2 wins"]
            b = []
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        if player_health > player2_health:
            b.clear()
            b.insert(0, "Player 1 wins")
        elif player2_health > player_health:
            b.clear()
            b.insert(0, "Player 2 wins")
        elif player_health == player2_health:
            b.clear()
            b.insert(0, random.choice(a))
            redrawgame()
        gameDisplay.fill(white)
        redrawgame()
        largeText = pygame.font.SysFont("timesnewromanms", 115)
        TextSurf, TextRect = text_objects(b[0], largeText)
        TextRect.center = ((display_width / 2), (display_height / 2))
        gameDisplay.blit(TextSurf, TextRect)

        button("Play Again", 450, 450, 100, 50, blue, blue, game_loop)
        button("Quit", 650, 450, 100, 50, red, red, quitgame)


        pygame.display.update()
        clock.tick(15)
def game_intro():
    intro = True

    while intro:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        gameDisplay.fill(white)
        largeText = pygame.font.SysFont("timesnewromanms", 115)
        TextSurf, TextRect = text_objects("Wert", largeText)
        TextRect.center = ((display_width / 2), (display_height / 2))
        gameDisplay.blit(TextSurf, TextRect)

        button("Play", 450, 450, 100, 50, blue, blue, game_loop)
        button("Quit", 650, 450, 100, 50, red, red, quitgame)

        pygame.display.update()
        clock.tick(15)
def quitgame():
    pygame.quit()
    quit()
def text_objects(text, font):
    textSurface = font.render(text, True, black)
    return textSurface, textSurface.get_rect()


def paused():
    largeText = pygame.font.SysFont("timesnewromanms", 115)
    TextSurf, TextRect = text_objects("Paused", largeText)
    TextRect.center = ((display_width / 2), (display_height / 2))
    gameDisplay.blit(TextSurf, TextRect)

    pause = True
    while pause:
        for event in pygame.event.get():

            if event.type == pygame.QUIT:
                pygame.quit()
                quit()



        button("Continue", 450, 450, 100, 50, blue, blue, game_loop)
        button("Quit", 650, 450, 100, 50, red, red, quitgame)

        pygame.display.update()
        clock.tick(15)





def game_loop():
    x = (0)
    y = (display_height * 0.37)
    ny = (display_height * 0.37)
    nx = (display_width * 0.87)
    y_change = 0
    x_change = 0
    x_change1 = 0
    y_change1 = 0
    #thing_startx = display_width/2
    #thing_starty = display_height/2

    gameExit = False

    while not gameExit:

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    quit()
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        player.shoot()
                if event.type == pygame.MOUSEBUTTONDOWN:
                    player2.shoot()
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_p:
                        paused()



            y += y_change
            x += x_change
            ny += y_change1
            nx += x_change1


            player_health = 100
            player2_health = 100
            gameDisplay.fill(white)
            #pygame.draw.rect(gameDisplay, black, (thing_startx, thing_starty, thing_width, thing_height))

            player
            player2


            #if x > thing_startx and x < thing_startx + thing_width or x + person_width > thing_startx and x + person_width < thing_startx + thing_width:
                #hit()

            #if thing_starty > display_height:
                #thing_starty = 0 - thing_height
                #thing_startx = random.randrange(0, display_width)

            if pygame.sprite.collide_rect(player, player2):
                stabbed()


            player_health = 100
            player2_health = 100

            if pygame.sprite.collide_rect(bullet, player):
                bullet1.kill()
                player_health -= 10
                #return player_health
            if player_health == 0:
                died()


            if pygame.sprite.collide_rect(bullet1, player2):
                bullet.kill()
                player2_health -= 10
                #return player2_health
            if player2_health == 0:
                died1()



            #print(player_health)
            #print(player2_health)

            all_sprites.update()

            health_bars(player_health, player2_health)
            all_sprites.draw(gameDisplay)
            pygame.display.flip()

            pygame.display.update()
            clock.tick(60)


game_intro()
game_loop()
pygame.quit()
quit()

回答1:

The health of the players is rapidly initialized by 100, inside the game loop. Initialize the health of the players once before the loop. Clear the groups of bullets, this is important when the game is restarted:

player_health = 100
player2_health = 100

for bullet in bullets:
    bullet.kill()
for bullet in bullets1:
    bullet.kill()

while not gameExit:

    # [...]

Check if the bullets in container bullets1 hit player and check if the bullets in container bullets hit player2:

for bullet in bullets1:
    if pygame.sprite.collide_rect(bullet, player):
        bullet.kill()
        player_health -= 10
        break
if player_health == 0:
    died()

for bullet in bullets:
    if pygame.sprite.collide_rect(bullet, player2):
        bullet.kill()
        player2_health -= 10
        break
if player2_health == 0:
    died1()

Skip adding a single standalone bullet to the all_sprites group:

all_sprites.add(bullet1)
all_sprites.add(bullet)


The bar colors of the 2 players ar confused:

pygame.draw.rect(gameDisplay, player_health_color, (1080, 25, player_health, 25))
pygame.draw.rect(gameDisplay, player2_health_color, (20, 25, player2_health, 25))
pygame.draw.rect(gameDisplay, player2_health_color, (1080, 25, player2_health, 25))
pygame.draw.rect(gameDisplay, player_health_color, (20, 25, player_health, 25))


There is an issue in the update methods of the classes Bullet and Bullet2. You have to test self.rect.left respectively self.rect.right, instead of self.rect.bottom:

def update(self):
    self.rect.x += self.x_change
    if self.rect.left > display_width: # self.rect.left instead of self.rect.bottom
        self.kill()
    if self.rect.right < 0:            # self.rect.right instead of self.rect.bottom
        self.kill()


标签: python pygame