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)
Related
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.
How come my Goku sprites aren't loading my left and right image appear correct but my others aren't playing in motion? the mian thing am trying to accomplish is for my character images to work correctly in motion
below is the code with a link to the full code description:
https://pastebin.com/umMJHNQj
import pygame
pygame.init()#We always need to initialize our pygame IN EVERY PROJECT/FILE
win = pygame.display.set_mode((500, 480))# Here win is representing "window" for our screen which we have set at 500 by 480
pygame.display.set_caption("First Game")#We are giving our Window/Screen a name
walkRight = [pygame.image.load('image/gokuR0.png'), pygame.image.load('image/gokutest2.png'), pygame.image.load('image/gokuR2.png')]
walkLeft = [pygame.image.load('image/gokuL0.png'), pygame.image.load('image/gokutest.png'), pygame.image.load('image/gokuL2.png')]
bg = pygame.image.load('image/bg.jpg')
char = pygame.image.load('image/goku sprite - standing.png')
clock = pygame.time.Clock()
class player():
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 = False
Here is where i have tried to alter the code but yet no results.
def draw(self, win):
if self.walkCount + 1 >= 8:
self.walkCount = 0
if not self.standing:
if self.left:
win.blit(walkLeft[self.walkCount // 100], (self.x, self.y))
self.walkCount += 1
elif self.right:
win.blit(walkRight[self.walkCount // 100], (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))
pygame.display.flip()
print(walkLeft)
print(walkRight)
class projectile():
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)
All these images are working correctly yet can't seem to get my main characters images to work in properly in motion
class enemy():
walkRight = [pygame.image.load("image/R1E.png"), pygame.image.load("image/R2E.png"), pygame.image.load("image/R3E.png"), pygame.image.load("image/R4E.png"), pygame.image.load("image/R5E.png"), pygame.image.load("image/R6E.png"), pygame.image.load("image/R7E.png"), pygame.image.load("image/R8E.png"), pygame.image.load("image/R9E.png"), pygame.image.load("image/R10E.png"), pygame.image.load("image/R11E.png")]
walkLeft = [pygame.image.load("image/L1E.png"), pygame.image.load("image/L2E.png"), pygame.image.load("image/L3E.png"), pygame.image.load("image/L4E.png"), pygame.image.load("image/L5E.png"), pygame.image.load("image/L6E.png"), pygame.image.load("image/L7E.png"), pygame.image.load("image/L8E.png"), pygame.image.load("image/L9E.png"), pygame.image.load("image/L10E.png"), pygame.image.load("image/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
def draw(self,win):
self.move()
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
print(walkLeft)
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 redrawGameWindow():
win.blit(bg, (0, 0))
goblin.draw(win)
man.draw(win)
for bullet in bullets:
bullet.draw(win)
pygame.display.update()
# mainloop
man = player(200, 400, 85, 85)
goblin = enemy(100, 400, 64, 64, 450)
bullets = []
run = True
while run:
clock.tick(27)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
for bullet in bullets:
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]:
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))
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()
The issue is that self.walkCount is (integral) divided by 100:
win.blit(walkLeft[self.walkCount // 100], (self.x, self.y))
Note self.walkCount will never become grater than 7, because of:
if self.walkCount + 1 >= 8:
self.walkCount = 0
So the result of self.walkCount // 100 is always 0.
Anyway this code makes no sense, since walkLeft and walkRight are lists containing 3 images. I recommend to do the following:
def draw(self, win):
walkfps = 10
if self.standing:
self.walkCount = 0
if self.right:
win.blit(walkRight[0], (self.x, self.y))
else:
win.blit(walkLeft[0], (self.x, self.y))
elif self.left:
if self.walkCount // walkfps >= len(walkLeft):
self.walkCount = 0
win.blit(walkLeft[self.walkCount // walkfps], (self.x, self.y))
self.walkCount += 1
elif self.right:
if self.walkCount // walkfps >= len(walkRight):
self.walkCount = 0
win.blit(walkRight[self.walkCount // walkfps], (self.x, self.y))
self.walkCount += 1
If the images change to rapidly, then increase walkfps.
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
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.
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.