I am a first time coding student in grade 11 and I am trying to create multiple instances of an enemy class in python for my game. Below is my pygame code.
i am having trouble seeing what needs to be changed. Lines 180=183 are where I am trying to create 3 instances of my "enemy" but when I run my code it just create one
import pygame
import random
pygame.init()
window = pygame.display.set_mode((800, 480))
pygame.display.set_caption("Who Killed M?")
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')]
backGround = pygame.image.load('backGround.png')
char = pygame.image.load('standing.png')
clock = pygame.time.Clock()
bulletSound = pygame.mixer.Sound('bullet.wav')
hitSound = pygame.mixer.Sound('hit.wav')
music = pygame.mixer.music.load('music.mp3')
pygame.mixer.music.play(-1)
score = 0
goblincount = 3
class player(object):
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 8
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, window):
if self.walkCount + 1 >= 27:
self.walkCount = 0
if not self.standing:
if self.left:
window.blit(walkLeft[self.walkCount // 3], (self.x, self.y))
self.walkCount += 1
elif self.right:
window.blit(walkRight[self.walkCount // 3], (self.x, self.y))
self.walkCount += 1
else:
if self.right:
window.blit(walkRight[0], (self.x, self.y))
else:
window.blit(walkLeft[0], (self.x, self.y))
self.hitBox = (self.x + 17, self.y + 11, 29, 52)
pygame.draw.rect(window, (255,0,0), self.hitBox,2)
def hit(self):
self.isJump = False
self.jumpCount = 10
self.x = 100
self.y = 415
self.walkCount = 0
font1 = pygame.font.SysFont('comicsans', 200)
text = font1.render('-2', 1, (255, 0, 0))
window.blit(text, (400 - (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, colour, facing):
self.x = x
self.y = y
self.radius = radius
self.colour = colour
self.facing = facing
self.vel = 8 * facing
def draw(self, window):
pygame.draw.circle(window, self.colour, (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 = 2
self.hitBox = (self.x + 17, self.y + 2, 31, 57)
self.health = 10
self.visible = True
def draw(self, window):
self.move()
if self.visible:
if self.walkCount + 1 >= 33:
self.walkCount = 0
if self.vel > 0:
window.blit(self.walkRight[self.walkCount // 3], (self.x, self.y))
self.walkCount += 1
else:
window.blit(self.walkLeft[self.walkCount // 3], (self.x, self.y))
self.walkCount += 1
pygame.draw.rect(window, (255, 0, 0), (self.hitBox[0], self.hitBox[1] - 20, 50, 10))
pygame.draw.rect(window, (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(window, (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 redrawGamewindowdow():
window.blit(backGround, (0, 0))
text = font.render('Score: ' + str(score), 1, (0, 0, 0))
window.blit(text, (350, 10))
mc.draw(window)
goblin.draw(window)
for bullet in bullets:
bullet.draw(window)
pygame.display.update()
# mainloop
font = pygame.font.SysFont('comicsans', 30, True)
mc = player(10, 415, 64, 64)
goblin = enemy(400, 415, 64, 64, 700)
enemies = []
for i in range(3):
enemies.append(enemy(random.randint(0, 800), random.randint(0, 480), 80, 84, 650))
print(2)
# goblin = enemy(random.random()*599+20, 415, 64, 64, 700)
shootLoop = 0
bullets = []
run = True
while run:
#print here
clock.tick(27)
if goblin.visible:
if mc.hitBox[1] < goblin.hitBox[1] + goblin.hitBox[3] and mc.hitBox[1] + mc.hitBox[3] > goblin.hitBox[1]:
if mc.hitBox[0] + mc.hitBox[2] > goblin.hitBox[0] and mc.hitBox[0] < goblin.hitBox[0] + goblin.hitBox[2]:
mc.hit()
score -= 2
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]:
hitSound.play()
goblin.hit()
score += 1
bullets.pop(bullets.index(bullet))
if 800 > 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:
bulletSound.play()
if mc.left:
facing = -1
else:
facing = 1
if len(bullets) < 3:
bullets.append(
projectile(round(mc.x + mc.width // 2), round(mc.y + mc.height // 2), 6, (0, 0, 0), facing))
shootLoop = 1
if keys[pygame.K_LEFT] and mc.x > mc.vel:
mc.x -= mc.vel
mc.left = True
mc.right = False
mc.standing = False
elif keys[pygame.K_RIGHT] and mc.x < 800 - mc.width - mc.vel:
mc.x += mc.vel
mc.right = True
mc.left = False
mc.standing = False
else:
mc.standing = True
mc.walkCount = 0
if not mc.isJump:
if keys[pygame.K_UP]:
mc.isJump = True
mc.right = False
mc.left = False
mc.walkCount = 0
else:
if mc.jumpCount >= -10:
neg = 1
if mc.jumpCount < 0:
neg = -1
mc.y -= (mc.jumpCount ** 2) * 0.3 * neg #changes the .3 from a .5
mc.jumpCount -= 1
else:
mc.isJump = False
mc.jumpCount = 10
redrawGamewindowdow()
pygame.quit()
Your enemies are well constructed, but you do not draw and move them. Draw the elements of the list enemies in a loop is redrawGamewindowdow:
def redrawGamewindowdow():
window.blit(backGround, (0, 0))
text = font.render('Score: ' + str(score), 1, (0, 0, 0))
window.blit(text, (350, 10))
mc.draw(window)
goblin.draw(window)
# draw enemies
for e in enemies:
e.draw(window)
for bullet in bullets:
bullet.draw(window)
pygame.display.update()
Related
import pygame
import math
import random
import time
pygame.init()
clock = pygame.time.Clock()
width = 800
height = 600
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Shadow Warrior")
#its like that because this reduses lag a lot and help for better gameplay
def loadify(imgname):
return pygame.image.load(imgname).convert_alpha(screen)
#Models:
logo = loadify("textures/logo.png")
pygame.display.set_icon(logo)
wallModel = loadify("textures/wall.png")
groundModel = loadify("textures/ground.png")
weaponModel = loadify("textures/weapon.png")
enemyBullet = loadify("textures/bullet.png")
playerBullet = loadify("textures/enemyBullet.png")
crosshair = loadify("textures/crosshair.png")
playerWalkAnimR = [loadify("textures\walk0.png"),
loadify("textures\walk1.png"),
loadify("textures\walk2.png")]
playerWalkAnimL = [loadify("textures\walk3.png"),
loadify("textures\walk4.png"),
loadify("textures\walk5.png")]
pygame.mouse.set_visible(False)
tileSize = 64
level = 0
hitParticles = []
weapons = []
removed_bullets = []
enemies = []
backgrounds = []
walls = []
all_bullets = []
# Classes
class Particle:
def __init__(self, x, y, velocityX, velocityY, radius, color):
self.x = x
self.y = y
self.velocityX = velocityX
self.velocityY = velocityY
self.radius = radius
self.color = color
self.lifetime = random.randrange(50, 100)
def draw(self, screen, camx, camy):
self.lifetime -= 1
self.x += self.velocityX
self.y += self.velocityY
pygame.draw.circle(screen, self.color, (self.x - camx, self.y - camy), self.radius)
class Background:
def __init__(self, x, y):
self.x = x
self.y = y
def draw(self, camx, camy):
screen.blit(groundModel, (self.x - camx - tileSize / 2, self.y - camy - tileSize / 2))
class Wall:
def __init__(self, x, y):
self.x = x
self.y = y
#Check if wall collides with smth
def collidesWith(self, other):
return pygame.Rect(self.x, self.y, tileSize, tileSize).colliderect(other.x, other.y, tileSize-16, tileSize)
def draw(self, camx, camy):
screen.blit(wallModel, (self.x - camx - tileSize / 2, self.y - camy - tileSize / 2))
class Bullet:
def __init__(self, x, y, velx, vely, isPlayer):
self.x = x
self.y = y
self.velx = velx
self.vely = vely
self.isPlayer = isPlayer
def collidesWith(self, other):
return pygame.Rect(self.x, self.y, tileSize - 16, tileSize - 16).colliderect(other.x, other.y, tileSize-36, tileSize-36)
def update(self):
self.x += self.velx
self.y += self.vely
for bullet in all_bullets:
for wall in walls:
if bullet.collidesWith(wall):
removed_bullets.append(bullet)
for i in removed_bullets:
if i in all_bullets:
all_bullets.remove(i)
def draw(self, camx, camy):
if (self.isPlayer):
screen.blit(pygame.transform.smoothscale(playerBullet, (16, 16)), (self.x - camx + 5, self.y - camy + 7))
else: screen.blit(pygame.transform.smoothscale(enemyBullet, (16, 16)), (self.x - camx + 5, self.y - camy + 7))
class slimeEnemy:
def __init__(self, x, y):
self.x = x
self.y = y
self.bulletSpeed = 1
self.aliveAnimations = [loadify("textures\slime_animation_0.png"),
loadify("textures\slime_animation_1.png"),
loadify("textures\slime_animation_2.png"),
loadify("textures\slime_animation_3.png"),]
self.animationsCount = 0
self.attackRate = 60
self.resetOffset = 0
self.SlimeHp = 7 + level * 2
self.slimeCollisionDmg = 1 + level/2
self.dmg = 1 + level / 2
self.isAlive = True
# self.isBoss = isBoss
#adding offset so the enemy doesnt move directly towards the player
self.offsetX = random.randrange(-150, 150)
self.offsetY = random.randrange(-150, 150)
def collidesWithAnything(self):
for wall in walls:
if wall.collidesWith(self):
return True
return False
def healthBar(self):
pygame.draw.rect(screen, (0, 255, 0), (self.x - camx - 20, self.y + 40 - camy, self.SlimeHp*10 + level*2, 7))
def collidesWith(self, other):
return pygame.Rect(self.x, self.y, tileSize-36, tileSize-36).colliderect(other.x, other.y, tileSize-36, tileSize-36)
def update(self):
# move enemy accordingly
if self.resetOffset == 0:
self.offsetX = random.randrange(-400, 400)
self.offsetY = random.randrange(-400, 400)
self.resetOffset = random.randrange(120, 150)
else: self.resetOffset -= 1
if player.x + self.offsetX > self.x:
self.x += 1
if self.collidesWithAnything():
self.x -= 1
elif player.x + self.offsetX < self.x:
self.x -= 1
if self.collidesWithAnything():
self.x += 1
if player.y + self.offsetY > self.y:
self.y += 1
if self.collidesWithAnything():
self.y -= 1
elif player.y + self.offsetY < self.y:
self.y -= 1
if self.collidesWithAnything():
self.y += 1
self.healthBar()
def attack(self):
for i in range(3):
angle = random.randrange(0, 360)
bulletSpeed_x = self.bulletSpeed * math.cos(angle) + random.uniform(-5, 5)
bulletSpeed_y = self.bulletSpeed * math.sin(angle) + random.uniform(-5, 5)
all_bullets.append(Bullet(self.x, self.y, bulletSpeed_x, bulletSpeed_y, False))
def drawAlive(self, camx, camy):
if self.animationsCount + 1 == 32:
self.animationsCount = 0
self.animationsCount += 1
if self.attackRate == 0:
self.attackRate = 60
self.attack()
self.attackRate -= 1
screen.blit(pygame.transform.scale(self.aliveAnimations[self.animationsCount// 8], (32, 30)), (self.x - camx, self.y - camy))
class Weapon:
def __init__(self, bulletSpeed, fireRate, bulletDmg):
self.shooting = False
self.bulletSpeed = bulletSpeed
self.fireRate = fireRate
self.bulletDmg = bulletDmg
self.energy = 100
self.i = 0
def handle_weapons(self, screen):
mouse_x, mouse_y = pygame.mouse.get_pos()
rel_x, rel_y = mouse_x - width/2, mouse_y - height/2
angle = (180/math.pi) * - math.atan2(rel_y, rel_x)
#draw crosshair
screen.blit(crosshair, (mouse_x, mouse_y+5))
#rotate and draw weapon accordingly
if angle > 90 or angle < -90:
player_weapon_copy = pygame.transform.rotate(pygame.transform.flip(weaponModel, True, False), angle - 180)
else:
player_weapon_copy = pygame.transform.rotate(weaponModel, angle)
screen.blit(player_weapon_copy, (width/2 +5 - int(player_weapon_copy.get_width()/2), height/2 + 15 - int(player_weapon_copy.get_height()/2)))
def Shooting(self):
if self.shooting:
#calculates the angles the bullet should travel :/
if self.i % self.fireRate == 0:
if (self.energy == 0):
pass
else:
mouse_x, mouse_y = pygame.mouse.get_pos()
distance_x = mouse_x - width/2
distance_y = mouse_y - height/2
angle = math.atan2(distance_y, distance_x)
bulletSpeed_x = self.bulletSpeed * math.cos(angle)
bulletSpeed_y = self.bulletSpeed * math.sin(angle)
all_bullets.append(Bullet(player.x, player.y, bulletSpeed_x, bulletSpeed_y, True))
self.energy -= 1
self.i += 1
class Player:
def __init__(self, x, y):
self.x = int(x)
self.y = int(y)
self.leftPr = False
self.rightPr = False
self.downPr = False
self.upPr = False
self.speed = 4
self.health = 5
self.maxHp = 5
self.animationsCount = 0
def healthBar(self):
pygame.draw.rect(screen, (255, 0, 0), (20, 25, 200, 10))
pygame.draw.rect(screen, (0, 255, 0), (20, 25, self.health*40, 10))
def energyBar(self):
pygame.draw.rect(screen, (255, 0, 0), (20, 55, 200, 10))
pygame.draw.rect(screen, (48, 117, 255), (20, 55, weapon.energy*2, 10))
def collidesWithAnything(self):
for wall in walls:
if wall.collidesWith(self):
return True
return False
def update(self):
if self.leftPr and not self.rightPr:
self.x -= self.speed
if self.collidesWithAnything():
self.x += self.speed
if self.rightPr and not self.leftPr:
self.x += self.speed
if self.collidesWithAnything():
self.x -= self.speed
if self.upPr and not self.downPr:
self.y -= self.speed
if self.collidesWithAnything():
self.y += self.speed
# revert if collision
if self.downPr and not self.upPr:
self.y += self.speed
if self.collidesWithAnything():
self.y -= self.speed
# check for enemy colisions
def animations(self):
if self.animationsCount + 1 >= 36:
self.animationsCount = 0
if self.rightPr:
screen.blit(pygame.transform.scale(playerWalkAnimR[self.animationsCount//12],(64, 64)), (width/2 - 40, height/2 - 30))
elif self.leftPr:
screen.blit(pygame.transform.scale(playerWalkAnimL[self.animationsCount//12],(64, 64)), (width/2 - 40, height/2 - 30))
else:
screen.blit(pygame.transform.scale(playerWalkAnimR[0],(64, 64)), (width/2 - 40, height/2 - 30))
self.animationsCount += 1
weapon = Weapon(10, 20, 2)
player = Player(1, 0)
#Loads map from file
def loadMapFromFile(path):
walls.clear()
backgrounds.clear()
enemies.clear()
with open(path, "r") as f:
y = 0
enemyLocations = []
# bossLocations = []
for line in f.readlines():
x = 0
for char in line:
if char != ' ' and char != "\n":
backgrounds.append(Background(x * tileSize, y * tileSize))
if char == '#':
walls.append(Wall(x * tileSize, y * tileSize))
elif char == 'p' or char == 'P':
player.x = x * tileSize
player.y = y * tileSize
elif char == 'e' or char == 'E':
if random.randint(1, 100) <= 40:
enemyLocations.append((x * tileSize, y * tileSize))
# elif char == 'b' or char == 'B':
# if random.randint(1, 100) <= 10:
# bossLocations.append((x * tileSize, y * tileSize, "True"))
x += 1
y += 1
for enemyL in enemyLocations:
enemies.append(slimeEnemy(*enemyL))
# for enemyL in bossLocations:
# enemies.append(slimeEnemy(*enemyL, "True"))
def gameOverScreen():
pygame.font.init()
font = pygame.font.Font('arial.ttf', 32)
text = font.render('GAME OVER', True, (255, 0, 0), (0, 0, 0))
text.set_colorkey((0, 0, 0))
screen.blit(text, (width/2-80,height/2-40))
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
loadMapFromFile('maps/Map0.txt')
hitCooldown = 75
cooldown = 600
#running loop
gameOver = False
running = True
while running:
if gameOver:
gameOverScreen()
pass
else:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
player.upPr = True
if event.key == pygame.K_s:
player.downPr = True
if event.key == pygame.K_d:
player.rightPr = True
if event.key == pygame.K_a:
player.leftPr = True
if event.type == pygame.KEYUP:
if event.key == pygame.K_w:
player.upPr = False
if event.key == pygame.K_s:
player.downPr = False
if event.key == pygame.K_d:
player.rightPr = False
if event.key == pygame.K_a:
player.leftPr = False
if event.type == pygame.MOUSEBUTTONDOWN:
weapon.shooting = True
if event.type == pygame.MOUSEBUTTONUP:
weapon.shooting = False
# updating
camx = player.x - width / 2
camy = player.y - height / 2
screen.fill((0, 0, 0))
player.update()
#check if slime got hit
for bullet in all_bullets:
bullet.update()
for enemy in enemies:
if enemy.collidesWith(player):
if hitCooldown < 0:
hitCooldown = 75
player.health -= enemy.slimeCollisionDmg
if player.health <= 0:
gameOver = True
elif enemy.collidesWith(bullet) and bullet.isPlayer:
removed_bullets.append(bullet)
for i in range(10):
hitParticles.append(Particle(enemy.x, enemy.y, random.randrange(-5, 5)/10, random.randrange(-5, 5)/10, 4, (108, 216, 32)))
enemy.SlimeHp -= weapon.bulletDmg
if enemy.SlimeHp <= 0:
enemy.isAlive = False
if player.health >= player.maxHp:
player.health = player.maxHp
else:
player.health += 1
if weapon.energy >= 100:
weapon.energy = 100
else:
weapon.energy += 2
if bullet.collidesWith(player) and not bullet.isPlayer:
if hitCooldown < 0:
hitCooldown = 75
player.health -= enemy.dmg
if player.health <= 0:
gameOver = True
removed_bullets.append(bullet)
for bg in backgrounds:
bg.draw(camx, camy)
for wall in walls:
wall.draw(camx, camy)
# update all other entities
#draw bullet
for bullet in all_bullets:
bullet.draw(camx, camy)
# slime animations and remove dead slimes
for enemy in enemies:
enemy.update()
if enemy.isAlive:
enemy.drawAlive(camx, camy)
if not enemy.isAlive:
enemies.remove(enemy)
# draw particles
for particle in hitParticles:
if particle.lifetime > 0:
particle.draw(screen, camx, camy)
else:
hitParticles.pop(hitParticles.index(particle))
player.animations()
weapon.handle_weapons(screen)
weapon.Shooting()
player.healthBar()
player.energyBar()
if len(enemies) == 0:
if cooldown <= 0:
cooldown = 600
loadMapFromFile("maps\Map{0}.txt".format(level+1))
level+=1
hitCooldown -= 1
cooldown -= 1
# finally update screen
pygame.display.update()
clock.tick(60)
I know it is written really badly but I'm learning. The game is really laggy and I was wondering how I can make it run faster and smoother. Also is the lag created from the many calculations or am I just dumb? The lag comes when there are a lot of enemies on the map and they shoot at the same time. Can I fix the lag by making all the enemies shoot in different times? The game is for a school project.
I think your biggest issue is this:
class Bullet:
[ ... ]
def update(self):
self.x += self.velx
self.y += self.vely
for bullet in all_bullets: # <-- HERE
for wall in walls:
if bullet.collidesWith(wall):
removed_bullets.append(bullet)
for i in removed_bullets:
if i in all_bullets:
all_bullets.remove(i)
Then in the main loop:
#check if slime got hit
for bullet in all_bullets: # <-- AGAIN
bullet.update()
The code is iterating through the bullets many more times than is necessary. By the time all your bullet objects are updated, they have been processed /N/ * /N/ times (i.e.: N-squared). So as you get more any more bullets, this square grows catastrophically.
Try changing your Bullet.update() to only check itself. This will probably fix your lag issues - or at least help a lot. It will also "correct" your object encapsulation. A single Bullet has no business knowing about all the others, let alone checking collisions on their behalf.
class Bullet:
[ ... ]
def update(self):
self.x += self.velx
self.y += self.vely
for wall in walls:
if self.collidesWith(wall):
all_bullets.remove( self )
break
If you have any more N-squared loops like this, it will give the best speedup reworking them first.
moving object. It currently moves left and right across the screen and I would like the user to be able to jump on it.
def moving_object():
global x_speed, y_speed
pygame.draw.rect(win, (200, 140, 150), rectangle)
rectangle.x += x_speed
if rectangle.right >= 500 or rectangle.left <= 0:
x_speed *= -1
class for my enemy. They currently move left and right across the screen but I would like them to follow the user. They can also not jump
class enemy():
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.WalkCount = 0
self.vel = 3
self.path = [self.x, self.end]
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, 255, 0), (self.hitbox[0], self.hitbox[1] - 20, 50, 10))
self.hitbox = (self.x + 17, self.y + 2, 31, 57)
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
pass
So here is one way to make a pathfinding algorithm:
import pygame
import time
pygame.init()
screen = pygame.display.set_mode((700, 500))
clock = pygame.time.Clock()
to_coords = [550, 100]
from_coords = (150, 400)
def go_to_koeff(from_, to):
dx = to[0] - from_[0]
dy = to[1] - from_[1]
if dx != 0:
dx /= abs(dx)
if dy != 0:
dy /= abs(dy)
return dx, dy
follow_coords_x = from_coords[0]
follow_coords_y = from_coords[1]
velocity = 1
run = True
while run:
clock.tick(60)
screen.fill((0, 0, 0))
pygame.draw.circle(screen, (0, 255, 0), to_coords, 5)
pygame.draw.circle(screen, (255, 0, 0), from_coords, 5)
pygame.draw.circle(screen, (255, 255, 255), (follow_coords_x, follow_coords_y), 5)
koeff = go_to_koeff((follow_coords_x, follow_coords_y), to_coords)
follow_coords_x += velocity * koeff[0]
follow_coords_y += velocity * koeff[1]
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
to_coords[1] -= 3
if keys[pygame.K_DOWN]:
to_coords[1] += 3
if keys[pygame.K_LEFT]:
to_coords[0] -= 3
if keys[pygame.K_RIGHT]:
to_coords[0] += 3
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.display.update()
pygame.quit()
so basically the whole algorithm is that go_to_koeff() function: that function returns the koefficent of direction that can be used to change where the white dot moves that can be seen where the coefficient is multiplied by velocity. This algorithm isn't perfect but it finds the position so there is that. (You can play around a bit by moving the green dot with arrow keys to see how it moves)
Another idea that came to mind was tracking player position in a list and making the enemy follow all the coords in the list which could be even worse but it will feel like it is actually following You.
Also I just noticed that there is some useless change of variable names, but it doesn't affect anything much.
So I am currently making a game where the hotdog shoots bullets that should damage the Enemy. But after the bullet-enemy collision, The red healthbar that signifies its health does not shrink at all. Any tips on how to fix this? Thanks in advance.
import pygame
import random
import math
# Screen parameters
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("SPPACCE")
bg = pygame.image.load("bg.png")
font = pygame.font.SysFont('comicsans', 30, True)
clock = pygame.time.Clock()
score = 0
# Player parameters
class Player(object):
def __init__(self, x, y, height, width):
self.x = x
self.y = y
self.height = height
self.width = width
self.player_vel = 5
def draw(self, screen):
screen.blit(player_char, (self.x, self.y))
# Enemy parameters
class Enemy(object):
def __init__(self, x, y, height, width, end):
self.x = x
self.y = y
self.height = height
self.width = width
self.enemy_vel = 1.5
self.end = end
self.path = [self.x, self.end]
self.hitbox = (self.x + 17, self.y + 2, 65, 65)
self.health = 10
self.visible = True
def draw(self, screen):
self.move()
if self.visible:
self.hitbox = (self.x + 0, self.y, 65, 65)
pygame.draw.rect(screen, (255, 0, 0), self.hitbox, 2)
screen.blit(enemy_char, (self.x, self.y))
# Health bars
pygame.draw.rect(screen, (0, 0, 0), (self.hitbox[0], self.hitbox[1] - 20, 65, 10))
pygame.draw.rect(screen, (255, 0, 0), (self.hitbox[0], self.hitbox[1] - 20, 65 - (6.5 * (10 - self.health)), 10))
def move(self):
if self.enemy_vel > 0:
if self.x < self.path[1] + self.enemy_vel:
self.x += self.enemy_vel
else:
self.enemy_vel = self.enemy_vel * -1
self.x += self.enemy_vel
else:
if self.x > self.path[0] - self.enemy_vel:
self.x += self.enemy_vel
else:
self.enemy_vel = self.enemy_vel * -1
self.x += self.enemy_vel
def hit(self):
if self.health > 0:
self.health -= 1
else:
self.visible = False
# Player Projectile parameters
class Projectile(object):
def __init__(self, x, y, color, radius):
self.x = x
self.y = y
self.color = color
self.radius = radius
self.vel = 12.5
def draw(self, screen):
pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius)
# Images
player_char = pygame.image.load('sprites/hotdog.png')
enemy_char = pygame.image.load('sprites/hamburger.png')
def blit(): # This draws the sprites
player.draw(screen)
enemy.draw(screen)
for projectile in projectiles:
projectile.draw(screen)
score_text = font.render("Score: " + str(score), 1, (0, 109, 255))
version = font.render("Version 01 ", 1, (51, 153, 255))
screen.blit(score_text, (0, 0))
screen.blit(version, (520, 0))
shootloop = 0
if shootloop > 0:
shootloop += 1
if shootloop > 2:
shootloop = 0
player = Player(300, 400, 64, 64)
enemy = Enemy(random.randint(10, 100), random.randint(20, 100), 64, 64, 480)
projectiles = []
run = True
while run:
clock.tick(60)
screen.fill((0, 0, 0))
screen.blit(bg, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# Movement keys with playeborders
keys = pygame.key.get_pressed()
if keys[pygame.K_s] and player.y < 480 - player.height - player.player_vel:
player.y += player.player_vel
if keys[pygame.K_w] and player.y > 280:
player.y -= player.player_vel
if keys[pygame.K_d] and player.x < 640 - player.width - player.player_vel:
player.x += player.player_vel
if keys[pygame.K_a] and player.x > player.player_vel:
player.x -= player.player_vel
for projectile in projectiles:
if projectile.y - projectile.radius < enemy.hitbox[1] + enemy.hitbox[3] and projectile.y + projectile.radius > enemy.hitbox[1]:
if projectile.x + projectile.radius > enemy.hitbox[0] and projectile.x - projectile.radius < enemy.hitbox[0] + enemy.hitbox[2]:
score += 1
projectiles.pop(projectiles.index(projectile))
if projectile.y < 640 and projectile.y > 0:
enemy.hit
projectile.y -= projectile.vel
else:
projectiles.pop(projectiles.index(projectile))
# Player shooting
if keys[pygame.K_SPACE] and shootloop == 0:
if len(projectiles) < 1:
projectiles.append(Projectile(round(player.x + player.width //2),
round(player.y + player.height //2), [255, 150, 0], 7))
blit()
pygame.display.update()
I followed TechwithTim's tutorial by the way. Also, I think this is enough to run the code.
There are two issues with your code. The first, as #Apple points out, is that you are not correctly calling enemy.hit().
The other issue is that the enemy.hit() is not being called in the correct spot. It needs to be called after the collision is detected, and the existing code has it where the projectile moves up:
for projectile in projectiles:
if projectile.y - projectile.radius < enemy.hitbox[1] + enemy.hitbox[3] and projectile.y + projectile.radius > enemy.hitbox[1]:
if projectile.x + projectile.radius > enemy.hitbox[0] and projectile.x - projectile.radius < enemy.hitbox[0] + enemy.hitbox[2]:
score += 1
projectiles.pop(projectiles.index(projectile))
if projectile.y < 640 and projectile.y > 0:
enemy.hit # <<-- HERE
projectile.y -= projectile.vel
else:
projectiles.pop(projectiles.index(projectile))
If you change it to apply the hit() when the projectile collides, it seems to work as desired:
for projectile in projectiles:
if projectile.y - projectile.radius < enemy.hitbox[1] + enemy.hitbox[3] and projectile.y + projectile.radius > enemy.hitbox[1]:
if projectile.x + projectile.radius > enemy.hitbox[0] and projectile.x - projectile.radius < enemy.hitbox[0] + enemy.hitbox[2]:
# Enemy was hit by the projectile
score += 1
enemy.hit() # <<-- HERE
projectiles.pop(projectiles.index(projectile))
if projectile.y < 640 and projectile.y > 0:
# move the projectile up
projectile.y -= projectile.vel
else:
# projectile went off-screen
projectiles.pop(projectiles.index(projectile))
Please don't forget to add comments to your code, they really really help.
I don't know if it's the only issue, but you are missing a set of parentheses when you are attempting to call the hit method:
enemy.hit
Should be
enemy.hit()
This question already has answers here:
how to make image/images disappear in pygame?
(1 answer)
Do not display removed sprites, Pygame
(1 answer)
Closed 2 years ago.
So the problem is an trying to get my sprite to disappear once the health bar goes 0 but I can’t seem to that the most I can do is make him invisible but I am trying to delete my sprite not make it invisible
import pygame import sys
pygame.init()#We always need to initalize 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("Dragon Ball Z Mini-game")#We are giving our Window/Screen a name
walkRight = [pygame.image.load('image/young_goku_right_image0 - t.png'), pygame.image.load('image/young_goku_right_image1 - t.png'), pygame.image.load('image/young_goku_right_image2 - t.png'), pygame.image.load('image/young_goku_right_image3 - t.png'), pygame.image.load('image/young_goku_right_image4 - t.png')] walkLeft = [pygame.image.load('image/young_goku_left_image0 - t.png'), pygame.image.load('image/young_goku_left_image1 - t.png'), pygame.image.load('image/young_goku_left_image2 - t.png'), pygame.image.load('image/young_goku_left_image3 - t.png'), pygame.image.load('image/young_goku_left_image4 - t.png')] bg = pygame.image.load('image/bg2.jpg') char = pygame.image.load('image/young_goku - standing - t.png')
clock = pygame.time.Clock()
bulletSound = pygame.mixer.Sound("image/kiblast.wav") hitSound = pygame.mixer.Sound("image/Bomb+1.wav")
#bulletSound.play() music = pygame.mixer.music.load("image/Dragon Ball Z - Rock The Dragon.mp3") pygame.mixer.music.play(-1)
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):
font2 = pygame.font.SysFont("Papyrus", 45)
text2 = font2.render("DBZ Adventure!", 1, (255, 50, 25))
win.blit(text2, (120 - (text2.get_width() / 2), 15))
#pygame.display.flip()
if self.walkCount + 1 >= 10:
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)
if keys[pygame.K_a]:
if self.left:
ki_stance_left = pygame.image.load("image/goku-ki_left.png")
win.blit(ki_stance_left, (self.x, self.y))
elif self.right:
ki_stance = pygame.image.load("image/goku-ki.png")
win.blit(ki_stance, (self.x, self.y))
if keys[pygame.K_SPACE]:
if self.left:#needed to put self.left and self the right
ki_stance_left = pygame.image.load("image/goku-ki_left.png")
win.blit(ki_stance_left, (self.x, self.y))
elif self.right:
ki_stance = pygame.image.load("image/goku-ki.png")
win.blit(ki_stance, (self.x, self.y))
pygame.display.flip()
def hit(self):
self.isJump = False
self.jumpCount = 10
self.x = 100
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):
ki = pygame.image.load("image/ki.png")
win.blit(ki, (self.x, self.y))
ki_stance = pygame.image.load("image/goku-ki.png")
win.blit(ki, (self.x, self.y))
pygame.draw.circle(win, (255,255,0), (self.x, self.y), self.radius) """ def draw2(self, win):
ki2 = pygame.image.load("image/b4.png")
win.blit(ki2, (self.x, self.y))
ki_stance = pygame.image.load("image/goku-ki.png")
win.blit(ki2, (self.x, self.y))
pygame.draw.rect(win, (255, 255, 0), (self.x, self.y), self.radius) """
class projectile2(): 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):
ki = pygame.image.load("image/b4.png")
win.blit(ki, (self.x, self.y))
ki_stance = pygame.image.load("image/goku-ki.png")
win.blit(ki, (self.x, self.y))
#pygame.draw.circle(win, (0,0,139), (self.x, self.y), self.radius)
class enemy(object): 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
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
Here’s where I can keep on trying to delete my sprite but it does not seem to work? The most I can do is just make it invisible but it does not go away permanently.
def hit(self):
hit = enemy
if self.health > 0:
self.health -= 1
else:
self.visible = False
font2 = pygame.font.SysFont("Papyrus", 45)
text2 = font2.render("You won!", 5, (45, 50, 45))
win.blit(text2, (95 - (text2.get_width() / 3), 45))
pygame.display.flip()
print('hit')
class enemy2(): walkRight = [pygame.image.load("image/enemy-sprite-standing-T.gif"), pygame.image.load("image/enemy-sprite-moving_T.gif"), pygame.image.load("image/enemy-sprite-moving_T.gif"), pygame.image.load("image/enemy-sprite-move_right-T.gif")] walkLeft = [pygame.image.load("image/enemy-sprite-standing-T.gif"), pygame.image.load("image/enemy-sprite - moving_left-T.gif"), pygame.image.load("image/enemy-sprite - moving_left-T.gif"), pygame.image.load("image/enemy-sprite - moving_left2-T.gif")] 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 + 20, self.y, 28, 60)
self.health = 10
self.visible = True
def draw(self, win):
self.move()
if self.visible:
if self.walkcount + 0 >= 10:
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 + 20, self.y, 28, 60)
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
self.visible = False
font2 = pygame.font.SysFont("Papyrus", 45)
text2 = font2.render("You won!", 5, (45, 50, 45))
win.blit(text2, (95 - (text2.get_width() / 3), 45))
pygame.display.flip()
print("Hit!!")
pass
def redrawGameWindow(): win.blit(bg, (0, 0)) text = font.render('Score: ' + str(score), 1, (0, 0, 0)) win.blit(text, (390, 5)) man.draw(win) goblin.draw(win) goblin2.draw(win) for bullet in bullets:
bullet.draw(win)
pygame.display.update()
# mainloop font = pygame.font.SysFont("comicsans", 30, True, True) man = player(200, 420, 64, 64) goblin = enemy(50, 410, 64, 64, 450) goblin2 = enemy2(250, 410, 64, 64, 450) shootloop = 0 bullets = [] run
= True while run: clock.tick(27) if goblin.visible == True:
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
print("Hurt")
if goblin2.visible == True:
if man.hitbox[1] < goblin2.hitbox[1] + goblin2.hitbox[3] and man.hitbox[1] + man.hitbox[3] > goblin2.hitbox[1]:
if man.hitbox[0] + man.hitbox[2] > goblin2.hitbox[0] and man.hitbox[0] < goblin2.hitbox[0] + goblin2.hitbox[2]:
man.hit()
score -= 5
print("Hurt")
if shootloop > 0:
shootloop += 1 if shootloop > 3:
shootloop = 0
for event in pygame.event.get():
if event.type == pygame.QUIT:
#pygame.quit()
sys.exit()
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]:
#hitSound.play()
goblin.hit()
score += 1
#bullets.pop(bullets.index(bullet))
for bullet in bullets:
if bullet.y - bullet.radius < goblin2.hitbox[1] + goblin2.hitbox[3] and bullet.y + bullet.radius > goblin2.hitbox[1]:
if bullet.x + bullet.radius > goblin2.hitbox[0] and bullet.x - bullet.radius < goblin2.hitbox[0] + goblin2.hitbox[2]:
#hitSound.play()
goblin2.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:
bulletSound.play()
if man.left:
facing = -1
else:
facing = 1
if len(bullets) < 5:
bullets.append(projectile(round(man.x + man.width // 3), round(man.y + man.height // 3), 6, (0, 0, 0), facing))
shootloop = 1
if keys[pygame.K_a] and shootloop == 0:
bulletSound.play()
if man.left:
facing = -1
else:
facing = 1
if len(bullets) < 5:
bullets.append(projectile2(round(man.x + man.width // 3), round(man.y + man.height // 3), 12, (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()
In order to move a created image off of the screen you can do either one of the following solutions.
1. Move the image off of the screen.
An example of moving a sprite off of a screen is as follows:
someImg = pygame.image.load("coolWater.png")
screen.blit(someImg, (int(someXValueOffScreen), int(someYValueOffScreen))
2. Make the image transparent
Here's an example of this:
someImg = pygame.image.load("coolWater.png")
someImg.image.fill((0,0,0,0)) #Makes the image transparent. The last parameter is the alpha value. An alpha value of 0 makes it transparent. The first 3 zeros is the RGB value
Quick note: You should format your code in this post correctly with encapsulating your code with these three characters " ``` ".
I am making a little game with a car which the playe moves and cars will be coming down and you have to dodge them. For some reason collision is always true and I can't figure it out. I tried reformatting the Rect's and making that whole system better but that doesn't seem to work. The Rect values are in the player class and the car class. Thanks.
import time, pygame, random
import math
pygame.init()
#First Variables
BLACK = (0, 0, 0)
BLUE = (0, 0, 255)
GREEN = (100, 255, 100)
ORANGE = (255, 140, 0)
YELLOW = (155, 135, 12)
white = (255, 255, 255)
GOLD = (255, 215, 0)
screenwidth = 500
screenheight = 500
Lines = True
Space = True
color = random.sample(range(250), 3)
doris = []
i = []
x = 247
y = - 20
y1 = 40
y2 = 100
y3 = 160
y4 = 220
y5 = 280
y6 = 340
y7 = 400
y8 = 460
#Display and caption
win = pygame.display.set_mode((screenwidth, screenheight))
pygame.display.set_caption('Lil cary')
clock = pygame.time.Clock()
#Load in images
bkg = pygame.image.load('BG.jpg')
#Actual player class
class player():
def __init__(self):
self.x = 200
self.y = 390
self.width = 50
self.height = 100
self.color = (12, 124, 134)
self.vel = 5
self.grassdamage = 0
self.image = pygame.Surface([self.width, self.height], pygame.SRCALPHA, 32)
pygame.draw.rect(self.image, (self.color), (0, 0, self.width, self.height))
self.rect = self.image.get_rect()
self.damage1 = False
self.damage2 = False
self.damage3 = False
self.damage4 = False
self.damage5 = False
self.damage6 = False
self.damage7 = False
self.damage8 = False
self.dead = False
def draw (self, win):
#pygame.draw.rect(win, (self.color), (self.x, self.y, self.width, self.height))
win.blit(self.image, [self.x, self.y])
def moveback(self):
if self.y < 390 and self.y >= 0:
self.y += 10
def grass(self):
if player.x > -10 and player.x < 150:
self.grassdamage += 1
self.vel = 3
elif player.x > 300 and player.x < 500:
self.vel =3
self.grassdamage += 1
else:
self.vel = 5
def grasshealth(self):
if self.grassdamage == 100:
self.damage1 = True
print ("First bar filled ")
elif self.grassdamage == 200:
self.damage2 = True
print ("doing this")
elif self.grassdamage == 300:
self.damage3 = True
elif self.grassdamage == 400:
self.damage4 = True
elif self.grassdamage == 500:
self.damage5 = True
elif self.grassdamage == 600:
self.damage6 = True
elif self.grassdamage == 600:
self.damage6 = True
elif self.grassdamage == 700:
self.damage7 = True
elif self.grassdamage == 800:
self.damage8 = True
self.dead = True
def death(self):
if self.dead == True:
exit()
#Text Setup
def text_objects(text, font):
textSurface = font.render(text, True, BLACK)
return textSurface, textSurface.get_rect()
#Drawing damage bar
def drawbar ():
if player.damage1 == True:
pygame.draw.rect(win, (GOLD), (50, 50, 25, 25))
if player.damage2 == True:
pygame.draw.rect(win, (GOLD), (50, 75, 25, 25))
if player.damage3 == True:
pygame.draw.rect(win, (GOLD), (50, 100, 25, 25))
if player.damage4 == True:
pygame.draw.rect(win, (GOLD), (50, 125, 25, 25))
if player.damage5 == True:
pygame.draw.rect(win, (GOLD), (50, 150, 25, 25))
if player.damage6 == True:
pygame.draw.rect(win, (GOLD), (50, 175, 25, 25))
if player.damage7 == True:
pygame.draw.rect(win, (GOLD), (50, 200, 25, 25))
if player.damage8 == True:
pygame.draw.rect(win, (GOLD), (50, 225, 25, 25))
pygame.draw.rect(win, (0,0,0), (50, 50, 25, 200), 3)
Text = pygame.font.Font('freesansbold.ttf', 20)
TextSurf, TextRect = text_objects("Damage", Text)
TextRect.center = ((65), (30))
win.blit(TextSurf, TextRect)
#Seting up the cars class
class car():
def __init__(self):
self.x = 175
self.y = -100
self.width = 50
self.height = 100
self.color = random.sample(range(250), 3)
self.image = pygame.Surface([self.width, self.height], pygame.SRCALPHA, 32)
pygame.draw.rect(self.image, (self.color), (0, 0, self.width, self.height))
self.rect = self.image.get_rect()
self.carvel = random.randrange(5, 10)
def draw(self, win):
#pygame.draw.rect(win,(self.color),self.rect)
win.blit(self.image, (self.x,self.y))
def move(self):
if self.y < 530:
self.y += self.carvel
else:
self.y = -100
self.color = random.sample(range(250), 3)
print(self.color)
self.carvel = random.randrange(6, 10)
def collision_check(self, another_object):
if self.rect.colliderect(another_object):
print('collison')
#Putting variables to the classes
player = player()
car = car()
#Main drawing function
def redrawgamewindow():
win.blit(bkg, (0, 0))
pygame.draw.rect(win, (0, 0, 0), (150, 0, 200, 500))
pygame.draw.rect(win, (255, 255, 255), (x, (y), 10, 30))
pygame.draw.rect(win, (255, 255, 255), (x, (y1), 10, 30))
pygame.draw.rect(win, (255, 255, 255), (x, (y2), 10, 30))
pygame.draw.rect(win, (255, 255, 255), (x, (y3), 10, 30))
pygame.draw.rect(win, (255, 255, 255), (x, (y4), 10, 30))
pygame.draw.rect(win, (255, 255, 255), (x, (y5), 10, 30))
pygame.draw.rect(win, (255, 255, 255), (x, (y6), 10, 30))
pygame.draw.rect(win, (255, 255, 255), (x, (y7), 10, 30))
pygame.draw.rect(win, (255, 255, 255), (x, (y8), 10, 30))
player.draw(win)
car.draw(win)
drawbar()
pygame.display.update()
#MAINLOOP
run = True
while run:
#Making background and FPS
clock.tick(80)
#Quiting Funciton
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
#Scrolling the lines
if Lines:
y += player.vel
y1 += player.vel
y2 += player.vel
y3 += player.vel
y4 += player.vel
y5 += player.vel
y6 += player.vel
y7 += player.vel
y8 += player.vel
if Lines:
if y >= 500:
y = -40
if y1 >= 500:
y1 = -40
if y2 >= 500:
y2 = -40
if y3 >= 500:
y3 = -40
if y4 >= 500:
y4 = -40
if y5 >= 500:
y5 = -40
if y6 >= 500:
y6 = -40
if y7 >= 500:
y7 = -40
if y8 >= 500:
y8 = -40
#User input
keys = pygame.key.get_pressed()
#Boost controller
if keys[pygame.K_SPACE]:
start_time = time.time()
if player.y > 200:
player.y -= 9
Space = True
else:
player.moveback()
end_time = time.time()
#Left movement
if keys[pygame.K_LEFT] and player.x > 150:
player.x -= 5
if keys [pygame.K_LEFT] and player.x <= 150:
if player.x > 0:
player.x -=5
#Right movement
if keys[pygame.K_RIGHT] and player.x < 300:
player.x += 5
if keys[pygame.K_RIGHT]and player.x >= 300:
if player.x < 500 - player.width:
player.x += 5
#Car reset
#Grass and grass damage
player.grass()
player.grasshealth()
player.death()
car.collision_check(player.rect)
car.move()
#MAIN DRAW RECALL
redrawgamewindow()
self.rect.x and self.rect.y is never set and constantly stays 0. Delete self.x, self.y, self.width and self.height and use the attributes of the pygame.Rect object (self.rect.x, self.rect.y, and self.rect.widht and self.rect.height) instead.
In class player:
class player():
def __init__(self):
self.color = (12, 124, 134)
self.vel = 5
self.grassdamage = 0
self.image = pygame.Surface([50, 100], pygame.SRCALPHA, 32)
pygame.draw.rect(self.image, (self.color), (0, 0, 50, 100))
self.rect = self.image.get_rect(center = (200, 390))
self.damage1 = False
self.damage2 = False
self.damage3 = False
self.damage4 = False
self.damage5 = False
self.damage6 = False
self.damage7 = False
self.damage8 = False
self.dead = False
def draw (self, win):
#pygame.draw.rect(win, (self.color), (self.x, self.y, self.width, self.height))
win.blit(self.image, self.rect.topleft)
def moveback(self):
if self.rect.y < 390 and self.rect.y >= 0:
self.rect.y += 10
def grass(self):
if self.rect.x > -10 and self.rect.x < 150:
self.grassdamage += 1
self.vel = 3
elif self.rect.x > 300 and self.rect.x < 500:
self.vel =3
self.grassdamage += 1
else:
self.vel = 5
# [...]
In class car:
class car():
def __init__(self):
self.color = random.sample(range(250), 3)
self.image = pygame.Surface([50, 100], pygame.SRCALPHA, 32)
pygame.draw.rect(self.image, (self.color), (0, 0, 50, 100))
self.rect = self.image.get_rect(topleft = (175, -100))
self.carvel = random.randrange(5, 10)
def draw(self, win):
#pygame.draw.rect(win,(self.color),self.rect)
win.blit(self.image, self.rect.topleft)
def move(self):
if self.rect.y < 530:
self.rect.y += self.carvel
else:
self.rect.y = -100
self.color = random.sample(range(250), 3)
print(self.color)
self.carvel = random.randrange(6, 10)
def collision_check(self, another_object):
if self.rect.colliderect(another_object):
print('collison')
And in the main application loop:
run = True
while run:
# [...]
#User input
keys = pygame.key.get_pressed()
#Boost controller
if keys[pygame.K_SPACE]:
start_time = time.time()
if player.rect.y > 200:
player.rect.y -= 9
Space = True
else:
player.moveback()
end_time = time.time()
#Left movement
if keys[pygame.K_LEFT] and player.rect.x > 150:
player.rect.x -= 5
if keys [pygame.K_LEFT] and player.rect.x <= 150:
if player.rect.x > 0:
player.rect.x -=5
#Right movement
if keys[pygame.K_RIGHT] and player.rect.x < 300:
player.rect.x += 5
if keys[pygame.K_RIGHT]and player.rect.x >= 300:
if player.rect.rect.x < 500 - player.rect.width:
player.rect.x += 5
# [...]