After the first goblin the second is not spawning randomly - python

my code is not working to randomize the goblins spawn point, basically what its doing is randomly spawning a single goblin but not spawning more then one goblin randomly, even though I've set up a while loop that should be accessed more then once. (note i am a very new programmer, i'm sorry if i'm asking a question that should be obvious). im sorry i really can't figure out how to put my code on properly, so the indents are all messed up.
here's the code
import pygame
import random
pygame.init()
win = pygame.display.set_mode((500,480))
pygame.display.set_caption("First Game")
walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'),
pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'),
pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]
walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'),
pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'),
pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]
bg = pygame.image.load('bg.jpg')
char = pygame.image.load('standing.png')
clock = pygame.time.Clock()
bulletSound = pygame.mixer.Sound('bullet.wav')
hitSound = pygame.mixer.Sound('hit.wav')
stage = 1
printStage = True
music = pygame.mixer.music.load('music.mp3')
pygame.mixer.music.play(-1)
goblinAlive = True
score = 0
class player(object):
def __init__(self,x,y,width,height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 5
self.isJump = False
self.left = False
self.right = False
self.walkCount = 0
self.jumpCount = 10
self.standing = True
self.hitbox = (self.x + 17, self.y + 11, 29, 52)
def draw(self, win):
if self.walkCount + 1 >= 27:
self.walkCount = 0
if not(self.standing):
if self.left:
win.blit(walkLeft[self.walkCount//3], (self.x,self.y))
self.walkCount += 1
elif self.right:
win.blit(walkRight[self.walkCount//3], (self.x,self.y))
self.walkCount +=1
else:
if self.right:
win.blit(walkRight[0], (self.x, self.y))
else:
win.blit(walkLeft[0], (self.x, self.y))
self.hitbox = (self.x + 17, self.y + 11, 29, 52)
#pygame.draw.rect(win, (255,0,0), self.hitbox,2)
def hit(self):
self.x = 60
self.y = 410
self.walkCount = 0
font1 = pygame.font.SysFont('comicsans', 100)
text = font1.render('-5', 1, (255,0,0))
win.blit(text, (250 - (text.get_width()/2),200))
pygame.display.update()
i = 0
while i < 200:
pygame.time.delay(10)
i += 1
for event in pygame.event.get():
if event.type == pygame.QUIT:
i = 201
pygame.quit()
class projectile(object):
def __init__(self,x,y,radius,color,facing):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.facing = facing
self.vel = 8 * facing
def draw(self,win):
pygame.draw.circle(win, self.color, (self.x,self.y), self.radius)
class enemy(object):
walkRight = [pygame.image.load('R1E.png'), pygame.image.load('R2E.png'),
pygame.image.load('R3E.png'), pygame.image.load('R4E.png'), pygame.image.load('R5E.png'),
pygame.image.load('R6E.png'), pygame.image.load('R7E.png'), pygame.image.load('R8E.png'),
pygame.image.load('R9E.png'), pygame.image.load('R10E.png'), pygame.image.load('R11E.png')]
walkLeft = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'),
pygame.image.load('L3E.png'), pygame.image.load('L4E.png'), pygame.image.load('L5E.png'),
pygame.image.load('L6E.png'), pygame.image.load('L7E.png'), pygame.image.load('L8E.png'),
pygame.image.load('L9E.png'), pygame.image.load('L10E.png'), pygame.image.load('L11E.png')]
def __init__(self, x, y, width, height, end):
self.x = x
self.y = y
self.width = width
self.height = height
self.end = end
self.path = [self.x, self.end]
self.walkCount = 0
self.vel = 3
self.hitbox = (self.x + 17, self.y + 2, 31, 57)
self.health = 10
self.visible = True
def draw(self,win):
self.move()
if self.visible:
if self.walkCount + 1 >= 33:
self.walkCount = 0
if self.vel > 0:
win.blit(self.walkRight[self.walkCount //3], (self.x, self.y))
self.walkCount += 1
else:
win.blit(self.walkLeft[self.walkCount //3], (self.x, self.y))
self.walkCount += 1
pygame.draw.rect(win, (255,0,0), (self.hitbox[0], self.hitbox[1] - 20, 50, 10))
pygame.draw.rect(win, (0,128,0), (self.hitbox[0], self.hitbox[1] - 20, 50 - (5 * (10 - self.health)), 10))
self.hitbox = (self.x + 17, self.y + 2, 31, 57)
#pygame.draw.rect(win, (255,0,0), self.hitbox,2)
def move(self):
if self.vel > 0:
if self.x + self.vel < self.path[1]:
self.x += self.vel
else:
self.vel = self.vel * -1
self.walkCount = 0
else:
if self.x - self.vel > self.path[0]:
self.x += self.vel
else:
self.vel = self.vel * -1
self.walkCount = 0
def hit(self):
if self.health > 0:
self.health -= 1
else:
self.visible = False
print('hit')
def redrawGameWindow():
win.blit(bg, (0,0))
text = font.render('You Are On Stage: ' + str(stage), 1, (0,0,0))
win.blit(text, (10, 10))
text = font.render('Score: ' + str(score), 1, (0,0,0))
win.blit(text, (370, 10))
man.draw(win)
goblin.draw(win)
for bullet in bullets:
bullet.draw(win)
pygame.display.update()
#mainloop
font = pygame.font.SysFont('comicsans', 30, True)
printStageFont = pygame.font.SysFont('comicsans', 20, True)
man = player(30, 410, 64,64)
goblin = enemy(random.randint(0, 200), 410, 64, 64, random.randint(201, 490))
shootLoop = 0
numOfGoblins = 1
bullets = []
run = True
while run:
clock.tick(27)
if man.y > 410:
man.y = 410
while numOfGoblins < stage:
goblin = enemy(random.randint(0, 200), 410, 64, 64, random.randint(201, 490))
numOfGoblins += 1
if goblin.visible:
if man.hitbox[1] < goblin.hitbox[1] + goblin.hitbox[3] and man.hitbox[1] + man.hitbox[3] > goblin.hitbox[1]:
if man.hitbox[0] + man.hitbox[2] > goblin.hitbox[0] and man.hitbox[0] < goblin.hitbox[0] + goblin.hitbox[2]:
man.hit()
score -= 5
vel = 5
if shootLoop > 0:
shootLoop += 1
if shootLoop > 15:
shootLoop = 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
for bullet in bullets:
if goblin.visible == True:
if bullet.y - bullet.radius < goblin.hitbox[1] + goblin.hitbox[3] and bullet.y + bullet.radius > goblin.hitbox[1]:
if bullet.x + bullet.radius > goblin.hitbox[0] and bullet.x - bullet.radius < goblin.hitbox[0] + goblin.hitbox[2]:
hitSound.play()
goblin.hit()
score += 1
bullets.pop(bullets.index(bullet))
if bullet.x < 500 and bullet.x > 0:
bullet.x += bullet.vel
else:
bullets.pop(bullets.index(bullet))
keys = pygame.key.get_pressed()
if keys[pygame.K_z] and shootLoop == 0:
bulletSound.play()
if man.left:
facing = -1
else:
facing = 1
if len(bullets) < 5:
bullets.append(projectile(round(man.x + man.width //2), round(man.y + man.height//2), 6, (0,0,0), facing))
shootLoop = 1
if keys[pygame.K_LEFT] and man.x > man.vel:
man.x -= man.vel
man.left = True
man.right = False
man.standing = False
elif keys[pygame.K_RIGHT]:
if man.x == 500 and goblin.visible == False:
man.x = 30
stage += 1
numOfGoblins = 0
if man.x > 500 - man.width - man.vel and goblin.visible == True:
vel = 0
else:
man.x += man.vel
man.right = True
man.left = False
man.standing = False
else:
man.standing = True
man.walkCount = 0
if not(man.isJump):
if keys[pygame.K_SPACE]:
man.isJump = True
man.right = False
man.left = False
man.walkCount = 0
else:
if man.jumpCount >= -10:
neg = 1
if man.jumpCount < 0:
neg = -1
man.y -= (man.jumpCount ** 2) * 0.5 * neg
man.jumpCount -= 1
else:
man.isJump = False
man.jumpCount = 10
redrawGameWindow()
pygame.quit()

The code is re-assigning a new enemy object into the goblin variable each time, this over-writes the existing value. So there is only ever one enemy:
while numOfGoblins < stage:
goblin = enemy(random.randint(0, 200), 410, 64, 64, random.randint(201, 490)) # <-- HERE
numOfGoblins += 1
Maybe use a list of enemy. A list - which is behaves much like an array in other programming languages is an ordered set of items. So whereas a plain variable stores only one object or value, a list can store many.
For example, we can create a list of 3 enemies:
goblins = [] # a new list, which is empty
goblins.append( enemy( 100, 410, 64, 64, 200 ) ) # Add 1st goblin to list
goblins.append( enemy( 150, 410, 64, 64, 220 ) ) # Add 2nd goblin
goblins.append( enemy( 200, 410, 64, 64, 240 ) ) # Add 3rd goblin
To access the items in the list goblins, the program uses a square-bracket notation, with the number of the item, e.g.: goblins[1]. There is an important point here though - the first item in the list is at [0]. Normally we think of the first item being item 1, but in most programming languages, this is number 0. So goblins[0] refers to the first enemy in the list.
Thus:
# Put the first goblin in the list onto the screen
goblins[0].draw( window )
But watch out for going past the end of the list:
goblins[3].draw( window ) # <-- ERROR! so-far only elements [0], [1], [2] have been added.
The really useful aspect of using lists is to be able to write simple loops that perform the same action with each item in the list:
# Paint 3 goblins
for i in range( 0, 3 ):
goblins[i].draw( window )
# Paint every goblin in the list (no matter how many):
for i in range( len( goblins ) ):
goblins[i].draw( window )
# Paint every goblin, looping without the numeric counter
# On each loop, the <gob> variable becomes equal to the next-item
for gob in goblins:
gob.draw( window )
Keeping all your enemy objects in a list makes drawing, and checking for collisions simple because the code can just loop over the list, performing the same action for each one.
When it's time to remove an item from the list (say the goblin is retired), the code can use the Python del() function, or perhaps pop().
So merging this idea with your existing code:
goblins = []
while ( len( goblins ) < stage ):
goblins.append( enemy(random.randint(0, 200), 410, 64, 64, random.randint(201, 490)) )
(which can also be done in a single line of code, but is less-readable)
And then when painting the goblins, iterate through the list, drawing each one:
for gobbo in goblins:
gobbo.draw( win )
Obviously collisions need to be handled in much the same way - checking each goblin in the goblins list. The PyGame sprite class already has code for this sort of operation.

Related

The text isn't coming up in pygame when it is supposed to and causing problems [duplicate]

This question already has answers here:
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
How do I detect collision in pygame?
(5 answers)
Closed 2 years ago.
So, I am making a simple game in which when the player collides with the enemy it's health is supposed to decrease with a graphic of a -5 popping up and then the game restarts. But when I start the programme the -5 pops up while it is not even supposed to and the rest of the screen stays black. And their is no error except a warning that has nothing to do with the messed up graphics. So, I am just going to paste the whole code as I think there is a problem with the player class, the scoring method and also with the blit method.
import pygame
pygame.init()
win = pygame.display.set_mode((500,480))
pygame.display.set_caption("First Game")
walkRight = [pygame.image.load('Game//R1.png'), pygame.image.load('Game//R2.png'), pygame.image.load('Game//R3.png'), pygame.image.load('Game//R4.png'), pygame.image.load('Game//R5.png'), pygame.image.load('Game//R6.png'), pygame.image.load('Game//R7.png'), pygame.image.load('Game//R8.png'), pygame.image.load('Game//R9.png')]
walkLeft = [pygame.image.load('Game//L1.png'), pygame.image.load('Game//L2.png'), pygame.image.load('Game//L3.png'), pygame.image.load('Game//L4.png'), pygame.image.load('Game//L5.png'), pygame.image.load('Game//L6.png'), pygame.image.load('Game//L7.png'), pygame.image.load('Game//L8.png'), pygame.image.load('Game//L9.png')]
bg = pygame.image.load('Game//bg.jpg')
char = pygame.image.load('Game//standing.png')
clock = pygame.time.Clock()
score = 0
class player(object):
def __init__(self,x,y,width,height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 5
self.isJump = False
self.left = False
self.right = False
self.walkCount = 0
self.jumpCount = 10
self.standing = True
self.hitbox = (self.x + 17, self.y + 11, 29, 52)
def draw(self, win):
if self.walkCount + 1 >= 27:
self.walkCount = 0
if not(self.standing):
if self.left:
win.blit(walkLeft[self.walkCount//3], (self.x,self.y))
self.walkCount += 1
elif self.right:
win.blit(walkRight[self.walkCount//3], (self.x,self.y))
self.walkCount +=1
else:
if self.right:
win.blit(walkRight[0], (self.x, self.y))
else:
win.blit(walkLeft[0], (self.x, self.y))
self.hitbox = (self.x + 17, self.y + 11, 29, 52)
#pygame.draw.rect(win, (255,0,0), self.hitbox,2)
def hit(self):
self.x = 60
self.y = 410
self.walkCount = 0
font1 = pygame.font.SysFont('comicsans', 100)
text = font1.render('-5', 1, (255,0,0))
win.blit(text, (250 - round(text.get_width()/2), 200))
pygame.display.update()
i = 0
while i < 300:
pygame.time.delay(10)
i += 1
for event in pygame.event.get():
if event.type == pygame.QUIT:
i = 301
pygame.quit()
class projectile(object):
def __init__(self,x,y,radius,color,facing):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.facing = facing
self.vel = 8 * facing
def draw(self,win):
pygame.draw.circle(win, self.color, (self.x,self.y), self.radius)
class enemy(object):
walkRight = [pygame.image.load('Game//R1E.png'), pygame.image.load('Game//R2E.png'), pygame.image.load('Game//R3E.png'), pygame.image.load('Game//R4E.png'), pygame.image.load('Game//R5E.png'), pygame.image.load('Game//R6E.png'), pygame.image.load('Game//R7E.png'), pygame.image.load('Game//R8E.png'), pygame.image.load('Game//R9E.png'), pygame.image.load('Game//R10E.png'), pygame.image.load('Game//R11E.png')]
walkLeft = [pygame.image.load('Game//L1E.png'), pygame.image.load('Game//L2E.png'), pygame.image.load('Game//L3E.png'), pygame.image.load('Game//L4E.png'), pygame.image.load('Game//L5E.png'), pygame.image.load('Game//L6E.png'), pygame.image.load('Game//L7E.png'), pygame.image.load('Game//L8E.png'), pygame.image.load('Game//L9E.png'), pygame.image.load('Game//L10E.png'), pygame.image.load('Game//L11E.png')]
def __init__(self, x, y, width, height, end):
self.x = x
self.y = y
self.width = width
self.height = height
self.end = end
self.path = [self.x, self.end]
self.walkCount = 0
self.vel = 3
self.hitbox = (self.x + 17, self.y + 2, 31, 57)
self.health = 10
self.visible = True
def draw(self,win):
self.move()
if self.visible:
if self.walkCount + 1 >= 33:
self.walkCount = 0
if self.vel > 0:
win.blit(self.walkRight[self.walkCount //3], (self.x, self.y))
self.walkCount += 1
else:
win.blit(self.walkLeft[self.walkCount //3], (self.x, self.y))
self.walkCount += 1
pygame.draw.rect(win, (255,0,0), (self.hitbox[0], self.hitbox[1] - 20, 50, 10))
pygame.draw.rect(win, (0,128,0), (self.hitbox[0], self.hitbox[1] - 20, 50 - (5 * (10 - self.health)), 10))
self.hitbox = (self.x + 17, self.y + 2, 31, 57)
#pygame.draw.rect(win, (255,0,0), self.hitbox,2)
def move(self):
if self.vel > 0:
if self.x + self.vel < self.path[1]:
self.x += self.vel
else:
self.vel = self.vel * -1
self.walkCount = 0
else:
if self.x - self.vel > self.path[0]:
self.x += self.vel
else:
self.vel = self.vel * -1
self.walkCount = 0
def hit(self):
if self.health > 0:
self.health -= 1
else:
self.visible = False
print('hit')
def redrawGameWindow():
win.blit(bg, (0,0))
text = font.render('Score: ' + str(score), 1, (0,0,0))
win.blit(text, (390, 10))
man.draw(win)
goblin.draw(win)
for bullet in bullets:
bullet.draw(win)
pygame.display.update()
#mainloop
font = pygame.font.SysFont('comicsans', 30, True)
man = player(200, 410, 64,64)
goblin = enemy(100, 410, 64, 64, 450)
shootLoop = 0
bullets = []
run = True
while run:
clock.tick(27)
if man.hitbox[1] < goblin.hitbox[1] + goblin.hitbox[3] and man.hitbox [1] + man.hitbox[3] > goblin.hitbox[1]:
if man.hitbox[0] + man.hitbox[2] > goblin.hitbox[0] and man.hitbox[0] < goblin.hitbox[0] + goblin.hitbox[0]:
man.hit()
score += 5
if shootLoop > 0:
shootLoop += 1
if shootLoop > 3:
shootLoop = 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
for bullet in bullets:
if bullet.y - bullet.radius < goblin.hitbox[1] + goblin.hitbox[3] and bullet.y + bullet.radius > goblin.hitbox[1]:
if bullet.x + bullet.radius > goblin.hitbox[0] and bullet.x - bullet.radius < goblin.hitbox[0] + goblin.hitbox[2]:
goblin.hit()
score += 1
bullets.pop(bullets.index(bullet))
if bullet.x < 500 and bullet.x > 0:
bullet.x += bullet.vel
else:
bullets.pop(bullets.index(bullet))
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE] and shootLoop == 0:
if man.left:
facing = -1
else:
facing = 1
if len(bullets) < 5:
bullets.append(projectile(round(man.x + man.width //2), round(man.y + man.height//2), 6, (0,0,0), facing))
shootLoop = 1
if keys[pygame.K_LEFT] and man.x > man.vel:
man.x -= man.vel
man.left = True
man.right = False
man.standing = False
elif keys[pygame.K_RIGHT] and man.x < 500 - man.width - man.vel:
man.x += man.vel
man.right = True
man.left = False
man.standing = False
else:
man.standing = True
man.walkCount = 0
if not(man.isJump):
if keys[pygame.K_UP]:
man.isJump = True
man.right = False
man.left = False
man.walkCount = 0
else:
if man.jumpCount >= -10:
neg = 1
if man.jumpCount < 0:
neg = -1
man.y -= (man.jumpCount ** 2) * 0.5 * neg
man.jumpCount -= 1
else:
man.isJump = False
man.jumpCount = 10
redrawGameWindow()
pygame.quit()
And so sorry for the inconvenience with the previous question, I hope this one clears out everything. And if it doesn't please let me know.
Without images it's hard to run that locally and observe what exactly happens, but at this point it seems that hit condition, the whole
if man.hitbox[1] < goblin.hitbox[1] + goblin.hitbox[3] and man.hitbox[1] + \
man.hitbox[3] > goblin.hitbox[1]:
if man.hitbox[0] + man.hitbox[2] > goblin.hitbox[0] and man.hitbox[0] < \
goblin.hitbox[0] + goblin.hitbox[0]:
is true at the very beginning. This means that as only main loop starts, it goes to man.hit(). Please check your initial settings for both items.
By the way, consider to make it somewhat more readable with changes like
if (
man.hitbox[1] < goblin.hitbox[1] + goblin.hitbox[3] and
man.hitbox[1] + man.hitbox[3] > goblin.hitbox[1] and
man.hitbox[0] + man.hitbox[2] > goblin.hitbox[0] and
man.hitbox[0] < goblin.hitbox[0] + goblin.hitbox[0]
):
...
Also you could think about moving that condition into some method called collide (form example), which could calculate that internally.

IndexError: pop from empty list in pygame [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Hi guy i have a problem with my game, i receive this error when u run it, "line 283, in
bullets.pop(0)", "IndexError: pop from empty list", i think it is because the list of bullets is empty and it cannot pop them, but i dont know how to fix it.
If you can help me i would appreciate it very much.
Here is the code, thanks.
import pygame
import math
import random
pygame.init()
win = pygame.display.set_mode((800, 400))
pygame.display.set_caption("Pandemic")
clock = pygame.time.Clock()
score = 0
walkup = [pygame.image.load("Soldier-1up.png"), pygame.image.load("Soldier-2up.png"), pygame.image.load("Soldier-3up.png")]
walkdown = [pygame.image.load("Soldier-1down.png"), pygame.image.load("Soldier-2down.png"), pygame.image.load("Soldier-3down.png")]
walkright = [pygame.image.load("Soldier-1right.png"), pygame.image.load("Soldier-2right.png"), pygame.image.load("Soldier-3right.png")]
walkleft = [pygame.image.load("Soldier-1left.png"), pygame.image.load("Soldier-2left.png"), pygame.image.load("Soldier-3left.png")]
bg = pygame.image.load("map.png")
ch = pygame.image.load("Soldier-1up.png")
bulletimg = pygame.image.load("bullet.png")
walkvirus1 = [pygame.image.load("virus1.png"), pygame.image.load("virus2.png"), pygame.image.load("virus3.png")]
walkvirus2 = [pygame.image.load("1virus1.png"), pygame.image.load("1virus2.png"), pygame.image.load("1virus3.png")]
background1 = pygame.image.load("menu.png")
class player(object):
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 5
self.walkcount = 0
self.right = False
self.left = False
self.up = False
self.down = False
self.standing = True
self.hitbox = (self.x, self.y, self.width, self.height)
self.life = 3
def draw(self, win):
if self.walkcount + 1 >= 60:
self.walkcount = 0
if not (self.standing):
if self.left:
win.blit(walkleft[self.walkcount // 20], (self.x, self.y))
self.walkcount += 1
elif self.right:
win.blit(walkright[self.walkcount // 20], (self.x, self.y))
self.walkcount += 1
elif self.up:
win.blit(walkup[self.walkcount // 20], (self.x, self.y))
self.walkcount += 1
elif self.down:
win.blit(walkdown[self.walkcount // 20], (self.x, self.y))
self.walkcount += 1
else:
if self.up:
win.blit(walkup[0], (self.x, self.y))
elif self.down:
win.blit(walkdown[0], (self.x, self.y))
elif self.right:
win.blit(walkright[0], (self.x, self.y))
elif self.left:
win.blit(walkleft[0], (self.x, self.y))
self.hitbox = (self.x, self.y, self.width, self.height)
#pygame.draw.rect(win, (255, 0, 0), self.hitbox, 2)
def hit(self):
self.x = 0
self.y = 0
self.life -= 1
self.walkcount = 0
font1 = pygame.font.SysFont("comicsans", 100)
text = font1.render("-1 out of 3 lifes.", 1, (255,0,0))
win.blit(text, (400 - (text.get_width()/2),150))
pygame.display.update()
pygame.time.delay(1000)
if self.life == 0:
pygame.quit()
class Bullet(object):
def __init__(self, x, y, radius, color, vertfacing, hortfacing):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.speed = 8
self.vertfacing = vertfacing
self.hortfacing = hortfacing
def draw(self, screen):
pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius)
def move(self):
if self.hortfacing == -1:
self.x -= self.speed
elif self.hortfacing == 1:
self.x += self.speed
elif self.vertfacing == 1:
self.y += self.speed
elif self.vertfacing == -1:
self.y -= self.speed
class enemy(object):
def __init__(self, x, y, width, height, end):
self.x = x
self.y = y
self.width = width
self.height = height
self.end = end
self.path = [self.x, self.end]
self.walkcount = 0
self.vel = 2
self.life = 3
self.hitbox = (self.x, self.y, self.width, self.height)
self.health = 15
self.visible = True
def draw(self, win):
self.move()
if self.visible:
if self.walkcount + 1 >= 60:
self.walkcount = 0
if self.vel > 0:
win.blit(walkvirus1[self.walkcount // 20], (self.x, self.y))
self.walkcount += 1
else:
win.blit(walkvirus1[self.walkcount // 20], (self.x, self.y))
self.walkcount += 1
pygame.draw.rect(win, (250, 0, 0), (self.hitbox[0], self.hitbox[1] - 20, 65, 10))
pygame.draw.rect(win, (0, 250, 0), (self.hitbox[0], self.hitbox[1] - 20, 65 - ((65/15) * (15 - self.health)), 10))
self.hitbox = (self.x, self.y, self.width, self.height)
#pygame.draw.rect(win, (255, 0, 0), self.hitbox, 2)
def move(self):
dx, dy = man.x - self.x, man.y - self.y
dist = math.hypot(dx, dy)
dx, dy = dx / dist, dy / dist
self.x += dx * self.vel
self.y += dy * self.vel
def hit(self):
self.walkcount = 0
if self.health > 0:
self.health -= 1
elif self.life > 0:
self.x = random.randint(400, 600)
self.y = random.randint(800, 1000)
self.health = 15
self.life -= 1
else:
self.visible = False
print("hit")
class enemy1(object):
def __init__(self, x, y, width, height, end):
self.x = x
self.y = y
self.width = width
self.height = height
self.end = end
self.path = [self.x, self.end]
self.walkcount = 0
self.vel = 2
self.hitbox = (self.x, self.y, self.width, self.height)
self.health = 30
self. life = 3
self.visible = True
def draw(self, win):
self.move()
if self.visible:
if self.walkcount + 1 >= 60:
self.walkcount = 0
if self.vel > 0:
win.blit(walkvirus2[self.walkcount // 20], (self.x, self.y))
self.walkcount += 1
else:
win.blit(walkvirus2[self.walkcount // 20], (self.x, self.y))
self.walkcount += 1
pygame.draw.rect(win, (250, 0, 0), (self.hitbox[0], self.hitbox[1] - 20, 65, 10))
pygame.draw.rect(win, (0, 250, 0), (self.hitbox[0], self.hitbox[1] - 20, 65 - ((65/30) * (30 - self.health)), 10))
self.hitbox = (self.x, self.y, self.width, self.height)
#pygame.draw.rect(win, (255, 0, 0), self.hitbox, 2)
def move(self):
dx, dy = man.x - self.x, man.y - self.y
dist = math.hypot(dx, dy)
dx, dy = dx / dist, dy / dist
self.x += dx * self.vel
self.y += dy * self.vel
def hit(self):
self.walkcount = 0
if self.health > 0:
self.health -= 1
elif self.life > 0:
self.x = random.randint(400, 600)
self.y = random.randint(800, 1000)
self.health = 30
self.life -= 1
else:
self.visible = False
print("hit1")
def RedrawGame():
win.blit(bg, (0, 0))
text = font.render("score: " + str(score), 1, (0,0,0))
win.blit(text, (380, 10))
man.draw(win)
virus1.draw(win)
virus2.draw(win)
for bullet in bullets:
bullet.draw(win)
pygame.display.update()
#Loop
font = pygame.font.SysFont("comicsans",30,True)
man = player(400, 100, 64, 64)
virus1 = enemy(40, 110, 64, 64, 450)
virus2 = enemy1(40, 10, 64, 64, 450)
shoot = 0
bullets = []
run = True
menu = True
while run:
while menu:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
menu = False
win.fill((0, 0, 0))
clock.tick(60)
win.blit(background1, (0, 0))
pygame.display.update()
clock.tick(60)
if virus1.visible == True:
if man.hitbox[1] < virus1.hitbox[1] + virus1.hitbox[3] and man.hitbox[1] + man.hitbox[3] > virus1.hitbox[1]:
if man.hitbox[0] + man.hitbox[2] > virus1.hitbox[0] and man.hitbox[0] < virus1.hitbox[0] + virus1.hitbox[2]:
man.hit()
if virus2.visible == True:
if man.hitbox[1] < virus2.hitbox[1] + virus2.hitbox[3] and man.hitbox[1] + man.hitbox[3] > virus2.hitbox[1]:
if man.hitbox[0] + man.hitbox[2] > virus2.hitbox[0] and man.hitbox[0] < virus2.hitbox[0] + virus2.hitbox[2]:
man.hit()
if shoot > 0:
shoot += 1
if shoot > 3:
shoot = 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
for bullet in bullets:
if virus1.visible == True:
if bullet.y - bullet.radius < virus1.hitbox[1] + virus1.hitbox[3] and virus1.y + bullet.radius > virus1.hitbox[1]:
if bullet.x + bullet.radius > virus1.hitbox[0] and bullet.x - bullet.radius < virus1.hitbox[0] + \
virus1.hitbox[2]:
virus1.hit()
score += 1
bullets.pop(0)
if virus2.visible == True:
if bullet.y - bullet.radius < virus2.hitbox[1] + virus2.hitbox[3] and virus2.y + bullet.radius > virus2.hitbox[1]:
if bullet.x + bullet.radius > virus2.hitbox[0] and bullet.x - bullet.radius < virus2.hitbox[0] + \
virus2.hitbox[2]:
virus2.hit()
score += 1
bullets.pop(0)
if bullet.x < 800 and bullet.x > 0 and bullet.y < 400 and bullet.y > 0:
bullet.move()
else:
bullets.remove(bullet)
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE] and shoot == 0:
hortfacing, vertfacing = 0, 0
if man.left:
hortfacing = -1
elif man.right:
hortfacing = 1
elif man.up:
vertfacing = -1
elif man.down:
vertfacing = 1
if len(bullets) < 5:
bullet = Bullet(round(man.x + man.width // 2),
round(man.y + man.height // 2), 6, (255, 165, 0),
vertfacing, hortfacing)
bullets.append(bullet)
shoot = 1
if keys[pygame.K_a] and man.x >= man.vel:
man.x -= man.vel
man.right = False
man.left = True
man.up = False
man.down = False
man.standing = False
elif keys[pygame.K_d] and man.x < 800 - man.width:
man.x += man.vel
man.right = True
man.left = False
man.up = False
man.down = False
man.standing = False
elif keys[pygame.K_s] and man.y < 400 - man.height:
man.y += man.vel
man.right = False
man.left = False
man.up = False
man.down = True
man.standing = False
elif keys[pygame.K_w] and man.y >= man.vel:
man.y -= man.vel
man.right = False
man.left = False
man.up = True
man.down = False
man.standing = False
else:
man.standing = True
man.walkcount = 0
RedrawGame()
pygame.quit()
Add an if statement so the program will only execute the for loop when there are bullets in the list:
if bullets:
for bullet in bullets:
if virus1.visible == True:
if bullet.y - bullet.radius < virus1.hitbox[1] + virus1.hitbox[3] and virus1.y + bullet.radius > virus1.hitbox[1]:
if bullet.x + bullet.radius > virus1.hitbox[0] and bullet.x - bullet.radius < virus1.hitbox[0] + \
virus1.hitbox[2]:
virus1.hit()
score += 1
bullets.pop(0)

Problems with working shield in pygame platformer

Been messing around with Pygame for a while now and I wanted to make a 2d game where the player has the access to a shield which will only block enemy bullets if they are the same colour as the shield itself. I've been stuck on this problem a good few weeks now and was hoping anyone on here would be able to help me if possible. This is my first post on this website so I'm sorry if it's not the best.
This is a shortened down version of the code located below ….
import pygame
import random
pygame.init()
win = pygame.display.set_mode((600, 600))
pygame.display.set_caption("First Game")
walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'),
pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'),
pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]
walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'),
pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'),
pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]
walkRight2 = [pygame.image.load('R1E.png'), pygame.image.load('R2E.png'), pygame.image.load('R3E.png'),
pygame.image.load('R4E.png'), pygame.image.load('R5E.png'), pygame.image.load('R6E.png'),
pygame.image.load('R6E.png'), pygame.image.load('R5E.png'), pygame.image.load('R4E.png')]
walkLeft2 = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'),
pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'),
pygame.image.load('L6E.png'), pygame.image.load('L5E.png'), pygame.image.load('L4E.png')]
bg = pygame.image.load('Bg_1.png').convert()
clock = pygame.time.Clock()
class player(object):
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 5
self.isjump = False
self.jumpcount = 10
self.left = False
self.right = False
self.walkcount = 0
self.standing = True
self.hitbox = (self.x + 20, self.y + 15, self.width - 40, self.height - 20)
self.right_shield = (self.x + 15, self.y, self.width - 35, self.height)
self.left_shield = (self.x + 17, self.y, self.width - 35, self.height)
self.lifes = 35
def draw(self, win):
if self.walkcount + 1 >= 27:
self.walkcount = 0
if not (self.standing):
if self.left == True:
win.blit(walkLeft[self.walkcount // 3], (self.x, self.y))
self.walkcount += 1
elif self.right == True:
win.blit(walkRight[self.walkcount // 3], (self.x, self.y))
self.walkcount += 1
else:
if self.right == True:
win.blit(walkRight[0], (self.x, self.y))
else:
win.blit(walkLeft[0], (self.x, self.y))
self.hitbox = (self.x + 20, self.y + 15, self.width - 40, self.height - 20)
self.right_shield = (self.x + 15, self.y, self.width - 35, self.height)
self.left_shield = (self.x + 17, self.y, self.width - 35, self.height)
def hit(self, win):
global run
global bad_guys_kiled
if self.lifes > 0:
self.lifes -= 1
if self.lifes % 2 == 0:
pass
if self.lifes <= 0:
run = False
print("You have ran out of lifes!")
print("Thank you for playing!")
class enemy(object):
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 5
self.boss_vel = 2
self.left = True
self.right = False
self.walkcount = 0
self.isjump = False
self.jumpcount = 10
self.standing = True
self.hitbox = (self.x + 20, self.y + 10, self.width - 40, self.height - 20)
self.shootloop1 = 0
self.bullets2 = []
self.bullets3 = []
self.lifes = 2
self.half_health = False
def draw(self, win):
global half_health
global bad_guys_kiled
if bad_guys_kiled <= 25:
if self.walkcount + 1 >= 27:
self.walkcount = 0
if not (self.standing):
if self.left == True:
win.blit(walkLeft2[self.walkcount // 3], (self.x, self.y))
self.walkcount += 1
elif self.right == True:
win.blit(walkRight2[self.walkcount // 3], (self.x, self.y))
self.walkcount += 1
else:
if self.right == True:
win.blit(walkRight2[0], (self.x, self.y))
else:
win.blit(walkRight2[0], (self.x, self.y))
self.hitbox = (self.x + 20, self.y + 10, self.width - 40, self.height - 20)
enemy_health = (self.x + 25, self.y + 5, self.width - 40, self.height - 70)
pygame.draw.rect(win, (0, 255, 0), enemy_health)
if self.half_health == True:
pygame.draw.rect(win, (255, 0, 0), (self.x + 50, self.y + 5, self.width - 75, self.height - 70))
def draw2(self, win):
global half_health
global bad_guys_kiled
if self.walkcount + 1 >= 27:
self.walkcount = 0
if not (self.standing):
if self.left == True:
win.blit(walkLeft2[self.walkcount // 3], (self.x, self.y))
self.walkcount += 1
elif self.right == True:
win.blit(walkRight2[self.walkcount // 3], (self.x, self.y))
self.walkcount += 1
else:
if self.right == True:
win.blit(walkRight2[0], (self.x, self.y))
else:
win.blit(walkRight2[0], (self.x, self.y))
self.hitbox = (self.x + 20, self.y + 10, self.width - 40, self.height - 20)
enemy_health = (self.x + 25, self.y + 5, self.width - 40, self.height - 70)
pygame.draw.rect(win, (0, 255, 0), enemy_health)
if self.half_health == True:
pygame.draw.rect(win, (255, 0, 0), (self.x + 50, self.y + 5, self.width - 75, self.height - 70))
def walk(self, win):
global shield
global drop_spot
global drop
global shield_health
global bad_guys_kiled
global temp_num
global temp_number
global colours
global shield_colour
global shield_number
global bullet_colour
global test_number
bullet_colour = random.choice(colours)
if bullet_colour == "blue":
colour_number = (0, 0, 255)
test_number = 0
else:
colour_number = (255, 0, 0)
test_number = 1
if temp_num == False:
temp_number = random.randint(4, 34)
temp_num = True
if self.shootloop1 > 0:
self.shootloop1 += 1
if self.shootloop1 > int(temp_number):
self.shootloop1 = 0
if bad_guys_kiled <= 25 and not (main_menu):
for bullet in self.bullets2:
if man.left:
if int(shield_number) == int(test_number):
if bullet.y - bullet.radius < man.right_shield[1] + man.right_shield[3] and bullet.y + bullet.radius > man.right_shield[1]:
if bullet.x + bullet.radius > man.right_shield[0] and bullet.x - bullet.radius < man.right_shield[0] + man.right_shield[2]:
try:
self.bullets2.pop(self.bullets2.index(bullet))
except ValueError:
pass
elif man.right:
if int(shield_number) == int(test_number):
if bullet.y - bullet.radius < man.left_shield[1] + man.left_shield[3] and bullet.y + bullet.radius > man.left_shield[1]:
if bullet.x + bullet.radius > man.left_shield[0] and bullet.x - bullet.radius < man.left_shield[0] + man.left_shield[2]:
try:
self.bullets2.pop(self.bullets2.index(bullet))
except ValueError:
pass
elif int(shield_number) != int(test_number):
if bullet.y - bullet.radius < man.hitbox[1] + man.hitbox[3] and bullet.y + bullet.radius > man.hitbox[1]:
if bullet.x + bullet.radius > man.hitbox[0] and bullet.x - bullet.radius < man.hitbox[0] + man.hitbox[2]:
man.hit(win)
try:
self.bullets2.pop(self.bullets2.index(bullet))
except ValueError:
pass
if bullet.x < 800 and bullet.x > -50:
bullet.x += bullet.vel
else:
try:
self.bullets2.pop(self.bullets2.index(bullet))
except ValueError:
pass
if self.left:
facing = -1
elif self.right:
facing = 1
if len(self.bullets2) < 7 and self.shootloop1 == 0:
self.bullets2.append(projectile(round(self.x + self.width // 2), round(self.y + self.height // 2), 6, (colour_number),facing))
self.shootloop1 = 1
if self.x != -50:
self.x -= self.vel
self.right = False
self.left = True
self.standing = False
else:
for x in range(1, 200):
if self.x >= 700:
self.x = 650
self.half_health = False
self.x += self.vel
self.right = False
self.left = True
self.standing = False
else:
for bullet in self.bullets2:
try:
self.bullets2.pop(self.bullets2.index(bullet))
except ValueError:
pass
def hit(self, win):
global bad_guys_kiled
global drop
global drop_spot
global drop_count
global min
global max
global score
Hit_noise.play()
if self.lifes > 0:
self.lifes -= 1
self.half_health = True
if self.lifes <= 0:
random_number = random.randint(min, max)
if bad_guys_kiled <= 25:
if random_number == 1:
if drop_count != 1:
drop = True
drop_count += 1
drop_spot = [self.x + 20]
drop_spot += [self.y + 10]
drop_spot += [self.width - 40]
drop_spot += [self.height - 40]
else:
try:
max -= 1
except ValueError:
max = 20
if bad_guys_kiled >= 25:
drop_spot = []
self.half_health = False
self.x = self.x + 700
self.lifes = 2
bad_guys_kiled += 1
score += 1
class projectile(object):
def __init__(self, x, y, radius, colour, facing):
self.x = x
self.y = y
self.radius = radius
self.colour = colour
self.facing = facing
self.vel = 8 * facing
def draw(self, win):
pygame.draw.circle(win, self.colour, (self.x, self.y), self.radius)
def redraw_game_window():
global drop_spot
global drop
global bad_guys_kiled
global jump_block
global main_menu
global run
global count
global score
global shield
global man_movement_block
global shield_colour
global bullet_colour
global test_number
global shield_number
win.blit(bg, (0, 0))
man.draw(win)
print("man = ",shield_number)
print("bullet =",test_number)
text_score = font.render("Score:" + str(score), 1, (0, 0, 0))
text_shield = font.render("Shield Colour:" + "temp", 1, (0, 0, 0))
text_player_health = font.render("Player Health:" + str(man.lifes), 1, (0, 0, 0))
win.blit(text_score, (450, 10))
win.blit(text_shield, (225, 10))
win.blit(text_player_health, (20, 10))
if bad_guys_kiled <= 25:
if drop == True:
try:
pygame.draw.rect(win, (0, 0, 255), (drop_spot[0], drop_spot[1], drop_spot[2], drop_spot[3]))
except IndexError:
pass
if man.left == True and shield_colour == "blue":
pygame.draw.rect(win, (0, 0, 255), (man.x + 17, man.y, man.width - 35, man.height), 2)
elif not(main_menu) and shield_colour == "blue":
pygame.draw.rect(win, (0, 0, 255), (man.x + 15, man.y, man.width - 35, man.height), 2)
if man.right == True and shield_colour == "red":
pygame.draw.rect(win, (255, 0, 0), (man.x + 17, man.y, man.width - 35, man.height), 2)
elif not(main_menu) and shield_colour == "red":
pygame.draw.rect(win, (255, 0, 0), (man.x + 15, man.y, man.width - 35, man.height), 2)
if bad_guys_kiled <= 25 :
bad_guy1.draw(win)
bad_guy2.draw(win)
bad_guy3.draw(win)
for bullet in bullets:
bullet.draw(win)
for bullet in bad_guy1.bullets2:
bullet.draw(win)
for bullet in bad_guy2.bullets2:
bullet.draw(win)
for bullet in bad_guy3.bullets2:
bullet.draw(win)
pygame.display.update()
def game_credits():
pygame.draw.rect(win, (40, 26, 13), (0, 0, 650, 650))
text_help = font.render("CONTROLS", 1, (0, 255, 0))
text_help1 = font.render("UP ARROW = JUMP", 1, (255, 255, 255))
text_help2 = font.render("LEFT ARROW = LEFT", 1, (255, 255, 255))
text_help3 = font.render("RIGHT ARROW = RIGHT", 1, (255, 255, 255))
text_help4 = font.render("ZERO ON NUMPAD = FIRE", 1, (255, 255, 255))
text_help5 = font.render("P = PAUSE", 1, (255, 255, 255))
text_help6 = font.render("O = UNPAUSE ", 1, (255, 255, 255))
text_help7 = font.render("(PRESSING P WILL NOT ", 1, (255, 255, 255))
text_help8 = font.render("UNPAUSE THE GAME !)", 1, (255, 255, 255))
text_help9 = font.render("B = SHIELD", 1, (255, 255, 255))
win.blit(text_help, (22, 50))
win.blit(text_help1, (22, 100))
win.blit(text_help2, (22, 150))
win.blit(text_help3, (22, 200))
win.blit(text_help4, (22, 250))
win.blit(text_help5, (22, 300))
win.blit(text_help6, (22, 350))
win.blit(text_help7, (22, 400))
win.blit(text_help8, (22, 450))
win.blit(text_help9, (22, 500))
# Main Loop #
Air_raid = pygame.mixer.Sound("Air raid.wav")
Godzilla_roar = pygame.mixer.Sound("Godzilla roar.wav")
Victory_noise = pygame.mixer.Sound("Victory noise.wav")
Gun_shot = pygame.mixer.Sound("Gun shot.wav")
Hit_noise = pygame.mixer.Sound("Hit noise.wav")
man = player(300, 450, 64, 64)
bad_guy1 = enemy(0, 450, 64, 64)
bad_guy2 = enemy(250, 450, 64, 64)
bad_guy3 = enemy(500, 450, 64, 64)
count = 0
bullets = []
shootloop = 0
bad_guys_kiled = 0
temp_num = False
temp_number = 0
drop = False
drop_spot = []
drop_count = 0
min = 1
max = 20
main_menu = False
main_spawn = False
score = 0
man_movement_block = False
shield_count = 0
colours = ["blue", "red"]
shield_colour = "blue"
bullet_colour = None
shield_number = 0
test_number = 0
font = pygame.font.SysFont("Calibri Light", 25, True)
run = True
while run == True:
temp_number = random.randint(4, 34)
if man.y >= 500:
man.y = 450
clock.tick(27)
shield = True
if shootloop > 0:
shootloop += 1
if shootloop > 5:
shootloop = 0
if shield_count > 0:
shield_count += 1
if shield_count > 5:
shield_count = 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
for bullet in bullets:
if bad_guys_kiled <= 25:
if bullet.y - bullet.radius < bad_guy1.hitbox[1] + bad_guy1.hitbox[3] and bullet.y + bullet.radius > bad_guy1.hitbox[1]:
if bullet.x + bullet.radius > bad_guy1.hitbox[0] and bullet.x - bullet.radius < bad_guy1.hitbox[0] + bad_guy1.hitbox[2]:
bad_guy1.hit(win)
bullets.pop(bullets.index(bullet))
if bullet.y - bullet.radius < bad_guy2.hitbox[1] + bad_guy2.hitbox[3] and bullet.y + bullet.radius > bad_guy2.hitbox[1]:
if bullet.x + bullet.radius > bad_guy2.hitbox[0] and bullet.x - bullet.radius < bad_guy2.hitbox[0] + bad_guy2.hitbox[2]:
bad_guy2.hit(win)
try:
bullets.pop(bullets.index(bullet))
except ValueError:
pass
if bullet.y - bullet.radius < bad_guy3.hitbox[1] + bad_guy3.hitbox[3] and bullet.y + bullet.radius > bad_guy3.hitbox[1]:
if bullet.x + bullet.radius > bad_guy3.hitbox[0] and bullet.x - bullet.radius < bad_guy3.hitbox[0] + bad_guy3.hitbox[2]:
bad_guy3.hit(win)
try:
bullets.pop(bullets.index(bullet))
except ValueError:
pass
try:
if man.hitbox[1] - (man.hitbox[3] / 2) < drop_spot[1] + (drop_spot[3] / 2) and man.hitbox[1] + (man.hitbox[3] / 2) > drop_spot[1]:
if man.hitbox[0] + (man.hitbox[3] / 2) > drop_spot[0] and man.hitbox[0] - (man.hitbox[3] / 2) < drop_spot[0] + drop_spot[2]:
Gun_shot.stop()
if man.lifes <= 35:
man.lifes += 10
else:
Gun_shot.stop()
pass
try:
bullets.pop(bullets.index(bullet))
drop = False
drop_count = 0
drop_spot = []
except ValueError:
pass
except:
pass
if bullet.x < 650 and bullet.x > -20:
bullet.x += bullet.vel
else:
try:
bullets.pop(bullets.index(bullet))
except ValueError:
pass
keys = pygame.key.get_pressed()
if keys[pygame.K_KP0] and not (main_menu):
if man.left:
facing = -1
elif man.right:
facing = 1
else:
facing = -1
if len(bullets) < 5 and shootloop == 0:
Gun_shot.play()
bullets.append(projectile(round(man.x + man.width // 2), round(man.y + man.height // 2), 6, (0, 0, 255), facing))
shootloop = 1
if keys[pygame.K_LEFT] and man.x > man.vel and not(man_movement_block):
man.x -= man.vel
man.left = True
man.right = False
man.standing = False
elif keys[pygame.K_RIGHT] and man.x < 620 - man.vel - man.width:
man.x += man.vel
man.right = True
man.left = False
man.standing = False
elif keys[pygame.K_b] and shield_count == 0:
if shield_colour == "blue":
shield_colour = "red"
shield_number = 1
else:
shield_colour = "blue"
shield_number = 0
shield_count = 1
if not (man.isjump):
if keys[pygame.K_UP]:
man.isjump = True
man.walkcount = 0
else:
if man.jumpcount >= -10:
neg = 1
if man.jumpcount < 0:
neg = -1
man.y -= (man.jumpcount ** 2) / 2 * neg
man.jumpcount -= 1
else:
man.isjump = False
man.jumpcount = 10
bad_guy1.walk(win)
bad_guy2.walk(win)
bad_guy3.walk(win)
redraw_game_window()
pygame.quit()
The problem is caused by the code in the walk method of the enemy class, where you check for collisions between enemy bullets and the player.
if man.left:
... # block bullets with the shield when the player is pointing left
elif man.right:
... # block bullets with the shield when the player is pointing right
elif int(shield_number) != int(test_number):
... # if the player has been hit, call man.hit
Because you have used an elif, the code that checks if the player has been hit (and calls man.hit) will only be executed if both man.left and man.right are false, which never happens. Just changing it from an elif to an if should solve your problem.
if man.left:
... # block bullets with the shield when the player is pointing left
elif man.right:
... # block bullets with the shield when the player is pointing right
if int(shield_number) != int(test_number):
... # if the player has been hit, call man.hit

Trying to pop enemy in pygame when health reaches 0

Here is the section I'm trying to get to work, my intent is to have the enemy 'pop' out of the code, currently when the enemy reaches 0 it disappears and no longer hurts the play, but bullets can still hit the enemy at the location it was destroyed:
for lizard in enemy:
if lizard.visible == True:
enemy.pop(enemy.index(lizard))
Here is the error I keep receiving:
TypeError: 'type' object is not iterable
Below you can see the full code:
import pygame
pygame.init()
win = pygame.display.set_mode((600, 580))
pygame.display.set_caption('new nas')
screenWidth = 500
walkRight = [pygame.image.load('R1.png'),
pygame.image.load('R2.png'), pygame.image.load('R3.png'), pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'), pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]
walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'), pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'), pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]
bg = pygame.image.load('sunset.jpg')
char = pygame.image.load('standing.png')
clock = pygame.time.Clock()
bowSound = pygame.mixer.Sound('Bow_release.wav')
arrowSound = pygame.mixer.Sound('Arrow_hit.wav')
music = pygame.mixer.music.load('upbeat.mp3')
pygame.mixer.music.play(-1)
score = 0
#hero
class player(object):
def __init__(self,x,y,width,height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 5
self.isJump = False
self.jumpCount = 10
self.left = False
self.right = False
self.walkCount = 0
self.standing = True
self.hitbox = (self.x + 17, self.y + 11, 29, 52)
self.health = 10
self.visible = True
def draw(self, win):
if self.visible:
self.health > 1
else:
self.visible == False
if self.walkCount + 1 >= 27:
self.walkCount = 0
if not (self.standing):
if self.left:
win.blit(walkLeft[self.walkCount//3], (self.x,self.y))
self.walkCount += 1
elif self.right:
win.blit(walkRight[self.walkCount//3], (self.x,self.y))
self.walkCount += 1
else:
if self.right:
win.blit(walkRight[0], (self.x, self.y))
else:
win.blit(walkLeft[0], (self.x, self.y))
self.hitbox = (self.x + 17, self.y + 11, 29, 52)
pygame.draw.rect(win, (255,0,0), (self.hitbox[0], self.hitbox[1] - 20, 50,10))
pygame.draw.rect(win, (0,100,0), (self.hitbox[0], self.hitbox[1] - 20, 50 - ((50/10) * (10 - self.health)),10))
#pygame.draw.rect(win, (255,0,0), self.hitbox,2)
def hit(self):
self.jumpCount = False
self.jumpCount = 10
self.x = 25
self.y = 480
self.walkCount = 0
font1 = pygame.font.SysFont('forte', 100)
text = font1.render('-5', 1, (255,0,0))
pygame.display.update()
i = 0
while i < 100:
pygame.time.delay(10)
i += 1
for event in pygame.event.get():
if event.type == pygame.QUIT:
i = 301
pygame.quit()
# weap
class projectile(object):
def __init__(self,x,y,radius,color,facing):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.facing = facing
self.vel = 8 * facing
def draw(self,win):
pygame.draw.circle(win, self.color, (self.x,self.y), self.radius)
# enemy fodder
class enemy(object):
walkRight = [pygame.image.load('R1E.png'), pygame.image.load('R2E.png'), pygame.image.load('R3E.png'), pygame.image.load('R4E.png'), pygame.image.load('R5E.png'), pygame.image.load('R6E.png'), pygame.image.load('R7E.png'), pygame.image.load('R8E.png'), pygame.image.load('R9E.png'), pygame.image.load('R10E.png'), pygame.image.load('R11E.png')]
walkLeft = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'), pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'), pygame.image.load('L7E.png'), pygame.image.load('L8E.png'), pygame.image.load('L9E.png'), pygame.image.load('L10E.png'), pygame.image.load('L11E.png')]
def __init__(self, x, y, width, height, end):
self.x = x
self.y = y
self.width = width
self.height = height
self.end = end
self.path = [self.x, self.end]
self.walkCount = 0
self.vel = 3
self.hitbox = (self.x + 17, self.y + 2, 31, 57)
self.health = 10
self.visible = True
def draw(self,win):
self.move()
if self.visible:
if self.walkCount + 1 >= 33:
self.walkCount = 0
if self.vel > 1:
win.blit(self.walkRight[self.walkCount //3], (self.x, self.y))
self.walkCount += 1
else:
win.blit(self.walkLeft[self.walkCount //3], (self.x, self.y))
self.walkCount += 1
pygame.draw.rect(win, (255,0,0), (self.hitbox[0], self.hitbox[1] - 20, 50,10))
pygame.draw.rect(win, (0,100,0), (self.hitbox[0], self.hitbox[1] - 20, 50 - ((50/10) * (10 - self.health)),10))
self.hitbox = (self.x + 17, self.y + 2, 31, 57)
#pygame.draw.rect(win, (255,0,0), self.hitbox,2)
def move(self):
if self.vel > 0:
if self.x < self.path[1] + self.vel:
self.x += self.vel
else:
self.vel = self.vel * -1
self.walkCount = 0
else:
if self.x > self.path[0] - self.vel:
self.x += self.vel
else:
self.vel = self.vel * -1
self.walkCount = 0
def hit(self):
if self.health > 0:
self.health -= 1
else:
self.visible = False
print('hit')
def redrawGameWindow():
win.blit(bg, (0,0))
text = font.render('Score: ' + str(score), 1, (0,0,0))
win.blit(text, (400, 10))
nas.draw(win)
lizard.draw(win)
for bullet in bullets:
bullet.draw(win)
pygame.display.update()
#main loop
font = pygame.font.SysFont('forte', 20, True)
nas = player(50, 480, 64, 64)
lizard = enemy(100, 485, 64, 64, 450)
run = True
shootLoop = 0
bullets = []
while run:
clock.tick(27)
if lizard.visible == True:
if nas.hitbox[1] < lizard.hitbox[1] + lizard.hitbox[3] and nas.hitbox[1] + nas.hitbox[3] > lizard.hitbox[1]:
if nas.hitbox[0] + nas.hitbox[2] > lizard.hitbox[0] and nas.hitbox[0] < lizard.hitbox[0] + lizard.hitbox[2]:
nas.hit()
score -= 5
for lizard in enemy:
if lizard.visible == True:
enemy.pop(enemy.index(lizard))
# projectile cool down
if shootLoop > 0:
shootLoop += 1
if shootLoop > 3:
shootLoop = 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
for bullet in bullets:
if bullet.y - bullet.radius < lizard.hitbox[1] + lizard.hitbox[3] and bullet.y + bullet.radius > lizard.hitbox[1]:
if bullet.x + bullet.radius > lizard.hitbox[0] and bullet.x - bullet.radius < lizard.hitbox[0] + lizard.hitbox[2]:
arrowSound.play()
lizard.hit()
score += 1
bullets.pop(bullets.index(bullet))
if bullet.x < 500 and bullet.x > 0:
bullet.x += bullet.vel
else:
bullets.pop(bullets.index(bullet))
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE] and shootLoop == 0:
bowSound.play()
if nas.left:
facing = -1
else:
facing = 1
if len(bullets) < 3:
bullets.append(projectile(round(nas.x + nas.width//2), round(nas.y + nas.height//2), 6,(250,0,0), facing))
shootLoop = 1
if keys [pygame.K_a] and nas.x > nas.vel:
nas.x -= nas.vel
nas.left = True
nas.right = False
nas.standing = False
elif keys [pygame.K_d] and nas.x < 500 - nas.width - nas.vel:
nas.x += nas.vel
nas.right = True
nas.left = False
nas.standing = False
else:
nas.standing = True
nas.walkCount = 0
if not (nas.isJump):
if keys[pygame.K_w]:
nas.isJump = True
nas.right = False
nas.left = False
nas.walkCount = 0
else:
if nas.jumpCount >= -10:
neg = 1
if nas.jumpCount < 0:
neg = -1
nas.y -= (nas.jumpCount ** 2) * 0.2 * neg
nas.jumpCount -= 1
else:
nas.isJump = False
nas.jumpCount = 10
redrawGameWindow()
pygame.quit()
enemy is a class not a list, so it can't be iterated. By the way, class names should normally use the CapWords convention. See Style Guide for Python Code.
Anyway, add a list of enemies to the application. The list can be traversed and the killed enemies can be removed:
enemies = []
enemies.append(Enemy(100, 485, 64, 64, 450))
# [...]
while run:
# [...]
for lizard in enemies[:]:
if lizard.visible == True:
if nas.hitbox[1] < lizard.hitbox[1] + lizard.hitbox[3] and nas.hitbox[1] + nas.hitbox[3] > lizard.hitbox[1]:
if nas.hitbox[0] + nas.hitbox[2] > lizard.hitbox[0] and nas.hitbox[0] < lizard.hitbox[0] + lizard.hitbox[2]:
nas.hit()
score -= 5
if lizard.visible == False:
enemies.pop(enemies.index(lizard))
I recommend to read about pygame.Rect. Use collidepoint() to simplify the collision test code. e.g:
while run:
# [...]
for lizard in enemies[:]:
if lizard.visible:
lizard_rect = pygame.Rect(*lizard.hitbox)
nas_rect = pygame.Rect(*nas.hitbox)
if nas_rect.colliderect(lizard_rect):
nas.hit()
score -= 5
if not lizard.visible:
enemies.pop(enemies.index(lizard))
Further mote, the way to implement applications like this in pygame, is to use pygame.sprite.Sprite and pygame.sprite.Group
Try moving the enemy off the screen. Something like enemy.move(-100, 100) in pseudocode.

These hit boxes are crossing over even though they are literally not with if statements

I am trying to get my pieces to collide and and when I jump up into the air the characters should not collide.
Here is a video explaining the problem:
https://drive.google.com/file/d/1a26Vmd6TF4C3dJ0DpnFLTR1d3a_lEfn4/view?usp=sharing
The collision is with the goblin.
Furthermore, we can see that the goblin is colliding even though the boxes aren't touching and when on top of the hitbox.
I have tried to change the condition of the loop for example changed the ">" around to "<" and tried making the jump higher. Both of these did not resolve the problem and I am not an experienced coder.
Here is the main problem:
if (adventurer.hitbox_running[0] > attacker.hitbox[0] and adventurer.hitbox_running[0] < attacker.hitbox[0]+70) or (adventurer.hitbox_running[0]+70 > attacker.hitbox[0] and adventurer.hitbox_running[0]+90 < attacker.hitbox[0]+70):
if (adventurer.hitbox_running[1] > attacker.hitbox[1] and adventurer.hitbox_running[1] < attacker.hitbox[1]+70) or (adventurer.hitbox_running[1]+90 > attacker.hitbox[1] and adventurer.hitbox_running[1]+90 < attacker.hitbox[1]+70):
window.fill((255,255,255))
death()
pygame.display.update()
s(0.1)
print("hit")
Here is the entire code with all of the classes and everything:
from time import sleep as s
import random
import pygame
import time
#Loads and plays the music
pygame.mixer.pre_init(44100,16,2,4096)
pygame.init()
pygame.mixer.music.load("Music.mp3")
pygame.mixer.music.set_volume(0.0)
pygame.mixer.music.play(-1)
score = 0
#sets the dimension of the window and loads in the background
window = pygame.display.set_mode((1000, 500))
pygame.display.set_caption("Practice Game")
background = pygame.image.load('pixel6.png')
#Transforms the background to desired dimensions
background = pygame.transform.scale(background, (1000, 500))
#Loads all the jump animation
jumpv1 = [pygame.image.load('adventurer-jump-00.png'),pygame.image.load('adventurer-jump-01.png'),pygame.image.load('adventurer-jump-02.png'),pygame.image.load('adventurer-jump-03.png'), pygame.image.load('adventurer-smrslt-00.png'),pygame.image.load('adventurer-smrslt-01.png'),pygame.image.load('adventurer-smrslt-02.png'),pygame.image.load('adventurer-smrslt-03.png')]
jumpv2 = [pygame.image.load('adventurer-smrslt-00.png'),pygame.image.load('adventurer-smrslt-01.png'),pygame.image.load('adventurer-smrslt-02.png'),pygame.image.load('adventurer-smrslt-03.png')]
jumpv3 = [pygame.image.load('adventurer-smrslt-00.png'),pygame.image.load('adventurer-smrslt-01.png'),pygame.image.load('adventurer-smrslt-02.png'),pygame.image.load('adventurer-smrslt-03.png')]
jumpv4 = [pygame.image.load('adventurer-smrslt-00.png'),pygame.image.load('adventurer-smrslt-01.png'),pygame.image.load('adventurer-smrslt-02.png'),pygame.image.load('adventurer-smrslt-03.png')]
jump = jumpv1+jumpv2+jumpv3+jumpv4
#running animation
run = [pygame.image.load('adventurer-run-00.png'), pygame.image.load('adventurer-run-01.png'),pygame.image.load('adventurer-run-02.png'),pygame.image.load('adventurer-run-03.png')]
#sliding animation
slide = [pygame.image.load('adventurer-slide-00.png'),pygame.image.load('adventurer-slide-01.png'),pygame.image.load('adventurer-stand-00.png'),pygame.image.load('adventurer-stand-01.png'),pygame.image.load('adventurer-stand-02.png')]
#attacking animation
firstattack = [pygame.image.load('adventurer-attack3-00.png'),pygame.image.load('adventurer-attack3-01.png'),pygame.image.load('adventurer-attack3-02.png'),pygame.image.load('adventurer-attack3-03.png'),pygame.image.load('adventurer-attack3-04.png'),pygame.image.load('adventurer-attack3-05.png')]
secondattack = [pygame.image.load('adventurer-attack2-00.png'),pygame.image.load('adventurer-attack2-01.png'),pygame.image.load('adventurer-attack2-02.png'),pygame.image.load('adventurer-attack2-03.png'),pygame.image.load('adventurer-attack2-04.png'),pygame.image.load('adventurer-attack2-05.png')]
thirdattack = [pygame.image.load('adventurer-attack1-00.png'),pygame.image .load('adventurer-attack1-01.png'),pygame.image.load('adventurer-attack1-02.png'),pygame.image.load('adventurer-attack1-03.png'), pygame.image.load('adventurer-attack1-04.png')]
attack = firstattack+secondattack+ thirdattack
#falling animation
falling = [pygame.image.load('adventurer-fall-00.png'), pygame.image.load('adventurer-fall-01.png')]
score = 0
run_program = True
#resizes all the adventuruer images to specified dimensions
for i in range (20):
jump[i] = pygame.transform.scale(jump[i],(90,90))
for i in range(3):
run[i] = pygame.transform.scale(run[i],(90,90))
for i in range (4):
slide[i] = pygame.transform.scale(slide[i],(90,90))
for i in range (1):
falling[i] = pygame.transform.scale(falling[i],(90,90))
for i in range(16):
attack[i] = pygame.transform.scale(attack[i],(90,90))
background_x = 0
background_2 = background.get_width()
clock = pygame.time.Clock()
ghost_image = pygame.image.load('imgg.png')
def text_objects(text, font):
textSurface = font.render(text, True, (0,0,0))
return textSurface, textSurface.get_rect()
def message_display(text):
largeText = pygame.font.Font('freesansbold.ttf',115)
TextSurf, TextRect = text_objects(text, largeText)
TextRect.center = ((1000/2),(500/2))
window.blit(TextSurf, TextRect)
pygame.display.update()
def death():
message_display('You DIED')
class ghost(object):
ghost_animation = [pygame.image.load('imgg.png'),pygame.image.load('imgg.png')]
def __init__(self, x,y,height):
self.x = x
self.y =y
self.height = height
self.hitbox = (x,y,100,100)
self.count = 0
def draw(self, window):
self.hitbox = (self.x, self.y, 45, 60)
if self.count >=1:
self.count = 0
self.count +=1
window.blit(pygame.transform.scale(self.ghost_animation[self.count], (45,60)), (self.x, self.y))
pygame.draw.rect(window, (255,0,0), self.hitbox, 2)
def hit(self):
print ("hit")
class eye(object):
eye_load = pygame.image.load('obstc2.png')
def __init__(self, x,y,width2, height2):
self.x = x
self.y =y
self.hitbox_enemy = (x,y,200,100)
self.count1 = 0
def draw(self, window):
self.hitbox_enemy = (self.x, self.y, 65, 65)
window.blit(pygame.transform.scale(self.eye_load, (65,65)), (self.x, self.y))
pygame.draw.rect(window, (255,0,0), self.hitbox_enemy, 2)
class player(object):
def __init__(self, x,y):
self.vel = 0.5
self.running = True
self.jumping = True
self.sliding = True
self.attacking = True
self.isJump = False
self. jumps = True
self.fall = True
self.player_x = 40
self.player_y = 378
self.x = 40
self.y = 378
self.width = 378
self.speed = 0.6
self.jumpcount = 10
self.jumpingcount = 0
self.runcount = 0
self.attackcount = 0
self.slidecount = 0
self.fallspeed = 0.3
self.fallingcount = 0
self.hitbox_running = (self.player_x,self.player_y,90,90)
self.hitbox_sliding = (45,self.player_y+47,65,45)
self.hitbox_falling = (self.player_x+30,self.player_y,35,80)
self.hitbox_jumping = (self.player_x+20,self.player_y+20,52,55)
self.hitbox_attacking = (58,405,47,70)
self.hitbox_sword = (108, 405, 20, 50)
def movement(self, window):
pygame.time.delay(20)
if self.runcount >= 3:
self.runcount = 0
if self.running == True:
window.blit(run[self.runcount],(int(self.player_x),int(self.player_y)))
self.runcount +=1
self.hitbox_running = (self.player_x+30,self.player_y+20,48,70)
pygame.draw.rect(window,(255,0,0),self.hitbox_running, 2)
if (keys[pygame.K_DOWN]) or ((keys[pygame.K_DOWN]) and keys[pygame.K_p]):
if self.player_y == 378:
self.running = False
if self.slidecount >= 4:
self.slidecount = 0
if self.sliding:
window.blit(slide[self.slidecount],(int(self.player_x),int(self.player_y)))
self.slidecount +=1
pygame.draw.rect(window,(255,0,0),self.hitbox_sliding, 2)
if event.type == pygame.KEYDOWN:
if (event.key == pygame.K_DOWN )and self.player_y < self.width:
self.running = False
self.jumping = False
self.fallspeed += 0.2
if self.fallingcount >= 1:
self.fallingcount = 0
if self.fall:
window.blit(falling[self.fallingcount], (int(self.player_x),int(self.player_y)))
self.hitbox_falling = (self.player_x+30,self.player_y,35,80)
pygame.draw.rect(window,(255,0,0),self.hitbox_falling, 2)
self.fallingcount +=1
if keys[pygame.K_UP] and keys[pygame.K_p] :
self.fallspeed = 0.3
self.running = False
self.jumping = False
self.sliding = False
if self.attackcount >= 16:
self.attackcount = 0
if self.attacking:
window.blit(attack[self.attackcount],(int(self.player_x),int(self.player_y)))
self.attackcount += 1
self.hitbox_attacking = (self.player_x+30,self.player_y+20,38,70)
self.hitbox_sword = (self.player_x+72, self.player_y+20, 20, 50)
pygame.draw.rect(window,(255,0,0),self.hitbox_attacking, 2)
pygame.draw.rect(window,(255,0,0),self.hitbox_sword, 2)
if self.jumpingcount >= 20:
self.jumpingcount = 0
if self.jumping and self.player_y < self.width:
window.blit(jump[self.jumpingcount],(int(self.player_x),int(self.player_y)))
self.hitbox_jumping = (int(self.player_x+20),int(self.player_y+20),52,55)
pygame.draw.rect(window,(255,0,0),self.hitbox_jumping, 2)
self.jumpingcount +=1
self.fallspeed = 0.3
if keys[pygame.K_UP]:
self.fallspeed = 0.3
self.running = False
if self.jumpingcount >= 20:
self.jumpingcount = 0
if self.jumping and self.player_y < self.width:
window.blit(jump[self.jumpingcount],(int(self.player_x),int(self.player_y)))
self.hitbox_jumping = (int(self.player_x+20),int(self.player_y+20),52,55)
pygame.draw.rect(window,(255,0,0),self.hitbox_jumping, 2)
self.jumpingcount +=1
self.fallspeed = 0.3
if keys[pygame.K_p] and not keys[pygame.K_UP]:
self.running = False
self.jumping = False
self.sliding = False
if self.attackcount >= 16:
self.attackcount = 0
if self.attacking:
self.hitbox_attacking = (self.player_x+30,self.player_y+20,38,70)
self.hitbox_sword = (self.player_x+72, self.player_y+20, 20, 50)
window.blit(attack[self.attackcount],(int(self.player_x),int(self.player_y)))
self.attackcount += 1
pygame.draw.rect(window,(255,0,0),self.hitbox_attacking, 2)
pygame.draw.rect(window,(255,0,0),self.hitbox_sword, 2)
if keys[pygame.K_DOWN] and keys[pygame.K_UP]:
self.running = False
if event.type == pygame.KEYUP:
if event.key == pygame.K_DOWN:
self.running = True
self.jumping = True
self.fallspeed = 0.3
if event.key == pygame.K_UP:
self.running=True
if event.key == pygame.K_p:
self.running = True
self.jumping = True
self.sliding = True
class enemy(object):
walkright = [pygame.image.load('R1E.png'), pygame.image.load('R2E.png'), pygame.image.load('R3E.png'), pygame.image.load('R4E.png'), pygame.image.load('R5E.png'), pygame.image.load('R6E.png'), pygame.image.load('R7E.png'), pygame.image.load('R8E.png'), pygame.image.load('R9E.png'), pygame.image.load('R10E.png'), pygame.image.load('R11E.png')]
walkleft = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'), pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'), pygame.image.load('L7E.png'), pygame.image.load('L8E.png'), pygame.image.load('L9E.png'), pygame.image.load('L10E.png'), pygame.image.load('L11E.png')]
for i in range (10):
walkright[i] = pygame.transform.scale(walkright[i],(70,70))
for i in range(10):
walkleft[i] = pygame.transform.scale(walkleft[i],(70,70))
def __init__(self,enemy_x,enemy_y, end):
self.x = enemy_x
self.y = enemy_y
self.end = end
self.path = [self.x,self.end]
self.walkcount = 0
self.vel = 7
self.hitbox = (self.x,self.y-15,90,90)
def draw_enemy(self,window):
self.move()
if self.walkcount+1 >= 33:
self.walkcount = 0
self.vel+=0.2
#walking right
if self.vel > 0:
window.blit(self.walkleft[self.walkcount//3], (self.x,self.y-15))
self.walkcount += 1
#walking left
if self.vel < 0:
## window.blit(self.walkleft[self.walkcount//3], (self.x,self.y))
self.walkcount -= 1
if self.x < -100:
self.x = 1050
self.hitbox = (self.x+25,self.y-15,41,70)
pygame.draw.rect(window, (255,0,0),self.hitbox,2)
def move(self):
if self.vel > 0:
#see if position + movement space is < the end, then it is able to move
if self.x + self.vel < self.path[1]:
self.x -= self.vel
#past end point and turns 180
else:
self.vel = self.vel*-1
self.walkcount = 0
#see if position is smaller than starting position
else:
if self.x - self.vel > self.path[0]:
#vel is already negative
self.x += self.vel
else:
#Truns 180 agian
self.vel = self.vel* -1
self.walkcount = 0
class wizard(object):
walkleft = [pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_05.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_05.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_05.gif'),pygame.image.load('wizard-fly-forward_04.gif'), pygame.image.load('wizard-fly-forward_04.gif'),pygame.image.load('wizard-fly-forward_05.gif')]
for i in range(16):
walkleft[i] = pygame.transform.scale(walkleft[i],(70,70))
def __init__(self,enemy_x,enemy_y, end):
self.x = enemy_x
self.y = enemy_y
self.end = end
self.path = [self.x,self.end]
self.walkcount = 0
self.vel = 7
self.hitbox = (self.x,self.y-15,90,90)
def draw_enemy(self,window):
self.move()
if self.walkcount >= 16:
self.walkcount = 0
#walking left
if self.vel > 0:
window.blit(self.walkleft[self.walkcount], (self.x,self.y-15))
self.walkcount += 1
self.vel+=0.002
if self.x < -120:
self.x = 1100
self.hitbox = (self.x+25,self.y-15,41,70)
pygame.draw.rect(window, (255,0,0),self.hitbox,2)
def move(self):
if self.vel > 0:
#see if position + movement space is < the end, then it is able to move
if self.x + self.vel < self.path[1]:
self.x -= self.vel
#past end point and turns 180
else:
self.vel = self.vel*-1
self.walkcount = 0
#see if position is smaller than starting position
else:
if self.x - self.vel > self.path[0]:
#vel is already negative
self.x += self.vel
else:
#Truns 180 agian
self.vel = self.vel* -1
self.walkcount = 0
class dragon(object):
walkleft = [pygame.image.load('dragon_1.gif'), pygame.image.load('dragon_2.gif'), pygame.image.load('dragon_3.gif'), pygame.image.load('dragon_4.gif'), pygame.image.load('dragon_5.gif'), pygame.image.load('dragon_6.gif')]
for i in range (6):
walkleft[i] = pygame.transform.scale(walkleft[i],(200,176))
def __init__(self,enemy_x,enemy_y, end):
self.x = enemy_x
self.y = enemy_y
self.end = end
self.path = [self.x,self.end]
self.walkcount = 0
self.vel = 7
self.hitbox = (self.x,self.y-15,90,90)
def draw_enemy(self,window):
self.move()
if self.walkcount >= 6:
self.walkcount = 0
#walking left
if self.vel > 0:
window.blit(self.walkleft[self.walkcount], (self.x,300))
self.walkcount += 1
self.vel+=0.002
if self.x < -120:
self.x = 1100
self.hitbox = (self.x+25,self.y-15,41,70)
pygame.draw.rect(window, (255,0,0),self.hitbox,2)
def move(self):
if self.vel > 0:
#see if position + movement space is < the end, then it is able to move
if self.x + self.vel < self.path[1]:
self.x -= self.vel
#past end point and turns 180
else:
self.vel = self.vel*-1
self.walkcount = 0
#see if position is smaller than starting position
else:
if self.x - self.vel > self.path[0]:
#vel is already negative
self.x += self.vel
else:
#Truns 180 agian
self.vel = self.vel* -1
self.walkcount = 0
ghost_list = []
eye_list = []
def keepdrawing():
window.blit(background, (background_x,0))
window.blit(background, (background_2,0))
for draw_ghost in ghost_list:
draw_ghost.draw(window)
for draw_eye in eye_list:
draw_eye.draw(window)
adventurer.movement(window)
attacker.draw_enemy(window)
wizard.draw_enemy(window)
dragon.draw_enemy(window)
score_text = score_font.render("score: " + str(score), 1, (0,0,0))
window.blit(score_text,(470,10))
pygame.display.update()
score_font = pygame.font.SysFont("Arial",30,True)
attacker = enemy(950,407,951)
adventurer = player(40,387)
wizard = wizard(905,407,951)
dragon = dragon(905,407, 951)
vel_background = 2
pygame.time.set_timer(pygame.USEREVENT+1,random.randint(1000, 2000))
pygame.time.set_timer(pygame.USEREVENT+2,random.randint(2000, 3000))
while run:
while run_program:
clock.tick(60)
background_x -= vel_background
background_2 -= vel_background
if background_x < background.get_width() * -1:
background_x = background.get_width()
if background_2 < background.get_width() * -1:
background_2 = background.get_width()
keys = pygame.key.get_pressed()
if (adventurer.hitbox_running[0] > attacker.hitbox[0] and adventurer.hitbox_running[0] < attacker.hitbox[0]+70) or (adventurer.hitbox_running[0]+70 > attacker.hitbox[0] and adventurer.hitbox_running[0]+90 < attacker.hitbox[0]+70):
if (adventurer.hitbox_running[1] > attacker.hitbox[1] and adventurer.hitbox_running[1] < attacker.hitbox[1]+70) or (adventurer.hitbox_running[1]+90 > attacker.hitbox[1] and adventurer.hitbox_running[1]+90 < attacker.hitbox[1]+70):
window.fill((255,255,255))
death()
pygame.display.update()
s(0.1)
print("hit")
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
exit()
if event.type == pygame.USEREVENT+1:
vel_background+=0.2
if event.type == pygame.USEREVENT+2:
r = random.randint(0,1)
if r==0:
new_eye = eye(1050, 390, 64,64)
eye_list.append(new_eye)
if r==1:
new_ghost = ghost(1050,390,64)
ghost_list.append(new_ghost)
if not(adventurer.isJump):
if keys[pygame.K_UP]:
adventurer.isJump =True
else:
if adventurer.jumpcount >= -10:
neg=1
if adventurer.player_y > adventurer.width:
adventurer.player_y = adventurer.width
if adventurer.jumpcount <0:
neg = -1
## s(0.01)
adventurer.player_y -= (adventurer.jumpcount**2)*adventurer.fallspeed*neg*2
## s(0.01)
adventurer.jumpcount -=1
if adventurer.player_y > adventurer.width:
adventurer.player_y=adventurer.width
else:
adventurer.isJump = False
adventurer.jumpcount = 10
if adventurer.player_y > adventurer.width:
player_y = adventurer.width
adventurer.fallspeed = 0.05
keepdrawing()
The expected results should be that the output should not be shit if the hit boxes are not in contact.
The major issue is that you've different "hitboxis, which have different meanings at different states of the game, but you use adventurer.hitbox_running for the collison test event if adventurer is .running or .falling.
The best solution would be the set one .hitbox attribute, which always contains the proper location of adventurer in the method player.movement.
But it is also possible the choose the proper hit box:
if adventurer.running:
hitbox = adventurer.hitbox_running
elif adventurer.jumping:
hitbox = adventurer.hitbox_jumping
elif adventurer.falling:
hitbox = adventurer.hitbox_falling
Further I recommend to use pygame.Rect objects and .colliderect() for the collision test:
rect_adventurer = pygame.Rect(*hitbox)
rect_attacker = pygame.Rect(*attacker.hitbox)
if rect_adventurer.colliderect(rect_attacker):
window.fill((255,255,255))
death()
pygame.display.update()
s(0.1)
print("hit")

Categories