【问题标题】:Obstacles spawn too close to each other障碍物产生的距离太近
【发布时间】:2020-03-31 13:29:17
【问题描述】:

我的第一款游戏已经完成了 99% 的编程。我对它的工作方式感到非常满意,我只想改变一件事,但我不知道如何......

这是我的代码:

"""Program based on
https://www.youtube.com/watch?v=-8n91btt5d8&list=PLNAPMEWWbHeegjsyN7_pSwXbYPrbyiYhh&index=2&t=1849s"""

import pygame
import sys
import time
import random

pygame.init()

width = 1400
height = 800

green = (0, 51, 0)
black = (0, 0, 0)
yellow = (255, 255, 0)
white = (255, 255, 255)

player_location = [width - 1350, height - 200]
player_size = [100, 200]

obsticle_size = [101, 101]
obsticle_location = [width - 100, height - 100]

obsticle_list = [obsticle_location]

screen = pygame.display.set_mode((width, height))

speed = 10

score = 0

clock = pygame.time.Clock()
FPS = 60

myFont = pygame.font.SysFont("monospace", 35)

run = True

def set_speed(score, speed): #speed up game as score gets higher
    if score < 5:
        speed = 10
    elif score < 10:
        speed = 15
    elif score < 20:
        speed = 20
    elif score < 35:
        speed = 25
    elif score < 50:
        speed = 30
    elif score < 75:
        speed = 35
    elif score < 100:
        speed = 40
    else:
        speed = 50
    return speed

def spawn_obsticle(obsticle_list): #spawn obsticle on floor, max 3 on screen
    delay = random.random()
    if len(obsticle_list) < 3 and delay < 0.0085:
        x_pos = width - 100
        y_pos = height - 100
        obsticle_list.append([x_pos, y_pos])

def spawn_obsticle_2(obsticle_list): #spawn obsticle in air, max 3 on screen
    delay = random.random()
    if len(obsticle_list) < 3 and delay < 0.0085:
        x_pos = width - 100
        y_pos = height - 300
        obsticle_list.append([x_pos, y_pos])

def draw_obsticle(obsticle_list): #create obsticle
    for obsticle_location in obsticle_list:
        pygame.draw.rect(screen, white, (obsticle_location[0], obsticle_location[1], obsticle_size[0], obsticle_size[1]))

def update_obsticle_positions(obsticle_list, score): #making obsticles move from right to left
    for idx, obsticle_location in enumerate(obsticle_list):
        if obsticle_location[0] >= 0 and obsticle_location[0] < width:
            obsticle_location[0] -= speed
        else:
            obsticle_list.pop(idx) #drop obsticles off screen, score +1 everytime this happenes
            score += 1
    return score

def collision_check(obsticle_list, player_location): #detect collision between player and obsticle, part 1
    for obsticle_location in obsticle_list:
        if detect_collision(obsticle_location, player_location):
            return True
        return False


def detect_collision(player_location, obsticle_location): #detect collision between player and obsticle, part 2
    p_x = player_location[0]
    p_y = player_location[1]

    p_width = player_size[0]
    p_height = player_size[1]

    o_x = obsticle_location[0]
    o_y = obsticle_location[1]

    o_width = obsticle_size[0]
    o_height = obsticle_size[1]

    if (o_x >= p_x and o_x < (p_x + p_width)) or (p_x >= o_x and p_x < (o_x + o_width)):
        if (o_y >= p_y and o_y < (p_y + p_height)) or (p_y >= o_y and p_y < (o_y + o_height)):
            return True
    return False

while run:

    clock.tick(FPS) 

    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            run = False
            sys.exit

        if event.type == pygame.KEYDOWN: 

            x = player_location[0]   #x location of player
            y = player_location[1]   #y location of player

            p_width = player_size[0]    #starting player width
            p_height = player_size[1]    #starting player height


            if event.key == pygame.K_UP: #jump up by changing y location
                y -= 200

            player_location = [x,y] 

        if event.type == pygame.KEYUP:

            if event.key == pygame.K_SPACE or event.key == pygame.K_UP: #back to starting size and location when releasing key
               player_size = [100, 200]
               player_location = [50, 600]

    keys = pygame.key.get_pressed() #stooping by switching width and heigt of player
    if keys[pygame.K_SPACE]:
        p_width = player_size[1]
        p_height = player_size[0]
        y = 700

        player_size = [p_width,p_height]
        player_location = [x,y]

    screen.fill(black)

    spawn_obsticle(obsticle_list)
    spawn_obsticle_2(obsticle_list)
    score = update_obsticle_positions(obsticle_list, score)
    speed = set_speed(score, speed)

    text = "Score:" + str(score)            #making score appear on screen
    label = myFont.render(text, 1, yellow)
    screen.blit(label, (600, 250))

    if collision_check(obsticle_list, player_location): #ending game when there is contact between player and obsticle
        run = False

    draw_obsticle(obsticle_list)

    pygame.draw.rect(screen, green, (player_location[0], player_location[1], player_size[0], player_size[1]))

    pygame.display.update()

这个游戏很简单:你是绿色方块,你必须避开白色方块。对于您避开的每个街区,您都会得到一分。您的分数越高,障碍物移动的越快。

我的问题是,有时飞行物块和地板上的物块会(几乎)完全重叠生成,因此无法躲避。 (第一次运行可能不会发生,但运行几次肯定会遇到)

我怎样才能让它们总是在彼此之间产生一些距离?

我只是想不通,这将完成我的第一场比赛。提前致谢 (抱歉有些地方英语不好。英语不是我的母语)

【问题讨论】:

  • 一种策略是在随机位置继续生成,但随后检查每个对象是否离其他对象太近。如果是,则丢弃它并尝试在新位置再次产卵

标签: python pygame


【解决方案1】:

增加每次生成之间的延迟。将 spawn_obsticle 函数更改为:

def spawn_obsticle(obsticle_list): #spawn obsticle on floor, max 3 on screen
    delay = random.random()
    if len(obsticle_list) < 3 and delay < 0.0185: # Used to be 0.0085
        x_pos = width - 100
        y_pos = height - 100
        obsticle_list.append([x_pos, y_pos])

对这两个函数都执行此操作。我建议将两个障碍函数放在一个函数中,并将更改减半,这样两个就不会在彼此之上生成,并形成一个不可能的障碍,例如:

def spawn_obsticle(obstacle_list):
    delay = random.random()
    dist = random.choice([100, 300])
    if len(obstacle_list) < 6:
        x_pos = width-100
        y_pos = height-dist
        obsticle_list.append([x_pos, y_pos])

【讨论】:

  • 我认为将两个 spawn_obstacle 函数放在一起可以解决问题,但我还是编程新手。如果不是因为我在开始时提到的视频,我将无法接近这个结果?。老实说,我不知道如何将它们放在一起,因为我正在使用 2 个不同的 y 位置。我已经尝试了一些东西,但没有成功
  • 我编辑了它,希望对您有所帮助。另外,这里有一个很好的 python 教程:tutorialspoint.com/python/index.htm.
  • 谢谢!它仍然偶尔发生,但已经不那么频繁了。从这里开始,我会尝试自己弄清楚。该教程将有很大帮助,谢谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
  • 1970-01-01
  • 2013-12-23
相关资源
最近更新 更多