Как создать прямоугольник, где произошло столкновение между двумя - PullRequest
0 голосов
/ 21 января 2020

Я плохо объясняю, поэтому я попытаюсь сделать это проще: я делаю игру, в которой вы управляете веслом, чтобы ударить блоки мячом, и они исчезают. После того, как вы дважды ударьте по блоку, маленький круг (названный power_up) случайно появляется на оси x и начинает медленно падать (вы должны поймать его веслом).

Изображение игры : enter image description here

Я пытаюсь сделать так, чтобы прямоугольник power_up появлялся случайным образом на оси x после того, как мяч попал в блок.

Другой способ его программирования чтобы прямоугольник power_up отображался там, где мяч столкнулся с блоком, но я не знаю, как это сделать.

Вот код, в котором я пытаюсь сделать прямоугольник случайным образом после двойного удара , (Если вы знаете, как, вы можете сделать так, чтобы прямоугольник power_up отображался прямо там, где мяч столкнулся с блоком, пожалуйста, это было бы более удивительно, чем оригинальная идея, которая у меня была)

    #activate power up if collision is 10x
    if power_up_var == 2:
        #chooses random coordinates to place power up
        power_up_rect.x = rand_int
        power_up_rect.y = 10
        draw_power_up = True
        power_up_var = 0

Вот полный код.

#December 16, 2019
#Final Project - Breakout

#IMPORTING LIBRARIES-----
import pygame
import sys
import time
import random

#INITIALIZING SCREEN SIZE-----
pygame.init()
screen_size = (597, 700)
screen = pygame.display.set_mode((screen_size),0)
pygame.display.set_caption("BREAKOUT")

#retrieve screen measurements
screen_w = screen.get_width()
screen_h = screen.get_height()

#retrieve position of center of screen
center_x = int(screen_w/2)
center_y = int(screen_h/2)

#COLOURS-----
WHITE = (255,255,255)
BLACK = (0, 0, 0)
GREEN = (0,255,0)
RED = (255,0,0)
BLUE = (0,0,255)
PURPLE = (154, 136, 180)

#BACKGROUND-----
screen.fill(BLACK)
pygame.display.update()

#PICTURES-----
background_image = pygame.image.load("space_background.png")
blue_block_image = pygame.image.load("easy_block.png")
purple_block_image = pygame.image.load("medium_block.png")
pink_block_image = pygame.image.load("hard_block.png")
metal_block_image = pygame.image.load("metal_block.png")
paddle_image = pygame.image.load("paddle.png")
ball_image = pygame.image.load("ball.png")
#title_image = pygame.image.load("S4.png")

#SPEED-----
clock = pygame.time.Clock()
FPS = 60 #set frames per second
speed = [4,4]
paddle_speed = 6

# -------------------------VARIABLES-------------------------
#paddle speed
paddle_dx = 0
paddle_dy = 0

#power_ups
power_up_var = 0

#random # list
rand_list = range(12, 580)

rand_spin = False

#finds random integer
rand_int = random.choice(rand_list)


# -------------------------FUNCTIONS/CLASSES-------------------------
#repeated values for the blocks combined into class
class Object:
    def __init__(self, x, y, w, h):
        self.x = x
        self.y = y
        self.w = w
        self.h = h

blue_block = Object(5, 172, 40, 10)
purple_block = Object(5, 148, 40, 10)
pink_block = Object(5, 124, 40, 10)
metal_block = Object(5, 110, 40, 10)
lives_displayed_fun = Object(4, 685, 79, 10)
paddle = Object(center_x, 600, 78, 10)
ball = Object(center_x, center_y, 12, 12)

#rects
paddle = pygame.Rect(paddle.x, paddle.y, paddle.w, paddle.h)
ball = pygame.Rect(ball.x, ball.y, ball.w, ball.h)
power_up_rect = pygame.Rect(ball.x, ball.y, ball.w, ball.h)
lives_displayed_rect = pygame.Rect(lives_displayed_fun.x, lives_displayed_fun.y, lives_displayed_fun.w, lives_displayed_fun.h)

# -------------------------ARRAYS-------------------------

#empty array to store rects for each block row of level
blue_blocks = []
purple_blocks = []
pink_blocks = []
metal_blocks = []
lives_displayed = []

#layout of blocks for each level
#layout of blocks for each level
blue_block_array = [
"B B B B B B B B B B B B B B",
"B B B B B B B B B B B B B B",
]

purple_block_array = [
"P P P P P P P P P P P P P P",
"P P P P P P P P P P P P P P",
]

pink_block_array = [
"I I I I I I I I I I I I I I",
"I I I I I I I I I I I I I I",
]

metal_block_array = [
"M M M M M M M M M M M M M M",
]

lives_displayed_array = [
"L L L",
]

# -------------------------CREATING BLOCK RECTS-------------------------

#read the array and create the appropriate Rects FOR EACH LEVEL, store them in the walls array
for row in blue_block_array: #easy/blue
    for col in row:
        if col == "B":
            blue_block_rect = pygame.Rect(blue_block.x, blue_block.y, blue_block.w, blue_block.h)
            blue_blocks.append(blue_block_rect)
        blue_block.x += 21
    blue_block.y += 12
    blue_block.x = 5

for row in purple_block_array:
    for col in row:
        if col == "P":
            purple_block_rect = pygame.Rect(purple_block.x, purple_block.y, purple_block.w, purple_block.h)
            purple_blocks.append({"rect": purple_block_rect, "strength": 2})
        purple_block.x += 21
    purple_block.y += 12
    purple_block.x = 5

for row in pink_block_array:
    for col in row:
        if col == "I":
            pink_block_rect = pygame.Rect(pink_block.x, pink_block.y, pink_block.w, pink_block.h)
            pink_blocks.append({"rect": pink_block_rect, "strength": 3})
        pink_block.x += 21
    pink_block.y += 12
    pink_block.x = 5

for row in metal_block_array:
    for col in row:
        if col == "M":
            metal_block_rect = pygame.Rect(metal_block.x, metal_block.y, metal_block.w, metal_block.h)
            metal_blocks.append({"rect": metal_block_rect, "strength": 4})
        metal_block.x += 21
    metal_block.y += 12
    metal_block.x = 5

for row in lives_displayed_array: #lives/paddle
    for col in row:
        if col == "L":
            lives_displayed_rect = pygame.Rect(lives_displayed_fun.x, lives_displayed_fun.y, lives_displayed_fun.w, lives_displayed_fun.h)
            lives_displayed.append(lives_displayed_rect)
        lives_displayed_fun.x += 41
    lives_displayed_fun.y += 12
    lives_displayed_fun.x = 5

# -------------------------POWER UPS-------------------------
#chooses random power up from list
#power_up_list = [e_power_up, s_power_up, l_power_up, a_power_up]

#//all power ups work until the next power up is activated

#power up 'e' - expands the paddle

#power up 's' - slows down the speed of the ball

#power up 'l' - adds two lasers to the paddle that also destroy blocks

#power up 'a' - adds an extra life


# -------------------------LOOPS-------------------------
intro_screen = False
game_screen = True
end_screen = False
power_up_fall = False
draw_power_up = False

#introduction + instructions loop
while intro_screen:
    for event in pygame.event.get():
        if event.type ==pygame.QUIT:
            game = False
            pygame.quit()
            sys.exit()

    #constrain this loop to the specified FPS
    clock.tick(FPS)#main gaming loop
while game_screen:
    for event in pygame.event.get():
        if event.type ==pygame.QUIT:
            game = False
            pygame.quit()
            sys.exit()

        #moving paddle with keys
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                paddle_dx = -paddle_speed
            elif event.key == pygame.K_RIGHT:
                paddle_dx = paddle_speed

    if event.type == pygame.KEYUP:
        paddle_dx = 0

    #constrain this loop to the specified FPS
    clock.tick(FPS)

    #removes screen trail
    screen.fill(BLACK)
    screen.blit(background_image, [0, 0])

    #PADDLE EVENTS-----

    #store old paddle positions
    old_paddle_x = paddle.x
    old_paddle_y = paddle.y

    #moving the paddle rect
    paddle.move_ip(paddle_dx, paddle_dy)

    #check to see if rect has left screen
    if paddle.left < 0 or paddle.right > screen_w:
        paddle.x = old_paddle_x

    #BALL EVENTS-----

    #moving ball
    ball = ball.move(speed)

    #collision bounce left & right
    if ball.left < 0 or ball.right > screen_w:
        speed[0] = -speed[0]

    #collision bounce top & bottom
    if ball.top < 0 or ball.bottom > screen_h:
        speed[1] = -speed[1]
    #collision of ball with paddle
    if paddle.colliderect(ball):
        speed[1] = -speed[1]

    #collision with bottom - life removed
    if ball.bottom > screen_h:
        if len(lives_displayed) > 0:
            lives_displayed.pop(len(lives_displayed) - 1)

    #activate power up if collision is 10x
    if power_up_var == 2:
        #chooses random coordinates to place power up
        power_up_rect.x = rand_int
        power_up_rect.y = 10
        draw_power_up = True
        power_up_var = 0
        #power_up = random.choice(power_up_list)

    #BLOCKS EVENTS-----

    #editing dictionaries according to collision

    for block in blue_blocks:
        if block.colliderect(ball):
            speed[1] = -speed[1]
            blue_blocks.remove(block)
            power_up_var += 1
            print(power_up_var)

    for block in purple_blocks:
        if block["rect"].colliderect(ball):
            speed[1] = -speed[1]
            block["strength"] -= 1
            if block["strength"] <= 0:
                purple_blocks.remove(block)

    for block in pink_blocks:
        if block["rect"].colliderect(ball):
            speed[1] = -speed[1]
            block["strength"] -= 1
            if block["strength"] <= 0:
                pink_blocks.remove(block)

    for block in metal_blocks:
        if block["rect"].colliderect(ball):
            speed[1] = -speed[1]
            block["strength"] -= 1
            if block["strength"] <= 0:
                metal_blocks.remove(block)


# -------------------------BLIT/DRAWING-------------------------

    #drawing paddle/ball inside rect
    screen.blit(paddle_image, paddle)
    screen.blit(ball_image, ball)
    if draw_power_up == True:
        screen.blit(ball_image, power_up_rect)

    #draws blocks and applies transparency as needed
    for block in blue_blocks:
        screen.blit(blue_block_image, block)

    for block in purple_blocks:
        alpha = 255 * block["strength"] // 2 #number will always remain under 255 until it is hit two times
        if alpha < 255: #if the number is below 255, it will add a white color on top to resemble transparency per hit
            transp_image = purple_block_image.copy().convert_alpha() #creates a new copy of the image to support per pixel alpha
            transp_image.fill((255, 255, 255, alpha), special_flags = pygame.BLEND_RGBA_MIN) #using pygame.Surface.fill to fill the surface, but set the special blending flag ^ so that texture is calculated the minimum of the pixel color and (255, 255, 255, alpha)
            screen.blit(transp_image, block["rect"])
        else:
            screen.blit(purple_block_image, block["rect"]) #once hit three times, block removed

    for block in pink_blocks:
        alpha = 255 * block["strength"] // 3
        if alpha < 255: 
            transp_image = pink_block_image.copy().convert_alpha() 
            transp_image.fill((255, 255, 255, alpha), special_flags = pygame.BLEND_RGBA_MIN)
            screen.blit(transp_image, block["rect"])
        else:
            screen.blit(pink_block_image, block["rect"])

    for block in metal_blocks:
        alpha = 255 * block["strength"] // 4
        if alpha < 255: 
            transp_image = metal_block_image.copy().convert_alpha() 
            transp_image.fill((255, 255, 255, alpha), special_flags = pygame.BLEND_RGBA_MIN)
            screen.blit(transp_image, block["rect"])
        else:
            screen.blit(metal_block_image, block["rect"])

    #draws a paddle life for each "L"
    for life in lives_displayed:
        screen.blit(paddle_image, life)

    #updating the screen
    pygame.display.update()

pygame.quit()
sys.exit()

# -------------------------CREDITS-------------------------
# transparency not done by me solely, got help from starbucks guy
#background - https://www.wallpaperflare.com/dragon-flying-above-sky-artwork-wallpaper-181535
#block/paddle/ball pictures were created on pixilart.com by myself

1 Ответ

0 голосов
/ 21 января 2020

Случайное значение в диапазоне может быть получено с помощью random.randint(a, b). Вы должны вызывать random.randint каждый раз, когда хотите получить новую случайную позицию. Так как радиус объекта шара равен 6, случайная координата x может быть получена следующим образом:

#chooses random coordinates to place power up
power_up_rect.centerx = random.randint(6, screen_w-6)

Примечание power_up_rect.x слева от pygame.Rect, но power_up_rect.centerx - это его центр.

Если координата x при увеличении мощности должна быть координатой x шара, когда мяч попадает в блок, вы должны установить:

power_up_rect.centerx = ball.centerx

Я рекомендую установить poerw, после того, как мяч попал в блок

for block in blue_blocks:
    if block.colliderect(ball):
        speed[1] = -speed[1]
        blue_blocks.remove(block)
        power_up_var += 1
        print(power_up_var)

#activate power up if collision is 10x
if power_up_var == 2:
    power_up_rect.centerx = ball.centerx
    power_up_rect.y = 10
    draw_power_up = True
    power_up_var = 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...