Итак, я делаю платформерную игру в 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.