screen.blit error in Pygame - python

I'm trying to make arrow keys movement in pygame but screen.blit isn't working :/
it keeps coming with a error saying
>###AttributeError: 'builtin_function_or_method' object has no attribute 'blit'
here is my code:
import sys, pygame
from pygame.locals import *
pygame.init()
pygame.display.set_caption(" Arrow keys to move ")
#Colour Defintions
white = pygame.Color(255,255,255)
black = pygame.Color( 0, 0 ,0)
gray = pygame.Color(90, 90, 90)
silver = pygame.Color( 200, 200, 200)
red = pygame.Color( 200, 0 , 0)
blue = pygame.Color(0, 255, 0)
#screen size
size = width, height = 1024, 640
velocity = [5, -20]
screen = pygame.display.set_mode
sprite = pygame.image.load("sprite01.png")
spriterect = sprite.get_rect()
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
pressed_keys = pygame.key.get_pressed()
if pressed_keys[pygame.K_RIGHT]:
spriterect = spriterect.move(5, 0)
if pressed_keys[pygame.K_LEFT]:
spriterect = spriterect.move(-5, 0)
if pressed_keys[pygame.K_UP]:
spriterect = spriterect.move(0, 5)
if pressed_keys[pygame.K_UP]:
spriterect = spriterect.move(0, -5)
if spriterect.top < 0:
spriterect.top = 0
if spriterect.bottom > height:
spriterect.bottom = height
screen.blit(sprite(0, 0))
screen.blit(spriterect(0, 0))
pygame.display.flip()
clock.tick(120)}

You've missed the parentheses on your set_mode call, so are referencing a function rather than the return value from calling that function.
screen = pygame.display.set_mode
Should be:
screen = pygame.display.set_mode(size)

Related

transparent bits in pygame mask are black instead of being transparent

I have a program where it fills in the bits of a mask that are overlapped from another mask, but when I blit the mask of the overlapping bits onto the screen, the transparent bits are fully black for some reason? The program works as intended and I've tried converting the surface for the overlapping bits to per pixel alpha but the transparent bits are black
example gif
import pygame
import sprites
SCREEN_HEIGHT, SCREEN_WIDTH = 800, 800
running = True
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
clock = pygame.time.Clock()
player = sprites.Block((100, 100))
block2 = sprites.Block((100, 100))
blocks = pygame.sprite.Group(block2)
block2.rect.topleft = 150, 150
block2.image.fill((0, 255, 0))
while running:
events = pygame.event.get()
screen.fill((100, 100, 100))
for event in events:
if event.type == pygame.QUIT:
running = False
player.move(screen.get_rect())
screen.blit(player.image, player.rect)
blocks.draw(screen)
for block in blocks:
offset = (player.rect.x - block.rect.x, player.rect.y - block.rect.y)
colliding_bits = player.mask.overlap_mask(block.mask, offset)
colliding_bits_image = colliding_bits.to_surface(setcolor=(0, 255, 0))
screen.blit(colliding_bits_image, block.rect)
clock.tick(144)
pygame.display.flip()
code containing the sprite classes:
import pygame
class Block(pygame.sprite.Sprite):
def __init__(self, size):
self.image = pygame.image.load("flappy_bird.png")
self.rect = self.image.get_rect()
self.mask = pygame.mask.from_surface(self.image)
self.speed = 1
super().__init__()
def move(self, screen_rect):
pressed_keys = pygame.key.get_pressed()
if pressed_keys[pygame.K_w]:
self.rect.move_ip(0, -self.speed)
if pressed_keys[pygame.K_s]:
self.rect.move_ip(0, self.speed)
if pressed_keys[pygame.K_a]:
self.rect.move_ip(-self.speed, 0)
if pressed_keys[pygame.K_d]:
self.rect.move_ip(self.speed, 0)
self.rect.clamp_ip(screen_rect)
I added the unsetcolor attribute to the to_surface method and removed the line blocks.draw(screen) and it seems to produce the desired result :
from math import fabs
import pygame
import sprites
SCREEN_HEIGHT, SCREEN_WIDTH = 800, 800
running = True
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
clock = pygame.time.Clock()
player = sprites.Block((100, 100))
block2 = sprites.Block((100, 100))
blocks = pygame.sprite.Group(block2)
block2.rect.topleft = 150, 150
block2.image.fill((0, 255, 0))
while running:
events = pygame.event.get()
screen.fill((100, 100, 100))
for event in events:
if event.type == pygame.QUIT:
running = False
player.move(screen.get_rect())
screen.blit(player.image, player.rect)
for block in blocks:
offset = (player.rect.x - block.rect.x, player.rect.y - block.rect.y)
colliding_bits = player.mask.overlap_mask(block.mask, offset)
colliding_bits_image = colliding_bits.to_surface(setcolor=(0, 255, 0, 255), unsetcolor=(0, 0, 0, 0))
screen.blit(colliding_bits_image, block.rect)
clock.tick(144)
pygame.display.flip()

How to make entities take damage with color collision in pygame?

How do I make entities take damage with colors? I made a game with enemies shooting blue lasers and I want the player to take damage. And the player shoots a red laser. Upon detecting colors, I want a certain statement to be true. That would lower an entity's health by one. If color collision is a thing, it can be very useful for making many different games. Here is my code:
# importing packages
import pygame
import random
import time
import sys
# Initializing Pygame
pygame.init()
# Setting a display caption
pygame.display.set_caption("Space Invaders")
spaceship = pygame.image.load("spaceship2.png")
blue_enemy = pygame.image.load("blue_enemy.png")
green_enemy = pygame.image.load("green_enemy.png")
orange_enemy = pygame.image.load("orange_enemy.png")
pink_enemy = pygame.image.load("pink_enemy.png")
yellow_enemy = pygame.image.load("yellow_enemy.png")
# Creating a font
pygame.font.init()
font = pygame.font.SysFont("consolas", 30)
large_font = pygame.font.SysFont("consolas", 60)
small_font = pygame.font.SysFont("consolas", 20)
# Setting a display width and height and then creating it
display_width = 700
display_height = 500
display_size = [display_width, display_height]
game_display = pygame.display.set_mode(display_size)
intro_display = pygame.display.set_mode(display_size)
# Creating a way to add text to the screen
def message(sentence, color, x, y, font_type, display):
sentence = font_type.render(str.encode(sentence), True, color)
display.blit(sentence, [x, y])
def main():
global white
global black
global clock
# Spaceship coordinates
spaceship_x = 300
spaceship_y = 375
spaceship_x_change = 0
blue_enemy_health = 5
green_enemy_health = 5
orange_enemy_health = 5
pink_enemy_health = 5
yellow_enemy_health = 5
# Clock making
# Initializing pygame
pygame.init()
# Creating colors
red = (0, 0, 0)
blue = (0, 0, 255)
# clock stuff
clock = pygame.time.Clock()
time_elapsed_since_last_action = 0
time_elapsed_since_last_action2 = 0
time_elapsed_since_last_action3 = 0
# Creating a loop to keep program running
while True:
laser_rect = pygame.Rect(spaceship_x + 69, 70, 4, 310)
# --- Event Processing and controls
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
spaceship_x_change = 10
elif event.key == pygame.K_LEFT:
spaceship_x_change = -10
elif event.key == pygame.K_r:
red = (255, 0, 0)
elif time_elapsed_since_last_action2 > 250:
pygame.draw.rect(game_display, red, laser_rect)
time_elapsed_since_last_action2 = 0
elif event.type == pygame.KEYUP:
spaceship_x_change = 0
red = (0, 0, 0)
spaceship_x += spaceship_x_change
# Preventing the ship from going off the screen
if spaceship_x > display_width - 140:
spaceship_x -= 10
if spaceship_x < 1:
spaceship_x += 10
# Setting Display color
game_display.fill(black)
laser_coords = [70, 209, 348, 505, 630]
random_x_coord = random.choice(laser_coords)
dt = clock.tick()
time_elapsed_since_last_action += dt
if time_elapsed_since_last_action > 500:
pygame.draw.rect(game_display, blue, [random_x_coord, 85, 6, 305])
time_elapsed_since_last_action = 0
time_elapsed_since_last_action2 += dt
# Creating a spaceship, lasers, and enemies
game_display.blit(spaceship, (spaceship_x, spaceship_y))
message(str(blue_enemy_health), white, 65, 10, font, game_display)
game_display.blit(blue_enemy, (20, 25))
message(str(green_enemy_health), white, 203, 10, font, game_display)
game_display.blit(green_enemy, (160, 25))
message(str(orange_enemy_health), white, 341, 10, font, game_display)
game_display.blit(orange_enemy, (300, 25))
message(str(pink_enemy_health), white, 496, 10, font, game_display)
game_display.blit(pink_enemy, (440, 25))
message(str(yellow_enemy_health), white, 623, 10, font, game_display)
game_display.blit(yellow_enemy, (580, 25))
health = 10
message("Spaceship durability: " + str(health), white, 20, 480, small_font, game_display)
# Updating Screen so changes take places
pygame.display.update()
# Setting FPS
FPS = pygame.time.Clock()
FPS.tick(60)
black = (0, 0, 0)
white = (255, 255, 255)
gray = (100, 100, 100)
while True:
intro_display.fill(black)
pygame.event.poll()
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
message("Space Bugs", white, 180, 150, large_font, intro_display)
if 150 + 100 > mouse[0] > 150 and 350 + 50 > mouse[1] > 350:
pygame.draw.rect(game_display, gray, [150, 350, 100, 50])
if click[0] == 1:
break
else:
pygame.draw.rect(game_display, white, [150, 350, 100, 50])
if 450 + 100 > mouse[0] > 450 and 350 + 50 > mouse[1] > 350:
pygame.draw.rect(game_display, gray, [450, 350, 100, 50])
if click[0] == 1:
pygame.quit()
quit()
else:
pygame.draw.rect(game_display, white, [450, 350, 100, 50])
message("Start", black, 155, 360, font, intro_display)
message("Quit", black, 465, 360, font, intro_display)
# Go ahead and update the screen with what we've drawn.
pygame.display.update()
# Wrap-up
# Limit to 60 frames per second
clock = pygame.time.Clock()
clock.tick(60)
# Executing the function
if __name__ == "__main__":
main()
No, there is no such a "thing" as a "color collision". What color have the images? Are they uniformly colored? Most likely the pictures are only different in some details. A collision which checks for a uniform color is completely useless. A collision that also looks for a uniform color is almost useless.
If you detect a collision, you know the laser and the enemy. Hence, you know the color with which you represent them. All you have to do is do an additional check after the collision is detected.
Use pygame.sprite.Sprite to implement the objects. Add an attribute that indicates the color of the object:
class ColoredSprite(pygame.sprite.Sprite):
def __init__(self, x, y, image, color):
super().__init__()
self.image = image
self.rect = self.image.get_rect(center = (x, y)
slef.color = color
Manage the spites in pygame.sprite.Groups and use spritecollide to detect the collisions. Check the color attributes when a collision is detected
collide_list = sprite.spritecollide(sprite_group, False):
for other_sprite in collide_list:
if sprite.color == 'red' and other_sprite.color == 'blue':
# [...]
elif sprite.color == 'blue' and other_sprite.color == 'red':
# [...]
It is even possible to implement your own collision detection method and use it in combination with spritecollide by setting the optional collided argument:
def color_collision(sprite1, sprite2):
if sprite1.rect.colliderect(sprite2.rect):
return ((sprite1.color == 'red' and sprite2.color == 'blue') or
(sprite1.color == 'blue' and sprite2.color == 'red'))
return false
collide_list = sprite.spritecollide(sprite_group, False, color_collision):
for other_sprite in collide_list:
# [...]
Minimal example:
import pygame
pygame.init()
window = pygame.display.set_mode((250, 250))
sprite1 = pygame.sprite.Sprite()
sprite1.image = pygame.Surface((75, 75))
sprite1.image.fill('red')
sprite1.rect = pygame.Rect(*window.get_rect().center, 0, 0).inflate(75, 75)
sprite1.color = 'red'
sprite2 = pygame.sprite.Sprite()
sprite2.image = pygame.Surface((75, 75))
sprite2.image.fill('blue')
sprite2.rect = pygame.Rect(*window.get_rect().center, 0, 0).inflate(75, 75)
sprite2.color = 'blue'
all_group = pygame.sprite.Group([sprite2, sprite1])
def color_collision(sprite1, sprite2):
if sprite1.rect.colliderect(sprite2.rect):
return ((sprite1.color == 'red' and sprite2.color == 'blue') or
(sprite1.color == 'blue' and sprite2.color == 'red'))
return False
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
sprite1.rect.center = pygame.mouse.get_pos()
collide = pygame.sprite.spritecollide(sprite1, all_group, False, color_collision)
window.fill(0)
all_group.draw(window)
for s in collide:
pygame.draw.rect(window, (255, 255, 255), s.rect, 5, 1)
pygame.display.flip()
pygame.quit()
exit()

TypeError: text must be unicode or bytes & how to make a working bullet in pygame

I am making Space Invaders. Here is my code so far:
# importing packages
import pygame
# Initializing Pygame
pygame.init()
# Setting a display caption
pygame.display.set_caption("Space Invaders")
spaceship = pygame.image.load("spaceship2.png")
blue_enemy = pygame.image.load("blue_enemy.png")
green_enemy = pygame.image.load("green_enemy.png")
orange_enemy = pygame.image.load("orange_enemy.png")
pink_enemy = pygame.image.load("pink_enemy.png")
yellow_enemy = pygame.image.load("yellow_enemy.png")
# Creating a font
pygame.font.init()
font = pygame.font.SysFont("consolas", 30)
# Setting a display width and height and then creating it
display_width = 700
display_height = 500
display_size = [display_width, display_height]
game_display = pygame.display.set_mode(display_size)
# Creating a way to add text to the screen
def message(sentence, color, x, y, font_type, display):
sentence = font_type.render(sentence, True, color)
display.blit(sentence, [x, y])
def main():
# Spaceship coordinates
spaceship_x = 300
spaceship_y = 375
spaceship_x_change = 0
# Enemy health
blue_enemy_health = 5
green_enemy_health = 5
orange_enemy_health = 5
pink_enemy_health = 5
yellow_enemy_health = 5
# Initializing pygame
pygame.init()
# Creating colors
black = (0, 0, 0)
red = (0, 0, 0)
done = False
# Creating a loop to keep the program running
while not done:
# --- Event Processing and controls
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
spaceship_x_change = 7
elif event.key == pygame.K_LEFT:
spaceship_x_change = -7
elif event.key == pygame.K_r:
red = (255, 0, 0)
elif event.type == pygame.KEYUP:
spaceship_x_change = 0
red = (0, 0, 0)
spaceship_x += spaceship_x_change
# Preventing the spaceship from going off the screen
if spaceship_x > display_width - 140:
spaceship_x -= 10
if spaceship_x < 1:
spaceship_x += 10
# Setting Display color
game_display.fill(black)
# Creating a spaceship, bullets, and enemies
pygame.draw.rect(game_display, red, [spaceship_x + 69, 70, 4, 310])
game_display.blit(spaceship, (spaceship_x, spaceship_y))
message(blue_enemy_health, (255, 255, 255), 350, 250, font, game_display)
game_display.blit(blue_enemy, (20, 25))
game_display.blit(green_enemy, (160, 25))
game_display.blit(orange_enemy, (300, 25))
game_display.blit(pink_enemy, (440, 25))
game_display.blit(yellow_enemy, (580, 25))
# Updating Screen so changes take places
pygame.display.update()
# Setting FPS
FPS = pygame.time.Clock()
FPS.tick(60)
# Executing the function
if __name__ == "__main__":
main()
However, when I want to display my enemy health, it shows me this error. I don't know what to do about it, please help out. Also i am using an awkward "laser" that the spaceship shoots. I chose this as a shortcut around making bullets as I am new to pygame. If you can, please help with that too.
The error:
Traceback (most recent call last):
File "C:/Users/admin/PycharmProjects/ProgrammingLearn/SpaceInvaders.py", line 103, in <module>
main()
File "C:/Users/user/PycharmProjects/ProgrammingLearn/SpaceInvaders.py", line 86, in main
message(blue_enemy_health, (255, 255, 255), 350, 250, font, game_display)
File "C:/Users/user/PycharmProjects/ProgrammingLearn/SpaceInvaders.py", line 30, in message
sentence = font_type.render(sentence, True, color)
TypeError: text must be a unicode or bytes
The first argument of font_type.render needs to be a string, and you are passing an int into the sentence parameter (you are passing blue_enemy_health integer). You need to convert it into a string before rendering it with the font by str(blue_enemy_health) when you pass it into the message function.

how to generate random rectangles in a pygame and make them move like flappy bird?

I am a python beginner. I want to recreate chrome dino game. the random rectangle won't stop and the loop runs forever...please help me to stop the loop and make rectangles move.
Code:
import pygame
import random
pygame.init()
win = pygame.display.set_mode((500, 500))
#red rectangle(dino)
x = 20
y = 400
width = 30
height = 42
gravity = 5
vel = 18
black = (0, 0, 0)
#ground
start_pos = [0, 470]
end_pos = [500, 470]
#cactus
x1 = 20
y1 = 30
white = (2, 200, 200)
run = True
clock = pygame.time.Clock()
while run:
clock.tick(30)
pygame.time.delay(10)
win.fill(black)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#random rectangle generation
for i in range(1):
width2 = random.randint(25, 25)
height2 = random.randint(60, 60)
top = random.randint(412, 412)
left = random.randint(300, 800)
rect = pygame.draw.rect(win, white, (left, top, width2,height2))
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
y = y - vel
else:
y = min(428, y + gravity)
pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.draw.line(win, white, start_pos, end_pos, 2)
pygame.display.update()
pygame.display.flip()
pygame.quit()
pygame.draw.rect() des not "generate" a rectangle, it draws a rectangle on a surface.
pygame.Rect is a rectangle object. Create an instance of pygame.Rect before the main application loop:
obstracle = pygame.Rect(500, random.randint(0, 412), 25, 60)
Change the position of the rectangle:
obstracle.x -= 3
if obstracle.right <= 0:
obstracle.y = random.randint(0, 412)
And draw the rectangle to the window surface:
pygame.draw.rect(win, white, obstracle)
Example:
import pygame
import random
pygame.init()
win = pygame.display.set_mode((500, 500))
start_pos = [0, 470]
end_pos = [500, 470]
gravity = 5
vel = 18
black = (0, 0, 0)
white = (2, 200, 200)
hit = 0
dino = pygame.Rect(20, 400, 30, 40)
obstracles = []
number = 5
for i in range(number):
ox = 500 + i * 500 // number
oy = random.randint(0, 412)
obstracles.append(pygame.Rect(ox, oy, 25, 60))
run = True
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
dino.y -= vel
else:
dino.y = min(428, dino.y + gravity)
for obstracle in obstracles:
obstracle.x -= 3
if obstracle.right <= 0:
obstracle.x = 500
obstracle.y = random.randint(0, 412)
if dino.colliderect(obstracle):
hit += 1
win.fill(black)
color = (min(hit, 255), max(255-hit, 0), 0)
pygame.draw.rect(win, color, dino)
for obstracle in obstracles:
pygame.draw.rect(win, white, obstracle)
pygame.draw.line(win, white, start_pos, end_pos, 2)
pygame.display.update()
pygame.quit()

Can't draw rect in python pygame

I'm just getting started with PyGame. Here, I'm trying to draw a rectangle, but it's not rendering.
Here's the whole program.
import pygame
from pygame.locals import *
import sys
import random
pygame.init()
pygame.display.set_caption("Rafi's Game")
clock = pygame.time.Clock()
screen = pygame.display.set_mode((700, 500))
class Entity():
def __init__(self, x, y):
self.x = x
self.y = y
class Hero(Entity):
def __init__(self):
Entity.__init__
self.x = 0
self.y = 0
def draw(self):
pygame.draw.rect(screen, (255, 0, 0), ((self.x, self.y), (50, 50)), 1)
hero = Hero()
#--------------Main Loop-----------------
while True:
hero.draw()
keysPressed = pygame.key.get_pressed()
if keysPressed[K_a]:
hero.x = hero.x - 3
if keysPressed[K_d]:
hero.x = hero.x + 3
if keysPressed[K_w]:
hero.y = hero.y - 3
if keysPressed[K_s]:
hero.y = hero.y + 3
screen.fill((0, 255, 0))
#Event Procesing
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
#Event Processing End
pygame.display.flip()
clock.tick(20)
self.x and self.y are currently 0 and 0.
Note that this is not a finished program, all it should do is draw a red square on a green background that can be controled by the WASD keys.
Let's look at a portion of your main loop:
while True:
hero.draw()
keysPressed = pygame.key.get_pressed()
if keysPressed[K_a]:
hero.x = hero.x - 3
if keysPressed[K_d]:
hero.x = hero.x + 3
if keysPressed[K_w]:
hero.y = hero.y - 3
if keysPressed[K_s]:
hero.y = hero.y + 3
screen.fill((0, 255, 0))
Inside the Hero class's draw function, you are drawing the rect. In the main loop, you are calling hero.draw(), and then after handling your inputs, you are calling screen.fill(). This is drawing over the rect you just drew. Try this:
while True:
screen.fill((0, 255, 0))
hero.draw()
keysPressed = pygame.key.get_pressed()
....
That will color the entire screen green, then draw your rect over the green screen.
This is more of an extended comment and question than an answer.
The following draws a red square. Does it work for you?
import sys
import pygame
pygame.init()
size = 320, 240
black = 0, 0, 0
red = 255, 0, 0
screen = pygame.display.set_mode(size)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill(black)
# Either of the following works. Without the fourth argument,
# the rectangle is filled.
pygame.draw.rect(screen, red, (10,10,50,50))
#pygame.draw.rect(screen, red, (10,10,50,50), 1)
pygame.display.flip()
Check these links:
http://www.pygame.org/docs/ref/draw.html#pygame.draw.rect
And here have a some examples:
http://nullege.com/codes/search?cq=pygame.draw.rect
pygame.draw.rect(screen, color, (x,y,width,height), thickness)
pygame.draw.rect(screen, (255, 0, 0), (self.x, self.y, 50, 50), 1)

Categories

Resources