Pygame:我如何生成随机出现和掉落的事物?

时间:2018-12-15 18:34:29

标签: python random pygame

我正在尝试制作类似的游戏,球随机掉落,底部的男孩接住球。我随机地在上面放了一排球,但是我不确定如何使它们随机出现并分别掉下来。

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()

ball.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()

因此,第一排球被随机放置在顶部,但是我如何使其不能一次全部出现并分别掉下来呢?

3 个答案:

答案 0 :(得分:1)

由于您提到要使各个球分别掉落,因此我们可以想到每个球都有两个状态:“掉落”和“不掉落”。我们可以相应地为update调整__init__ball.py函数:

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()

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

如果某些条件为Ball(在下面的示例中为True),则可以将新的if random.randrange(100) < 2:实例添加到组中。如果应该有最大数量的球,请添加and len(balls) < 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()