简体   繁体   中英

collision detection code in pygame doesn't work properly

I am working on a game based on a 1973 arcade game called space race (more info: https://en.wikipedia.org/wiki/Space_Race_(video_game) ) using pygame, but it doesn't give the results I expected. it is supposed to send the player's rocket back to the spawning point when it collides with an asteroid, it doesn't give any syntax errors, but it still goes right through the rocket.

I've tried messing around with the code, however, it still won't do what I want it to.

Here is the code for the whole program.

import random as r
import pygame as pg
pg.init ()

screen = pg.display.set_mode ((960, 720))

pg.display.set_caption ("space race!")
icon = pg.image.load ("icon.png")
pg.display.set_icon (icon)

score1num = 0
font1 = pg.font.Font ("freesansbold.ttf", 50)

score2num = 0
font2 = pg.font.Font ("freesansbold.ttf", 50)

player1_img = pg.image.load ("player1.png")
player1_x = 430
player1_y = 580
player1_y_change = 0

player2_img = pg.image.load ("player2.png")
player2_x = 530
player2_y = 580
player2_y_change = 0

timer_img = pg.image.load ("timer.png")
timer_x = 480
timer_y = 0
timer_y_change = 0.02

bullet1_img = pg.image.load ("bullet.png")
bullet1_x = 480
bullet1_y = 0
bullet1_x_change = -0.5


def player1 (x, y):
    screen.blit (player1_img, (x, y))

def player2 (x, y):
    screen.blit (player2_img, (x, y))

def score1 (x, y):
    display_score = font1.render("wasd score: " + str(score1num), True, (255, 255, 255))
    screen.blit(display_score, (x, y))

def score2 (x, y):
    display_score = font2.render("ijkl score: " + str(score2num), True, (255, 255, 255))
    screen.blit(display_score, (x, y))

def timer (x, y):
    screen.blit (timer_img, (x, y))

def bullet1 (x, y):
    screen.blit (bullet1_img, (x, y))

def gameover (x, y):
    gameoverfont = pg.font.Font ("freesansbold.ttf", 100)
    display_gameover = gameoverfont.render ("game over!", True, (255, 255, 255))
    screen.blit (display_gameover, (x, y))

execute = True
while execute:
    screen.fill ((0, 0, 0))
    for event in pg.event.get ():
        if event.type == pg.QUIT:
            execute = False
        if event.type == pg.KEYDOWN:
            if event.key == pg.K_w:
                player1_y_change = -0.5

            if event.key == pg.K_s:
                player1_y_change = 0.5

            if event.key == pg.K_i:
                player2_y_change = -0.5

            if event.key == pg.K_k:
                player2_y_change = 0.5

        if event.type == pg.KEYUP:
            player1_y_change = 0
            player2_y_change = 0

    if timer_y >= 720:
        break
    if player1_y > 592:
        player1_y = 592
    if player2_y > 592:
        player2_y = 592
    if player1_y < -64:
        player1_y = 580
        score1num = score1num + 1
    if player2_y < -64:
        player2_y = 580
        score2num = score2num + 1

    if bullet1_x == 0:
        bullet1_x = 960
        bullet1_y = r.randint (10, 550)

    if player1_x >= bullet1_x and player1_y >= bullet1_y:
        if player1_x + 32 <= bullet1_x + 25 and player1_y + 128 <= bullet1_y + 25:
            player1_y = 580

    player1 (player1_x, player1_y)
    player2 (player2_x, player2_y)
    timer (timer_x, timer_y)
    score1 (100, 100)
    score2 (560, 100)
    bullet1 (bullet1_x, bullet1_y)

    player1_y = player1_y + player1_y_change
    player2_y = player2_y + player2_y_change
    timer_y = timer_y + timer_y_change
    bullet1_x = bullet1_x + bullet1_x_change
    pg.display.update ()

while execute:
    screen.fill ((0, 0, 0))
    for event in pg.event.get ():
        if event.type == pg.QUIT:
            execute = False
    gameover (220, 360)
    pg.display.update ()

also the sizes of the images: player1 and player2 - 32x128, timer - 25x960, bullet - 25x25.

To test if 2 rectangles ( x1 , y1 , w1 , h1 ) and ( x2 , y2 , w2 , h2 ) intersect you need to test if:

x1 < x2+w2 and x2 < x1+w1 and y1 < y2+h2 and y2 < y1+h1

In your code this means:

if (player1_x < bullet1_x+25 and bullet1_x < player1_x + 32 and 
    player1_y < player1_y+25 and bullet1_y < player1_y + 128):
    player1_y = 580

However, see How do I detect collision in pygame? In pygame you can simplify this code with pygame.Rect objects and colliderect :

player_rect = pygame.Rect(player1_x, player1_y, 32, 128)
bullet_rect = pygame.Rect(bullet1_x, player1_y, 25, 25)
if player_rect.colliderect(bullet_rect):
    player1_y = 580

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM