Давненько возился с Pygame, и я хотел сделать 2D-игру, в которой у игрока есть доступ к щиту, который блокирует пули противника, только если они того же цвета, что и сам щит. Я застрял над этой проблемой уже несколько недель и надеялся, что кто-нибудь здесь сможет мне помочь, если это возможно. Это мой первый пост на этом сайте, поэтому извините, если он не самый лучший. Это сокращенная версия кода, расположенного ниже….
import pygame
import random
pygame.init()
win = pygame.display.set_mode((600, 600))
pygame.display.set_caption("First Game")
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')]
walkRight2 = [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('R6E.png'), pygame.image.load('R5E.png'), pygame.image.load('R4E.png')]
walkLeft2 = [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('L6E.png'), pygame.image.load('L5E.png'), pygame.image.load('L4E.png')]
bg = pygame.image.load('Bg_1.png').convert()
clock = pygame.time.Clock()
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.jumpcount = 10
self.left = False
self.right = False
self.walkcount = 0
self.standing = True
self.hitbox = (self.x + 20, self.y + 15, self.width - 40, self.height - 20)
self.right_shield = (self.x + 15, self.y, self.width - 35, self.height)
self.left_shield = (self.x + 17, self.y, self.width - 35, self.height)
self.lifes = 35
def draw(self, win):
if self.walkcount + 1 >= 27:
self.walkcount = 0
if not (self.standing):
if self.left == True:
win.blit(walkLeft[self.walkcount // 3], (self.x, self.y))
self.walkcount += 1
elif self.right == True:
win.blit(walkRight[self.walkcount // 3], (self.x, self.y))
self.walkcount += 1
else:
if self.right == True:
win.blit(walkRight[0], (self.x, self.y))
else:
win.blit(walkLeft[0], (self.x, self.y))
self.hitbox = (self.x + 20, self.y + 15, self.width - 40, self.height - 20)
self.right_shield = (self.x + 15, self.y, self.width - 35, self.height)
self.left_shield = (self.x + 17, self.y, self.width - 35, self.height)
def hit(self, win):
global run
global bad_guys_kiled
if self.lifes > 0:
self.lifes -= 1
if self.lifes % 2 == 0:
pass
if self.lifes <= 0:
run = False
print("You have ran out of lifes!")
print("Thank you for playing!")
class enemy(object):
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 5
self.boss_vel = 2
self.left = True
self.right = False
self.walkcount = 0
self.isjump = False
self.jumpcount = 10
self.standing = True
self.hitbox = (self.x + 20, self.y + 10, self.width - 40, self.height - 20)
self.shootloop1 = 0
self.bullets2 = []
self.bullets3 = []
self.lifes = 2
self.half_health = False
def draw(self, win):
global half_health
global bad_guys_kiled
if bad_guys_kiled <= 25:
if self.walkcount + 1 >= 27:
self.walkcount = 0
if not (self.standing):
if self.left == True:
win.blit(walkLeft2[self.walkcount // 3], (self.x, self.y))
self.walkcount += 1
elif self.right == True:
win.blit(walkRight2[self.walkcount // 3], (self.x, self.y))
self.walkcount += 1
else:
if self.right == True:
win.blit(walkRight2[0], (self.x, self.y))
else:
win.blit(walkRight2[0], (self.x, self.y))
self.hitbox = (self.x + 20, self.y + 10, self.width - 40, self.height - 20)
enemy_health = (self.x + 25, self.y + 5, self.width - 40, self.height - 70)
pygame.draw.rect(win, (0, 255, 0), enemy_health)
if self.half_health == True:
pygame.draw.rect(win, (255, 0, 0), (self.x + 50, self.y + 5, self.width - 75, self.height - 70))
def draw2(self, win):
global half_health
global bad_guys_kiled
if self.walkcount + 1 >= 27:
self.walkcount = 0
if not (self.standing):
if self.left == True:
win.blit(walkLeft2[self.walkcount // 3], (self.x, self.y))
self.walkcount += 1
elif self.right == True:
win.blit(walkRight2[self.walkcount // 3], (self.x, self.y))
self.walkcount += 1
else:
if self.right == True:
win.blit(walkRight2[0], (self.x, self.y))
else:
win.blit(walkRight2[0], (self.x, self.y))
self.hitbox = (self.x + 20, self.y + 10, self.width - 40, self.height - 20)
enemy_health = (self.x + 25, self.y + 5, self.width - 40, self.height - 70)
pygame.draw.rect(win, (0, 255, 0), enemy_health)
if self.half_health == True:
pygame.draw.rect(win, (255, 0, 0), (self.x + 50, self.y + 5, self.width - 75, self.height - 70))
def walk(self, win):
global shield
global drop_spot
global drop
global shield_health
global bad_guys_kiled
global temp_num
global temp_number
global colours
global shield_colour
global shield_number
global bullet_colour
global test_number
bullet_colour = random.choice(colours)
if bullet_colour == "blue":
colour_number = (0, 0, 255)
test_number = 0
else:
colour_number = (255, 0, 0)
test_number = 1
if temp_num == False:
temp_number = random.randint(4, 34)
temp_num = True
if self.shootloop1 > 0:
self.shootloop1 += 1
if self.shootloop1 > int(temp_number):
self.shootloop1 = 0
if bad_guys_kiled <= 25 and not (main_menu):
for bullet in self.bullets2:
if man.left:
if int(shield_number) == int(test_number):
if bullet.y - bullet.radius < man.right_shield[1] + man.right_shield[3] and bullet.y + bullet.radius > man.right_shield[1]:
if bullet.x + bullet.radius > man.right_shield[0] and bullet.x - bullet.radius < man.right_shield[0] + man.right_shield[2]:
try:
self.bullets2.pop(self.bullets2.index(bullet))
except ValueError:
pass
elif man.right:
if int(shield_number) == int(test_number):
if bullet.y - bullet.radius < man.left_shield[1] + man.left_shield[3] and bullet.y + bullet.radius > man.left_shield[1]:
if bullet.x + bullet.radius > man.left_shield[0] and bullet.x - bullet.radius < man.left_shield[0] + man.left_shield[2]:
try:
self.bullets2.pop(self.bullets2.index(bullet))
except ValueError:
pass
elif int(shield_number) != int(test_number):
if bullet.y - bullet.radius < man.hitbox[1] + man.hitbox[3] and bullet.y + bullet.radius > man.hitbox[1]:
if bullet.x + bullet.radius > man.hitbox[0] and bullet.x - bullet.radius < man.hitbox[0] + man.hitbox[2]:
man.hit(win)
try:
self.bullets2.pop(self.bullets2.index(bullet))
except ValueError:
pass
if bullet.x < 800 and bullet.x > -50:
bullet.x += bullet.vel
else:
try:
self.bullets2.pop(self.bullets2.index(bullet))
except ValueError:
pass
if self.left:
facing = -1
elif self.right:
facing = 1
if len(self.bullets2) < 7 and self.shootloop1 == 0:
self.bullets2.append(projectile(round(self.x + self.width // 2), round(self.y + self.height // 2), 6, (colour_number),facing))
self.shootloop1 = 1
if self.x != -50:
self.x -= self.vel
self.right = False
self.left = True
self.standing = False
else:
for x in range(1, 200):
if self.x >= 700:
self.x = 650
self.half_health = False
self.x += self.vel
self.right = False
self.left = True
self.standing = False
else:
for bullet in self.bullets2:
try:
self.bullets2.pop(self.bullets2.index(bullet))
except ValueError:
pass
def hit(self, win):
global bad_guys_kiled
global drop
global drop_spot
global drop_count
global min
global max
global score
Hit_noise.play()
if self.lifes > 0:
self.lifes -= 1
self.half_health = True
if self.lifes <= 0:
random_number = random.randint(min, max)
if bad_guys_kiled <= 25:
if random_number == 1:
if drop_count != 1:
drop = True
drop_count += 1
drop_spot = [self.x + 20]
drop_spot += [self.y + 10]
drop_spot += [self.width - 40]
drop_spot += [self.height - 40]
else:
try:
max -= 1
except ValueError:
max = 20
if bad_guys_kiled >= 25:
drop_spot = []
self.half_health = False
self.x = self.x + 700
self.lifes = 2
bad_guys_kiled += 1
score += 1
class projectile(object):
def __init__(self, x, y, radius, colour, facing):
self.x = x
self.y = y
self.radius = radius
self.colour = colour
self.facing = facing
self.vel = 8 * facing
def draw(self, win):
pygame.draw.circle(win, self.colour, (self.x, self.y), self.radius)
def redraw_game_window():
global drop_spot
global drop
global bad_guys_kiled
global jump_block
global main_menu
global run
global count
global score
global shield
global man_movement_block
global shield_colour
global bullet_colour
global test_number
global shield_number
win.blit(bg, (0, 0))
man.draw(win)
print("man = ",shield_number)
print("bullet =",test_number)
text_score = font.render("Score:" + str(score), 1, (0, 0, 0))
text_shield = font.render("Shield Colour:" + "temp", 1, (0, 0, 0))
text_player_health = font.render("Player Health:" + str(man.lifes), 1, (0, 0, 0))
win.blit(text_score, (450, 10))
win.blit(text_shield, (225, 10))
win.blit(text_player_health, (20, 10))
if bad_guys_kiled <= 25:
if drop == True:
try:
pygame.draw.rect(win, (0, 0, 255), (drop_spot[0], drop_spot[1], drop_spot[2], drop_spot[3]))
except IndexError:
pass
if man.left == True and shield_colour == "blue":
pygame.draw.rect(win, (0, 0, 255), (man.x + 17, man.y, man.width - 35, man.height), 2)
elif not(main_menu) and shield_colour == "blue":
pygame.draw.rect(win, (0, 0, 255), (man.x + 15, man.y, man.width - 35, man.height), 2)
if man.right == True and shield_colour == "red":
pygame.draw.rect(win, (255, 0, 0), (man.x + 17, man.y, man.width - 35, man.height), 2)
elif not(main_menu) and shield_colour == "red":
pygame.draw.rect(win, (255, 0, 0), (man.x + 15, man.y, man.width - 35, man.height), 2)
if bad_guys_kiled <= 25 :
bad_guy1.draw(win)
bad_guy2.draw(win)
bad_guy3.draw(win)
for bullet in bullets:
bullet.draw(win)
for bullet in bad_guy1.bullets2:
bullet.draw(win)
for bullet in bad_guy2.bullets2:
bullet.draw(win)
for bullet in bad_guy3.bullets2:
bullet.draw(win)
pygame.display.update()
def game_credits():
pygame.draw.rect(win, (40, 26, 13), (0, 0, 650, 650))
text_help = font.render("CONTROLS", 1, (0, 255, 0))
text_help1 = font.render("UP ARROW = JUMP", 1, (255, 255, 255))
text_help2 = font.render("LEFT ARROW = LEFT", 1, (255, 255, 255))
text_help3 = font.render("RIGHT ARROW = RIGHT", 1, (255, 255, 255))
text_help4 = font.render("ZERO ON NUMPAD = FIRE", 1, (255, 255, 255))
text_help5 = font.render("P = PAUSE", 1, (255, 255, 255))
text_help6 = font.render("O = UNPAUSE ", 1, (255, 255, 255))
text_help7 = font.render("(PRESSING P WILL NOT ", 1, (255, 255, 255))
text_help8 = font.render("UNPAUSE THE GAME !)", 1, (255, 255, 255))
text_help9 = font.render("B = SHIELD", 1, (255, 255, 255))
win.blit(text_help, (22, 50))
win.blit(text_help1, (22, 100))
win.blit(text_help2, (22, 150))
win.blit(text_help3, (22, 200))
win.blit(text_help4, (22, 250))
win.blit(text_help5, (22, 300))
win.blit(text_help6, (22, 350))
win.blit(text_help7, (22, 400))
win.blit(text_help8, (22, 450))
win.blit(text_help9, (22, 500))
# Main Loop #
Air_raid = pygame.mixer.Sound("Air raid.wav")
Godzilla_roar = pygame.mixer.Sound("Godzilla roar.wav")
Victory_noise = pygame.mixer.Sound("Victory noise.wav")
Gun_shot = pygame.mixer.Sound("Gun shot.wav")
Hit_noise = pygame.mixer.Sound("Hit noise.wav")
man = player(300, 450, 64, 64)
bad_guy1 = enemy(0, 450, 64, 64)
bad_guy2 = enemy(250, 450, 64, 64)
bad_guy3 = enemy(500, 450, 64, 64)
count = 0
bullets = []
shootloop = 0
bad_guys_kiled = 0
temp_num = False
temp_number = 0
drop = False
drop_spot = []
drop_count = 0
min = 1
max = 20
main_menu = False
main_spawn = False
score = 0
man_movement_block = False
shield_count = 0
colours = ["blue", "red"]
shield_colour = "blue"
bullet_colour = None
shield_number = 0
test_number = 0
font = pygame.font.SysFont("Calibri Light", 25, True)
run = True
while run == True:
temp_number = random.randint(4, 34)
if man.y >= 500:
man.y = 450
clock.tick(27)
shield = True
if shootloop > 0:
shootloop += 1
if shootloop > 5:
shootloop = 0
if shield_count > 0:
shield_count += 1
if shield_count > 5:
shield_count = 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
for bullet in bullets:
if bad_guys_kiled <= 25:
if bullet.y - bullet.radius < bad_guy1.hitbox[1] + bad_guy1.hitbox[3] and bullet.y + bullet.radius > bad_guy1.hitbox[1]:
if bullet.x + bullet.radius > bad_guy1.hitbox[0] and bullet.x - bullet.radius < bad_guy1.hitbox[0] + bad_guy1.hitbox[2]:
bad_guy1.hit(win)
bullets.pop(bullets.index(bullet))
if bullet.y - bullet.radius < bad_guy2.hitbox[1] + bad_guy2.hitbox[3] and bullet.y + bullet.radius > bad_guy2.hitbox[1]:
if bullet.x + bullet.radius > bad_guy2.hitbox[0] and bullet.x - bullet.radius < bad_guy2.hitbox[0] + bad_guy2.hitbox[2]:
bad_guy2.hit(win)
try:
bullets.pop(bullets.index(bullet))
except ValueError:
pass
if bullet.y - bullet.radius < bad_guy3.hitbox[1] + bad_guy3.hitbox[3] and bullet.y + bullet.radius > bad_guy3.hitbox[1]:
if bullet.x + bullet.radius > bad_guy3.hitbox[0] and bullet.x - bullet.radius < bad_guy3.hitbox[0] + bad_guy3.hitbox[2]:
bad_guy3.hit(win)
try:
bullets.pop(bullets.index(bullet))
except ValueError:
pass
try:
if man.hitbox[1] - (man.hitbox[3] / 2) < drop_spot[1] + (drop_spot[3] / 2) and man.hitbox[1] + (man.hitbox[3] / 2) > drop_spot[1]:
if man.hitbox[0] + (man.hitbox[3] / 2) > drop_spot[0] and man.hitbox[0] - (man.hitbox[3] / 2) < drop_spot[0] + drop_spot[2]:
Gun_shot.stop()
if man.lifes <= 35:
man.lifes += 10
else:
Gun_shot.stop()
pass
try:
bullets.pop(bullets.index(bullet))
drop = False
drop_count = 0
drop_spot = []
except ValueError:
pass
except:
pass
if bullet.x < 650 and bullet.x > -20:
bullet.x += bullet.vel
else:
try:
bullets.pop(bullets.index(bullet))
except ValueError:
pass
keys = pygame.key.get_pressed()
if keys[pygame.K_KP0] and not (main_menu):
if man.left:
facing = -1
elif man.right:
facing = 1
else:
facing = -1
if len(bullets) < 5 and shootloop == 0:
Gun_shot.play()
bullets.append(projectile(round(man.x + man.width // 2), round(man.y + man.height // 2), 6, (0, 0, 255), facing))
shootloop = 1
if keys[pygame.K_LEFT] and man.x > man.vel and not(man_movement_block):
man.x -= man.vel
man.left = True
man.right = False
man.standing = False
elif keys[pygame.K_RIGHT] and man.x < 620 - man.vel - man.width:
man.x += man.vel
man.right = True
man.left = False
man.standing = False
elif keys[pygame.K_b] and shield_count == 0:
if shield_colour == "blue":
shield_colour = "red"
shield_number = 1
else:
shield_colour = "blue"
shield_number = 0
shield_count = 1
if not (man.isjump):
if keys[pygame.K_UP]:
man.isjump = True
man.walkcount = 0
else:
if man.jumpcount >= -10:
neg = 1
if man.jumpcount < 0:
neg = -1
man.y -= (man.jumpcount ** 2) / 2 * neg
man.jumpcount -= 1
else:
man.isjump = False
man.jumpcount = 10
bad_guy1.walk(win)
bad_guy2.walk(win)
bad_guy3.walk(win)
redraw_game_window()
pygame.quit()