I am trying to create a basic snake game with Python and I am not familiar with Pygame. I have created a window and I am trying to split that window up into a grid based on the size of the window and a set square size.
def get_initial_snake( snake_length, width, height, block_size ):
window = pygame.display.set_mode((width,height))
background_colour = (0,0,0)
window.fill(background_colour)
return snake_list
What should I add inside window.fill function to create a grid based on width, height, and block_size? Any info would be helpful.
Using the for loop as a reference from the answer: https://stackoverflow.com/a/33963521/9715289
This is what I did when I was trying to make a snake game.
BLACK = (0, 0, 0)
WHITE = (200, 200, 200)
WINDOW_HEIGHT = 400
WINDOW_WIDTH = 400
def main():
global SCREEN, CLOCK
pygame.init()
SCREEN = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
CLOCK = pygame.time.Clock()
SCREEN.fill(BLACK)
while True:
drawGrid()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
def drawGrid():
blockSize = 20 #Set the size of the grid block
for x in range(0, WINDOW_WIDTH, blockSize):
for y in range(0, WINDOW_HEIGHT, blockSize):
rect = pygame.Rect(x, y, blockSize, blockSize)
pygame.draw.rect(SCREEN, WHITE, rect, 1)
How the result looks like:
You can draw rectangles
for y in range(height):
for x in range(width):
rect = pygame.Rect(x*block_size, y*block_size, block_size, block_size)
pygame.draw.rect(window, color, rect)
I assumed that the height and width is the number of blocks.
if you need one pixel gap between rectangles then use
rect = pygame.Rect(x*(block_size+1), y*(block_size+1), block_size, block_size)
To draw snake you can use list and head_color, tail_color
snake = [(0,0), (0,1), (1,1), (1,2), (1,3)]
# head
x, y = snake[0]
rect = pygame.Rect(x*block_size, y*block_size, block_size, block_size)
pygame.draw.rect(window, head_color, rect)
# tail
for x, y in snake[1:]:
rect = pygame.Rect(x*block_size, y*block_size, block_size, block_size)
pygame.draw.rect(window, tail_color, rect)
Related
How can I tell pygame to repeat a small image to fill the screen ? I tried using blit but it only puts one image on the screen and doesn't fill it.
You need to use nested loops to blit the image multiple times like tiles. Get the width and height of the screen and the image with get_size(). Use range to generate the top left positions of the tiles:
screen_w, screen_h = screen.get_size()
image_w, image_h = image.get_size()
for x in range(0, screen_w, image_w):
for y in range(0, screen_h, image_h):
screen.blit(image, (x, y))
Minimal example:
import pygame
pygame.init()
screen = pygame.display.set_mode((300, 200))
image = pygame.image.load('Apple.png')
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
screen.fill((255, 255, 255))
screen_w, screen_h = screen.get_size()
image_w, image_h = image.get_size()
for x in range(0, screen_w, image_w):
for y in range(0, screen_h, image_h):
screen.blit(image, (x, y))
pygame.display.flip()
pygame.quit()
exit()
import pygame
pygame.init()
width = 800
height = 600
running = True
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Dijkstra's Path-Finding Algorithm Solver")
icon = pygame.image.load('icon.jpg')
pygame.display.set_icon(icon)
def title():
button_font = pygame.font.Font('TrajanPro-Regular.otf', 40)
rect_display = button_font.render('Dijkstra Path-Finding Algorithm', True, (255, 255, 255))
# display global total deaths
screen.blit(rect_display, (12, 10))
def title_underline():
# create the button
rect = pygame.Rect(0, 60, 800, 3)
rect_display = pygame.draw.rect(screen, [255, 255, 255], rect)
button_font = pygame.font.Font('TrajanPro-Regular.otf', 100)
rect_display = button_font.render('', True, (255, 255, 255))
# display global total deaths
screen.blit(rect_display, (270, 198))
def grid():
blockSize = 20 #Set the size of the grid block
for x in range(width):
for y in range(height):
rect = pygame.Rect(x*blockSize, y*blockSize, blockSize, blockSize)
pygame.draw.rect(screen, (200,200,200), rect, 1)
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((0, 0, 0))
title()
title_underline()
grid()
pygame.display.update()
I have created a title for my project and I created a grid for which I want to run my application, but the grid is being made in every single x, y location on my screen. But I want the grid to only be made under the title and not over it.
Define the top left coordinates of the grid (grid_x, grid_y) and add the coordinates when constructing the rectangle of a cell. For instance:
def grid():
grid_x = 12
grid_y = 30
blockSize = 20 #Set the size of the grid block
for x in range(width):
for y in range(height):
rect = pygame.Rect(
grid_x + x*blockSize, grid_y + y*blockSize,
blockSize, blockSize)
pygame.draw.rect(screen, (200,200,200), rect, 1)
I created a window with a width and height of 800 pixels using pygame then drew rectangles with size 32 to make the window a 25x25 grid. What I want to do is change the color of the rectangle I click to change.
My Code:
def createGrid():
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 800
BLOCK_SIZE = 32
WHITE = (255,255,255)
pygame.init()
frame = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("PathFinder")
frame.fill(WHITE)
for y in range(SCREEN_HEIGHT):
for x in range(SCREEN_WIDTH):
rect = pygame.Rect(x*BLOCK_SIZE, y*BLOCK_SIZE, BLOCK_SIZE - 1, BLOCK_SIZE - 1)
pygame.draw.rect(frame, (0,250,0), rect)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
First you should create list with all rects and they colors.
Next you should draw all rect inside while loop.
And finally you have to use event.MOUSEBUTTONDOWN to get mouse click and compare mouse position with every rect on list and change color on list.
import pygame
import sys
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 800
BLOCK_SIZE = 32
WHITE = (255,255,255)
pygame.init()
frame = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("PathFinder")
# create list with all rects
all_rects = []
for y in range(0, SCREEN_HEIGHT, BLOCK_SIZE):
row = []
for x in range(0, SCREEN_WIDTH, BLOCK_SIZE):
rect = pygame.Rect(x, y, BLOCK_SIZE-1, BLOCK_SIZE-1)
row.append([rect, (0, 255, 0)])
all_rects.append(row)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
# check which rect was clicked and change its color on list
for row in all_rects:
for item in row:
rect, color = item
if rect.collidepoint(event.pos):
if color == (0, 255, 0):
item[1] = (255, 0, 0)
else:
item[1] = (0, 255, 0)
# draw all in every loop
frame.fill(WHITE)
for row in all_rects:
for item in row:
rect, color = item
pygame.draw.rect(frame, color, rect)
pygame.display.flip()
Eventually you could draw all rects before loop and use event to draw new rect on clicked rect. But you still need list with all rects to check which rect was click and what is its color.
It depends on what your code is intended to do? This example shows how to paint to the primary display surface but doesn't keep track of which colour is where.
import pygame
white = (255, 255, 255)
red = (255, 0, 0)
size = 32
pygame.init()
s = pygame.display.set_mode((800, 800))
s.fill(white)
# press escape to exit example
while True:
e = pygame.event.get()
if pygame.key.get_pressed()[pygame.K_ESCAPE]: break
x = int(pygame.mouse.get_pos()[0] / size) * size
y = int(pygame.mouse.get_pos()[1] / size) * size
if pygame.mouse.get_pressed()[0]:
pygame.draw.rect(s, red, (x, y, size, size), 0)
pygame.display.update()
pygame.time.Clock().tick(60)
pygame.quit()
I'm trying to create an excel document look alike using recursion in pygame. I got the first if statement to fill the top row of the screen, and looking for it to go down by 50 (height of my rectangle) each time and keep going until it hits the edge of my screen again, filling the screen completely. I did another for loop to try this but it stops and misses one rectangle at (0,0), is there any way to do this in one loop so the screen will fill and make a bunch of columns and rows? Thanks.
"""
Recursively draw rectangles.
Sample Python/Pygame Programs
Simpson College Computer Science
http://programarcadegames.com/
http://simpson.edu/computer-science/
"""
import pygame
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
def recursive_draw(x, y, width, height):
""" Recursive rectangle function. """
pygame.draw.rect(screen, BLACK,
[x, y, width, height],
1)
# Is the rectangle wide enough to draw again?
if(x < 750):
# Scale down
x += 150
y = 0
width = 150
height = 50
# Recursively draw again
recursive_draw(x, y, width, height)
if (x < 750):
# Scale down
x += 0
y += 50
width = 150
height = 50
# Recursively draw again
recursive_draw(x, y, width, height)
pygame.init()
# Set the height and width of the screen
size = [750, 500]
screen = pygame.display.set_mode(size)
pygame.display.set_caption("My Game")
# 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
# Set the screen background
screen.fill(WHITE)
# ALL CODE TO DRAW SHOULD GO BELOW THIS COMMENT
recursive_draw(0, 0, 150, 50)
# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Limit to 60 frames per second
clock.tick(60)
# Be IDLE friendly. If you forget this line, the program will 'hang'
# on exit.
pygame.quit()
I'd first add a base case so that the function returns when the bottom of the screen is reached. Add the width to x until the right side is reached and when it is there, increment y += height and reset x = 0 to start drawing the next row.
import pygame
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
def recursive_draw(x, y, width, height):
"""Recursive rectangle function."""
pygame.draw.rect(screen, BLACK, [x, y, width, height], 1)
if y >= 500: # Screen bottom reached.
return
# Is the rectangle wide enough to draw again?
elif x < 750-width: # Right screen edge not reached.
x += width
# Recursively draw again.
recursive_draw(x, y, width, height)
else:
# Increment y and reset x to 0 and start drawing the next row.
x = 0
y += height
recursive_draw(x, y, width, height)
pygame.init()
size = [750, 500]
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()
screen.fill(WHITE)
recursive_draw(0, 0, 150, 50)
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
pygame.display.flip()
clock.tick(60)
pygame.quit()
It would be easier to use nested for loops to draw the grid:
def draw_grid(x, y, width, height, size):
for y in range(0, size[1], height):
for x in range(0, size[0], width):
pygame.draw.rect(screen, BLACK, [x, y, width, height], 1)
I have created a window using
pygame.display.set_mode((width, height),
pygame.OPENGL | pygame.DOUBLEBUF | pygame.RESIZABLE)
Later on in the app I want to be able to ask that window its width and height so I can decide how to process the mouse position.
How do I access the dimensions of that pygame window elsewhere in the program? (event processing loop)
You want to get the surface, then get the size from the surface object.
Using tuple unpacking:
w, h = pygame.display.get_surface().get_size()
You can get the windows size by first getting the display surface. pygame.display.get_surface(), then calling get_width() / get_height() on the surface.
Like this!
surface = pygame.display.get_surface() #get the surface of the current active display
x,y = size = surface.get_width(), surface.get_height()#create an array of surface.width and surface.height
import pygame as pg
def create_window(width, height):
"""create a width x height resizable window/frame"""
win = pg.display.set_mode((width, height), pg.RESIZABLE)
# optional fill bg red, default is black
win.fill((255, 0, 0))
# optional title info
sf = "size x=%s y=%s" % (width, height)
pg.display.set_caption(sf)
# any extra code here ...
# draw a white circle
white = (255, 255, 255)
# center can be fixed or calculated for resize
center = (150, 150)
radius = 100
pg.draw.circle(win, white, center, radius)
pg.display.flip()
return win
pg.init()
width = 300
height = 200
win = create_window(width, height)
# event loop and exit conditions (windows titlebar x click)
while True:
for event in pg.event.get():
if event.type == pg.VIDEORESIZE:
width, height = event.size
# redraw win in new size
win = create_window(width, height)
print(win.get_size()) # test
if event.type == pg.QUIT:
raise SystemExit
Try this out.
Hope it helps.
Adding another answer since I haven't seen this one yet.
screen = pygame.display.set_mode() # Default to screen resolution.
area = screen.get_rect()
We can call get_rect() on screen because it is a surface object. area will be a Rect object, with (0, 0, width, height) information in it.
changed = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit(0)
if event.type == pygame.VIDEORESIZE:
scrsize = event.size # or event.w, event.h
screen = pygame.display.set_mode(scrsize,RESIZABLE)
changed = True
it's almost exactly like this in the comments for pygame.display.init doc page https://www.pygame.org/docs/ref/display.html#comment_pygame_display_update
edited only slightly from 2011-01-25T23:10:35 - Dave Burton thanks dave
gameDisplay = pygame.display.set_mode((800,600))
x=gameDisplay.get_width()
y=gameDisplay.get_height()
You can get the pygame.Surface object associated with the display with pygame.display.get_surface():
window_surface = pygame.display.get_surface()
Each Surface object can be asked for its with and height with get_width() respectively get_height():
window_width = pygame.display.get_surface().get_width()
window_height = pygame.display.get_surface().get_height()
get_size() returns a tuple with the width and height of the window:
window_width, window_height = pygame.display.get_surface().get_size()
get_rect() returns a rectangle the size of the window, always starting at (0, 0):
This can be used to get the center of the display:
window_center = pygame.display.get_surface().get_rect().center
It can even be used to limit the movement of an object to the window area:
object_rect = pygame.Rect(x, y, w, h)
object_rect.clamp_ip(pygame.display.get_surface().get_rect())
Minimal example:
import pygame
pygame.init()
pygame.display.set_mode((200, 200))
clock = pygame.time.Clock()
object_rect = pygame.Rect(pygame.display.get_surface().get_rect().center, (0, 0)).inflate(30, 30)
vel = 5
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
print(pygame.key.name(event.key))
keys = pygame.key.get_pressed()
object_rect.move_ip(
(keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel,
(keys[pygame.K_DOWN] - keys[pygame.K_UP]) * vel)
object_rect.clamp_ip(pygame.display.get_surface().get_rect())
pygame.display.get_surface().fill([64] * 3)
pygame.draw.rect(pygame.display.get_surface(), (255, 0, 0), object_rect)
pygame.display.flip()
pygame.quit()
exit()