Related
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()
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.
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]
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".
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.