2016-12-21 3 views
4

В настоящее время я нарисовал две строки на экране, которые имеют один и тот же цвет, но оба имеют значение альфа меньше 1. Когда эти линии пересекаются, другой цвет, чем остальные строки. Был предыдущий пост, рассматривающий тот же вопрос: swift drawing translucent lines, how to make overlapping parts not getting darker? Однако на этот пост недостаточно ответов. Я рисую линии в настоящее время, как это:Swift: Сделать полупрозрачные перекрывающиеся линии одного цвета не меняют цвет при пересечении

var points = [CGPoint]() 

    points = [CGPoint(x: -100, y: 100), CGPoint(x: 100, y: -100)] 
    let FirstLine = SKShapeNode(points: &points, count: points.count) 
    FirstLine.strokeColor = UIColor.init(red: 0.25, green: 0.62, blue: 0.0, alpha: 0.5) 
    FirstLine.lineWidth = 30 
    addChild(FirstLine) 

    points = [CGPoint(x: 100, y: 100), CGPoint(x: -100, y: -100)] 
    let SecondLine = SKShapeNode(points: &points, count: points.count) 
    SecondLine.strokeColor = UIColor.init(red: 0.25, green: 0.62, blue: 0.0, alpha: 0.5) 
    SecondLine.lineWidth = 30 
    addChild(SecondLine) 

Вот как это выглядит:

Я понимаю, почему это происходит, но есть ли способ, чтобы сделать пересечение выглядят одинаково, так что выглядит гораздо лучше?

Редактировать: Я решил реализовать ответ @ Confused. Однако теперь проблема заключается в том, что текстура всегда центрируется до середины экрана. Это пример:

красный крест находится в правильном положении, как он соединяет указанные точки вместе. Однако, как только я делаю красный крест текстурой, он всегда центрируется к середине экрана (зеленый крест - красный крест в виде текстуры). Могу ли я использовать любой код, который мог бы переместить текстуру в правильное положение. Примечание: этот код не может работать только в этом примере, мне нужен тот, который работает все время независимо от положения красного креста.


FINAL ИЗМЕНИТЬ ДЛЯ ЛЮДЕЙ С ТЕМ ЖЕ ПРОБЛЕМА

Во-первых, установка все так:

var points = [CGPoint]() 
let crossParent = SKNode() 
addChild(crossParent) 

Обратите внимание , что вы должны создать родительский SKNode для в противном случае все, что на экране станет текстурой, а не только узлом, который вы хотите. Затем добавьте этот родительский узел в сцену.

После, создать строки, которые вы хотите (в данном случае зеленый крест):

//The first line of the green cross 
points = [CGPoint(x: -300, y: 300), CGPoint(x: -100, y: 100)] 
let FirstLine = SKShapeNode(points: &points, count: points.count) 
FirstLine.strokeColor = UIColor.init(red: 0.25, green: 0.62, blue: 0.0, alpha: 1.0) 
FirstLine.lineWidth = 30 
crossParent.addChild(FirstLine) 

Помните к НЕ добавить первую строку, вы создаете на сцене, а в родительский SKNode, который вы создали в начале. Также установите значение alpha равным 1.0 для каждой линии, которую вы рисуете. Затем добавить другие строки:

//The second line of the green cross 
points = [CGPoint(x: -100, y: 300), CGPoint(x: -300, y: 100)] 
let SecondLine = SKShapeNode(points: &points, count: points.count) 
SecondLine.strokeColor = UIColor.init(red: 0.25, green: 0.62, blue: 0.0, alpha: 1.0) 
SecondLine.lineWidth = 30 
FirstLine.addChild(SecondLine) 

Обратите внимание, что вы должны добавить эту строку в первой строке, как это и не к месту. Если вы добавляете более одной строки после добавления первой строки, добавьте ее в первую строку, как я сделал здесь тоже для каждой последовательной строки , которую вы добавляете.

Теперь создадим текстуру, как это:

let tex = view?.texture(from: FirstLine) 
let cross = SKSpriteNode(texture: tex, color: .clear, size: (tex?.size())!) 
cross.alpha = 0.5 
addChild(cross) 

После этого, все, что вы называете крест будет ваша текстура, и вы можете изменить значение альфа, как я сделал здесь все, что вы хотите получить, а изображение не будет иметь разных цветов. Не забудьте добавить эту текстуру к сцене.

Наконец, вы можете заметить, что текстура находится не в том месте, где вы первоначально ставили точки. Вы можете поместить его обратно в том же положение, как это:

cross.position = CGPoint(x: (FirstLine.frame.midX), y: (FirstLine.frame.midY)) 

Надеется, что это помогает :) Спасибо вам @Confused для текстуры части программы: D


+1

Это происходит потому, что в точке пересечения цвета превышены. Таким образом, вы можете справиться с этим, не используя Alpha <1. Выберите проданный цвет с альфа 1.0, и этого не произойдет. –

+0

@UmairAfzal «Я понимаю, почему это происходит, но есть ли способ сделать пересечение одинаковым, так что он выглядит намного лучше?» Он хочет альфа, не хочет смешивания. – Confused

+0

Являются ли эти линии статичными или движущимися? Есть ли способ объединить 2 SKShapeNodes в один узел, а затем перерисовать его как одну фигуру? Я знаю, что есть способ извлечь текстуру, созданную из спрайта и узла обрезки, и вы можете сгенерировать новый узел из этого. Возможно, поразительная производительность, особенно если это нужно делать много раз в секунду. –

ответ

2

Это техника. Он не решает вашу проблему и не отвечает на ваш вопрос. Вместо этого он предлагает способ получить желаемый результат, но без гибкости и неотъемлемого характера линий, которые вы действительно хотите.

Вы можете создавать текстуры из всего, что вы рисуете с любым количеством узлов, с любым количеством методов.

Вы делаете это (самый простой способ), присоединяя все элементы чертежа к одному узлу в пределах пространства SKView, к которому у вас есть доступ, а затем визуализируйте «родительский» узел ваших нарисованных объектов на текстуру.

Как это помогает?

Я рад, что вы спросили:

Вы можете сделать все на уровне непрозрачности 100%, и вынести его на текстуру, а затем взять эту текстуру ваших рисунков, поместить его там, где вам нравится, и уменьшить его непрозрачность для любого процента, который вам нравится, и получить ровный результат. Нет ярких пятен, где вещи накладываются друг на друга.

Вот код, который делает все выше:

var points = [CGPoint]() 

    points = [CGPoint(x: -100, y: 100), CGPoint(x: 100, y: -100)] 
    let FirstLine = SKShapeNode(points: &points, count: points.count) 
    FirstLine.strokeColor = UIColor.init(red: 0.25, green: 0.62, blue: 0.0, alpha: 1) 
    FirstLine.lineWidth = 30 
//  ^^ Note the FirstLine is not added to the Scene 

    points = [CGPoint(x: 100, y: 100), CGPoint(x: -100, y: -100)] 
    let SecondLine = SKShapeNode(points: &points, count: points.count) 
    SecondLine.strokeColor = UIColor.init(red: 0.25, green: 0.62, blue: 0.0, alpha: 1) 
    SecondLine.lineWidth = 30 
    FirstLine.addChild(SecondLine) 
// ^^ Note SecondLine being added to FirstLine, and that they both have alpha of 1 

// Now the magic: use the view of the SKScene to render FirstLine and its child (SecondLine) 
// They are rendered into a texture, named, imaginatively, "tex" 

    let tex = view.texture(from: FirstLine) 
    let cross = SKSpriteNode(texture: tex, color: .clear, size: (tex?.size())!) 
     cross.alpha = 0.5 

// ^^ The alpha of the above sprite is set to your original desire of 0.5 
// And then added to the scene, with the desired result. 
    addChild(cross) 

и вот результат:

enter image description here

+0

Спасибо! Поскольку это способ, который работает, я каким-то образом попытаюсь реализовать это в своей программе. –

+0

Если у вас возникли проблемы, сообщите мне. Я не эксперт ... но немного понимаю графику. – Confused

+0

Большое спасибо! Теперь я редактировал свой пост с моей проблемой. Спасибо за решение, хотя он работает очень хорошо. Я просто пытаюсь выяснить, как исправить мою проблему сейчас. –

1

НЕТ! Я думаю, что это, к сожалению, ответ.

Существуют следующие режимы смешивания, ни один из которых обеспечивают результат, который вы ищете:

case alpha // Blends the source and destination colors by multiplying the source alpha value. 

case add // Blends the source and destination colors by adding them up. 

case subtract // Blends the source and destination colors by subtracting the source from the destination. 

case multiply // Blends the source and destination colors by multiplying them. 

case multiplyX2 // Blends the source and destination colors by multiplying them and doubling the result. 

case screen // Blends the source and destination colors by multiplying one minus the source with the destination and adding the source. 

case replace // Replaces the destination with the source (ignores alpha). 

Единственный вариант, который может работать обычай шейдер, что цифры, если это перекрывающихся себя, так или иначе. Но у меня нет НИКАКОГО CLUE, чтобы даже начать делать что-то подобное, или если это возможно.

+0

Я увижу эффект от них в моей программе. Благодаря! –

+0

Как я проверял, вы правы, так как ни один из них не дает желаемого эффекта. Должен быть способ достичь этого, хотя, поскольку я думаю, что это будет не редкая проблема. –

+0

Я создал новый пост, который, если он будет решен, может заменить эту проблему. –

1
  1. сделать цвет мазка полностью непрозрачным.
  2. Добавьте свои пути к SKEffectNode.
  3. Установите альфа узла эффекта на нужное значение.
  4. Поместите узел эффекта в основную сцену.

Делая это, вы также можете поместить все строки в одном узле формы:

let path = CGMutablePath() 
path.move( to: CGPoint(x: -100, y: 100)) 
path.addLine(to: CGPoint(x: 100, y: -100)) 
path.move( to: CGPoint(x: 100, y: 100)) 
path.addLine(to: CGPoint(x: -100, y: -100)) 

let shape = SKShapeNode(path: path) 
shape.strokeColor = UIColor(red: 0.25, green: 0.62, blue: 0.0, alpha: 1) 
shape.lineWidth = 30 

let effect = SKEffectNode() 
effect.addChild(shape) 
effect.alpha = 0.5 
addChild(effect) 
+0

Спасибо за это. Единственная проблема с этим, так это то, что я не думаю, что я могу изменить индивидуально изменить цвет каждой строки, которую я добавляю в этот путь. –

1

Проблема заключается в том что вы делаете альфа-смесь на уровне цвета, сделать альфа-смешивание на уровне узла

var points = [CGPoint]() 
var cross = SKEffectNode() 
points = [CGPoint(x: -100, y: 100), CGPoint(x: 100, y: -100)] 
let FirstLine = SKShapeNode(points: &points, count: points.count) 
FirstLine.strokeColor = UIColor.init(red: 0.25, green: 0.62, blue: 0.0, alpha: 1) 
FirstLine.lineWidth = 30 
cross.addChild(FirstLine) 

points = [CGPoint(x: 100, y: 100), CGPoint(x: -100, y: -100)] 
let SecondLine = SKShapeNode(points: &points, count: points.count) 
SecondLine.strokeColor = UIColor.init(red: 0.25, green: 0.62, blue: 0.0, alpha: 1) 
SecondLine.lineWidth = 30 
cross.addChild(SecondLine) 
cross.alpha = 0.5 
addChild(cross) 
+0

Это не работает для меня, оно все равно выглядит одинаково. –

+0

Странно, это должно быть только «SKEffectNode» ..... ahhhh он превращает детей в отдельный буфер, вот почему – Knight0fDragon

+0

Возможно, вы захотите просто применить шейдер к кресту, не уверенный, сколько ресурсов эффект узел будет потреблять – Knight0fDragon

Смежные вопросы