Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I am using pygame to make a game but when I try to load my pictures it results in a error: Couldn't open ball.png. can any one please help? here is my entire code.
To be exact I am trying to figure out why in the class BoxSprite class does ("ball.png") not load. Also why does that happen in class missle and class gun with ("arrow.png") and ("gun.png")???
import pygame
import sys
from pygame.locals import KEYDOWN, KEYUP, K_SPACE, K_ESCAPE, K_RIGHT, K_LEFT
width = 320
height = 240
imageWidth = 32
imageHeight = 32
goingLeft = True
invaderHeight = 0
gunLeft = False
gunRight = False
gunXpos = (width/2)-(imageWidth/2)
delay = 10
class BoxSprite(pygame.sprite.Sprite):
image = None
def __init__(self, initial_position):
pygame.sprite.Sprite.__init__(self)
if BoxSprite.image is None:
BoxSprite.image = pygame.image.load("ball.png")
self.image = BoxSprite.image
self.rect = self.image.get_rect()
self.rect.topleft = initial_position
self.next_update_time = 0 # update() hasn't been called yet.
self.yPos = initial_position[1]
def update(self, current_time, left, right):
global goingLeft, invaderHeight, imageWidth, delay
# Update every 2 milliseconds = 1/500th of a second.
if self.next_update_time < current_time:
# If we're at the left or right the screen, switch directions.
if self.rect.topleft[0] == left:
goingLeft = False
invaderHeight += 1
elif self.rect.topleft[0] == right-imageWidth:
goingLeft = True
invaderHeight += 1
if goingLeft == True:
self.rect.topleft = [self.rect.topleft[0]-1, self.rect.topleft[1]]
else:
self.rect.topleft = [self.rect.topleft[0]+1, self.rect.topleft[1]]
self.rect.topleft = [self.rect.topleft[0], invaderHeight+self.yPos]
self.next_update_time = current_time + delay
class missile(pygame.sprite.Sprite):
image = None
def __init__(self, initial_position):
pygame.sprite.Sprite.__init__(self)
if missile.image is None:
missile.image = pygame.image.load("arrow.png")
self.image = missile.image
self.rect = self.image.get_rect()
self.rect.topleft = initial_position
self.next_update_time = 0 # update() hasn't been called yet.
def update(self, current_time, left, right):
global missile
# Update every 2 milliseconds = 1/500th of a second.
if self.next_update_time < current_time:
# If we're reached the top then stop
if self.rect.topleft[1] == 0:
missiles.remove(self)
self.kill()
return
else:
self.rect.topleft = [self.rect.topleft[0], self.rect.topleft[1]-1]
self.next_update_time = current_time + 4
class gun(pygame.sprite.Sprite):
image = None
def __init__(self):
global width, imageHeight, gunXpos
pygame.sprite.Sprite.__init__(self)
if gun.image is None:
gun.image = pygame.image.load("gun.png")
self.image = gun.image
self.rect = self.image.get_rect()
self.rect.topleft = [gunXpos, height-imageHeight]
self.next_update_time = 0 # update() hasn't been called yet.
def update(self, current_time, left, right):
global gunXpos, width, imageWidth
# check update
if self.next_update_time < current_time:
if gunLeft and gunXpos>0:
gunXpos -= 1
if gunRight and gunXpos<width-imageWidth:
gunXpos += 1
self.rect.topleft = [gunXpos, self.rect.topleft[1]]
self.next_update_time = current_time + 1
def checkInput():
global gunLeft, gunRight, missiles, gunXpos, height
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
sys.exit(0)
elif event.key == K_RIGHT:
gunLeft = False
gunRight = True
elif event.key == K_LEFT:
gunLeft = True
gunRight = False
else:
missiles.append(missile([gunXpos, height]))
elif event.type == KEYUP and event.key != K_SPACE:
gunRight = False
gunLeft = False
def checkCollisions():
global missiles, boxes
if missiles != [] and boxes != []:
for m in missiles:
found = False
for b in pygame.sprite.spritecollide(m, boxes, 0):
boxes.remove(b)
b.kill()
found = True
if found:
missiles.remove(m)
m.kill()
pygame.init()
boxes = []
missiles = []
for x in range(0, width, 32):
for y in range(0, 96, 32):
boxes.append(BoxSprite([x, y]))
screen = pygame.display.set_mode([320, 240])
gunControl = gun()
while boxes != []:
screen.fill([0, 0, 0]) # blank the screen.
time = pygame.time.get_ticks()
for b in boxes:
b.update(time, 0, width)
screen.blit(b.image, b.rect)
checkInput()
checkCollisions()
gunControl.update(time, 0, width)
screen.blit(gunControl.image, gunControl.rect)
for m in missiles:
m.update(time, 0, width)
screen.blit(m.image, m.rect)
pygame.display.update()
if pygame.sprite.spritecollide(gunControl, boxes, 0) != []:
pygame.time.delay(50)
print ("loser")
sys.exit(0)
if len(boxes)<10:
delay = len(boxes)
pygame.time.delay(50)
print ("winner")
http://www.pygame.org/docs/ref/image.html#pygame.image.load
you can use pygame.image.load(os.path.join('path', 'to', 'image.png'))
which returns a Surface object. You should then be able to set your sprite's image attribute to equal this value.
like so:
def __init__(self, initial_position):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(os.path.join("path", "to", "ball.png"))
Related
I am making a python game with pygame on my home computer for school running with python 3.6.3 and pygame 1.9.3. When working on my game I also worked at school where it was working correctly just slower as expected but when I started to load images it randomly choose the images and didn't load the correct ones on school computer not home one (I think this might be due to change in arrays and loading them). I soon found I was running python 3.5.3 at school and then when updating it the python and pygame, The game ran extremely slow and was unplayable. The images loaded correctly but the change in speed was extreme.
Summary:
Pygame at home working great pygame 1.9.3 python 3.6.3.
Working fine at school until loading images python 3.5.3.
Updating school corrected it but is now running unbearably slow.
I would love a fix for this problem either working for other python version or running at a variable speed for school computers.
If there is any optimisation that could be easily implemented that would be very useful as well as I am not sure how to load images effectively
Code:
import pygame
import random
import math
def main():
#load images?:
bg = pygame.image.load("background6.png")
wall = 100
zombies = []
currentnumber = 0
gamepaused = False
moveupx = False
movedownx = False
moveupy = False
movedowny = False
movex = 0
movey = 0
movespeed = 10
time10 = False
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
blue = (0, 0, 255)
fullscreen = pygame.FULLSCREEN
pygame.init()
pygame.font.init()
myfont = pygame.font.SysFont('Comic Sans MS', 100)
clock = pygame.time.Clock()
clock.tick(30)
#creating sprite groups
heads = pygame.sprite.Group()
bodys = pygame.sprite.Group()
bullets = pygame.sprite.Group()
allsprites = pygame.sprite.Group()
players = pygame.sprite.Group()
playerr = Player()
allsprites.add(playerr)
players.add(playerr)
heads.add()
bodys.add()
gameDisplay = pygame.display.set_mode((1920, 1080), fullscreen)
pygame.display.set_caption("Last Stand")
gameExit = False
pygame.display.update()
#This will get the ticks from inisilising pygame in ms
pretime = pygame.time.get_ticks()
while not gameExit:
time = pygame.time.get_ticks()-pretime
#print (time/1000)
timerounded = round(time/1000)
timedisplay = round(time/1000,1)
spawnbullet = False
mouse = pygame.mouse.get_pos()
# background things
gameDisplay.fill(white)
gameDisplay.blit(bg, (0, 0))
if timerounded % 10 == 0:
if timerounded != currentnumber:
time10 = True
currentnumber = timerounded
else:
time10 = False
#start gameimput look e is event and it loops for each event in pygame
#IT WILL GO THOUGH EACH EVEN!!!!!!! SO CHEACK FOR EACH EVENT
for e in pygame.event.get():
if e.type == pygame.MOUSEBUTTONDOWN:
#so only if it will shoot foward NEED TO ADD FEEDBACK LATER
if mouse[0] < 1500:
spawnbullet = True
#so the problem is that if there is a key up for s then it would kill the key down for w as it would be set
# to 0
if e.type == pygame.KEYDOWN and e.key == pygame.K_w:
moveupy = True
if e.type == pygame.KEYDOWN and e.key == pygame.K_s:
movedowny = True
if e.type == pygame.KEYUP and e.key == pygame.K_w:
moveupy = False
if e.type == pygame.KEYUP and e.key == pygame.K_s:
movedowny = False
if e.type == pygame.KEYDOWN and e.key == pygame.K_a:
moveupx = True
if e.type == pygame.KEYDOWN and e.key == pygame.K_d:
movedownx = True
if e.type == pygame.KEYUP and e.key == pygame.K_a:
moveupx = False
if e.type == pygame.KEYUP and e.key == pygame.K_d:
movedownx = False
if e.type == pygame.QUIT:
gameExit = True
if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
gameDisplay = pygame.display.set_mode((1920, 1080), fullscreen)
gameExit = True
# CAHNGE BACK LATER
# END event loop
#LOGIC FOR MOVING THE PLAYER:
if moveupy == True:
movey = -movespeed
if movedowny == True:
movey = movespeed
if movedowny == False and moveupy == False:
movey = 0
if moveupx == True:
movex = -movespeed
if movedownx == True:
movex = movespeed
if movedownx == False and moveupx == False:
movex = 0
# Updating player have to do this at the start as need the angle and the top left cords
for player in players:
#REALLY NOT WOKRING THE MOVEX DOESNT WORK AND THE CHANGING HTE X AND WHY DOESNT WORK!!!
player.move(movex, movey)
angle, topleft = player.update(mouse)
# needed another name for bullet so went for bullett
if spawnbullet == True:
bullett = Bullet(angle, topleft)
#having the bullets only in the bullets class so it can render after the player
bullets.add(bullett)
#creating zombies
if random.randint(0,2) == 1:
ztype = "fast"
else:
ztype = "slow"
#so at the start it spawns one for sure
if time == 0:
startlocation = [5, random.randint(320, 920)]
zombies, heads, bodys = createz(zombies, ztype, startlocation, heads, bodys)
if random.randint(0,10000) >9950-(timerounded**2): #So the time incraeed the odds expernetray
startlocation = [5, random.randint(320, 920)]
# WOULD LIKE THE ZOMBIES TO RUN FASTER AS THE GAME GOES ON!
zombies, heads, bodys = createz(zombies, ztype, startlocation, heads, bodys)
#updating Z
zombies, totaldamnge = updatez(zombies, heads, bodys)
#updating bullets
for bullet in bullets:
bullet.update()
#print(totaldamnge)
wall -= totaldamnge
#Cheacking for hitting bullets
colstions(zombies, heads, bodys, bullets)
if time10 == True:
wall += 25
if wall >100: wall = 100
walltext = myfont.render(str(wall)+"%",False, (0, 0, 0))
gameDisplay.blit(walltext,(1600,100))
#print(wall)
timedisplayer = myfont.render(str(timedisplay) + "Seconds", False, (0, 0, 0))
gameDisplay.blit(timedisplayer, (10, 5))
#drawing:
#so cant use allsprites so might just wont have zomnbie head and zombie body in it
#I CAN CHANGE WHEN WHAT IS DRAW AND WHAT IS ON WHAT
bullets.draw(gameDisplay)
allsprites.draw(gameDisplay)
heads.draw(gameDisplay)
bodys.draw(gameDisplay)
pygame.display.update()
clock.tick(30)
def colstions(zombies, heads, bodys, bullets):
#so as having both hp and having the zombie having a head and body with 2 diffrent hitboxes
headdamage = 140
bodydamge = 60
#so this part had sooooooo many proplems frist with like all the while loops next spend a long time trying to find what was wrong when it was just the head in bodys and vis versa
if len(pygame.sprite.groupcollide(bullets, heads,False, False)) != 0 or len(pygame.sprite.groupcollide(bullets, bodys,False, False)) != 0:
for bullet in bullets:
hitthehead = False
hitthebody = False
zheadkilledzombie = False
zbodykilledzombie = False
counter1 = 0
counter2 = 0
for head in heads:
#so it doesnt make the bullet hit more than one zombie head
if hitthehead == False:
if pygame.sprite.collide_circle(bullet, head):
hp = zombies[counter1].hpordead(headdamage)
hitthehead = True
if hp <= 0:
zheadkilledzombie = True
head.kill()
print("hithead")
counter1 += 1
#so it doesnt check for body hits if it has hit a heah
if hitthehead == False:
for body in bodys:
if hitthebody == False:
#If it colldes and if the zombie is not already dead from the head shots
if pygame.sprite.collide_rect(bullet, body):
print("hitbody")
hp = zombies[counter2].hpordead(bodydamge)
hitthebody = True
if hp <= 0:
zbodykilledzombie = True
body.kill()
counter2 += 1
if hitthehead == True or hitthebody == True:
bullet.kill()
#so killing the head if the body hit killed the zombie
if zheadkilledzombie == True:
zombiekilled = False
counter3 = 0
for body in bodys:
if zombiekilled == False:
hp = zombies[counter3].hpordead(0)
if hp <= 0:
body.kill()
zombies.pop(counter3)
zombiekilled = True
counter3 += 1
#killing the body if killing is arealy dead
if zbodykilledzombie == True:
zombiekilled = False
counter4 = 0
for head in heads:
if zombiekilled == False:
hp = zombies[counter4].hpordead(0)
if hp <= 0:
head.kill()
zombies.pop(counter4)
zombiekilled = True
counter4 += 1
def createz(zombies, ztype, startlocation, heads, bodys, ):
createdzombie = Zombie(startlocation, ztype)
zombies.append(createdzombie)
Hcords = (startlocation[0]+20, startlocation[1]-57)
Bcords = (startlocation[0], startlocation[1])
#need to have it also say what type of z it is.
heads.add(head(Hcords,ztype))
bodys.add(body(Bcords,ztype))
print ("created")
#dont think i need to return?
return zombies, heads, bodys
def updatez(zombies, heads, bodys):
totaldamnge = 0
#somthing ent working
Hcordsx = []
Hcordsy = []
Bcordsx = []
Bcordsy = []
ATWALLupdateanimationN = []
for x in range(len(zombies)):
cords, walldamge, updateanimationN = zombies[x].update()
ATWALLupdateanimationN.append(updateanimationN)
totaldamnge += walldamge
#putting all the cords into arrays just after reading them
Hcordsx.append(cords[0]+ 20)
Hcordsy.append(cords[1] - 57)
Bcordsx.append(cords[0])
Bcordsy.append(cords[1])
counter = 0
for body in bodys:
Bcords = (Bcordsx[counter], Bcordsy[counter])
body.update(Bcords, ATWALLupdateanimationN[counter])
counter += 1
counter = 0
#I have to use the counter as cant do 1 per 1 on the head in heads thing so have to have a seperat counter
for head in heads:
Hcords = (Hcordsx[counter],Hcordsy[counter])
head.update(Hcords,ATWALLupdateanimationN[counter])
counter += 1
return zombies, totaldamnge
class Bullet(pygame.sprite.Sprite):
def __init__(self,angle, playerpos):
pygame.sprite.Sprite.__init__(self)
#Chanig the scale of the image so it doesnt stick out the gun too much
self.image = pygame.transform.rotozoom(pygame.image.load("bulletpixel 6.png"), angle, 0.8)
self.rect = self.image.get_rect()
self.speed = 60
self.angle = angle
self.rect.x = (self.rect.x + playerpos[0])
self.rect.y = (self.rect.y + playerpos[1])
def update(self):
#moging it depending on its angle. so spliting up to horizontal and vertical bny taking thee cos and sin of the angle
self.rect.x -= int(self.speed*math.cos(-self.angle*math.pi/180))
self.rect.y -= int(self.speed*math.sin(-self.angle*math.pi/180))
#could make this better for so when top of screen also deleate
if self.rect.x <= -5:
pygame.sprite.Sprite.kill(self)
if self.rect.y <= -20 or self.rect.y >= 2000:
pygame.sprite.Sprite.kill(self)
def kill(self):
pygame.sprite.Sprite.kill(self)
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.angle = 0
#for now sttg to to zombie as didnt save the player image
self.image = pygame.image.load("player2.png")
self.rect = self.image.get_rect()
#need to create an image for player.
#ok so got too choess so i could if e.type == MOUSEMOTION:
#and just have less than more than or like so i can 3 locations it is pointed or could have the player angle towards the mouse pointer and also the shotsneed to be angled anywhay so.
self.rect.x = 1600
self.rect.y = 600
self.center = self.image.get_rect().center
#setting the starting location
self.movingamoutx = 1640
self.movingamouty = 500
self.posforbullet = (1640, 500)
def update(self,mouse):
# SO THIS THIS IS MAD
#Code for making the player follow the mouse:
#First sets the image to the stating image if this is not here the image gets bugged out from rotating many times
self.image = pygame.image.load("player2.png")
#Taking the x and y apart from the mouse
mouse_x, mouse_y = mouse
#calulationg the relative position of the mouse by subtracting the player postion
#I subtracke the previs frame player pos to calulate the new anlge as that is the only way i can get the angle from the gun and not the player and so it will go to the curcer
#This does in fact make it be one frame behind for the angle but as it is 30 fps this will not make a differnce
#subtracking 10 so it comes from a but up from the center and so is on the cetner of the curcer
rel_x, rel_y = mouse_x - self.posforbullet[0], mouse_y - self.posforbullet[1]-10
#calqulating the angle by using atan2
#this takes 2 vectors and calclated the angle inbeween them NOT 100 ON THIS this is in rad so it needs to be degress so is changed to degress by timesing my 180/ pi
# also Return atan(y / x), in radians. The result is between -pi and pi. The vector in the plane from the origin to point (x, y) makes this angle with the positive X axis.
#The point of atan2() is that the signs of both inputs are known to it, so it can compute the correct quadrant for the angle. For example, atan(1) and atan2(1, 1) are both pi/4, but atan2(-1, -1) is -3*pi/4.
self.angle = (180 / math.pi) * -math.atan2(rel_y, rel_x)
#the angle is inverted so to make it be where it is pointed subtracted 180 degress
self.angle -= 180
#seting self.rotated to the image rotated to by the angle
self.rotated = pygame.transform.rotate(self.image, self.angle)
#getting the cords of the new rotated image
rotRect = self.rotated.get_rect()
#keeping the old center from before
rotRect.center = self.rotated.get_rect().center
#setting the new cords to image rotated cords, the adding is the amout that is getting moved by
self.rect = (rotRect[0]+ self.movingamoutx), (rotRect[1]+ self.movingamouty)
#setting the image to the new rotated one
self.image = self.rotated
#Creating a variable basited of the center of the rotated image so the bullet can shoot from the image then
#adding the move amouts to put it into spot then subtracting to make it really shoot from the barrel and not the
#true center
#self.posforbullet = (rotRect.center[0] + self.movingamoutx-int(math.cos(self.changedangle)*20) ,rotRect.center[1]+ self.movingamouty-40)
self.posforbullet = (rotRect.center[0] + self.movingamoutx-15 ,rotRect.center[1]+ self.movingamouty-45)
return self.angle, self.posforbullet
def move(self,movex, movey):
self.movingamoutx += movex
self.movingamouty += movey
#cheaking to see if the player is trying to go to far away
if self.movingamouty <= 320:
self.movingamouty = 320
elif self.movingamouty >= 840:
self.movingamouty = 840
if self.movingamoutx >= 1700:
self.movingamoutx = 1700
elif self.movingamoutx <= 1500:
self.movingamoutx = 1500
class head(pygame.sprite.Sprite):
def __init__(self,cords, type):
pygame.sprite.Sprite.__init__(self)
if type == "fast":
self.type = "fast"
self.image = pygame.transform.scale(pygame.image.load("fasthead.png"),[70,60])
else:
self.type = "slow"
self.image = pygame.transform.scale(pygame.image.load("slowhead.png"),[70,60])
self.rect = self.image.get_rect()
self.rect.x = cords[0]
self.rect.y = cords[1]
self.ticks = 0
self.putheadonbodyx = -11
self.putheadonbodyy = -2
self.firsttimewall = True
def update(self,newcords,updateanimationNumber):
self.ticks += 1
if updateanimationNumber != 100:
if self.firsttimewall == True:
self.firsttimewall = False
updateanimationNumber = 1
if self.type == "slow":
if updateanimationNumber == 2:
self.image = pygame.image.load("satwallhead1.png")
elif updateanimationNumber == 1:
self.image = pygame.image.load("satwallhead2.png")
if self.type == "fast":
if updateanimationNumber == 2:
self.image = pygame.image.load("fatwallhead1.png")
elif updateanimationNumber == 1:
self.image = pygame.image.load("fatwallhead2.png")
self.rect = self.image.get_rect()
self.rect.x = newcords[0] + self.putheadonbodyx
self.rect.y = newcords[1] + self.putheadonbodyy
def kill(self):
pygame.sprite.Sprite.kill(self)
class body(pygame.sprite.Sprite):
def __init__(self, cords, type):
pygame.sprite.Sprite.__init__(self)
if type == "fast":
self.type = "fast"
self.image = pygame.image.load("fastbody1.png")
self.tickamout = 10
else:
self.type = "slow"
self.image = pygame.image.load("slowbody1.png")
self.tickamout = 15
self.rect = self.image.get_rect()
self.rect.x = cords[0]
self.rect.y = cords[1]
self.ticks = 0
self.number = 0
self.firsttimewall = True
def update(self, newcords, Atwallnumber):
self.ticks += 1
if Atwallnumber == 100:
#This is so it only trys to change image it if is time to changer
if self.ticks % self.tickamout == 0:
self.number += 1
if self.number == 5:
self.number = 1
if self.type == "slow":
if self.number == 1:
self.image = pygame.image.load("slowbody1.png")
elif self.number == 2:
self.image = pygame.image.load("slowbody2.png")
elif self.number == 3:
self.image = pygame.image.load("slowbody3.png")
elif self.number == 4:
self.image = pygame.image.load("slowbody4.png")
elif self.type == "fast":
if self.number == 1:
self.image = pygame.image.load("fastbody1.png")
elif self.number == 2:
self.image = pygame.image.load("fastbody2.png")
elif self.number == 3:
self.image = pygame.image.load("fastbody3.png")
elif self.number == 4:
self.image = pygame.image.load("fastbody4.png")
self.rect = self.image.get_rect()
else:
self.atwall(Atwallnumber)
#Dont think that chaning the codes from the get rect will be too much of a problem and also could save the
#images beofre having ot load them
self.rect.x = newcords[0]
self.rect.y = newcords[1]
def atwall(self,updateanimationNumber):
#seeing if this is the first time
if self.firsttimewall == True:
self.firsttimewall = False
updateanimationNumber = 1
if self.type == "slow":
if updateanimationNumber == 2:
self.image = pygame.image.load("satwallbody1.png")
elif updateanimationNumber == 1:
self.image = pygame.image.load("satwallbody2.png")
else:
if updateanimationNumber == 2:
self.image = pygame.image.load("fatwallbody1.png")
elif updateanimationNumber == 1:
self.image = pygame.image.load("fatwallbody2.png")
self.rect = self.image.get_rect()
def kill(self):
pygame.sprite.Sprite.kill(self)
class Zombie():
def __init__(self, startlocation, ztype):
if ztype == "fast":
self.speed = 11
self.hp = 100
else:
self.speed = 6
self.hp = 200
self.location = startlocation
self.walldamage = 0
self.ticks = 0
#So it will stay 100 before it gets to the wall
self.updateanimationnumber = 100
def update(self):
if self.location[0] < 1300: #the y direction
self.walldamage = 0
self.location[0] += self.speed #as this should be 30 frams a second it should move 3 pixies each time
#so if at the wall
elif self.location[0] >= 1300:
self.walldamage = 0
#cjamge the % number to change how fast the wall dies
if self.ticks % 30 == 0:
self.walldamage = 5
self.updateanimationnumber = 1
#so it will have to hitting animation when dealing damgage
elif self.ticks % 15 == 0:
self.updateanimationnumber = 2
if self.ticks % 15 != 0:
self.updateanimationnumber = 0
self.ticks += 1
return self.location, self.walldamage, self.updateanimationnumber
def hpordead(self,subtrackhp):
self.hp -= subtrackhp
return self.hp
if __name__ == '__main__':
main()
You should load the images in the global scope or another module and import them and then reuse them in your program. Do not load them in your functions or __init__ methods that get called in the while loop all the time or when you create an instance. Reading from the hard disk is slow.
Also, use the convert or convert_alpha methods of surfaces to improve the performance (converted surfaces get blitted faster), e.g.:
# All uppercase letters indicate that it's a constant and should never be changed.
MY_IMAGE = pygame.image.load('my_image.png').convert() # Or `.convert_alpha()`
# Load the images once at program start. You can also do that in
# another module and import them or load all images automatically
# and put them into a dictionary.
PLAYER_IMAGE = pygame.image.load("player2.png").convert_alpha()
BULLET_IMAGE = pygame.image.load("bulletpixel 6.png").convert_alpha()
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = PLAYER_IMAGE # Either assign the global image directly ...
#-----------------------------------
# or pass the image to __init__.
def __init__(self, image):
pygame.sprite.Sprite.__init__(self)
self.image = image
player = Player(PLAYER_IMAGE)
In the Bullet class you can rotate the original image. transform.rototzoom creates a new surface/image and doesn't modify the original.
class Bullet(pygame.sprite.Sprite):
def __init__(self, angle, playerpos):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.transform.rotozoom(BULLET_IMAGE, angle, 0.8)
You load images too many times. Load them only once in __init__ and later assign from one variable to another.
For example in Player load image to self.original and later assign
self.image = self.original
or
self.image = pygame.transform.rotate(self.original, self.angle)
Similar with
self.number += 1
if self.number == 5:
self.number = 1
if self.type == "slow":
if self.number == 1:
self.image = pygame.image.load("slowbody1.png")
elif self.number == 2:
self.image = pygame.image.load("slowbody2.png")
elif self.number == 3:
self.image = pygame.image.load("slowbody3.png")
elif self.number == 4:
self.image = pygame.image.load("slowbody4.png")
elif self.type == "fast":
if self.number == 1:
self.image = pygame.image.load("fastbody1.png")
elif self.number == 2:
self.image = pygame.image.load("fastbody2.png")
elif self.number == 3:
self.image = pygame.image.load("fastbody3.png")
elif self.number == 4:
self.image = pygame.image.load("fastbody4.png")
load all images in __init__ to two list
self.slowimages = [
pygame.image.load("slowbody1.png"),
pygame.image.load("slowbody2.png"),
pygame.image.load("slowbody3.png"),
pygame.image.load("slowbody4.png"),
]
self.fastimages = [
pygame.image.load("fastbody1.png"),
pygame.image.load("fastbody2.png"),
pygame.image.load("fastbody3.png"),
pygame.image.load("fastbody4.png"),
]
and later you can assign image without if/elif using one line
if self.type == "slow":
self.image = self.slowimages[self.number - 1]
elif self.type == "fast":
self.image = self.fastimages[self.number - 1]
or even load all in one dictionary with two lists
self.all_images = {
"slow": [
pygame.image.load("slowbody1.png"),
pygame.image.load("slowbody2.png"),
pygame.image.load("slowbody3.png"),
pygame.image.load("slowbody4.png"),
],
"fast": [
pygame.image.load("fastbodu1.png"),
pygame.image.load("fastbodu2.png"),
pygame.image.load("fastbodu3.png"),
pygame.image.load("fastbodu4.png"),
],
]
and later you can assign image without if/elif using one line
self.image = self.all_images[self.type][self.number - 1]
BTW in self.number you could keep values 0..3 instead of 1..4 and then in self.all_images[self.type][self.number - 1] you could use self.number instead of self.number - 1
And then instead of
self.number += 1
if self.number == 5:
self.number = 1
you can use modulo and get one line
self.number = (self.number + 1) % 4
Instead of
self.rect.x = newcords[0]
self.rect.y = newcords[1]
you can do in one line
self.rect.topleft = newcords
I'm having problems with making my car move. For an assignment, I have to make a simulator. I need to make cars spawn, let them check if the trafficlight's red, orange or green, and the move when the green light appears. How can i make it so that the cars I spawn move along waypoints i specify by using a waypoint-create class I made?
I have the following python file that makes a list of waypoints.
waypoints.py:
class WayPoint:
def __init__(self, x, y):
self.x = x
self.y = y
def getX(self):
return self.x
def getY(self):
return self.y
class WayPointsList:
def __init__(self):
self.wayPoints = []
def add_wayPoint(self, x, y):
self.wayPoints.append(WayPoint(x, y))
def __len__(self):
return len(self.wayPoints)
def get_wayPoint(self, i):
return [self.wayPoints[i].getX(), self.wayPoints[i].getY()]
When I call this class, the way I use it is like this:
l = WayPointsList
l.add_wayPoint(55,67)
Here's my main.py:
import math
import random, assets
from bus import Bus
from car import Car
from lights import Lights
from waypoints import WayPointsList
import pygame as pg
class Mainstuff(object):
def __init__(self):
pg.init()
self.clock = pg.time.Clock()
self.screen = pg.display.set_mode((assets.screen_width, assets.screen_height))
self.background = pg.image.load(assets.background)
self.running = True
self.car_group = pg.sprite.Group()
self.light_group = pg.sprite.Group()
def event_loop(self):
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
elif event.type == pg.KEYDOWN:
if event.key == pg.K_1:
car110 = Car()
car110.set_image(assets.furore)
car110.rotate(180)
car110.set_position(0, 273)
self.car_group.add(car110)
elif event.key == pg.K_2:
car109 = Car()
car109.set_image(assets.hachura)
car109.rotate(180)
car109.set_position(0, 306)
self.car_group.add(car109)
elif event.key == pg.K_3:
car108 = Car()
car108.set_image(assets.jefferson)
car108.rotate(180)
car108.set_position(0, 343)
self.car_group.add(car108)
elif event.key == pg.K_4:
car107 = Car()
car107.set_image(assets.michelli)
car107.rotate(270)
car107.set_position(410, 550)
self.car_group.add(car107)
elif event.key == pg.K_5:
car106 = Car()
car106.set_image(assets.traceAM)
car106.rotate(270)
car106.set_position(460, 550)
self.car_group.add(car106)
elif event.key == pg.K_6:
car105 = Car()
car105.set_image(assets.traceAM)
car105.set_position(750, 300)
self.car_group.add(car105)
elif event.key == pg.K_7:
car104 = Car()
car104.set_image(assets.rumbler)
car104.set_position(750, 265)
self.car_group.add(car104)
elif event.key == pg.K_8:
car103 = Car()
car103.set_image(assets.rumbler)
car103.rotate(90)
car103.set_position(294, 0)
self.car_group.add(car103)
elif event.key == pg.K_9:
car102 = Car()
car102.set_image(assets.rumbler)
car102.rotate(90)
car102.set_position(337, 0)
self.car_group.add(car102)
elif event.key == pg.K_0:
car101 = Car()
car101.set_image(assets.rumbler)
car101.rotate(90)
car101.set_position(380, 0)
self.car_group.add(car101)
elif event.key == pg.K_b:
car201 = Bus()
car201.set_image(assets.bus)
car201.set_position(700, 229)
self.car_group.add(car201)
elif event.key == pg.K_x:
self.car_group.empty()
def update(self):
self.screen.fill(assets.white)
self.car_group.update()
#self.light_group.update()
def draw(self):
self.screen.blit(self.background,(0,0))
self.car_group.draw(self.screen)
self.light_group.draw(self.screen)
def run(self):
while self.running:
self.event_loop()
self.update()
self.draw()
pg.display.update()
self.clock.tick(assets.FPS)
if __name__ == '__main__':
test = Mainstuff()
test.run()
pg.quit()
And here's my car.py:
import pygame, assets, math
class Car(pygame.sprite.Sprite):
def __init__(self):
super(Car, self).__init__()
self.image = pygame.Surface((assets.car_width, assets.car_height))
self.image.fill(assets.red)
self.rect = self.image.get_rect()
self.speed = 1
self.angle = 0
def set_position(self, x, y):
self.rect.x = x
self.rect.y = y
def get_x_position(self):
return self.rect.x
def get_y_position(self):
return self.rect.y
def set_image(self, filename=None):
if filename != None:
self.image = pygame.image.load(filename).convert()
#self.image.fill(assets.green)
self.rect = self.image.get_rect()
def rotate(self, angle):
self.angle = angle
self.image = pygame.transform.rotate(self.image, angle)
self.rect = self.image.get_rect()
#not sure what to do here
def move_position(self, x, y):
# use angle to calculate direction
radius_angle = math.radians(self.angle)
self.rect.x -= self.speed * math.cos(radius_angle)
self.rect.y -= self.speed * math.sin(radius_angle)
print('move', self.angle, self.rect.x, self.rect.y)
def update(self):
self.move_position(0, 0)
I made example.
It takes first point from list as start position and second as target.
It uses pygame.math.Vector2() to calculate one step
current = current + (target - current).normalize() * speed
When player is in target then it get next point from the list as target.
#!/usr/bin/env python3
import pygame
# === CONSTANS === (UPPER_CASE names)
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = ( 0, 255, 0)
BLUE = ( 0, 0, 255)
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 400
# === CLASSES === (CamelCase names)
class Player():
def __init__(self, waypoints, loop=False):
# create green circe
r = 10
self.image = pygame.Surface((2*r, 2*r)).convert_alpha()
self.rect = self.image.get_rect()
self.image.fill((0,0,0,0))
pygame.draw.circle(self.image, (0,255,0), (r, r), r)
# ---
self.loop = loop
self.speed = 5
self.waypoints = waypoints
self.next_point = 0
# set current position
# I use Vector2 because it keeps position as float numbers
# and it makes calcuations easier and more precise
self.current = pygame.math.Vector2(self.waypoints[0])
# set position in rect to draw it
self.rect.center = self.current
# set end point if exists on list
self.target_index = 1
if self.target_index < len(self.waypoints) - 1:
self.target = pygame.math.Vector2(self.waypoints[self.target_index])
self.moving = True
else:
self.target = self.current
self.moving = False
def move(self):
if self.moving:
# get distance to taget
distance = self.current.distance_to(self.target)
#
if distance > self.speed:
self.current = self.current + (self.target - self.current).normalize() * self.speed
self.rect.center = self.current
else:
# put player in tagert place,
# and find new target on list with waypoints
self.current = self.target
self.rect.center = self.current
# set next end point if exists on list
self.target_index += 1
if self.target_index < len(self.waypoints):
self.target = pygame.math.Vector2(self.waypoints[self.target_index])
else:
if self.loop:
self.target_index = 0
else:
self.moving = False
def draw(self, surface):
surface.blit(self.image, self.rect)
# === MAIN === (lower_case names)
# --- init ---
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
screen_rect = screen.get_rect()
# --- objects ---
start = pygame.math.Vector2(screen_rect.centerx, screen_rect.bottom)
end = start
length = 150
waypoints = [(50, 50), (400, 150), (500, 50), (450, 350), (200, 200), (100, 350), (50, 50)]
player = Player(waypoints, True)
# --- mainloop ---
clock = pygame.time.Clock()
is_running = True
while is_running:
# --- events ---
for event in pygame.event.get():
# --- global events ---
if event.type == pygame.QUIT:
is_running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
is_running = False
# --- objects events ---
# empty
# --- updates ---
# empty
player.move()
# --- draws ---
screen.fill(BLACK)
for start, end in zip(waypoints, waypoints[1:]):
pygame.draw.line(screen, RED, start, end)
player.draw(screen)
pygame.display.update()
# --- FPS ---
clock.tick(25)
# --- the end ---
pygame.quit()
BTW: because player doesn't change direction when it moves from one point to another (and target doesn't change position) so it could calculate this value only once
(target - current).normalize() * speed
and recalculate it when it get next point as targe.
BTW: example how to calculate with math module in answer to
finding change in x and y given two points and length of vector
This question already has answers here:
Why is my PyGame application not running at all?
(2 answers)
Why do group lists in pygame have to have "update" functions, and not any other?
(1 answer)
Closed 2 years ago.
I am trying to create a game similar to "Bubble Trouble" in which the player detects eggs that are falling from the top of the screen. I have several problems with this.
The eggs will not appear on the screen no matter how much I attempt at drawing them and having them appear at some point on the y axis
I have no idea if the collision detection will work because
the program wont open and there is no error message.
Please help me figure out a solutions to this problem. I was so excited to work on this when I started but after days of trying I am being disheartened. Thank you in advance.
Code:
import pygame, random
import Tkinter
from pygame.locals import *
# CONSTANTS
WWD = 1280 # Window width
WHT = 720 # Window height
BLACK = (0,0,0) # Colors
WHITE = (255,255,255)
BACK = BLACK # Background Color
FORE = WHITE # Foreground Color
INT = 40 # Time interval for game and key repeat
BG = pygame.image.load("barn.png")
BG = pygame.transform.scale(BG, (1280, 720))
pygame.init()
pygame.key.set_repeat(INT,INT) # pygame.init disables keyboard repetition. This reenables it with a delay and rep interval
class Label:
def __init__(self,surf,cx,cy,fsize,strng,fcolor,bcolor):
self.screen = surf
self.fc = fcolor
self.bc = bcolor
self.font = pygame.font.SysFont(None,fsize)
self.cx = cx
self.cy = cy
self.str = strng
self.vis = False # tells if the label is visible
def draw(self):
self.text = self.font.render(self.str,True,self.fc,self.bc)
self.rect = self.text.get_rect()
self.rect.centerx = self.cx
self.rect.centery = self.cy
self.screen.blit(self.text,self.rect)
pygame.display.update([self.rect])
self.vis = True
def undraw(self):
self.text.fill(self.bc)
self.screen.blit(self.text,self.rect)
pygame.display.update([self.rect])
self.vis = False
def OpeningScreen(Scr):
Scr.blit(BG, (0, 0))
pygame.display.update()
L1 = Label(Display,WWD//2,WHT*3//8,WHT*3//50,"Use Arrow Keys to Begin",WHITE,BLACK) #Creating the menus
L1.draw()
L2 = Label(Display,WWD//2,WHT*4//8,WHT*3//50,"Hit Q to Quit Anytime",WHITE,BLACK) #Second menu option
L2.draw()
class Player:
def __init__(self,Scr,cx,cy,speed,bcolor):
self.screen = Scr
self.surf = pygame.image.load('player.png').convert_alpha()
self.surf = pygame.transform.scale(self.surf, (160, 200)).convert_alpha()
self.rect = self.surf.get_rect()
self.rect.centerx = cx
self.rect.y = 510
self.speed = 30
self.bc = bcolor
def draw(self):
self.screen.blit(self.surf,self.rect).convert_alpha()
pygame.display.update([self.rect])
def undraw(self):
surf = self.surf.copy()
surf.fill(self.bc)
self.screen.blit(surf,self.rect)
pygame.display.update([self.rect])
def move(self,mv):
self.undraw()
if mv == 'd' and self.rect.bottom < WHT:
self.rect.top += self.speed
if mv == 'u' and self.rect.top > 0:
self.rect.top -= self.speed
if mv == 'l' and self.rect.left > 0:
self.rect.left -= self.speed
if mv == 'r' and self.rect.right < WWD:
self.rect.right += self.speed
self.draw()
pygame.display.update()
def jump(self,top,left):
self.undraw()
self.rect.top = top
self.rect.left = left
self.draw()
pygame.display.update()
class EggDrop:
def __init__(self,Scr):
pygame.display.update()
pygame.mixer.music.load('background.mid')
pygame.mixer.music.play(-1,0.0)
self.Mplay = True
self.Player = Player(Scr,WWD//2,WHT//2,6,BLACK)
Scr.blit(BG, (0, 0))
self.Scr = Scr
def toggleMusic(self):
self.Mplay = not self.Mplay
if self.Mplay:
pygame.mixer.music.play(-1,0.0)
else:
pygame.mixer.music.stop()
def togglePlayer(self):
if self.Pvis:
self.Player.undraw()
else:
self.Player.draw()
self.Pvis = not self.Pvis
def hatchGif(self):
#files in order animated
files = ["pics\hatch1.gif", "pics\hatch2.gif", "pics\hatch2.gif", "pics\hatch3.gif", "pics\hatch4.gif", "pics\hatch5.gif", "pics\hatch6.gif", "pics\hatch7.gif", "pics\hatch8.gif", "pics\hatch9.gif", "pics\hatch10.gif", "pics\hatch11.gif", "pics\hatch12.gif", "pics\hatch13.gif"]
photos = [Tkinter.PhotoImage(file=x) for x in files]
label = Tkinter.Label()
label.photos = photos
label.counter = 0
def next_pic():
label['image'] = label.photos[label.counter%len(label.photos)]
label.after(25, next_pic) #25 = speed of animation
label.counter += 1
label.pack()
next_pic()
def splatGif(self):
files = ["pics\splat1.gif", "pics\splat2.gif", "pics\splat2.gif", "pics\splat3.gif", "pics\splat4.gif", "pics\splat5.gif", "pics\splat6.gif", "pics\splat7.gif", "pics\splat8.gif"]
photos = [Tkinter.PhotoImage(file=x) for x in files]
label = Tkinter.Label()
label.photos = photos
label.counter = 0
def next_pic():
label['image'] = label.photos[label.counter%len(label.photos)]
label.after(40, next_pic) #25 = speed of animation
label.counter += 1
label.pack()
next_pic()
def eggs(self):
while self.Player.draw():
self.eggsImage = pygame.image.load('hatch1.gif')
self.eggsImage = pygame.transform.scale(self.eggsImage, (30, 40))
self.screen.blit(self.eggsImage)
pygame.display.update([self.eggsImage])
self.eggsImage.centerx = cx
self.eggsImage.y = 300
self.speed = 30
def detectCollisions(x1,y1,w1,h1,x2,y2,w2,h2):
if (x2+w2>=x1>=x2 and y2+h2>=y1>=y2):
return True
elif (x2+w2>=x1+w1>=x2 and y2+h2>=y1>=y2):
return True
elif (x2+w2>=x1>=x2 and y2+h2>=y1+h1>=y2):
return True
elif (x2+w2>=x1+w1>=x2 and y2+h2>=y1+h1>=y2):
return True
else:
return False
class Sprite:
def __init__(self,x,y,width,height):
self.x=x
self.y=y
self.width=width
self.height=height
def render(self,collision):
if (collision==True):
hatchGif()
else:
pass
Sprite1=Player
Sprite2=eggs
moveX,moveY=0,0
gameLoop=True
while gameLoop:
STOP = False
while not STOP:
for event in pygame.event.get():
if event.type==pygame.QUIT:
gameLoop=False
STOP = True
if event.type==pygame.KEYDOWN:
if event.key==pygame.K_LEFT or event.key == ord('a'):
moveX = -4
if event.key==pygame.K_RIGHT or event.key == ord('d'):
moveX = 4
if event.key== K_SPACE:
detectCollisions()
if event.type==pygame.KEYUP:
if event.key == ord('q'):
STOP = True
if event.key == K_ESCAPE:
STOP = True
if event.key == ord('x'):
top = random.randint(0, WHT - self.Player.rect.height)
left = random.randint(0, WWD - self.Player.rect.width)
self.Player.jump(top,left)
if event.key == ord('m'):
self.toggleMusic()
pygame.mixer.music.stop()
Sprite1.x+=moveX
Sprite1.y+=moveY
collisions=detectCollisions(Sprite1.x,Sprite1.y,Sprite1.width,Sprite1.height,Sprite2.x,Sprite2.y,Sprite2.width,Sprite2.height)
Sprite1.render(collisions)
Sprite2.render(False)
pygame.display.flip()
Display = pygame.display.set_mode((WWD,WHT),0,0)
pygame.display.set_caption('Incubator 3000 V.1')
OpeningScreen(Display)
g = EggDrop(Display)
g.run()
pygame.quit()
I am building a game and I keep on running up against this error. I can't seem to fix it. I believe the problem is either in the function "main" at the bottom or in the classes "Level" and "Level01". If you find there is a way I can improve my code can you also tell me as I am just learning how to build games with OOP.
File "C:/Users/fabma/Documents/PythonGames/RPG/Scroller!.py", line 148, in main
currentLevel.drawer(display)
TypeError: drawer() missing 1 required positional argument: 'display1'
Here is my code:
import pygame
# Colours + Global constants
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
WIDTH = 800
HEIGHT = 600
SIZE = (WIDTH, HEIGHT)
# CLASSES
# Block is the common platform
class Block(pygame.sprite.Sprite):
def __init__(self, length, height, colour):
super().__init__()
# Making image
self.image = pygame.Surface([length, height])
self.image.fill(colour)
self.rect = self.image.get_rect()
# Setting Y coordinates
self.rect.y = HEIGHT * 0.95
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
# Is it touching the floor?
self.velocity = 0
self.standing = True
# Rendering image and creating some variables
self.height = 40
self.length = 40
self.sprite_x_change = 0
self.sprite_y_change = 0
self.image = pygame.Surface([self.height, self.length])
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.y = HEIGHT * 0.884
self.level = None
# Mobility: Left, right, up and stop
def move_right(self):
self.sprite_x_change = 15
def move_left(self):
self.sprite_x_change = -15
def move_up(self, platform):
# Seeing if we hit anything if so then we can jump!
self.rect.y -= 2
hit_list = pygame.sprite.spritecollide(self, platform, False)
if len(hit_list) > 0 or self.rect.bottom >= HEIGHT - Block.height:
self.change_y = -10
def stop(self):
self.sprite_x_change = 0
def updater(self):
self.gravity()
platforms_hit = pygame.sprite.spritecollide(self, self.level.platforms, False)
for blocks in platforms_hit:
self.sprite_y_change = 0
# Going down
if self.sprite_y_change > 0:
self.rect.bottom = blocks.rect.top
self.velocity = 0
self.standing = True
# Going up
if self.sprite_y_change < 0:
self.rect.top = blocks.rect.bottom
self.standing = False
if self.sprite_x_change > 0:
self.rect.right = blocks.rect.left
if self.sprite_x_change < 0:
self.rect.left = blocks.rect.right
if self.sprite_x_change == 0 and self.sprite_y_change == 0:
self.rect.y = HEIGHT * 0.884
if self.standing == False:
self.velocity += 1
self.rect.x += self.sprite_x_change
self.rect.y += self.sprite_y_change
def gravity(self):
self.sprite_y_change += 0.980665*self.velocity
class Level:
def __init__(self):
# Creating groups
self.sprites = pygame.sprite.Group()
self.all_things = pygame.sprite.Group()
self.platforms = pygame.sprite.Group()
def drawer(self, display1):
display1.fill(BLUE)
self.all_things.draw(display1)
class Level01(Level):
def __init__(self, player1):
# Initialise level1
Level.__init__(self)
# Level01 things
block = Block(WIDTH, HEIGHT * 0.05, RED)
Level.all_things = self.all_things
self.sprites.add(player1)
self.platforms.add(block)
self.all_things.add(player1, block)
def main():
# Init pygame
pygame.init()
# Set screen
display = pygame.display.set_mode(SIZE)
# Creating FPS thingy
clock = pygame.time.Clock()
# Making levels + Player
player = Player()
level_1 = Level01(player)
# Choosing level
levelList = []
levelList.append(Level01)
currentLevelNumber = 0
currentLevel = levelList[currentLevelNumber]
# Game loop
loop = True
while loop == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
player.move_right()
if event.key == pygame.K_LEFT:
player.move_left()
if event.key == pygame.K_UP:
player.move_up(currentLevel.platforms)
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT and player.sprite_x_change < 0:
player.stop()
if event.key == pygame.K_RIGHT and player.sprite_x_change > 0:
player.stop()
# Update things
currentLevel.all_things.update()
currentLevel.drawer(display)
# Refresh screen
clock.tick(30)
pygame.display.update()
pygame.quit()
if __name__ == "__main__":
main()
You need to create an instance of your level rather than just appending the class itself into your list:
levelList.append(Level01)
should be...
levelList.append(level_1)
As it stands, you're using the class object rather than an instance of it, which means that the display you're passing is getting put into the self argument (because the class object won't pass along an instance, because it's not one). Once you're calling it on an instance of the class, the self argument will be automatically passed and thus your display argument will get passed to the correct spot.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a game with jumping included. He can jump normally when the variable stand is True, when I hit this block, I set stand to True. I tested by typing :
if stand == True:
print("stand is true")
It printed out. Though he is unable to jump.
My code is:
import pygame, random, time, os, sys, tkinter
###################################################################################
# This is a small 10 level project of a minimalistic platformer.
# It isn't too special, but fun to make!
# It uses images instead of drawing rectangles in pygame
# I found it a bit quicker honestly.
# Copyright Hunter Kepley 2014
#
#
###################################################################################
pygame.init()
disw = 720
dish = 680
black = ( 0, 0, 0)
white = (255,255,255)
red = (255, 50, 50)
green = ( 50,255, 50)
blue = ( 50, 50,255)
flag = False
stand = False
gameDisplay = pygame.display.set_mode((disw,dish))
pygame.display.set_caption("Rec")
clock = pygame.time.Clock()
class player:
def __init__(self, x, y, image, w, h, xc, yc): # Initialization
self.x = x
self.y = y
self.image = image
self.w = w
self.h = h
self.xc = xc
self.yc = yc
def update(self): # Update class display
gameDisplay.blit(self.image, (self.x, self.y))
class level:
def __init__(self, spawnx, spawny, var, plcl, prev):
self.spawnx = spawnx
self.spawny = spawny
self.var = var
self.plcl = plcl
def spawn(self):
self.plcl.x = self.spawnx
self.plcl.y = self.spawny
def set(self):
self.var = True
self.prev = False
class block: # Class for blocks, namely collisions
def __init__(self, x, y, w, h, plcl, img, stand):
self.x = x
self.y = y
self.w = w
self.h = h
self.plcl = plcl
self.img = img
self.stand = stand
if plcl.x + plcl.w >= self.x and plcl.y + plcl.h >= self.y and plcl.x <= self.x + self.w and plcl.y <= self.y + self.h:
if plcl.x + plcl.w >= self.x and plcl.x <= self.x + self.w and plcl.y <= self.y + 20 and plcl.y + plcl.h >= self.y:
plcl.y = self.y - plcl.h
stand = True
def update(self):
gameDisplay.blit(self.img, (self.x, self.y))
player1 = player(10, 10, pygame.image.load("images/player.png"), 30, 40, 0 ,6) # Defining player1 as a player class
start = True
lone = False
ltwo = False
lthree = False
lfour = False
lfive = False
lsix = False
lseven = False
leight = False
lnine = False
lten = False
lives = 3
def gameloop():
global flag, stand, start, lone, ltwo, lthree, lfour, lfive, lsix, lseven, leight, lnine, lten, lives
gameExit = False
starttime = pygame.time.get_ticks()
while not gameExit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == pygame.KEYDOWN:
if flag == False and event.key == pygame.K_SPACE and stand == True: # For jumping
starttime = pygame.time.get_ticks()
player1.yc = -6
flag = True
stand = False
if event.key == pygame.K_d: # Right
player1.xc = 4
if event.key == pygame.K_a: # Left
player1.xc = -4
elif event.type == pygame.KEYUP:
if event.key == pygame.K_SPACE: # For jumping
player1.yc = 6
if event.key == pygame.K_d:
player1.xc = 0
if event.key == pygame.K_a:
player1.xc = 0
if flag == True and pygame.time.get_ticks() - starttime >= 300: # For jumping
player1.yc = 6
flag = False
gameDisplay.fill(white) # Fill
player1.update() # Update player display
player1.x += player1.xc # update player movements
player1.y += player1.yc
if player1.y >= dish - player1.h: # Bottom collisions
player1.y = dish - player1.h
stand = True
if lives > 0:
lives -= 1
elif lives <= 0: # Reset the game if you die
start = True
lone = False
ltwo = False
lthree = False
lfour = False
lfive = False
lsix = False
lseven = False
leight = False
lnine = False
lten = False
lives = 3
player1.x = 10
player1.y = 10
if player1.x <= 0: # Left wall collisions
player1.x = 0
if player1.x >= disw - player1.w: # Right wall collisions
player1.x = disw - player1.w
# Level one class
levelone = level(10, 200, lone, player1, start)
# Start Collisions
if player1.x >= disw - player1.w:
levelone.spawn()
levelone.set()
# Blocks in Start
block1start = block(5, dish - 50, 250, 50, player1, pygame.image.load("images/block1.png"), stand) # Here is the 1st block defined
block1start.update()
pygame.display.update()
clock.tick(60)
if __name__ == "__main__":
gameloop()
pygame.quit()
quit()
As you can see, stand is set to True when you touch the block, but he is unable to perform a jump.
Restatement:
Problem: Stand is True and flag is False but can't jump for some reason.
Tried: Not using a class, printing if stand is True, etc.
Need: An answer on how to fix it. I don't need criticism on my coding in general like most people do when I post, just how to fix it.
You are setting a local variable to True, in block.__init__:
stand = True
That variable won't be visible anywhere else. You cannot simply make that a global either, as you also use stand as an argument to the method.
You'll have to use:
global stand
in that method to make the name act as a global, but rename the argument to the method too:
def __init__(self, x, y, w, h, plcl, img, block_stand):
# ...
self.stand = block_stand