def make_stats_box(screen, player, dungeon_level, box_x_start, box_heigth, box_width): """Create the box displaying the stats @param screen: the screen to draw on @param player: the player object @param dungeon_level: the current dungeon level @param box_x_start: rectangle upper left corner x-coordinate @param box_heigth: height of rectangle @param box_width: width of rectangle """ #create the rectangle stats_box = Rect(box_x_start, 0, box_width, box_heigth) #set font type stats_font = font.SysFont('arial', 20) #render game info player_HP = stats_font.render("Hit Points: " + str(player.getHP()), True, Color('white')) player_AP = stats_font.render("Attack Power: " + str(player.getAttackPower()), True, Color('white')) player_Armor = stats_font.render("Armor: " + str(player.getArmor()), True, Color('white')) level = stats_font.render("Dungeon Level: " + str(dungeon_level), True, Color('white')) #For each line of text, draw it on the screen and move the rectangle for the next line screen.fill(Color('Black'), stats_box) screen.blit(player_HP, stats_box) screen.blit(player_AP, stats_box.move(0, player_HP.get_height())) screen.blit(player_Armor, stats_box.move(0, player_HP.get_height() + player_AP.get_height())) screen.blit(level, stats_box.move(0, player_HP.get_height() + player_AP.get_height() + player_Armor.get_height()))
class Button: def __init__(self): self.buttonOn = ButtonOn() self.buttonOff = ButtonOff() self.isOn = False; self.rect = Rect(0,0,0,0) def get_sprite(self): if self.isOn: return self.buttonOn else: return self.buttonOff def set_x(self, x): self.buttonOn.rect.x = x self.buttonOff.rect.x = x self.rect = self.buttonOn.rect def set_y(self, y): self.buttonOn.rect.y = y self.buttonOff.rect.y = y self.rect = self.buttonOn.rect def check_pressed(self, pressed, x, y): if pressed: if self.rect.collidepoint(x, y): self.isOn = True return self.isOn def check_point(self, x, y): return self.rect.collidepoint(x, y) def set_pressed(self, pressed): self.isOn = pressed
def pick_rect(points, rects): ox, oy = sorted([ (sum(p), p) for p in points ])[0][1] x = ox y = oy ex = None while 1: x += 1 if not (x, y) in points: if ex is None: ex = x - 1 if ((ox, y+1) in points): if x == ex + 1 : y += 1 x = ox else: y -= 1 break else: if x <= ex: y-= 1 break c_rect = Rect(ox*tilewidth,oy*tileheight,\ (ex-ox+1)*tilewidth,(y-oy+1)*tileheight) rects.append(c_rect) rect = Rect(ox,oy,ex-ox+1,y-oy+1) kill = [ p for p in points if rect.collidepoint(p) ] [ points.remove(i) for i in kill ] if points: pick_rect(points, rects)
def draw(self, screen, work_rects=None): """Draw the map to the screen""" if work_rects is None: work_rects = [Rect(0,0,screen.get_width(),screen.get_height())] extra_things = collections.defaultdict(list) for (k,v) in self.map_to_draw.objects.items(): extra_things[k].extend(v) extra_things[self.map_coords(pygame.mouse.get_pos(), screen)].append(self.mouse_cursor) for i in range(self.map_to_draw.w): for j in range(self.map_to_draw.h): view_x = 32*i-32*j view_y = 16*i+16*j x, y = view_x - self.view_x + screen.get_width()//2, view_y-self.view_y + screen.get_height()//2 t = self.map_to_draw.terrain((i,j)) s = t.sprite s_pos = Rect(x-32,y+16-s.get_height(),s.get_width(),s.get_height()) if s_pos.collidelist(work_rects)>=0: screen.blit(s, s_pos) if (i,j) in extra_things: for t in extra_things[(i,j)]: if isinstance(t, pygame.Surface): s = t else: s = t.sprite screen.blit(s,(x-32,y+16-s.get_height()))
def get_item_at_pos (self, position): """L.get_item_at_pos (...) -> ListItem Gets the item at the passed position coordinates. """ eventarea = self.rect_to_client () if not eventarea.collidepoint (position): return None position = position[0] - eventarea.left, position[1] - eventarea.top border = base.GlobalStyle.get_border_size \ (self.__class__, self.style, StyleInformation.get ("ACTIVE_BORDER")) * 2 posy = self.vadjustment items = self.scrolledlist.items width = eventarea.width bottom = eventarea.bottom images = self.images spacing = self.scrolledlist.spacing for item in items: rect = Rect (images [item][1]) rect.y = posy rect.width = width + border if rect.bottom > bottom: rect.height = bottom - rect.bottom + border if rect.collidepoint (position): return item posy += images[item][1].height + spacing + border return None
def set_screen_background(self): """ Update the background """ logger.log( 9, 'set_screen_background()') if not self.background: self.background = osd.get_singleton().getsurface(rect=self.rect) self.updates = [] elif len(self.updates) > 0: # find the topleft corner x = self.rect.right y = self.rect.bottom for i in self.updates: x = min(x, i.left) y = min(y, i.top) # find the total rect of the collisions upd = Rect(x, y, 0, 0) upd.unionall_ip(self.updates) self.updates = [] x = upd[0] - self.rect.left y = upd[1] - self.rect.top bg_tmp = osd.get_singleton().getsurface(rect=upd) self.background.blit(bg_tmp, (x, y)) self.surface.blit(self.background, (0,0))
def update_world_window(self, screen, floor_s, map_data): blit_area = Rect(0,0,64,64) # Get the dirty tile -coordinates from map_data for dirty_tile_position in map_data.get_dirty_tile_positions: # Calculate the screen position for given tile dirty_screen_position = screen_position_of_tile(dirty_tile_position) area_x, area_y = dirty_tile_position blit_area.topleft = (area_x*64, area_y*64) # Blit the tile from floor, to screen. screen.blit(floor_s, dirty_screen_position, blit_area) # Blit items in the tile # Try if this position contains a list of items. Note: these may fail :s items_in_position = map_data.get_items_on_position(dirty_tile_position) if items_in_position is not None: self.draw_items_on_tile(screen, items_in_position, dirty_screen_position) # Blit character in here. character = map_data.get_character_on_position(dirty_tile_position) if character is not None: screen.blit(character.surface, dirty_screen_position) map_data.reset_dirty_tiles()
def testUnionAll( self ): r1 = Rect( 0, 0, 1, 1 ) r2 = Rect( -2, -2, 1, 1 ) r3 = Rect( 2, 2, 1, 1 ) r4 = r1.unionall( [r2,r3] ) self.assertEqual( Rect(-2, -2, 5, 5), r4 )
class Projectile(sprite.Sprite): def __init__(self, pos, tower, target, image, speed, damage): sprite.Sprite.__init__(self) self.pos = pos self.tower = tower self.target = target self.image = image self.speed = speed self.damage = damage self.rect = Rect(self.pos, self.image.get_size()) self.angle = atan2((self.target.rect.centery-self.rect.centery), (self.target.rect.centerx-self.rect.centerx)) self.x_speed = cos(self.angle)*self.speed self.y_speed = sin(self.angle)*self.speed def update(self, monsters, screen): # Kills the projectile if it doesn't get there before the target dies if self.target is None: self.kill() return # Calculates where the projectile needs to go self.angle = atan2((self.target.rect.centery-self.rect.centery), (self.target.rect.centerx-self.rect.centerx)) distance = hypot(self.target.rect.centerx - self.rect.centerx, self.target.rect.centery - self.rect.centery) mod = self.target.speed+1 # Calculates the X and Y speed xspeed, yspeed = cos(self.angle)*mod, sin(self.angle)*mod self.x_speed = xspeed + xspeed/abs(xspeed) if xspeed != 0 else 0 self.y_speed = yspeed + yspeed/abs(yspeed) if yspeed != 0 else 0 # If the projectile is within range, it hit the target if abs(self.rect.centerx - self.target.rect.centerx) <= 20: if abs(self.rect.centery - self.target.rect.centery) <= 20: self.do_damage(monsters) self.kill() else: self.rect.move_ip((self.x_speed, self.y_speed)) else: self.rect.move_ip((self.x_speed, self.y_speed)) # Destroys the projectile if it goes off screen if not screen.contains(self.rect): self.kill() def do_damage(self, monsters): for monster in monsters: # Does damage to the target, and adds kills and money rewards if it dies, also adds damage_done to tower if monster == self.target: # dmg_result returns (None/Value of monster, Damage done by projectile) dmg_result = monster.damage(self.damage) if dmg_result[0] is not None: self.tower.kills += 1 self.tower.turn_yield += dmg_result[0] self.tower.damage_done += dmg_result[1] break
def _draw_animation(self, entity): height = entity.cliche.surface.get_height() dest = Rect(0, 0, height, height) dest.center = self._on_screen(entity.position) self.screen.blit(entity.cliche.surface, dest, entity.cliche.active_rect)
def build(self): # calculate the max dimensions max_w, max_h = 0, 0 for item in self.items: width, height = self.font.size(item.text) max_w = max(width, max_w) max_h = max(height, max_h) rect = Rect(0,0,max_w,max_h).inflate(self.padding, self.padding) # place and initialize each menu item bounds = Rect(0, 0, 0, 0) top = 0 for item in self.items: item.image = Surface(rect.size, SRCALPHA) item.rect = rect.copy() item.rect.top = top top = item.rect.bottom + self.margin bounds.union_ip(item.rect) # tmp, render each sprite initially for item in self.items: item.draw_normal()
def test_move( self ): r = Rect( 1, 2, 3, 4 ) move_x = 10 move_y = 20 r2 = r.move( move_x, move_y ) expected_r2 = Rect(r.left+move_x,r.top+move_y,r.width,r.height) self.assertEqual( expected_r2, r2 )
def __init__(self,midbottom): Rect.__init__(self,self.rect) self.midbottom = midbottom self.dx = random()-0.5 self.X = self.x self.dy = 4+random() self.Y = self.y
def test_unionall_ip( self ): r1 = Rect( 0, 0, 1, 1 ) r2 = Rect( -2, -2, 1, 1 ) r3 = Rect( 2, 2, 1, 1 ) r1.unionall_ip( [r2,r3] ) self.assertEqual( Rect(-2, -2, 5, 5), r1 )
def test_collidedictall(self): # __doc__ (as of 2008-08-02) for pygame.rect.Rect.collidedictall: # Rect.collidedictall(dict): return [(key, value), ...] # test if all rectangles in a dictionary intersect # # Returns a list of all the key and value pairs that intersect with # the Rect. If no collisions are found an empty dictionary is # returned. # # Rect objects are not hashable and cannot be used as keys in a # dictionary, only as values. r = Rect(1, 1, 10, 10) r2 = Rect(1, 1, 10, 10) r3 = Rect(5, 5, 10, 10) r4 = Rect(10, 10, 10, 10) r5 = Rect(50, 50, 10, 10) rects_values = 1 d = {2: r2} l = r.collidedictall(d, rects_values) self.assertEqual(l, [(2, r2)]) d2 = {2: r2, 3: r3, 4: r4, 5: r5} l2 = r.collidedictall(d2, rects_values) self.assertEqual(l2, [(2, r2), (3, r3), (4, r4)])
def create_platforms_rect(self, tiles, layer): """ Create a collision rect for each non-empty tile segment, that is, one or more tiles together """ if len(tiles) < 1: return False x, y = tiles.pop(0) width = self.map.content['tilewidth'] height = self.map.content['tileheight'] rect = Rect((0, 0, 0, 0)) rect.left = x * width rect.top = y * height rect.width = width rect.height = height # self.platforms.append(Platform(rect, layer)) n_tiles_x, n_tiles_y = 0, 0 # exclude the tiles we're about to create a platform for excluded_tiles = [] for (n_x, n_y) in tiles: if abs(n_x - x) == n_tiles_x and n_y == y: rect.width += width n_tiles_x += 1 excluded_tiles.append((n_x, n_y)) if abs(n_y - y) == n_tiles_y and n_x == x: rect.height += height n_tiles_y += 1 excluded_tiles.append((n_x, n_y)) self.platforms.append(Platform(rect, layer)) self.create_platforms_rect([t for t in tiles if not t in excluded_tiles], layer)
def init (self): n_pads = pg.joystick.get_count() if n_pads == 0: img = 'nopads' elif n_pads == 1: img = '1pad' else: img = '2pads' gm_r = Rect((0, 0), self.graphics.size) frame = gm_r.inflate(*(-2 * w for w in conf.INTRO_FRAME_WIDTH)) viewport = GraphicsManager(self.scheduler, frame.size) setup_bg(viewport, 1, self.scheduler) text = Graphic('intro-{0}.png'.format(img)) viewport.add(text) text.align() self.graphics.add( util.tile_graphic(Graphic('solid.png'), gm_r, 1), viewport ) viewport.align() for i in xrange(n_pads): pg.joystick.Joystick(i).init() self.evthandler.add((pg.KEYDOWN, pg.JOYBUTTONDOWN, lambda: conf.GAME.switch_world(Level)))
def draw_round_border(surface, width=4, color=None, bounds=None): """draw_round_border(Surface, line_width, Color, Rect) => None only Surface is required""" h = surface.get_height() w = surface.get_width() img = dialog.circle_border_image if color == None: color = pygame.color.Color("white") if bounds == None: bounds = surface.get_rect() r = Rect(0,0,8,8) border = bounds.inflate(-8,-8) border.topleft = bounds.topleft surface.blit(img, border.topleft, r) r.top = 8 surface.blit(img, border.bottomleft, r) r.left = 8 surface.blit(img, border.bottomright, r) r.top = 0 surface.blit(img, border.topright, r) i = bounds.inflate(-17,-17) o = bounds.inflate(-3,-3) o.topleft = bounds.topleft draw.line(surface, color, (i.left,o.top),(i.right,o.top), 4 ) draw.line(surface, color, (o.left,i.top),(o.left,i.bottom), 4 ) draw.line(surface, color, (i.left,o.bottom),(i.right,o.bottom), 4 ) draw.line(surface, color, (o.right,i.top),(o.right,i.bottom), 4 )
class CircleUnionObject(PhysicsObject): def __init__(self,particle,color): ''' Constructor ''' PhysicsObject.__init__(self,particle) self.rect = Rect(0,0,0,0) for c in particle.collider.colliders: radius = int(c.r) rect = pygame.Rect(c.p.x-radius,c.p.y-radius,radius*2+1, radius*2+1) self.rect.union_ip(rect) self.original = pygame.surface.Surface([self.rect.width,self.rect.height],SRCALPHA) for c in particle.collider.colliders: radius = int(c.r) x = int(c.p.x) y = int(c.p.y) pygame.gfxdraw.aacircle(self.original, x-self.rect.left,y-self.rect.top,radius,color) pygame.gfxdraw.filled_circle(self.original,x-self.rect.left,y-self.rect.top,radius,color) self.view = self.original self.update()
def draw_sprite(self, sprite, ratio=None): if ratio is None: ratio = self.ratio # calculate the size of the shadow w = sprite.rect.width * ratio + 1 h = w/2 rect = Rect(0,0,w,h) # shrink the shadow according to height if hasattr(sprite, "height"): height0 = sprite.__class__.height ratio = (height0 - sprite.height) / float(height0) rect.width = max(8, rect.width * ratio) rect.height = max(4, rect.height * ratio) # move the the midbottom of the sprite rect.center = sprite.rect.midbottom rect.x -= 1 rect.y -= 3 # if the sprite has a height property, use it to move the shadow if hasattr(sprite, "height"): rect.y += sprite.height # draw to the layer pygame.draw.ellipse(self._layer, self.color, rect)
def grow_rect(self, rect, growth, rects, direction): """Tries to grow a rectangle in the specified direction Returns whether the growth succeeded""" changed = False if growth[direction]: left, top, width, height = rect.x, rect.y, rect.w, rect.h if direction == LEFT: left -= 1 width += 1 elif direction == RIGHT: width += 1 elif direction == DOWN: height += 1 elif direction == UP: top -= 1 height += 1 new = Rect(left, top, width, height) if not (set(util.points_in(new)) - self.space) and len(new.collidelistall(rects)) == 1: rect.left = left rect.width = width rect.top = top rect.height = height changed = True #if rect.width >= 8 and rect.height >= 8 and random.randrange(5) == 0: # growth[direction] = False else: growth[direction] = False return changed
def __init__(self, pygameWindow,gameVariable,images): # bool hodnoty self.notOver = True self.startGame = False self.closeGame = False self.loadGame = False self.gameVariable = gameVariable # okno self.window = pygameWindow self.images = images #velkosti self.rectWidth = pygameWindow.get_width() / 3 self.rectHeight = pygameWindow.get_height() / 10 self.rectX = (pygameWindow.get_width() / 2) - (self.rectWidth / 2) # Rect(top,left, width, height) self.nazovHryRect = Rect(0,0,self.window.get_width(),pygameWindow.get_height()/3) self.newGameRect = Rect(self.rectX, 150, self.rectWidth, self.rectHeight) self.loadGameRect = Rect(self.rectX, 250, self.rectWidth, self.rectHeight) self.exitRect = Rect(self.rectX, 350, self.rectWidth, self.rectHeight) # font a texty font.init() self.font = font.SysFont("norasi",int(self.rectHeight/2)) #iniclializacia lablov self._initLabel()
def bar(self, surface, text, pos, w=300): rect = Rect(pos, (w, 60)) draw.rect(surface, (0, 200, 200), rect) sf = font.SysFont('blah', 60, bold=False, italic=False) txt = sf.render(text, True, (0, 0, 0)) surface.blit(txt, rect.inflate(-10, -10))
def _prepare_sprite(self, sprite): """Prepare a sprite before drawing. Return the corresponding rectangle. """ # Aliases old_rect_dct = self.spritedict use_update = self._use_update # Test dirty rects try: sprite.dirty_rects except AttributeError: sprite.dirty_rects = None # Update dirtyness if not sprite.dirty and sprite.dirty_rects: sprite.dirty = 1 # Get actual size try: size_rect = Rect((0,0), sprite.source_rect.size) except AttributeError: size_rect = Rect((0,0), sprite.rect.size) # Compare rect new_rect = size_rect.move(sprite.rect.topleft) has_moved = new_rect != old_rect_dct[sprite] # Whole rect is dirty if not use_update or has_moved or sprite.dirty_rects is None: sprite.dirty_rects = [size_rect] return new_rect # Clip the dirty rects for k, area in enumerate(sprite.dirty_rects): sprite.dirty_rects[k] = area.clip(size_rect) # Return return new_rect
def update_world_window(self, screen, world_s, camera, floor_s, map_data): blit_area = Rect(0, 0, 64, 64) # Get the dirty tile -coordinates from map_data for dirty_tile_position in map_data.get_dirty_tile_positions: # Calculate the screen position for given tile dirty_world_position = world_pos_of_tile(dirty_tile_position) area_x, area_y = dirty_tile_position blit_area.topleft = (area_x * 64, area_y * 64) # Blit the tile from floor, to screen. world_s.blit(floor_s, dirty_world_position, blit_area) # Blit items in the tile # Try if this position contains a list of items. Note: these may fail :s items_in_position = map_data.get_items_on_position(dirty_tile_position) if items_in_position is not None: self.draw_items_on_tile(world_s, items_in_position, dirty_world_position) # Blit character in here. character = map_data.get_character_on_position(dirty_tile_position) if character is not None: world_s.blit(character.surface, dirty_world_position) camera_rectangle = camera.get_viewport_rect assert isinstance(camera_rectangle, Rect) screen.blit(world_s, (16,16), area=world_rect_of_tile_rect(camera_rectangle)) map_data.reset_dirty_tiles()
def update(self, image, basePos, width, height): xb, yb = basePos if self.ship.armor != self.hp1: if abs(self.ship.armor - self.hp1) > 5: # new damage self.hp2 = self.hp1 self.hp1 = self.ship.armor self.t = 0 else: self.hp1 = self.ship.armor if self.t < self.maxT1: if self.t + self.dt >= self.maxT1: self.dhp = (self.hp1 - self.hp2) / (self.maxT2 - self.maxT1) elif self.t < self.maxT2: self.hp2 += self.dhp * self.dt else: self.hp2 = self.hp1 self.t += self.dt hp1, hp2 = self.hp1, self.hp2 rect = Rect((0, 0), (width, hp1/config.MaxArmor * height)) rect.bottomleft = (xb, yb) pygame.draw.rect(image, self.HPColor, rect) if hp1 < hp2: rect.size = (width, (hp2 - hp1)/config.MaxArmor * height) rect.bottomleft = (xb,1 + yb - hp1/config.MaxArmor * height) pygame.draw.rect(image, self.HPColorDamage, rect)
def scroll_down_rect(self): d = self.scroll_button_size r = Rect(0, 0, d, d) m = self.margin r.bottom = self.height - m r.right = self.width - m r.inflate_ip(-4, -4) return r
def scroll_up_rect(self): d = self.scroll_button_size r = Rect(0, 0, d, d) m = self.margin r.top = m r.right = self.width - m r.inflate_ip(-4, -4) return r
def set_pos(self, pos): self.rect = Rect(pos, (64, 40))
def calculate_rect(self, position): width = self.size[0] * self.cut[0] height = self.size[1] * self.cut[1] return Rect(position, (width, height))
def shift_by_topleft(self, rect: pg.Rect) -> pg.Rect: return rect.move(self.rect.topleft)
def stick_to(self, target, target_side, self_side, align=True): """Sides must be either 'top', 'bottom, 'left' or 'right'. This function moves self in order to make its <self_side> just next to target's <target_side>. Note that unless <align> = True, this does not move self along the orthogonal axis: e.g, stick_to(target_element, 'right', 'left') will move self such that self.left = target.right (using storers rects), but self.top might not be target.top. Then this is up to the user to move self on the vertical axis once self is sticked to target. <target> can either be an element, "screen" or a rect. """ r = self.get_storer_rect() topleft = r.topleft size = r.size if target == "screen": W, H = functions.get_screen_size() t = Rect(0, 0, W, H) elif isinstance(target, Rect): t = target else: t = target.get_storer_rect() target_topleft = t.topleft target_size = t.size if target_side == "left": sx = topleft[0] tx = target_topleft[0] if self_side == "right": sx += size[0] self.move((tx - sx, 0)) elif target_side == "right": sx = topleft[0] tx = target_topleft[0] + target_size[0] if self_side == "right": sx += size[0] self.move((tx - sx, 0)) elif target_side == "left": sx = topleft[0] tx = target_topleft[0] if self_side == "right": sx += size[0] self.move((tx - sx, 0)) elif target_side == "bottom": sy = topleft[1] ty = target_topleft[1] + target_size[1] if self_side == "bottom": sy += size[1] self.move((0, ty - sy)) elif target_side == "top": sy = topleft[1] ty = target_topleft[1] if self_side == "bottom": sy += size[1] self.move((0, ty - sy)) else: raise Exception("not possible") if align: if target_side == "top" or target_side == "bottom": self.set_center((t.centerx, None)) else: self.set_center((None, t.centery))
class PlayerCommand: """ Display pannel for player input/output Controls display area for player input/output """ def __init__(self): self.msg1 = "text area 1" self.msg2 = "text area 2" self.msg3 = "text area 3" self.x = 50 self.width = 20 self.offset = 0 self.back_color = "black" self.message_rect = Rect(600, 0, SCREEN_WIDTH, SCREEN_HEIGHT) self.message_size = (int(self.message_rect[2]) - self.message_rect[0], int(self.message_rect[3])) self.unit_group_rect = Rect(630, 150, 15, 15) self.player_msg = "Player message here" self.tick_counter = "Ticks here" def msg_to_player(self, screen): """ tracks and handles messages to player """ message1_sf = DEFAULT_GAME_FONT.render(self.player_msg, True, Color('white')) screen.blit(message1_sf, (20, 550, SCREEN_WIDTH, SCREEN_HEIGHT)) """ tick counter """ message2_sf = DEFAULT_GAME_FONT.render(self.tick_counter, True, Color('white')) screen.blit(message2_sf, (20, 20, SCREEN_WIDTH, SCREEN_HEIGHT)) def draw_messageboard(self, screen): self.draw_rimmed_box(screen, self.message_rect, (self.x, self.width, self.offset), 4, Color(self.back_color)) DEFAULT_GAME_FONT = pygame.font.SysFont('arial', 18) message1_sf = DEFAULT_GAME_FONT.render(self.msg1, True, Color('white')) message2_sf = DEFAULT_GAME_FONT.render(self.msg2, True, Color('white')) message3_sf = DEFAULT_GAME_FONT.render(self.msg3, True, Color('white')) message4 = "Heroes: " + str(HERO_WINS) message4_sf = DEFAULT_GAME_FONT.render(message4, True, Color('white')) message5 = "Enemies: " + str(ENEMY_WINS) message5_sf = DEFAULT_GAME_FONT.render(message5, True, Color('white')) screen.blit(message1_sf, self.message_rect.move(0, message1_sf.get_height())) screen.blit(message2_sf, self.message_rect.move(0, message2_sf.get_height() * 2)) screen.blit(message3_sf, self.message_rect.move(0, message2_sf.get_height() * 3)) screen.blit(message4_sf, self.message_rect.move(0, message4_sf.get_height() * 4)) screen.blit(message5_sf, self.message_rect.move(0, message5_sf.get_height() * 5)) self.msg_to_player(screen) def draw_player_units(self, screen, unit_group): """ blits player unit text to output display window """ self.draw_rimmed_box(screen, Rect(600, 150, SCREEN_WIDTH, SCREEN_HEIGHT), (self.x, self.width, self.offset), 4, Color(self.back_color)) DEFAULT_GAME_FONT = pygame.font.SysFont('arial', 12) offset = 0 for unit in unit_group: message1_sf = DEFAULT_GAME_FONT.render(unit.info_msg1, True, Color('white')) message1_status = DEFAULT_GAME_FONT.render(unit.txt_status, True, Color('white')) message2_sf = DEFAULT_GAME_FONT.render(unit.info_msg2, True, Color('white')) screen.blit( message1_sf, self.unit_group_rect.move( 0, message1_sf.get_height() * 1 + offset * 24)) screen.blit( message1_status, self.unit_group_rect.move( 100, message1_status.get_height() * 1 + offset * 24)) screen.blit( message2_sf, self.unit_group_rect.move( 0, message2_sf.get_height() * 2 + offset * 24)) for button in unit.unit_btns: button.draw(screen) offset += 2 def draw_rimmed_box(self, screen, box_rect, box_color, rim_width=0, rim_color=Color('black')): """ Draw a rimmed box on the given surface. The rim is drawn outside the box rect. """ if rim_width: rim_rect = Rect(box_rect.left - rim_width, box_rect.top - rim_width, box_rect.width + rim_width * 2, box_rect.height + rim_width * 2) pygame.draw.rect(screen, rim_color, rim_rect) pygame.draw.rect(screen, box_color, box_rect) def in_field(self, pos): """ verify if clicked pos is in playable grid area - returns True/False """ loc = self.coord_to_grid(pos) if loc[0] < 0 or loc[0] >= self.x or loc[1] < 0 or \ loc[1] >= GRID_SIZE[1]: #print("you missed the player_command grid") return (False) else: return (True) def grid_clicked(self, pos): """ tells what grid was clicked on and reports for testing purposes pos: the passed mouse coordinates variable passed through """ if self.in_field(pos): #print("click is in player_command field") #print("pos clicked:", pos) dummy = False ################################################################################ ## TEST ################################################################################ # # if __name__ == "__main__": # # screen = pygame.display.set_mode((params.SCREEN_WIDTH, params.SCREEN_HEIGHT), 0, 32) # create screen area for tiles # # #pawn = SimpleUnit() # pawn_group = SimpleUnitGroup(screen) # for unit in pawn_group.group_list: # print("unit loc:", unit.loc) # #test loop to give coords to units # for unit in pawn_group.group_list: # unit.targ_tile = (25,25) # unit.active = True # print("status:") # test of status message update # print(unit.info_msg1) # test of status message update # print(unit.info_msg2) # test of status message update # #test loop to move units # unit.move_unit() # for unit in pawn_group.group_list: # check locations again to see if moved # print("unit loc:", unit.loc) # # # test player groups - test works # # all_players = PlayerUnitGroup(screen) # - These lines are the lines to call/create the players & units for a game # # all_players.print_all_player_units() # Test to print all player units to shell - works # # all_players.update_players() # Test of update logic path # # print() # print("-- TEST DONE --") # print() # pygame.quit() # sys.exit()
class Node: def __init__(self, index, rect): self.state = 0 self.index = index self.came_from = None self.rect = Rect(rect) # Heuristic serch stuff self.came_from_cost = 0 self.goal_cost = None # weight search stuff self.weight = 0 def is_pressed(self, mouse_pos): if self.rect.collidepoint(mouse_pos): return True def get_colour(self): if self.state == EMPTY_NODE: weight_colour = (0, self.weight, self.weight) return weight_colour return COLOURS[self.state] def calculate_gradient(self, start_node, start_colour): diff = abs(start_node.index[0] - self.index[0]) + abs(start_node.index[1] - self.index[1]) new_colour = start_colour new_colour[0] = abs(int(diff * (255 / (ROW * 2)))) return new_colour def set_state(self, node_state): self.state = node_state def set_came_from(self, came_from_node): self.came_from = came_from_node self.came_from_cost = self.calculate_came_from_cost(came_from_node) def clear_came_from(self): self.came_from = None self.came_from_cost = 0 def calculate_came_from_cost(self, came_from_node): diff = (self.index[0] - came_from_node.index[0], self.index[1] - came_from_node.index[1]) came_from_to = math.sqrt(diff[0]**2 + diff[1]**2) * 10 return came_from_node.get_came_from_cost() + math.floor(came_from_to) def calculate_goal_cost(self, end_node, multiplier): diff = (self.index[0] - end_node.index[0], self.index[1] - end_node.index[1]) # self.goal_cost = abs(diff[0]) + abs(diff[1]) # manhattan distance self.goal_cost = math.floor( math.sqrt(diff[0]**2 + diff[1]**2) * multiplier) def turn_into_wall(self): if self.state == EMPTY_NODE: self.set_state(WALL_NODE) def from_wall_turn_into_empty(self): if self.state == WALL_NODE: self.set_state(EMPTY_NODE) def get_came_from_cost(self): return self.came_from_cost def get_goal_cost(self): return self.goal_cost
def _set_pos(self, val: Tuple[int, int]) -> None: '''Set the position of the panel's top-left corner.''' self._x, self._y = val self._pos = val self._rect = Rect(val, self._size)
def __init__(self, lerp=5, width=config.XWIN, height=config.YWIN): self.state = Rect(0, 0, width, height) self.lerp = lerp self.center = height // 2 self.maxheight = self.center
def __init__(self): super().__init__() self.name = "RectRenderer" self.colour = (255, 0, 0) self.extent = Vector2(0, 0) self.rect = Rect(0, 0, 0, 0)
class Game: DEFAULT_RECT_SIZE = 40 DEFAULT_RECT = Rect(0, 0, DEFAULT_RECT_SIZE, DEFAULT_RECT_SIZE)
def __init__(self, gui) -> None: """ Creates a button with attributes Note: If colour is none then the button is invisible on_click is a function that will exectute when the button has been pressed """ self.gui = gui # Title self.title_rect = Rect(120, self.gui.height // 8, self.gui.width // 2, self.gui.width // 2 * 244 / 925) self.title_rect.centerx = self.gui.width // 2 self.game_title = pygame.image.load('assets/A45.png').convert_alpha() self.game_title = pygame.transform.smoothscale( self.game_title, self.title_rect.size) # Start 2 Player Button two_player_rect = Rect(0, 0, 200, 50) two_player_rect.centerx = self.gui.width // 2 two_player_rect.centery = self.gui.height // 2 - 50 two_player_button = Button(two_player_rect, self.gui.start_game_two_player, (255, 255, 255), '2 Player') # Start AI Easy Button easy_rect = Rect(0, 0, 200, 50) easy_rect.centerx = self.gui.width // 2 easy_rect.centery = self.gui.height // 2 + 50 easy_button = Button(easy_rect, self.gui.start_game_easy, (255, 255, 255), 'Easy AI') # Start AI Hard Button hard_rect = Rect(0, 0, 200, 50) hard_rect.centerx = self.gui.width // 2 hard_rect.centery = self.gui.height // 2 + 150 hard_button = Button(hard_rect, self.gui.start_game_hard, (255, 255, 255), 'Hard AI') # Quit Button end_rect = Rect(0, 0, 200, 50) end_rect.centerx = self.gui.width // 2 end_rect.centery = self.gui.height // 2 + 250 end_game_button = Button(end_rect, self.gui.end_game, (255, 255, 255), 'Quit Game') self.buttons = [] self.buttons.append(two_player_button) self.buttons.append(easy_button) self.buttons.append(hard_button) self.buttons.append(end_game_button)
def __init__(self, game, **kwds): Widget.__init__(self, Rect(0, 0, 16, 16), **kwds) self.game = game
def __init__(self, x, y, width, height, image): super().__init__() self.rect = Rect(x, y, width, height) self.image = image
ghost = Ghost(self) skeleton = Skeleton(self) self.level.all.add(ghost) self.level.all.add(skeleton) ghost.visible() skeleton.visible() Basic_Actor.kill(self) def damage(self, damage): '''Damage the caveman. If the energy becomes negative he dies.''' self.energy -= damage if self.energy < 0: self.kill() SCREENRECT = Rect(0, 0, 800, 600) from pygame.locals import * random.seed(100) #print "seed" #class Volador(Basic_Actor): #image=None #_images=[] #def __init__(self, initial_position, AI): #Basic_Actor.__init__(self) #if Volador.image is None: #Volador._images=cargar_secuencia("voladorAnim.png", 5) #Volador.image = Volador._images[0][0]
def _render(self): s = self._background.copy() fill_width = (self.width - 4) * (1.0 * self.value / self.maxvalue) pygame.draw.rect(s, Color("blue"), Rect(2,2,fill_width, self.height - 4)) return s
def _set_size(self, val: Tuple[int, int]): '''Set the panel's size.''' self._w, self._h = val self._size = val self._rect = Rect(self._pos, val)
def __init__(self, **kwds): Widget.__init__(self, Rect((0, 0), (100, 20)), **kwds)
def update(self, surface, rect=Rect(0, 0, 0, 0)): self.surface = surface self.rect = rect
def active_rect(self): size = self.surface.get_height() return Rect(self.active_frame * size, 0, size, size)
def __init__(self, screen, font, x, y, width, height, message): pygame.draw.rect(screen, BUTTON_COLOUR, [x, y, width, height]) button_text = font.render(message, False, BUTTON_TEXT_COLOUR) screen.blit(button_text, (x, y)) self.rect = Rect(x, y, width, height)
def rect(self, position): rect = Rect(0, 0, self.width, self.height) rect.center = (round(position.x), round(position.y)) return rect
class Ball: def __init__(self, screen_W, screen_H): """ Ball instanciation """ self.HEIGHT = screen_H // 100 # Player height self.WIDTH = self.HEIGHT # Ball width self.screen_W = screen_W self.screen_H = screen_H self.rect = Rect( screen_W // 2 - self.WIDTH // 2, # left screen_H // 2 - self.HEIGHT // 2, # top self.WIDTH, # width self.HEIGHT, # height ) self.radius = self.HEIGHT // 2 self.direction = Vector2(0, 1) self.speed = 0.5 def get_center(self): """ Return graphical (x, y) center of the ball """ return (self.rect.left + self.radius, self.rect.top + self.radius) def reset_pos(self): """ Reset ball position to beginning """ self.rect.top = self.screen_H // 2 - self.HEIGHT // 2 self.rect.left = self.screen_W // 2 - self.WIDTH // 2 self.direction = Vector2(0, 1) def move(self, player, blocks_grid, dt): """ Collision check to update direction, and update self.rect accordingly """ # Bottom wall collision detection : game over if self.rect.top + self.rect.height > self.screen_H: return True # Player collision check if self.rect.colliderect(player.rect): ball_center = self.rect.left + self.radius player_center = player.rect.left + player.rect.width // 2 coeff = (ball_center - player_center) / player.rect.width self.direction = -self.direction self.direction.x = coeff * 1.5 # Block collision for block in blocks_grid.blocks: if self.rect.colliderect(block): new_direction = self.direction # Vertical if (block.rect.left < self.rect.left + self.radius < block.rect.left + block.rect.width): # Bottom collision if (block.rect.top + block.rect.height * 4 / 5 < self.rect.top): new_direction = Vector2(0, 1) # Top collision else: new_direction = Vector2(0, -1) # Horizontal elif (block.rect.top < self.rect.top + self.radius < block.rect.top + block.rect.height): # Right collision if (block.rect.left + block.rect.width * 4 / 5 < self.rect.left): new_direction = Vector2(1, 0) # Left collision else: new_direction = Vector2(-1, 0) # Top left corner elif (self.get_center()[0] <= block.rect.left and self.get_center()[1] <= block.rect.top): new_direction = Vector2(-1, -1).normalize() # Top right corner elif (block.rect.left + block.rect.width <= self.get_center()[0] and self.get_center()[1] <= block.rect.top): new_direction = Vector2(1, -1).normalize() # Bottom left corner elif (self.get_center()[0] <= block.rect.left and block.rect.top + block.rect.height <= self.get_center()[1]): new_direction = Vector2(-1, 1).normalize() # Bottom right corner elif (block.rect.left + block.rect.width <= self.get_center()[0] and block.rect.top + block.rect.height <= self.get_center()[1]): new_direction = Vector2(1, 1).normalize() self.direction = 2 * new_direction + self.direction blocks_grid.remove_block(block) # Top wall collision check if self.rect.top < 1: self.direction = 2 * Vector2(0, 1) + self.direction # Left wall collision check if self.rect.left < 1: self.direction = 2 * Vector2(1, 0) + self.direction # Right wall collision check if self.rect.left + self.rect.width > self.screen_W - 1: self.direction = 2 * Vector2(-1, 0) + self.direction self.direction = self.direction.normalize() # Update position self.rect.left += self.direction.x * self.speed * dt self.rect.top += self.direction.y * self.speed * dt return False def draw(self, window): """ Draw ball """ center = (self.rect.left + self.radius, self.rect.top + self.radius) pygame.draw.circle(window, (255, 0, 0), center, self.radius)
def test_inside(self, inner: pygame.Rect, outside: pygame.Rect, flag): return outside.collidepoint(inner.topleft[0], inner.topleft[1]) and \ outside.collidepoint(inner.topright[0], inner.topright[1]) and \ outside.collidepoint(inner.bottomleft[0], inner.bottomleft[1]) and \ outside.collidepoint(inner.bottomright[0], inner.bottomright[1])
def getRect(self): return Rect(self.position[0], self.position[1], self.getWidth(), self.height)
circle_width = 0 # 設定矩形參數 rect_color = (233, 30, 99) rect_pos_x = 400 rect_pos_y = 200 rect_width = 200 rect_height = 150 while 1: # 偵測事件 for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # 更新遊戲資料 # TODO Task1 & 2 # 更新遊戲畫面 screen.fill(background_color) # 畫圓 pygame.draw.circle(screen, circle_color, circle_pos, circle_radius, circle_width) # 畫方 pygame.draw.rect(screen, rect_color, Rect(rect_pos_x, rect_pos_y, rect_width, rect_height)) pygame.display.flip() clock.tick(10)
def get_rect(self, location): return Rect(location[0] * self.cut[0] + self.rect.x, location[1] * self.cut[1] + self.rect.y, self.slice[0], self.slice[1])
class Panel: ''' A class to represent an interactable UI panel. Attributes: x (int): The x-coordinate of the panel's top-left corner y (int): The y-coordinate of the panel's top-left corner pos (Tuple[int, int]): The position of the panel's top-left corner w (int): The width of the panel h (int): The height of the panel size (Tuple[int, int]): The size of the panel rect (Rect): The rect that describes the area occupied by the panel label (object): The object that labels the panel hovered (bool): A flag indicating if the mouse is over the panel ''' def __init__(self, label: object, pos: Tuple[int, int] = (0, 0), size: Tuple[int, int] = (0, 0)): ''' Initialize the Panel object. Attributes: label: The object that labels the panel pos: The position of the panel's top-left corner (default (0, 0)) size: The size of the panel (default (0, 0)) ''' self._x, self._y = pos self._pos = pos self._w, self._h = size self._size = size self._rect = Rect(pos, size) self._label = label self._hovered = False def _get_pos(self) -> Tuple[int, int]: '''Get the position of the panel's top-left corner.''' return self._pos def _set_pos(self, val: Tuple[int, int]) -> None: '''Set the position of the panel's top-left corner.''' self._x, self._y = val self._pos = val self._rect = Rect(val, self._size) pos = property(_get_pos, _set_pos) def center_on(self, center: Tuple[int, int]) -> None: '''Center the panel on a position.''' x = center[0] - self._w // 2 y = center[1] - self._h // 2 self.pos = x, y def _get_size(self) -> Tuple[int, int]: '''Get the panel's size.''' return self._size def _set_size(self, val: Tuple[int, int]): '''Set the panel's size.''' self._w, self._h = val self._size = val self._rect = Rect(self._pos, val) size = property(_get_size, _set_size) def collides(self, collision_pos: Tuple[int, int]) -> bool: '''Detect if a position collides with the panel.''' return self._rect.collidepoint(collision_pos) def handle_click(self, event: Event) -> None: '''Handle a click interaction with the panel.''' pass def handle_hover(self, mouse_pos: Tuple[int, int]) -> None: '''Handle a hover interaction with the panel.''' self._hovered = True def render(self, buffer: Surface, theme: Theme, active: bool = False, render_label: bool = True, render_border: bool = True) -> None: ''' Render panel on to the buffer using the theme. Parameters: buffer: the pygame surface to render on to theme: the color and layout scheme to use for rendering active: boolean indicating if the active color should be used render_label: boolean indicating if the label should be rendered render_border: boolean indicating if the border should be rendered ''' if active: bg_col = theme.act_col else: bg_col = theme.bg_col draw.rect(buffer, bg_col, self._rect, border_radius=theme.bord_r) if render_border: draw.rect(buffer, theme.bord_col, self._rect, theme.bord_w, theme.bord_r) if render_label: label = theme.large_text(self._label) label_x = self._rect.centerx - label.get_width() // 2 label_y = self._rect.centery - label.get_height() // 2 buffer.blit(label, (label_x, label_y)) self._hovered = False
def appendSnake(self): # add node to tail newSnakeLink = Rect((self.snake[len(self.snake) - 1].x, self.snake[len( self.snake) - 1].y), (self.gameUnitsize, self.gameUnitsize)) self.snake.append(newSnakeLink)
def init_wind(self, w, h, dir): x, y = 0, 0 # self.pos[0], self.pos[1] scale_list = [ (Rect(0, 0, 128, 128), (w - 4, h - 4), Rect(x + 2, y + 2, w - 4, h - 4)), # back (Rect(144, 0, 32, 16), (w - 32, 16), Rect(x + 16, y, w - 32, 16)), # top (Rect(128, 16, 16, 32), (16, h - 32), Rect(x, y + 16, 16, h - 32)), # left (Rect(176, 16, 16, 32), (16, h - 32), Rect(x + w - 16, y + 16, 16, h - 32)), # right (Rect(144, 48, 32, 16), (w - 32, 16), Rect(x + 16, y + h - 16, w - 32, 16)), # bottom (Rect(128, 0, 16, 16), Rect(x, y, 16, 16)), # top left (Rect(176, 0, 16, 16), Rect(x + w - 16, y, 16, 16)), # top right (Rect(128, 48, 16, 16), Rect(x, y + h - 16, 16, 16)), # bottom left (Rect(176, 48, 16, 16), Rect(x + w - 16, y + h - 16, 16, 16)), # bottom right ] src_dir = { "up": (Rect(128, 96, 32, 32), Rect(x + int(w / 2), y + h - 3, 32, 32)), "down": (Rect(160, 96, 32, 32), Rect(x + int(w / 2), y - 29, 32, 32)) } if dir is not None: scale_list.append(src_dir[dir]) blit_list = [self.trans_image(fmt) for fmt in scale_list] ret = Surface([w, h]) for l1, l2 in blit_list: ret.blit(l1, l2) # ret.blits(blit_list) return ret
def _create_background(self): s = pygame.Surface((self.width, self.height)) s.fill(self.bgcolor) pygame.draw.rect(s, Color("white"), Rect(0,0,self.width,self.height), 2) self._background = s
def get_aa_round_rect(size, radius, color): surface = Surface(size, flags=SRCALPHA).convert_alpha() rect = Rect((0, 0), size) color = Color(*color) alpha = color.a color.a = 0 rectangle = Surface(size, SRCALPHA) #here 5 is an arbitrary multiplier, we will just rescale later circle = Surface([min(size) * 5, min(size) * 5], SRCALPHA) draw.ellipse(circle, (0,0,0), circle.get_rect(), 0) circle = transform.smoothscale(circle, (2*radius, 2*radius)) #now circle is just a small circle of radius #blit topleft circle: radius_rect = rectangle.blit(circle, (0, 0)) #now radius_rect = Rect((0, 0), circle.size), rect=Rect((0, 0), size) #blit bottomright circle: radius_rect.bottomright = rect.bottomright #radius_rect is growing rectangle.blit(circle, radius_rect) #blit topright circle: radius_rect.topright = rect.topright rectangle.blit(circle, radius_rect) #blit bottomleft circle: radius_rect.bottomleft = rect.bottomleft rectangle.blit(circle, radius_rect) #black-fill of the internal rect rectangle.fill((0, 0, 0), rect.inflate(-radius_rect.w, 0)) rectangle.fill((0, 0, 0), rect.inflate(0, -radius_rect.h)) #fill with color using blend_rgba_max rectangle.fill(color, special_flags=BLEND_RGBA_MAX) #fill with alpha-withe using blend_rgba_min in order to make transparent #the rectangle.fill((255, 255, 255, alpha), special_flags=BLEND_RGBA_MIN) surface.blit(rectangle, rect.topleft) return surface
def get_monsters_in_range(self, x1, y1, rnge): area = Rect(x1 - rnge, y1 - rnge, 2 * rnge, 2 * rnge) for monster in self.arena.creeps: x2, y2 = monster.rect.center if area.collidepoint((x2, y2)): if sqrt((x1-x2) ** 2 + (y1-y2) ** 2) < rnge: yield monster