简体   繁体   中英

Collision detection simple game - Pygame

Trying to call crash function when the pirate ship and the block collide, yet for some reason the block will hit the screen and will call the crash function. Game does end when they collide but the game will randomly end when the block hits certain parts of the screen.

import pygame
import time
from pygame.locals import * #all the imports I use
import random

pygame.init() # initialise pygame

display_width = 1500
display_height = 700

black = (0,0,0)
white = (255,255,255)
red = (255,0,0)


gameDisplay = pygame.display.set_mode((display_width,display_height)) #creates the window
pygame.display.set_caption('A bit Shipy')
clock = pygame.time.Clock()

shipIMG = pygame.image.load('ship.png')
ship_width = 50
ship_height = 50 # in pixels

def things_dodged(count):
    font = pygame.font.SysFont(None, 25)
    text = font.render("Dodged: "+str(count), True, black)
    gameDisplay.blit(text, (0,0))

def things(thingx, thingy, thingw, thingh, color): #the scrolling object
    pygame.draw.rect(gameDisplay, color, [thingx, thingy, thingw, thingh])

def ship(x,y): #ship function
    gameDisplay.blit(shipIMG,(x,y))



def text_objects(text, font):
    textSurface = font.render(text, True, red) #game over text
    return textSurface, textSurface.get_rect()


def message_display(text):
    largeText = pygame.font.Font('freesansbold.ttf',200)
    TextSurf, TextRect = text_objects(text, largeText)
    TextRect.center = ((display_width/2),(display_height/2)) #creates the text 
    gameDisplay.blit(TextSurf, TextRect)

    pygame.display.update()
    time.sleep(2) #Game over text lasts two seconds

    game_loop() #runs the game again afterwards

def crash():
    message_display('You Sunk!') #when the player goes off screen or hits an object




#x = (display_width * 0.45)
#y = (display_height * 0.8)

def game_loop(): #the main game loop
    x = (display_width * 0.45)
    y = (display_height * 0.8)
    x_change = 0
    y_change = 0

    thing_startx = display_width
    thing_starty = random.randrange(0, display_height)  #enemy object
    thing_speed = 7
    thing_width = 50
    thing_height = 50

    dodged = 0


    gameExit = False

    while not gameExit:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    x_change = -5
                elif event.key == pygame.K_RIGHT:
                    x_change = 5

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: #changes x or y dependant on key pressed
                    x_change = 0

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP:
                    y_change = -5

                elif event.key == pygame.K_DOWN:
                    y_change = 5

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                    y_change = 0
        x += x_change
        y += y_change



        gameDisplay.fill((0,0,155)) #blue background 


        things(thing_startx, thing_starty, thing_width, thing_height, black) #calls the thing function 
        thing_startx -= thing_speed #moves the block left 
        ship(x,y)
        things_dodged(dodged)


        if x > display_width - ship_width or y > display_height-ship_height or x < 0 or y < 0:
             crash()

        if thing_startx < 0:
            thing_startx = display_width
            thing_starty = random.randrange(0, display_height)
            dodged = dodged + 1

        #here is where the collision detection starts:    
        if x < thing_startx+thing_width:
            print(' y crossover 1')

            if y >= thing_starty and y < thing_starty + thing_height or y+ship_height > thing_starty and y + ship_height < thing_starty +thing_height:
                print (' x crossover 2')
                crash()

        pygame.display.update()
        clock.tick(200)



game_loop()
pygame.quit()
quit()

Looks like you collision test with the screen wasn't correct. Here is an alternative version.

    #if x > display_width - ship_width or y > display_height - ship_height or x < 0 or y < 0:
    if (x + ship_width/2 > display_width or    # right edge
        x - ship_width/2 < 0 or                # left edge
        y + ship_height/2 > display_height or  # top
        y - ship_width/2 < 0):                 # bottom
        crash()

You should think about introducing the ship as an object (class).

Your collision detection with the object on the x axis is only checking if the block is left of the ship:

    #here is where the collision detection starts:
    if (x  > thing_startx - thing_width/2 and
        x  < thing_startx  + thing_width/2):
        print(' y crossover 1')

Maybe you should use the builtin sprites to represent the ship and the block: sprite

They are objects and have a function to detect collusions with other sprites: collide_rect

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