Pygame: Как перейти на отдельный уровень? - PullRequest
0 голосов
/ 22 апреля 2020

Итак, я делаю платформерную игру в Pygame. В настоящее время я немного застрял с переходом на следующий уровень. У меня уже есть готовый объект (и столкновение), поэтому, когда игрок ударяет по этому объекту, ожидаемый эффект - перейти на следующий уровень. Я использую списки для всех своих объектов, таких как враги, платформы, бонусы. Я также использую класс all sprites, поэтому все эти объекты хранятся там. Вот какой-то важный код (скажите, если вам нужно что-нибудь еще):

import pygame as pg

#Importing Settings
from settings import *
from Sprites import *


#Class Main Game
class Game:

    def __init__(self):
        # initialize game window, etc
        pg.init()
        pg.mixer.init()
        self.screen = pg.display.set_mode((screenWidth, screenLength))
        pg.display.set_caption("Wild West: Platformer Edition")
        self.clock = pg.time.Clock()
        self.running = True
        self.font_name = pg.font.match_font(font_name)

        #Anything that needs to be added to allsprites, or making groups
    def new(self):
        # start a new game
        self.health = 3
        self.score = 0
        self.start_time = pg.time.get_ticks()
        self.clock = pg.time.Clock()
        #Groups
        self.bullets = pg.sprite.Group()
        self.all_sprites = pg.sprite.Group()
        self.platforms = pg.sprite.Group()
        self.all_enemy = pg.sprite.Group()
        self.attacking = pg.sprite.Group()
        self.powerups = pg.sprite.Group()
        self.endings = pg.sprite.Group()
        #Adding stuff
        self.player = Player(self,self.bullets,self.attacking)
        self.projectile = bullet(self,(self.player.rect.x),(self.player.rect.y))
        self.attack = sword(self,self.player.rect.x, self.player.rect.y)
        self.all_sprites.add(self.player)
        #Ending Object
        self.end = end_level(400,-450)
        self.all_sprites.add(self.end)
        self.endings.add(self.end)
        self.level = 1
        self.platform_list = None
        self.load_level()

        #Enemies spawning
        for ene in enemy_list1:
            e = enemy(*ene)
            self.all_enemy.add(e)
            self.all_sprites.add(e)

        #Platforms spawning
        if self.level == 1
            for plat in self.platform_list1:
                p = Platform(*plat)
                self.all_sprites.add(p)
                self.platforms.add(p)


        #Power ups spawning
        for powerup in powerUpList1:
            pu = powerUp(*powerup)
            self.all_sprites.add(pu)
            self.powerups.add(pu)
        self.run()

    def run(self):
        # Game Loop
        self.playing = True
        while self.playing:
            self.clock.tick(FPS)
            self.events()
            self.update()
            self.draw()
            self.load_level()

    def load_level(self):
        if self.level == 1:
            self.platform_list = platform_list1
        if self.level == 2:
            self.platform_list = platform_list2

    def update(self):
        # Game Loop - Update
        # Collision
        self.all_sprites.update()
        if self.player.vel.y > 0:
            hits = pg.sprite.spritecollide(self.player, self.platforms, False)
            if hits:
                self.player.pos.y = hits[0].rect.top
                self.player.vel.y = 0

        # Bullet with Enemy
        EBhits = pg.sprite.groupcollide(self.all_enemy, self.bullets, True, True)
        #Sword with Enemy
        Ehits = pg.sprite.groupcollide(self.all_enemy,self.attacking, True, False)
        #Player with Powerups
        puHits = pg.sprite.spritecollide(self.player, self.powerups, True)
        #Player with Enemy
        pHits = pg.sprite.spritecollide(self.player,self.all_enemy, False, False)
        #Player with ending
        endingHits = pg.sprite.spritecollide(self.player,self.endings,False,False)

        #Ending the level
        if endingHits:
            self.all_sprites.empty()
            self.level = 2
            self.ammo = 3
            self.health = 3
            self.new()

        #Power up collision
        if puHits:
            self.player.ammo += 2
        #Sword with Enemy
        if Ehits:
            self.score += 150
        # Bullet with Enemy
        if EBhits:
            self.score += 100
            # Invincibility


        # Player with Enemy
        if pHits:
            self.player.invincin = True
            self.health -= 1

        # Scrolling Screen
        if self.player.rect.top <= screenLength / 4:
            self.player.pos.y += abs(self.player.vel.y)
            for ene in self.all_enemy:
                ene.rect.y += abs(self.player.vel.y)
            #Platform Scrolling
            for plat in self.platforms:
                plat.rect.y += abs(self.player.vel.y)
                if plat.rect.top >= screenLength:
                    plat.kill()

            self.projectile.rect.y += abs(self.player.vel.y)
            #Projectile scrolling
            for bull in self.bullets:
                bull.rect.y += abs(self.player.vel.y)
            #Powerup scrolling
            for powerup in self.powerups:
                powerup.rect.y += abs(self.player.vel.y)

            #End object scrolling
            for End in self.endings:
                End.rect.y += abs(self.player.vel.y)

        # Hitting bottom of the screen
        if self.player.rect.bottom > screenLength + 7:
            self.player.vel.y = -player_jump
            self.player.health -= 1
            self.health -= 1

        #Dying
        if self.health <= 0:
            self.playing = False

        #Time:
        self.timer = pg.time.get_ticks() - self.start_time
        # Loading Level
        self.load_level()

    def events(self):
        # Game Loop - events
        for event in pg.event.get():
            # check for closing window
            if event.type == pg.QUIT:
                if self.playing:
                    self.playing = False
                self.running = False
            #Shooting
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_j:
                    if self.projectile.rect.x < 800 and self.projectile.rect.x > 0:
                        now = pg.time.get_ticks()
                        if now - self.player.timer >= self.player.cooldown:
                            self.player.timer = now
                            self.player.shoot()
                    else:
                         self.projectile.kill()
                #Attacking
                if event.key == pg.K_h:
                    now1 = pg.time.get_ticks()
                    if now1 - self.attack.timer >= self.attack.cooldown:
                        self.attack.timer = now1
                        self.player.attack()
                # Jumping 
                if event.key == pg.K_w or event.key == pg.K_SPACE:
                    self.player.jump()

                # Pausing
                if event.key == pg.K_p:
                    self.pause_screen()

        self.load_level()



    def draw(self):
        # Game Loop - draw
        self.screen.blit(background, (0, 0))
        self.all_sprites.draw(self.screen)
        self.draw_text(str('Health:'),30,RED,50,15)
        self.draw_text(str(self.health),30,RED,110,15)
        self.draw_text(str('Ammo:'),30,BLUE,50,45)
        self.draw_text(str(self.player.ammo), 30, BLUE, 115, 45)
        self.draw_text(str(self.score),30,YELLOW,screenWidth / 2, 20)
        self.draw_text(str('Score:'), 30, YELLOW, 330,20)
        self.draw_text(str(self.timer / 1000),30, WHITE, 780,20)
        self.draw_text(str('Time:'),30,WHITE,670,20)
        self.load_level()


        # *after* drawing everything, flip the display
        pg.display.flip()

    def show_start_screen(self):
        #game splash/start screen
        waiting = True
        while waiting:
            self.clock.tick(FPS)
            for event in pg.event.get():
                if event.type == pg.QUIT:
                    waiting = False
                    self.running = False
                if event.type == pg.KEYDOWN:
                    if event.key == pg.K_h:
                        waiting = False
                    if event.key == pg.K_c:
                        self.control_screen()
                    if event.key == pg.K_q:
                        pg.quit()

            self.screen.blit(MMbackground,(0,0))
            self.draw_text('Wild West: Platformer Edition™',48 ,WHITE ,screenWidth/2 ,screenLength/6.5)
            self.draw_text('Jump across platforms, and Watch out for the bottom!', 30, WHITE, screenWidth/2,screenLength/2)
            self.draw_text('Kill enemies to get score', 30, WHITE, 400, 500)
            self.draw_text('Press H to play.Press C for controls',30 ,WHITE, screenWidth/2, screenLength * 3 / 4)
            pg.display.flip()

    def show_go_screen(self):
        # game over/continue
        if not self.running:
            return
        if death_animation == False:
            waiting = True
            while waiting:
                self.clock.tick(FPS)
                for event in pg.event.get():
                    if event.type == pg.QUIT:
                        waiting = False
                        self.running = False
                    if event.type == pg.KEYDOWN:
                        if event.key == pg.K_h:
                            waiting = False
                        if event.key == pg.K_q:
                            pg.quit()




                self.screen.fill(sandybrown)
                self.draw_text('GAME OVER', 48, WHITE, screenWidth / 2, screenLength / 4)
                self.draw_text('Press the H key to retry', 30, WHITE, screenWidth / 2, screenLength * 3 / 4)
                self.draw_text('Press Q to quit', 30, WHITE, 400, 650)
                pg.display.flip()

    def pause_screen(self):
        paused = True
        while paused:
            for event in pg.event.get():
                if event.type == pg.QUIT:
                    pg.quit()

                if event.type == pg.KEYDOWN:
                    if event.key == pg.K_p:
                        paused = False

                    elif event.key == pg.K_q:
                        pg.quit()

            self.screen.fill(WHITE)
            self.draw_text(str('PAUSED'),70,BLACK,400,200)
            self.draw_text(str('Press p to unpause'),50,BLACK,400,300)
            self.draw_text(str('Press q to quit game'),50,BLACK,400,400)
            pg.display.flip()
            self.clock.tick(5)

    def control_screen(self):
        control = True
        while control:
            for event in pg.event.get():
                if event.type == pg.QUIT:
                    pg.quit()
                if event.type == pg.KEYDOWN:
                    if event.key == pg.K_c:
                        control = False

                    if event.key == pg.K_q:
                        pg.quit()
            self.screen.fill(sandybrown)
            self.draw_text(str('CONTROLS'),70,BLACK,400,100)
            self.draw_text(str('A to move left, D to move right'),50,BLACK,400,200)
            self.draw_text(str('W or SPACE to jump'),50,BLACK, 400, 300)
            self.draw_text(str('H for melee attack, J for projectile attack'),40,BLACK,400,400)
            self.draw_text(str('P to pause the game'), 50, BLACK, 400, 500)
            self.draw_text(str('C to return to Main Menu'),40,BLACK, 400, 600)
            pg.display.flip()

    def draw_text(self,text,size,colour,x,y):
        font = pg.font.Font(self.font_name,size)
        text_surface = font.render(text, True, colour)
        text_rect = text_surface.get_rect()
        text_rect.midtop = (x,y)
        self.screen.blit(text_surface,text_rect)



g = Game()
g.show_start_screen()
while g.running:
    g.new()
    g.show_go_screen()

pg.quit()
```

Это мои классы

    # Sprite Classes
import pygame as pg
from settings import *

vec = pg.math.Vector2

class Player(pg.sprite.Sprite):
        def __init__(self, Game,bullet,sword):
            pg.sprite.Sprite.__init__(self)
            self.Game = Game
            self.image = pg.image.load('idle.png')
            self.rect = self.image.get_rect()
            self.rect.center = (screenWidth / 2, screenLength / 2)
            self.pos = vec(screenWidth / 2, screenLength / 2)
            self.vel = vec(0, 0)
            self.acc = vec(0,0)
            self.health = 3
            self.ammo = 3
            self.sword = sword
            self.cooldown = 700
            self.bullet = bullet
            self.timer = pg.time.get_ticks()
            self.itimer = pg.time.get_ticks()
            self.left = False
            self.right = False
            self.standing = True
            self.invincin = False
            self.invincinCoolDown= 1300

        def jump(self):
            # Jump only if standing on platforms
            self.rect.x += 1
            hits = pg.sprite.spritecollide(self,self.Game.platforms,False)
            self.rect.x -= 1
            if hits:
                self.vel.y = -player_jump

        def update(self):
            self.acc = vec(0,player_grav)
            keys = pg.key.get_pressed()
            #Moving and borders

            if keys[pg.K_a]:
                self.acc.x = -player_acc
                self.left = True
                self.right = False
                self.standing = False
            elif keys[pg.K_d]:
                self.acc.x = player_acc
                self.right = True
                self.left = False
                self.standing = False
            else:
                self.standing = True
             #Friction
            self.acc.x += self.vel.x * player_friction
            #Motion
            self.vel += self.acc
            self.pos += self.vel + 0.5 * self.acc
            self.rect.midbottom = self.pos
            #Borders
            if self.rect.x > 770:
                self.rect.x = 760
            if self.rect.x < -1:
                self.rect.x = 0
        def shoot(self):
            if self.ammo > 0:
                Bullet = bullet(self.Game,self.rect.x,self.rect.top)
                self.Game.all_sprites.add(Bullet)
                self.Game.bullets.add(Bullet)
                self.ammo -= 1

                if self.left:
                    Bullet.speed = 10 * -1
                if self.right:
                    Bullet.speed = 10

        def attack(self):
            if self.right:
                melee = sword(self, self.rect.x + 50, self.rect.top - 15)
                self.Game.all_sprites.add(melee)
                self.Game.attacking.add(melee)
            if self.left:
                melee = sword(self, self.rect.x - 50, self.rect.top - 15)
                self.Game.all_sprites.add(melee)
                self.Game.attacking.add(melee)

class bullet(pg.sprite.Sprite):
    def __init__(self, Game,x,y):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.image.load('magicBullet.png')
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.Game = Game
        self.Player = Player
        self.speed = 10

    def update(self):
        self.rect.x += self.speed

class sword(pg.sprite.Sprite):
    def __init__(self,Game,x,y):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.image.load('dagger.png')
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.Game = Game
        self.speed = 0.1
        self.cooldown = 75
        self.timer = pg.time.get_ticks()

    def update(self):
        self.rect.x += self.speed
        now = pg.time.get_ticks()
        if now - self.timer >= self.cooldown:
            self.kill()

class Platform(pg.sprite.Sprite):
     def __init__(self,x,y,w,h,colour):
         pg.sprite.Sprite.__init__(self)
         self.image = pg.Surface((w,h))
         self.image.fill(colour)
         self.rect = self.image.get_rect()
         self.rect.x = x
         self.rect.y = y

class enemy(pg.sprite.Sprite):
    def __init__(self,x,y,end,speed):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.image.load("enemy.png")
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.alive = True
        self.health = 3
        self.end = end
        self.speed = speed
        self.timer = pg.time.get_ticks()

    def update(self):
            self.rect.x += self.speed
            now = pg.time.get_ticks()
            if now - self.timer >= self.end:
               self.timer = now
               self.speed *= -1

class powerUp(pg.sprite.Sprite):
    def __init__(self,x,y):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.image.load('ammo.png')
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

class end_level(pg.sprite.Sprite):
    def __init__(self,x,y):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.image.load('Doors.png')
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

Это настройки и списки

    import pygame as pg
#Variables
screenWidth = 800
screenLength = 800
#Player Propertes
player_acc = 1
player_friction = -0.06
player_grav = 0.77
player_jump = 18
font_name = 'arial'
background = pg.image.load('Background.png')
MMbackground = pg.image.load('Main_Menu.png')
ending = pg.image.load('Doors.png')
death_animation = False




BROWN = (100,40,0)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
sandybrown = (244, 164, 96, 255)

FPS = 60


powerUpList1 = [(75,360)]

platform_list1 =  [(0,screenLength - 40,screenWidth, 40,BROWN),
                  (screenWidth/2 -50,screenLength * 3/4,100,20,GREEN),
                  (75,400, 250, 20,WHITE),
                  (325,200,150,31,BLUE),
                  (60,100,50,20,YELLOW),
                  (625,375,165,15,GREEN),
                  (230,-100,450,20,BROWN),
                  (400,-340,125,10,GREEN)]

enemy_list1 = [(200,-169,3000, 2)]

platform_list2 = [(400,200,300,300,BROWN)]




Platform is just what my class is, and platforms is the group.

    Also, the lists for objects aren't in the main game loop. And show_go_screen is just the game over screen. 
    Any help will be apreciated.

1 Ответ

1 голос
/ 22 апреля 2020

, используя platform_list в качестве примера

В классе Game может быть основной platform_list, затем для каждого уровня назначьте его в правильный список

class Game:

    def __init__(self):
        # initialize game window, etc
        self.platform_list = None
        self.level = 1
        self.Load_Level()

Есть метод, который изменяет список

def Load_Level(self):
    if self.level == 1:
        self.platform_list = platform_list1
        ...
    elif self.level == 2:
        self.platform_list = platform_list2
        ...

Или, чтобы он выглядел немного лучше, у вас могут быть платформы для всех уровней в одном списке

platform_list1 =  [(0,screenLength - 40,screenWidth, 40,BROWN),
                  (screenWidth/2 -50,screenLength * 3/4,100,20,GREEN),
                  (75,400, 250, 20,WHITE),
                  (325,200,150,31,BLUE),
                  (60,100,50,20,YELLOW),
                  (625,375,165,15,GREEN),
                  (230,-100,450,20,BROWN),
                  (400,-340,125,10,GREEN)]

platform_list2 = [(100,200,300,300,BROWN)]

all_platforms_list = [platform_list1, platform_list2...]



def Load_Level(self):
    self.platform_list = all_platforms_list[self.level]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...