玩家升级时遇到新敌人的问题

时间:2020-08-09 14:42:27

标签: pygame

我正在为大学项目开发​​一个简单的“太空侵略者”克隆。这个想法是,当玩家升级时,敌人的数量会增加,但是当我尝试这样做时,当稳定条件为真时,敌人会无限创造。我无法解决这个问题,所以如果你们中的一个可以帮助我,我会很感激的。

import random
import csv
import operator

import pygame
import time
from pygame import mixer

# Intialize the pygame
pygame.init()

# create the screen
screen = pygame.display.set_mode((800, 600))

# Background
background = pygame.image.load('background.png')

# Sound
mixer.music.load("background.wav")
mixer.music.play(-1)

#Reloj
clock = pygame.time.Clock()

# Caption and Icon
pygame.display.set_caption("Space Invader")
icon = pygame.image.load('ufo.png')
pygame.display.set_icon(icon)



# Score
score_value = 0
level_value = 1
level_up_value = ""
font = pygame.font.Font('freesansbold.ttf', 20)
game_over = False

high_scores = []
names = []


with open('high_scores.csv') as csvfile:
    reader = csv.reader(csvfile)
    sortedlist = sorted(reader, key=operator.itemgetter(1), reverse=True)
    for i in sortedlist:
        names.append(i[0])
        high_scores.append(i[1])



scoreX = 10
scoreY = 10
level_textX = 10
level_textY = 80
levelX = 10
levelY = 40



# Game Over
over_font = pygame.font.Font('freesansbold.ttf', 64)
menu_font = pygame.font.Font('freesansbold.ttf', 48)
scores_font = pygame.font.Font('freesansbold.ttf', 45)




#Número de vidas
num_vidas = 3
font = pygame.font.Font('freesansbold.ttf', 32)

vidasX = 650
vidasY = 10



# Player
playerImg = pygame.image.load('player.png')
playerX = 370
playerY = 480
playerX_change = 0




# Enemy
enemyImg = []
bichoImg = []
meteoroImg = []

enemyX = []
enemyY = []
enemyY_change = []

bichoX = []
bichoY = []
bichoY_change = []

meteoroX = []
meteoroY = []
meteoroY_change = []


num_of_enemies_10 = 5
num_of_enemies_20 = 4
num_of_enemies_30 = 3


for i in range(num_of_enemies_10):
    enemyImg.append(pygame.image.load('enemy.png'))
    enemyX.append(random.randint(0, 736))
    enemyY.append(random.randint(50, 150))
    enemyY_change.append(0.5)

for i in range(num_of_enemies_20):
    bichoImg.append(pygame.image.load('bicho.png'))
    bichoX.append(random.randint(0, 736))
    bichoY.append(random.randint(10, 120))
    bichoY_change.append(0.5)

for i in range(num_of_enemies_30):
    meteoroImg.append(pygame.image.load('meteoro.png'))
    meteoroX.append(random.randint(0, 736))
    meteoroY.append(random.randint(0, 150))
    meteoroY_change.append(0.5)
    



# Bullet

# Ready - You can't see the bullet on the screen
# Fire - The bullet is currently moving

bulletImg = pygame.image.load('bullet.png')
bulletX = 0
bulletY = 480
bulletX_change = 0
bulletY_change = 10
bullet_state = "ready"






def show_score(x, y):
    score = font.render("Score : " + str(score_value), True, (255, 255, 255))
    screen.blit(score, (x, y))



def show_level(x, y):
    level = font.render("Level: " + str(level_value), True, (255, 255, 255))
    screen.blit(level, (x, y))

def level_up_text(x, y):
    level_text = font.render(level_up_value, True,  (255, 255, 0))
    screen.blit(level_text, (level_textX, level_textY))

def show_vidas(x, y):
    vidas = font.render("Vidas : " + str(num_vidas), True, (255, 255, 255))
    screen.blit(vidas, (x, y))




def game_over_text():
    over_text = over_font.render("GAME OVER", True, (255, 255, 255))
    screen.blit(over_text, (200, 250))

def player(x, y):
    screen.blit(playerImg, (x, y))




def enemy(x, y, i):
    screen.blit(enemyImg[i], (x, y))

def bicho(x, y, i):
    screen.blit(bichoImg[i], (x, y))

def meteoro(x, y, i):
    screen.blit(meteoroImg[i], (x, y))




def fire_bullet(x, y):
    global bullet_state
    bullet_state = "fire"
    screen.blit(bulletImg, (x + 16, y + 10))




#Colisiones para cada tipo de enemigo
def isCollision1(enemyX, enemyY, bulletX, bulletY):
    distance = math.sqrt(math.pow(enemyX - bulletX, 2) + (math.pow(enemyY - bulletY, 2)))
    if distance < 27:
        return True
    else:
        return False

def isCollision2(bichoX, bichoY, bulletX, bulletY):
    distance = math.sqrt(math.pow(bichoX - bulletX, 2) + (math.pow(bichoY - bulletY, 2)))
    if distance < 27:
        return True
    else:
        return False

def isCollision3(meteoroX, meteoroY, bulletX, bulletY):
    distance = math.sqrt(math.pow(meteoroX - bulletX, 2) + (math.pow(meteoroY - bulletY, 2)))
    if distance < 27:
        return True
    else:
        return False




# Pause Loop

def show_pause():
    paused = True
    while paused:
        # RGB = Red, Green, Blue
        screen.fill((0, 0, 0))
        # Background Image
        screen.blit(background, (0, 0))
        pause_title = menu_font.render("PAUSED", True,  (255, 255, 0))
        pauseRect = pause_title.get_rect()
        pauseRect.centerx = screen.get_rect().centerx
        pauseRect.centery = screen.get_rect().centery - 50
        screen.blit(pause_title, pauseRect)

        high_title = menu_font.render("HIGH SCORES", True,  (255, 255, 255))
        highRect = high_title.get_rect()
        highRect.centerx = screen.get_rect().centerx
        highRect.centery = screen.get_rect().centery + 50
        screen.blit(high_title, highRect)

        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    paused = False
                    break
            if event.type == pygame.MOUSEBUTTONDOWN:
                mpos = pygame.mouse.get_pos()
                
                if highRect.collidepoint(mpos):
                    show_high_scores_menu()
                    break

        pygame.display.update()

        

# High Scores Loop

def show_high_scores_menu():
    high_scores_menu = True
    global high_scores, names
    high_scores.clear()
    names.clear()
    with open('high_scores.csv') as csvfile:
        reader = csv.reader(csvfile)
        sortedlist = sorted(reader, key=operator.itemgetter(1), reverse=True)
        for i in sortedlist:
            names.append(i[0])
            high_scores.append(i[1])

    while high_scores_menu:
        # RGB = Red, Green, Blue
        screen.fill((0, 0, 0))
        # Background Image
        screen.blit(background, (0, 0))
        high_title = menu_font.render("HIGH SCORES", True,  (255, 255, 0))
        highRect = high_title.get_rect()
        highRect.centerx = screen.get_rect().centerx
        highRect.centery = 100
        screen.blit(high_title, highRect)

        score1 = scores_font.render(names[0] + " : " + str(high_scores[0]), True, (255, 255, 255))
        score1Rect = score1.get_rect()
        score1Rect.centerx = screen.get_rect().centerx
        score1Rect.centery = 250
        screen.blit(score1, score1Rect)
        score2 = scores_font.render(names[1] + " : " + str(high_scores[1]), True, (255, 255, 255))
        score2Rect = score1.get_rect()
        score2Rect.centerx = screen.get_rect().centerx
        score2Rect.centery = 300
        screen.blit(score2, score2Rect)
        score3 = scores_font.render(names[2] + " : " + str(high_scores[2]), True, (255, 255, 255))
        score3Rect = score3.get_rect()
        score3Rect.centerx = screen.get_rect().centerx
        score3Rect.centery = 350
        screen.blit(score3, score3Rect)
        score4 = scores_font.render(names[3] + " : " + str(high_scores[3]), True, (255, 255, 255))
        score4Rect = score4.get_rect()
        score4Rect.centerx = screen.get_rect().centerx
        score4Rect.centery = 400
        screen.blit(score4, score4Rect)
        score5 = scores_font.render(names[4] + " : " + str(high_scores[4]), True, (255, 255, 255))
        score5Rect = score1.get_rect()
        score5Rect.centerx = screen.get_rect().centerx
        score5Rect.centery = 450
        screen.blit(score5, score5Rect)

        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    high_scores_menu = False
                    show_pause()
                    break

        pygame.display.update()



def save_high_scores():
    # RGB = Red, Green, Blue
    screen.fill((0, 0, 0))
    # Background Image
    screen.blit(background, (0, 0))

    name = ""
    while len(name) < 3:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.unicode.isalpha():
                    name += event.unicode
                elif event.key == pygame.K_BACKSPACE:
                    name = name[:-1]
            
        name = name.upper()
        screen.fill((0, 0, 0))
        screen.blit(background, (0, 0))
        high_title = menu_font.render("High Score!", True,  (255, 255, 0))
        highRect = high_title.get_rect()
        highRect.centerx = screen.get_rect().centerx
        highRect.centery = 100
        screen.blit(high_title, highRect)
        
        inpt = font.render("Enter a 3-letter name", True,  (255, 255, 255))
        inptRect = inpt.get_rect()
        inptRect.centerx = screen.get_rect().centerx
        inptRect.centery = 200
        screen.blit(inpt, inptRect)
        namedisplay = menu_font.render(name, True, (255, 255, 255))
        namedisplayRect = namedisplay.get_rect()
        namedisplayRect.center = screen.get_rect().center
        screen.blit(namedisplay, namedisplayRect)
        pygame.display.update()

    #replace lowest 
    lowest = high_scores[0]
    lowest_index = 0
    for i in range(len(high_scores)):
        if high_scores[i] <= lowest:
            lowest = high_scores[i]
            lowest_index = i
    high_scores[lowest_index] = score_value
    names[lowest_index] = name

    with open('high_scores.csv', 'w',newline='') as csvfile:
            writer = csv.writer(csvfile)
            for i in range(len(names)):
                writer.writerow([str(names[i]), str(high_scores[i])])

    show_high_scores_menu()





BLACK = (0, 0, 0)

#Agregar imágenes para explosión
explosión_anim = []
for i in range(9):
    file = "Explosión/Explosión 0{}.png".format(i)
    img = pygame.image.load(file).convert()
    img.set_colorkey(BLACK)
    img_scale = pygame.transform.scale(img, (70, 70))
    explosión_anim.append (img_scale)
    




def explosión1():
    image = explosión_anim[0]
    center = image.get_rect()
    frame = 0
    last_update = pygame.time.get_ticks()
    frame_rate = 50 #Velocidad de la explosión
    screen.blit(image, (enemyX[i], enemyY[i]))

    now = pygame.time.get_ticks()
    if now - last_update > frame_rate:
        last_update = now
        frame += 1
        if frame == len(explosión_anim):
            kill()
        else:
            center = rect.center
            image = explosión_anim[frame]
            rect = image.get_rect()
            rect.center = center
        
def explosión2():
    image = explosión_anim[0]
    center = image.get_rect()
    frame = 0
    last_update = pygame.time.get_ticks()
    frame_rate = 50 #Velocidad de la explosión
    screen.blit(image, (bichoX[i], bichoY[i]))

    now = pygame.time.get_ticks()
    if now - last_update > frame_rate:
        last_update = now
        frame += 1
        if frame == len(explosión_anim):
            kill()
        else:
            center = rect.center
            image = explosión_anim[frame]
            rect = image.get_rect()
            rect.center = center


def explosión3():
    image = explosión_anim[0]
    center = image.get_rect()
    frame = 0
    last_update = pygame.time.get_ticks()
    frame_rate = 50 #Velocidad de la explosión
    screen.blit(image, (meteoroX[i], meteoroY[i]))

    now = pygame.time.get_ticks()
    if now - last_update > frame_rate:
        last_update = now
        frame += 1
        if frame == len(explosión_anim):
            kill()
        else:
            center = rect.center
            image = explosión_anim[frame]
            rect = image.get_rect()
            rect.center = center





# Game Loop
en_partida = True
while en_partida:
    clock.tick(60)

    en_final = False
    

    # RGB = Red, Green, Blue
    screen.fill((0, 0, 0))
    # Background Image
    screen.blit(background, (0, 0))


    
    # if player levels up
    if score_value < 40:
        level_value = 1
    elif score_value <= 80:
        level_value = 2
    elif score_value <= 120:
        level_value = 3
    elif score_value <= 160:
        level_value = 4

    if (score_value >= 40 and score_value <= 42):
        level_up_value = "LEVEL UP!"
    elif (score_value >= 80 and score_value <= 82):
        level_up_value = "LEVEL UP!"
    elif (score_value >= 120 and score_value <= 122):
        level_up_value = "LEVEL UP!"
    else:
        level_up_value = ""


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

        # if keystroke is pressed check whether its right or left
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                playerX_change = -5
            if event.key == pygame.K_RIGHT:
                playerX_change = 5
            if event.key == pygame.K_SPACE:
                if bullet_state == "ready":
                    bulletSound = mixer.Sound("laser.wav")
                    bulletSound.play()
                    # Get the current x cordinate of the spaceship
                    bulletX = playerX
                    fire_bullet(bulletX, bulletY)

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                playerX_change = 0

    # 5 = 5 + -0.1 -> 5 = 5 - 0.1
    # 5 = 5 + 0.1

    playerX += playerX_change
    if playerX <= 0:
        playerX = 0
    elif playerX >= 736:
        playerX = 736



    # Enemy Movement
    for i in range(num_of_enemies_10):

        # Game Over
        enemyY[i] += enemyY_change[i]
        if enemyY[i] > 440:
            for j in range(num_of_enemies_10):
                enemyY[j] = 2000
            game_over_text()
            break


    for i in range(num_of_enemies_20):

        # Game Over
        bichoY[i] += bichoY_change[i]
        if bichoY[i] > 440:
            for j in range(num_of_enemies_20):
                bichoY[j] = 2000
            game_over_text()
            break

    for i in range(num_of_enemies_30):

        # Game Over
        meteoroY[i] += meteoroY_change[i]
        if meteoroY[i] > 440:
            for j in range(num_of_enemies_30):
                meteoroY[j] = 2000
            game_over_text()
            break




        # Collision
        collision1 = isCollision1(enemyX[i], enemyY[i], bulletX, bulletY)
        collision2 = isCollision2(bichoX[i], bichoY[i], bulletX, bulletY)
        collision3 = isCollision3(meteoroX[i], meteoroY[i], bulletX, bulletY)
        
        enemy(enemyX[i], enemyY[i], i)
        bicho(bichoX[i], bichoY[i], i)
        meteoro(meteoroX[i], meteoroY[i], i)
        
        if collision1:
            explosionSound = mixer.Sound("explosion.wav")
            explosionSound.play()
            
            explosión1()
            bulletY = 480
            bullet_state = "ready"
            score_value += 10
            num_of_enemies_10 -= 1


        if collision2:
            explosionSound = mixer.Sound("explosion.wav")
            explosionSound.play()
            
            explosión2()
            bulletY = 480
            bullet_state = "ready"
            score_value += 20
            num_of_enemies_20 -= 1


        if collision3:
            explosionSound = mixer.Sound("explosion.wav")
            explosionSound.play()
            
            explosión3()
            bulletY = 480
            bullet_state = "ready"
            score_value += 30
            num_of_enemies_30 -= 1


    
    #Aumento de enemigos por nivel
    enemy_created = False
    flag = False
    if(level_value == 2 and flag == True):
        flag = True
        enemyX[i] = random.randint(0,736)
        enemyY[i] = random.randint(50,150)
        enemy(enemyX[i], enemyY[i], i)
    enemy_created = True

        
    # Bullet Movement
    if bulletY <= 0:
        bulletY = 480
        bullet_state = "ready"

    if bullet_state == "fire":
        fire_bullet(bulletX, bulletY)
        bulletY -= bulletY_change

    
    player(playerX, playerY)
    show_score(scoreX, scoreY)
    show_level(levelX, levelY)
    level_up_text(levelX + 100, levelY)
    show_vidas(vidasX, vidasY)
    pygame.display.update()

pygame.quit()

1 个答案:

答案 0 :(得分:1)

在游戏循环之前设置标志:

# Game Loop
flag = True    # set flag here
en_partida = True
while en_partida:
    clock.tick(60)

....................

#Aumento de enemigos por nivel
enemy_created = False
if(level_value == 2 and flag == True):  # check flag
    flag = False  # reset flag
    enemyX[i] = random.randint(0,736)
    enemyY[i] = random.randint(50,150)
    enemy(enemyX[i], enemyY[i], i)
enemy_created = True
相关问题