Python Forum
Sprite on mouse-button hold
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Sprite on mouse-button hold
#1
I'm working with pygame 1.9.6
I am trying to make a program that displays a translucent sprite only when the left mouse-button is held down.
This sprite is supposed to track with the mouse position, show the background through it, and disappear when the mouse-button is released.

Currently:
It is tracking with the mouse position.
It is stamping a new copy instead of just moving the sprite.
The sprite(s) are not disappearing when the mouse-button is released.
The sprite alpha is not working, they are a solid color.

Here is the complete code. It is relatively short.
import pygame
import sys
from pygame.locals import *

pygame.init()

LTGRAY = (199, 210, 199)
HLIGHT = ( 80, 100,   0)
BLACK  = (  0,   0,   0)

main_surface = pygame.display.set_mode((900, 650), 0, 32)
main_surface.fill(LTGRAY)

clock = pygame.time.Clock()
fps = 30

pygame.draw.line(main_surface, BLACK,
                     (0, 0), (900, 650), 3)
pygame.draw.line(main_surface, BLACK,
                     (900, 0), (0, 650), 3)

class hlight(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((50, 50), flags=pygame.SRCALPHA)
        self.image.fill(HLIGHT)
        self.image.set_alpha(35)
        self.rect = self.image.get_rect()
        
    def update(self, pos):
        self.rect.x, self.rect.y = pos
        
highlights = pygame.sprite.Group()

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        elif pygame.mouse.get_pressed()[0]:
            if len(highlights) == 0:
                highlights.add(hlight())
        elif event.type == pygame.MOUSEBUTTONUP:
            for highlight in highlights:
                highlight.kill()
        
    highlights.update(pygame.mouse.get_pos())
    highlights.draw(main_surface)
    pygame.display.update() 
    
    clock.tick(fps)
Thanks for any help
Reply
#2
1. You are using multi alphas on image. On non alpha image. You use set_alpha. Otherwise use color alpha.
2. You should not kill image and recreate.
3. Only use pygame.mouse.get_pos(). When you need to update every frame.

Example
import pygame
import os

from pygame.sprite import Sprite

class MouseImage(Sprite):
    def __init__(self):
        Sprite.__init__(self)
        self.image = pygame.Surface((50, 50), flags=pygame.SRCALPHA)
        self.fill_image()
        self.rect = self.image.get_rect()

    def fill_image(self):
        color = pygame.Color("gray90")
        color.a = 35
        self.image.fill(color)

    def draw(self, surface):
        surface.blit(self.image, self.rect)

class Example:
    def __init__(self):
        # Center surface on screen. Must be done before creating main surface
        os.environ['SDL_VIDEO_CENTERED'] = '1'
        # Basic pygame setup
        pygame.display.set_caption("Mouse Hold Image")
        self.surface = pygame.display.set_mode((800, 600))
        self.rect = self.surface.get_rect()
        self.clock = pygame.time.Clock()
        self.running = False
        self.delta = 0
        self.fps = 60

        self.mouse_image = MouseImage()
        self.mouse_image_show = False

    def mainloop(self):
        self.running = True
        while self.running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False
                elif event.type == pygame.MOUSEMOTION:
                    if self.mouse_image_show is True:
                        self.mouse_image.rect.center = event.pos
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    if event.button == 1: # left mouse button
                        self.mouse_image_show = True
                        self.mouse_image.rect.center = event.pos
                elif event.type == pygame.MOUSEBUTTONUP:
                    if event.button == 1:
                        self.mouse_image_show = False

            self.surface.fill(pygame.Color("black"))
            if self.mouse_image_show:
                self.mouse_image.draw(self.surface)

            pygame.display.flip()
            self.delta = self.clock.tick(self.fps)

if __name__ == "__main__":
    pygame.init()
    example = Example()
    example.mainloop()
99 percent of computer problems exists between chair and keyboard.
Reply
#3
(Oct-07-2019, 11:34 AM)Windspar Wrote: 2. You should not kill image and recreate.

Thank you, your example was very helpful. I was able to solve all of my problems, save one. I need the sprites to go away when the mouse moves off of them. I think this means that I do need to kill and recreate them elsewhere.
I provided a simplified example. Here is the code that I corrected using your example:
(There is a whole lot more, but this is the important part)
class hlight(pygame.sprite.Sprite):
    def __init__(self, pos, size):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface(size, flags=pygame.SRCALPHA)
        color = pygame.Color(*HLIGHT)
        color.a = 2
        self.image.fill(color)
        self.rect = self.image.get_rect()
        self.rect.x = pos[0]
        self.rect.y = pos[1]

highlights = pygame.sprite.Group()

def clear_highlights():
    for highlight in highlights:
        highlight.kill()
    
def highlight_intersection(selected_cell):
    clear_highlights()
    x = (selected_cell[0] - 2) * cell + offset
    y1 = offset 
    y2 = offset + (selected_cell[1] - 1) * cell
    height = y2 + cell - offset
    width = (max_factor - selected_cell[0] + 2) * cell 
    # Vertical highlight
    highlights.add(hlight((x, y1), (cell, height)))
    # Horizontal highlight
    highlights.add(hlight((x, y2), (width, cell)))
        
selected_cell = None
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        elif pygame.mouse.get_pressed()[0]:
            new_cell = get_cell(pygame.mouse.get_pos())
            if new_cell and new_cell != selected_cell:
                selected_cell = new_cell
                clear_highlights()
                highlights.update()
                highlights.draw(main_surface)
                pygame.display.update()
                if selected_cell:
                    print(selected_cell)
                highlight_intersection(selected_cell)
        elif event.type == pygame.MOUSEBUTTONUP:
            print("Up")
            clear_highlights()
        
    highlights.update()
    highlights.draw(main_surface)
    pygame.display.update()
This image shows that the alpha is now working correctly
[Image: xLggV6d]

However, when I move to another box or release the mouse button, the highlights do not go away.
[Image: hXDTkcJ]

I believe the problem is in the game loop and/or the class code.
Reply
#4
1. This is not a pygame event.
elif pygame.mouse.get_pressed()[0]:
You should be using.
elif event.type == pygame.MOUSEBUTTONDOWN:
    if event.button == 1:
        # rest of code.
2. If you can only highlight one image. Then it doesn't belong in a group.

I would need more code or you explain more what you are doing ?
Sound more like a drag n drop.
99 percent of computer problems exists between chair and keyboard.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyGame] Sprite image.get_rect() moves sprite to 0, 0 michael1789 2 4,551 Dec-13-2019, 08:37 PM
Last Post: michael1789
  Sprite not rendering Clunk_Head 2 2,095 Oct-03-2019, 11:27 AM
Last Post: Clunk_Head
  Need help making a sprite GalaxyCoyote 4 3,184 Aug-11-2019, 09:12 PM
Last Post: metulburr
  moving a sprite pfaber11 3 2,546 May-15-2019, 12:52 PM
Last Post: pfaber11
  [PyGame] Need Help With Sprite ghost0fkarma 2 3,252 Jan-09-2018, 02:14 PM
Last Post: ghost0fkarma

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020