Rect value not updating x postition? - python

I'm creating a game with cars coming at you. I want the cars to change x_pos every time they go off the screen, but for some reason the value changes but the cars don't actually move. I don't know how to fix this and was wondering if there's something I have to do to make it change. If you want to test my code just remove the background and everything else will work. 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)
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.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
self.score = 0
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
def grasshealth(self):
if self.grassdamage == 100:
self.damage1 = True
elif self.grassdamage == 200:
self.damage2 = True
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:
raise SystemExit ('YOU MOFO DIED')
def scorecount (self):
if self.score >= 15:
raise SystemExit ('YOU WIN OMG KIDS')
def scoredraw(self):
Text = pygame.font.Font('freesansbold.ttf', 25)
TextSurf, TextRect1 = text_objects("Score: " + str(self.score), Text)
TextRect1.center = ((50), (450))
win.blit(TextSurf, TextRect1)
#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 and car.damage1 == False or car.damage1 == True:
pygame.draw.rect(win, (GOLD), (50, 50, 25, 25))
if player.damage2 == True and car.damage1 == False or car.damage1 == True:
pygame.draw.rect(win, (GOLD), (50, 75, 25, 25))
if car.damage1 == True and player.grassdamage <= 200:
player.grassdamage = 201
if player.damage3 == True and car.damage2 == False or car.damage2 == True:
pygame.draw.rect(win, (GOLD), (50, 100, 25, 25))
if player.damage4 == True and car.damage2 == False or car.damage2 == True:
pygame.draw.rect(win, (GOLD), (50, 125, 25, 25))
if car.damage2 == True and player.grassdamage <= 400:
player.grassdamage = 401
if player.damage5 == True and car.damage3 == False or car.damage3 == True:
pygame.draw.rect(win, (GOLD), (50, 150, 25, 25))
if player.damage6 == True and car.damage3 == False or car.damage3 == True:
pygame.draw.rect(win, (GOLD), (50, 175, 25, 25))
if car.damage3 == True and player.grassdamage <= 600:
player.grassdamage = 601
if player.damage7 == True and car.damage4 == False or car.damage4 == True:
pygame.draw.rect(win, (GOLD), (50, 200, 25, 25))
if player.damage8 == True and car.damage4 == False or car.damage4 == True:
pygame.draw.rect(win, (GOLD), (50, 225, 25, 25))
raise SystemExit ('YOU LOST')
if car.damage4 == True and player.grassdamage <= 800:
player.grassdamage = 800
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)
class car1():
ROAD_LEFT = 175
ROAD_RIGHT = 300
def __init__(self):
self.x_pos = random.randrange(car1.ROAD_LEFT, car1.ROAD_RIGHT)
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 = (self.x_pos, -100))
self.carvel = random.randrange(8, 10)
self.damage = 0
self.damage1 = False
self.damage2 = False
self.damage3 = False
self.damage4 = False
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
player.score += 1
self.color = random.sample(range(250), 3)
self.carvel = random.randrange(6, 8)
self.x_pos = random.randrange(car1.ROAD_LEFT, car1.ROAD_RIGHT)
def collision_check(self, another_object):
if self.rect.colliderect(another_object):
print('collison')
self.rect.y = -100
self.damage += 1
def cardamage(self):
if self.damage == 1:
self.damage1 = True
player.damage1 = True
player.damage2 = True
if self.damage == 2:
self.damage2 = True
player.damage3 = True
player.damage4 = True
if self.damage == 3:
self.damage3 = True
player.damage5 = True
player.damage6 = True
if self.damage == 4:
self.damage4 = True
player.damage7 = True
player.damage8 = True
#Putting variables to the classes
player = player()
car = car1()
car_list = [ car ] # start with one car
car_add_time = 0
#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)
for car in car_list:
car.draw(win)
player.grasshealth()
for car in car_list:
car.cardamage()
player.grass()
player.death()
for car in car_list:
car.collision_check(player.rect)
car.move()
drawbar()
player.scorecount()
player.scoredraw()
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
time_now = pygame.time.get_ticks()
if (time_now - car_add_time > 5000):
new_car = car1()
car_list.append(new_car)
car_add_time = time_now
#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.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.x < 500 - player.rect.width:
player.rect.x += 5
#Grass and grass damage
#MAIN DRAW RECALL
redrawgamewindow()

It is not sufficient to set a random value to self.x_pos. For drawing the "car" the position of the pygame.Rect object self.rect is used:
def draw(self, win):
win.blit(self.image, self.rect.topleft)
So you've to change self.rect.x, too:
class car1():
# [...]
def move(self):
if self.rect.y < 530:
self.rect.y += self.carvel
else:
self.rect.y = -100
player.score += 1
self.color = random.sample(range(250), 3)
self.carvel = random.randrange(6, 8)
self.x_pos = random.randrange(car1.ROAD_LEFT, car1.ROAD_RIGHT)
self.rect.x = self.x_pos # <---------------------------------------

Related

Pygame program stopping/crashing without any error logged

As a beginner im trying to create flappy bird to learn the basics of python and pygame. But when i run this code and click the button that is created the code just stops and python becomes not responsive. Does any one know why?
import pygame
import math
import random
import pyautogui as pg
pygame.init()
screenWidth, screenHeight = pg.size()
gameDisplay = pygame.display.set_mode((screenWidth, screenHeight), pygame.FULLSCREEN)
pygame.display.set_caption("Flappy by Tallik")
time = pygame.time.Clock()
crashed = False
bg = (0, 0, 0)
textSize = 32
font = pygame.font.Font("freesansbold.ttf", textSize)
buttonClicked = [0, 0]
mainGame = False
titleScreen = True
settings = False
changeBird = False
dead = False
phase = 1
def buttonFunc(x, y, width, height, color1, color2, text, textColor, textColor2, buttonNum, dissaperance):
global buttonClicked
mouseClick = pygame.mouse.get_pressed()
mouseX, mouseY = pygame.mouse.get_pos()
buttonText = font.render(str(text), True, textColor)
buttonText2 = font.render(str(text), True, textColor2)
textX = x + 10
textY = y + (height//3)
buttonClicked = [0, buttonNum]
if mouseX >= x and mouseX <= x + width and mouseY >= y and mouseY <= y + height:
pygame.draw.rect(gameDisplay, (color2), (x, y, width, height))
gameDisplay.blit(buttonText2, (textX, textY))
if mouseClick[0] == True:
buttonClicked[0] = 1
if dissaperance == False:
pygame.draw.rect(gameDisplay, (color2), (x, y, width, height))
gameDisplay.blit(buttonText2, (textX, textY))
buttonClicked[0] = 1
else:
gameDisplay.fill(bg)
else:
pygame.draw.rect(gameDisplay, (color1), (x, y, width, height))
gameDisplay.blit(buttonText, (textX, textY))
class bird(object):
def __init__(self, birdVelMultiplier, skin, width, height):
self.birdVelMultiplier = birdVelMultiplier
self.skin = skin
self.grav = -1
self.height = height
self.width = width
self.y = screenHeight//2
self.x = screenWidth//30
self.vel = screenHeight//100
self.jumps = 0
self.minVel = -20
self.maxVel = 20
def jump(self):
if keys[pygame.K_SPACE] and self.jumps == 0:
self.vel = -15
self.jumps += 1
if keys[pygame.K_UP] and self.jumps == 0:
self.vel = -15
self.jumps += 1
if not keys[pygame.K_UP] and not keys[pygame.K_SPACE]:
self.jumps = 0
def drawToGame(self, gameDisplay):
if self.y + self.height <= screenHeight:
if self.y >= 0:
if self.vel < self.maxVel and self.vel > self.minVel:
self.vel -= self.grav
self.y += self.vel
else:
if abs(self.vel)/self.vel == 1:
self.vel = self.maxVel
self.vel -= self.grav
self.y += self.vel
else:
self.vel = self.minVel
self.vel -= self.grav
self.y += self.vel
else:
self.y = 0
self.vel = 1
else:
self.y = screenHeight//2
self.vel = 0
pygame.draw.rect(gameDisplay, (0, 0, 255), (self.x, self.y, self.width, self.height))
class obstacle(object):
def __init__(self, speedMultiplier, width):
self.speedMultiplier = speedMultiplier
self.width = width
self.ranHeight = random.randrange(50, screenHeight - (screenHeight//16)*4)
self.ranHeight2 = (screenHeight - self.ranHeight) - 150
def spawn(self):
print(1)
def drawToSurface(self, gameDisplay):
print(3)
bird1 = bird(1, 1, 60, 60)
pipe = obstacle(1, 130)
sB = bird1
while not crashed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
gameDisplay.fill(bg)
keys = pygame.key.get_pressed()
if buttonClicked == [1, 1]:
phase = 4
if phase == 1:
buttonFunc(screenWidth//2, screenHeight//4, screenWidth//18, screenHeight//20, (115, 115, 115), (85, 85, 85), "Start!", (0, 0, 0), (0, 0, 0), 1, True)
elif phase == 2:
print("?")
elif phase == 3:
print("??")
elif phase == 4:
while dead == False:
sB.jump()
sB.drawToGame(gameDisplay)
pygame.display.update()
time.tick(30)
pygame.quit()
quit()
To specify: after i have pressed the button created by buttFunc and the phase variable gets to 4 the program just stops and no eroor message is recieved. Also when closing the program the IDLE shell says the program is still running. I posted all the code because i dont know what made it break.
The program does not "crash", you just have an infinite loop. You do not need a loop that controls the game in the application loop. The application loop is continuously executed. Remove while dead == False::
while not crashed and not dead:
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
gameDisplay.fill(bg)
keys = pygame.key.get_pressed()
if buttonClicked == [1, 1]:
phase = 4
if phase == 1:
buttonFunc(screenWidth//2, screenHeight//4, screenWidth//18, screenHeight//20, (115, 115, 115), (85, 85, 85), "Start!", (0, 0, 0), (0, 0, 0), 1, True)
elif phase == 2:
print("?")
elif phase == 3:
print("??")
elif phase == 4:
sB.jump()
sB.drawToGame(gameDisplay)
pygame.display.update()
time.tick(30)

How to make my cannon fire continuously in pygame

In my game I can place a cannon on user player's location. I'm able to make the cannon fire once but can't make it repeat the firing process multiple times. I want the bullet to be reset at its original value after it travels a certain distance and repeat the firing process. I'm attaching my whole code below along with the part that places the cannon. Thank you for your help.
import pygame
import random
import math
pygame.font.init()
width = 900
height = 600
screen = pygame.display.set_mode([width, height])
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')]
char = pygame.image.load('standing.png')
bomb_pic = pygame.transform.scale(pygame.image.load('bomb.png'), (20, 20))
bomb_explosion = pygame.transform.scale(pygame.image.load('explosion1.png'), (40, 40))
pics = [bomb_pic, bomb_explosion]
shop = pygame.transform.scale(pygame.image.load("shop.png"), (60, 60))
boss = pygame.image.load("enemyboss.png")
player = [walkLeft, walkRight, char]
enemy_Left = [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')]
enemy_pic = pygame.image.load('L1E.png')
boss = pygame.image.load('pixel_monster.png')
cannon = pygame.image.load('tank_cannon.png')
bullet = pygame.image.load('bullet.png')
position = [60, 60]
x = 50 # same as position
y = 50 # same as position
width = 40
height = 60
vel = 5
isJump = False
jumpCount = 10
left = False
right = False
down = False
up = False
walkCount = 0
run_once = False
enemy_list = []
clock = pygame.time.Clock()
FPS = 60
font = pygame.font.Font('freesansbold.ttf', 32)
font_large = pygame.font.Font('freesansbold.ttf', 45)
items_font = pygame.font.Font('freesansbold.ttf', 16)
font_small = pygame.font.Font('freesansbold.ttf', 18)
font_tiny = pygame.font.Font('freesansbold.ttf', 13)
font_verytiny =pygame.font.Font('freesansbold.ttf', 9)
bombs = []
explosions = []
bag = {'bomb': 0, 'heal': 0, 'cannon': 0}
health = 100
base_health = 150
normal_enemies = []
kills = 0
cannon_list = []
bullet_list = []
class Button():
def __init__(self, color, x, y, width, height, text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self, win, outline=None):
# Call this method to draw the button on the screen
if outline:
pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)
pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)
if self.text != '':
font = pygame.font.SysFont('comicsans', 20)
text = font.render(self.text, 1, (0, 0, 0))
win.blit(text, (
self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))
def shop_run():
bright_green = (0, 255, 0)
green = (0, 200, 0)
shop_bomb = Button((0, 200, 0), 820, 150, 70, 20, text="Bomb_b")
shop_bomb.draw(screen)
shop_heal = Button((0, 200, 0), 820, 120, 70, 20, text="Heal_h")
shop_heal.draw(screen)
shop_cannon = Button((0, 200, 0), 820, 180, 70, 20, text="Cannon_c")
shop_cannon.draw(screen)
def walk():
global walkCount
global walkcount
if walkCount + 1 >= 27:
walkCount = 0
if left:
screen.blit(player[0][walkCount // 3], (x, y))
walkCount += 1
elif right:
screen.blit(player[1][walkCount // 3], (x, y))
walkCount += 1
elif down:
screen.blit(player[2], (x, y))
walkcount = 0
elif up:
screen.blit(player[2], (x, y))
walkcount = 0
else:
screen.blit(player[2], (x, y))
walkCount = 0
def enemy_spawn(number_of_enemies):
global normal_enemies
global health
global base_health
global kills
# for random_velocity in range(number_of_enemies):
player_rect = pygame.Rect(x+20, y+20, 20, 20)
for ne in range(number_of_enemies):
random_velocity = random.uniform(0.3, 1.3)
random_enemy_location_y = random.randrange(170, 470)
random_enemy_location_x = random.randrange(800, 1000)
normal_enemies.append([random_enemy_location_x, random_enemy_location_y, random_velocity])
# print(normal_enemies[ne][0], normal_enemies[ne][1], normal_enemies[ne][2])
for e in range(number_of_enemies):
ex, ey, evel = normal_enemies[e]
screen.blit(enemy_pic, (ex, ey))
if ex > 75:
normal_enemies[e][0] -= evel
else:
base_health -= 0.02
normal_enemy_rect = pygame.Rect(ex, ey, 50, 50)
if player_rect.colliderect(normal_enemy_rect):
health -= 0.2
for j in reversed(range(len(explosions))):
pos, end_time_2, hurt = explosions[j]
explosion_rect = pygame.Rect(pos[0], pos[1], 20, 20)
if explosion_rect.colliderect(normal_enemy_rect):
normal_enemies.pop(e)
kills += 1
def redrawGameWindow():
global walkCount
global font
global font_small
global font_tiny
global font_verytiny
global bag
global items_font
global enemy_list
global pics
global position
global health
global base_health
global run_once
global explosions
global bullet_list
current_time = pygame.time.get_ticks()
dx = []
dy = []
dist = []
screen.fill([166, 166, 166])
pygame.draw.rect(screen, (220, 0, 0), (700, 500, 100, 100))
# for five_enemies in range(5):
# random_enemy_location_y = random.randrange(170, 470)
# random_enemy_location_x = random.randrange(700, 840)
# enemy_list.append([random_enemy_location_x, random_enemy_location_y])
# for enemies in range(5):
# screen.blit(enemy_Left[enemies], enemy_list[enemies])
# dx.append(position[0] - enemy_list[enemies][0])
# dy.append(position[1] - enemy_list[enemies][1])
# dist.append(math.hypot(dx[enemies], dy[enemies]))
# dx[enemies], dy[enemies] = dx[enemies] / dist[enemies], dy[enemies] / dist[enemies]
# enemy_list[enemies][0] += dx[enemies] * 2
# enemy_list[enemies][1] += dy[enemies] * 2
pygame.draw.rect(screen, (70, 0, 220), (0, 120, 100, 400)) # main base
pygame.draw.rect(screen, (220, 0, 0), (50, 470, 5, -300))
pygame.draw.rect(screen, (0, 220, 0), (50, 470, 5, -base_health*2))
screen.blit(font.render("B", True, (0, 0, 0)), (10, 200 + 40))
screen.blit(font.render("A", True, (0, 0, 0)), (10, 235 + 40))
screen.blit(font.render("S", True, (0, 0, 0)), (10, 270 + 40))
screen.blit(font.render("E", True, (0, 0, 0)), (10, 305 + 40))
enemy_spawn(5)
# cannon_balls()
pygame.draw.rect(screen, (0, 0, 0), (800, 0, 100, 600))
if x + char.get_width() < 60 and y + char.get_height() < 60:
shop_run()
screen.blit(shop, (0, 0))
screen.blit(font_small.render("Shop", True, (0, 0, 0)), (5, 5))
pygame.draw.rect(screen, (220, 0, 0), (position[0] - 3, position[1], 50, 5))
pygame.draw.rect(screen, (0, 220, 0), (position[0] - 3, position[1], health/2, 5))
screen.blit(font.render("Menu", True, (255, 255, 255)), (805, 10))
screen.blit(items_font.render("Bombs: " + str(bag["bomb"]), True, (255, 255, 255)), (805, 550))
screen.blit(items_font.render("Heal: " + str(bag["heal"]), True, (255, 255, 255)), (805, 570))
screen.blit(items_font.render("Cannon: " + str(bag["cannon"]), True, (255, 255, 255)), (805, 530))
# screen.blit(bullet, (450, 300))
# screen.blit(bomb_explosion, (450, 300))
# screen.blit(boss, (450, 300))
walk()
for i in reversed(range(len(bombs))):
pos, end_time = bombs[i]
if current_time > end_time:
end_time_2 = end_time + 5000
pos2 = (pos[0] - 10, pos[1] - 20)
explosions.append((pos2, end_time_2, False))
bombs.pop(i)
else:
screen.blit(pics[0], pos)
for j in reversed(range(len(explosions))):
pos, end_time_2, hurt = explosions[j]
if current_time > end_time_2:
explosions.pop(j)
else:
screen.blit(pics[1], pos)
if not hurt:
explosion_rect = pygame.Rect(pos[0], pos[1], 20, 20)
player_rect = pygame.Rect(x+20, y+20, 20, 20)
if player_rect.colliderect(explosion_rect):
explosions[j] = (pos, end_time_2, True)
health -= 5
# print(health)
for i in cannon_list:
screen.blit(cannon, i)
for j in bullet_list:
screen.blit(bullet, j)
j[0] += 3
screen.blit(font_tiny.render("Health: " + str("{:.2f}".format(health)), True, (255, 255, 255)), (805, 60))
screen.blit(font_verytiny.render("Base Health: " + str("{:.2f}".format(base_health)), True, (255, 255, 255)), (805, 90))
screen.blit(font_tiny.render("Kills: " + str(kills), True, (255, 255, 255)), (805, 110))
pygame.display.update()
def main():
run = True
pygame.display.set_caption("bomb-mania")
global x
global y
global width
global height
global vel
global left
global right
global down
global up
global walkCount
global bomb_pic
global font
global bombs
global explosions
global position
global health
global kills
global cannon_list
global bullet_list
while run:
current_time = pygame.time.get_ticks()
redrawGameWindow()
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
run = False
shop_rect = pygame.Rect(0, 0, 40, 40)
player_rect = pygame.Rect(x+20, y+20, 20, 20)
if player_rect.colliderect(shop_rect):
buy = pygame.key.get_pressed()
if buy[pygame.K_b]:
bag["bomb"] += 1
# print(bag["bomb"])
if buy[pygame.K_h]:
bag["heal"] += 1
if buy[pygame.K_c] and kills > 3:
kills -= 3
bag["cannon"] += 1
# print(bag["cannon"])
if event.type == pygame.KEYDOWN and not player_rect.colliderect(shop_rect):
if (event.key == pygame.K_SPACE or event.key == pygame.K_b) and bag["bomb"] >= 1:
current_time_2 = pygame.time.get_ticks()
pos = x + char.get_width() / 2, y + char.get_height() - 20
pos2 = ((x + char.get_width() / 2) - 10), (y + char.get_height() - 30)
end_time = current_time + 3000 # 3000 milliseconds = 3 seconds
bombs.append((pos, end_time))
bag["bomb"] -= 1
if event.key == pygame.K_h and not player_rect.colliderect(shop_rect) and health < 90 and bag["heal"] >= 1:
health += 10
bag["heal"] -= 1
if event.key == pygame.K_c and not player_rect.colliderect(shop_rect):
print("reached")
cannon_list.append([x,y])
bullet_list.append([x,(y-20)])
if health <= 0 or base_health <= 0:
main_menu()
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > vel - 15:
x -= vel
position[0] -= vel
left = True
right = False
down = False
up = False
# print(position)
elif keys[pygame.K_RIGHT] and x < 800 - vel - width:
x += vel
position[0] += vel
left = False
right = True
down = False
up = False
# print(position)
elif keys[pygame.K_DOWN] and y < 600 - height:
y += vel
position[1] += vel
left = False
right = False
down = True
up = False
# print(position)
elif keys[pygame.K_UP] and y > vel - 15:
y -= vel
position[1] -= vel
left = False
right = False
down = False
up = True
# print(position)
else:
left = False
right = False
down = False
up = False
walkCount = 0
clock.tick(FPS)
pygame.display.flip()
def main_menu():
global width
global height
global health
global base_health
global bag
global position
global x
global y
global left
global right
global down
global up
global walkCount
global normal_enemies
global explosions
global bombs
global enemy_list
global kills
global cannon_list
cannon_list =[]
kills = 0
enemy_list = []
normal_enemies = []
bombs = []
explosions = []
position = [60, 60]
x = 50 # same as position
y = 50 # same as position
left = False
right = False
down = False
up = False
walkCount = 0
enemy_vel = 2
enemy_list = []
bag["bomb"] = 0
bag["heal"] =0
health = 100
base_health = 150
pygame.display.set_caption("Main Menu")
run = True
bright_green = (0, 255, 0)
green = (0, 200, 0)
screen.fill((163, 163, 194))
while run:
mouse = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
quit()
run = False
if 400 + 100 > mouse[0] > 400 and 275 + 50 > mouse[1] > 275:
pygame.draw.rect(screen, bright_green, (400, 275, 100, 50))
if event.type == pygame.MOUSEBUTTONDOWN:
main()
else:
pygame.draw.rect(screen, green, (400, 275, 100, 50))
screen.blit(font_large.render("Bomb-Mania", True, (255, 255, 255)), (325, 50))
screen.blit(font.render("Play", True, (0, 0, 0)), (417, 285))
pygame.display.flip()
clock.tick(FPS)
main_menu()
The code below is the part that places the cannon.
This is part of main()
if event.key == pygame.K_c and not player_rect.colliderect(shop_rect):
print("reached")
cannon_list.append([x,y])
bullet_list.append([x,(y-20)])
This is part of redrawGameWindow()
for i in cannon_list:
screen.blit(cannon, i)
for j in bullet_list:
screen.blit(bullet, j)
j[0] += 3
Edits
bullet_list.append([x,(y+25),0, 0])
The changes i"ve made to keep track of the distance traveled are given below
for i in cannon_list:
screen.blit(cannon, i)
for j in bullet_list:
screen.blit(bullet, (j[0], j[1]))
j[3] = j[0]
if j[0] == j[3]:
j[0] += 3
j[2] += 3
if j[2] >= 100:
j[0] = j[3]
Edits2
I'm implementing OOP, Please help me debug.
class Cannon():
global cannon_list
global bullet_list
def __init__(self, x, y, track, old_x):
self.x = x
self.y = y
self.track = track
self.old_x = old_x
def spawnBullet(self):
for j in bullet_list:
self.old_x = j[3]
self.track = j[2]
screen.blit(bullet, (j[0], j[1]))
def moveBullet(self):
if self.x <= self.track:
self.x += 3
self.track += 3
def resetBullet(self):
if self.x >= self.track:
self.x = self.old_x
def spawnCannon(self):
for i in cannon_list:
screen.blit(cannon, i)
Using class Cannon
for j in bullet_list:
cannonsAndBullets = Cannon(j[0], j[1], j[2], j[0])
cannonsAndBullets.spawnCannon()
cannonsAndBullets.spawnBullet()
cannonsAndBullets.moveBullet()
cannonsAndBullets.resetBullet()
You say that you want the canons bullet to travel a fixed distance and then refire. What have you done to try to achieve that?
This appears to be the code that causes the bullet to move:
for j in bullet_list:
screen.blit(bullet, j)
j[0] += 3
There is nothing in here that stops it after it has travelled some specific distance or triggers a re-firing.
Your code would significantly benefit from object oriented restructuring and use of classes, in particular I would recommend that you make player, enemy, canon. bullet into classes. It not only cleans up the code but makes it simpler to keep track of the objects and all the respective state information that you need for each object.
For example for you question of re-firing after a certain distance has been traveled by the bullet. Right now the only information that you are keeping on the bullet is its position. To make it stop after a certain distance, you also need to know either its initial position or how far it has traveled since being fired. To re-fire you again need to know the canon it was fired from or possibly just its initial position if you just want to restart from the same place (assuming the canon is stationary). What about if the bullet hits something? Can the canon immediately re-fire, or does it have to wait for the same amount of time to elapse as if it had not hit anything and had to travel the full distance? If later you want your canon to be rate limited or something rather than just only one existing bullet at a time you will need state information in the canon about firing rate and the last time it fired.
Structuring your elements as objects allows you to cleanly keep all of that specific state information together for each instance of each object. It makes it simpler for you to modify behaviour when you want to since the logic related to the objects can be contained and you know where it all is. That is very important as the code gets larger and more complicated, but is always good practice regardless.
It also generally makes it simpler for other to look at, understand your code when you are asking for assistance, or if you were to pass a project on to someone else.
Edit after OP modified question based on comments:
You edited your code and added this:
for j in bullet_list:
screen.blit(bullet, (j[0], j[1]))
j[3] = j[0]
if j[0] == j[3]:
j[0] += 3
j[2] += 3
if j[2] >= 100:
j[0] = j[3]
Which does not make sense. The line if j[0] == j[3]: will always be true since in the line immediately before it you set j[3] = j[0].
I think what you are trying to do is have this state information for initial position and distance traveled in the list along with the x,y position, and that j[3] is supposed to be the initial position and j[2] is the distance? This is not how I would do this at all, but ... You might try this instead:
bullet_list.append([x,(y+25),0, x])
and
for j in bullet_list:
screen.blit(bullet, (j[0], j[1]))
j[0] += 3
j[2] += 3
if j[2] >= 100:
j[0] = j[3]
Again, you really should be using a class for this, not trying to keep the state as parts of a list.

Having trouble creating multiple enemies for my pygame

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()

Collision in constantly true?

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
# [...]

Control shooting frequency when the button to shoot is pressed?

The bullets shoot all at once when the button is pressed but I only want them to shoot once every 0.5 seconds if the button to shoot is pressed.
I have tried to import time and delay the bullets but it just delayed pygame itself.
Is there any way that I can regulate how frequent the character can shoot?
import pygame
pygame.init()
win = pygame.display.set_mode((700, 480))
pygame.display.set_caption("First project")
run = True
red = (255, 0, 0)
green = (0, 255, 0)
def drawbg():
pygame.display.update()
win.fill((255, 255, 255))
for bullet in bullets:
bullet.draw(win)
class person(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
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 = 7 * facing
def draw(self, win):
pygame.draw.circle(win, self.colour, (self.x, self.y), self.radius)
man = person(100, 400, 50, 60)
man2 = person(500, 400, 50, 60)
bullets = []
while run:
pygame.time.delay(25)
for bullet in bullets:
if bullet.x < 700 and bullet.x > 0:
bullet.x += bullet.vel
else:
bullets.pop(bullets.index(bullet))
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_g]:
if man.left:
facing = -1
else:
facing = 1
if len(bullets) < 5:
bullets.append(projectile(man.x + man.width//2, round(man.y + man.height/2), 6, (100, 100, 100), facing))
if keys[pygame.K_p]:
if man2.left:
facing = -1
else:
facing = 1
if len(bullets) < 50:
bullets.append(projectile(man2.x + man2.width//2, round(man2.y + man2.height/2), 6, (0, 0, 0), facing))
if keys[pygame.K_LEFT] and man2.x > man2.vel:
man2.x -= man2.vel
man2.left = True
man2.right = False
if keys[pygame.K_RIGHT] and man2.x < 700 - man2.width - man2.vel:
man2.x += man2.vel
man2.right = True
man2.left = False
if keys[pygame.K_a] and man.x > man.vel:
man.x -= man.vel
man.left = True
man.right = False
if keys[pygame.K_d] and man.x < 700 - man.width - man.vel:
man.x += man.vel
man.right = True
man.left = False
if not man.IsJump and keys[pygame.K_w]:
man.IsJump = True
man.JumpCount = 10
if man.IsJump:
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
if not man2.IsJump and keys[pygame.K_UP]:
man2.IsJump = True
man2.JumpCount = 10
if man2.IsJump:
if man2.JumpCount >= -10:
neg = 1
if man2.JumpCount < 0:
neg = -1
man2.y -= (man2.JumpCount ** 2) / 2 * neg
man2.JumpCount -= 1
else:
man2.IsJump = False
man2.JumpCount = 10
pygame.draw.rect(win, red, (man.x, man.y, man.width, man.height))
pygame.draw.rect(win, green, (man2.x, man2.y, man2.width, man2.height))
drawbg()
pygame.quit()
You can check for the time the last bullet was fired.
initiate the variable by:
import time
last_bullet = time.time()
then change your code to:
if len(bullets) < 5:
if time.time() - last_bullet > 0.5:
last_bullet = time.time()
bullets.append(projectile(man.x + man.width//2, round(man.y + man.height/2), 6, (100, 100, 100), facing))

Categories

Resources