BSP Dungeon Generator 出现无法修复的错误
BSP Dungeon Generator giving an unfixable error
我正在研究 t运行slating this ActionScript tutorial 二进制 space 分区成 Swift 这样我就可以在我的 rogue-like 游戏中使用它。我遇到了一个问题。
在文章中,作者这样初始化他的class:
public function Leaf(X:int, Y:int, Width:int, Height:int)
{
// initialize our leaf
x = X;
y = Y;
width = Width;
height = Height;
}
当我 运行 将其设置为 Swift 时,我 运行 出错了。上面的代码没有初始化所有声明的值。这使我陷入了一个我似乎无法修复的不可能的错误。不知何故,文章的作者用初始化范围之外的这个函数初始化了他的 leftChild
和 rightChild
变量。
public function split():Boolean
{
// begin splitting the leaf into two children
if (leftChild != null || rightChild != null)
return false; // we're already split! Abort!
// determine direction of split
// if the width is >25% larger than height, we split vertically
// if the height is >25% larger than the width, we split horizontally
// otherwise we split randomly
var splitH:Boolean = FlxG.random() > 0.5;
if (width > height && width / height >= 1.25)
splitH = false;
else if (height > width && height / width >= 1.25)
splitH = true;
var max:int = (splitH ? height : width) - MIN_LEAF_SIZE; // determine the maximum height or width
if (max <= MIN_LEAF_SIZE)
return false; // the area is too small to split any more...
var split:int = Registry.randomNumber(MIN_LEAF_SIZE, max); // determine where we're going to split
// create our left and right children based on the direction of the split
if (splitH)
{
leftChild = new Leaf(x, y, width, split);
rightChild = new Leaf(x, y + split, width, height - split);
}
else
{
leftChild = new Leaf(x, y, split, height);
rightChild = new Leaf(x + split, y, width - split, height);
}
return true; // split successful!
}
这在某种程度上在 ActionScript 中是可以的,但在 Swift 中它导致了我的问题。
这是我的 运行 预定代码 (Swift):
private let mapWidth:Int = 50
private let mapHeight:Int = 50
class Leaf {
var leftLeaf = [Leaf]()
var rightLeaf = [Leaf]()
var minLeafSize:Int = 6
var x, y, width, height: Int
var leftChild:Leaf
var rightChild:Leaf
init (X:Int, Y:Int, W:Int, H:Int) {
x = Y
y = Y
width = W
height = H
let maxLeafSize:UInt = 20
var leaves = [Leaf]()
// first, create a Leaf to be the 'root' of all Leafs.
let root = Leaf(X: 0, Y: 0, W: mapWidth, H: mapHeight)
leaves.append(root)
var didSplit:Bool = true
// we loop through every Leaf in our Vector over and over again, until no more Leafs can be split.
while (didSplit) {
didSplit = false
for l in leaves {
if l.leftLeaf.isEmpty == true && l.rightLeaf.isEmpty == true {
// if this Leaf is too big, or 75% chance...
if l.width > maxLeafSize || l.height > maxLeafSize || Int(arc4random_uniform(100)) > 25 {
if (l.split()) {
// if we did split, push the child leafs to the Vector so we can loop into them next
leaves.append(l.leftChild)
leaves.append(l.rightChild)
didSplit = true
}
}
}
}
}
}
func split() -> Bool {
if leftLeaf.isEmpty == true || rightLeaf.isEmpty == true {
return false
}
var splitH = arc4random_uniform(100) > 50 ? true : false
if width > height && Double(width / height) >= 1.25 {
splitH = false
}
if height > width && Double(height / width) >= 1.25 {
splitH = true
}
let max:Int = (splitH ? height : width) - minLeafSize // determine the maximum height or width
if max <= minLeafSize { return false }
let split:Int = Int(arc4random_uniform(UInt32(minLeafSize - max) + UInt32(max)))
if (splitH) {
leftChild = Leaf(X: x, Y: y, W: width, H: split)
rightChild = Leaf(X: x, Y: y + split, W: width, H: height - split)
leftLeaf.append(leftChild)
rightLeaf.append(rightChild)
} else {
leftChild = Leaf(X: x, Y: y, W: split, H: height)
rightChild = Leaf(X: x + split, Y: y, W: width - split, H: height);
leftLeaf.append(leftChild)
rightLeaf.append(rightChild)
}
return true
}
}
它与文章中的 ActionScript 代码相同(据我所知)。但它给了我一个错误。 leftChild
和 rightChild
变量未在我的 init
方法中初始化。当我将 split() -> Bool
函数移动到 init
方法时,它不会让我使用该函数,给我一个错误 "Value of type Leaf has no member split()"。从 if (l.spit())
行中删除 l
会给我第二个错误 "Use of local variable 'split' before its declaration"。 split()
函数必须在初始化范围之外。
如果我尝试像这样初始化 leftChild
和 rightChild
:
init (X:Int, Y:Int, W:Int, H:Int) {
x = Y
y = Y
width = W
height = H
leftChild = Leaf(X: x, Y: y, W: width, H: height)
rightChild = Leaf(X: x, Y: y, W: width, H: height)
}
它创建了一个最终导致崩溃的无限循环。
代码应该在 split() -> Bool
函数中初始化 leftChild
和 rightChild
,但我不认为它在 Swift 中是这样工作的。您应该能够 copy/paste 将其放入 Swift 文件并得到相同的错误。
为什么会这样?我的代码写得不好吗?我该如何解决这个问题?
在 ActionScript 中,未初始化的变量会自动计算为特殊值 undefined
;另外,在 ActionScript 中,undefined == null
,这就是 if (leftChild != null || rightChild != null)
起作用的原因。
在 Swift 中,您需要明确 allow 您的变量可以为 nilable。您担心的变量需要以 nil
开头(如果您允许,它们会自动将其类型设置为 Optional
- 请注意问号):
var leftChild:Leaf?
var rightChild:Leaf?
我正在研究 t运行slating this ActionScript tutorial 二进制 space 分区成 Swift 这样我就可以在我的 rogue-like 游戏中使用它。我遇到了一个问题。
在文章中,作者这样初始化他的class:
public function Leaf(X:int, Y:int, Width:int, Height:int)
{
// initialize our leaf
x = X;
y = Y;
width = Width;
height = Height;
}
当我 运行 将其设置为 Swift 时,我 运行 出错了。上面的代码没有初始化所有声明的值。这使我陷入了一个我似乎无法修复的不可能的错误。不知何故,文章的作者用初始化范围之外的这个函数初始化了他的 leftChild
和 rightChild
变量。
public function split():Boolean
{
// begin splitting the leaf into two children
if (leftChild != null || rightChild != null)
return false; // we're already split! Abort!
// determine direction of split
// if the width is >25% larger than height, we split vertically
// if the height is >25% larger than the width, we split horizontally
// otherwise we split randomly
var splitH:Boolean = FlxG.random() > 0.5;
if (width > height && width / height >= 1.25)
splitH = false;
else if (height > width && height / width >= 1.25)
splitH = true;
var max:int = (splitH ? height : width) - MIN_LEAF_SIZE; // determine the maximum height or width
if (max <= MIN_LEAF_SIZE)
return false; // the area is too small to split any more...
var split:int = Registry.randomNumber(MIN_LEAF_SIZE, max); // determine where we're going to split
// create our left and right children based on the direction of the split
if (splitH)
{
leftChild = new Leaf(x, y, width, split);
rightChild = new Leaf(x, y + split, width, height - split);
}
else
{
leftChild = new Leaf(x, y, split, height);
rightChild = new Leaf(x + split, y, width - split, height);
}
return true; // split successful!
}
这在某种程度上在 ActionScript 中是可以的,但在 Swift 中它导致了我的问题。
这是我的 运行 预定代码 (Swift):
private let mapWidth:Int = 50
private let mapHeight:Int = 50
class Leaf {
var leftLeaf = [Leaf]()
var rightLeaf = [Leaf]()
var minLeafSize:Int = 6
var x, y, width, height: Int
var leftChild:Leaf
var rightChild:Leaf
init (X:Int, Y:Int, W:Int, H:Int) {
x = Y
y = Y
width = W
height = H
let maxLeafSize:UInt = 20
var leaves = [Leaf]()
// first, create a Leaf to be the 'root' of all Leafs.
let root = Leaf(X: 0, Y: 0, W: mapWidth, H: mapHeight)
leaves.append(root)
var didSplit:Bool = true
// we loop through every Leaf in our Vector over and over again, until no more Leafs can be split.
while (didSplit) {
didSplit = false
for l in leaves {
if l.leftLeaf.isEmpty == true && l.rightLeaf.isEmpty == true {
// if this Leaf is too big, or 75% chance...
if l.width > maxLeafSize || l.height > maxLeafSize || Int(arc4random_uniform(100)) > 25 {
if (l.split()) {
// if we did split, push the child leafs to the Vector so we can loop into them next
leaves.append(l.leftChild)
leaves.append(l.rightChild)
didSplit = true
}
}
}
}
}
}
func split() -> Bool {
if leftLeaf.isEmpty == true || rightLeaf.isEmpty == true {
return false
}
var splitH = arc4random_uniform(100) > 50 ? true : false
if width > height && Double(width / height) >= 1.25 {
splitH = false
}
if height > width && Double(height / width) >= 1.25 {
splitH = true
}
let max:Int = (splitH ? height : width) - minLeafSize // determine the maximum height or width
if max <= minLeafSize { return false }
let split:Int = Int(arc4random_uniform(UInt32(minLeafSize - max) + UInt32(max)))
if (splitH) {
leftChild = Leaf(X: x, Y: y, W: width, H: split)
rightChild = Leaf(X: x, Y: y + split, W: width, H: height - split)
leftLeaf.append(leftChild)
rightLeaf.append(rightChild)
} else {
leftChild = Leaf(X: x, Y: y, W: split, H: height)
rightChild = Leaf(X: x + split, Y: y, W: width - split, H: height);
leftLeaf.append(leftChild)
rightLeaf.append(rightChild)
}
return true
}
}
它与文章中的 ActionScript 代码相同(据我所知)。但它给了我一个错误。 leftChild
和 rightChild
变量未在我的 init
方法中初始化。当我将 split() -> Bool
函数移动到 init
方法时,它不会让我使用该函数,给我一个错误 "Value of type Leaf has no member split()"。从 if (l.spit())
行中删除 l
会给我第二个错误 "Use of local variable 'split' before its declaration"。 split()
函数必须在初始化范围之外。
如果我尝试像这样初始化 leftChild
和 rightChild
:
init (X:Int, Y:Int, W:Int, H:Int) {
x = Y
y = Y
width = W
height = H
leftChild = Leaf(X: x, Y: y, W: width, H: height)
rightChild = Leaf(X: x, Y: y, W: width, H: height)
}
它创建了一个最终导致崩溃的无限循环。
代码应该在 split() -> Bool
函数中初始化 leftChild
和 rightChild
,但我不认为它在 Swift 中是这样工作的。您应该能够 copy/paste 将其放入 Swift 文件并得到相同的错误。
为什么会这样?我的代码写得不好吗?我该如何解决这个问题?
在 ActionScript 中,未初始化的变量会自动计算为特殊值 undefined
;另外,在 ActionScript 中,undefined == null
,这就是 if (leftChild != null || rightChild != null)
起作用的原因。
在 Swift 中,您需要明确 allow 您的变量可以为 nilable。您担心的变量需要以 nil
开头(如果您允许,它们会自动将其类型设置为 Optional
- 请注意问号):
var leftChild:Leaf?
var rightChild:Leaf?