2
votes

I use Pygame in this code. This is like a game that when user hit mouse button, from the mouse position comes a laser image that will go up, and eventually go out of the screen. I am trying to blit an image when the user hit mouse button. This code I am using does not work and I do not know why. My problem starts at the main for loop

    import pygame

    # Initialize Pygame
    pygame.init()

    #___GLOBAL CONSTANTS___
    # Define some colors
    BLACK = (0, 0, 0)
    WHITE = (255, 255, 255)
    GREEN = (0, 255, 0)
    RED = (255, 0, 0)


    # Set the height and width of the screen
    screen_width = 500
    screen_height = 500
    screen = pygame.display.set_mode([screen_width, screen_height])


    #Load Laser image of spaceship
    laser_image = pygame.image.load('laserRed16.png').convert()


    #Load sound music
    sound = pygame.mixer.Sound('laser5.ogg')


    # Loop until the user clicks the close button.
    done = False

    # Used to manage how fast the screen updates
    clock = pygame.time.Clock()


    # -------- Main Program Loop -----------
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
            elif event.type == pygame.MOUSEBUTTONDOWN:
                # Get the current mouse position. This returns the position
                # as a list of two numbers.
                sound.play()
                #Get the mouse position 
                mouse_position = pygame.mouse.get_pos()
                mouse_x = mouse_position[0]
                mouse_y = mouse_position[1]
                # Set the laser image when the spaceship fires
                for i in range(50):
                    screen.blit(laser_image,[mouse_x + laser_x_vector,mouse_y + laser_x_vector])
                    laser_x_vector += 2
                    laser_x_vector += 2


        # Clear the screen
        screen.fill(WHITE)

        #Limit to 20 sec
        clock.tick(20)

        # Go ahead and update the screen with what we've drawn.
        pygame.display.flip()
pygame.quit()
2
you blit laser before fill so fill removes laser before flip sends buffer to video card which will diplay it on monitor. - furas
you will have anothet problem - for loop which moves laser - it will not work as you expect because you move it 50 times in one frame (between two flip) so you get laser in target position at once. you have to do one move in every while not doneloop - it means without for. - furas
if you have event MOUSEBUTTONDOWN then you have mouse position in event.pos - furas
@furas I removed the for loop before "screen.blit(laser_image,[mouse_x + laser_x_vector,mouse_y + laser_x_vector])" but it only gave me the laser image, not the moving laser image - Ian
as I said 'you will have another problem' :) you have to move laser in while loop but without for i loop. And you have to do after for even loop because MOUSEBUTTONDOWN exists only in single loop/frame - when button change state from 'not-pressed' to 'pressed', but not when you hold it preessed - furas

2 Answers

1
votes

You fill the screen after you blit the lazer, so the lazer will not appear. You should fill before you blit the lazer so the lazer appears.

1
votes

The others have already explained why you don't see the laser. Here's a working solution for you. First I suggest to use pygame.Rects for the positions of the lasers and put them into a list (rects can also be used for collision detection). Then iterate over these positions/rects in the main while loop, update and blit them. I also show you how to remove rects that are off screen.

import pygame


pygame.init()

WHITE = (255, 255, 255)
GREEN = (0, 255, 0)

screen_width = 500
screen_height = 500
screen = pygame.display.set_mode([screen_width, screen_height])

laser_image = pygame.Surface((10, 50))
laser_image.fill(GREEN)
done = False
clock = pygame.time.Clock()
laser_rects = []
laser_velocity_y = -20

while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        elif event.type == pygame.MOUSEBUTTONDOWN:
            # Turn the mouse position into a rect with the dimensions
            # of the laser_image. You can use the event.pos instead
            # of pygame.mouse.get_pos() and pass it as the `center`
            # or `topleft` argument.
            laser_rect = laser_image.get_rect(center=event.pos)
            laser_rects.append(laser_rect)

    remaining_lasers = []
    for laser_rect in laser_rects:
        # Change the y-position of the laser.
        laser_rect.y += laser_velocity_y
        # Only keep the laser_rects that are on the screen.
        if laser_rect.y > 0:
            remaining_lasers.append(laser_rect)
    # Assign the remaining lasers to the laser list.
    laser_rects = remaining_lasers

    screen.fill(WHITE)
    # Now iterate over the lasers rect and blit them.
    for laser_rect in laser_rects:
        screen.blit(laser_image, laser_rect)

    pygame.display.flip()
    clock.tick(30)  # 30 FPS is smoother.


pygame.quit()