Pygame Collision Error - python

I am coding a simple dodging kinda game in pygame, hopefully I will develop it to build something like Asteroids.
I have used .collidelist() to recognize collision with my randomly generated "asteroids". But when the player goes under or above the asteroid, a collision is detected.
# -------------------- COLLISION --------------------
collision = player_rect.collidelist(objects)
if collision != -1:
lives -= 1
if lives >= 0:
gameLoop()
else:
pygame.quit()
quit()
My asteroids only seem to be moving in the vertical direction, not horizontal even though I have changed their horizontal value.
for x in random_x_pos:
random_y_pos[random_x_pos.index(x)] += object_y_vel[random_x_pos.index(x)]
x += object_x_vel[random_x_pos.index(x)]
Here is the rest of my code:
import pygame, random
from pygame.locals import *
pygame.init()
pygame.display.set_caption('Dodge')
#icon = pygame.image.load('icon.png')
#pygame.display.set_icon(icon)
# -------------------- Colours --------------------
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
green = (0,155,0)
blue = (0,0,255)
pink = (233,30,98)
# -------------------- Variables --------------------
display_width = 600
display_height = 600
FPS = 60
lives = 3
clock = pygame.time.Clock()
gameDisplay = pygame.display.set_mode((display_width, display_height))
# -------------------- Actual Game --------------------
def gameLoop():
global lives
# -------------------- Player --------------------
player_dim = 20
x_pos = ((display_width / 2) - player_dim)
y_pos = ((display_height / 2) - player_dim)
vel = 5
player_rect = pygame.draw.rect(gameDisplay, pink, (x_pos, y_pos, player_dim, player_dim))
# -------------------- Random Objects --------------------
object_dimensions = 30
amount_of_objects = 10
random_x_pos, random_y_pos, object_x_vel, object_y_vel, objects = [], [], [], [], []
for int in range(amount_of_objects):
x, y, x_vel, y_vel = random.randint(0, display_width), random.randint(0, display_height), random.randint(-5,5), random.randint(-5,5)
rect1 = pygame.draw.rect(gameDisplay, white, (x, y, 30, 30))
again = rect1.colliderect(player_rect)
while again:
x, y = random.randint(0, display_width), random.randint(0, display_height)
rect1 = pygame.draw.rect(gameDisplay, white, (x, y, 30, 30))
again = rect1.colliderect(player_rect)
random_x_pos.append(x)
random_y_pos.append(y)
object_x_vel.append(x_vel)
object_y_vel.append(y_vel)
# -------------------- Event Handling --------------------
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
keys = pygame.key.get_pressed()
if keys[pygame.K_ESCAPE]:
pygame.quit()
quit()
if keys[pygame.K_UP] and y_pos > 0:
y_pos -= vel
if keys[pygame.K_DOWN] and (y_pos + player_dim) < display_height:
y_pos += vel
if keys[pygame.K_LEFT] and x_pos > 0:
x_pos -= vel
if keys[pygame.K_RIGHT] and (x_pos + player_dim) < display_width:
x_pos += vel
for x in random_x_pos:
random_y_pos[random_x_pos.index(x)] += object_y_vel[random_x_pos.index(x)]
x += object_x_vel[random_x_pos.index(x)]
# -------------------- COLLISION --------------------
collision = player_rect.collidelist(objects)
if collision != -1:
lives -= 1
if lives >= 0:
gameLoop()
else:
pygame.quit()
quit()
gameDisplay.fill(black)
player_rect = pygame.draw.rect(gameDisplay, pink, (x_pos, y_pos, player_dim, player_dim))
for obj in random_x_pos:
y = random_y_pos[random_x_pos.index(obj)]
var = pygame.draw.rect(gameDisplay, white, (obj, y, object_dimensions, object_dimensions))
objects.append(var)
pygame.display.update()
clock.tick(FPS)
gameLoop()

In the for obj in random_x_pos: loop, you're appending new rects to the objects lists like crazy. You don't move and draw these old rects, so you get thousands of invisible rects pretty quickly which are still used for the collision detection.
You have to restructure the code. I suggest to create a list of rects together with their velocities.
objects = []
for i in range(amount_of_objects):
rect = pygame.Rect(random.randint(0, display_width), random.randint(0, display_height), 30, 30)
velocity = [random.randint(-5,5), random.randint(-5,5)]
# Put the rect and the velocity into a list and append it to the objects.
objects.append([rect, velocity])
Update the rect positions in a for loop. You can do the collision detection at the same time.
collision = False
for rect, velocity in objects:
rect.x += velocity[0]
rect.y += velocity[1]
if player_rect.colliderect(rect):
collision = True
if collision:
lives -= 1
# etc.
Draw the rects like so:
for rect, velocity in objects:
pygame.draw.rect(gameDisplay, white, rect)

One of your problems lies in this code fragment:
for x in random_x_pos:
random_y_pos[random_x_pos.index(x)] += object_y_vel[random_x_pos.index(x)]
x += object_x_vel[random_x_pos.index(x)]
In this loop, x is the loop variable which changes in every cycle of the loop. The line x += object_x_vel[random_x_pos.index(x)] has no effect on the code because this is immediately followed by the next loop iteration in which x is assigned to the next value of random_x_pos.
Instead, you could try something like this:
for i in range(len(random_x_pos)):
random_y_pos[i] += object_y_vel[i]
random_x_pos[i] += object_x_vel[i]
Notice, however, that there are other flaws in your code. For example, you assign the python internal int to a loop variable and hence override it. This can lead to unwanted behaviour.

Related

Collision doesn't work. Upon collision, it is supposed to end the game. (instead both objects pass straight through each other)

I'm working on a space shooter game where you have to dodge asteroids and shoot them. Right now, I'm working on collision for the asteroids. I'm just testing one asteroid for now, but the asteroid passes straight through the ship and doesn't end the game like I want it to.
Here's the code:
import pygame
pygame.init()
#initalizing all the clunky variables
size = (900,700)
BLACK = (0, 0, 30)
RED = (255, 0, 0)
YELLOW = (0, 255, 0)
x_pos = 450
y_pos = 600
global x_pos
global y_pos
direct = 0
w, h = 100, 100
screen = pygame.display.set_mode(size)
klok = pygame.time.Clock()
#main ship image and its rotations
ship = pygame.image.load('u-sniper.png')
shipL = pygame.transform.rotate(ship, 270)
shipR = pygame.transform.rotate(ship, 90)
shipD = pygame.transform.rotate(ship, 180)
#init hitbox
hitbox = ship.get_rect()
hitbox.center = w//2,h//2
#funct for drawing ship
def drawShip():
if direct == 0:
screen.blit(ship, [x_pos,y_pos])
if direct == 1:
screen.blit(shipR, [x_pos,y_pos])
if direct == 2:
screen.blit(shipD, [x_pos,y_pos])
if direct == 3:
screen.blit(shipL, [x_pos,y_pos])
#asteroid obstacles (these are meant to collide with the ship)
class asteroid:
def __init__(self,x,y,spawn):
self.x = x
self.y = y
self.spawn = spawn
def drawA(self):
if self.spawn == 1:
pygame.draw.circle(screen, RED, (self.x,self.y), 30)
def moveA(self):
self.y += 8
if self.y > 650:
self.spawn = 0
done = False
roid = asteroid(450,0,1)
#asteroid hitbox init
rect_asteroid = (roid.x, roid.y, 30, 30)
#here is where its going wrong, collision dosent register
def checkForCollisions():
collide = pygame.Rect.colliderect(hitbox,rect_asteroid)
if collide == True:
done = True
#loop
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
screen.fill(BLACK)
drawShip()
roid.drawA()
roid.moveA()
#calling fuction, but it dosent work
checkForCollisions()
#if branch that moves the ship
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
y_pos -= 5
direct = 0
if event.key == pygame.K_DOWN:
y_pos += 5
direct = 2
if event.key == pygame.K_RIGHT:
x_pos += 5
direct = 3
if event.key == pygame.K_LEFT:
x_pos -= 5
direct = 1
#collision between screen boundaries
if x_pos > 850:
x_pos -= 6
if x_pos < -50:
x_pos += 6
if y_pos > 650:
y_pos -= 6
if y_pos < 0:
y_pos += 6
pygame.display.flip()
klok.tick(60)
pygame.quit()
I tried multiple colliderect functions, but it just results in one thing: the ship and the asteroid pass straight through each other.
The pygame.Rect objects do not magically update their position when you change the coordinates used to draw the object. You need to update the location stored in the pygame.Rect objects before collision detection. Or just create the objects in checkForCollisions:
def checkForCollisions():
hitbox.topleft = (x_pos, y_pos)
rect_asteroid = (roid.x, roid.y, 30, 30)
collide = hitbox.colliderect(rect_asteroid)
return collide

Collision for Pygame Game Map

I am trying to make a maze game in Pygame but am unable to achieve collision for the 1 (maze wall) in the array. I tried to put the collision detection in the loop creating the map but it is not working. I also put the collision detection in the main loop but only the top left rect detected the collision, not all the 1 rects. How would I go about fixing this? Thank you!
import pygame
pygame.init()
screen = pygame.display.set_mode((700,700))
pygame.display.set_caption("Game")
speed = 20
x = 200
y = 600
def game_map():
global rect_one
surface = pygame.Surface((100, 100), pygame.SRCALPHA)
rect_one = pygame.draw.rect(surface, (0, 0, 255), (0, 0, 50, 50))
global rect_two
surface_one = pygame.Surface((80, 80), pygame.SRCALPHA)
rect_two = pygame.draw.rect(surface_one, (255, 255, 255), (0, 0, 50, 50))
tileX = 0
tileY = 0
global tile_list
tile_list = []
map = [
[1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,0,0,0,1,0,1,0,0,0,0,0,1],
[1,0,1,0,0,0,1,0,1,1,1,0,1],
[1,0,0,0,1,1,1,0,0,0,0,0,1],
[1,0,1,0,0,0,0,0,1,1,1,0,1],
[1,0,1,0,1,1,1,0,1,0,0,0,1],
[1,0,1,0,1,0,0,0,1,1,1,0,1],
[1,0,1,0,1,1,1,0,1,0,1,0,1],
[1,0,0,0,0,0,0,0,0,0,1,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1]
]
for y, row in enumerate(map):
tileX = 0
for x, cell in enumerate(row):
image = surface if cell == 1 else surface_one
screen.blit(image, [x*50, y*50])
tile_list.append(rect_one)
pygame.display.update()
def player():
player = pygame.draw.rect(screen, (255,0,0), (x, y, 20, 20))
for i in tile_list:
if player.colliderect(i):
print("hello")
loop = True
while loop:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
loop = False
#player controls
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x -= speed
if keys[pygame.K_RIGHT]:
x += speed
if keys[pygame.K_UP]:
y -= speed
if keys[pygame.K_DOWN]:
y += speed
screen.fill((255,255,255))
game_map()
player()
pygame.display.update()
pygame.quit()
Your tile_list only contains one Rect multiple times.
I simplified your code a little bit and use a Rect with the correct coordinates for each 1 in your map. Also note the comments:
import pygame
pygame.init()
screen = pygame.display.set_mode((700,700))
pygame.display.set_caption("Game")
speed = 10
player_x = 200
player_y = 600
# Use a constant. There's not need to make big Surfaces and then draw a smaller rect on them to create the map.
TILESIZE = 50
tile_list = []
map = [
[1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,0,0,0,1,0,1,0,0,0,0,0,1],
[1,0,1,0,0,0,1,0,1,1,1,0,1],
[1,0,0,0,1,1,1,0,0,0,0,0,1],
[1,0,1,0,0,0,0,0,1,1,1,0,1],
[1,0,1,0,1,1,1,0,1,0,0,0,1],
[1,0,1,0,1,0,0,0,1,1,1,0,1],
[1,0,1,0,1,1,1,0,1,0,1,0,1],
[1,0,0,0,0,0,0,0,0,0,1,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1]
]
# let's create a single Surface for the map and reuse that
grid = pygame.Surface((len(map[0]) * TILESIZE, len(map) * TILESIZE), pygame.SRCALPHA)
for y, row in enumerate(map):
for x, cell in enumerate(row):
# if we want a wall, we draw it on the new Surface
# also, we store the Rect in the tile_list so collision detection works
if cell:
rect = pygame.draw.rect(grid, 'blue', (x*TILESIZE, y*TILESIZE, TILESIZE, TILESIZE))
tile_list.append(rect)
loop = True
clock = pygame.time.Clock()
while loop:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
loop = False
#player controls
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_x -= speed
if keys[pygame.K_RIGHT]:
player_x += speed
if keys[pygame.K_UP]:
player_y -= speed
if keys[pygame.K_DOWN]:
player_y += speed
screen.fill((255,255,255))
# draw the map surface to the screen
screen.blit(grid, (0 ,0))
player = pygame.draw.rect(screen, (255,0,0), (player_x, player_y, 20, 20))
# now collision detection works because for each 1 in the map
# there's a Rect in tile_list with the correct coordinates
for i in tile_list:
if player.colliderect(i):
print("colliding")
break
else:
print('not colliding')
pygame.display.update()
pygame.quit()
Save the position of the player before moving it:
pos = x, y
Compute the row and column after the player has moved:
row = y // 50
column = x // 50
Reset the player's position if the new position is on a wall:
if map[row][column] == 1:
x, y = pos
Additionally you have to move the map variable to global namespace. The speed should a integral divider of the tile size. Change the starting position to a position in the grid:
speed = 25
x = 50
y = 50
Complete code:
import pygame
pygame.init()
screen = pygame.display.set_mode((700,700))
pygame.display.set_caption("Game")
speed = 25
x = 50
y = 50
map = [
[1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,0,0,0,1,0,1,0,0,0,0,0,1],
[1,0,1,0,0,0,1,0,1,1,1,0,1],
[1,0,0,0,1,1,1,0,0,0,0,0,1],
[1,0,1,0,0,0,0,0,1,1,1,0,1],
[1,0,1,0,1,1,1,0,1,0,0,0,1],
[1,0,1,0,1,0,0,0,1,1,1,0,1],
[1,0,1,0,1,1,1,0,1,0,1,0,1],
[1,0,0,0,0,0,0,0,0,0,1,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1]
]
def game_map():
global rect_one
surface = pygame.Surface((100, 100), pygame.SRCALPHA)
rect_one = pygame.draw.rect(surface, (0, 0, 255), (0, 0, 50, 50))
global rect_two
surface_one = pygame.Surface((80, 80), pygame.SRCALPHA)
rect_two = pygame.draw.rect(surface_one, (255, 255, 255), (0, 0, 50, 50))
tileX = 0
tileY = 0
for y, row in enumerate(map):
tileX = 0
for x, cell in enumerate(row):
image = surface if cell == 1 else surface_one
screen.blit(image, [x*50, y*50])
pygame.display.update()
def player():
player = pygame.draw.rect(screen, (255,0,0), (x, y, 25, 25))
loop = True
while loop:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
loop = False
#player controls
keys = pygame.key.get_pressed()
pos = x, y
if keys[pygame.K_LEFT]:
x -= speed
if keys[pygame.K_RIGHT]:
x += speed
if keys[pygame.K_UP]:
y -= speed
if keys[pygame.K_DOWN]:
y += speed
row = y // 50
column = x // 50
if map[row][column] == 1:
x, y = pos
screen.fill((255,255,255))
game_map()
player()
pygame.display.update()
pygame.quit()

Is there a way to make a function for all the code relating to drawing a bouncing ball in pygame?

The ball bounces around and I can draw it but I want to draw multiple and have them start at random places without having to type every scenario. Is there a way to write a function to do this?
import pygame
import sys
import random
pygame.init()
screenSize = (800,600)
screen = pygame.display.set_mode(screenSize)
pygame.display.set_caption("Jacob Cardoso Basic Drawing")
WHITE = (255,255,255)
BLACK = (0,0,0)
RED = (255,0,0)
GREEN = (0,255,0)
BLUE = (0,0,255)
COLOUR = (random.randint(0,255), random.randint(0,255),random.randint(0,255))
x = random.randint(50,750)
y = random.randint(50,550)
dx = random.randint(1, 3)
dy = random.randint(-1, 3)
screen.fill(WHITE)
go = True
while go:
for event in pygame.event.get():
if event.type == pygame.QUIT:
go = False
x = x + dx
y = y + dy
if (y <= 50) or (y >= 550):
dy = -dy
COLOUR = (random.randint(0,255), random.randint(0,255),random.randint(0,255))
if (x <= 50) or (x >= 750):
dx = -dx
COLOUR = (random.randint(0,255), random.randint(0,255),random.randint(0,255))
screen.fill(WHITE)
pygame.draw.circle (screen, COLOUR, (x,y), 50, 0)
pygame.display.update()
pygame.quit()
sys.exit()
Create a Class for the balls. The coordinates, moving direction and color become instance attributes. Move the code which handles the movement to an update method. Do the drawing of the ball in a draw method.
class Ball:
def __init__(self):
self.x = random.randint(50,750)
self.y = random.randint(50,550)
self.dx = random.randint(1, 3)
self.dy = random.randint(-1, 3)
self.color = (random.randint(0,255), random.randint(0,255),random.randint(0,255))
def update(self):
self.x = self.x + self.dx
self.y = self.y + self.dy
bounce = False
if (self.y <= 50) or (self.y >= 550):
self.dy = -self.dy
bounce = True
if (self.x <= 50) or (self.x >= 750):
self.dx = -self.dx
bounce = True
if bounce:
self.color = (random.randint(0,255), random.randint(0,255),random.randint(0,255))
def draw(self, surf):
pygame.draw.circle(surf, self.color, (self.x, self.y), 50, 0)
Create a number of (max_balls) ball instances in a loop and append them to a list (balls), before the application loop. Update the position of the balls and draw them in for-loops in the application loop:
# crate the balls
max_balls = 5
balls = []
for _ in range(max_balls):
balls.append(Ball())
screen.fill(WHITE)
go = True
while go:
for event in pygame.event.get():
if event.type == pygame.QUIT:
go = False
# update the ball positions
for ball in balls:
ball.update()
screen.fill(WHITE)
# draw the balls
for ball in balls:
ball.draw(screen)
pygame.display.update()

Pygame collision detection issue

I am making a game with pygame where you have to dodge falling objects. I am having trouble with the collision detection, as when the obstacle touches the player, it just passes through to the bottom. Here is my code.
pygame.K_LEFT:
p_x_change = 0
screen.fill(WHITE)
pygame.draw.rect(screen,BLUE,(p_x,p_y, 60, 60))
pygame.draw.rect(screen,RED,(e_x,e_y,100,100))
p_x += p_x_change
e_y += e_ychange
if e_y > display_height:
e_y = 0
e_x = random.randint(1,display_width)
#Collision detection below
elif e_y == p_y - 90 and e_x == p_x :
done = True
clock.tick(60)
pygame.display.update()
Could you tell me what is wrong with my code?
I suggest to create two pygame.Rects, one for the player and one for the enemy. Then move the enemy by incrementing the y attribute of the rect and use the colliderect method to see if the two rects collide.
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
display_width, display_height = screen.get_size()
clock = pygame.time.Clock()
BG_COLOR = pygame.Color('gray12')
BLUE = pygame.Color('dodgerblue1')
RED = pygame.Color('firebrick1')
# Create two rects (x, y, width, height).
player = pygame.Rect(200, 400, 60, 60)
enemy = pygame.Rect(200, 10, 100, 100)
e_ychange = 2
done = False
while not done:
# Event handling.
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
keys = pygame.key.get_pressed()
if keys[pygame.K_a]:
player.x -= 5
elif keys[pygame.K_d]:
player.x += 5
# Game logic.
enemy.y += e_ychange # Move the enemy.
if enemy.y > display_height:
enemy.y = 0
enemy.x = random.randint(1, display_width)
# Use the colliderect method for the collision detection.
elif player.colliderect(enemy):
print('collision')
# Drawing.
screen.fill(BG_COLOR)
pygame.draw.rect(screen, BLUE, player)
pygame.draw.rect(screen, RED, enemy)
pygame.display.flip()
clock.tick(30)
pygame.quit()

Collisions detection in pygame

I'm trying to detect collisions between the player and the floor. This is part of my school project so any insight would be helpful. Also suggestions to improve the code will be appreciated. Here is my code:
import pygame
#initialise pygame
pygame.init()
#variables
level = 0
velx = 0
vely = 0
health = 1
floor_group = set([])
clock = pygame.time.Clock()
#collisions
def detectCollisions(x1, y1, w1,h1, x2, y2, w2, h2):
if (x2 + w2 >= x1 >= x2 and y2 + h2 >= y1 >= y2):
return True
elif (x2 + w2 >= x1 + w1 >= x2 and y2 + h2 >= y1 >= y2):
return True
elif (x2 + w2 >= x1 >= x2 and y2 + h2 >= y1 + h1 >= y2):
return True
elif (x2 + w2 >= x1 + w1 >= x2 and y2 + h2 >= y1+ h1 >= y2):
return True
else:
return False
#screen size the same size as my background
window = pygame.display.set_mode((900,563))
#Load Images: Backgrounds
background0 = pygame.image.load("background0.png").convert()
#Load Sprites
halfspike = pygame.image.load("halfspike.png").convert_alpha()
spike = pygame.image.load("spike.png").convert_alpha()
platform = pygame.image.load("platform.png").convert_alpha()
spider = pygame.image.load("spider.png").convert_alpha()
char1 = pygame.image.load("char1.png").convert_alpha()
char2 = pygame.image.load("char2.png").convert_alpha()
#Window title
pygame.display.set_caption("Super Boshy Brothers")
# character class
class Sprite:
def __init__(self,x,y):
self.x = x
self.y = y
self.width = 42
self.height = 44
self.velx = 0
self.vely = 0
self.image0 = pygame.image.load("char1.png")
self.image1 = pygame.image.load("char2.png")
self.timeTarget = 10
self.timeNumber = 0
self.currentImage = 0
def update(self):
self.timeNumber += 1
if (self.timeNumber == self.timeTarget):
if (self.currentImage == 0):
self.currentImage = 1
else:
self.currentImage = 0
self.timeNumber = 0
self.render()
def render(self):
if (self.currentImage == 0):
window.blit(self.image0, (self.x, self.y))
else:
window.blit(self.image1, (self.x, self.y))
# Floor class
class Floor:
def __init__(self,x,y):
self.x = x
self.y = y
self.width = 43
self.height = 44
self.image0 = pygame.image.load("floor.png")
def update(self):
self.render()
def render(self):
window.blit(self.image0, (self.x, self.y))
def floor_spawner(row):
global floor_group
for i in range(0,946,43):
floor_group.add(Floor(i,row))
#Create first level floor
floor_spawner(519)
floor_spawner(475)
#player
player = Sprite(0,431)
#create our main loop
gameloop = True
while gameloop:
for event in pygame.event.get(): #get function handles events
if (event.type == pygame.QUIT): #if Quit (red x) pressed exit loop
gameloop = False
if (event.type == pygame.KEYDOWN): #If a key is pressed down
if (event.key ==pygame.K_LEFT): #If Left Arrow
velx = -7
if (event.key ==pygame.K_RIGHT): #If Right Arrow
velx = 7
if (event.key ==pygame.K_UP): #If Up Arrow
vely = -7
if (event.type == pygame.KEYUP): #If a key is pressed down
if (event.key ==pygame.K_LEFT): #If Left Arrow
velx = 0
if (event.key ==pygame.K_RIGHT): #If Right Arrow
velx = 0
if (event.key ==pygame.K_UP): #If Up Arrow
vely = 0
#Level 0
if level == 0:
window.blit(background0, (0,0)) #Bottom bricks
for f in list(floor_group):
f.render()
if player.x <= 0: #Left side collision
player.x = 0
if player.x >= 900: #Level change
level = 1
player.x = 0
#Level 1
if level == 1:
window.blit(background0, (0,0)) #Bottom bricks
for f in list(floor_group):
f.render()
player.x += velx
player.y += vely
player.update()
clock.tick(50) #Tick Tock Tick Tock
pygame.display.flip() #Updates the window
pygame.quit()
It's better if you use pygame sprite to do your assignment.
For managing the floor collision problem, just detect the collision as I do in the code below, if a collision between player and floor occurs then simply move the player back to the previous position.
Here's my code:
import pygame
import random
BLACK = (0, 0, 0)
RED = (255, 0, 0)
BLUE = (0, 255, 0)
WHITE = (255, 255, 255)
#Sprite are basically game images in pygame
#Through sprites collision detection and rendering becomes much easier
class Block(pygame.sprite.Sprite):
#Here I've a block class which is a subclass of the pygame's sprite class
def __init__(self, image):
pygame.sprite.Sprite.__init__(self)
# Here I've initialised he superclass Sprite
self.image = image
#Image of sprite = image .. that's it
self.rect = self.image.get_rect()
#It get's all dimesion's of image which will help it in detecting collision
pygame.init()
infoObject = pygame.display.Info()
# pygame.display.Info() provides us with the information about cureent resolution and a bunch of other stuff
screen = pygame.display.set_mode((infoObject.current_w, infoObject.current_h))
char1 = pygame.image.load("char1.png").convert_alpha()
char2 = pygame.image.load("char2.png").convert_alpha()
char2_list = pygame.sprite.Group()
# Sprite groups are sets for sprites
# i.e. We have different types of object stored in different groups
# In our game the char1 and char2 are of different
#internal interaction between all char2 does'nt matter
#It's the interaction between the char1 and char2 that we've to deal with
all_list = pygame.sprite.Group()
#I've made a group which contains all the blocks which helps me in rendering them all together
for i in range(50):
block = Block(char1)
block.rect.x = random.randrange(infoObject.current_w)
block.rect.y = random.randrange(infoObject.current_h)
charimport pygame
import random
BLACK = (0, 0, 0)
RED = (255, 0, 0)
BLUE = (0, 255, 0)
WHITE = (255, 255, 255)
#Sprite are basically game images in pygame
#Through sprites collision detection and rendering becomes much easier
class Block(pygame.sprite.Sprite):
#Here I've a block class which is a subclass of the pygame's sprite class
def __init__(self, image):
pygame.sprite.Sprite.__init__(self)
# Here I've initialised he superclass Sprite
self.image = image
#Image of sprite = image .. that's it
self.rect = self.image.get_rect()
#It get's all dimesion's of image which will help it in detecting collision
pygame.init()
infoObject = pygame.display.Info()
# pygame.display.Info() provides us with the information about cureent resolution and a bunch of other stuff
screen = pygame.display.set_mode((infoObject.current_w, infoObject.current_h))
char1 = pygame.image.load("char1.png").convert_alpha()
char2 = pygame.image.load("char2.png").convert_alpha()
char2_list = pygame.sprite.Group()
# Sprite groups are sets for sprites
# i.e. We have different types of object stored in different groups
# In our game the char1 and char2 are of different
#internal interaction between all char2 does'nt matter
#It's the interaction between the char1 and char2 that we've to deal with
all_list = pygame.sprite.Group()
#I've made a group which contains all the blocks which helps me in rendering them all together
for i in range(50):
block = Block(char1)
block.rect.x = random.randrange(infoObject.current_w)
block.rect.y = random.randrange(infoObject.current_h)
char2_list.add(block)
all_list.add(block)
player = Block(char2)
running = True
clock = pygame.time.Clock()
score = 1
all_list.add(player)
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill(BLACK)
pos = pygame.mouse.get_pos()
#Gets position of the mouse
player.rect.x = pos[0]
player.rect.y = pos[1]
char_hit_list = pygame.sprite.spritecollide(player, char2_list, True)#Set it to false and see the result
#Checks collision
for block in char_hit_list:
score += 1
print score
all_list.draw(screen)
#renders(draw) all the sprites onto screen
pygame.display.update()
#update's display
clock.tick(60)
# Sets Frame Rate to 60
pygame.quit()2_list.add(block)
all_list.add(block)
player = Block(char2)
running = True
clock = pygame.time.Clock()
score = 1
all_list.add(player)
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill(BLACK)
pos = pygame.mouse.get_pos()
#Gets position of the mouse
player.rect.x = pos[0]
player.rect.y = pos[1]
char_hit_list = pygame.sprite.spritecollide(player, char2_list, True)#Set it to false and see the result
#Checks collision
for block in char_hit_list:
score += 1
print score
all_list.draw(screen)
#renders(draw) all the sprites onto screen
pygame.display.update()
#update's display
clock.tick(60)
# Sets Frame Rate to 60
pygame.quit()
And one more thing try not to hard-code stuff like you did for screen dimension.
For learning more about pygame Sprites have a look at this.
If you have any problem, let me know by commenting in the comments section below, I'll try my best to help you out with your problem.
Keep pygaming :)

Categories

Resources