Ich versuche, ein Spiel in SpriteKit zu erstellen, und ich brauche eine Möglichkeit, Objekte zu legen, platzieren Sie sie in zufällig generierten Punkte war es nicht für mich zu viel Gruppierung .Poisson Disk Generator schließt drei von vier Ansicht Quadranten
Nach ein paar Recherchen sah ein Poisson Disk Generator so aus, wie ich es brauchte.
Ich habe versucht, meine eigenen zu implementieren. Allerdings sind alle Positionen ausgeschaltet, sie fehlen 3/4 des Displays.
Wohin gehe ich falsch?
min Bei einem Radius von 100.
Bei einem Radius von min 10.
class GameScene: SKScene {
var radius = 100
var lookUpCount = 30
var grid = [CGPoint?](), ordered = [CGPoint](), active = [CGPoint]()
var w = CGFloat()
var cols = Int()
var rows = Int()
var sizeScren = CGSize()
override func didMove(to view: SKView) {
generate()
for item in ordered {
let gamePiece = SKSpriteNode(imageNamed: "Spaceship")
gamePiece.setScale(0.0625)
gamePiece.position = item
addChild(gamePiece)
}
}
func distance(p1: CGPoint, p2: CGPoint) -> CGFloat {
let dx = p1.x - p2.x
let dy = p1.y - p2.y
return sqrt(dx * dx + dy * dy)
}
func generateRandomPointAround(point: CGPoint, minDist: CGFloat) -> CGPoint
{
let rd1 = CGFloat(Float(arc4random())/Float(UINT32_MAX))
let rd2 = CGFloat(Float(arc4random())/Float(UINT32_MAX))
//random radius
let radius = minDist * (rd1 + 1)
//random angle
let angle = 2 * CGFloat.pi * rd2
//new point is generated around the point (x, y)
let newX = point.x + radius * cos(angle)
let newY = point.y + radius * sin(angle)
return CGPoint(x: newX, y: newY)
}
func generate() {
sizeScren = UIScreen.main.bounds.size
//create cell
w = (CGFloat(Double(radius)/sqrt(2)))
cols = Int(floor(sizeScren.height/w))
rows = Int(floor(sizeScren.width/w))
grid = [CGPoint?](repeating: nil, count: (cols * rows))
let x = sizeScren.height/2
let y = sizeScren.width/2
let i = floor(x/w)
let j = floor(y/w)
//first posistion
let pos = CGPoint (x: frame.midX, y: frame.midY)
let index = Int(i + j * CGFloat(cols))
grid[index] = pos
active.append(pos)
while (active.count > 0) {
let randomIndex = Int(arc4random_uniform(UInt32(active.count)))
let currentPos = active[randomIndex]
var found = false
Mainloop: for _ in 0..<Int(lookUpCount) {
let samplePoint = generateRandomPointAround(point: currentPos, minDist: CGFloat(radius))
let col = floor(samplePoint.x/w)
let row = floor(samplePoint.y/w)
//check neighbouring cells are empty and valid, if have a point in already
if (col > -1 && row > -1 && CGFloat(col) < CGFloat(cols) && CGFloat(row) < CGFloat(rows) && (grid[Int(col + CGFloat(row) * CGFloat(cols))] == nil)) {
var ok = true
for index1 in -1...1 {
for index2 in -1...1 {
//break down complexity for swift compiler
let part1 = Int(col + CGFloat(index1))
let part2 = Int(row + CGFloat(index2))
let part3 = part1 + part2 * cols
let sampleIndex = part3
let isIndexValid = grid.indices.contains(sampleIndex)
if isIndexValid {
let neighbor = grid[sampleIndex]
if neighbor != nil {
let distanceAmount = distance(p1: samplePoint, p2: neighbor!)
if distanceAmount < CGFloat(radius) {
ok = false
}
}
}
}
}
if (ok == true) {
found = true
grid[Int(col + row * CGFloat(cols))] = samplePoint
active.append(samplePoint)
ordered.append(samplePoint)
// break MainLoop
}
}
}
if (!found) {
active.remove(at: randomIndex)
}
}
}
}
(0, 0) der Mittelpunkt der Bildschirm oder eine der Ecken? Denn wenn es das Zentrum ist, dann ist 'if (col> -1 && reihe> -1 'wird 3 von 4 Quadranten ausschließen) – samgak
(0,0) ist die Mitte, aber ich dachte, es sollte keine Rolle spielen, da es Punkte geben sollte Rund um den Radius gesampelt Ich dachte, mein Problem bestehe eher darin, das 2D-Array auf ein 1D-Array abzubilden. – Magrafear