top down shooter zombie survival how to get the player to shoot? - python

Would someone please tell me how to get the bullet class/variable working cause i always get the error "'Bullet' object is not callable".
Heres the bullet class
class Bullet(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface([3,3])
self.image.fill(brown)
self.rect = self.image.get_rect()
self.rect.center = Body.rect.center
self.tick = True
self.tickNum = 0
self.tickTarget = 10
def update(self):
if self.tickNum == self.tickTarget:
self.tick = True
else:
self.tickNum += 1
self.velX = mouseX/20
self.velY = mouseY/20
self.rect.x += self.velX
self.rect.y += self.velY
heres the bit that calls it and makes it shoot
while True:
if buttonDown:
Bullet = Bullet()
if Bullet.tick == True:
bullet_list.add(Bullet)
all_sprites_list.add(Bullet)
Bullet.tick = False
Heres the entire code:
import pygame, sys, time, math
from pygame.locals import *
pygame.init()
pygame.display.set_caption("###Zombie Survival###")
fps = 60
clock = pygame.time.Clock()
dpWidth = 1500
dpHeight = 800
middleX = int(dpWidth/2)
middleY = int(dpHeight/2)
middle = middleX,middleY
dp = pygame.display.set_mode((dpWidth,dpHeight))
mouseX = 0
mouseY = 0
mouse = mouseX,mouseY
buttonDown = False
black = 0,0,0
white = 255,255,255
purple = 255,0,255
lightblue = 170,190,255
blue = 0,0,255
red = 255,0,0
brown = 85,65,0
green = 0,100,0
all_sprites_list = pygame.sprite.Group()
zombie_list = pygame.sprite.Group()
bullet_list = pygame.sprite.Group()
block_list = pygame.sprite.Group()
player_list = pygame.sprite.Group()
load = pygame.image.load
class Legs(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = load("player/player_legs_1.png")
self.rect = self.image.get_rect()
self.rect.center = middle
self.animate = False
self.timeNum = 0
self.newImg = 1
self.timeTarget = 8
self.rootImg = "player/player_legs_"
def update(self):
updatePlayer(self)
class Body(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = load("player/player_gun_1.png")
self.rect = self.image.get_rect()
self.rect.center = middle
self.animate = False
self.timeNum = 0
self.newImg = 1
self.timeTarget = 5
self.rootImg = "player/player_gun_"
def update(self):
updatePlayer(self)
class Bullet(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface([3,3])
self.image.fill(brown)
self.rect = self.image.get_rect()
self.rect.center = Body.rect.center
self.tick = True
self.tickNum = 0
self.tickTarget = 10
def update(self):
if self.tickNum == self.tickTarget:
self.tick = True
else:
self.tickNum += 1
self.velX = mouseX/20
self.velY = mouseY/20
self.rect.x += self.velX
self.rect.y += self.velY
##class Zombie(pygame.sprite.Sprite):
##
##class Block(pygame.sprite.Sprite):
def basic():
global mouseX
global mouseY
global mouse
global buttonDown
for event in pygame.event.get():
if event.type == MOUSEMOTION:
mouseY = event.pos[1]
mouseX = event.pos[0]
mouse = mouseX,mouseY
if event.type == MOUSEBUTTONDOWN:
buttonDown = True
elif event.type == MOUSEBUTTONUP:
buttonDown = False
elif event.type == QUIT:
pygame.quit()
exit
curser()
def curser():
pygame.draw.circle(dp,black,mouse,10,2)
pygame.draw.circle(dp,black,mouse,3)
def rotatePlayer(Class):
playerXdif = mouseX-middleX
playerYdif = mouseY-middleY
dif = (playerXdif),(playerYdif)
rotDeg1 = math.atan2(dif[0],dif[1])
rotDeg2 = math.degrees(rotDeg1)
img1 = rotateImage(Class.image,rotDeg2)
return img1
def rotateImage(img,angle):
orig_rect = img.get_rect()
rot_img = pygame.transform.rotate(img,angle)
rot_rect = orig_rect.copy()
rot_rect.center = rot_img.get_rect().center
rot_img = rot_img.subsurface(rot_rect).copy()
return rot_img
def updatePlayer(Class):
Class.newTimeTarget = int(fps/Class.timeTarget)
if Class.animate == True:
Class.timeNum += 1
if Class.timeNum == self.newTimeTarget:
if Class.newImg != self.maxImg:
Class.newImg += 1
else:
Class.newImg = 1
Class.animate = False
Class.timeNum = 0
else:
Class.newImg = 1
Class.image = load(str(Class.rootImg+str(Class.newImg)+".png"))
Class.image = rotatePlayer(Class)
Legs = Legs()
Body = Body()
player_list.add([Body,Legs])
all_sprites_list.add([Body,Legs])
while True:
if buttonDown:
Bullet = Bullet()
if Bullet.tick == True:
bullet_list.add(Bullet)
all_sprites_list.add(Bullet)
Bullet.tick = False
dp.fill(green)
basic()
all_sprites_list.update()
all_sprites_list.draw(dp)
clock.tick(fps)
#print(mouse)
pygame.display.update()

Bullet = Bullet() is your problem. You're doing nasty things to your namespace. Instead, do something like bullet = Bullet() or b = Bullet()

Related

Im stuck on doing an explosion animation for my cement block sprites [duplicate]

This question already exists:
I want to do an explosion animation. I have 4 png files number 0 - 3. In my debris class I loaded them into an image list using a for loop [duplicate]
Closed 1 year ago.
I want to do an explosion animation. I have 4 png files number 0 - 3. In my debris class I loaded them into an image list using a for loop. Then I made an explosion function but when I load my pygame windows and start shooting my cement block sprites, my cement block sprites disappear which is fine but they don't do the exploding animation I want. How can I fix this problem. Would appreciate the help.
My code:
import random
import pygame
import pygame.freetype
pygame.init()
#screen settings
WIDTH = 1000
HEIGHT = 400
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("AutoPilot")
screen.fill((255, 255, 255))
#fps
FPS = 120
clock = pygame.time.Clock()
#load images
bg = pygame.image.load('background/street.png').convert_alpha() # background
bullets = pygame.image.load('car/bullet.png').convert_alpha()
debris_img = pygame.image.load('debris/cement.png')
#define game variables
shoot = False
#player class
class Player(pygame.sprite.Sprite):
def __init__(self, scale, speed):
pygame.sprite.Sprite.__init__(self)
self.bullet = pygame.image.load('car/bullet.png').convert_alpha()
self.bullet_list = []
self.speed = speed
#self.x = x
#self.y = y
self.moving = True
self.frame = 0
self.flip = False
self.direction = 0
self.score = 0
#load car
self.images = []
img = pygame.image.load('car/car.png').convert_alpha()
img = pygame.transform.scale(img, (int(img.get_width()) * scale, (int(img.get_height()) * scale)))
self.images.append(img)
self.image = self.images[0]
self.rect = self.image.get_rect()
self.update_time = pygame.time.get_ticks()
self.movingLeft = False
self.movingRight = False
self.rect.x = 465
self.rect.y = 325
#draw car to screen
def draw(self):
screen.blit(self.image, (self.rect.centerx, self.rect.centery))
#move car
def move(self):
#reset the movement variables
dx = 0
dy = 0
#moving variables
if self.movingLeft and self.rect.x > 33:
dx -= self.speed
self.flip = True
self.direction = -1
if self.movingRight and self.rect.x < 900:
dx += self.speed
self.flip = False
self.direction = 1
#update rectangle position
self.rect.x += dx
self.rect.y += dy
#shoot
def shoot(self):
bullet = Bullet(self.rect.centerx + 18, self.rect.y + 30, self.direction)
bullet_group.add(bullet)
#check collision
def collision(self, debris_group):
for debris in debris_group:
if pygame.sprite.spritecollide(debris, bullet_group, True):
debris.health -= 1
if debris.health <= 0:
self.score += 1
debris.kill()
#player stats
def stats(self):
myfont = pygame.font.SysFont('comicsans', 30)
scoretext = myfont.render("Score: " + str(self.score), 1, (0,0,0))
screen.blit(scoretext, (100,10))
#bullet class
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y, direction):
pygame.sprite.Sprite.__init__(self)
self.speed = 5
self.image = bullets
self.rect = self.image.get_rect()
self.rect.center = (x,y)
self.direction = direction
def update(self):
self.rect.centery -= self.speed
#check if bullet has gone off screen
if self.rect.centery < 1:
self.kill()
#debris class
class Debris(pygame.sprite.Sprite):
def __init__(self,scale,speed):
pygame.sprite.Sprite.__init__(self)
self.scale = scale
self.x = random.randrange(100,800)
self.speed_y = 10
self.y = 15
self.speed = speed
self.vy = 0
self.on_ground = True
self.move = True
self.health = 4
self.max_health = self.health
self.alive = True
self.velocity = random.randrange(1,2)
self.speed_x = random.randrange(-3,3)
self.moving_down = True
#load debris
self.image = debris_img
self.rect = self.image.get_rect()
self.rect.x = random.randrange(100, 800)
self.rect.y = random.randrange(-150, -100)
self.rect.center = (self.x,self.y)
#load explosion
self.images = []
for i in range(4):
self.images.append(pygame.image.load(f'explosion/{i}.png'))
self.index = 0
self.img = self.images[self.index]
#spawn new debris
def spawn_new_debris(self):
self.rect.x = random.randrange(100, 800)
self.rect.y = random.randrange(-150, -100)
self.velocity = random.randrange(1, 2)
self.speed_x = random.randrange(-3, 3)
#respawn debris when they go of the screen
def boundaries(self):
if self.rect.left > WIDTH + 10 or self.rect.right < -10 or self.rect.top > HEIGHT + 10:
self.spawn_new_debris()
#update image
def update(self):
self.rect.y += self.velocity
self.rect.x += self.speed_x
self.boundaries()
#make debris fall down
def falldown(self):
self.rect.centery += self.velocity
if self.moving_down and self.rect.y > 350:
self.kill()
#explosion
def explode(self):
if self.max_health <= 0:
self.index += 1
if self.index >= len(self.images):
self.index = 0
self.img = self.images[self.index]
######################CAR/DEBRIS##########################
player = Player(1,5)
##########################################################
#groups
bullet_group = pygame.sprite.Group()
debris_group = pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
for i in range(50):
d = Debris(1,5)
debris_group.add(d)
all_sprites.add(d)
#game runs here
run = True
while run:
#draw street
screen.blit(bg, [0, 0])
#update groups
bullet_group.update()
bullet_group.draw(screen)
debris_group.update()
debris_group.draw(screen)
#draw car
player.draw()
player.move()
player.collision(debris_group)
player.stats()
#update all sprites
all_sprites.update()
all_sprites.draw(screen)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#check if key is down
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
if event.key == pygame.K_a:
player.movingLeft = True
if event.key == pygame.K_d:
player.movingRight = True
if event.key == pygame.K_SPACE:
player.shoot()
shoot = True
#check if key is up
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
player.movingLeft = False
if event.key == pygame.K_d:
player.movingRight = False
#update the display
pygame.display.update()
pygame.display.flip()
clock.tick(FPS)
pygame.quit()

Python: Space Invaders Score System

Been trying to add a scoring system to my game but I keep getting a weird error and now I'm stumped. Here's the code:
##Space Invaders##
import pygame
import sys
from random import shuffle
from pygame.locals import *
##CONSTANTS##
## Colors ##
GRAY = (100,100,100)
NAVYBLUE = (60,60,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)
PURPLE = (255,0,255)
CYAN = (0,255,255)
BLACK = (0,0,0)
NEARBLACK = (19,15,48)
COMBLUE = (233,232,255)
## Player ##
PLAYERWIDTH = 40
PLAYERHEIGHT = 10
PLAYERCOLOR = COMBLUE
PLAYER1 = 'Player 1'
PLAYERSPEED = 5
PLAYERCOLOR = GREEN
## Display ##
GAMETITLE =('SPACE INVADERS')
DISPLAYWIDTH = 640
DISPLAYHEIGHT = 480
BGCOLOR = NEARBLACK
XMARGIN = 50
YMARGIN = 50
## Bullet ##
BULLETWIDTH = 5
BULLETHEIGHT = 5
BULLETOFFSET = 700
## Enemy ##
ENEMYWIDTH = 25
ENEMYHEIGHT = 25
ENEMYNAME = 'Enemy'
ENEMYGAP = 20
ARRAYWIDTH = 10
ARRAYHEIGHT = 4
MOVETIME = 1000
MOVEX = 10
MOVEY = ENEMYHEIGHT
TIMEOFFSET = 300
## SCORE ##
score=0
## This allows for shooting bullets while moving without
## the inputs interupting each other.
DIRECT_DICT = {pygame.K_LEFT : (-1),
pygame.K_RIGHT : (1)}
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.width = PLAYERWIDTH
self.height = PLAYERHEIGHT
self.image = pygame.Surface((self.width, self.height))
self.color = PLAYERCOLOR
self.image.fill(self.color)
self.rect = self.image.get_rect()
self.name = PLAYER1
self.speed = PLAYERSPEED
self.vectorx = 0
def update(self, keys, *args):
for key in DIRECT_DICT:
if keys[key]:
self.rect.x += DIRECT_DICT[key] * self.speed
self.checkForSide()
self.image.fill(self.color)
def checkForSide(self):
if self.rect.right > DISPLAYWIDTH:
self.rect.right = DISPLAYWIDTH
self.vectorx = 0
elif self.rect.left < 0:
self.rect.left = 0
self.vectorx = 0
class Blocker(pygame.sprite.Sprite):
def __init__(self, side, color, row, column):
pygame.sprite.Sprite.__init__(self)
self.width = side
self.height = side
self.color = color
self.image = pygame.Surface((self.width, self.height))
self.image.fill(self.color)
self.rect = self.image.get_rect()
self.name = 'blocker'
self.row = row
self.column = column
class Bullet(pygame.sprite.Sprite):
def __init__(self, rect, color, vectory, speed):
pygame.sprite.Sprite.__init__(self)
self.width = BULLETWIDTH
self.height = BULLETHEIGHT
self.color = color
self.image = pygame.Surface((self.width, self.height))
self.image.fill(self.color)
self.rect = self.image.get_rect()
self.rect.centerx = rect.centerx
self.rect.top = rect.bottom
self.name = 'bullet'
self.vectory = vectory
self.speed = speed
def update(self, *args):
self.oldLocation = (self.rect.x, self.rect.y)
self.rect.y += self.vectory * self.speed
if self.rect.bottom < 0:
self.kill()
elif self.rect.bottom > 500:
self.kill()
class Enemy(pygame.sprite.Sprite):
def __init__(self, row, column):
pygame.sprite.Sprite.__init__(self)
self.width = ENEMYWIDTH
self.height = ENEMYHEIGHT
self.row = row
self.column = column
self.image = self.setImage()
self.rect = self.image.get_rect()
self.name = 'enemy'
self.vectorx = 1
self.moveNumber = 0
self.moveTime = MOVETIME
self.timeOffset = row * TIMEOFFSET
self.timer = pygame.time.get_ticks() - self.timeOffset
def update(self, keys, currentTime):
if currentTime - self.timer > self.moveTime:
if self.moveNumber < 6:
self.rect.x += MOVEX * self.vectorx
self.moveNumber += 1
elif self.moveNumber >= 6:
self.vectorx *= -1
self.moveNumber = 0
self.rect.y += MOVEY
if self.moveTime > 100:
self.moveTime -= 50
self.timer = currentTime
def setImage(self):
if self.row == 0:
image = pygame.image.load('alien1.png')
elif self.row == 1:
image = pygame.image.load('alien2.png')
elif self.row == 2:
image = pygame.image.load('alien3.png')
else:
image = pygame.image.load('alien1.png')
image.convert_alpha()
image = pygame.transform.scale(image, (self.width, self.height))
return image
class Text(object):
def __init__(self, font, size, message, color, rect, surface):
self.font = pygame.font.Font(font, size)
self.message = message
self.surface = self.font.render(self.message, True, color)
self.rect = self.surface.get_rect()
self.setRect(rect)
def setRect(self,rect):
self.rect.centerx = rect.centerx - 5
self.rect.centery = rect.centery - 5
def draw(self, surface):
surface.blit(self.surface, self.rect)
class App(object):
def __init__(self):
pygame.init()
self.displaySurf, self.displayRect = self.makeScreen()
self.gameStart = True
self.gameOver = False
self.gameWon = False
self.beginGame = False
self.laserSound = pygame.mixer.Sound('laser.ogg')
self.startLaser = pygame.mixer.Sound('alienLaser.ogg')
self.playIntroSound = True
def resetGame(self):
self.gameStart = True
self.needToMakeEnemies = True
self.introMessage1 = Text('orena.ttf', 50,'Space Invaders',GREEN, self.displayRect,self.displaySurf)
self.introMessage2 = Text('orena.ttf', 25,'Press Space to Continue',GREEN, self.displayRect,self.displaySurf)
self.introMessage2.rect.top = self.introMessage1.rect.bottom + 5
self.gameOverMessage = Text('orena.ttf', 50,'GAME OVER',GREEN, self.displayRect,self.displaySurf)
self.gameWinMessage = Text('orena.ttf',50,'Congrats You Won',GREEN,self.displayRect,self.displaySurf)
self.gameWinMessage2 = Text('orena.ttf', 30,'Click Space to return to the menu',GREEN, self.displayRect,self.displaySurf)
self.gameWinMessage2.rect.top = self.gameWinMessage.rect.bottom + 5
self.scoreText = Text('orena.ttf',10,'Score:',WHITE,self.displayRect,self.displaySurf)
self.player = self.makePlayer()
self.bullets = pygame.sprite.Group()
self.greenBullets = pygame.sprite.Group()
self.blockerGroup1 = self.makeBlockers(0)
self.blockerGroup2 = self.makeBlockers(1)
self.blockerGroup3 = self.makeBlockers(2)
self.blockerGroup4 = self.makeBlockers(3)
self.allBlockers = pygame.sprite.Group(self.blockerGroup1, self.blockerGroup2,self.blockerGroup3, self.blockerGroup4)
self.allSprites = pygame.sprite.Group(self.player, self.allBlockers)
self.keys = pygame.key.get_pressed()
self.clock = pygame.time.Clock()
self.fps = 60
self.score = score
self.enemyMoves = 0
self.enemyBulletTimer = pygame.time.get_ticks()
self.gameOver = False
self.gameWon = False
self.gameOverTime = pygame.time.get_ticks()
self.gameWinTime = pygame.time.get_ticks()
if self.playIntroSound:
self.startLaser.play()
self.playIntroSound = False
def makeBlockers(self, number=1):
blockerGroup = pygame.sprite.Group()
for row in range(5):
for column in range(7):
blocker = Blocker(10, GREEN, row, column)
blocker.rect.x = 50 + (150 * number) + (column * blocker.width)
blocker.rect.y = 375 + (row * blocker.height)
blockerGroup.add(blocker)
for blocker in blockerGroup:
if (blocker.column == 0 and blocker.row == 0
or blocker.column == 6 and blocker.row == 0):
blocker.kill()
return blockerGroup
def checkForEnemyBullets(self):
redBulletsGroup = pygame.sprite.Group()
for bullet in self.bullets:
if bullet.color == RED:
redBulletsGroup.add(bullet)
for bullet in redBulletsGroup:
if pygame.sprite.collide_rect(bullet, self.player):
if self.player.color == GREEN:
self.player.color = YELLOW
elif self.player.color == YELLOW:
self.player.color = RED
elif self.player.color == RED:
self.gameOver = True
self.gameOverTime = pygame.time.get_ticks()
bullet.kill()
def shootEnemyBullet(self, rect):
if (pygame.time.get_ticks() - self.enemyBulletTimer) > BULLETOFFSET:
self.bullets.add(Bullet(rect, RED, 1, 5))
self.allSprites.add(self.bullets)
self.enemyBulletTimer = pygame.time.get_ticks()
def findEnemyShooter(self):
columnList = []
for enemy in self.enemies:
columnList.append(enemy.column)
#get rid of duplicate columns
columnSet = set(columnList)
columnList = list(columnSet)
shuffle(columnList)
column = columnList[0]
enemyList = []
rowList = []
for enemy in self.enemies:
if enemy.column == column:
rowList.append(enemy.row)
row = max(rowList)
for enemy in self.enemies:
if enemy.column == column and enemy.row == row:
self.shooter = enemy
def makeScreen(self):
pygame.display.set_caption(GAMETITLE)
displaySurf = pygame.display.set_mode((DISPLAYWIDTH, DISPLAYHEIGHT))
displayRect = displaySurf.get_rect()
displaySurf.fill(BGCOLOR)
displaySurf.convert()
return displaySurf, displayRect
def makePlayer(self):
player = Player()
#Place the player centerx and five pixels from the bottom
player.rect.centerx = self.displayRect.centerx
player.rect.bottom = self.displayRect.bottom - 5
return player
def makeEnemies(self):
enemies = pygame.sprite.Group()
for row in range(ARRAYHEIGHT):
for column in range(ARRAYWIDTH):
enemy = Enemy(row, column)
enemy.rect.x = XMARGIN + (column * (ENEMYWIDTH + ENEMYGAP))
enemy.rect.y = YMARGIN + (row * (ENEMYHEIGHT + ENEMYGAP))
enemies.add(enemy)
return enemies
def checkInput(self):
for event in pygame.event.get():
self.keys = pygame.key.get_pressed()
if event.type == QUIT:
self.terminate()
elif event.type == KEYDOWN:
if event.key == K_SPACE and len(self.greenBullets) < 1:
if self.score < 1000:
bullet = Bullet(self.player.rect, GREEN, -1, 20)
self.greenBullets.add(bullet)
self.bullets.add(self.greenBullets)
self.allSprites.add(self.bullets)
self.laserSound.play()
elif event.key == K_ESCAPE:
self.terminate()
def calculate_score(self, row):
scores = {0: 30,
1: 20,
2: 20,
3: 10,
4: 10,
5: choice([50, 100, 150, 300])
}
score = scores[row]
self.score += score
return score
def gameStartInput(self):
for event in pygame.event.get():
if event.type == QUIT:
self.terminate()
elif event.type == KEYUP:
self.gameWon = False
self.gameOver = False
self.gameStart = False
self.beginGame = True
def gameOverInput(self):
for event in pygame.event.get():
if event.type == QUIT:
self.terminate()
elif event.type == KEYUP:
self.gameStart = True
self.beginGame = False
self.gameOver = False
self.gameWon = False
def gameWonInput(self):
for event in pygame.event.get():
if event.type == QUIT:
self.terminate()
elif event.type == KEYUP:
self.gameStart = True
self.beginGame = False
self.gameOver = False
self.gameWon = False
def checkCollisions(self):
self.checkForEnemyBullets()
enemiesdict = pygame.sprite.groupcollide(self.bullets, self.enemies, True, True)
if enemiesdict:
for value in enemiesdict.values():
for currentSprite in value:
self.killedRow = currentSprite.row
self.killedColumn = currentSprite.column
score = self.calculate_score(currentSprite.row)
self.enemies.remove(currentSprite)
self.allSprites.remove(currentSprite)
pygame.sprite.groupcollide(self.enemies, self.allBlockers, False, True)
self.collide_green_blockers()
self.collide_red_blockers()
def collide_green_blockers(self):
for bullet in self.greenBullets:
casting = Bullet(self.player.rect, GREEN, -1, 20)
casting.rect = bullet.rect.copy()
for pixel in range(bullet.speed):
hit = pygame.sprite.spritecollideany(casting,self.allBlockers)
if hit:
hit.kill()
bullet.kill()
break
casting.rect.y -= 1
def collide_red_blockers(self):
reds = (shot for shot in self.bullets if shot.color == RED)
red_bullets = pygame.sprite.Group(reds)
pygame.sprite.groupcollide(red_bullets, self.allBlockers, True, True)
def checkGameOver(self):
if len(self.enemies) == 0:
self.gameWon = True
self.gameStart = False
self.beginGame = False
self.gameOverTime = pygame.time.get_ticks()
self.gameWinTime = pygame.time.get_ticks()
else:
for enemy in self.enemies:
if enemy.rect.bottom > DISPLAYHEIGHT:
self.gameOver = True
self.gameStart = False
self.beginGame = False
self.gameOverTime = pygame.time.get_ticks()
def terminate(self):
pygame.quit()
sys.exit()
def mainLoop(self):
while True:
if self.gameStart:
self.resetGame()
self.gameOver = False
self.displaySurf.fill(BGCOLOR)
self.introMessage1.draw(self.displaySurf)
self.introMessage2.draw(self.displaySurf)
self.scoreText2 = Text('orena.ttf', 20, str(self.score), GREEN, 85, 5)
self.scoreText.draw(self.screen)
self.scoreText2.draw(self.screen)
self.gameStartInput()
pygame.display.update()
elif self.gameOver:
self.playIntroSound = True
self.displaySurf.fill(BGCOLOR)
self.gameOverMessage.draw(self.displaySurf)
#prevent users from exiting the GAME OVER screen
#too quickly
if (pygame.time.get_ticks() - self.gameOverTime) > 2000:
self.gameOverInput()
pygame.display.update()
elif self.gameWon:
self.gameOver = False
self.playIntroSound = True
self.displaySurf.fill(BGCOLOR)
self.gameWinMessage.draw(self.displaySurf)
self.gameWinMessage2.draw(self.displaySurf)
if (pygame.time.get_ticks() - self.gameWinTime) > 2000:
self.gameWonInput()
pygame.display.update()
elif self.beginGame:
if self.needToMakeEnemies:
self.enemies = self.makeEnemies()
self.allSprites.add(self.enemies)
self.needToMakeEnemies = False
pygame.event.clear()
else:
currentTime = pygame.time.get_ticks()
self.displaySurf.fill(BGCOLOR)
self.checkInput()
self.allSprites.update(self.keys, currentTime)
self.scoreText2 = Text('orena.ttf', 20, str(self.score), WHITE, 85, 5)
self.scoreText.draw(self.screen)
self.scoreText2.draw(self.screen)
if len(self.enemies) > 0:
self.findEnemyShooter()
self.shootEnemyBullet(self.shooter.rect)
self.checkCollisions()
self.allSprites.draw(self.displaySurf)
self.blockerGroup1.draw(self.displaySurf)
pygame.display.update()
self.checkGameOver()
self.clock.tick(self.fps)
if __name__ == '__main__':
app = App()
app.mainLoop()
Error (Line 178):
AttributeError: 'int' object has no attribute 'centerx'
Game files like pictures, sound files, etc. can be changed/replaced. If you need the files let me know. However I'd prefer if I could keep those private.
Thanks in advance! Any help is appreciated.
In this class:
class Text(object):
def __init__(self, font, size, message, color, rect, surface):
In the init you have:
self.rect = self.surface.get_rect()
self.setRect(rect)
Notice you are setting self.rect but sending rect to the function
It should be
self.rect = self.surface.get_rect()
self.setRect(self.rect)
The issue also comes from this call:
self.scoreText2 = Text('orena.ttf', 20, str(self.score), GREEN, 85, 5)
Most places you call it by sending something like:
self.introMessage1 = Text('orena.ttf', 50,'Space Invaders',GREEN, self.displayRect,self.displaySurf)
self.displayRect has a centerx. The int 85 does not.
Debugging
Read and understand your error message:
It is telling you rect is an int but you are expecting a rect type. Print your values until you find where it changes from being correct to wrong to narrow down the issue.
Also, by creating a Minimal, Complete, and Verifiable example, a lot of the noise goes away and you are able to focus on your issue and can often catch errors like these yourself.

TypeError: argument 1 must be pygame.Surface, not list [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I was working on a movement animations since I saw a youtuber explaining how to do it, but I'm getting this error:
TypeError: argument 1 must be pygame.Surface, not list
My code is about 500 lines.
# Pygame Template - skeleton for a new pygame project
import pygame
import random
import os
from os import path
vec = pygame.math.Vector2
width = 800
height = 600
FPS = 60
POWERUP_TIME = 5000
title = 'Parkourse'
# Player properties
player_acceleration = 0.5
player_friction = -0.12
player_gravity = 0.8
player_jump = 10
# Starting platforms
platforms_list = [(0,height-40,width,50), # Ground
(0,0,800,10), # Top
(0,0,10,600), # Left Border
(790,height-400,10,600),# Right Border
(250,height - 160,width-200,10), # Floor 1
(0,height - 280,width-200,10), # Floor 2
(250,height - 400,width-100,10)] # Floor 3
# Define Colors
white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
# set up assets folders
game_folder = os.path.dirname(__file__)
image_folder = os.path.join(game_folder, "Image")
sound_folder = os.path.join(game_folder, "Sound")
# Initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption(title)
clock = pygame.time.Clock()
# Load all game graphics
background = pygame.image.load(path.join(image_folder, "background.png")).convert()
background_rect = background.get_rect()
no_mvmt_0 = pygame.image.load(path.join(image_folder,"no_mvmt_0.png")).convert()
no_mvmt_1 = pygame.image.load(path.join(image_folder,"no_mvmt_1.png")).convert()
running_0 = pygame.image.load(path.join(image_folder,"running_0.png")).convert()
running_1 = pygame.image.load(path.join(image_folder,"running_1.png")).convert()
jumping_0 = pygame.image.load(path.join(image_folder,"jumping_0.png")).convert()
mini_no_mvmt = pygame.transform.scale(no_mvmt_0, (25,48))
mini_no_mvmt.set_colorkey(white)
scissors = pygame.image.load(path.join(image_folder,"scissors.png")).convert()
mob_left = pygame.image.load(path.join(image_folder,"mob_left.png")).convert()
power_upper_image = {}
power_upper_image['shield_0'] = pygame.image.load(path.join(image_folder,"shield_upper_0.png")).convert()
power_upper_image['shield_1'] = pygame.image.load(path.join(image_folder,"shield_upper_1.png")).convert()
power_upper_image['shield_2'] = pygame.image.load(path.join(image_folder,"shield_upper_2.png")).convert()
power_upper_image['life'] = pygame.image.load(path.join(image_folder,"life_upper.png")).convert()
power_upper_image['power'] = pygame.image.load(path.join(image_folder,"power.png")).convert()
explosion_animation = {}
explosion_animation['normal']=[]
explosion_animation['small']=[]
explosion_animation['player']=[]
for explosion in range(5):
explose = 'explosion_{}.png'.format(explosion)
image = pygame.image.load(path.join(image_folder, explose)).convert()
image.set_colorkey(white)
image.set_colorkey(black)
image_normal = pygame.transform.scale(image, (80,80))
explosion_animation['normal'].append(image_normal)
image_small = pygame.transform.scale(image, (30, 30))
explosion_animation['small'].append(image_small)
death = 'dying_{}.png'.format(explosion)
image = pygame.image.load(path.join(image_folder, death)).convert()
image.set_colorkey(white)
explosion_animation['player'].append(image)
#Load all game sounds
scream_sound = []
for scream in ["slightscream_0.wav", "slightscream_1.wav", "slightscream_2.wav",
"slightscream_3.wav", "slightscream_4.wav", "slightscream_5.wav",
"slightscream_6.wav", "slightscream_7.wav", "slightscream_8.wav",
"slightscream_9.wav", "slightscream_10.wav", "slightscream_11.wav",
"slightscream_12.wav", "slightscream_13.wav", "slightscream_14.wav"]:
scream_sound.append(pygame.mixer.Sound(path.join(sound_folder,scream)))
shoot_sound = pygame.mixer.Sound(path.join(sound_folder,"shoot.wav"))
shield = pygame.mixer.Sound(path.join(sound_folder,"shield.wav"))
life = pygame.mixer.Sound(path.join(sound_folder,"life.wav"))
special_power = pygame.mixer.Sound(path.join(sound_folder,"special_power.wav"))
death_sound = pygame.mixer.Sound(path.join(sound_folder,"death.ogg"))
explosion_sound = []
for sound in ["explosion.wav", "explosion_2.wav"]:
explosion_sound.append(pygame.mixer.Sound(path.join(sound_folder, sound)))
pygame.mixer.music.load(path.join(sound_folder,"gameplay.ogg"))
pygame.mixer.music.set_volume(0.6)
font_name = pygame.font.match_font('arial')
def draw_text (surf, text,color,size, x, y):
font = pygame.font.Font(font_name, size)
text_surface = font.render(text, True, color)
text_rect = text_surface.get_rect()
text_rect.midtop = (x, y)
surf.blit(text_surface, text_rect)
def newmob():
m = Mobs()
all_sprites.add(m)
mobs.add(m)
def draw_shield_bar(screen, x,y,percentage):
if percentage < 0:
percentage = 0
bar_lenght = 100
bar_height = 10
fill = (percentage / 100) * bar_lenght
outline_rect = pygame.Rect(x,y,bar_lenght,bar_height)
fill_rect = pygame.Rect(x,y,fill, bar_height)
pygame.draw.rect(screen, green, fill_rect)
pygame.draw.rect(screen, black, outline_rect, 2) # 2 is the the number of pixels
# of how wide you want the outline
# of the rectangle to be
def draw_lives (surface, x, y, lives, image):
for i in range(lives):
image_rect = image.get_rect()
image_rect.x = x + 30 * i
image_rect.y = y
surface.blit(image, image_rect)
score = 0
def show_game_over_screen():
screen.blit(background, background_rect)
draw_text(screen, "Dang..!",red,100, width/2, 200)
draw_text(screen, "Score: " + str(score),blue,30, width/2, 330)
draw_text(screen, "Press any key to retry",blue,30, width/2, 390)
pygame.display.flip()
waiting = True
while waiting:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYUP:
waiting = False
def show_start_screen():
screen.blit(background, background_rect)
draw_text(screen,"Parkourse!", green, 100, width/2, 200)
draw_text(screen, "Use the arrow keys to move, S to fire, and space to Jump",blue,30, width/2, 330)
draw_text(screen, "Press any key to begin",blue,30, width/2, 390)
pygame.display.flip()
waiting = True
while waiting:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYUP:
waiting = False
class Player (pygame.sprite.Sprite):
# Sprite for the player
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.load_movement_images()
self.image = self.standing_frame[0]
self.rect = self.image.get_rect()
self.pos = vec(50,500)
self.vel = vec(0,0)
self.acc = vec(0,0)
self.shield = 100
self.lives = 3
self.hidden = False
self.hide_timer = pygame.time.get_ticks()
self.power = 1
self.power_timer = pygame.time.get_ticks()
self.running = False
self.jumping = False
self.current_frame = 0
self.last_update = 0
def load_movement_images(self):
self.standing_frame = [no_mvmt_0, no_mvmt_1]
self.running_frame_right = [running_0,running_1]
self.running_frame_left = []
for frame in self.standing_frame:
frame.set_colorkey(white)
for frame in self.running_frame_right:
self.running_frame_left.append(pygame.transform.flip(frame,True,False)) # True is horizontaly, False is vertically
frame.set_colorkey(white)
self.jumping_frame = jumping_0
self.jumping_frame.set_colorkey(white)
def animate(self):
now = pygame.time.get_ticks()
if not self.jumping and not self.running:
if now - self.last_update > 350:
self.last_update = now
self.current_frame = (self.current_frame + 1) % len(self.standing_frame)
self.image = self.standing_frame
def jump(self):
# Jump only if standing on a Platform
self.rect.x +=1
hits = pygame.sprite.spritecollide(player,platforms, False)
self.rect.x -= 1
if hits:
self.vel.y = - player_jump
def update(self):
self.animate()
# timeout for powerups
if self.power >=2 and pygame.time.get_ticks() - self.power_time > POWERUP_TIME:
self.power -= 1
self.power_time = pygame.time.get_ticks()
# unhide if hidden
if self.hidden and pygame.time.get_ticks() - self.hide_timer > 1000:
self.hidden = False
self.pos = vec(30, 400)
self.acc = vec(0,player_gravity)
keystate = pygame.key.get_pressed()
if keystate[pygame.K_LEFT] or keystate[pygame.K_a]:
self.acc.x = -player_acceleration
if keystate[pygame.K_RIGHT] or keystate[pygame.K_d]:
self.acc.x = player_acceleration
if keystate[pygame.K_SPACE]:
player.jump()
# apply friction
self.acc.x += self.vel.x * player_friction
# equations of motions
self.vel += self.acc
self.pos += self.vel + 0.5 * self.acc
# wrap around the sides of the screen
if self.pos.x > 750:
self.pos.x = 750
if self.pos.x <= 0:
self.pos.x = 25
self.rect.midbottom = self.pos
def powerup(self):
self.power += 1
self.power_time = pygame.time.get_ticks()
def shoot(self):
if self.power == 1:
bullet = Bullet(self.pos.x + 5, self.pos.y - 20)
all_sprites.add(bullet)
bullets.add(bullet)
shoot_sound.play()
if self.power >= 2:
bullet1 = Bullet(self.pos.x + 5, self.pos.y - 20)
bullet2 = Bullet(self.pos.x + 35, self.pos.y -20)
all_sprites.add(bullet1)
all_sprites.add(bullet2)
bullets.add(bullet1)
bullets.add(bullet2)
shoot_sound.play()
def hide(self):
# hide the player temporarily
self.hidden = True
self.hide_timer = pygame.time.get_ticks()
self.pos = vec(0, 6000)
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = scissors
self.rect = self.image.get_rect()
self.image.set_colorkey(white)
self.image = pygame.transform.scale(scissors, (30,15))
self.rect.bottom = y
self.rect.centerx = x
self.speedx = 10
def update(self):
self.rect.x += self.speedx
# kill if it moves off the top of the screen
if self.rect.bottom < 0:
self.kill()
class Mobs(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = mob_left
self.rect = self.image.get_rect()
self.image.set_colorkey(white)
self.rect.x = random.randrange(0,800)
self.rect.y = 530
self.speedx = 2
def update(self):
self.rect.x -= self.speedx
if self.rect.right < 0:
self.rect.x = 800
class Explosion(pygame.sprite.Sprite):
def __init__(self, center, size, frame):
pygame.sprite.Sprite.__init__(self)
self.size = size
self.image = explosion_animation[self.size][0]
self.rect = self.image.get_rect()
self.rect.center = center
self.frame = 0
self.last_update = pygame.time.get_ticks()
self.frame_rate = frame
def update(self):
now = pygame.time.get_ticks()
if now - self.last_update > self.frame_rate:
self.last_update = now
self.frame += 1
if self.frame == len(explosion_animation[self.size]):
self.kill()
else:
center = self.rect.center
self.image = explosion_animation[self.size][self.frame]
self.rect = self.image.get_rect()
self.rect.center = center
class Normal_Power(pygame.sprite.Sprite):
def __init__(self, center):
pygame.sprite.Sprite.__init__(self)
self.type = random.choice(['shield_0','shield_1','shield_2'])
self.image = power_upper_image[self.type]
self.rect = self.image.get_rect()
self.image.set_colorkey(white)
self.rect.center = center
class Special_Power(pygame.sprite.Sprite):
def __init__(self, center):
pygame.sprite.Sprite.__init__(self)
self.type = random.choice(['life','power'])
self.image = power_upper_image[self.type]
self.rect = self.image.get_rect()
self.image.set_colorkey(white)
self.rect.center = center
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(black)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
pygame.mixer.music.play(loops=-1) # loops = -1 means that pygame will restart the song when it's finished
# Game loop
running = True
new_game = True
game_over = False
while running:
if new_game:
show_start_screen()
new_game = False
all_sprites = pygame.sprite.Group()
platforms = pygame.sprite.Group()
for plat in platforms_list:
p = Platform (*plat)
all_sprites.add(p)
platforms.add(p)
mobs = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
bullets = pygame.sprite.Group()
powerups = pygame.sprite.Group()
for i in range(1):
newmob()
score = 0
if game_over:
show_game_over_screen()
game_over = False
all_sprites = pygame.sprite.Group()
platforms = pygame.sprite.Group()
for plat in platforms_list:
p = Platform (*plat)
all_sprites.add(p)
platforms.add(p)
mobs = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
bullets = pygame.sprite.Group()
powerups = pygame.sprite.Group()
for i in range(1):
newmob()
score = 0
# Keep loop running at the right speed
clock.tick(FPS)
# Process input (events)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_s:
player.shoot()
# Updates
all_sprites.update()
# check if player hits a platform - only if falling
if player.vel.y > 0:
hits = pygame.sprite.spritecollide(player,platforms,False)
if hits:
player.pos.y = hits[0].rect.top
player.vel.y = 0
# check to see if a bullet hit a mob
hits = pygame.sprite.groupcollide(mobs,bullets,True,True)
for hit in hits:
score += 1
random.choice(explosion_sound).play()
expl = Explosion(hit.rect.center, 'normal', 50)
all_sprites.add(expl)
if random.random() > 0.75:
power = Normal_Power(hit.rect.center)
all_sprites.add(power)
powerups.add(power)
if random.random() > 0.90:
lives = Special_Power(hit.rect.center)
all_sprites.add(lives)
powerups.add(lives)
newmob()
# check to see if the mob hit the player
hits = pygame.sprite.spritecollide(player, mobs,True)
for hit in hits:
random.choice(explosion_sound).play()
player.shield -= 25
newmob()
expl = Explosion(hit.rect.center, 'small', 50)
all_sprites.add(expl)
if player.shield <= 0:
death_sound.play()
death_animation = Explosion(player.rect.center, 'player', 100)
all_sprites.add(death_animation)
player.hide()
player.lives -= 1
player.shield = 100
else:
random.choice(scream_sound).play()
# check if the player hit a powerup
hits = pygame.sprite.spritecollide(player, powerups, True)
for hit in hits:
if hit.type == 'shield_0':
player.shield += 5
if player.shield >= 100:
player.shield = 100
shield.play()
if hit.type == 'shield_1':
player.shield += 20
if player.shield >= 100:
player.shield = 100
shield.play()
if hit.type == 'shield_2':
player.shield += 20
if player.shield >= 100:
player.shield = 100
shield.play()
if hit.type == 'life':
player.lives += 1
if player.lives >= 3:
player.lives = 3
life.play()
if hit.type == 'power':
special_power.play()
player.powerup()
# if the player died and the explosion finished playing
if player.lives == 0 and not death_animation.alive():
game_over = True
# Draw / Render
screen.fill(white)
screen.blit(background, background_rect)
all_sprites.draw(screen)
draw_text(screen,str(score),red,30, width/ 2, 30)
draw_text(screen,"Score:",red,30, width / 2, 3)
draw_shield_bar(screen,90,20, player.shield)
draw_lives(screen,95,40,player.lives, mini_no_mvmt)
# *after* drawing everything, flip the display
pygame.display.flip()
pygame.quit()
quit()
The error is caused by a sprite in your all_sprites group that has a list as its self.image attribute. I've just printed the sprites before the all_sprites.draw(screen) line
for sprite in all_sprites:
print(sprite, sprite.image)
and it was the player sprite which had a list as its image.
<Player sprite(in 1 groups)> [<Surface(40x25x32 SW)>, <Surface(40x25x32 SW)>]
In the load_movement_images method you define self.standing_frame as a list of two images/pygame.Surfaces and in __init__ you set self.image to the first item of that list. But in the animate method you set self.image to the whole list instead of the active image self.image = self.standing_frame and that leads to the error.
class Player (pygame.sprite.Sprite):
# Sprite for the player
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.load_movement_images()
# self.image is the first image in the
# self.standing_frame list.
self.image = self.standing_frame[0]
# ...
def load_movement_images(self):
self.standing_frame = [no_mvmt_0, no_mvmt_1]
# ...
def animate(self):
now = pygame.time.get_ticks()
if not self.jumping and not self.running:
if now - self.last_update > 350:
self.last_update = now
self.current_frame = (self.current_frame + 1) % len(self.standing_frame)
# Here you set the self.image to the self.standing_fram list instead one image.
self.image = self.standing_frame
# It should be:
# self.image = self.standing_frame[self.current_frame]

How do you get sprites to appear within this space invader game?

I am currently making a space invader game, the sprites that I have created are not appearing the only thing that happens when I run the programme is the interpreter says "processed finished with error code 0" in addition I am using the pycharm IDE. Can you help fix this issue?.
import pygame
import sys
from pygame.locals import *
class Launcher(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load('LaserBase.png')
self.rect = self.image.get_rect()
self.rocketXPos = 512
self.rect.x = self.rocketXPos
self.rect.y = 650
def update(self, gametime):
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
self.rocketXPos += 4
elif keys[pygame.K_LEFT]:
self.rocketXPos -= 4
self.rect.x = self.rocketXPos
self.rect.y = 650
class Invader(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.image.load('inv12.png')
self.rect = self.image.get_rect()
self.__alienPosX = 0
self.__alienPosY = 0
self.__listPos = 0
self.alienSpeed = 4
self.alienDirection = -1
def setPosX(self, x):
self.__alienPosX = x
self.rect.x = x
def setPosY(self, y):
self.__alienPosY = y
self.rect.y = y
def setListPos(self, pos):
self.__listPos = pos
def update(self, gametime):
self.__alienPosX += self.alienSpeed * self.alienDirection
if self.__alienPosX < 100 + (self.__listPos * 32):
self.alienDirection = +1
self.__alienPosY += 4
elif self.__alienPosX > 924 - ((10 - self.__listPos) * 32) :
self.alienDirection = -1
self.__alienPosY += 4
self.rect.x = self.__alienPosX
self.rect.y = self.__alienPosY
class Missile(pygame.sprite.Sprite):
def __init__(self, xInitialPos, yInitialPos):
super().__init__()
self.image = pygame.image.load('bullet.png')
self.rect = self.image.get_rect()
self.__missilePosY = yInitialPos
self.rect.x = xInitialPos
self.rect.y = self.__missilePosY
def update(self, gametime):
self.__missilePosY -= 4
self.rect.y = self.__missilePosY
class Game:
def __init__(self):
pygame.init()
pygame.key.set_repeat(1, 1)
self.width = 1024
self.height = 768
self.screen = pygame.display.set_mode((self.width, self.height))
self.caption = "Space Invaders!!"
pygame.display.set_caption(self.caption)
self.framerate = 60
self.clock = pygame.time.Clock()
self.starfieldImg = pygame.image.load('Starfield1024x768.png')
self.allsprites = pygame.sprite.Group()
self.launcher = Launcher()
self.allsprites.add(self.launcher)
self.aliens = pygame.sprite.Group()
self.missileFired = None
xPos = 512
for i in range(11):
invader = Invader()
invader.setPosX(xPos)
invader.setPosY(100)
self.allsprites.add(invader)
self.aliens.add(invader)
xPos += 32
def update(self, gametime):
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
self.missileFired = Missile(self.launcher.rocketXPos, 650)
self.allsprites.add(self.missileFired)
self.allsprites.update(gametime)
def draw(self):
self.screen.blit(self.starfieldImg, (0, 0))
self.allsprites.draw(self.screen)
pygame.display.flip()
You need endless loop (called "mainloop") to handle events, move/update objects, draw objects on screen.
You could add to Game class
def run(self):
while True:
self.update()
self.draw()
self.clock.tick(self.framerate)
and then use it
g = Game()
g.run()
or
Game().run()
--
BTW: "error code 0" means "program finished without problem".

Pygame - Collisions With Floor/Walls

Hello I am currently making a survival shooter but cannot find any way on how to do my collisions! I am trying to make the player collide with the floors but with no success. Here is an image of the map (I want to collide with moon blocks):
http://i.stack.imgur.com/R2apz.jpg
Here is an image of moon blocks with no Background:
http://i.stack.imgur.com/W9H2m.png
And finally here is my code:
import pygame
import random
gravity = .5
jump_time = 2000
x = 0
y = 0
# Player
class Player(pygame.sprite.Sprite):
def __init__(self, x, y, gravity):
# Player dimensions and position
self.gravity = gravity
# Player image and animation
self.images = []
self.images.append(pygame.image.load('images/player.png'))
self.images.append(pygame.image.load('images/player2.png'))
#~ self.images.append(pygame.image.load('ball1.png'))
#~ self.images.append(pygame.image.load('ball2.png'))
self.maxImage = len(self.images)
self.currentImage = 0
#~ self.rect = pygame.Rect(x, y, 80, 80)
self.rect = self.images[0].get_rect()
self.rect.x = x
self.rect.y = y
self.timeTarget = 10
self.timeNum = 1
self.velX = 0
self.velY = 0
# Jump and gravity
self.vSpeed = 3
self.jumpForce = 15
self.maxVspeed = 3
self.isJumping = False
# Jump inputs
def handle_events(self, event):
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
if not self.isJumping:
self.isJumping = True
elif event.key == pygame.K_a:
self.velX = -5
elif event.key == pygame.K_d:
self.velX = +5
elif event.type == pygame.KEYUP:
if event.key in (pygame.K_a, pygame.K_d):
self.velX = 0
# PLayer updates
def update(self, ground):
keys = pygame.key.get_pressed()
# Jumping
self.vSpeed += gravity
if self.vSpeed > self.maxVspeed:
self.vSpeed = self.maxVspeed
self.rect.y += self.vSpeed
if self.rect.y >= ground.y:
self.vSpeed = 0
self.rect.y = ground.y
self.isJumping = False
if keys[pygame.K_SPACE]:
if not self.isJumping:
self.isJumping = True
if self.isJumping:
if pygame.time.get_ticks() < jump_time:
self.isJumping == True
else:
self.isJumping = False
self.vSpeed -= self.jumpForce
#print "isJumping:", self.isJumping
# Animations
if self.timeNum == self.timeTarget:
self.currentImage += 1
if self.currentImage >= self.maxImage:
self.currentImage = 0
self.timeNum = 0
self.rect.centerx += self.velX
self.rect.centery += self.velY
# Screen wrap
if self.rect.right > 1280:
self.rect.left = 0
elif self.rect.left < 0:
self.rect.right = 1280
# Player rendering
def render(self, surface):
surface.blit(self.images[self.currentImage], self.rect)
#----------------------------------------------------------------------
class Zombie():
def __init__(self, x, y):
self.image = pygame.image.load('images/zombie.png')
#~ self.image = pygame.image.load('ball2.png')
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.direction_left = True
def update(self, surface_rect):
if self.direction_left:
self.rect.x -= 1
if self.rect.left <= surface_rect.left:
self.direction_left = not self.direction_left
else:
self.rect.x += 1
if self.rect.right >= surface_rect.right:
self.direction_left = not self.direction_left
def render(self, surface):
surface.blit(self.image, self.rect)
#----------------------------------------------------------------------
class Background():
def __init__(self):
self.image = pygame.image.load('images/arena2.jpg')
#~ self.image = pygame.image.load('background.jpg')
self.rect = self.image.get_rect()
def render(self, surface):
surface.blit(self.image, self.rect)
#----------------------------------------------------------------------
class Game():
def __init__(self):
pygame.init()
# A few variables
self.gravity = .50
self.ground = pygame.Rect(0, 640, 1280, 80)
# Screen
size = (1280, 720)
self.screen = pygame.display.set_mode(size)
pygame.display.set_caption('Moon Survival!')
# Moon / Background
self.moon = Background()
# Zombies
self.zombies = []
for i in range(10):
self.zombies.append( Zombie(random.randint(0,1280), random.randint(0,720)) )
# Player
self.player = Player(25, 320, self.gravity)
# Font for text
self.font = pygame.font.SysFont(None, 72)
# Pause - center on screen
self.pause_text = self.font.render("PAUSE", -1, (255,0,0))
self.pause_rect = self.pause_text.get_rect(center = self.screen.get_rect().center)
def run(self):
clock = pygame.time.Clock()
# "state machine"
RUNNING = True
PAUSED = False
GAME_OVER = False
# Game loop
while RUNNING:
# (all) Events
for event in pygame.event.get():
if event.type == pygame.QUIT:
RUNNING = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
RUNNING = False
elif event.key == pygame.K_p:
PAUSED = not PAUSED
# Player/Zomies events
if not PAUSED and not GAME_OVER:
self.player.handle_events(event)
# (all) Movements / Updates
if not PAUSED and not GAME_OVER:
self.player.update(self.ground)
for z in self.zombies:
z.update(self.screen.get_rect())
# (all) Display updating
self.moon.render(self.screen)
for z in self.zombies:
z.render(self.screen)
self.player.render(self.screen)
if PAUSED:
self.screen.blit(self.pause_text, self.pause_rect)
pygame.display.update()
# FTP
clock.tick(100)
# --- the end ---
pygame.quit()
#---------------------------------------------------------------------
Game().run()
Any help will be greatly appreciated, thank you.
I made a very similar game for PyWeek #17 called "Miner".
Here's a screenshot: http://media.pyweek.org/dl/17/powrtoch/miner_ss.png (you can see the similarity!)
You can find the relevant code on GitHub here: https://github.com/marcusmoller/pyweek17-miner/blob/master/miner/engine.py#L202-L220:
def checkCollision(self, sprite, xVel, yVel):
for x in range(len(level.levelStructure)):
for y in range(len(level.levelStructure[x])):
block = level.levelStructure[x][y]
if block is not None:
if pygame.sprite.collide_rect(sprite, block):
if xVel < 0:
sprite.rect.x = block.rect.x + block.rect.w
if xVel > 0:
sprite.rect.x = block.rect.x - sprite.rect.w
if yVel < 0:
sprite.rect.y = block.rect.y + block.rect.h
if yVel > 0 and not sprite.onGround:
sprite.onGround = True
sprite.rect.y = block.rect.y - sprite.rect.h
You could do something like this using collide_rect:
# See if the Sprite block collides with anything in the Ground block_list
for block in groundBlocks:
if(collide_rect(player, block)):
# do not fall
else:
# fall
where all Block you can walk on are in the groundBlocks list.

Categories

Resources