size = width, height = 800, 500
display_surface = pygame.display.set_mode((width, height))
self.screen = pygame.display.set_mode(size)
pygame.display.set_caption("Temperature Test")
myfont = pygame.font.SysFont("freesansbold.ttf", 25)
white = (255, 255, 255)
green = (0, 255, 0)
blue1 = (255, 0, 0)
black = (0,0,0)
red = (255, 0, 0)
while True:
pygame.display.update()
for row in sensor.pixels:
row.sort()
print(["Temperature is: {0}".format(temp) for temp in row], 1, red)
celsius = myfont.render("Temperature is: {0}".format(row[-1]), 1, red)
#pygame.draw.rect(screen, (0,0,0),celsius.get_rect())
screen.blit(celsius, celsius.get_rect(center=(160, 240)))
pygame.display.update()
I don't why the display is not working according to the code
To draw your text in different locations, you need to increment your y position every iteration, e.g.
y = starting_value
for foo in bar:
screen.blit(foo)
y += line_height
Here's a minimal example based on your code that shows how to render your text in different positions on the screen.
import pygame
# create placeholder class
class FakeSensor(object):
pass
# initialisations
pygame.init()
pygame.font.init()
size = width, height = 800, 500
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Temperature Test")
myfont = pygame.font.SysFont("freesansbold.ttf", 25)
white = (255, 255, 255)
green = (0, 255, 0)
blue1 = (255, 0, 0)
black = (0, 0, 0)
red = (255, 0, 0)
clock = pygame.time.Clock()
sensor = FakeSensor()
sensor.pixels = [[1, 2, 300.5], [1, 2, 311.2]]
running = True
while running:
pygame.display.update() # redundant
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill(green)
y = 240 # initial Y position
for row in sensor.pixels:
row.sort()
print(["Temperature is: {0}".format(temp) for temp in row], 1, red)
celsius = myfont.render("Temperature is: {0}".format(row[-1]), 1, red)
# pygame.draw.rect(screen, (0, 0, 0), celsius.get_rect(center=(160, y)), 1)
screen.blit(celsius, celsius.get_rect(center=(160, y)))
y += 20 # increment Y position for line spacing
pygame.display.update()
clock.tick(60) # limit frame rate
pygame.quit()
Note: the extra initial pygame.display.update() function call is so you can confirm for yourself that multiple calls are unrelated to your original error.
Related
I'm following the programarcadegames website to try and move an object along with mouse movement. When I run the program, the coordinates of the moving mouse print out as it goes which is good, but the issue is that the item itself is constantly stuck in its starting position. I've tried making changes and running them to see what went wrong but the same thing keeps happening. Here is my code so far:
import pygame
import random
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GRAY = (128, 128, 128)
pygame.init()
star_list = []
for i in range(50):
x = random.randrange(0, 700)
y = random.randrange(0, 700)
star_list.append([x, y])
# Set the width and height of the screen [width, height]
size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Space Game")
# Loop until the user clicks the close button.
done = False
# Draw spaceship
def draw_spaceship(screen, x ,y):
#body
pygame.draw.rect(screen, GRAY, [350,375,20,40], 0)
#wing1 pygame.draw.polygon(screen, BLUE, [[350,375], [330,375], [350,400]], 0)
pygame.draw.polygon(screen, GRAY, [[390,375], [365,375], [365,400]], 0)
#wing2
pygame.draw.polygon(screen, GRAY, [[350,375], [330,375], [350,400]], 0)
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
# -------- Main Program Loop -----------
while not done:
# --- Main event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
# Game logic
# Mouse movement
pos = pygame.mouse.get_pos()
print (pos)
x=pos[0]
y=pos[1]
# Background
screen.fill(BLACK)
# Process each star in the list
for i in range(len(star_list)):
pygame.draw.circle(screen, WHITE, star_list[i], 2)
star_list[i][1] += 1
if star_list[i][1] > 700:
y = random.randrange(-50, -10)
star_list[i][1] = y
x = random.randrange(0, 700)
star_list[i][0] = x
#call draw_spaceship
draw_spaceship(screen, 0, 0)
# --- Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# --- Limit to 60 frames per second
clock.tick(60)
# Close the window and quit.
pygame.quit()
Your draw_spaceship function draws the ship at a constant position. Draw the ship relative to the x and y coordiante:
def draw_spaceship(screen, x, y):
#body
pygame.draw.rect(screen, GRAY, [x-10, y-20, 20, 40], 0)
#wing1
pygame.draw.polygon(screen, GRAY, [[x+30,y-20], [x+10,y-20], [x+10,y+5]], 0)
#wing2
pygame.draw.polygon(screen, GRAY, [[x-10,y-20], [x-30,y-20], [x-10,y+5]], 0)
Call draw_spaceship with the current mouse position, instead of (0, 0):
while not done:
# [...]
#draw_spaceship(screen, 0, 0)
draw_spaceship(screen, pos[0], pos[1])
draw_spaceship is drawing your ship at a constant position, (0,0). You should change the call for that to something more like
draw_spaceship(screen, pos[0], pos[1])
Edit: It looks like your draw_spaceship() function has hardcoded values for where to draw the spaceship, without even using the x and y arguments given.
Something that looks like this but I want the image and text editable.
Instead of having something like:
title = menuFont.render("COMPUTER INFORMATION!", 1, BLACK)
screen.blit(title, Rect(50, 100, 400, 400))
Is it possible for the colour in the text to be an image instead, or an animation?
EDIT:
For those curious... when I imported the imaged, I had to change the end of the code a bit
screen.blit(texture, (50, 50))
screen.fill(BG_COLOR)
screen.blit(text_surface, (50, 170))
pg.display.update()
clock.tick(30)
The screen.fill comes after the texture... just a heads up :)
To texture your text, you can first render the text in white, then blit the texture onto it and pass pygame.BLEND_RGB_MULT as the special_flags argument to use the multiply blend mode. The texture will appear only on the opaque parts of the text surface.
Also, make sure that your texture is bigger than the text surface, otherwise some parts of the text will remain unaffected.
import pygame as pg
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
BG_COLOR = pg.Color('gray32')
FONT = pg.font.Font(None, 50)
# I create a grid texture for demonstration purposes here.
# Just load your image with pygame.image.load instead.
texture = pg.Surface((200, 100))
texture.fill((200, 100, 0))
for x in range(0, 201, 5):
pg.draw.line(texture, (0, 0, 0), (x, 0), (x, 200))
for y in range(0, 101, 5):
pg.draw.line(texture, (0, 0, 0), (0, y), (200, y))
# Render the text and use pure white as the color.
text_surface = FONT.render('Hello world!', True, (255, 255, 255))
# Now blit the texture onto the text surface and pass BLEND_RGB_MULT as
# the special_flags argument, so that only the opaque parts are affected.
text_surface.blit(texture, (0, 0), special_flags=pg.BLEND_RGB_MULT)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
screen.fill(BG_COLOR)
screen.blit(texture, (50, 50))
screen.blit(text_surface, (50, 170))
pg.display.flip()
clock.tick(30)
pg.quit()
Here's the animated version. You have to load the separate frames of the animation and do the same as above for each frame. Put the resulting surfaces into a list and then play them back in the main loop.
import pygame as pg
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
BG_COLOR = pg.Color('gray32')
FONT = pg.font.Font(None, 50)
# I create a grid texture for demonstration purposes here.
# Just load your image with pygame.image.load instead.
texture = pg.Surface((200, 100))
texture.fill((200, 100, 0))
for x in range(0, 201, 5):
pg.draw.line(texture, (0, 0, 0), (x, 0), (x, 200))
for y in range(0, 101, 5):
pg.draw.line(texture, (0, 0, 0), (0, y), (200, y))
# Render the text and use pure white as the color.
text_surface = FONT.render('Hello world!', True, (255, 255, 255))
frames = []
for i in range(5):
surf = text_surface.copy() # We need a fresh copy of the text.
# Now blit the texture onto the text surface and pass BLEND_RGB_MULT as
# the special_flags argument, so that only the opaque parts are affected.
# The y-position is shifted by -1 each iteration.
surf.blit(texture, (0, -1*i), special_flags=pg.BLEND_RGB_MULT)
frames.append(surf)
frame_counter = 0
frame_timer = 0
dt = 0
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
frame_timer += dt # Add the passed time.
if frame_timer >= 150: # If 150 milliseconds have passed...
frame_timer = 0 # Reset the timer.
frame_counter += 1 # Increment the counter.
frame_counter %= len(frames) # Keep it in the correct range.
screen.fill(BG_COLOR)
# Now use `frame_counter` as the list index and blit the surface.
screen.blit(frames[frame_counter], (50, 170))
pg.display.flip()
dt = clock.tick(60) # `dt` is the passed time in milliseconds.
pg.quit()
Question
I'm pretty new at Python and Pygame so I figured I'd jump right it head first and work on making a little rpg style game. I keep getting the error message below. I keep checking the code and re-watching the tutorial I'm following and I can't seem to find the problem.
I'm sure it's pretty obvious but I don't see the problem. I'm pretty sure I formatted the code in this post right but I don't know.
Error Message
Traceback (most recent call last):
File "C:\Users\Clayton\PycharmProjects\newgame\main.py", line 42, in <module>
gameDisplay.blit(Tiles.grass(x, y))
TypeError: 'pygame.Surface' object is not callable
Main.py
import pygame
from gamescripts.textures import *
# initialize PyGame
pygame.init()
# display information
# int defines number a an integer (ex1)
display_width = int(800)
display_height = int(600)
tile_size = 32
# color definitions
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
skyblue = (135, 206, 235)
yellow = (255, 255, 0)
# window
gameDisplay = pygame.display.set_mode((display_width, display_height),
pygame.HWSURFACE | pygame.DOUBLEBUF)
pygame.display.set_caption('test game')
clock = pygame.time.Clock()
crashed = False
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
print(event)
# render graphics
gameDisplay.fill(skyblue)
for x in range(0, 620, tile_size):
for y in range(0, 480, tile_size):
gameDisplay.blit(Tiles.grass(x, y))
# draws everything to window
pygame.display.update()
# num entered is game fps
clock.tick(60)
# quit PyGame
pygame.quit()
# quit python
quit()
Textures.py
import pygame
pygame.init()
class Tiles:
Size = 32
def load_texture(file, Size):
bitmap1 = pygame.image.load(file)
bitmap2 = pygame.transform.scale(bitmap1, (Size, Size))
surface = pygame.Surface((Size, Size), pygame.HWSURFACE | pygame.SRCALPHA)
surface.blit(bitmap2, (0, 0))
return surface
grass = load_texture('graphics\\grass.png', Size)
You have to create an instance of your Tiles class.
Your Tiles class cannot be directly blitted without creating an instance first.
#create a instance of `Tiles`
tile=Tiles()
tile.load_texture('graphics\\grass.png',32)
Implemented into your code:
import pygame
from gamescripts.textures import *
# initialize PyGame
pygame.init()
# display information
# int defines number a an integer (ex1)
display_width = int(800)
display_height = int(600)
tile_size = 32
# color definitions
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
skyblue = (135, 206, 235)
yellow = (255, 255, 0)
# window
gameDisplay = pygame.display.set_mode((display_width, display_height),
pygame.HWSURFACE | pygame.DOUBLEBUF)
pygame.display.set_caption('test game')
clock = pygame.time.Clock()
#create an instance of your `Tile` class
tile=Tile()
tile.load_texture('graphics\\grass.png',32)
crashed = False
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
print(event)
# render graphics
gameDisplay.fill(skyblue)
for x in range(0, 620, tile_size):
for y in range(0, 480, tile_size):
#choose example coordinates for x and y
gameDisplay.blit(tile,(x,y))
# draws everything to window
pygame.display.update()
# num entered is game fps
clock.tick(60)
# quit PyGame
pygame.quit()
# quit python
quit()
import pygame
pygame.init()
You should change your Tile class as well.
class Tiles:
#initialize your class
def__init__(self):
pass
#ALWAYS use self as the first parameter
def load_texture(self,file, Size):
bitmap1 = pygame.image.load(file)
bitmap2 = pygame.transform.scale(bitmap1, (Size, Size))
surface = pygame.Surface((Size, Size), pygame.HWSURFACE | pygame.SRCALPHA)
surface.blit(bitmap2, (0, 0))
return surface
I suggest you really take a look at the the pygame documentation and the python documentation.
You should also look at SO if your question was already posted. For example, I found this example.
It sounds like a simple thing to do , but I'm struggling.
I have a png image of a rectangle with a transparent centre called "zero". I want to change the colour of the visible part of the image. To try and change it, I have tried using "zero.fill" but no option I try changes only the non-transparent part, or it merges the new colour with the old and stays like that.
I'm not keen on installing numpy as I wish to take the finished program to a friend who doesn't have it. Any simple suggestions welcome.
I've got an example that works with per pixel alpha surfaces that can also be translucent. The fill function just loops over the surface's pixels and sets them to the new color, but keeps their alpha value. It's probably not recommendable to do this every frame with many surfaces. (Press f, g, h to change the color.)
import sys
import pygame as pg
def fill(surface, color):
"""Fill all pixels of the surface with color, preserve transparency."""
w, h = surface.get_size()
r, g, b, _ = color
for x in range(w):
for y in range(h):
a = surface.get_at((x, y))[3]
surface.set_at((x, y), pg.Color(r, g, b, a))
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
# Uncomment this for a non-translucent surface.
# surface = pg.Surface((100, 150), pg.SRCALPHA)
# pg.draw.circle(surface, pg.Color(40, 240, 120), (50, 50), 50)
surface = pg.image.load('bullet2.png').convert_alpha()
surface = pg.transform.rotozoom(surface, 0, 2)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
if event.type == pg.KEYDOWN:
if event.key == pg.K_f:
fill(surface, pg.Color(240, 200, 40))
if event.key == pg.K_g:
fill(surface, pg.Color(250, 10, 40))
if event.key == pg.K_h:
fill(surface, pg.Color(40, 240, 120))
screen.fill(pg.Color('lightskyblue4'))
pg.draw.rect(screen, pg.Color(40, 50, 50), (210, 210, 50, 90))
screen.blit(surface, (200, 200))
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
sys.exit()
In this version, the visible and transparent parts are the other way round to the original question as per Ankur's suggestion.
Here is the essential working code:
import pygame, sys
from pygame.locals import *
pygame.init()
def load_image(name):
image = pygame.image.load(name).convert()
return image
def resize(obj, w, h):
global scale
return pygame.transform.scale(obj, (int(w * scale), int(h * scale)))
pink = (255, 0, 160)
red = (255, 0, 0)
peach = (255, 118, 95)
blue = (0, 0, 255)
blue_1 = (38, 0, 160)
dark_yellow = (255, 174, 0)
green = (38, 137, 0)
orange = (255, 81, 0)
colour = [pink, red, peach, blue, blue_1, dark_yellow, green, orange, green]
clock = pygame.time.Clock()
scale = 4
screen = pygame.display.set_mode((292 * scale, 240 * scale),0, 32)
banner = load_image("banner.png") #292x35
zero = load_image("zero.png") #5x7
c = 0
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
rgb = colour[c]
c = c + 1
if c > 7:
c = 0
pygame.draw.line(banner, rgb, (53, 21), (53, 27), 5) #line the same size as zero image
banner.blit(zero, (51, 21)) #blit image with transparency over line
large_banner = resize(banner, 292, 35)
screen.blit(large_banner, (0, 0))
clock.tick(120)
pygame.display.flip()
pygame.quit()
sys.exit()
This code for drop all color brightness
def drop(surface):
w, h = surface.get_size()
for x in range(w):
for y in range(h):
r = surface.get_at((x, y))[0]
if r>150:
r-=50
g = surface.get_at((x, y))[1]
if g>150:
g-=50
b = surface.get_at((x, y))[2]
if b>150:
b-=50
a = surface.get_at((x, y))[3]
surface.set_at((x, y), pygame.Color(r, g, b, a))
img = pygame.image.load("image.png").convert_alpha()
drop(img)
Problem is that all I can see is a black screen when run, think the problem is to do with blitting but not 100% sure
#IMPORTING PYGAME
import pygame, sys
from pygame.locals import *
pygame.init()
FPS = 60
fpsClock = pygame.time.Clock()
windowSurface = pygame.display.set_mode((600,400), 0, 32)
pygame.display.set_caption("My Game")
#DIRECTIONS
LEFT = 1
DOWN = 3
UP = 7
RIGHT = 9
#SPEED OF MOVEMENT
MOVESPEED = 4
#COLOURS
WHITE = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
#DRAWING ASSETS/SPRITES
player1 = (windowSurface, pygame.Rect(200, 200, 20, 20), GREEN, UP)
player1.blit(pygame.surface.blit, (200), area=None, special_flags = 0)
player2 = (windowSurface, pygame.Rect(100, 100, 20, 20), GREEN, DOWN)
#player2 = (pygame.Surface.blit(, windowSurface))
barricade1 = {windowSurface:pygame.Rect(50, 5000, 20, 20), :GREEN, :UP}
#barricade1(pygame.Surface.blit(, windowSurface))
barricade2 = {windowSurface:pygame.Rect(250, 250, 20, 20), :GREEN, :DOWN}
#barricade2(pygame.Surface.blit(, windowSurface))
#ball = {'rect':pygame.Rect(200, 200, 20, 20), 'color':GREEN, 'dir':UPDOWNLEFTRIGHT}
#ball(pygame.Surface.blit(, windowSurface))
#SPRITE GROUPS
players = [player1, player2]
barricades = [barricade1, barricade2]
ball = [ball]
windowSurface.fill(WHITE)
pygame.display.update()
fpsclock = pygame.time.Clock
1. Your WHITE Variable is wrong. That is Black in RGB Format. White is (255,255,255)
2. You are filling the screen and immediately after that you update it.
First fill the screen and THEN you can draw your players on top.
windowSurface.fill(WHITE)
#Do drawing here
pygame.display.update()