class StoreIcon(QGraphicsPixmapItem): def __init__(self, parent=None): super().__init__() # bool to check if it is available self.available = False # set store gui self.gui = Store() # set graphics self.setPixmap(QPixmap('./res/imgs/blue_chest.png').scaled(80, 80, Qt.KeepAspectRatio)) # create points vector points = [QPointF(1, 0), QPointF(2, 0), QPointF(3, 1), QPointF(3, 2), QPointF(2, 3), QPointF(1, 3), QPointF(0, 2), QPointF(0, 1)] # scale points SCALE_FACTOR = 100 points = [p * SCALE_FACTOR for p in points] # create polygon self.polygon = QPolygonF(points) # create QGraphicsPolygonItem self.available_area = QGraphicsPolygonItem(self.polygon, self) self.available_area.setPen(QPen(Qt.DotLine)) # move the polygon poly_center = QPointF(1.5 * SCALE_FACTOR, 1.5 * SCALE_FACTOR) poly_center = self.mapToScene(poly_center) store_center = QPointF(self.x() + 40, self.y() + 40) ln = QLineF(poly_center, store_center) self.available_area.setPos(self.x() + ln.dx(), self.y() + ln.dy()) # connect the timer to acquire_champion self.timer = QTimer() self.timer.timeout.connect(self.acquire_champion) self.timer.start(1000) def mousePressEvent(self, event): if self.available: self.launch_store() def acquire_champion(self): colliding_items = self.available_area.collidingItems() found = False for item in colliding_items: if isinstance(item, PlayerChampion): self.set_available(True) found = True if not found: self.set_available(False) def set_available(self, bool_input): self.available = bool_input if not self.available and self.gui.isVisible(): self.gui.close() def launch_store(self): self.gui.show()
class Tower(StaticGameObject): def __init__(self): super().__init__() # initialize attack range (area) self.attack_area = QGraphicsPolygonItem() self.attack_dest = QPointF(0, 0) self.has_target = False # set the graphics self.setPixmap( QPixmap('./res/imgs/lol_tower.png').scaled(80, 80, Qt.KeepAspectRatio)) # initializes health h = Bar(self) h.set_max_val(250) h.set_current_val(250) self.set_health(h) self.attack = 30 # create points vector points = [ QPointF(1, 0), QPointF(2, 0), QPointF(3, 1), QPointF(3, 2), QPointF(2, 3), QPointF(1, 3), QPointF(0, 2), QPointF(0, 1) ] # scale points SCALE_FACTOR = 100 points = [p * SCALE_FACTOR for p in points] self.range = SCALE_FACTOR # create polygon self.polygon = QPolygonF(points) # create QGraphicsPolygonItem self.attack_area = QGraphicsPolygonItem(self.polygon, self) self.attack_area.setPen(QPen(Qt.DotLine)) # move the polygon poly_center = QPointF(1.5 * SCALE_FACTOR, 1.5 * SCALE_FACTOR) poly_center = self.mapToScene(poly_center) tower_center = QPointF(self.x() + 40, self.y() + 40) ln = QLineF(poly_center, tower_center) self.attack_area.setPos(self.x() + ln.dx(), self.y() + ln.dy()) # connect a timer to acquire target self.damage_timer = QTimer() self.damage_timer.timeout.connect(self.acquire_target) self.damage_timer.start(1000) # allow responding to hover events self.setAcceptHoverEvents(True) def fire(self): if not self.scene(): return bullet = Bullet(self) bullet.setPos(self.x() + 40, self.y() + 40) # set the angle to be paralel to the line that connects the # tower and target ln = QLineF(QPointF(self.x() + 40, self.y() + 40), self.attack_dest) angle = -1 * ln.angle() # -1 to make it clock wise bullet.setRotation(angle) self.scene().addItem(bullet) def acquire_target(self): # get a list of all items colliding with attack area colliding_items = self.attack_area.collidingItems() self.has_target = False closest_dist = 300 closest_point = QPointF(0, 0) for i in colliding_items: if hasattr(i, 'team') and i.team != self.team: this_distance = self.distance_to(i) if this_distance < closest_dist: closest_dist = this_distance closest_point = i.pos() self.has_target = True self.attack_dest = closest_point if self.has_target: self.fire() def distance_to(self, item): '''item: QGraphicsItem ''' ln = QLineF(self.pos(), item.pos()) return ln.length() def hoverEnterEvent(self, event): '''event: QGraphicsSceneHoverEvent ''' # change pixmap if self.team == 2: self.setPixmap( QPixmap('./res/imgs/lol_tower_red.png').scaled( 80, 80, Qt.KeepAspectRatio)) def hoverLeaveEvent(self, event): '''event: QGraphicsSceneHoverEvent ''' # change back pixmap if self.team == 2: self.setPixmap( QPixmap('./res/imgs/lol_tower.png').scaled( 80, 80, Qt.KeepAspectRatio))
class Tower(QGraphicsPixmapItem): SCALE_FACTOR = 300 def __init__(self, parent=None): super(Tower, self).__init__(parent) self.setPixmap(QPixmap(':/Resources/images/Tower.png')) self.setScale(0.5) self.points = [ QPointF(1, 0), QPointF(2, 0), QPointF(3, 1), QPointF(3, 2), QPointF(2, 3), QPointF(1, 3), QPointF(0, 2), QPointF(0, 1) ] for point in self.points: point.setX(point.x() * Tower.SCALE_FACTOR) point.setY(point.y() * Tower.SCALE_FACTOR) self.polygon = QPolygonF(self.points) self.border = QGraphicsPolygonItem(self.polygon, self) # self.border.setPen(QPen(Qt.red)) self.border.setScale(0.5) self.border.setPen(QPen(Qt.DashLine)) self.poly_center = QPointF(1.5, 1.5) self.poly_center *= Tower.SCALE_FACTOR self.poly_center = self.mapToScene(self.poly_center) self.tower_center = QPointF(self.x() + 50, self.y() + 50) self.line = QLineF(self.poly_center, self.tower_center) self.border.setPos(self.border.x() + self.line.dx(), self.border.y() + self.line.dy()) # self.attack_destination = QPointF(800,0) self.timer = QTimer() self.timer.timeout.connect(lambda: self.accquire_target()) self.timer.start(1000) def fire(self): arrow = Arrow() arrow.setPos(self.x(), self.y()) attack_line = QLineF(QPointF(self.x() + 25, self.y() + 25), self.attack_destination) line = QGraphicsLineItem(attack_line) line.setPen(QPen(Qt.blue)) # self.scene().addItem(line) attack_angle = -1 * attack_line.angle( ) # Multiplied by -1 because the angle is given in counter clockwise direction arrow.setRotation(attack_angle) self.scene().addItem(arrow) def distance_to(self, item): distance = QLineF(QPointF(self.pos().x() + 25, self.pos().y() + 25), item.pos()) line = QGraphicsLineItem(distance) line.setPen(QPen(Qt.red)) # self.scene().addItem(line) return distance.length() def accquire_target(self): attack_item = self.border.collidingItems() if (len(attack_item) == 1): self.has_target = False return closet_distance = 300 closet_pt = QPointF(0, 0) for item in attack_item: if isinstance(item, Enemy): distance = self.distance_to(item) if (distance < closet_distance): closet_distance = distance closet_pt = QPointF(item.pos().x() + 50, item.pos().y() + 50) self.has_target = True self.attack_destination = closet_pt self.fire()
class DynamicGameObject(StaticGameObject): '''Class to modelate objects that can move and attack (minions, Ia's champion) ''' def __init__(self): super().__init__() # set speed self.speed = 0 self.attack = 1 # set pos / destination self.x_prev = 0 self.y_prev = 0 self.setPos(0, 0) self.destination = QPointF(0, 0) # initialize attack range (area) self.attack_area = QGraphicsPolygonItem() self.attack_dest = QPointF(0, 0) self.has_target = False def set_range(self, SCALE_FACTOR): '''It gives the object a QGraphicsPolygonItem to attack at a certain range ''' # create points vector self.range = SCALE_FACTOR points = [ QPointF(1, 0), QPointF(2, 0), QPointF(3, 1), QPointF(3, 2), QPointF(2, 3), QPointF(1, 3), QPointF(0, 2), QPointF(0, 1) ] # scale points points = [p * SCALE_FACTOR for p in points] # create polygon self.polygon = QPolygonF(points) # create QGraphicsPolygonItem self.attack_area = QGraphicsPolygonItem(self.polygon, self) self.attack_area.setPen(QPen(Qt.DotLine)) # move the polygon poly_center = QPointF(1.5 * SCALE_FACTOR, 1.5 * SCALE_FACTOR) poly_center = self.mapToScene(poly_center) minion_center = QPointF(self.x() + self.pixmap().width() / 2, self.y() + self.pixmap().height() / 2) ln = QLineF(poly_center, minion_center) self.attack_area.setPos(self.x() + ln.dx(), self.y() + ln.dy()) def fire(self): if not self.scene(): return bullet = Bullet(self) bullet.setPos(self.x() + self.pixmap().width() / 2, self.y() + self.pixmap().height() / 2) # set the angle to be paralel to the line that connects the # tower and target ln = QLineF( QPointF(self.x() + self.pixmap().width() / 2, self.y() + self.pixmap().height() / 2), self.attack_dest) angle = -1 * ln.angle() # -1 to make it clock wise bullet.setRotation(angle) self.scene().addItem(bullet) def acquire_target(self): # get a list of all items colliding with attack area colliding_items = self.attack_area.collidingItems() self.has_target = False closest_dist = 300 closest_point = QPointF(0, 0) for i in colliding_items: if hasattr(i, 'team') and i.team != self.team: this_distance = self.distance_to(i) if this_distance < closest_dist: closest_dist = this_distance closest_point = i.pos() self.has_target = True self.attack_dest = closest_point if self.has_target: self.fire() def set_attack(self, value): self.attack = value def set_destination(self, point): '''QPoinF : point ''' self.destination = point def set_speed(self, s): self.speed = s @property def should_be_moving(self): ln = QLineF(self.pos(), self.destination) CLOSE_DIST = 30 if ln.length() > CLOSE_DIST: return True else: return False def move_forward(self): # move object if self.should_be_moving: ln = QLineF(self.pos(), self.destination) ln.setLength(self.speed) self.rotate_to_point(self.destination) # avoid collision colliding_items = self.collidingItems() for i in colliding_items: if isinstance(i, StaticGameObject): collision_line = QLineF(self.pos(), i.pos()) collision_line.setLength(30) self.setPos(self.x() - collision_line.dx(), self.y() - collision_line.dy()) # move object forward at current angle self.setPos(self.x() + ln.dx(), self.y() + ln.dy()) self.x_prev = self.pos().x() self.y_prev = self.pos().y() def distance_to(self, item): '''item: QGraphicsItem ''' ln = QLineF(self.pos(), item.pos()) return ln.length() def set_dest_to_closest(self): '''Sets destination to closest enemy ''' if not self.scene(): return scene_items = self.scene().items() closest_point = QPointF(0, 0) closest_dist = 1000 for i in scene_items: if hasattr(i, 'team') and i.team != self.team: this_distance = self.distance_to(i) if this_distance < closest_dist: closest_dist = this_distance closest_point = i.pos() self.set_destination(closest_point) def rotate_to_point(self, point): '''point: QPointF''' ln = QLineF(self.pos(), point) # that 90 is because sprite sheet is pointing north self.setRotation(-1 * ln.angle() + 90)