sprite not showing up in pygame & invalid rectstyle object - python

I am following a tutorial on PyGame and in one of the tutorial we are creating a simple Space Invaders game. I have a few problems.
The spaceship sprite won't show on the screen, and 2. I get an error. (more details on that below)
Code:
import pygame, sys
from pygame.locals import *
clock = pygame.time.Clock() #framerate
size = x,y=800,600
screen = pygame.display.set_mode((size)) #creates window, with resolution of 1600,900
pygame.mouse.set_visible(0)
ship = pygame.image.load('ship.png')
ship_top = screen.get_height() - ship.get_height() #makes it so ship is in the centre at the bottom
ship_left = screen.get_width()/2 - ship.get_width()/2
while True: #main game loop
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
screen.fill(0,0,0)
screen.blit(ship,(ship_left,ship_top))
clock.tick(60)
pygame.display.update
Error:
Traceback (most recent call last):
File "D:\python_tuts\space_invaders.py", line 24, in <module>
screen.fill(0,0,0)
ValueError: invalid rectstyle object
So the sprites do not show, and I get that error.
Thanks,

The fill method looks like this:
fill(color, rect=None, special_flags=0) -> Rect
Since you are calling it like this:
screen.fill(0,0,0)
It assigns 0 to rect and special_flags. I think you meant to do this:
screen.fill((0,0,0))
It's even better to define color tuples at the start of your code
BLACK = (0,0,0)
screen.fill(BLACK)

Related

How to fix float integer TypeError in game

I'm making a game called Bunnies and Badgers and this is the code I have so far
import pygame
from pygame.locals import *
pygame.init()
width, height = 640, 480
screen = pygame.display.set_mode((width, height))
player = pygame.image.load("resources/images/dude.png")
grass = pygame.image.load("resources/images/grass.png")
castle = pygame.image.load("resources/images/castle.png")
while 1:
screen.fill(0)
screen.blit(player, (100, 100))
for x in range(width/grass.get_width()+1):
for y in range(height/grass.get_height()+1):
screen.blit(grass,(x*100, y*100))
screen.blit(castle,(0,30))
screen.blit(castle,(0, 135))
screen.blit(castle,(0, 240))
screen.blit(castle,(0, 345))
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit(0)
However, when I run the module, I get this error
Traceback (most recent call last):
File "C:\Users\Ben\Documents\U Game Online\Games\Bunnies and Badgers\game.py", line 12, in <module>
for x in range(width/grass.get_width()+1):
TypeError: 'float' object cannot be interpreted as an integer
I don't see any errors with the code given with the error.
The range function requires an integer argument. Just case the parameter to int when calling range.
for x in range(int(width/grass.get_width()+1)):
for y in range(int(height/grass.get_height()+1)):
screen.blit(grass,(x*100, y*100))

Pygame will not blit lists of images

I started building a simple window in python with pygame to iterate through a list of images and blit them.
import pygame
pygame.init()
Window = pygame.display.set_mode((800, 600))
bg = pygame.image.load("/Users/luke.redwine/Documents/Python/PyGame/Examples/pygame lesson spaceinvaders/space.jpg")
clock = pygame.time.Clock()
animateNeutral = [pygame.image.load("/Users/luke.redwine/Documents/Python/PyGame/Space Shooter Game/Plasma T Neutral %s.png"% frame)for frame in range (1,3)]
animateFiring = [pygame.image.load("/Users/luke.redwine/Documents/Python/PyGame/Space Shooter Game/plasma T fire %s.png"% frame)for frame in range (1,7)]
running = True
while running:
events = pygame.event.get()
keys = pygame.key.get_pressed()
for event in events:
if event.type==pygame.QUIT or keys[pygame.K_ESCAPE]:
pygame.quit()
Window.blit(bg, (0,0))
clock.tick(10)
Window.blit(animateNeutral)
Window.blit(animateFiring)
pygame.quit()
i tried to quickly make it so i could just see it animate, but it threw up this error:
Traceback (most recent call last):
File "/Users/luke.redwine/Documents/Python/PyGame/Space Shooter Game/space rpg.py", line 22, in <module>
Window.blit(animateNeutral)
TypeError: argument 1 must be pygame.Surface, not list
The blit function requires a surface argument.
You can use the built-in itertools.cycle to create a generator that will cycle through the images forever.
Here's some untested code based on your sample:
import itertools
import pygame
pygame.init()
Window = pygame.display.set_mode((800, 600))
bg = pygame.image.load("/Users/luke.redwine/Documents/Python/PyGame/Examples/pygame lesson spaceinvaders/space.jpg")
clock = pygame.time.Clock()
animateNeutral = [pygame.image.load("/Users/luke.redwine/Documents/Python/PyGame/Space Shooter Game/Plasma T Neutral %s.png"% frame)for frame in range (1,3)]
animateFiring = [pygame.image.load("/Users/luke.redwine/Documents/Python/PyGame/Space Shooter Game/plasma T fire %s.png"% frame)for frame in range (1,7)]
neutral_animations = itertools.cycle(animateNeutral)
firing_animations = itertools.cycle(animateFiring)
neutral_dest = (50, 50)
firing_dest = (200, 50)
running = True
while running:
events = pygame.event.get()
keys = pygame.key.get_pressed()
for event in events:
if event.type==pygame.QUIT or keys[pygame.K_ESCAPE]:
pygame.quit()
Window.blit(bg, (0,0))
clock.tick(10)
Window.blit(next(neutral_animations), neutral_dest)
Window.blit(next(firing_animations), firing_dest)
pygame.quit()
Alternatively you could manually track the index of the current animation frame, incrementing with each frame and resetting once greater than the length of the list.
EDIT: add destinations as required by surface.blit()
https://www.pygame.org/docs/ref/surface.html?highlight=blit#pygame.Surface.blit
be sure to check the link above, for some documentation, however it may be hard to find answers
Answer
Try using blits if you are trying to blit in sequences
for
animateNeutral = [pygame.image.load("/Users/luke.redwine/Documents/Python/PyGame/Space Shooter Game/Plasma T Neutral %s.png"% frame)for frame in range (1,3)]
animateFiring = [pygame.image.load("/Users/luke.redwine/Documents/Python/PyGame/Space Shooter Game/plasma T fire %s.png"% frame)for frame in range (1,7)]
This is a list of images, blits() takes a sequence of surfaces (in your case images)
If you are going to use many sprites, you should look into converting the surfaces, if they have transparency (alpha) use convert_alpha()

Images not showing on surface in pygame

I am attempting to make a game with two surfaces. However when I try and add an image to the game layer it doesn't show up. I have tried using pygame.display.flip() which, from what I understand, should update everything on the screen.
If I try to use either Game_Layer.update() or Game_Layer.flip() as seen in the code below... (I think Game_Layer.flip() doesn't work because .flip is used to update the entire screen and thus can't be called for specific layers but correct me if I am wrong).
#game play
def Dragon():
DragonIMG=pygame.image.load("Green Dragon.gif")
DragonIMG.convert()
global Game_Layer
x=0
y=0
Game_Layer.blit(DragonIMG,(x,y))
Game_Layer.update()
Dragon()
I get the following error message:
RESTART: C:\Users\Alex\OneDrive\A- Levels\1 COMPUTER SCIENCE\Course work\Coding\CSCW Pre Alfa 1.9.5.py
Traceback (most recent call last):
File "C:\Users\Alex\OneDrive\A- Levels\1 COMPUTER SCIENCE\Course work\Coding\CSCW Pre Alfa 1.9.5.py", line 133, in <module>
Dragon()
File "C:\Users\Alex\OneDrive\A- Levels\1 COMPUTER SCIENCE\Course work\Coding\CSCW Pre Alfa 1.9.5.py", line 131, in Dragon
Game_Layer.update()
AttributeError: 'pygame.Surface' object has no attribute 'update'
>>>
However when I try to display an image on the root layer using the code below it works.
#game play
def Dragon():
DragonIMG=pygame.image.load("Green Dragon.gif")
DragonIMG.convert()
global Base_Layer
x=0
y=0
Base_Layer.blit(DragonIMG,(x,y))
pygame.display.flip()
Dragon()
Below is the code I am using to set up the layers:
#libraries
import time, random, pygame, sqlite3, GIFimage2
pygame.init()
#screen setup
#variables
clock=pygame.time.Clock() #for use in .tick
black=pygame.color.Color("black") #set black
white=pygame.color.Color("white") #set white
#set up the base layer
Base_Layer=pygame.display.set_mode((1000,600)) #desplay setup
pygame.display.set_caption("Dragon King: Legacy") #set caption
black=(0,0,0) #colour set
Base_Layer.fill(black) #colour set
Base_Layer.convert() #converts the base layer, may have no effect in current position
icon=pygame.image.load("LOGO.png") #find logo
pygame.display.set_icon(icon) #set icon to logo
#set up the game layer
Game_Layer=pygame.Surface((600,600)) #set layer peramaters
Game_Layer.fill(white) #set layer to white
Game_Layer.convert() #converts the game layer, may have no effect in current position
Base_Layer.blit(Game_Layer, (10, 0)) #blit layer on to screen
pygame.display.flip() #get the layer to show
If anyone could explain to me why this is not working I would appreciate it. I would also appreciate if someone knows a way to display my images in the way I am currently (within a definition) without using global variables.
Pygame programs are usually structured similarly to the following example. First of all, initialize everything and load the images and other resources (do that only once ahead of the main loop), then, in the main while loop, handle the events, update the game and blit everything. Finally, call pygame.display.flip() or pygame.display.update() to make all changes visible and clock.tick(fps) to limit the frame rate.
import pygame
pygame.init()
screen = pygame.display.set_mode((1000, 600))
# Constants (use uppercase letters to signal that these shouldn't be modified).
BLACK = pygame.color.Color("black")
WHITE = pygame.color.Color("white")
GAME_LAYER = pygame.Surface((600, 600))
GAME_LAYER.fill(WHITE)
# convert() returns a new surface, so you have to assign it to a variable.
DRAGON_IMG = pygame.image.load("Green Dragon.gif").convert()
def main(screen):
clock = pygame.time.Clock()
# Variables
x = 0
y = 0
while True:
# Handle events.
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
# Game logic.
x += 1
# Clear the screen and blit everything.
screen.fill(BLACK)
screen.blit(GAME_LAYER, (10, 0))
screen.blit(DRAGON_IMG, (x, y))
pygame.display.flip()
clock.tick(60)
if __name__ == '__main__':
main(screen)
pygame.quit()
If you want to blit onto a background surface instead of the screen/display and it's unicolored, you can just fill the background surface each frame with the fill method, then blit the dragon and finally blit the background onto the screen:
game_layer.fill(WHITE)
game_layer.blit(DRAGON_IMG, (x, y))
screen.blit(game_layer, (10, 0))
Or if your background surface is an actual image, you can create a copy each frame and then blit onto this copy:
game_layer_copy = GAME_LAYER.copy()
game_layer_copy.blit(DRAGON_IMG, (x, y))
screen.blit(game_layer_copy, (10, 0))
Game_Layer is a surface, and surfaces have no update method. update is a function of pygame.display. pygame.display.update is like pygame.display.flip except you can specify what parts of the screen should be flipped.
Also, please don't use global if you have any other choice. It's considered better to wrap everything into a class, pass Game_Layer as a argument, or use pygame.display.get_surface()

PYTHON PYGAME Image

Hey i'm just making a small game in python its python 2.7.13 i'm using cause i'm used to its syntax(lol i have a syntax error in a way its to do with TypeError: argument 1 must be pygame.Surface, not function) but i'm taking an image from the same directory and trying to display it on screen just to get the layout of the game but i can't get it to work the error i get is on this line
display.blit(floor,(x,y))
THE ERROR:
Traceback (most recent call last):
File "1stgame.py", line 38, in
floor(x,y)
File "1stgame.py", line 25, in floor
display.blit(floor,(x,y))
TypeError: argument 1 must be pygame.Surface, not function
here's the code
import pygame
#Start pygame
pygame.init()
#Window/Screen/Display
display_x = 800
display_y = 600
display = pygame.display.set_mode((display_x,display_y))
pygame.display.set_caption('Platforms')
clock = pygame.time.Clock()
#Colors
black = (0,0,0)
green = (1,166,17)
#Images
floor = pygame.image.load('rock.jpg')
def floor(x,y):
display.blit(floor,(x,y))
x = (display_x * 0.45)
y = (display_y * 0.8)
not_dead=True
while not_dead:
for event in pygame.event.get():
if (event.type==pygame.QUIT):
not_dead=False
display.fill(black)
pygame.draw.rect(display, green, [0,550,800,50])
floor(x,y)
pygame.display.update()
clock.tick(60)
print "Hello"
pygame.quit()
You just need to read the traceback:
Here's the error:
def floor(x,y):
display.blit(floor,(x,y))
When you do def floor, you define the function floor. So, the value of floor is now a function instead of the surface you set earlier. So, in your function, you're trying to blit a function, and not a Surface.
You need to change the variable name of either
the function
the surface

Having Trouble Blitting Image From Dictionary

So I'm trying to get into using Pygame, but all of the tutorials I can find online utilize only one file. I played around with ideas on how I can load all of the images in a single function. and decided on saving them in a Dictionary. Problem is, when I try to paste the image from the dictionary, I get the following error:
Traceback (most recent call last):
File "J:\Growth of Deities\Main.py", line 32, in <module>
pygame.Surface.blit(Sprites["TileWastelandBasic"], (0, 0))
TypeError: argument 1 must be pygame.Surface, not tuple
So I played around with the code a bit and googled it for an hour or so, but I can't figure out why I'm getting an error. I assume it's because I can't save images in dictionaries, but I'm not certain. Does anyone have any ideas on how to fix it?
My Main File:
import pygame
from Startup import LoadTextures
pygame.init()
#Sets the color White
WHITE = (255, 255, 255)
#Sets screen size Variable
size = (900, 900)
#Sets Screen Size
screen = pygame.display.set_mode(size)
#Sets name of Game
pygame.display.set_caption("Growth of Deities")
closeWindow = False
clock = pygame.time.Clock()
Sprites = LoadTextures.Load()
while not closeWindow:
#Repeat while game is playing
for event in pygame.event.get():
#Close Window if you close the window
if event.type == pygame.QUIT:
closeWindow = True
#Logic Code
#Rendering Code
pygame.Surface.blit(Sprites["TileWastelandBasic"], (0, 0))
#Clear Screen
screen.fill(WHITE)
#Update Screen
pygame.display.flip()
#Set Tick Rate
clock.tick(60)
#Closes Game
pygame.quit()
My Image Loading File:
import pygame
import os, sys
def Load():
Sprites = {}
WastelandSprites = 'Assets\Textures\Tile Sprites\Wasteland'
Sprites["TileWastelandBasic"] = pygame.image.load(os.path.join(WastelandSprites + "\WastelandBasic.png")).convert_alpha()
Sprites["TileWastelandBasic"] = pygame.transform.scale(Sprites["TileWastelandBasic"], (50, 50)).convert_alpha()
return Sprites
The problem is not because of your dictionary. The signature of blit is
blit(source, dest, area=None, special_flags = 0) -> Rect
where source must be a surface. However, this assumes that blit is being invoked with a pygame.Surface instance as the receiver. Instead, you're calling the blit function from its class, which means that its signature is effectively
blit(self, source, dest, area=None, special_flags = 0) -> Rect
where self must also be a surface. You could fix your problem by changing the call to
pygame.Surface.blit(screen, Sprites["TileWastelandBasic"], (0, 0))
but I would recommend the more idiomatic
screen.blit(Sprites["TimeWastelandBasic"], (0, 0))
instead.
See: http://www.pygame.org/docs/ref/surface.html#pygame.Surface.blit

Categories

Resources