Pygame: создать столкновение с игроком и платформой - PullRequest
0 голосов
/ 29 февраля 2020

У меня проблема с моим кодом. Итак, я хотел бы создать платформерскую игру в Pygame. Но я испытываю немало трудностей, создавая коллизию между игроком и платформой.

Я попытался упростить мне задачу, создав хитбоксы. Так что, когда игрок касается платформы, возвращается «хороший». Но я не могу заставить его создать код для того, что происходит, когда игрок переходит на платформу Hitbox. Я надеюсь, что кто-то может помочь мне с этим.

Это мой код:

import pygame
pygame.init()

#create the window and give the Game a name
window = pygame.display.set_mode((700, 480))
pygame.display.set_caption("Untitled Project")

walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'), pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'), pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]
walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'), pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'), pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]
bg = pygame.image.load('bg1.png')
char = pygame.image.load('standing.png')
platform1 = pygame.image.load('p1.png')



clock = pygame.time.Clock()

#Make everything an attribut in a class/ not global anymore
class player(object):
    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 5
        self.isJump = False
        self.left = False
        self.right = False
        self.walkCount = 0
        self.jumpCount = 10
        self.standing = True
        self.on_platform = False
        self.hitbox = (self.x + 17, self.y + 11, 29, 52) #x, y, width, height

#draw out character
    def draw(self, window):
        if self.walkCount + 1 >= 27:
            self.walkCount = 0

        if not(self.standing):
            if self.left:
                window.blit(walkLeft[self.walkCount // 3], (self.x, self.y))
                self.walkCount += 1
            elif self.right:
                window.blit(walkRight[self.walkCount // 3], (self.x, self.y))
                self.walkCount += 1
        else:
            if self.right:
                window.blit(walkRight[0], (self.x, self.y))
            else:
                window.blit(walkLeft[0], (self.x, self.y))
        self.hitbox = (self.x + 17, self.y + 11, 29, 52)
        pygame.draw.rect(window, (255,0,0), self.hitbox, 2)

class projectile(object):
    def __init__(self,x,y,radius,color,facing):
        self.x = x
        self.y = y
        self.radius = radius
        self.color = color
        self.facing = facing
        self.vel = 8 * facing

    def draw(self, window):
        pygame.draw.circle(window, self.color, (self.x, self.y), self.radius, 1)

class enemy(object):
    walkRight = [pygame.image.load('R1E.png'), pygame.image.load('R2E.png'), pygame.image.load('R3E.png'), pygame.image.load('R4E.png'), pygame.image.load('R5E.png'), pygame.image.load('R6E.png'), pygame.image.load('R7E.png'), pygame.image.load('R8E.png'), pygame.image.load('R9E.png'), pygame.image.load('R10E.png'), pygame.image.load('R11E.png')]
    walkLeft = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'), pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'), pygame.image.load('L7E.png'), pygame.image.load('L8E.png'), pygame.image.load('L9E.png'), pygame.image.load('L10E.png'), pygame.image.load('L11E.png')]

    def __init__(self, x, y, width, height, end):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.end = end
        self.path = (x, end)
        self.walkCount = 0
        self.vel = 3
        self.hitbox = (self.x + 17, self.y + 2, 31, 57)

    def draw(self, window):
        self.move()
        if self.walkCount + 1 >= 33:
            self.walkCount = 0

        if self.vel > 0:
            window.blit(self.walkRight[self.walkCount//3], (self.x, self.y)) #// 3 so we are not moving to fast
            self.walkCount += 1
        else:
            window.blit(self.walkLeft[self.walkCount//3], (self.x, self.y))
            self.walkCount += 1
        self.hitbox = (self.x + 17, self.y + 2, 31, 57)
        pygame.draw.rect(window, (255, 0, 0), self.hitbox, 2)


    def move(self):
        if self.vel > 0:
            if self.x < self.path[1] + self.vel:
                self.x += self.vel
            else:
                self.vel = self.vel * -1
                self.x += self.vel
                self.walkCount = 0
        else:
            if self.x > self.path[0] - self.vel:
                self.x += self.vel
            else:
                self.vel = self.vel * -1
                self.x += self.vel
                self.walkCount = 0

    def hit(self):
        print('Nice Shot!')
        pass


class platform(object):
    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 0
        self.hitbox = (self.x, self.y + 23, 130 , 70)

    def draw(self, window):
        window.blit(platform1, (self.x, self.y))
        pygame.draw.rect(window, (255, 0, 0), self.hitbox, 2)


def redrawGameWindow(): #display it on the window
    window.blit(bg, (0,0))
    man.draw(window)
    goblin.draw(window)
    p1.draw(window)
    for bullet in bullets:
        bullet.draw(window)
    pygame.display.update()


#MainLoop
man = player(200, 410, 64, 64)
goblin = enemy(100, 410, 64, 64, 350)
shootLoop = 0
p1 = platform(150, 280, 60, 20)
bullets = []
run = True
while run:
    clock.tick(27)

    if shootLoop > 0:
        shootLoop += 1
    if shootLoop > 3:
        shootLoop = 0

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    for bullet in bullets:
        if bullet.y - bullet.radius < goblin.hitbox[1] + goblin.hitbox[3] and bullet.y + bullet.radius > goblin.hitbox[1]:
            if bullet.x + bullet.radius > goblin.hitbox[0] and bullet.x - bullet.radius < goblin.hitbox[0] + goblin.hitbox[2]:
                goblin.hit()
                bullets.pop(bullets.index(bullet))

        if bullet.x < 700 and bullet.x > 0: #not off the screen with our bullets
            bullet.x += bullet.vel #bullet will move in the direction we wet it to go
        else:
            bullets.pop(bullets.index(bullet))

    keys = pygame.key.get_pressed()

    if keys[pygame.K_SPACE] and shootLoop == 0:
        if man.left:
            facing = -1
        else:
            facing = 1

        if len(bullets) < 5:
            bullets.append(projectile(round(man.x + man.width //2), round(man.y + man.height // 2), 6, (234, 137, 154), facing)) #bullet is coming from the middle of the man

        shootLoop = 1

    if keys[pygame.K_LEFT] and man.x > man.vel:
        man.x -= man.vel
        man.left = True
        man.right = False
        man.standing = False

    elif keys[pygame.K_RIGHT] and man.x < 700 - man.width - man.vel:
        man.x += man.vel
        man.right = True
        man.left = False
        man.standing = False
    else:
        man.standing = True #is he looking right or looking left
        man.walkCount = 0

    if man.hitbox[1] < p1.hitbox[1] and man.hitbox[0] > p1.hitbox[0] and man.hitbox[0] < p1.hitbox[0]+ p1.hitbox[2]:
        man.on_platform = True
        print('nice')

    if not (man.isJump):
        if keys[pygame.K_UP]:
            man.isJump = True
            man.right = False
            man.left = False
            man.walkCount = 0
    else:
        if man.jumpCount >= -10:
           if not(man.on_platform):
                neg = 1
                if man.jumpCount < 0:
                    neg = -1
                man.y -= (man.jumpCount ** 2) * 0.5 * neg
                man.jumpCount -= 1
           else:
               neg = 1
               if man.jumpCount < 0:
                   neg = -1
               if man.hitbox[1] < p1.hitbox[1]:
                   man.y -= (man.jumpCount ** 2) * 0.5 * neg
               elif man.hitbox[1] == p1.hitbox[1]:
                   man.isJump = False
                   man.jumpCount = 10
               man.jumpCount -= 1
        else:
            man.isJump = False
            man.jumpCount = 10

    redrawGameWindow()


pygame.quit()

if __name__ == "__main__":
    main()
...