Detect when my mouse is on 2 rect and choose the action - python

I don't know how to detect when my mouse is on 2 rect and choose (if two rect has an action) the action. For example, in Windows, when two windows are one over the other, it's the first window that will be selected. I want to do exactly the same thing.
import pygame
class Rectangle(pygame.sprite.Sprite):
def __init__(self, screen, rect, x, y, color, name):
super().__init__()
self.screen = screen
self.name = name
self.screen_str = str(screen)
self.rect = rect
self.color = color
self.x, self.y = x, y
self.r = pygame.Surface((self.rect[2], self.rect[3]), pygame.SRCALPHA)
self.rect = self.r.get_rect()
self.rect.x, self.rect.y = x, y
self.r.fill(self.color)
pygame.init()
screen = pygame.display.set_mode((1280, 720))
pygame.display.set_caption("PyStoneTest")
width, height = screen.get_size()
background_default = "image\Settings\Wallpaper\default_1.jpg"
D = {}
D["Rect2"] = Rectangle(screen, (0, 200, width, 70), 0,
50, (255, 255, 0), "Rect2")
D["Rect1"] = Rectangle(screen, (0, 100, width-200, 200), 0,
100, (255, 0, 255), "Rect1")
Programme = ["Rect1", "Rect2"]
while True:
background = pygame.image.load(background_default).convert()
background = pygame.transform.scale(background, (width, height))
for event in pygame.event.get():
x,y = pygame.mouse.get_pos()
if event.type == pygame.QUIT:
pygame.quit()
for element in Programme:
if D[element].rect.collidepoint(x,y) and event.type == pygame.MOUSEBUTTONDOWN:
del Programme[Programme.index(D[element].name)]
Programme.append(D[element].name)
print(Programme)
screen.blit(background, (0, 0))
for element in Programme:
screen.blit(D[element].r, D[element].rect)
pygame.display.update()

You should first run for-loop to check all windows and use last one which collides with mouse.
elif event.type == pygame.MOUSEBUTTONDOWN:
last = None
for element in Programme:
if D[element].rect.collidepoint(event.pos):
last = element
if last:
Programme.remove(last)
Programme.append(last)
print(Programme)
Or you would have to check in reverse order - from last to first - and break loop on first matching rectangle.
elif event.type == pygame.MOUSEBUTTONDOWN:
last = None
for element in reversed(Programme):
if D[element].rect.collidepoint(event.pos):
last = element
break
if last:
Programme.remove(last)
Programme.append(last)
print(Programme)
Minimal working code with other changes
import pygame
# --- classes ---
class Rectangle(pygame.sprite.Sprite):
# I skip `x,y` because I have it in `rect`
def __init__(self, screen, rect, color, name):
super().__init__()
self.screen = screen
self.color = color
self.name = name
self.rect = pygame.Rect(rect)
self.image = pygame.Surface(self.rect.size, pygame.SRCALPHA)
self.image.fill(self.color)
def draw(self):
self.screen.blit(self.image, self.rect)
# --- functions ---
# empty
# --- main ---
pygame.init()
screen = pygame.display.set_mode((1280, 720))
screen_rect = screen.get_rect() # it can be useful to center elements on screen - `d[name].rect.center = screen_rect.center`
pygame.display.set_caption("PyStoneTest")
# raw string
background_default = r"image\Settings\Wallpaper\default_1.jpg"
# load and rescale before `while`-loop
background = pygame.image.load(background_default).convert()
background = pygame.transform.scale(background, screen_rect.size)
d = {} # PEP8: `lower_case_names` for variable
d["Rect2"] = Rectangle(screen, (0, 0, screen_rect.width-100, 70), (255, 255, 0), "Rect2")
d["Rect2"].rect.center = screen_rect.center
d["Rect1"] = Rectangle(screen, (0, 0, 70, screen_rect.height-100), (255, 0, 255), "Rect1")
d["Rect1"].rect.center = screen_rect.center
programme = ["Rect1", "Rect2"] # PEP8: `lower_case_names` for variable
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit() # to skip rest of while-loop
elif event.type == pygame.MOUSEBUTTONDOWN:
selected = None
for name in programme:
if d[name].rect.collidepoint(event.pos):
selected = name
if selected and selected != programme[-1]:
programme.remove(selected)
programme.append(selected)
print('after replace:', programme)
screen.blit(background, (0, 0))
for name in programme:
d[name].draw()
pygame.display.update()

I cannot help with your code since I cannot understand what you are doing but I can offer my own solution. Since pygame renders thigs that are drawn later on the top, you can change the rendering order of your rectangles by checking which rectangle is being clicked and swapping it with the last rectangle in your list.
Here is an example. The colors in my example change weirdly but that's because I am generating them on the fly just to be able to tell the different between the different rects. You shouldn't have this problem.
import pygame
pygame.init()
screen = pygame.display.set_mode((1280, 720))
pygame.display.set_caption("PyStoneTest")
rects = []
for i in range(10):
rects.append(pygame.Rect(i * 25, 100, 30, 30))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
screen.fill((0, 0, 0))
c = 1
for rect in rects:
pygame.draw.rect(screen, (c, 100, 100), rect)
c += 20
clicked = pygame.mouse.get_pressed()
x,y = pygame.mouse.get_pos()
for rect in rects:
if (rect.collidepoint(x, y) and clicked[0]):
#swap it
rects[-1][:], rect[:] = rect[:], rects[-1][:]
pygame.display.update()

Related

How to create different layer of background for pygame packed into one class

I'm really new to pygame and Python classes. I tried to create a game with different layers.
Layer 1: gameplay
Layer 2: HP: Position:...
It looks a little bit like this:
I think the problem with my code is that i did not know how to use class properly. And I use the wrong method to create a layer for my game.
import pygame
from pygame.locals import *
import sys
pygame.init()
colors = [(255, 255, 255), (204, 229, 255), (0, 0, 0)] #white, light_blue, black
X_AXIS = [x for x in range(11)]
Y_AXIS = ("X A B C D E F G H I").split()
class character:
pass
class Gameplay:
def __init__(self, width, height):
self.width = width
self.height = height
self.display = pygame.display.set_mode((self.width, self.height))
logo = pygame.image.load(r'logo.png')
pygame.display.set_caption("Battle Royale")
pygame.display.set_icon(logo)
def background_layer(self):
self.game_surf = pygame.surface.Surface((800,600))
game_surf.fill(colors[0])
display.blit(game_surf, (0, 0))
gameplay = Gameplay(1300, 760)
while True:
gameplay.background_layer()
for event in pygame.event.get():
if event.type == MOUSEBUTTONDOWN:
pass
elif event.type == QUIT:
pygame.quit()
sys.exit()
First few mistakes:
You forgot self. in few places and it should gives you error messages (but you didn't mention it).
You forgot pygame.display.flip() to send from buffer to screen.
If you want other layers then you should add other functions to draw them.
At this moment I see only def background_layer() but you could add other functions for other layers and later execute them in loop - like this:
while True:
self.draw_background()
self.draw_player()
self.draw_grid()
self.draw_info()
pygame.display.flip()
for event in pygame.event.get():
# ... code ...
Minimal working code with other changes.
import sys
import pygame
# --- constants ---- # PEP8: `UPPER_CASE_NAMES` for constants
COLORS = [(255, 255, 255), (204, 229, 255), (0, 0, 0)] #white, light_blue, black
X_AXIS = list(range(11))
Y_AXIS = list("XABCDEFGHI")
# --- classes --- # PEP8: `CamelCaseNames` for classes
class Character:
pass
class Game:
def __init__(self, width, height):
self.width = width
self.height = height
pygame.init()
self.display = pygame.display.set_mode((self.width, self.height))
#self.display_rect = self.display.get_rect()
pygame.display.set_caption("Battle Royale")
#logo = pygame.image.load(r'logo.png')
#pygame.display.set_icon(logo)
self.layer_background = pygame.surface.Surface((800, 600))
self.layer_background.fill(COLORS[0])
self.layer_background_rect = self.layer_background.get_rect()
self.pos = 'X0'
self.hp = 100
self.font = pygame.font.SysFont(None, 40)
def draw_background(self):
self.display.blit(self.layer_background, self.layer_background_rect)
def draw_grid(self):
for x in range(0, 800, 50):
pygame.draw.line(self.display, COLORS[2], (x, 0), (x, 600))
for y in range(0, 600, 50):
pygame.draw.line(self.display, COLORS[2], (0, y), (800, y))
def draw_info(self):
text_image = self.font.render(f"POS: {self.pos}", False, COLORS[0])
text_rect = text_image.get_rect(x=880, y=350)
self.display.blit(text_image, text_rect)
text_image = self.font.render(f"HP: {self.hp}", False, COLORS[0])
text_rect = text_image.get_rect(x=880, y=450)
self.display.blit(text_image, text_rect)
def run(self):
while True:
self.draw_background()
#self.draw_player()
self.draw_grid()
self.draw_info()
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
pass
elif event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# --- functions --- # PEP8: `lower_case_names` for functions
# empty
# --- main ---
game = Game(1300, 760)
game.run()

I'n creating my first game in pygame and i need help on showing up a screen when i press any key [duplicate]

This question already has answers here:
Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?
(1 answer)
Why is my PyGame application not running at all?
(2 answers)
Closed 1 year ago.
As i mention, i'm super new in pygame and need help with this. I'm just testing the pygame commands, and want to show up a white screen with a message whenever i initialize the game and press any key, but apparently, it's not working. Here's my code:
# pygame template
import pygame
# import random
WIDTH = 400
HEIGHT = 500
FPS = 60
TITLE = 'My Game'
FONT_NAME = 'SNAKE/DinoTopia.ttf'
# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# initialize pygame and create window
pygame.init()
pygame.mixer.init()
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(TITLE)
CLOCK = pygame.time.Clock()
# classes
class Main:
def __init__(self):
self.running = False
self.game_font = pygame.font.match_font(FONT_NAME)
def show_screen(self):
if self.running is True:
SCREEN.fill(WHITE)
self.draw_text('HELLO', 50, WIDTH/2, HEIGHT/2, BLUE)
pygame.display.flip()
self.wait_for_key()
def wait_for_key(self):
for key in pygame.event.get():
if key.type == pygame.KEYUP:
self.running = True
self.show_screen()
def draw_text(self, text, size, x, y, color):
font = pygame.font.Font(self.game_font, size)
text_surface = font.render(text, True, color)
text_rect = text_surface.get_rect()
text_rect.center = (x, y)
SCREEN.blit(text_surface, text_rect)
g = Main()
# game loop
running = True
while running:
# keep loop running at the right speed
CLOCK.tick(FPS)
# process input
for event in pygame.event.get():
# check for closing window
if event.type == pygame.QUIT:
running = False
# update
# draw/ render
SCREEN.fill(BLACK)
g.wait_for_key()
# *after* drawing everything, flip the display
pygame.display.flip()
pygame.quit()
i know something may be wrong with the wait_for_key function but i can't see what it is, so a little help would be nice! thanks in advance!
show screen function is only called when a key is up. A single frame. You have to call it every frame. Also don't call pygame.event.get and pygame.display.flip more than once.
# pygame template
import pygame
# import random
WIDTH = 400
HEIGHT = 500
FPS = 60
TITLE = 'My Game'
FONT_NAME = 'SNAKE/DinoTopia.ttf'
# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# initialize pygame and create window
pygame.init()
pygame.mixer.init()
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(TITLE)
CLOCK = pygame.time.Clock()
# classes
class Main:
def __init__(self):
self.running = False
self.game_font = pygame.font.match_font(FONT_NAME)
def show_screen(self):
if self.running:
SCREEN.fill(WHITE)
self.draw_text('HELLO', 50, WIDTH/2, HEIGHT/2, BLUE)
def wait_for_key(self, events):
for event in events:
if event.type == pygame.KEYUP:
self.running = True
def draw_text(self, text, size, x, y, color):
font = pygame.font.Font(self.game_font, size)
text_surface = font.render(text, True, color)
text_rect = text_surface.get_rect()
text_rect.center = (x, y)
SCREEN.blit(text_surface, text_rect)
g = Main()
# game loop
running = True
while running:
# keep loop running at the right speed
CLOCK.tick(FPS)
# process input
events = pygame.event.get()
for event in events:
# check for closing window
if event.type == pygame.QUIT:
running = False
# update
# draw/ render
SCREEN.fill(BLACK)
g.wait_for_key(events)
g.show_screen()
# *after* drawing everything, flip the display
pygame.display.flip()
pygame.quit()

Delete draw when clicking

I did a lot of research on how to delete a drawing on the screen after clicking it, and I couldn't do that
Try1 how to remove draw objects from pygame window?
Try2 How to remove a drawn circle in pygame? (without "going over" other things)
When clicked on the circle it will remove itself, and thus create another circle to be able to click.
import pygame, sys
from pygame.locals import *
from pygame import mixer
pygame.init()
musica = 'circles.mp3'
mixer.music.load(musica)
mixer.music.play()
pygame.init()
screen = pygame.display.set_mode((500, 500))
pygame.display.set_caption("OSU DA DEEP WEB")
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
screen.fill(WHITE)
#posição
width = 500 -30
height = 500 - 30
widthposition = random.randrange(width)
heightposition = random.randrange(width)
#sistema de pontos
points = 0
circle = pygame.draw.circle(screen, (0, 0, 0), (400, 300), 25)
def draw():
print('CLicked')
circle = pygame.draw.circle(screen, (0, 0, 0), (400, 300), 25)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
pygame.display.flip()
You have to check event to catch when left button was click and then you can draw white background and draw circle
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == pygame.BUTTON_LEFT:
screen.fill(WHITE)
draw(screen)
But this still doesn't check if you clicked on circle.
Minimal working code.
import sys
import random
import pygame
# --- constants ---
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
WIDTH = 500
HEIGHT = 500
# --- functions ---
def draw(screen):
print('Clicked')
x = random.randrange(30, WIDTH-30)
y = random.randrange(30, HEIGHT-30)
pygame.draw.circle(screen, (0, 0, 0), (x, y), 25)
# --- main ---
musica = 'circles.mp3'
pygame.init()
pygame.mixer.music.load(musica)
pygame.mixer.music.play()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen.fill(WHITE)
draw(screen)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == pygame.BUTTON_LEFT:
screen.fill(WHITE)
draw(screen)
pygame.display.flip()
draw.circle gives object pygame.Rect() with rectangle area used by circle and you could use it to "check collision" with mouse position
circle_rect = pygame.draw.circle(...)
#... code ...
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == pygame.BUTTON_LEFT:
if circle_rect.collidepoint(even.pos):
screen.fill(WHITE)
draw(screen)
and it check position in rectangle area so it works better but not ideal
import sys
import random
import pygame
# --- constants ---
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
WIDTH = 500
HEIGHT = 500
# --- functions ---
def draw(screen):
print('Clicked')
x = random.randrange(30, WIDTH-30)
y = random.randrange(30, HEIGHT-30)
circle_rect = pygame.draw.circle(screen, (0, 0, 0), (x, y), 25)
return circle_rect
# --- main ---
musica = 'circles.mp3'
pygame.init()
pygame.mixer.music.load(musica)
pygame.mixer.music.play()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen.fill(WHITE)
circle_rect = draw(screen)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == pygame.BUTTON_LEFT:
if circle_rect.collidepoint(event.pos):
screen.fill(WHITE)
circle_rect = draw(screen)
pygame.display.flip()
There is function to check collicion in cicle area but it works for two pygame.sprite.Sprite, not for single pygame.Rect and mouse position (single point). You would have to convert mouse position and pygame.Rect to pygame.sprite.Sprite but it is to complex for this problem.
Doc: pygame.sprite.collide_circle()
OR you can use pygame.math.Vector2.distance_to() to calculate distance between mouse position and center of circle - it has to be equal or smaller then 25
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == pygame.BUTTON_LEFT:
pos = pygame.math.Vector2(event.pos)
if pos.distance_to(circle_rect.center) <= 25:
screen.fill(WHITE)
circle_rect = draw(screen)
import sys
import random
import pygame
# --- constants ---
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
WIDTH = 500
HEIGHT = 500
# --- functions ---
def draw(screen):
print('Clicked')
x = random.randrange(30, WIDTH-30)
y = random.randrange(30, HEIGHT-30)
circle_rect = pygame.draw.circle(screen, (0, 0, 0), (x, y), 25)
return circle_rect
# --- main ---
musica = 'circles.mp3'
pygame.init()
pygame.mixer.music.load(musica)
pygame.mixer.music.play()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen.fill(WHITE)
circle_rect = draw(screen)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == pygame.BUTTON_LEFT:
pos = pygame.math.Vector2(event.pos)
if pos.distance_to(circle_rect.center) <= 25:
screen.fill(WHITE)
circle_rect = draw(screen)
pygame.display.flip()
EDIT:
If you will want to add other object which will move then you will have to organize it in different way. In while True in every loop you will have to clear screen and draw again all object. And this needs more changes
import sys
import random
import pygame
# --- constants ---
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = ( 0, 255, 0)
BLUE = ( 0, 0, 255)
WIDTH = 500
HEIGHT = 500
FPS = 25
# --- classes ---
class Circle():
def __init__(self, x, y, r, color, random=False):
self.x = x
self.y = y
self.r = r
self.color = color
# vector to check collision
self.center = pygame.math.Vector2((x, y))
if random:
self.set_random_position()
def draw(self, screen):
#pygame.draw.circle(screen, self.color, (self.x, self.y), self.r)
pygame.draw.circle(screen, self.color, self.center, self.r)
def check_collision(self, position):
return self.center.distance_to(position) <= self.r
def set_random_position(self):
self.x = random.randint(30, WIDTH-30) # `randint` better then `randrange`
self.y = random.randint(30, HEIGHT-30) # `randint` better then `randrange`
# vector to check collision
self.center = pygame.math.Vector2(self.x, self.y)
def move_random(self):
dx = random.randint(-5, 5) # `randint` better then `randrange`
dy = random.randint(-5, 5) # `randint` better then `randrange`
self.x += dx
self.y += dy
if self.x < self.r:
self.x = self.r
if self.x > WIDTH-self.r:
self.x = WIDTH-self.r
if self.y < self.r:
self.y = self.r
if self.y > HEIGHT-self.r:
self.y = HEIGHT-self.r
self.center = pygame.math.Vector2(self.x, self.y)
# --- functions ---
# ... empty ...
# --- main ---
musica = 'circles.mp3'
pygame.init()
#pygame.mixer.music.load(musica)
#pygame.mixer.music.play()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
# create circle
circle = Circle(0, 0, 25, RED, random=True)
# create other objects and keep on list
others = [Circle(0, 0, 10, GREEN, random=True) for _ in range(100)]
clock = pygame.time.Clock()
while True:
# - events - (without draws)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == pygame.BUTTON_LEFT:
if circle.check_collision(event.pos):
# only change `x,y` without drawing
circle.set_random_position()
# - updates - (without draws)
# move other objects from list
for item in others:
item.move_random()
# - draws - (without events and updates)
# clear screen
screen.fill(WHITE)
# draw circle
circle.draw(screen)
# draw other objects from list
for item in others:
item.draw(screen)
# send on monitor
pygame.display.flip()
# - FPS -
# to keep the same speed on different computers (with different CPU speed)
clock.tick(FPS)

How to Fill a rectangle with color every time the user clicks it? pygame

I know that there are several similar questions online, but none of them really helped me. I simply want to draw a grid and give the user the option to click into those grid cells. Every time the user clicks, the color/fill of the cell should change from black to white.
What I'm doing at the moment is the following:
BLACK = (0, 0, 0)
WHITE = (200, 200, 200)
def drawGrid(h, w, blocksize):
for x in range(w):
for y in range(h):
rect = pygame.Rect(x*blocksize, y*blocksize,
blocksize, blocksize)
pygame.draw.rect(SCREEN, WHITE, rect, 1)
def handle_events():
col = WHITE
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == MOUSEBUTTONDOWN:
col = WHITE
# determine mouse position
mpos_x, mpos_y = event.pos
# determine cell number
coord = mpos_x // blocksize, mpos_y // blocksize
rect = pygame.Rect(coord[0]*blocksize, coord[1]*blocksize,
blocksize, blocksize)
pygame.draw.rect(SCREEN, col, rect, 1)
pygame.display.update()
def main():
global SCREEN, CLOCK, blocksize
w = int( sys.argv[1] )
h = int( sys.argv[2] )
blocksize = int( sys.argv[3] )
pygame.init()
SCREEN = pygame.display.set_mode((h, w))
CLOCK = pygame.time.Clock()
SCREEN.fill(BLACK)
drawGrid(h,w,blocksize)
handle_events()
if __name__ == "__main__":
main()
The program is printing the grid. However, when I click somewhere nothing happens. I know this is not the best code, so I would appreciate for any suggestion.
I changed the code a little and it worked properly, pygame.draw.rect(SCREEN, col, rect, 1) you draw same thing and you can't see the change. You should use pygame.draw.rect(SCREEN, col, rect):
import pygame
import sys
BLACK = (0, 0, 0)
WHITE = (200, 200, 200)
# WINDOW_HEIGHT = 400
# WINDOW_WIDTH = 400
def drawGrid(h, w, blocksize):
#blockSize = 20 #Set the size of the grid block
for x in range(w):
for y in range(h):
rect = pygame.Rect(x*blocksize, y*blocksize,
blocksize, blocksize)
pygame.draw.rect(SCREEN, WHITE, rect, 1)
def handle_events():
#coords_list = []
col = WHITE
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
col = WHITE
# determine mouse position
mpos_x, mpos_y = event.pos
# determine cell number
coord = mpos_x // 32, mpos_y // 32
rect = pygame.Rect(coord[0]*32, coord[1]*32,
32, 32)
pygame.draw.rect(SCREEN, col, rect)
#coords_list.append(coord)
pygame.display.update()
#return coords_list
def main():
global SCREEN, CLOCK, blocksize
pygame.init()
SCREEN = pygame.display.set_mode((480, 640))
CLOCK = pygame.time.Clock()
SCREEN.fill(BLACK)
drawGrid(480,640,32)
handle_events()
if __name__ == "__main__":
main()
As a suggestion, I think you should use sprite for every cell. For example like this:
class Cell(pygame.sprite.Sprite):
def __init__(self, sprite_group, x, y, cell_dimension, color=BLACK):
self.groups = sprite_group
pygame.sprite.Sprite.__init__(self, self.groups)
self.image = pygame.Surface((cell_dimension, cell_dimension))
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x * cell_dimension
self.rect.y = y * cell_dimension
self.clicked = False
def update(self):
if self.clicked:
self.image.fill(WHITE)

Move polygon with move_ip in pygame

I can't get to move a polygon with the function move_ip() in pygame, the code works good if I draw a rectangle, but not with polygon. It doesn't respond when I press any arrow key.
I think I don't need spaceship rectangle because polygons are rects with pygame, but it seems not right, I don't know, i've got a mess.
This is my pygame code:
import sys, os
import pygame
from pygame.locals import *
import numpy as np
if sys.platform in ["win32","win64"]: os.environ["SDL_VIDEO_CENTERED"]='1'
width_screen = 600
height_screen = 480
screen_size = (width_screen, height_screen)
positionx_screen = 0
positiony_screen = 32
title_window = 'ASTEROIDS'
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
spaceship = pygame.Rect(200, 475, 120, 20)
def quit_screen(event):
if event.type == QUIT:
pygame.quit()
sys.exit()
class Spaceship():
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.colour = WHITE
self.thickness = 0
self.movex = 20
def draw_nave(self):
vertices = np.array([[screen_size[0]/2, screen_size[1] /2 - 30],[screen_size[0]/2 + 15, screen_size[1]/2],
[screen_size[0]/2-15, screen_size[1] / 2]])
pygame.draw.polygon(screen_game, self.colour, vertices, self.thickness)
def move_spaceship_right(self):
spaceship.move_ip(self.movex, 0)
def move_spaceship_left(self):
spaceship.move_ip(- self.movex, 0)
def game():
pygame.init()
running = True
global screen_game
screen_game = pygame.display.set_mode(screen_size,
positionx_screen, positiony_screen)
pygame.display.set_caption(title_window)
clock = pygame.time.Clock()
my_spaceship = Spaceship(200, 475, 120, 20)
screen_game.fill(BLACK)
while running:
screen_game.fill(BLACK)
for event in pygame.event.get():
quit_screen(event)
if event.type == pygame.KEYDOWN:
if event.key == K_RIGHT:
my_spaceship.move_spaceship_right()
if event.key == K_LEFT:
my_spaceship.move_spaceship_left()
my_spaceship.draw_nave()
pygame.display.flip()
clock.tick(60)
if __name__ == "__main__":
try:
game()
except:
pygame.quit()
Thanks
The problem is that your Rect is in no way related to the polygon you draw. You simply draw it at the same position every time.
Better create a Surface once, draw your polygon on that Surface once, and use spaceship as position when drawing that new Surface.
I recommend subclassing from Sprite, create that Surface in the __init__ function, and save the Rect in self.rect instead of the spaceship variable.
Then either use the draw function of Sprite or put your Sprite into a Group.

Categories