Right now, my game blits all the images in random positions correctly and also gets the rect of the images correctly, but I can´t figure out how to use colliderect to make sure the images don´t overlap. How could it work for my code?
Also I´m trying to make the first text fade out and I don´t know why it doesn´t work for me.
Here is the code:
class GAME1:
def __init__(self, next_scene):
self.background = pygame.Surface(size)
# Create an array of images with their rect
self.images = []
self.rects = []
self.imagenes1_array = ['autobus.png','coche.png','barco.png','autobus2.png','grua.png','bici.png']
for i in self.imagenes1_array:
# We divide in variables so we can then get the rect of the whole Img (i2)
i2 = pygame.image.load(i)
self.images.append(i2)
s = pygame.Surface(i2.get_size())
r = s.get_rect()
# Trying to use colliderect so it doesnt overlap
if pygame.Rect.colliderect(r,r) == True:
x = random.randint(300,1000)
y = random.randint(200,700)
self.rects.append(r)
def start(self, gamestate):
self.gamestate = gamestate
for rect in self.rects:
# Give random coordinates (we limit the dimensions (x,y))
x = random.randint(300,1000)
y = random.randint(200,700)
rect.x = x
rect.y = y
def draw(self,screen):
self.background = pygame.Surface(size)
font = pygame.font.SysFont("comicsansms",70)
# First half (Show image to remember)
text1 = font.render('¡A recordar!',True, PURPLE)
text1_1 = text1.copy()
# This surface is used to adjust the alpha of the txt_surf.
alpha_surf = pygame.Surface(text1_1.get_size(), pygame.SRCALPHA)
alpha = 255 # The current alpha value of the surface.
if alpha > 0:
alpha = max(alpha-4, 0)
text1_1 = text1.copy()
alpha_surf.fill((255, 255, 255, alpha))
text1_1.blit(alpha_surf, (0,0), special_flags = pygame.BLEND_RGBA_MULT)
screen.blit(text1_1, (600,50))
# Second half (Show all similar images)
text2 = font.render('¿Cuál era el dibujo?',True, PURPLE)
#screen.blit(text2, (500,50))
for i in range(len(self.images)):
#colliding = pygame.Rect.collidelistall(self.rects)
screen.blit(self.images[i], (self.rects[i].x, self.rects[i].y))
def update(self, events, dt):
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN:
for rect in self.rects:
if rect.collidepoint(event.pos):
print('works!')
Use collidelist() to test test if one rectangle in a list intersects:
for i in self.imagenes1_array:
s = pygame.image.load(i)
self.images.append(s)
r = s.get_rect()
position_set = False
while not position_set:
r.x = random.randint(300,1000)
r.y = random.randint(200,700)
margin = 10
rl = [rect.inflate(margin*2, margin*2) for rect in self.rects]
if len(self.rects) == 0 or r.collidelist(rl) < 0:
self.rects.append(r)
position_set = True
See the minimal example, that uses the algorithm to generate random not overlapping rectangles:
import pygame
import random
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
def new_recs(rects):
rects.clear()
for _ in range(10):
r = pygame.Rect(0, 0, random.randint(30, 40), random.randint(30, 50))
position_set = False
while not position_set:
r.x = random.randint(10, 340)
r.y = random.randint(10, 340)
margin = 10
rl = [rect.inflate(margin*2, margin*2) for rect in rects]
if len(rects) == 0 or r.collidelist(rl) < 0:
rects.append(r)
position_set = True
rects = []
new_recs(rects)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.KEYDOWN:
new_recs(rects)
window.fill(0)
for r in rects:
pygame.draw.rect(window, (255, 0, 0), r)
pygame.display.flip()
pygame.quit()
exit()
Related
I'm making a minesweeper game using python. I have the game working in a text only form and I'm adding a GUI now.
I have three difficulty options with different dimensions. Is there any way to generate a grid without having to make it manually. This is how I generated a square matrix in text form:
for count in range(side):
count2 = 0
temp1 = []
temp2 = []
for count2 in range(side):
temp1.append(0)
temp2.append("x")
grid.append(temp1)
field.append(temp2)
count+=1
Is there any way to automatically generate a grid like this in pygame? I am also using custom sprites and every cell needs to be clickable. Will I just have to make the grids manually and use them according to the difficulty?
I came across a similar issue, here is the solution I found worked well and is fairly simple to implement.
gridstate = {}
class Button:
def __init__(self, x, y, w, h, *get_co, action=False):
self.x = x
self.y = y
self.w = w
self.h = h
self.get_co = get_co
self.colour = (255, 255, 255)
self.clicked = False
self.box = py.draw.rect(screen, self.colour, (x, y, w, h))
self.action = action
def draw(self):
pos = py.mouse.get_pos()
if self.box.collidepoint(pos):
if py.mouse.get_pressed()[0] == 1 and self.clicked == False:
self.clicked = True
if self.action == False:
self.action = True
self.colour = (255, 0, 0)
elif self.action == True:
self.action = False
self.colour = (255, 255, 255)
if py.mouse.get_pressed()[0] == 0:
self.clicked = False
self.box = py.draw.rect(screen, self.colour,
(self.x, self.y, self.w, self.h))
gridstate.update({self.get_co: self.action})
return self.action
I created the class for the button as above, this accepts the argument "get_co" to which I put the 'co ordinate' relative to the rest of the grid so I am able to identify which button was pressed. I pass in the data in like so - This creates a 10x10 grid
resx = 10
resy = 10
buttonsize = 25
grid = []
for x in range(resx):
for y in range(resy):
grid.append(Button((x*buttonsize), (y*buttonsize),
buttonsize, buttonsize, x, y))
Within the loop of game I simply run
activecells = []
for key, value in gridstate.items():
if value == True:
activecells.append(key)
To find the clicked buttons and add them to a list to reference later.
for row in grid:
row.draw()
To draw the grid to the screen.
This seemed to do the trick for me. Apologies ahead of time for any actual programmers who will probably be horrified by my variable naming!
There is no simple solution to draw a grid. You have to loop over each cell as you did in your example. You can find all functions to draw in the pygame wiki.
Example for grid creation:
size = (100, 100)
cell_width = 10
cell_height = 10
grid_surface = pygame.Surface(size) # here you draw
grid = [] # simple list to save your data
for x in range(side):
grid.append([]) # new column for the list
for y in range(side):
# save data to grid
grid[x][y] = "x"
# draw something
# e.g.: this draws a red rectangle in each cell
pygame.draw.rect(grid_surface, (200, 0, 0), (x * cell_width, y * cell_height, cell_width, cell_height)
Potential event loop:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
x, y = (event.pos[0] // cell_width, event.pos[1] // cell_height)
# do something
print(grid[x][y])
grid[x][y] = "a"
pygame.draw.rect(grid_surface, (0, 200, 0), (x * cell_width, y * cell_height, cell_width, cell_height)
I will give you a very simple start. You should create a class that represents a cell in the grid. Create a matrix of cells to represent your board:
class Cell:
def __init__(self):
self.clicked = False
grid_size = 10
board = [[Cell() for _ in range(grid_size)] for _ in range(grid_size)]
Calculate the index of a cell when the mouse button is clicked and change the attributes in the cell:
for event in pygame.event.get():
# [...]
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
row = event.pos[1] // 20
col = event.pos[0] // 20
board[row][col].clicked = True
Draw the board in 2 nested loops:
for iy, rowOfCells in enumerate(board):
for ix, cell in enumerate(rowOfCells):
color = (64, 64, 64) if cell.clicked else (164, 164, 164)
pygame.draw.rect(window, color, (ix*20, iy*20, 20, 20))
Minimal example:
import pygame
class Cell:
def __init__(self):
self.clicked = False
grid_size = 10
board = [[Cell() for _ in range(grid_size)] for _ in range(grid_size)]
pygame.init()
window = pygame.display.set_mode((200, 200))
clock = pygame.time.Clock()
run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
row = event.pos[1] // 20
col = event.pos[0] // 20
board[row][col].clicked = True
window.fill(0)
for iy, rowOfCells in enumerate(board):
for ix, cell in enumerate(rowOfCells):
color = (64, 64, 64) if cell.clicked else (164, 164, 164)
pygame.draw.rect(window, color, (ix*20+1, iy*20+1, 18, 18))
pygame.display.flip()
pygame.quit()
exit()
Hi I want to make a game with rhombus what I want to fix is that I set the clock to XY and in while true cycles I have function with one built me a cube
I want to create a game with levels on each level a cube will be made again with another random variation of colors. I have not levels method created yet so I want to create a cube with some colors and after a restarting code, It should be another color variation. But I can not fix a blinking.
my code:
import pygame as pg
import random
pg.init()
screen = pg.display.set_mode((500, 800))
clock = pg.time.Clock()
BG_COLOR = pg.Color('black')
WHITE = pg.Color('white')
ORANGE = pg.Color('orange')
BLUE = pg.Color('blue')
RED = pg.Color('red')
PURPLE = pg.Color('purple')
m = 8
def rhumbus(screen,color,plus):
point1=(170, 500-plus)
point2=(350, 500-plus)
point3=(300, 550-plus)
point4=(120, 550-plus)
points=[point1, point2, point3, point4]
return pg.draw.polygon(screen,color, points)
def cube(rando):
plus = -72
old_col = None
for x in range(0,10):
rando = random.choice([RED,ORANGE,RED,BLUE,WHITE])
if rando != old_col:
rhumbus(screen,rando,plus)
plus += 8
old_col = rando
else:
rhumbus(screen,PURPLE,plus)
plus += 8
old_col = rando
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
screen.fill(BG_COLOR)
cube(m)
pg.display.flip()
clock.tick(10)
Instead of choosing a random sequence of colors on each frame, pick them beforehand.
The new make_random_sequence function returns a list chosen randomly from the given sequence, making sure there are no consecutive repeats of the same item (which seemed to be your logic with old_col too?)
You were not actually using the rando parameter given to cube.
Using enumerate to loop over the colors and their indices is shorter than dealing with a plus variable.
import pygame as pg
import random
pg.init()
screen = pg.display.set_mode((500, 800))
clock = pg.time.Clock()
BG_COLOR = pg.Color('black')
WHITE = pg.Color('white')
ORANGE = pg.Color('orange')
BLUE = pg.Color('blue')
RED = pg.Color('red')
PURPLE = pg.Color('purple')
def rhumbus(screen, color, plus):
point1 = (170, 500 - plus)
point2 = (350, 500 - plus)
point3 = (300, 550 - plus)
point4 = (120, 550 - plus)
points = [point1, point2, point3, point4]
return pg.draw.polygon(screen, color, points)
def make_random_sequence(options, n):
seq = []
while len(seq) < n:
choice = random.choice(options)
if seq and choice == seq[-1]: # skip if same as last
continue
seq.append(choice)
return seq
def cube(colors):
for i, color in enumerate(colors):
rhumbus(screen, color, -72 + i * 8)
colors = make_random_sequence([RED, ORANGE, BLUE, WHITE], 8)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
screen.fill(BG_COLOR)
cube(colors)
pg.display.flip()
clock.tick(10)
In my pygame-code, I have a drone that is supposed to follow a flight path.
I used pygame.draw.lines to draw lines between specified points. Now, I have a flight path with 10 points where after each point the path angle changes (a bit like a zigzag). The player can move the drone by pressing the keys.
My goal is to print a warning once the drone deviates from the path, e.g. by +/-30. I have been racking my brain for two days but can't come up with a condition to detect a deviation. I just can't figure out how to approach this.
I can determine the drone's x-coordinate at any time but how do I determine the offset from the path? I have attached an image to visualize my problem.
Edit:
As I am a beginner my code is a mess but when copy-pasting it, I guess only the lines 35-91 are interesting. Thank you for any kind of advice in advance!!
import pygame
import pygame.gfxdraw
import random
import sys
import math
pygame.init()
# Define some colors
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
red_transp = (255,0,0, 150)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
X = 0
Y = 250
#Display
display_width, display_height = 1200, 700
h_width, h_height = display_width/2, display_height/2
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('Game Display')
#Drone Sprite Image Load Function
droneImg_interim = pygame.image.load('drone.png')
droneImg = pygame.transform.scale(droneImg_interim, [50,50])
drone_width, drone_height = droneImg.get_rect().size
#Create 11 Waypoints with the same coordinates
p1=[X, Y]
p2=[X, Y]
p3=[X, Y]
p4=[X, Y]
p5=[X, Y]
p6=[X, Y]
p7=[X, Y]
p8=[X, Y]
p9=[X, Y]
p10=[X, Y]
p11=[X, Y]
pointlist = [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11]
x_min=drone_width
x_max=100
#Setting new x-coordinate for each point
for i in pointlist:
i[0] = random.randrange(x_min, x_max)
x_min+=250
x_max+=250
#Setting new y-coordinate for each point
for i in range(len(pointlist)):
if i == 0:
pointlist[i][1] = random.randrange(200, 400)
else:
prev = pointlist[i-1][1]
pointlist[i][1] = random.randrange(200, prev+100)
#Plotting pointlist on gameDisplay and connecting dots
def flightpath(pointlist):
pygame.draw.lines(gameDisplay, (255, 0, 0), False, pointlist, 2)
def margin(x):
for i in range(len(pointlist)-1):
p1_x = pointlist[i][0]
p2_x = pointlist[i+1][0]
p1_y = pointlist[i][1]
p2_y = pointlist[i+1][1]
distance_x = p2_x - p1_x
distance = math.sqrt((p2_x-p1_x)**2+(p2_y-p1_y)**2)
halfwaypoint_x = math.sqrt((p2_x - p1_x)**2)/2 + p1_x
halfwaypoint_y = math.sqrt((p2_y - p1_y)**2)/2 + p1_y
if p2_y < p1_y:
angle_rad = math.acos(distance_x/distance)
elif p2_y > p1_y:
angle_rad = 0 - math.acos(distance_x/distance)
angle_deg = math.degrees(angle_rad)
rect_width = distance
rect_height = 60
"""
This part of the code is meant for displaying the margins (the rectangles) around the flight path on the display.
marginSize = (rect_width, rect_height)
surface = pygame.Surface(marginSize, pygame.SRCALPHA)
surface.fill((255,0,0,25))
rotated_surface = pygame.transform.rotate(surface, angle_deg)
#new_rect = rotated_surface.get_rect(center = surface.get_rect(center = ((pointlist[i][0], pointlist[i][1]))).center)
new_rect = rotated_surface.get_rect(center = surface.get_rect(center = ((halfwaypoint_x, halfwaypoint_y))).center)
#gameDisplay.blit(rotated_surface, new_rect)
"""
#Placing drone on the screen
def drone(x,y):
rect = droneImg.get_rect ()
rect.center=(x, y)
gameDisplay.blit(droneImg,rect)
def displayMSG(value,ttext,posx,posy):
myFont = pygame.font.SysFont("Verdana", 12)
Label = myFont.render(ttext, 1, black)
Value = myFont.render(str(value), 1, black)
gameDisplay.blit(Label, (posx, posy))
gameDisplay.blit(Value, (posx + 100, posy))
#Main Loop Object
def game_loop():
global X, Y, FThrustX, FThrustY, FDragY, Time
FThrustY = 0
gameExit = False
while not gameExit:
#Event Checker (Keyboard, Mouse, etc.)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
keys = pygame.key.get_pressed() #checking pressed keys
if keys[pygame.K_LEFT]:
X -= 1
if keys[pygame.K_RIGHT]:
X +=1
if keys[pygame.K_DOWN]:
Y += 1
if keys[pygame.K_UP]:
Y -=1
#Display Background Fill
gameDisplay.fill(white)
#Plot flightpath
flightpath(pointlist)
#YS: Determine the position of the mouse
current_pos_x, current_pos_y = pygame.mouse.get_pos()
displayMSG(current_pos_x,'x:',20,665)
displayMSG(current_pos_y,'y:',20,680)
#Plot margin
margin(5)
#Move Drone Object
drone(X,Y)
#Determine the position of the mouse
current_pos_x, current_pos_y = pygame.mouse.get_pos()
#No exceeding of display edge
if X > display_width - drone_width: X = display_width - drone_width
if Y > display_height - drone_height: Y = display_height - drone_height
if X < drone_width: X = drone_width
if Y < drone_height: Y = drone_height
pygame.display.update()
#MAIN
game_loop()
pygame.quit()
sys.exit()
One approach is to find the minimum distance between the center of the drone and the line.
Write the function that calculates the minimum distance from a point to a line segment. To do this, use pygame.math.Vector2 and the Dot product:
def distance_point_linesegment(pt, l1, l2):
LV = pygame.math.Vector2(l2[0] - l1[0], l2[1] - l1[1])
PV = pygame.math.Vector2(pt[0] - l1[0], pt[1]- l1[1])
dotLP = LV.dot(PV)
if dotLP < 0:
return PV.length()
if dotLP > LV.length_squared():
return pygame.math.Vector2(pt[0] - l2[0], pt[1]- l2[1]).length()
NV = pygame.math.Vector2(l1[1] - l2[1], l2[0] - l1[0])
return abs(NV.normalize().dot(PV))
Find the line segment with the shortest distance in a loop:
def minimum_distance(pt, pointlist):
min_dist = -1
for i in range(len(pointlist)-1):
dist = distance_point_linesegment(pt, pointlist[i], pointlist[i+1])
if i == 0 or dist < min_dist:
min_dist = dist
return min_dist
Create an alert when the distance exceeds a certain threshold:
def game_loop():
# [...]
while not gameExit:
# [...]
dist_to_path = minimum_distance((X, Y), pointlist)
if dist_to_path > 25:
pygame.draw.circle(gameDisplay, (255, 0, 0), (X, Y), 25, 4)
drone(X,Y
# [...]
Another possible solution is to use pygame.Rect.clipline and detect the collision of the line segments and the rectangle surrounding the drone:
def intersect_rect(rect, pointlist):
for i in range(len(pointlist)-1):
if rect.clipline(pointlist[i], pointlist[i+1]):
return True
return False
def game_loop():
# [...]
while not gameExit:
# [...]
if not intersect_rect(droneImg.get_rect(center = (X, Y)), pointlist):
pygame.draw.circle(gameDisplay, (255, 0, 0), (X, Y), 25, 4)
drone(X,Y
# [...]
The interesting part of the question is of course finding the nearest point on the desired path to the actual position; distance is easy. The hard part of that is in turn identifying the nearest element (line segment) of the path; projecting onto it is also straightforward.
If the path is simple enough (in particular, if it doesn’t branch and it’s impossible/disallowed to skip sections at a self-intersection), you can finesse that part by just maintaining that current element in a variable and updating it to the previous or next element when the projection onto one of them is closer than the projection onto the current one. This is a typical algorithm used by racing games to determine the instantaneous order of racers.
Why do bodies in pymunk keep colliding without actually touching each other even after the position and body shape is correctly set?
You will see from my code below that the bird keeps colliding with the ball without actually touching the ball.
import pygame, pymunk
pygame.init()
WIDTH, HEIGHT = 900, 500
win = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption("Flappy OBJ")
color = (255,255,255)
win.fill(color)
fps = 120
fb_img = pygame.image.load("images/flappy-bird.png")#.convert()
fb_img = pygame.transform.rotate(pygame.transform.scale(fb_img, (30,20)), 0)
ball_img = pygame.image.load("images/ball.png")#.convert()
ball_img = pygame.transform.rotate(pygame.transform.scale(ball_img, (60,60)), 0)
def bird_body():
body = pymunk.Body(1, 100, body_type=pymunk.Body.DYNAMIC)
body.position = (50, 0)
shape = pymunk.Poly.create_box(body, (30,20))
space.add(body, shape)
return shape
def ball_body():
body = pymunk.Body(1, 100, body_type = pymunk.Body.KINEMATIC)
body.position = (500, 300)
body.velocity = (-25,0)
shape = pymunk.Circle(body, 60)
shape.color = (0,255,255, 128)
space.add(body, shape)
return shape
space = pymunk.Space()
space.gravity = (0, 20)
fb_body = bird_body()
b_body = ball_body()
def draw_window():
global scroll
win.fill(color)
space.step(0.03)
win.blit(ball_img, (b_body.body.position.x, b_body.body.position.y))
win.blit(fb_img, (fb_body.body.position.x, fb_body.body.position.y))
pygame.display.update()
def main():
w_was_down = True
clock = pygame.time.Clock()
run = True
while run:
clock.tick(fps)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys_pressed = pygame.key.get_pressed()
if keys_pressed[pygame.K_w]:
if not w_was_down:
fb_body.body.apply_impulse_at_local_point((0,-50))
w_was_down = True
else:
w_was_down = False
draw_window()
pygame.quit()
main()
Tap w to move the bird up. some more details some more details some more details
The 2nd argument of pymunk.Circle is the radius, but not the diameter:
shape = pymunk.Circle(body, 60)
shape = pymunk.Circle(body, 30)
And the position of the pymuk object is the center of the object:
win.blit(ball_img, (b_body.body.position.x, b_body.body.position.y))
win.blit(fb_img, (fb_body.body.position.x, fb_body.body.position.y))
win.blit(ball_img, (b_body.body.position.x-30, b_body.body.position.y-30))
win.blit(fb_img, (fb_body.body.position.x-15, fb_body.body.position.y-10))
I am a beginner programmer trying to build tetris in Python using Pygame. The problem is that I am unable to make my test shape fall. Only go up. When I attempt to make the shape fall, the program gives me an
IndexError: list assignment index out of range
I was wondering if I could please get help? The code is listed as follows.
import pygame, sys
from pygame.locals import *
import base64
from TetrisFont import Tetrisfont
from RGBTitle import RGBTitle
from TetrisLogo import logo
from BSOD import Cancer
from BSODFont import Death
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
DOWN = pygame.USEREVENT
class Game:
def __init__(self):
self.running = True
def run(self):
# The main gameplay loop
self.load_assets()
self.initialize_game()
clock = pygame.time.Clock()
while self.running:
self.handle_events()
self.update(clock.tick())
self.draw()
def handle_events(self):
for event in pygame.event.get():
if event.type == DOWN:
for ix, x in enumerate(self.grid):
for iy, y in enumerate(self.grid[0]):
print (y, end='')
print('') # create a new line
for x in range(len(self.grid)):
for y in range(len(self.grid[0])):
if self.grid[x][y] == True:
self.grid[x][y]= False
self.grid[x][y+1] = True
# print(x, y+1)
if event.type == QUIT:
self.running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
def draw(self):
# Handle game rendering
self.windowSurface.fill(BLACK)
pygame.draw.rect(self.windowSurface,WHITE,(550,0, 250, 600), 2)
for x in range(0,600,50):
pygame.draw.line(self.windowSurface,WHITE,(1,x),(550,x), 2)
pygame.draw.line(self.windowSurface,WHITE,(x,1),(x,550), 2)
self.title.render(self.windowSurface)
for x in range(len(self.grid)):
for y in range(len(self.grid[0])):
if self.grid[x][y] == True:
# draw a block in the right place
# render_rect(X * 50, Y * 50, )
pygame.draw.rect(self.windowSurface, RED, (x*50+2, y*50+2, 48, 48))
pygame.display.update()
def update(self, deltaTime):
pass
def load_assets(self):
# Load assets needed for the game. This should only be called once.
pygame.init()
pygame.time.set_timer(DOWN, 500)
with open('Tetrisfont.ttf', 'wb') as imagef:
imagef.write(base64.b64decode(Tetrisfont))
self.Font = pygame.font.Font('Tetrisfont.ttf', 48)
with open('Logo.png', 'wb') as imagef:
imagef.write(base64.b64decode(logo))
with open('BSODFont.ttf', 'wb') as imagef:
imagef.write(base64.b64decode(Death))
self.BSODFont = pygame.font.Font('BSODFont.ttf', 48)
with open('BSOD.png', 'wb') as imagef:
imagef.write(base64.b64decode(Cancer))
self.windowSurface = pygame.display.set_mode((800, 600), 0, 32)
pygame.display.set_caption('Tetris')
self.a = pygame.image.load('Logo.png')
pygame.display.set_icon(self.a)
def initialize_game(self):
# Set up the board for play. This can happen multiple times to restart the game.
self.score = 0
self.title = RGBTitle(self.Font, "Tetris", (200, 550), [WHITE, RED, GREEN, BLUE, GREEN, RED])
grid_width = 11
grid_height = 11
self.grid = [[0 for x in range(grid_width)] for y in range(grid_height)]
# self.grid = []
# for x in range(11):
# self.grid.append([False] * 11)
self.grid[5][5] = True
# print(self.grid)
# print(len(self.grid))
# print(len(self.grid[0]))
if __name__ == '__main__':
g = Game()
g.run()
Thank you.
The error is caused, by self.grid[x][y+1] in
for x in range(len(self.grid)):
for y in range(len(self.grid[0])):
if self.grid[x][y] == True:
self.grid[x][y]= False
self.grid[x][y+1] = True
If y is equal self.grid[0]-1, then y+1 is out of range.
Add an additional condition if y+1 < len(self.grid[0]). Furthermore, I recommend to iterate through the grid in reversed() order from the bottom to the top:
for x in range(len(self.grid)):
for y in reversed(range(len(self.grid[0]))):
if self.grid[x][y] == True:
self.grid[x][y] = False
if y+1 < len(self.grid[0]):
self.grid[x][y+1] = True