From 08bff52b048999c872a970d2129d22b665eec669 Mon Sep 17 00:00:00 2001 From: Emil Shanaty Date: Sun, 16 Mar 2025 00:16:38 +0300 Subject: [PATCH] Add active/unactive horse colour management. Add barrier spawning every 500 game ticks. Generated comments to describe code. --- __pycache__/gameobjects.cpython-311.pyc | Bin 0 -> 11367 bytes __pycache__/main.cpython-311.pyc | Bin 0 -> 3704 bytes gameobjects.py | 147 +++++++++++++++--------- main.py | 77 +++++++------ 4 files changed, 136 insertions(+), 88 deletions(-) create mode 100644 __pycache__/gameobjects.cpython-311.pyc create mode 100644 __pycache__/main.cpython-311.pyc diff --git a/__pycache__/gameobjects.cpython-311.pyc b/__pycache__/gameobjects.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8cfa35409816211289b94b81b3540cfd9756843 GIT binary patch literal 11367 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 SO*DA}sR*v%!W^8s9Jr?!*$^5Gz@>Z_p>H#*w- z3MnV&;94kwf#?DiQ33<;Lm&8*`jDdNW550gQea_%PXhYV^vOkDg1odt%Il+?21u9W z&g{%@XJ%)1wfddk??upF{Oj+z28Yl;tO054F7x`IE`**V0SQzdrQ4KBQ!u9U^a7$0 zM$27f(hFc-k^!QS(6vY-lxET_pukSMDQ?0!DP}Nxn|?uo1^C)6&2`N45V?~IOy?Z% z%BH;#7vC98ng^Lra6#ng1w{OEFY2@(G~I$*-~?`;CIFfq!6SGDexD{N_|m=DuY{bj z5Z+qL3t0I}_}Yy^Ih3Xa|GJg2KJe4A&MCAn)_xq!QRx9pD`8^6NwGgiby}d%d$Ii= zj2zgHgjf#cf^QZi4)FAJ6Ar1zC50e;n?yZ!GMK>gkQ1q zDIJ8k(DFw_+G&BZGE6Ne-lwgP!Q3R#DjyThNjoj3hj2f{^_TQ89$r2~a6(`=nxEq# zuy~lrBZNUxKOR;__J$6o(>{fY^R|so2xOm)6p=gWJ2pna+Yu*%@b4hQfcz2BIw|hu zt<$k@=K^}vi6Z=dyMX(Y=$!O_;Ep==gva|%1%>K=#S!Hg(L3ooHY3Z&iC#dvl{pWy z$B5KPJ7=fI@qqGUr=IY5ymRl{r|d(K1F&Zz=@aC6d*8g%_uD)`C*%%>=mI+CKr1l$qg z&)_(i{QT_X(p9OnjI)(g*Q@^kO0upYwERC;pcFLe2cyu_!U)gV62N- zpuVNjyQFczY&0v3OI)lDvou zVt#ya3d<{%Qh9N*B#6b_;*H9xu(k*(us)K8#X?3b9xboE^`6a(awS_Tl+R1uV9&a; zWa~Gpid4^J`~BnRzd5A#e5_p9qPMPn@6x=-bnme}?P~y|g^RDOa;DCkuJT$gQ^01I zye6Bx#g@LZ5-*#KSQINJduw)TVa9aLOwaywX2Em|qFl~r)=W;um8C*Sz@|&iN*EVS z-jZZ9<%(D;!nB#$g=v$%Ics_^WU?zcskB-YOxCWNWc?K~U3R_3O!tL$flO|4N?KCDN9(Ev0ySF zkxkb23YMW-WlMT#>E>0FUM-uhOG{H<+?qETp>(fkGI9kH#1u+*u^Gyg%lWmXyP0ej z=dqNrljGYJ%4KYs5v0sLSW>1a4MqzQi*_( zpk5}QE#>o~fb9WkhowSBT7jzG&WmMOx(GFAC-bH3iZ#fte2=66R7LVb z_m(>gm0iu_^U@bEv`&Eh2RIu$T@*zb$X~S|19_|VW1xsi-WKAku66!_e;qKbo&yj3 zRknK9@C51yw>^obC!rkL8c;scJY%|Ntm-n5YrT6LMVlzPc}_zq9i>#1YH{Hz+hX0- z>kk&z7pkA>W4@AbL4LkI3=2AQuj=P zF<)P80_G!r8}&9(Z)3V~N<%Rn#Z(kC_M|5@6xC5wMbRH*r!^GUQCvmw9T$R_M%3QJ zns-F^j#S+(L_Z2V3^ZIC3hOAWqVNv=DU~#W;f?rqFxd@xl7UHlJ+rNsS-U`Jw7m zD+p%%Y|QT3w$5!%13=}IMj+I310EyT-?+U|(1XJe zM_cQC=6&kh@HOCR0oXb81)t14p4;>{ey!Zmd@0?RQhiWK|2CIwa!|G*of}fQA;XeH zn_N`m;yM>sxj0CkcprNkCp9jrb5YfPA#tql(fq@Cjp@^wK9%V++}*l6wt1)NPN?pL zF);YN@T~B(v{9<@2G{c>@Hnu^YuvET4XfO+!G+phHqU6>h|Z0u+(;_~IiT22?5^fE zxWE(NV_&1t_@#1f4+J=H-FsjMF>KQA_NOccrJ?GTORcQ literal 0 HcmV?d00001 diff --git a/gameobjects.py b/gameobjects.py index cd06ad8..d09d645 100644 --- a/gameobjects.py +++ b/gameobjects.py @@ -1,97 +1,136 @@ import pygame import random +WIDTH, HEIGHT = 800, 600 + class GameObject: x = 0 y = 0 def __init__(self, image_path, x=0, y=0): - self.image = pygame.image.load(image_path) - self.rect = self.image.get_rect(topleft=(x,y)) - self.set_position(x, y) + self.image = pygame.image.load(image_path) # Load the image + self.rect = self.image.get_rect(topleft=(x,y)) # Set the rectangle for the image + self.set_position(x, y) # Set initial position def draw(self, surface): - surface.blit(self.image, self.rect) - def set_position(self, x, y): # TODO: FIX CENTERING - self.rect.x = x + surface.blit(self.image, self.rect) # Draw the image on the surface + def set_position(self, x, y): + self.rect.x = x # Update rectangle position self.rect.y = y - self.x = x + self.x = x # Update object position self.y = y def move(self, dx, dy): - self.set_position(self.rect.x + dx, self.rect.y + dy) + self.set_position(self.rect.x + dx, self.rect.y + dy) # Move object by dx and dy def set_size(self, width, height): - self.image = pygame.transform.scale(self.image, (width,height)) - self.rect = self.image.get_rect(topleft=(self.x,self.y)) + self.image = pygame.transform.scale(self.image, (width,height)) # Resize the image + self.rect = self.image.get_rect(topleft=(self.x,self.y)) # Update rectangle size def scale_by(self, scale): - self.image = pygame.transform.scale(self.image, (self.image.get_width() * scale, self.image.get_height() * scale)) - self.rect = self.image.get_rect(topleft=(self.x,self.y)) + self.image = pygame.transform.scale(self.image, (self.image.get_width() * scale, self.image.get_height() * scale)) # Scale the image + self.rect = self.image.get_rect(topleft=(self.x,self.y)) # Update rectangle size def get_position(self): - return (self.x, self.y) - - - + return (self.x, self.y) # Return current position + class Horse(GameObject): - default_vacceleration = 0.5 - vspeed = 0 - vacceleration = 0 - stopped = False - color = () + default_vacceleration = 0.5 # Default acceleration value + vspeed = 0 # Vertical speed + vacceleration = 0 # Vertical acceleration + stopped = False # Whether the horse is stopped + color = () # Color of the horse's mark def __init__(self, image_path, x, y): self.vspeed = 0 self.vacceleration = 0 self.stopped = False - self.color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) + self.color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) # Random color for the mark super().__init__(image_path, x, y) - self.set_size(75, 75) + self.set_size(75, 75) # Set the size of the horse def apply_vspeed(self): pos = self.get_position() - self.set_position(pos[0], pos[1] + self.vspeed) + self.set_position(pos[0], pos[1] + self.vspeed) # Apply vertical speed to position def apply_vacceleration(self): - self.vspeed += self.vacceleration + self.vspeed += self.vacceleration # Apply acceleration to speed def set_vspeed(self, speed): - self.vspeed = speed + self.vspeed = speed # Set vertical speed def add_vspeed(self, delta): - self.vspeed += delta + self.vspeed += delta # Add to vertical speed def set_vacceleration(self, vacceleration): - self.vacceleration = vacceleration + self.vacceleration = vacceleration # Set vertical acceleration def up(self): - self.set_vacceleration(-self.default_vacceleration) + self.set_vacceleration(-self.default_vacceleration) # Move up def down(self): - self.set_vacceleration(self.default_vacceleration) + self.set_vacceleration(self.default_vacceleration) # Move down def stay(self): - self.set_vacceleration(0) + self.set_vacceleration(0) # Stop vertical movement def stop(self): - self.stopped = True + self.stopped = True # Stop the horse self.set_vacceleration(0) self.set_vspeed(0) - - - + def draw(self, surface): + surface.blit(self.image, self.rect) # Draw the horse + pygame.draw.rect(surface, self.color, (self.x + 40, self.y + 20, 25, 25)) # Draw the horse's mark class Background(GameObject): def __init__(self, image_path, x, y): - super().__init__(image_path, x, y) + super().__init__(image_path, x, y) # Initialize background class Barrier(GameObject): def __init__(self, image_path, x, y): - super().__init__(image_path, x, y) - + super().__init__(image_path, x, y) # Initialize barrier + class UI: - children = [] - horizontal_offset = 25 - mark_size = 5 + children = [] # List of child objects + horizontal_offset = 25 # Horizontal spacing between marks + vertical_offset = -25 # Vertical spacing between marks + mark_size = 25 # Size of the marks def __init__(self): - self.children = [] + self.children = [] # Initialize children list def add_children(self, children): - new_children = [child for child in children if child not in self.children] + new_children = [child for child in children if child not in self.children] # Add new children self.children.extend(new_children) def draw_marks(self, screen): - x0 = 50 - - y0 = 300 - - for child in self.children: - if isinstance(child, Horse): - x0 += self.horizontal_offset - x1 = x0 + self.mark_size - y1 = y0 - self.mark_size - pygame.draw.rect(screen, child.color, (x0, y0, x1, y1)) - \ No newline at end of file + active_marks = [] # List of active horses + unactive_marks = [] # List of inactive horses + for i in range(len(self.children)): + if isinstance(self.children[i], Horse): + if (self.children[i].stopped == False): + active_marks.append(self.children[i]) # Add active horses + else: + unactive_marks.append(self.children[i]) # Add inactive horses + + width = 10 # Number of marks per row + active_marks_section_pos = (0 - self.mark_size, 600 - self.mark_size) # Starting position for active marks + xa = active_marks_section_pos[0] + ya = active_marks_section_pos[1] + for i in range(len(active_marks)): + xa += self.horizontal_offset + pygame.draw.rect(screen, self.children[i].color, (xa, ya, self.mark_size, self.mark_size)) # Draw active marks + if xa >= width * (self.mark_size - 3): # Move to the next row if the row is full + ya += self.vertical_offset + xa = active_marks_section_pos[0] + + unactive_marks_section_pos = (800, 600 - self.mark_size) # Starting position for inactive marks + xu = unactive_marks_section_pos[0] + yu = unactive_marks_section_pos[1] + for i in range(len(unactive_marks)): + xu -= self.horizontal_offset + pygame.draw.rect(screen, unactive_marks[i].color, (xu, yu, self.mark_size, self.mark_size)) # Draw inactive marks + if 800 - xu >= width * self.mark_size: # Move to the next row if the row is full + yu += self.vertical_offset + xu = unactive_marks_section_pos[0] + +class Spawner: + active = True # Whether the spawner is active + frequency = 500 # Number of ticks between spawns + tick_counter = 0 # Counter for ticks + + def __init__(self, barrier_image_path): + self.barrier_image_path = barrier_image_path # Path to the barrier image + + def handle(self): + if self.active: + self.tick_counter += 1 # Increment tick counter + if self.tick_counter >= self.frequency: # Check if it's time to spawn + self.spawn() + self.tick_counter = 0 # Reset tick counter + + def spawn(self): + random_y = random.randint(0, HEIGHT - 100) # Random Y position for the barrier + new_barrier = Barrier(self.barrier_image_path, WIDTH, random_y) # Create a new barrier + return new_barrier \ No newline at end of file diff --git a/main.py b/main.py index 0a25698..e8be994 100644 --- a/main.py +++ b/main.py @@ -4,63 +4,72 @@ from gameobjects import * pygame.init() -WIDTH, HEIGHT = 800, 600 -screen = pygame.display.set_mode((WIDTH, HEIGHT)) -pygame.display.set_caption("NIC_Project") +screen = pygame.display.set_mode((WIDTH, HEIGHT)) # Initialize the screen +pygame.display.set_caption("NIC_Project") # Set window title -WHITE = (255, 255, 255) +WHITE = (255, 255, 255) # Define white color -UI = UI() -grass = Background("images/grass.jpg", 0, 0) -horse1 = Horse("images/horse.png", 50, 50) -barrier1 = Barrier("images/barrier.png", 400, 300) +UI = UI() # Initialize UI +grass = Background("images/grass.jpg", 0, 0) # Create background +horse1 = Horse("images/horse.png", 50, 50) # Create a horse +barrier1 = Barrier("images/barrier.png", 400, 300) # Create a barrier -BARRIER_SPEED = 1 +BARRIER_SPEED = 1 # Speed of the barriers -grass.set_size(WIDTH, HEIGHT) +grass.set_size(WIDTH, HEIGHT) # Set background size -gameobjects = [grass, horse1, barrier1] -horses = [Horse("images/horse.png", 50, 50) for i in range(5)] -barriers = [barrier1] +gameobjects = [] # List of all game objects +horses = [Horse("images/horse.png", 50, 50 * i) for i in range(50)] # Create 50 horses +barriers = [barrier1] # List of barriers -UI.add_children(horses) +gameobjects.extend([grass]) # Add background to game objects +gameobjects.extend(horses) # Add horses to game objects +gameobjects.extend(barriers) # Add barriers to game objects + +spawner = Spawner("images/barrier.png") # Initialize spawner + +UI.add_children(horses) # Add horses to UI while True: for event in pygame.event.get(): - if event.type == pygame.QUIT: + if event.type == pygame.QUIT: # Handle window close event pygame.quit() sys.exit() - keys = pygame.key.get_pressed() + keys = pygame.key.get_pressed() # Get pressed keys for horse in horses: - if horse.stopped == False: - if keys[pygame.K_UP]: + if horse.stopped == False: # If the horse is not stopped + if keys[pygame.K_UP]: # Move horse up if UP key is pressed horse.up() - elif keys[pygame.K_DOWN]: + elif keys[pygame.K_DOWN]: # Move horse down if DOWN key is pressed horse.down() else: - horse.stay() + horse.stay() # Stop vertical movement if no key is pressed else: - horse.move(-BARRIER_SPEED, 0) + horse.move(-BARRIER_SPEED, 0) # Move stopped horse to the left - horse.apply_vacceleration() - horse.apply_vspeed() - horse.draw(screen) + horse.apply_vacceleration() # Apply acceleration to horse + horse.apply_vspeed() # Apply speed to horse + horse.draw(screen) # Draw the horse + + spawner.handle() # Handle spawner logic + if spawner.tick_counter == 0: # If a new barrier is spawned + new_barrier = spawner.spawn() # Spawn a new barrier + barriers.append(new_barrier) # Add barrier to barriers list + gameobjects.append(new_barrier) # Add barrier to game objects for barrier in barriers: - barrier.move(-BARRIER_SPEED, 0) + barrier.move(-BARRIER_SPEED, 0) # Move barriers to the left - # Checking collisions between horses and barriers for horse in horses: - if horse.stopped == False: + if horse.stopped == False: # Check for collisions between horses and barriers for barrier in barriers: - if horse.rect.colliderect(barrier.rect): - horse.stop() - + if horse.rect.colliderect(barrier.rect): # If collision detected + horse.stop() # Stop the horse for object in gameobjects: - object.draw(screen) - UI.draw_marks(screen) + object.draw(screen) # Draw all game objects + UI.draw_marks(screen) # Draw UI marks - pygame.display.flip() - pygame.time.Clock().tick(60) + pygame.display.flip() # Update the display + pygame.time.Clock().tick(160) # Limit the frame rate to 160 FPS \ No newline at end of file