class Triangle(QGraphicsView): def __init__(self, x1, y1, x2, y2, x3, y3): self.x1 = x1 self.y1 = y1 self.x2 = x2 self.y2 = y2 self.x3 = x3 self.y3 = y3 triangle = QtGui.QPolygonF(3) triangle[0] = QtCore.QPoint(self.x1, self.y1) triangle[1] = QtCore.QPoint(self.x2, self.y2) triangle[2] = QtCore.QPoint(self.x3, self.y3) self.triangle = QGraphicsPolygonItem(triangle) def draw_triangle(self, scene): scene.addItem(self.triangle) def move_triangle(self, m, n): self.triangle.setPos(m, n) def rotate_triangle(self, r): self.triangle.setRotation(r) def scale_triangle(self, s): self.triangle.setScale((s + 50) / 100) def recolor_triangle(self, r, g, b): self.triangle.setBrush(QColor(r, g, b))
def initMap(self): features = json.load(open("Data/world.json", encoding="utf8")).get("features") for feature in features: geometry = feature.get("geometry") if not geometry: continue _type = geometry.get("type") coordinates = geometry.get("coordinates") for coordinate in coordinates: if _type == "Polygon": polygon = QPolygonF([ QPointF(latitude, -longitude) for latitude, longitude in coordinate ]) item = QGraphicsPolygonItem(polygon) item.setPen(QPen(self.borderColor, 0)) item.setBrush(QBrush(self.backgroundColor)) item.setPos(0, 0) self._scene.addItem(item) elif _type == "MultiPolygon": for _coordinate in coordinate: polygon = QPolygonF([ QPointF(latitude, -longitude) for latitude, longitude in _coordinate ]) item = QGraphicsPolygonItem(polygon) item.setPen(QPen(self.borderColor, 0)) item.setBrush(QBrush(self.backgroundColor)) item.setPos(0, 0) self._scene.addItem(item)
def on_actItem_Polygon_triggered(self): # 添加一个梯形 item = QGraphicsPolygonItem() points = QPolygonF() points.append(QPointF(-40, -40)) points.append(QPointF(40, -40)) points.append(QPointF(100, 40)) points.append(QPointF(-100, 40)) item.setPolygon(points) item.setPos(-50 + (QtCore.qrand() % 100), -50 + (QtCore.qrand() % 100)) item.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsFocusable) item.setBrush(QBrush(Qt.green)) self.view.frontZ = self.view.frontZ + 1 item.setZValue(self.view.frontZ) self.view.seqNum = self.view.seqNum + 1 item.setData(self.view.ItemId, self.view.seqNum) # //自定义数据,ItemId键 item.setData(self.view.ItemDesciption, "梯形") self.scene.addItem(item) self.scene.clearSelection() item.setSelected(True)
def create_element_model(self, gscene): clut = rgbt.RGBTable(filename='gui/red_blue64.csv', data_range=[10.0, 100.]) ele_model = ele.ElementModel() ele_model.elements_from_sequence(self.seq_model) pen = QPen() pen.setCosmetic(True) for e in ele_model.elements: poly = e.shape() polygon = QPolygonF() for p in poly: polygon.append(QPointF(p[0], p[1])) gpoly = QGraphicsPolygonItem() gpoly.setPolygon(polygon) # set element color based on V-number gc = float(e.medium.glass_code()) vnbr = round(100.0 * (gc - int(gc)), 3) ergb = clut.get_color(vnbr) gpoly.setBrush(QColor(*ergb)) gpoly.setPen(pen) t = e.tfrm[1] gpoly.setPos(QPointF(t[2], -t[1])) gscene.addItem(gpoly)
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(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 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 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)