So I am making a space invaders game in python, the game will take the score the player has achieved and will add it to a csv file. My code for the csv file is:
col = pygame.sprite.spritecollideany(player, mobs)
if col:
with open("rec_Scores.csv", "a", newline" ") as f:
w = csv.writer(f, dilimiter = ",")
for i in range(len(score)):
w.writerow(name[i], score[i]])
crashed = True
However, I get the error:
File "C:\Users\Harry\Desktop\Desktop\Computing Project\Galaxian.py", line 162
with open("rec_Scores.csv", "a", newline" ") as f:
^
SyntaxError: invalid syntax
I am really stuck with this problem and I have no idea how to solve it. Any help would be much appreciated. Here is my code because I am probably going about this in a completely idiotic way:
import pygame
import random
import sys
import csv
# --- constants --- (UPPER_CASE names)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
ORANGE = (255, 255, 0)
YELLOW = (0, 255, 255)
DISPLAY_WIDTH = 720
DISPLAY_HEIGHT = 720 # sets res for the screen
FPS = 60
# --- classes --- (CamelCase names)
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("images\\user1.gif").convert()
self.image = pygame.transform.scale(self.image, (50, 50))
self.rect = self.image.get_rect()
self.speed_x = 0
def update(self):
self.speed_x = 0
keystate = pygame.key.get_pressed()
if keystate[pygame.K_LEFT]:
self.speed_x = -10
if keystate[pygame.K_RIGHT]:
self.speed_x = 10
self.rect.x += self.speed_x
if self.rect.right > DISPLAY_WIDTH:
self.rect.right = DISPLAY_WIDTH
if self.rect.left < 0:
self.rect.left = 0
def shoot(self):
bullet = Bullet(self.rect.centerx, self.rect.top)
all_sprites.add(bullet)
bullet_group.add(bullet)
class Mob(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.speed_y = random.randrange(5, 11)
self.image = pygame.image.load("images\\enemy1.gif").convert()
self.image = pygame.transform.scale(self.image, (50, 50))
self.rect = self.image.get_rect()
self.speed_x = 0
self.rect.x = random.randrange(0, DISPLAY_WIDTH - self.rect.width)
self.rect.y = random.randrange(-500, -40)
self.speedy = random.randrange(5, 11)
def update(self):
self.rect.y += self.speedy
if self.rect.top > DISPLAY_HEIGHT + 10:
self.rect.x = random.randrange(0, DISPLAY_WIDTH - self.rect.width)
self.rect.y = random.randrange(-500, -40)
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("images\\laser1.gif").convert() # sets the laser to be the image laser1.gif
self.image = pygame.transform.scale(self.image, (15, 25)) # trasforms the size to fit the screen
self.rect = self.image.get_rect() # sets hit box up, will fit around the image
self.rect.bottom = y
self.rect.centerx = x
self.speed_y = -30
def update(self):
self.rect.y += self.speed_y
if self.rect.bottom < 0:
self.kill()
# --- functions --- (lower_case names)
# --- main --- (lower_case names)
score =0
name = raw_input("Enter your name: ")
# - init -
pygame.init()
pygame.mixer.init()
display = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
display_rect = display.get_rect()
# - objects and groups -
all_sprites = pygame.sprite.Group() # creates class that all sprites will be in
mobs = pygame.sprite.Group() # creates class that all mobs will be stored in
bullet_group = pygame.sprite.Group() # creates class that all bullets will be stored in
player = Player() # assigns the player variable to the player class
player.rect.center = ((DISPLAY_WIDTH / 2), DISPLAY_HEIGHT / 1.2) # sets the player to spawn at the bottom and in the middle of the screen
all_sprites.add(player) # adds player to the all_sprites group
for z in range(12): # spawns 13 enemies
mob = Mob()
mobs.add(mob)
all_sprites.add(mob)
# - other -
pygame.mixer.music.load("audio\\soundtrack.mp3")
pygame.mixer.music.play(-1) # sets music to play in an infinite loop
pygame.mixer.music.set_volume(0.2)
# - mainloop -
crashed = False
clock = pygame.time.Clock()
while not crashed:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LCTRL:
player.shoot()
print(event)
# - updates (without draws) -
all_sprites.update() # updates sprite positions without drawing them onto the screen
# - draws (without updates) -
background = pygame.image.load("images\\background.jpg") # assigns the picture to a variable called background
background = pygame.transform.scale(background, (DISPLAY_WIDTH, DISPLAY_HEIGHT)) # streches the picture to fit the screen
display.blit(background, (0, 0)) # displays the background image
all_sprites.draw(display) # draws all sprites onto the screen
font = pygame.font.SysFont("monospace", 15)
text = font.render("Score: " + str(score), True, BLACK)
display.blit(text, (0, 0))
pygame.display.update() # updates display
# - Checks for a hit -
col = pygame.sprite.groupcollide(mobs, bullet_group, True, True)
if col: # if col = true then
mob = Mob() # spawns new mob
mobs.add(mob)
all_sprites.add(mob)
score += 10
# - checks for a collision -
col = pygame.sprite.spritecollideany(player, mobs)
if col:
with open("rec_Scores.csv", "a", newline" ") as f:
w = csv.writer(f, dilimiter = ",")
for i in range(len(score)):
w.writerow(name[i], score[i]])
crashed = True
# - FPS -
clock.tick(FPS) # built in function to make the program stay below specified frame per second
# - end -
pygame.quit()
Thank you in advance for any help.
with open("rec_Scores.csv", "a", newline" ") as f:
Should be:
with open("rec_Scores.csv", "a") as f:
delimiter is misspelled as dilimiter but is unneeded anyway.
The f.writerow arguments are not quite what you want here.
Next time try making a working reproducer that has all bits of code needed to work including import statements.
Actual working version:
import csv
name=['foo','bar']
score=[12345,54321]
with open("rec_Scores.csv", "a") as f:
w = csv.writer(f)
for i in range(len(score)):
w.writerow([str(name[i]),str(score[i])])
Related
Hello I am new to pygame and I am trying to write a shmup game.
However I am always having this error:
TypeError: add() argument after * must be an iterable, not int
self.add(*group)
This is the traceback of the error:
File "C:/Users/Pygame/game.py", line 195, in
player.shoot()
File "C:/Users/Pygame/game.py", line 78, in shoot
bullet = Bullets(self.rect.center,self.angle)
File "C:/Users/Pygame/game.py", line 124, in init
super(Bullets,self).init(pos,angle)
This is the code I have written so far, it works well however when the user wants to shoot the error is being raised.
import os
import pygame
import random
import math
WIDTH = 480
HEIGHT = 600
FPS = 60
#colors:
WHITE = (255,255,255)
BLACK = (0,0,0)
GREEN = (0,250,0)
RED = (255,0,0)
BLUE = (0,0,255)
YELLOW = (255,255,0)
#setup assets
game_folder = os.path.dirname("C:/Users/PygameP/")
img_folder = os.path.join(game_folder,"img")
#intialise pygame
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH,HEIGHT))
clock = pygame.time.Clock()
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50,40))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.centerx = WIDTH/2
self.rect.bottom = HEIGHT-10
#controls the speed
self.angle = 0
self.orig_image = self.image
#self.rect = self.image.get_rect(center=pos)
def update(self):
keystate = pygame.key.get_pressed()
if keystate[pygame.K_LEFT]:
self.angle -= 5
self.rotate()
if keystate[pygame.K_RIGHT]:
self.angle += 5
self.rotate()
def rotate(self):
self.image = pygame.transform.rotozoom(self.orig_image, self.angle, 1)
self.rect = self.image.get_rect(center=self.rect.center)
def shoot(self):
bullet = Bullets(self.rect.center,self.angle)
all_sprites.add(bullet)
bullets.add(bullet)
class Mob(pygame.sprite.Sprite):
def __init__(self):
super(Mob,self).__init__()
self.image = pygame.Surface((30,40))
self.image = meteor_img
self.image = pygame.transform.scale(meteor_img,(50,38))
self.image.set_colorkey(BLACK)
self.rect = self.image.get_rect()
self.radius = int(self.rect.width/2)
self.rect.x = random.randrange(0,WIDTH - self.rect.width)
self.rect.y = random.randrange(-100,-40)
self.speedy = random.randrange(1,8)
#updating the position of the sprite
def update(self):
self.rect.y += self.speedy
if self.rect.top > HEIGHT + 10:
self.rect.x = random.randrange(0,WIDTH - self.rect.width)
self.rect.y = random.randrange(-100,-40)
self.speedy = random.randrange(1,8)
class Bullets(pygame.sprite.Sprite):
def __init__(self,pos,angle):
super(Bullets,self).__init__(pos,angle)
# Rotate the image.
self.image = pygame.Surface((10,20))
self.image = bullet_img
self.image = pygame.transform.scale(bullet_img,(50,38))
self.image = pygame.transform.rotate(bullet_img, angle)
self.rect = self.image.get_rect()
speed = 5
self.velocity_x = math.cos(math.radians(-angle))*speed
self.velocity_y = math.sin(math.radians(-angle))*speed
#store the actual position
self.pos = list(pos)
def update(self):
self.pos[0] += self.velocity_x
self.pos[1] += self.velocity_y
self.rect.center = self.pos
if self.rect.bottom <0:
self.kill()
#load all game graphics
background = pygame.image.load(os.path.join(img_folder,"background.png")).convert()
background_rect = background.get_rect()
player_img = pygame.image.load(os.path.join(img_folder,"arrow.png")).convert()
bullet_img = pygame.image.load(os.path.join(img_folder,"bullet.png")).convert()
meteor_img = pygame.image.load(os.path.join(img_folder,"m.png")).convert()
#creating a group to store sprites to make it easier to deal with them
#every sprite we make goes to this group
all_sprites = pygame.sprite.Group()
mobs = pygame.sprite.Group()
bullets = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
for i in range(8):
m = Mob()
all_sprites.add(m)
mobs.add(m)
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
player.shoot()
#Update
all_sprites.update()
#checking if a bullet hits a mob
hits = pygame.sprite.groupcollide(mobs,bullets,True,True)
for hit in hits:
m = Mob()
all_sprites.add(m)
mobs.add(m)
hits = pygame.sprite.spritecollide(player,mobs, False,pygame.sprite.collide_circle)
#drawing the new sprites here
screen.fill(BLACK)
#show the background image
screen.blit(background,background_rect)
all_sprites.draw(screen)
pygame.display.flip()
pygame.quit()
Any comments?
You're passing the pos and the angle to the __init__ method of pygame.sprite.Sprite here,
super(Bullets,self).__init__(pos,angle)
but you can only pass sprite groups to which this sprite instance will be added. So just remove those arguments:
super(Bullets,self).__init__()
I am in the process of making a 'main character' which jumps around and can jump onto boxes etc using pygame. I have created the Player class, the Level class and the Box class. The spritecollide function never returns true, and I am unsure where I am going wrong.
I used spritecollideany and groupcollide to see if that helps (it didn't)
I have checked as best I can, and as far as I can tell the boxes are making their way into Level.box_list as a sprite Group, and both the boxes and the players are Sprites.
I have thoroughly read the documentation and feel as though there must be some key concept I am missing or misusing.
I greatly appreciate any help that you are able to offer. Thanks!
movementprototype.py
import random, pygame, sys
import math
from pygame.locals import *
from levelprototype import *
FPS = 60 # frames per second, the general speed of the program
WINDOWWIDTH = 640 # size of window's width in pixels
WINDOWHEIGHT = 480 # size of windows' height in pixels
# R G B
GRAY = (100, 100, 100)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = ( 0, 255, 0)
BLUE = ( 0, 0, 255)
YELLOW = (255, 255, 0)
ORANGE = (255, 128, 0)
BLACK = ( 0, 0, 0)
BGCOLOR = WHITE
def main():
#set up all relevant variables
global FPSCLOCK, DISPLAYSURF, player, box_list
pygame.init()
FPSCLOCK = pygame.time.Clock()
#the length, in ms, of one frame
tick = 1000/FPS
#create window
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
mousex = 0 # used to store x coordinate of mouse event
mousey = 0 # used to store y coordinate of mouse event
pygame.display.set_caption('Movement test environment')
#create the player object using Player() class, add to all_sprites group.
all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
#create the level object
level = Level()
while True: #main game loop
#fill with background colour
DISPLAYSURF.fill(BGCOLOR)
# Update items in the level
level.update()
level.draw(DISPLAYSURF)
#call the sprite update and draw methods.
all_sprites.update()
#check if the player has clicked the X or pressed escape.
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
[irrelevant code]
#update the screen
pygame.display.update()
FPSCLOCK.tick(FPS)
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
#.draw() called in main() requires that each Sprite have a Surface.image
#and a Surface.rect.
self.image = pygame.Surface((20,50))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
#attributes
self.velX = 0
self.velY = 0
self.x = 0
self.y = 0
self.gravity = 0.6
self.maxVelocity = 5
self.xResistance = 0.5
self.isJump = 0
self.isDash = 0
def update(self):
#check which keys are pressed and add velocity.
keys = pygame.key.get_pressed()
if (keys[K_d]) and self.velX < self.maxVelocity:
self.velX += 2.5
if (keys[K_a]) and self.velX > -self.maxVelocity:
self.velX -= 2.5
if (keys[K_w]) and self.isJump == 0:
self.velY -= 10
self.isJump = 1
if (keys[K_SPACE]) and self.isDash == 0:
#at the moment, can only dash once. add timer reset.
self.isDash = 1
if self.velX > 0:
self.x += 20
else:
self.x -= 20
#add gravity
self.velY += self.gravity
#add X resistance
if self.velX > 0.05:
self.velX -= self.xResistance
elif self.velX < -0.05:
self.velX += self.xResistance
#if velocity is really close to 0, make it 0, to stop xResistance moving it the other way.
if self.velX < 0.15 and self.velX > -0.15:
self.velX = 0
self.checkCollision()
#update position with calculated velocity
self.x += self.velX
self.y += self.velY
#call the draw function, below, to blit the sprite onto screen.
self.draw(DISPLAYSURF)
def checkCollision(self):
level = Level().box_list
for collide in pygame.sprite.spritecollide(self, level, False):
print("Collision")
#no matter what I put here, a collision never seems to be identified!!
def draw(self, DISPLAYSURF):
DISPLAYSURF.blit(self.image, (self.x, self.y))
if __name__ == '__main__':
main()
levelprototype.py
import pygame, sys
from pygame.locals import*
GREEN = ( 0, 255, 0)
BLUE = ( 0, 0, 255)
BLACK = ( 0, 0, 0)
class Box(pygame.sprite.Sprite):
""" Box the user can jump on """
def __init__(self, width, height):
super().__init__()
self.image = pygame.Surface([width, height])
self.image.fill(BLACK)
self.rect = self.image.get_rect()
class Level():
#create the box_list as a Class attribute that exists for all instances.
box_list = pygame.sprite.Group()
def __init__(self):
# Background image
self.background = None
# Array with width, height, x, and y of platform
level = [[210, 70, 500, 100],
[210, 70, 200, 400],
[210, 70, 600, 300],
]
# Go through the array above and add platforms
if len(Level.box_list) < 3:
for platform in level:
block = Box(platform[0], platform[1])
block.rect.x = platform[2]
block.rect.y = platform[3]
Level.box_list.add(block)
# Update everything on this level
def update(self):
""" Update everything in this level."""
# Level.box_list.update()
def draw(self, DISPLAYSURF):
""" Draw everything on this level. """
# Draw all the sprite lists that we have
Level.box_list.draw(DISPLAYSURF)
When checking for collisions, pygame.sprite.spritecollide will check whether the Sprite's rects are intersecting. You're not updating the player's rect attribute, so its position will be at (0, 0). Make sure they are synchronized:
# update position with calculated velocity
self.x += self.velX
self.y += self.velY
self.rect.x = self.x
self.rect.y = self.y
I am trying to find a certain sprite in a collision group. In this case, My code checks every platform to see if the player is touching it. If the player is touching the platform, I want the player's bottom y to become the platform's (that the player is touching) top y. I do not know how to grab a certain platform, and edit the attributes of that one. How would I edit my code to make this work?
import pygame
import random
WIDTH = 500
HEIGHT = 400
FPS = 30
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
playerImage = "blockBandit/BlockBandit.png"
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image = pygame.image.load(playerImage).convert()
self.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT / 2)
self.vx = 0
self.vy = 0
class Platform(pygame.sprite.Sprite):
def __init__(self, x, y, w, h):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((w, h))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Block Bandit")
clock = pygame.time.Clock()
allPlatforms = pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
player = Player()
p1 = Platform(0, HEIGHT - 40, WIDTH, 40)
all_sprites.add(p1)
allPlatforms.add(p1)
all_sprites.add(player)
def moveCharacter(object):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
object.vx += -2
if keys[pygame.K_RIGHT]:
object.vx += 2
if keys[pygame.K_UP]:
object.vy -= 12
pygame.quit()
object.vx = object.vx * 0.9
if abs(object.vx) < 1:
object.vx = 0
if abs(object.vx) > 10:
if object.vx < 0:
object.vx = -10
else:
object.vx = 10
object.vy = object.vy + 1
object.rect.x += object.vx
object.rect.y += object.vy
hits = pygame.sprite.spritecollide(object, allPlatforms, False)
if hits:
# object.rect.y = hits[0].rect.midbottom
object.rect.y -= 1
object.vy = 0
if object.rect.bottom < allPlatforms.top:
object.rect.y = allPlatforms.top
print(object.rect.midbottom)
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
moveCharacter(player)
# Update State
all_sprites.update()
# Render
screen.fill(BLACK)
all_sprites.draw(screen)
# screen.blit(player.icon, (20, 40))
pygame.display.flip()
pygame.quit()
hits is a list of the colliding platform sprites, so you can iterate over it with a for loop and set the object.rect.bottom to the platform.rect.top.
hits = pygame.sprite.spritecollide(object, allPlatforms, False)
for platform in hits:
object.vy = 0
object.rect.bottom = platform.rect.top
For my advanced higher computing course I need to do a project, mines is making space invaders, I have never used python before and I am pretty happy with my progress so far, however I have recently encountered an error that I dont know how to deal with. The code is below.
import pygame
import random
import sys
# --- constants --- (UPPER_CASE names)
WHITE = (255, 255, 255)
BLACK = ( 0, 0, 0)
RED = (255, 0, 0)
GREEN = ( 0, 255, 0)
BLUE = ( 0, 0, 255)
ORANGE = (255, 255, 0)
YELLOW = ( 0, 255, 255)
DISPLAY_WIDTH = 720
DISPLAY_HEIGHT = 720
FPS = 60
# --- classes --- (CamelCase names)
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("images\\user1.gif").convert()
self.image = pygame.transform.scale(self.image, (50, 50))
self.rect = self.image.get_rect()
self.speed_x = 0
def update(self):
self.speed_x = 0
keystate = pygame.key.get_pressed()
if keystate[pygame.K_LEFT]:
self.speed_x = -7
if keystate[pygame.K_RIGHT]:
self.speed_x = 7
self.rect.x += self.speed_x
if self.rect.right > DISPLAY_WIDTH:
self.rect.right = DISPLAY_WIDTH
if self.rect.left < 0:
self.rect.left = 0
def shoot(self):
bullet = Bullet(self.rect.centerx, self.rect.top)
all_sprites.add(bullet)
class Mob(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("images\\enemy1.gif").convert()
self.image = pygame.transform.scale(self.image, (50, 50))
self.rect = self.image.get_rect()
self.speed_x = 0
self.rect.x = random.randrange(0, DISPLAY_WIDTH - self.rect.width)
self.rect.y = random.randrange(-500, -40)
self.speedy = random.randrange(5, 11)
def update(self):
self.rect.y +=self.speedy
if self.rect.top > DISPLAY_HEIGHT + 10:
self.rect.x = random.randrange(0, DISPLAY_WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speed_y = random.randrange(5, 11)
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("images\\laser1.gif").convert()
self.image = pygame.transform.scale(self.image, (15, 25))
self.rect = self.image.get_rect()
self.rect.bottom = y
self.rect.centerx = x
self.speed_y = -20
def update(self):
self.rect.y += self.speed_y
if self.rect.bottom < 0:
self.kill()
# --- functions --- (lower_case names)
# empty
# --- main --- (lower_case names)
# - init -
pygame.init()
pygame.mixer.init()
display = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
display_rect = display.get_rect()
# - objects and groups -
all_sprites = pygame.sprite.Group()
mobs = pygame.sprite.Group()
bullet_group = pygame.sprite.Group
player = Player()
player.rect.center = ((DISPLAY_WIDTH / 2), DISPLAY_HEIGHT/1.2)
all_sprites.add(player)
for z in range(8):
mob = Mob()
mobs.add(mob)
all_sprites.add(mob)
background = pygame.image.load("images\\background.jpg")
background = pygame.transform.scale(background, (DISPLAY_WIDTH, DISPLAY_HEIGHT))
# - other -
pygame.mixer.music.load("audio\\soundtrack.mp3")
pygame.mixer.music.play(-1)
pygame.mixer.music.set_volume(0.4)
# - mainloop -
crashed = False
clock = pygame.time.Clock()
while not crashed:
# - checks for a hit -
col = pygame.sprite.spritecollideany(player, mobs)
if col:
sys.exit()
col = pygame.sprite.groupcollide(mobs, bullet_group, True, True)
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
player.shoot()
print(event)
# - updates (without draws) -
all_sprites.update()
# - draws (without updates) -
display.blit(background, (0, 0))
all_sprites.draw(display)
pygame.display.update()
# - FPS -
clock.tick(FPS)
# - end -
pygame.quit()
This is the error message I am receiving, any help would be great, thanks.
C:\Python27\python.exe "C:/Users/Iain/Desktop/Computing Project/Galaxian.py"
Traceback (most recent call last):
File "C:/Users/Iain/Desktop/Computing Project/Galaxian.py", line 132, in <module>
col = pygame.sprite.groupcollide(mobs, bullet_group, True, True)
File "C:\Python27\lib\site-packages\pygame\sprite.py", line 1382, in groupcollide
c = SC(s, groupb, dokillb, collided)
File "C:\Python27\lib\site-packages\pygame\sprite.py", line 1339, in spritecollide
for s in group.sprites():
TypeError: unbound method sprites() must be called with Group instance as first argument (got nothing instead)
Process finished with exit code 1
An "unbound method" is a method object that is obtained from a class. When called, it needs an instance of the class passed to it.
A "bound method" is a method that is bound to an instance of a class. It can be called "normally" since it already has the instance.
In your case, you have a simple typo. You have an unbound method, but it should have been a bound method. The message is misleading because the real problem is the argument you passed to pygame is incorrect.
On line 132 of your program, you call groupcollide. One of the arguments you provide is a variable named bullet_group.
The root cause of the problem is this line:
bullet_group = pygame.sprite.Group
You missed the parentheses, so as a result the name bullet_group refers to the class pygame.sprite.Group. You simply need to add the parentheses to call the class to create an instance of it.
bullet_group = pygame.sprite.Group()
You did this correctly on the preceding lines for mobs and all_sprites.
For my computing project I need to make some sort of app or game. I decided I would make space invaders. I have managed to get the basics working, the player sprite would spawn I could move it and the background and music worked properly, but now when I have tried to create enemy sprites I keep getting this error:
C:\Python27\python.exe "C:/Users/Harry/Desktop/Computing Project/Galaxian.py"
Traceback (most recent call last):
File "C:/Users/Harry/Desktop/Computing Project/Galaxian.py", line 87, in <module>
mobs.add(Mob)
TypeError: unbound method add() must be called with Mob instance as first argument (got type instance instead)
Process finished with exit code 1
If anyone could help I would really appreciate it! Here is my code:
import pygame
import random
# --- constants --- (UPPER_CASE names)
WHITE = (255, 255, 255)
BLACK = ( 0, 0, 0)
RED = (255, 0, 0)
GREEN = ( 0, 255, 0)
BLUE = ( 0, 0, 255)
ORANGE = (255, 255, 0)
YELLOW = ( 0, 255, 255)
DISPLAY_WIDTH = 720
DISPLAY_HEIGHT = 720
FPS = 60
# --- classes --- (CamelCase names)
class Player(pygame.sprite.Sprite):
# <-- empty line for readabelity
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("images\\user1.gif").convert()
self.image = pygame.transform.scale(self.image, (50, 50))
self.rect = self.image.get_rect()
self.speed_x = 0
def update(self):
self.speed_x = 0
keystate = pygame.key.get_pressed()
if keystate[pygame.K_LEFT]:
self.speed_x = -7
if keystate[pygame.K_RIGHT]:
self.speed_x = 7
self.rect.x += self.speed_x
if self.rect.right > DISPLAY_WIDTH:
self.rect.right = DISPLAY_WIDTH
if self.rect.left < 0:
self.rect.left = 0
class Mob(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((30, 40))
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.x = random.randrange(0, DISPLAY_WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
def update(self):
self.rect.y +=self.speedy
if self.rect.top > DISPLAY_HEIGHT + 10:
self.rect.x = random.randrange(0, DISPLAY_WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
# --- functions --- (lower_case names)
# empty
# --- main --- (lower_case names)
# - init -
pygame.init()
pygame.mixer.init()
display = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
display_rect = display.get_rect()
# - objects -
all_sprites = pygame.sprite.Group()
mobs = pygame.sprite.Group()
player = Player()
player.rect.center = ((DISPLAY_WIDTH / 2), 650)
all_sprites.add(player)
for z in range(8):
mobs = Mob()
all_sprites.add(mobs)
mobs.add(Mob)
background = pygame.image.load("C:\\Users\\Harry\\Desktop\\Computing Project\\images\\background.jpg")
background = pygame.transform.scale(background, (DISPLAY_WIDTH, DISPLAY_HEIGHT))
# - other -
pygame.mixer.music.load("C:\\Users\\Harry\\Desktop\\Computing Project\\Audio\\music\\soundtrack.mp3")
pygame.mixer.music.play(-1)
pygame.mixer.music.set_volume(0.4)
# - mainloop -
crashed = False
clock = pygame.time.Clock()
while not crashed:
# - events -
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
print(event)
# - updates (without draws) -
all_sprites.update()
# - draws (without updates) -
display.blit(background, (0, 0))
all_sprites.draw(display)
pygame.display.update()
# - FPS -
clock.tick(FPS)
# - end -
pygame.quit()
TypeError: unbound method add() must be called with Mob instance as first argument (got type instance instead)
The problem is that you've called the add method and passed in the name of the class Mob but not an instance of Mob.
all_sprites.add(player)
for z in range(8):
mobs = Mob()
all_sprites.add(mobs)
mobs.add(Mob) # This is the class name
Depending on the interface of add() you'll probably want to do:
mob = Mob()
mobs.add(mob)
But it's a bit unclear here what you're trying to accomplish