So I’m trying to make it so that if my rectangle collides with an another rectangle/Point, it will move the Point y position away from the rectangle and will add one to my score. The problem that I’m getting is that my score will add two instead of one evey single time my rectangle collides with my point https://gyazo.com/d9e4167f749f2a672fe7f713ce5bab2e. I have tried using a true and false statement to make it only add one instead of two to my score and that also did not work. I have also tried using a timer to tell it when to add and that did not work for me to.
This is what I tried
if point: score += 1 text = font.render(""+str(score), True,(0,0,0)) point = False # Making the rectangles get off the screen for a short amount of time if Ptimer > 0: Ptimer += 1 point1.y = -200 if Ptimer >= 15: Ptimer = 0 if Ptimer2 > 0: Ptimer2 += 1 point2.y = -200 if Ptimer2 >= 20: Ptimer2 = 0 # The player collideing with the point's if playerman.rect.colliderect(point1.rect): Ptimer = 1 point = True if playerman.rect.colliderect(point2.rect): Ptimer2 = 1 point = True
My full code
import pygame,random pygame.init() width = 500 height = 600 # Screen width and height window = pygame.display.set_mode((width,height)) # Name of the Screen pygame.display.set_caption("Game") # The background background = pygame.image.load("img/BG_2.png").convert_alpha() # Making both peipes separate Pipe_distance = 830 # part of making background shift bg_shift = 0 # player class class Player: def __init__(self,x,y,width,height,color): self.x = x self.y = y self.width = width self.height = height self.color = color self.normal = [pygame.image.load("img/Normal_fish" + str(i) + ".png") for i in range(1,7)] self.up = [pygame.image.load("img/Up_fish" + str(i) + ".png") for i in range(1,7)] self.down = [pygame.image.load("img/Down_fish" + str(i) + ".png") for i in range(1,7)] self.speed = 5 self.JumpCount = False self.isJump = 10 self.fall = 0 self.direction = "up" self.direction = "down" self.direction = "normal" self.next_frame_time = 0 self.fps = 10 self.normal = [pygame.transform.scale(image,(image.get_width()//5, image.get_height()//5)) for image in self.normal] self.up = [pygame.transform.scale(image,(image.get_width()//5, image.get_height()//5)) for image in self.up] self.down = [pygame.transform.scale(image,(image.get_width()//5, image.get_height()//5)) for image in self.down] self.clock = pygame.time.Clock() self.anim_index = 0 self.rect = pygame.Rect(x,y,width,height) def get_rect(self): self.rect.topleft = (self.x,self.y) return self.rect def draw(self): self.rect.topleft = (self.x,self.y) if self.direction == "normal": image_list = self.normal elif self.direction == "up": image_list = self.up elif self.direction == "down": image_list = self.down # Telling when to change frames time_now = pygame.time.get_ticks() if (time_now > self.next_frame_time): # The time until next frame inter_time_delay = 1000 // self.fps self.next_frame_time = time_now + inter_time_delay # Changing it to the next frame self.anim_index += 1 if self.anim_index >= len(image_list): self.anim_index = 0 if self.anim_index >= len(image_list): self.anim_index = 0 player_image = image_list[self.anim_index] player_rect = player_image.get_rect(center = self.get_rect().center) player_rect.centerx player_rect.centery window.blit(player_image,player_rect) # Pipe class class Pipe: def __init__(self,x,y,width,height,color): self.x = x self.y = y self.width = width self.height = height self.color = color self.speed = 3 self.pipe = pygame.image.load("img/chain.png").convert_alpha() self.pipe = pygame.transform.scale(self.pipe,(self.pipe.get_width()//2, self.pipe.get_height()//2)) self.rect = pygame.Rect(x,y,width,height) self.anim_index = 0 def get_rect(self): self.rect.topleft = (self.x,self.y) return self.rect def draw(self): self.rect.topleft = (self.x,self.y) pipe_rect = self.pipe.get_rect(center = self.get_rect().center) pipe_rect.centerx += 10 pipe_rect.centery += 595 window.blit(self.pipe,pipe_rect) # Pipe2 class class Pipe2: def __init__(self,x,y,width,height,color): self.x = x self.y = y self.width = width self.height = height self.color = color self.speed = 3 self.pipe = pygame.image.load("img/chain.png").convert_alpha() self.pipe = pygame.transform.scale(self.pipe,(self.pipe.get_width()//2, self.pipe.get_height()//2)) self.rect = pygame.Rect(x,y,width,height) self.anim_index = 0 def get_rect(self): self.rect.topleft = (self.x,self.y) return self.rect def draw(self): self.rect.topleft = (self.x,self.y) pipe_rect = self.pipe.get_rect(center = self.get_rect().center) pipe_rect.centerx += 26 pipe_rect.centery -= 635 window.blit(self.pipe,pipe_rect) # Partical class class Partical: def __init__(self,x,y,width,height,color): self.x = x self.y = y self.width = width self.height = height self.color = color self.par = [pygame.image.load("img/Partical" + str(i) + ".png") for i in range(1,8)] self.rect = pygame.Rect(x,y,width,height) self.anim_index = 0 self.next_frame_time = 0 self.fps = 10 self.play = False self.clock = pygame.time.Clock() self.direction = "par" def draw(self): self.rect.topleft = (self.x,self.y) if self.direction == "par": image_list = self.par # Is it time to show next frame? time_now = pygame.time.get_ticks() if (time_now > self.next_frame_time): # Time until the next frame inter_time_delay = 750 // self.fps self.next_frame_time = time_now + inter_time_delay # Show the next frame if self.play: self.anim_index += 1 if self.anim_index >= len(image_list): self.anim_index = 0 if self.play: if self.anim_index >= len(image_list): self.anim_index = 0 par_image = image_list[self.anim_index] window.blit(par_image,self.rect) # Point class class Point: def __init__(self,x,y,width,height,color): self.x = x self.y = y self.width = width self.height = height self.color = color self.speed = 3 self.rect = pygame.Rect(x,y,width,height) def draw(self): self.rect.topleft = (self.x,self.y) pygame.draw.rect(window,self.color,self.rect) # Color white = (255,255,255) green = (0,255,0) blue = (0,0,255) # Calss's cords,size, and color playerman = Player(200,250,40,40,white) pipe1 = Pipe(350,900,60,700,green) pipe2 = Pipe2(350,-900,60,700,green) pipe3 = Pipe(720,9900,60,700,white) pipe4 = Pipe2(720,-9900,60,700,blue) par = Partical(-300,350,50,50,blue) point1 = Point(400,-300,40,70,white) point2 = Point(770,-300,40,70,white) # All my list pipes = [pipe1,pipe3] pipes2 = [pipe2,pipe4] particals = [par] points = [point1,point2] # Point system font = pygame.font.Font("img/CAT.ttf",60) score = 0 text = font.render(""+str(score), True,(0,0,0)) textRect = text.get_rect() textRect.center = ((250,60)) # Displaying class's in main loop def redrawwindow(): window.fill((0,0,0)) window.blit(background,(0,0)) # Part of making background move bg_width = background.get_width() bg_offset = bg_shift % bg_width window.blit(background, (-bg_offset, 0)) window.blit(background, (bg_width - bg_offset, 0)) # Drawing my classes and other things playerman.draw() for Pipe in pipes: Pipe.draw() for Pipe2 in pipes2: Pipe2.draw() for Partical in particals: Partical.draw() for Point in points: Point.draw() window.blit(text,textRect) # To make the game more difuclt ptimer = 0 # for playing sprite when player jumps Jumping = 0 # Making it so the rectangle dose not come for a whilw Ptimer = 0 Ptimer2 = 0 point = False fps = 35 clock = pygame.time.Clock() run = True while run: clock.tick(fps) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False # Making most of my classes move for Pipe in pipes: Pipe.x -= Pipe.speed for Pipe2 in pipes2: Pipe2.x -= Pipe2.speed for Pipe2 in pipes2: if Pipe2.x <= -200: Pipe2.x = 550 for Point in points: Point.x -= Point.speed for Point in points: if Point.x <= -200: Point.x = 550 # Moving backgrond bg_shift += 2 # Randomizing pipe for Pipe in pipes: if Pipe.x <= -200: Pipe.x = 550 Pipe.y = random.randint(150,500) pipe2.y = pipe1.y - Pipe_distance pipe4.y = pipe3.y - Pipe_distance point1.y = pipe1.y - 90 point2.y = pipe3.y - 90 if point: score += 1 text = font.render(""+str(score), True,(0,0,0)) point = False # Making the rectangles get off the screen for a short amount of time if Ptimer > 0: Ptimer += 1 point1.y = -200 if Ptimer >= 15: Ptimer = 0 if Ptimer2 > 0: Ptimer2 += 1 point2.y = -200 if Ptimer2 >= 20: Ptimer2 = 0 # The player collideing with the point's if playerman.rect.colliderect(point1.rect): Ptimer = 1 point = True if playerman.rect.colliderect(point2.rect): Ptimer2 = 1 point = True # Making the game faster ptimer += 1 if ptimer == 3000: for Pipe in pipes: for Pipe2 in pipes2: for Point in points: Pipe.speed += 1 Pipe2.speed += 1 Point.speed += 1 bg_shift += 1 if ptimer == 6000: for Pipe in pipes: for Pipe2 in pipes2: for Point in points: Pipe.speed += 1 Pipe2.speed += 1 Point.speed += 1 bg_shift += 3 # If the player collides with the chain for Pipe in pipes: if playerman.rect.colliderect(Pipe.rect): print("collide") for Pipe2 in pipes2: if playerman.rect.colliderect(Pipe2.rect): print("collide2") # Mostly about player direction if Jumping > 0: Jumping += 1 playerman.direction = "up" for Partical in particals: Partical.x = playerman.x + 10 Partical.y = playerman.y + 25 Partical.play = True if Jumping >= 15: playerman.direction = "normal" Partical.y = -200 Partical.anim_index = 0 if Jumping >= 20: Jumping = 0 playerman.direction = "down" keys = pygame.key.get_pressed() if keys[pygame.K_SPACE]: Jumping = 1 collide = False playerman.y += playerman.speed # bird moving if not playerman.isJump: # [...] # the bird is allowed to jump even if it is not colliding: if keys[pygame.K_SPACE]: playerman.isJump = True if collide: playerman.fall = 0 else: if playerman.JumpCount > 0: playerman.y -= (playerman.JumpCount*abs(playerman.JumpCount))*0.3 playerman.JumpCount -= 1 else: playerman.JumpCount = 10 # if K_SPACE is pressed, then the bird keeps jumping if not keys[pygame.K_SPACE]: playerman.isJump = False redrawwindow() pygame.display.update() pygame.quit()
Advertisement
Answer
You change the y
attribute of the object when you move it out of the visible area:
point1.y = -200
However you use the rect
attribute for the collision test:
if playerman.rect.colliderect(point1.rect):
Hence, you need to update the rect
attribute after changing the y
attribute before the next collision test is performed:
if Ptimer > 0: Ptimer += 1 point1.y = -200 point1.rect.topleft = (point1.x, point1.y)