Pygame: Adding a background - python

I'm making a project for my senior year. Its a game where i can move a user. I would like to add a background that goes behind all the pictures i've blitted. I've searched everywhere but i can't seem to find the solution. Could anybody help?
import pygame
import os
class Player(object):
def __init__(self):
self.image = pygame.image.load("player1.png")
self.image2 = pygame.transform.flip(self.image, True, False)
self.coffee=pygame.image.load("coffee.png")
self.computer=pygame.image.load("computer.png")
self.flipped = False
self.x = 0
self.y = 0
def handle_keys(self):
""" Movement keys """
key = pygame.key.get_pressed()
dist = 5
if key[pygame.K_DOWN]:
self.y += dist
elif key[pygame.K_UP]:
self.y -= dist
if key[pygame.K_RIGHT]:
self.x += dist
self.flipped = False
elif key[pygame.K_LEFT]:
self.x -= dist
self.flipped = True
def draw(self, surface):
if self.flipped:
image = self.image2
else:
image = self.image
surface.blit(image, (self.x, self.y))
surface.blit(self.coffee, (700,500))
surface.blit(self.computer,(0,500))
pygame.init()
screen = pygame.display.set_mode((810, 610)) #creates the screen
player = Player()
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit() # quit the screen
running = False
player.handle_keys() # movement keys
screen.fill((255,255,255)) # fill the screen with white
player.draw(screen) # draw the player to the screen
pygame.display.update() # update the screen
clock.tick(60) # Limits Frames Per Second to 60 or less

A background image is no different from any other image. Just .blit it first.

Related

Why sprite isn't showing up in pygame? [duplicate]

im trying to get my image (bird) to move up and down on the screen but i cant figure out how to do it here is what i tried im sure its way off but im trying to figure it out if anyone can help that would be great!
import pygame
import os
screen = pygame.display.set_mode((640, 400))
running = 1
while running:
event = pygame.event.poll()
if event.type == pygame.QUIT:
running = 0
screen.fill([255, 255, 255])
clock = pygame.time.Clock()
clock.tick(0.5)
pygame.display.flip()
bird = pygame.image.load(os.path.join('C:\Python27', 'player.png'))
screen.blit( bird, ( 0, 0 ) )
pygame.display.update()
class game(object):
def move(self, x, y):
self.player.center[0] += x
self.player.center[1] += y
if event.key == K_UP:
player.move(0,5)
if event.key == K_DOWN:
player.move(0,-5)
game()
im trying to get it to move down on the down button press and up on the UP key press
As stated by ecline6, bird is the least of your worries at this point.
Consider reading this book..
For now, First let's clean up your code...
import pygame
import os
# let's address the class a little later..
pygame.init()
screen = pygame.display.set_mode((640, 400))
# you only need to call the following once,so pull them out of the while loop.
bird = pygame.image.load(os.path.join('C:\Python27', 'player.png'))
clock = pygame.time.Clock()
running = True
while running:
event = pygame.event.poll()
if event.type == pygame.QUIT:
running = False
screen.fill((255, 255, 255)) # fill the screen
screen.blit(bird, (0, 0)) # then blit the bird
pygame.display.update() # Just do one thing, update/flip.
clock.tick(40) # This call will regulate your FPS (to be 40 or less)
Now the reason that your "bird" is not moving is:
When you blit the image, ie: screen.blit(bird, (0, 0)),
The (0,0) is constant, so it won't move.
Here's the final code, with the output you want (try it) and read the comments:
import pygame
import os
# it is better to have an extra variable, than an extremely long line.
img_path = os.path.join('C:\Python27', 'player.png')
class Bird(object): # represents the bird, not the game
def __init__(self):
""" The constructor of the class """
self.image = pygame.image.load(img_path)
# the bird's position
self.x = 0
self.y = 0
def handle_keys(self):
""" Handles Keys """
key = pygame.key.get_pressed()
dist = 1 # distance moved in 1 frame, try changing it to 5
if key[pygame.K_DOWN]: # down key
self.y += dist # move down
elif key[pygame.K_UP]: # up key
self.y -= dist # move up
if key[pygame.K_RIGHT]: # right key
self.x += dist # move right
elif key[pygame.K_LEFT]: # left key
self.x -= dist # move left
def draw(self, surface):
""" Draw on surface """
# blit yourself at your current position
surface.blit(self.image, (self.x, self.y))
pygame.init()
screen = pygame.display.set_mode((640, 400))
bird = Bird() # create an instance
clock = pygame.time.Clock()
running = True
while running:
# handle every event since the last frame.
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit() # quit the screen
running = False
bird.handle_keys() # handle the keys
screen.fill((255,255,255)) # fill the screen with white
bird.draw(screen) # draw the bird to the screen
pygame.display.update() # update the screen
clock.tick(40)
The keyboard events (see pygame.event module) occur only once when the state of a key changes. The KEYDOWN event occurs once every time a key is pressed. KEYUP occurs once every time a key is released. Use the keyboard events for a single action or a step-by-step movement.
If you want to achieve a continuously movement, you have to use pygame.key.get_pressed(). pygame.key.get_pressed() returns a list with the state of each key. If a key is held down, the state for the key is True, otherwise False. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement.
See also Key and Keyboard event and How can I make a sprite move when key is held down.
Minimal example:
import pygame
import os
class Bird(object):
def __init__(self):
self.image = pygame.image.load(os.path.join('C:\Python27', 'player.png'))
self.center = [100, 200]
def move(self, x, y):
self.center[0] += x
self.center[1] += y
def draw(self, surf):
surf.blit(self.image, self.center)
class game(object):
def __init__(self):
self.screen = pygame.display.set_mode((640, 400))
self.clock = pygame.time.Clock()
self.player = Bird()
def run(self):
running = 1
while running:
self.clock.tick(60)
event = pygame.event.poll()
if event.type == pygame.QUIT:
running = 0
keys = pygame.key.get_pressed()
move_x = keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]
move_y = keys[pygame.K_DOWN] - keys[pygame.K_UP]
self.player.move(move_x * 5, move_y * 5)
self.screen.fill([255, 255, 255])
self.player.draw(self.screen)
pygame.display.update()
g = game()
g.run()

How do I make my background scroll as my Sprite moves left and right? Pygame

Right now my game works as so: My sprite can move right or left, jump and shoot fireballs (bullets). However, once my sprite walks past the limit of my background surface, it goes off-screen. So I want to make the background move along with my sprite. As soon as my player sprite moves about 50 pixels towards the edges of the screen, the background moves too. How do I create this with Pygame? I've found quite an amount of sources which shows you how to do this but with a plain colour background. But my background is an image I load into the game, so I would like to learn how to do so with an image as background. How to make it repeat once the sprite comes near the limit of both sides. I separated my codes into 3 different files: a Main.py, settings.py and Sprite1.py. Here's Main.py:
import pygame
import os
import sys
import time
from pygame import mixer
from Sprite1 import *
from settings import *
'''
Setup
'''
pygame.init()
clock = pygame.time.Clock()
pygame.mixer.music.load('.\\sounds\\Fairy.mp3')
pygame.mixer.music.play(-1, 0.0)
all_sprites = pygame.sprite.Group()
player = Player(all_sprites)
player.rect.x = 50
player.rect.y = 500
showStartScreen(surface)
'''
Main loop
'''
main = True
while main == True:
background = pygame.image.load(os.path.join('images', 'Bg.png'))
surface.blit(background, (0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
main = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT or event.key == ord('a'):
player.control(-steps,0)
if event.key == pygame.K_RIGHT or event.key == ord('d'):
player.control(steps,0)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == ord('a'):
player.control(steps,0)
if event.key == pygame.K_RIGHT or event.key == ord('d'):
player.control(-steps,0)
keys = pygame.key.get_pressed()
if not(isJump):
if keys[pygame.K_UP]:
isJump = True
else:
if jumpCount >= -10:
player.rect.y -= (jumpCount * abs(jumpCount)) * 1
jumpCount -= 2
else:
jumpCount = 10
isJump = False
# dt = time since last tick in milliseconds.
dt = clock.tick(60) / 1000
all_sprites.update(dt)
player.update(dt)
all_sprites.draw(surface) #refresh player position
pygame.display.flip()
Here's settings.py:
import pygame
isJump = False
jumpCount = 10
width = 960
height = 720
fps = 40 # frame rate
#ani = 4 # animation cycles
pygame.display.set_caption('B.S.G.')
surface = pygame.display.set_mode((width, height))
PLAYER_ACC = 0.5
PLAYER_FRICTION = -0.12
PLAYER_GRAV = 0.8
PLAYER_JUMP = 20
PLAYER_LAYER = 2
PLATFORM_LAYER = 1
steps = 10 # how fast to move
And here's Sprite1.py:
import pygame
import sys
import os
import time
from pygame import mixer
from pygame.locals import *
from settings import *
vec = pygame.math.Vector2
def showStartScreen(surface):
show = True
while (show == True):
background = pygame.image.load(os.path.join('images', 'Starting_scr.png'))
# rect = surface.get_rect()
surface.blit(background, (0,0))
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
show = False
class Player(pygame.sprite.Sprite):
def __init__(self, all_sprites):
pygame.sprite.Sprite.__init__(self)
self.movex = 0
self.movey = 0
self.frame = 0
self.health = 10
self.jumping = False
self.images = []
self.imagesleft = []
self.imagesright = []
self.direction = "right"
self.alpha = (0,0,0)
self.ani = 4 # animation cycles
self.all_sprites = all_sprites
self.add(self.all_sprites)
self.bullet_timer = .1
for i in range(1,5):
img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
img.convert_alpha()
img.set_colorkey(self.alpha)
self.imagesright.append(img)
self.image = self.imagesright[0]
self.rect = self.image.get_rect()
for i in range(1,5):
img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
img = pygame.transform.flip(img, True, False)
img.convert_alpha()
img.set_colorkey(self.alpha)
self.imagesleft.append(img)
self.image = self.imagesleft[0]
self.rect = self.image.get_rect()
def control(self,x,y):
'''
control player movement
'''
self.movex += x
self.movey -= y
def update(self, dt):
'''
Update sprite position
'''
self.rect.x = self.rect.x + self.movex
self.rect.y = self.rect.y + self.movey
# moving left
if self.movex < 0:
self.frame += 1
if self.frame > 3*self.ani:
self.frame = 0
self.image = self.imagesleft[self.frame//self.ani]
self.direction = "left"
# moving right
if self.movex > 0:
self.frame += 1
if self.frame > 3*self.ani:
self.frame = 0
self.image = self.imagesright[self.frame//self.ani]
self.direction = "right"
#enemy_hit_list = pygame.sprite.spritecollide(self,enemy_list, False)
#for enemy in enemy_hit_list:
#self.health -= 1
#print(self.health)
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
self.bullet_timer -= dt # Subtract the time since the last tick.
if self.bullet_timer <= 0:
self.bullet_timer = 100 # Bullet ready.
if keys: # Left mouse button.
# Create a new bullet instance and add it to the groups.
if self.direction == "right":
Bullet([self.rect.x + self.image.get_width(), self.rect.y + self.image.get_height()/2], self.direction, self.all_sprites)
else:
Bullet([self.rect.x, self.rect.y + self.image.get_height()/2], self.direction, self.all_sprites)
self.bullet_timer = .1 # Reset the timer.
class Bullet(pygame.sprite.Sprite):
IMAGE = None
FLIPPED_IMAGE = None
def __init__(self, pos, direction, *sprite_groups):
super().__init__(*sprite_groups)
# cache images
if not Bullet.IMAGE:
Bullet.IMAGE = pygame.image.load(os.path.join('images','fireball.png'))
Bullet.FLIPPED_IMAGE = pygame.transform.flip(Bullet.IMAGE, True, False)
if direction == "right":
self.vel = pygame.math.Vector2(750, 0)
self.image = Bullet.IMAGE
else:
self.vel = pygame.math.Vector2(-750, 0)
self.image = Bullet.FLIPPED_IMAGE
self.pos = pygame.math.Vector2(pos)
self.rect = self.image.get_rect(center=pos)
def update(self, dt):
# Add the velocity to the position vector to move the sprite
self.pos += self.vel * dt
self.rect.center = self.pos # Update the rect pos.
if not pygame.display.get_surface().get_rect().colliderect(self.rect):
self.kill()
I'm open to any suggestions. Thanks beforehand!
Here's how I would approach this...
set up a scrolling background as in the tutorial and make sure you can get that working OK by moving the background back & forth instead of the player (just freeze the player's x coordinate in the center and move the background with your left/right keys.
Add some constants into your settings for an edge buffer (the number of x-increments you want the player to avoid the boundaries by
AFTER you get the key input (left or right) set up a conditional statement. For this, you will have to access the player's x-coordinate and compare it to the buffer. Well, either 0+buffer or width-buffer actually and then based on those cases either move the player or the background. See if you can get that working.
Then, you will realize that when you move the background, you are moving the frame of reference for everything else, meaning things like the fireball, so if you are moving the background left or right, you will need to apply those updates to the other objects as well so it looks correct.
If yer stuck, make those updates to code above & message me back in a comment.

Pygame sprite creating duplicate instead of moving

I am fairly new to Pygame.
I am attempting to re-create Pong in Python using Pygame, but I have hit a roadblock.
Here is my code:
import pygame
pygame.init()
UP = "up"
DOWN = "down"
white = (255,255,255)
black = (0,0,0)
pygame.mouse.set_visible(True)
resolution = (800,600)
window = pygame.display.set_mode(resolution)
pygame.display.set_caption("Pong!")
clock = pygame.time.Clock()
sprites_list = pygame.sprite.Group()
running = True
class Paddle(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((25,100))
self.image.fill(white)
pygame.draw.rect(self.image,white, (0,0,25,100))
self.rect = self.image.get_rect()
def move(self,direction,pixels):
if direction == DOWN:
self.rect.y -= pixels
if direction == UP:
self.rect.y += pixels
player1 = Paddle()
player1.rect.x = 0
player1.rect.y = 200
sprites_list.add(player1)
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_DOWN]:
player1.move(DOWN, 5)
if keys[pygame.K_UP]:
player1.move(UP, 5)
sprites_list.update()
sprites_list.draw(window)
pygame.display.flip()
clock.tick(60)
pygame.quit()
I am trying to make player1, a Paddle object, move up or down depending on which key is pressed. When I run this code, player1 is stretched out after the up or down arrows are pressed; 5 pixels are added onto player1.rect.
What am I doing wrong and why will sprites_list.update() not put player1 in its new position?
You have to clear screen before you draw elements in new loop.
You can fill window with black color window.fill((0,0,0)) or draw background image in every loop.
This is your code after reorganization and adding window.fill(BLACK)
import pygame
# --- constants --- (UPPER_CASE_NAMES)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
UP = "up"
DOWN = "down"
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
# --- classes ---- (CamelCaseNames)
class Paddle(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((25,100))
self.image.fill(WHITE)
# you don't have to draw white rect if all surface already is white
#pygame.draw.rect(self.image,white, (0,0,25,100))
self.rect = self.image.get_rect()
def move(self, direction, pixels):
if direction == DOWN:
self.rect.y += pixels
if direction == UP:
self.rect.y -= pixels
# --- functions --- (lower_case_names)
# empty
# --- main --- (lower_case_names)
# - init -
pygame.init()
pygame.mouse.set_visible(True)
window = pygame.display.set_mode(resolution)
pygame.display.set_caption("Pong!")
# - objects -
sprites_list = pygame.sprite.Group()
player1 = Paddle()
player1.rect.x = 0
player1.rect.y = 200
sprites_list.add(player1)
# - mainloop -
clock = pygame.time.Clock()
running = True
while running:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_DOWN]:
player1.move(DOWN, 5)
if keys[pygame.K_UP]:
player1.move(UP, 5)
# - updates (without draws) -
sprites_list.update()
# - draws (without updates) -
window.fill(BLACK) # <--- clear screen
sprites_list.draw(window)
pygame.display.flip()
clock.tick(60)
# - end -
pygame.quit()

Multidimensional Array in Python and Pygame

As you might probably be able to guess, I'm quite new to Python! I'm trying to write a (very) simple Space Invaders game. Nothing flashy. No sounds, no explosions, not even any scores tracking (although, at some point, the aliens will move and shoot!).
Right now though the problem with my code is that I can shoot (and destroy) any aliens in the bottom row - but I can't destroy aliens in any other row. It's most perplexing - and I'd welcome any advice that anyone can offer.
This is my code:
# !/usr/bin/python
import pygame
bulletDelay = 40
class Bullet(object):
def __init__(self, xpos, ypos):
self.image = pygame.image.load("bullet.bmp")
self.rect = self.image.get_rect()
self.x = xpos
self.y = ypos
def current_position(self):
return [self.x, self.y]
def draw(self, surface):
surface.blit(self.image, (self.x, self.y))
class Player(object):
def __init__(self, screen):
self.image = pygame.image.load("spaceship.bmp") # load the spaceship image
self.rect = self.image.get_rect() # get the size of the spaceship
size = screen.get_rect()
self.x = (size.width * 0.5) - (self.rect.width * 0.5) # draw the spaceship in the horizontal middle
self.y = size.height - self.rect.height # draw the spaceship at the bottom
def current_position(self):
return self.x
def draw(self, surface):
surface.blit(self.image, (self.x, self.y)) # blit to the player position
class Alien(object):
def __init__(self, xpos, ypos):
self.image = pygame.image.load("alien.bmp") # load the alien image
self.rect = self.image.get_rect() # get the size of the alien
self.x = xpos
self.y = ypos
def current_position(self):
return [self.x, self.y]
def draw(self, surface):
surface.blit(self.image, (self.x, self.y)) # blit to the player position
def collision(alien,bullet):
if ((alien.current_position()[0] < bullet.current_position()[0] + 10) and
(alien.current_position()[0] > bullet.current_position()[0] - 10) and
(alien.current_position()[1] == bullet.current_position()[1])):
return True
else:
return False
def destroyObject(objectArray,killList):
if len(killList) > 0: # remove any bullets that have hit an alien
for item in killList:
del objectArray[item]
pygame.init()
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
player = Player(screen) # create the player sprite
missiles = [] # create missile array
aliensW = 6
aliensH = 3
# layout the initial field of aliens
aliens = [[Alien((screen.get_rect().width/7)*(x+0.75),(screen.get_rect().height/5)*(y+0.5)) for x in range(aliensW)] for y in range(aliensH)]
running = True
counter = bulletDelay
while running: # the event loop
counter=counter+1
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
key = pygame.key.get_pressed()
dist = 5 # distance moved for each key press
if key[pygame.K_RIGHT]: # right key
player.x += dist
elif key[pygame.K_LEFT]: # left key
player.x -= dist
elif key[pygame.K_SPACE]: # fire key
if counter > bulletDelay:
missiles.append(Bullet(player.current_position(),screen.get_rect().height))
counter=0
screen.fill((255, 255, 255)) # fill the screen with white - without this the old graphics will remain onscreen.
for m in missiles:
if m.y < (screen.get_rect()).height+1 and m.y > 0:
m.draw(screen)
m.y -= 5
else:
missiles.pop(0)
alienGrid = []
for a in aliens:
killList=[]
spentBullets=[]
alienNumber=0
alienRow = a
for b in alienRow:
#need to move aliens as well!
missileNumber=0
for m in missiles:
if (collision(b,m)):
killList.insert(0,alienNumber)
spentBullets.insert(0,missileNumber)
missileNumber+=1
alienNumber += 1
b.draw(screen)
destroyObject(alienRow,killList)
destroyObject(missiles,spentBullets)
alienGrid.insert(0,alienRow)
aliens = alienGrid
player.draw(screen) # draw the spaceship to the screen
pygame.display.update() # update the screen
clock.tick(40)
Of course, I also welcome any other advice that you might be able to offer for improving my code!
Use print() to check values in variables and which part of code is executed. This way you can find problem (if you don't know how to use debuger)
Problem is
alien.current_position()[1] == bullet.current_position()[1]
which not always is true because missile moves 5 pixels, not 1px.
Besides you use 0.75 and 0.5 in calculations of alien positions so you have float values.
You could use self.rect to keep position and then you could use
def collision(alien, bullet):
return alien.rect.colliderect(bullet.rect)
and
def draw(self, surface):
surface.blit(self.image, self.rect)
My version with many modifications. I use class inherition. And I use time (instead of counting frame) to control missiles.
# !/usr/bin/python
import pygame
# --- constants ---
BULLET_DELAY = 1000 # 1000ms = 1s
BULLET_DIST = 5 # distance moved for each key press
RED = (255, 0, 0)
WHITE = (255, 255, 255)
FPS = 40
# --- classes ---
class Sprite(object):
def __init__(self, xpos, ypos, image=None):
if image:
self.image = pygame.image.load(image)
else:
self.image = pygame.Surface(50,50)
self.image.fill(RED)
self.rect = self.image.get_rect(x=xpos, y=ypos)
def current_position(self):
return self.rect
def draw(self, surface):
surface.blit(self.image, self.rect)
class Bullet(Sprite):
def __init__(self, xpos, ypos):
Sprite.__init__(self, xpos, ypos, "bullet.bmp")
# modificate position
self.rect.centerx = xpos
self.rect.bottom = ypos
class Alien(Sprite):
def __init__(self, xpos, ypos):
Sprite.__init__(self, xpos, ypos, "alien.bmp")
class Player(Sprite):
def __init__(self, xpos, ypos):
Sprite.__init__(self, xpos, ypos, "spaceship.bmp")
# modificate position
self.rect.centerx = xpos
self.rect.bottom = ypos
# --- main ---
pygame.init()
screen = pygame.display.set_mode((640, 480))
screen_rect = screen.get_rect()
# -
player = Player(screen_rect.centerx, screen_rect.bottom) # create the player sprite
# -
missiles = [] # create missile array
# -
aliensW = 6
aliensH = 3
# layout the initial field of aliens
sx = screen_rect.width/7
sy = screen_rect.width/7
aliens = [[Alien(sx*(x+0.75),sy*(y+0.5)) for x in range(aliensW)] for y in range(aliensH)]
# move direction
move_left = False
# ---
current_time = pygame.time.get_ticks()
# missile delay
next_missile_time = current_time
# --- mainloop ---
clock = pygame.time.Clock()
running = True
while running: # the event loop
current_time = pygame.time.get_ticks()
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
key = pygame.key.get_pressed()
if key[pygame.K_RIGHT]: # right key
player.rect.x += BULLET_DIST
if player.rect.right > screen_rect.right:
player.rect.right = screen_rect.right
if key[pygame.K_LEFT]: # left key
player.rect.x -= BULLET_DIST
if player.rect.left < screen_rect.left:
player.rect.left = screen_rect.left
if key[pygame.K_SPACE]: # fire key
if current_time >= next_missile_time:
print('[D] fire')
missiles.append(Bullet(player.rect.centerx, player.rect.top))
# missile delay
next_missile_time = current_time + BULLET_DELAY
# --- updates (without draws) ---
# move missiles (and remove if leaves screen)
temp = []
for m in missiles:
m.rect.y -= BULLET_DIST
if m.rect.bottom >= 0:
temp.append(m)
missiles = temp
# move aliens (and check collisio)
temp = []
next_direction = move_left
for row in aliens:
temp_row = []
for a in row:
if move_left:
# move
a.rect.x -= 1
# check collision
for i, m in enumerate(missiles):
if a.rect.colliderect(m.rect):
# remove missile
del missiles[i]
# don't check collisions with other misilles
break
else: # chech only if "no break" so "no collide"
# chech if change direction
if a.rect.left == screen_rect.left:
# need to change direction but don't change `move_left` yet
next_direction = False
# add if not collide
temp_row.append(a)
else:
# move
a.rect.x += 1
# check collision
for i, m in enumerate(missiles):
if a.rect.colliderect(m.rect):
# remove missile
del missiles[i]
# don't check collisions with other misilles
break
else: # chech only if "no break" so "no collide"
# chech if change direction
if a.rect.right == screen_rect.right:
# need to change direction but don't change `move_left` yet
next_direction = True
# add if not collide
temp_row.append(a)
temp.append(temp_row)
# change after all checkings
move_left = next_direction
# new list without hitted aliens
aliens = temp
# --- draws (without updates) ---
screen.fill(WHITE) # fill the screen with white - without this the old graphics will remain onscreen.
for row in aliens:
for a in row:
a.draw(screen)
for m in missiles:
m.draw(screen)
player.draw(screen) # draw the spaceship to the screen
pygame.display.update() # update the screen
# --- FPS ---
clock.tick(FPS)

Pygame: Collision of two images

I'm working on my school project for which im designing a 2D game.
I have 3 images, one is the player and the other 2 are instances (coffee and computer). What i want to do is, when the player image collides with one of the 2 instances i want the program to print something.
I'm unsure if image collision is possible. But i know rect collision is possible. However, after several failed attempts, i can't manage to make my images rects. Somebody please help me. Here is my source code:
import pygame
import os
black=(0,0,0)
white=(255,255,255)
blue=(0,0,255)
class Player(object):
def __init__(self):
self.image = pygame.image.load("player1.png")
self.image2 = pygame.transform.flip(self.image, True, False)
self.coffee=pygame.image.load("coffee.png")
self.computer=pygame.image.load("computer.png")
self.flipped = False
self.x = 0
self.y = 0
def handle_keys(self):
""" Movement keys """
key = pygame.key.get_pressed()
dist = 5
if key[pygame.K_DOWN]:
self.y += dist
elif key[pygame.K_UP]:
self.y -= dist
if key[pygame.K_RIGHT]:
self.x += dist
self.flipped = False
elif key[pygame.K_LEFT]:
self.x -= dist
self.flipped = True
def draw(self, surface):
if self.flipped:
image = self.image2
else:
im = self.image
for x in range(0, 810, 10):
pygame.draw.rect(screen, black, [x, 0, 10, 10])
pygame.draw.rect(screen, black, [x, 610, 10, 10])
for x in range(0, 610, 10):
pygame.draw.rect(screen, black, [0, x, 10, 10])
pygame.draw.rect(screen, black, [810, x, 10, 10])
surface.blit(self.coffee, (725,500))
surface.blit(self.computer,(15,500))
surface.blit(im, (self.x, self.y))
pygame.init()
screen = pygame.display.set_mode((800, 600))#creates the screen
player = Player()
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit() # quit the screen
running = False
player.handle_keys() # movement keys
screen.fill((255,255,255)) # fill the screen with white
player.draw(screen) # draw the player to the screen
pygame.display.update() # update the screen
clock.tick(60) # Limits Frames Per Second to 60 or less
Use pygame.Rect() to keep image size and position.
Image (or rather pygame.Surface()) has function get_rect() which returns pygame.Rect() with image size (and position).
self.rect = self.image.get_rect()
Now you can set start position ie. (0, 0)
self.rect.x = 0
self.rect.y = 0
# or
self.rect.topleft = (0, 0)
# or
self.rect = self.image.get_rect(x=0, y=0)
(Rect use left top corner as (x,y)).
Use it to change position
self.rect.x += dist
and to draw image
surface.blit(self.image, self.rect)
and then you can test collision
if self.rect.colliderect(self.rect_coffe):
BTW: and now class Player looks almost like pygame.sprite.Sprite :)

Categories

Resources