【问题标题】:Pygame: how do I generate things to appear and fall down in random?Pygame:我如何生成随机出现和掉落的东西?
【发布时间】:2019-05-16 16:36:29
【问题描述】:

我正在尝试构建一个游戏,例如,球随机落下,底部的男孩接住球。我以随机方式在顶部制作了一排球,但我不确定如何让它们随机出现并单独掉落。

baseball_game.py

import sys
import pygame
from pygame.sprite import Group
from settings import Settings
from boy import Boy
from ball import Ball
import game_functions as gf


def run_game():
    # Initialize pygame, settings, and screen object.
    pygame.init()
    bg_settings = Settings()
    screen = pygame.display.set_mode(
            (bg_settings.screen_width, bg_settings.screen_height))
    pygame.display.set_caption("Catch the Baseball!")

    # Make a boy
    boy = Boy(bg_settings, screen)
    balls = Group()


    # Create the fleet of aliens.
    gf.create_fleet(bg_settings, screen, boy, balls)


    # Make a ball
    ball = Ball(bg_settings, screen)

    # Set the background color.
    bg_color = (217, 208, 187)

    # Start the main loop for the game.
    while True:
        gf.check_events(boy)
        boy.update()
        gf.update_balls(balls)
        gf.update_screen(bg_settings, screen, boy, balls)


run_game()

球.py

import pygame
from pygame.sprite import Sprite
import random


class Ball(Sprite):
    """A class to represent a single ball."""

    def __init__(self, bg_settings, screen):
        """Initalize the ball and set its starting position."""
        super(Ball, self).__init__()
        self.screen = screen
        self.bg_settings = bg_settings

        # Load the ball image and set its rect attribute.
        self.image = pygame.image.load('images/ball.png')
        self.rect = self.image.get_rect()

        # Start each new ball.
        self.rect.x = random.randint(-10, 40)
        self.rect.y = random.randint(-10, 40)

        # Store the ball's exact position.
        self.y = float(self.rect.y)

    def update(self):
        """Move the ball down."""
        self.y += self.bg_settings.ball_speed_factor
        self.rect.y = self.y

    def blitme(self):
        """Draw the ball at its current location."""
        self.screen.blit(self.image, self.rect)

game_functions.py

import sys
import pygame
from ball import Ball
from random import randint
random_number = randint(-15, 39)


def check_events(boy):
    """Respond to keypresses and mouse events."""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
             sys.exit()
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event, boy)
        elif event.type == pygame.KEYUP:
            check_keyup_events(event, boy)


def check_keydown_events(event, boy):
    """Respond to keypresses."""
    if event.key == pygame.K_RIGHT:
        boy.moving_right = True
    elif event.key == pygame.K_LEFT:
        boy.moving_left = True
    elif event.key == pygame.K_q:
        sys.exit()

def check_keyup_events(event, boy):
    """Respond to key releases."""
    if event.key == pygame.K_RIGHT:
        boy.moving_right = False
    elif event.key == pygame.K_LEFT:
        boy.moving_left = False

def update_screen(bg_settings, screen, boy, balls):
    """Update images on the screen and flip to the new screen."""
    # Redraw the screen during each pass through the loop.
    screen.fill(bg_settings.bg_color)
    boy.blitme()
    balls.draw(screen)

    # Make the most recently drawn screen visible.
    pygame.display.flip()

def get_number_balls_x(bg_settings, ball_width):
    """Determine the number of aliens that fit in a row."""
    available_space_x = bg_settings.screen_width - 2 * ball_width
    number_balls_x = int(available_space_x / (2 * ball_width))
    return number_balls_x

def create_ball(bg_settings, screen, balls, ball_number):
    """Create a ball and place it in the row."""
    ball = Ball(bg_settings, screen)
    ball_width = ball.rect.width
    ball.x = ball_width + 2 * ball_width * ball_number
    ball.rect.x = ball.x
    balls.add(ball)

def create_fleet(bg_settings, screen, boy, balls):
    ball = Ball(bg_settings, screen)
    number_balls_x = get_number_balls_x(bg_settings, ball.rect.width)

    for ball_number in range(number_balls_x):
         create_ball(bg_settings, screen, balls, ball_number)

def update_balls(balls):
    """Update the positions of all balls in the fleet."""
     balls.update()

所以第一排球是随机放在上面的,但是我怎样才能让它不是一下子出现,而是分开掉下来呢?

【问题讨论】:

  • 看起来你对random 做的唯一事情就是这个random_number = randint(-15, 39),然后你永远不会在任何地方使用random_number
  • 对不起,我刚刚编辑更新了!所以,我随机放置了球,但问题是让它们单独随机出现......
  • 请阅读Minimal, Complete and Verifiable example page。该程序无法运行。

标签: python random pygame


【解决方案1】:

既然您提到您希望球单独落下,我们可以认为每个球都有两种状态:“落下”和“不落下”。我们可以相应地调整ball.pyupdate__init__ 函数:

class Ball(Sprite):
    def __init__(self, bg_settings, screen)
        # ... all your other properties
        self.is_falling = False # the ball is not falling when first created

    # ...

    def update(self):
        if self.is_falling:
            self.y += self.bg_settings.ball_speed_factor
            self.rect.y = self.y

现在我们只需要一些随机触发每个球的下降属性的方法。在 game_functions.py 中,您有一个更新球的方法。我们可以在那里添加一些函数来随机决定我们是否要丢球,以及我们要丢哪个球:

from random import random
# ...

def update_balls(self):
    if random() < 0.4: # 40% percent chance of making a ball drop
        ball_index = randint(0, len(balls)-1)
        balls[ball_index].is_falling = True

    balls.update()

【讨论】:

  • 你可以在这里使用random.choice
  • 非常感谢您的友好回答,但是,我仍然收到如下错误! :回溯(最近一次调用最后):文件“baseball_game.py”,第 41 行,在 run_game() 文件“baseball_game.py”,第 37 行,在 run_game gf.update_balls(balls) 文件“C:\Users \Muffin\Desktop\python_work\project_1\baseball\game_functions.py",第 66 行,在 update_balls if random()
  • 在这种情况下,您只需import random,然后运行random.random() 即可获取号码。
【解决方案2】:

创建一个名为RNG 的变量并将其设置为生成任意范围之间的随机数,比如-5050。然后您可以创建一个名为RNG_CASES[] 的数组,并在您为RNG 设置的范围内为它们提供任何随机常数值。最后,做一个条件结构:

if(RNG in RNG_CASES[]): 
    fall();
else: 
    pass; #(pass not needed, only for pseudocode).

【讨论】:

    【解决方案3】:

    如果某些条件是True(在下面的示例中为if random.randrange(100) &lt; 2:),您可以将新的Ball 实例添加到组中。如果应该有最大数量的球,请添加and len(balls) &lt; max_balls:

    另外,当精灵离开屏幕时不要忘记kill

    import random
    import pygame
    from pygame.sprite import Sprite
    
    
    class Ball(Sprite):
        """A class to represent a single ball."""
    
        def __init__(self, bg_settings, screen):
            """Initalize the ball and set its starting position."""
            super(Ball, self).__init__()
            self.screen = screen
            self.bg_settings = bg_settings
            self.image = pygame.Surface((30, 30))
            self.image.fill((100, 200, 0))
            self.rect = self.image.get_rect()
            # Start each new ball.
            self.rect.x = random.randint(-10, self.bg_settings.screen_width)
            self.rect.y = random.randint(-100, -40)
            # Store the ball's exact position.
            self.y = float(self.rect.y)
    
        def update(self):
            """Move the ball down."""
            self.y += 1
            self.rect.y = self.y
    
            if self.rect.top > self.bg_settings.screen_height:
                self.kill()
    
    
    class Settings:
        screen_width = 640
        screen_height = 480
        bg_color = pygame.Color('gray12')
    
    
    def run_game():
        pygame.init()
        clock = pygame.time.Clock()
        bg_settings = Settings()
        screen = pygame.display.set_mode(
            (bg_settings.screen_width, bg_settings.screen_height))
        balls = pygame.sprite.Group()
    
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    return
    
            balls.update()
            if random.randrange(100) < 2:
                balls.add(Ball(bg_settings, screen))
    
            screen.fill(bg_settings.bg_color)
            balls.draw(screen)
    
            pygame.display.flip()
            clock.tick(60)
    
    
    run_game()
    

    【讨论】:

      猜你喜欢
      • 2020-04-26
      • 1970-01-01
      • 2014-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多