def run_game(): pygame.init() ai_settings = Settings() screen = pygame.display.set_mode((1000,600)) pygame.display.set_caption('Fighter') cha1=Cha1(screen) bullets1=Group() balls1=Group() attacks1=Group() cha2=Cha2(screen) bullets2=Group() balls2=Group() attacks2=Group() blood1=Blood1(screen) blood2=Blood2(screen) p2_win=False bgm=pygame.mixer.music.load('voice/bgm.wav') pygame.mixer.music.play(-1,0.0) clock=pygame.time.Clock() button = Button(screen) while True: clock.tick(250) gf.check_events(screen,cha1,cha2,bullets1,bullets2,balls1,balls2,attacks1,attacks2) screen.blit(ai_settings.inter_image,[0,0]) button.blitme() button.is_start() if button.game_start ==True: gf.update_bullets1(bullets1,cha2) gf.update_bullets2(bullets2,cha1) gf.update_balls1(balls1, cha2) gf.update_balls2(balls2, cha1) gf.update_attacks1(attacks1, cha1) gf.update_attacks2(attacks2, cha2) gf.update_blood1(blood1,cha2,bullets1,balls1,cha1,attacks1) gf.update_blood2(blood2,cha2,bullets2,balls2,cha1,attacks2) gf.inter_ball_bullets(bullets1,bullets2,balls1,balls2) gf.inter_bullets(bullets1,bullets2) gf.update_cha1(cha1,cha2) gf.update_cha2(cha2,bullets1,balls1,cha1) screen.blit(ai_settings.bg_image,[0,0]) gf.update_screen(cha1,cha2,bullets1,bullets2,balls1,balls2,blood1,blood2) pygame.display.flip()
def run_game(): pygame.init() dino_settings = Settings() screen = pygame.display.set_mode((dino_settings.screen_width, dino_settings.screen_height)) pygame.display.set_caption("dino") score = float(0) while True: ground = Ground(dino_settings, screen) dinosaur = Dinosaur(dino_settings, screen) clouds = Group() birds = Group() cactus = Group() gf.create_clouds(dino_settings, screen, clouds) gf.create_birds(dino_settings, screen, birds) gf.create_cactus(dino_settings, screen, cactus) sb = Scoreboard(dino_settings, screen) while not dinosaur.dead: gf.check_events(dinosaur) ground.update() dinosaur.update() score += 3 dino_settings.score = int(score) sb.prep_score() gf.update_clouds(dino_settings, screen, clouds) gf.update_birds(dino_settings, screen, birds, dinosaur) gf.update_cactus(dino_settings, screen, cactus, dinosaur) gf.update_screen(dino_settings, screen, ground, clouds, dinosaur, cactus, birds, sb) while dinosaur.dead: exit_game = False for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.MOUSEBUTTONDOWN: mouse_x, mouse_y = pygame.mouse.get_pos() if button.rect.collidepoint(mouse_x, mouse_y): exit_game = True if exit_game: if dino_settings.score > dino_settings.high_score: dino_settings.high_score = dino_settings.score sb.prep_high_score() dino_settings.score = 0 score = 0 break button = Button(dino_settings, screen) button.blitme() pygame.display.flip()
class Company(): """large unit of several batallions controlled by Flag Attributes ---------- coords : float 1-D numpy.ndarray [2], >=0 coords of center of Company speed : float, >=0 absolute velocity of Company moving : bool whether Company is moving, including marching and forming up angle : float angle in radians of Company to x-axis. oldAngle : float angle in radians of Company to x-axis saved from last forming up troops : list of Infantry list of sprites representing troops in Company flag : Flag sprite that user interacts with to give commands to Company target : Company or None enemy Company which this Company is aiming at maxSize : int, >= 0 number of Infantry that Company starts with sizex : int, >= 0 number of troops in a row of Infantry sizey : int, >= 0 number of rows of Infantry showOrders : int stage of selecting orders bayonetButton : Button button pressed to command Company to charge enemy with bayonets carreButton : Button button pressed to command Company to form carre lineButton : Button button pressed to command Company to form line play : bool whether Company can be given orders by player team : str team Company is on for friend-foe detection formation : String formation of Company defense : bool whether unit will ignore AI move orders allies : list of Battery, Company, Squadron list of all units with same team value enemies : list of Battery, Company, Squadron list of all units with different team value Properties ---------- size : int, >= 0 number of Infantry currently contained in Company formed : int, >= 0 count of Infantry in formation idle : bool whether AI can move this Company velocity : float 1-D numpy.ndarray [2] velocity of Company in vertical and horizontal axes morale : int percent chance of Company entering panic on losing next Infantry Methods ------- unitInit set allies and enemies setSpeed set speed to min of default, distance to coords distanceMany measure straight line distance Company to list of coords stop stop Company, Infantry update move Company, update Infantry, panic if necessary follow move Company and Infantry to flag lookAt set rotation to angle from current center to new point findTarget select enemy as target aim turn toward selected target getHit kill own Infantry when shot getShelled kill own Infantry hit by cannonball orders give orders other than move for Company formCarre Company forms a carre formLine Company forms a line AIcommand orders Company to move to coords AIsupport move to visible allies in combat AIcarre form carre when idle and charged by cavalry blitme print elements of Company __str__ return string with name of file for id, used in testing """ def __init__(self, screen, angle, x, y, sizex, sizey, team, flags, strength, play=True, defense=False): super().__init__() if team == "green": fil1, fil2, fil3, fileFlag = greenImages elif team == "blue": fil1, fil2, fil3, fileFlag = blueImages coords = np.array([x, y], dtype=float) self.troops = [] # self.maxSize = sizex * sizey # add infantry to company for i in range(sizex * sizey): """ x, y displacement from center of Company based on count shiftx increases with count with a period of sizex, creating a row of soldiers with a length of sizex shifty increases when count increases by sizex, starting a new row of soldiers every sizex soldiers """ shifty = I_GAPY * ((i % sizey) - sizey // 2) shiftx = I_GAPX * ((i // sizey) - sizex // 2) self.troops.append( Infantry(screen, angle, shiftx, shifty, strength, team, fil1, fil2, fil3, coords, play, defense)) self.flag = Flag(screen, (x, y), angle, fileFlag, play) flags.append(self.flag) # 0,1=click,release to show buttons, 2,3=click,release to select self.showOrders = 0 self.bayonetButton = Button(screen, "Bayonets") self.carreButton = Button(screen, "Carre") self.lineButton = Button(screen, "Line") self.healthDisp = Button(screen, str(self.health)) self.play = play self.team = team self.formation = "Line" self.oldUnits = [] # used to id object for testing, not meant to be seen/used self.id = fil1 def unitInit(self, units): # set allies and enemies if units != self.oldUnits: self.oldUnits = units.copy() [unit.unitInit(units) for unit in self.troops] @property def size(self): # number of Infantry currently contained in Company return len(self.troops) @property def flagVars(self): return (self.flag.coords, self.flag.select, self.flag.attackMove, self.flag.angle, self.flag.change) @property def health(self): return sum(inf.size for inf in self.troops) def update(self): # move Company, update Infantry, panic if necessary [unit.panic() for unit in self.troops if unit.panicTime > 0] for unit in self.troops: if unit.size <= 0: self.troops.remove(unit) elif unit.panicTime == -1: unit.update() def follow(self, flags): # move Company and Infantry to flag if self.play: self.flag.checkDrag(flags) [unit.follow(*self.flagVars) for unit in self.troops] self.flag.change = False def aim(self): # turn toward selected target [troop.aim() for troop in self.troops] def orders(self): # give orders other than move for Company if not self.play or self.size == 0: return if self.flag.select != 0 or pygame.mouse.get_pressed()[2]: self.showOrders = 0 mouse = pygame.mouse.get_pos() click = pygame.mouse.get_pressed()[0] touch = any([inf.rect.collidepoint(mouse) for inf in self.troops]) coords = self.troops[0].coords buttonCoords = (coords[0], coords[1] + FB_SIZE[1]) if click and self.showOrders == 0 and touch: self.showOrders = 1 if self.showOrders == 1 and not click: self.showOrders = 2 self.bayonetButton.draw(coords) if self.formation == "Line": self.carreButton.draw(buttonCoords) self.lineButton.draw((-100, -100)) if self.formation == "Carre": self.lineButton.draw(buttonCoords) self.carreButton.draw((-100, -100)) if self.showOrders == 2 and click: self.showOrders = 3 if self.bayonetButton.rect.collidepoint(mouse): for troop in self.troops: troop.bayonets = not troop.bayonets if self.carreButton.rect.collidepoint(mouse): self.formCarre() if self.lineButton.rect.collidepoint(mouse): self.formLine() if self.showOrders == 3 and not click: self.showOrders = 0 def formCarre(self): # Company forms a carre self.formation = "Carre" [inf.formCarre() for inf in self.troops] def formLine(self): # Company forms a line self.formation = "Line" [inf.formLine() for inf in self.troops] def AIcommand(self, coords, attackMove=False): # orders company to move to coords self.flag.coords = coords self.flag.attackMove = attackMove def AIsupport(self): # move to visible allies in combat if self.play or self.size == 0: return unit = self.troops[0] allyDist = unit.distanceMany([grp.coords for grp in unit.allies]) for ally, d in zip(unit.allies, allyDist): cannon = hasattr(ally, 'shot') canSee = d < I_SIGHT if unit.idle and ally.target is not None and canSee and not cannon: self.AIcommand(ally.target.coords, True) break def AIcarre(self): [troop.AIcarre() for troop in self.troops] def blitme(self): # print elements of Company if self.showOrders > 1: self.bayonetButton.blitme() self.carreButton.blitme() self.lineButton.blitme() coords = self.troops[0].coords healthCoords = (coords[0], coords[1] - FB_SIZE[1]) self.healthDisp.draw(healthCoords, str(self.health)) self.healthDisp.blitme() [infantry.blitme() for infantry in self.troops] self.flag.blitme() def __str__(self): return self.id
class Squadron(): """Small unit of several Cavalry controlled by Flag Attributes ---------- coords : float 1-D numpy.ndarray [2], >=0 coords of center of Squadron speed : float, >=0 absolute velocity of Squadron moving : bool whether Squadron is moving, including marching and forming up angle : float angle in radians of Squadron to x-axis. oldAngle : float angle in radians of Squadron to x-axis saved from last forming up troops : list of Cavalry list of sprites representing troops in Squadron flag : Flag sprite that user interacts with to give commands to Squadron target : Squadron or None enemy Squadron which this Squadron is aiming at maxSize : int, >= 0 number of Cavalry that Squadron starts with sizey : int, >= 0 number of rows of Cavalry panicTime : int, >= 0 time in milliseconds when Squadron started panicking showOrders : int stage of selecting orders chargeStart : int when Squadron started charging at target play : bool whether Squadron can be given orders by player team : str team Squadron is on for friend-foe detection defense : bool whether unit will ignore AI move orders allies : list of Battery, Squadron, Squadron list of all units with same team value enemies : list of Battery, Squadron, Squadron list of all units with different team value Properties ---------- size : int, >= 0 number of Cavalry currently contained in Squadron formed : int, >= 0 count of Cavalry in formation idle : bool whether AI can move this Squadron velocity : float 1-D numpy.ndarray [2] velocity of Squadron in vertical and horizontal axes allowShoot : bool whether Squadron will currently aim at targets range : int, >= 0 distance in pixels which Squadrons will set enemies as target aimVars : list of vars variables passed to Cavalry for aim funciton formVars : variables passed to Cavalry for form function morale : int percent chance of Squadron entering panic on losing next Cavalry Methods ------- unitInit set allies and enemies setSpeed set speed to min of default, distance to coords distance measure straight line distance Squadron to coords distanceMany measure straight line distance Squadron to list of coords stop stop Squadron, Cavalry update move Squadron, update Cavalry, panic if necessary follow move Squadron and Cavalry to flag lookAt set rotation to angle from current center to new point findTarget select enemy as target aim turn toward selected target hitBayonets take losses from defended enemies getHit kill own Cavalry when shot getShelled kill own Cavalry hit by cannonball orders give orders other than move for Squadron AIcommand orders company to move to coords AIsupport move to visible allies in combat blitme print elements of Squadron __str__ return string with name of file for id, used in testing """ def __init__(self, screen, angle, x, y, sizex, sizey, team, flags, strength, play=True, defense=False): super().__init__() if team == "green": file1, fileFlag = greenCav elif team == "blue": file1, fileFlag = blueCav coords = np.array([x, y], dtype=float) self.troops = [] # add infantry to company for i in range(sizex * sizey): """ x, y displacement from center of Company based on count shiftx increases with count with a period of sizex, creating a row of soldiers with a length of sizex shifty increases when count increases by sizex, starting a new row of soldiers every sizex soldiers """ shifty = CV_GAPY * ((i % sizey) - sizey // 2) shiftx = CV_GAPX * ((i // sizey) - sizex // 2) self.troops.append( Cavalry(screen, angle, shiftx, shifty, strength, team, file1, coords, play, defense)) self.flag = Flag(screen, (x, y), angle, fileFlag, play) flags.append(self.flag) # 0,1=click,release to show buttons, 2,3=click,release to select self.showOrders = 0 # self.bayonetButton = Button(screen, "Bayonets") self.healthDisp = Button(screen, str(self.health)) # self.bayonets = False self.play = play self.team = team self.oldUnits = [] # used to id object for testing, not meant to be seen/used self.id = file1 def unitInit(self, units): # set allies and enemies if units != self.oldUnits: self.oldUnits = units [unit.unitInit(units) for unit in self.troops] @property def size(self): # number of Cavalry currently contained in Squadron return len(self.troops) @property def flagVars(self): return (self.flag.coords, self.flag.select, self.flag.attackMove, self.flag.angle, self.flag.change) @property def health(self): return sum(inf.size for inf in self.troops) def update(self): # move Squadron, update Cavalry, panic if necessary [unit.panic() for unit in self.troops if unit.panicTime > 0] for unit in self.troops: if unit.size <= 0: self.troops.remove(unit) elif unit.panicTime == -1: unit.update() def follow(self, flags): # move Squadron and Cavalry to flag if self.play: self.flag.checkDrag(flags) [unit.follow(*self.flagVars) for unit in self.troops] self.flag.change = False def aim(self): # turn toward selected target [troop.aim() for troop in self.troops] def orders(self): # give orders other than move for Squadron if not self.play or self.size == 0: return if self.flag.select != 0 or pygame.mouse.get_pressed()[2]: self.showOrders = 0 mouse = pygame.mouse.get_pos() click = pygame.mouse.get_pressed()[0] touch = any([inf.rect.collidepoint(mouse) for inf in self.troops]) if click and self.showOrders == 0 and touch: self.showOrders = 1 if self.showOrders == 1 and not click: self.showOrders = 2 # self.bayonetButton.draw(self.coords) if self.showOrders == 2 and click: self.showOrders = 3 # if self.bayonetButton.rect.collidepoint(mouse): # self.bayonets = not self.bayonets if self.showOrders == 3 and not click: self.showOrders = 0 def AIcommand(self, coords, attackMove=False): # orders Squadron to move to coords self.flag.coords = coords self.flag.attackMove = attackMove def AIsupport(self): # move to visible allies in combat if self.play or self.size == 0: return unit = self.troops[0] allyDist = unit.distanceMany([grp.coords for grp in unit.allies]) for ally, d in zip(unit.allies, allyDist): cannon = hasattr(ally, 'shot') canSee = d < CV_SIGHT if unit.idle and ally.target is not None and canSee and not cannon: self.AIcommand(ally.target.coords, True) break def blitme(self): # print elements of Squadron [unit.blitme() for unit in self.troops] if self.size > 0: self.flag.blitme() if self.showOrders > 1: coords = self.troops[0].coords healthCoords = (coords[0], coords[1] - FB_SIZE[1]) self.healthDisp.draw(healthCoords, str(self.health)) self.healthDisp.blitme() # self.bayonetButton.blitme() def __str__(self): return self.id
class Game: """ This class initializes pygame and the game """ def __init__(self): pygame.init() # Creates a Settings instance self.settings = Settings() # Initialize screen self.screen = pygame.display.set_mode((self.settings.screen_size)) pygame.display.set_caption(self.settings.screen_caption) # Creates a Flipper instance. (we pass 'self' so we can create the screen in Flipper __init__()) self.flipper = Flipper(self) # Creates a Ball instance. (we pass 'self' so we can create the screen in Flipper __init__()) self.ball = Ball(self) # Creates a Button instance self.play_button = Button(self) # Creates a Scoreboard instance self.scoreboard = Scoreboard(self) def check_events(self): """ Checks for key presses events """ for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.MOUSEBUTTONDOWN: self._check_mousebutton_down(event) elif event.type == pygame.KEYDOWN: self._check_keydown_events(event) elif event.type == pygame.KEYUP: self._check_keyup_events(event) def check_collision(self): """ Check for ball and flipper collisions. Each time there's a collision, change ball movement and increase the current score """ if self.ball.rect.colliderect(self.flipper.rect): self.scoreboard.current_score += 1 # calls display_current_score() to update the current score to the screen self.scoreboard.display_current_score() # Inverts the ball direction self.ball.change_y *= -1 # Check for high score self.scoreboard.check_highest_score() # Calls display_highest_score() to update the high score to the screen self.scoreboard.display_highest_score() def _check_play_button(self, mouse_pos): """ Start a new game when the player presses Play """ if self.play_button.rect.collidepoint(mouse_pos): self.settings.game_active = True def _check_keydown_events(self, event): """ Check keydown events """ if event.key == pygame.K_RIGHT: self.flipper.moving_right = True elif event.key == pygame.K_LEFT: self.flipper.moving_left = True def _check_keyup_events(self, event): """ Check keyup events """ if event.key == pygame.K_RIGHT: self.flipper.moving_right = False elif event.key == pygame.K_LEFT: self.flipper.moving_left = False def _check_mousebutton_down(self, event): """ Check mousebutton down """ mouse_pos = pygame.mouse.get_pos() self._check_play_button(mouse_pos) def update_screen(self): """ Updates screen """ # Fill screen with color self.screen.fill(self.settings.screen_color) # Blits the flipper on screen self.flipper.blitme() # Blits the ball on the screen self.ball.blitme() # Blits the scoreboard on the screen only if settings.game_active is True if self.settings.game_active: self.scoreboard.blitme() self.scoreboard.display_lives_left(self.ball.lives) # Blits the button on the screen if the game status is inactive (game_active is False) if not self.settings.game_active: self.play_button.blitme() # Update the full display Surface to the screen pygame.display.flip() def run_game(self): """ Main loop of the game """ while True: self.check_events() if self.settings.game_active: self.flipper.update() self.ball.update() self.check_collision() self.update_screen()
class Flag: """Sprite that user interacts with to give commands to Company Attributes ---------- screen : pygame.Surface Surface on which Flag is drawn image : str path to image of Flag - sqrt of SCALE is used for flag rect : pygame.rect.Rect rectangle of Flag Surface coords : float 1-D numpy.ndarray [2], >=0 coords of center of Flag oldCoords : float 1-D numpy.ndarray [2], >=0 coords Flag will return to if move is cancelled angle : float angle in radians from oldCoords to coords draggable : bool whether Flag can be dragged by user moveButton : Button button user presses to move Company without stopping to shoot attackButton : Button button user presses to move Company while stopping to shoot select : bool whether the buttons are diplayed attackMove : bool whether Infantry should stop to shoot at enemies change : bool whether Infantry should update attackMove Methods ------- checkDrag drag Flag to mouse location, respond to button presses blitme draw flag, buttons """ def __init__(self, screen, coords, angle, file, draggable): self.screen = screen size = [int(i / math.sqrt(SCALE)) for i in file.get_rect().size] self.image = pygame.transform.scale(file, size) self.rect = self.image.get_rect() self.rect.center = coords self.coords = np.array(self.rect.center, dtype=float) self.oldCoords = coords self.angle = angle self.draggable = draggable self.moveButton = Button(screen, "Move") self.attackButton = Button(screen, "Attack") # 0,1=click,release to drag flag, 2,3=click,release to click button self.select = 0 self.attackMove = True self.change = False def checkDrag(self, flags): # drag Flag to mouse location, respond to button presses idle = all(flag.select == 0 for flag in flags) mouse = pygame.mouse.get_pos() click = pygame.mouse.get_pressed()[0] cancel = pygame.mouse.get_pressed()[2] if not idle and self.select == 0: return if cancel and self.select != 0: self.select = 0 self.coords = self.oldCoords if self.rect.collidepoint(mouse) and click: self.select = 1 if self.select == 1 and not click: self.moveButton.draw((self.rect.left - FB_SIZE[0] / 2, self.rect.centery)) self.attackButton.draw((self.rect.right + FB_SIZE[0] / 2, self.rect.centery)) self.select = 2 if self.select == 2 and click: if self.moveButton.rect.collidepoint(mouse): self.select = 3 elif self.attackButton.rect.collidepoint(mouse): self.select = 3 else: self.select = 1 if self.select == 3 and not click: if self.moveButton.rect.collidepoint(mouse): self.attackMove = False self.select = 0 self.moveButton.draw((0, 0)) self.attackButton.draw((0, 0)) self.lookAt() self.oldCoords = self.coords self.change = True if self.attackButton.rect.collidepoint(mouse): self.attackMove = True self.select = 0 self.moveButton.draw((0, 0)) self.attackButton.draw((0, 0)) self.lookAt() self.oldCoords = self.coords self.change = True if self.select == 1: self.coords = np.asarray(mouse) def lookAt(self): # point at coordinates distance = self.coords - self.oldCoords self.angle = math.atan2(-distance[1], distance[0]) def blitme(self): # draw flag, buttons self.rect.center = self.coords if self.draggable: self.screen.blit(self.image, self.rect) if self.select > 1: self.moveButton.blitme() self.attackButton.blitme()
class Menu(): def __init__(self, scene, x, y, text, screen): self.next = Button(screen, text) self.x = x self.y = y self.select = 0 self.scene = scene self.screen = screen text = ( "September 7, 1812\n" "Emperor Napoleon!\n" "The Russian Army has, at long last, turned to face us on the battlefield " "70 miles west of Moscow. Our army is ready! Drag the flag of an infantry " "company to order them to a location, and click the 'Attack' button for them to " "attack the enemy on sight, or the 'Move' button to have them march without " "firing a shot. You can also click on the company to order them to engage the " "enemy with bayonets. Remember: make the enemy flee by shattering their morale " "with overwhelming numbers, and use bayonets to finish off wounded formations." ) self.text = multiLine(text, pygame.font.SysFont('arial', FB_TXT_SIZE), pygame.Rect(20, 20, 1160, 660), FB_TXT_COLOR, BG_COLOR) def check(self): mouse = pygame.mouse.get_pos() click = pygame.mouse.get_pressed()[0] if self.next.rect.collidepoint(mouse) and click: self.select = 1 if self.select == 1 and not click: if self.next.rect.collidepoint(mouse): if self.scene == "instruction": self.scene = "borodino" return else: return "restart" else: self.select = 0 self.scene = "instruction" def update(self): if self.scene == "victory": text = ( "Victory! \n \n" "The Russian Army has retreated from the battlefield sir! " "I still believe you should sent the Imperial Guard. As it stands, their army " "is still a threat, and the heavy losses we suffered will be difficult to " "replace, especially with the Russian serfs attacking our supplies. However, " "our scouts are reporting pillars of smoke rising from the direction of " "Moscow. The Russians wouldn't light their own capital ablaze just to keep us " "out... would they?\nClick the button if you want to try the battle again!" ) if self.scene == "defeat": text = ( "Defeat! \n \n" "Our troops, exhausted by the 3 month march to Moscow, and weakened by the " "lack of supplies due to the raids made by Russian serfs of all people, " "proved unable to withstand the ferocious spirit of the Russian soldiers. " "Their unwavering resolve even in the frenzy of a bayonet melee is unmatched! " "We are forced to retreat, and with winter coming soon, we may not have " "the opportunity for another invasion until next year. But, we shall return " "and shatter the enemies of the French Empire!\n" "Click the button if you want to try the battle again") self.text = multiLine(text, pygame.font.SysFont('arial', FB_TXT_SIZE), pygame.Rect(20, 20, 1160, 660), FB_TXT_COLOR, BG_COLOR) def blitme(self): self.screen.blit(self.text, (20, 20)) self.next.draw((self.x, self.y)) self.next.blitme()