1

I want a line to be drawn and rendered (for a second) when the mouse has been clicked. My example is of a game that shoots a laser or spell etc from the player to an enemy on a mouse click.

My class for the spell:

class Magic():
    def __init__(self, mana=100):
        self.mana = mana
        self.recharge = 1
        self.mana_cost  = 5

    def recharge_rate(self):
        pass

    def magic_render(self,mouse_pos):
        pygame.draw.line(game_display,mg,(player.x,player.y),(mouse_pos),5)
        print('fire')

My game loop:

magic = Magic()
     while run_game == True: # main game loop
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                print('GoodBye')
                run_game = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                magic.magic_render(mouse_pos)

        game_display.fill(bg)
        pygame.display.flip()
        clock.tick(fps)

I cut out other parts of the program, but currently I can move my player around but when I click the mouse, no line is being shown, but if I remove the line game_display.fill(bg), then I can see the line being drawn but it stays there permanently, so I need a way it will appear for a second and still use the Magic class.

brexling
  • 49
  • 3

1 Answers1

1

I'd first give the class an image attribute and during the instantiation call self.start_time = pygame.time.get_ticks() to store the creation time.

Then add the instance to a list (or sprite group if you use a sprite subclass) and call the update method of the sprite each frame. In the update method you have to check if the life time of the instance has expired what you can do in this way: if pygame.time.get_ticks() - self.start_time > 1500:.

If you use sprites you can just call the kill method of the sprite when the time is up and it will be removed from all sprite groups. With a normal class and a list you'd have to iterate over the list and check which instance is still alive.

import pygame as pg


class Spell(pg.sprite.Sprite):

    def __init__(self, pos):
        super().__init__()
        self.image = pg.Surface((5, 120))
        self.image.fill(pg.Color('sienna1'))
        self.rect = self.image.get_rect(center=pos)
        self.start_time = pg.time.get_ticks()

    def update(self):
        # If current time - start time > 1500 milliseconds.
        if pg.time.get_ticks() - self.start_time > 1500:
            self.kill()  # Remove the instance from all sprite groups.


def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()
    all_sprites = pg.sprite.Group()

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            elif event.type == pg.MOUSEBUTTONDOWN:
                all_sprites.add(Spell(event.pos))

        all_sprites.update()
        screen.fill((30, 30, 30))
        all_sprites.draw(screen)

        pg.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()
skrx
  • 19,980
  • 5
  • 34
  • 48
  • You probably also want to know how to rotate a sprite and give it an offset: https://stackoverflow.com/a/42281315/6220679 – skrx Nov 22 '17 at 23:06