#swift #macos #screensaver
#swift #macos #заставка
Вопрос:
Я разработал то, что, по моему мнению, было аккуратной маленькой программой для обработки. Он настраивает некоторые ГСЧ, а затем отображает количество выходных данных каждого гсч. Вот код обработки. Я не думаю, что есть какие-либо проблемы с этой стороны, потому что она отлично работает при обработке:
int [] randomCounts;
int [] gaussianCounts;
int [] monteCarloCounts;
int [] invMonteCarloCounts;
void setup(){
size(1000,700);
randomCounts = new int[500];
gaussianCounts = new int[500];
monteCarloCounts = new int[500];
invMonteCarloCounts = new int[500];
}
float invMonteCarlo(){
while (true){
float r1 = random(1);
float r2 = random(1);
if (r2>r1){
return r1;
}
}
}
float monteCarlo(){
while (true){
float r1 = random(1);
float r2 = random(1);
if (r2<r1){
return r1;
}
}
}
void draw(){
background(255);
int randIndex = int(random(randomCounts.length));
int gaussIndex = int(randomGaussian()*20 250);
int monteIndex = int(monteCarlo()*monteCarloCounts.length);
int invMonteIndex = int(invMonteCarlo()*invMonteCarloCounts.length);
randomCounts[randIndex] ;
gaussianCounts[gaussIndex] ;
monteCarloCounts[monteIndex] ;
invMonteCarloCounts[invMonteIndex] ;
noStroke();
int w = width/randomCounts.length;
fill(0,255,0,150);
for (int x = 0; x < gaussianCounts.length;x ){
rect(x*w,height-gaussianCounts[x],w-1,gaussianCounts[x]);
}
fill(0,0,255,150);
for (int x = 0;x < monteCarloCounts.length;x ){
rect(x*w,height-monteCarloCounts[x],w-1,monteCarloCounts[x]);
}
fill(255,255,0,150);
for (int x = 0;x < invMonteCarloCounts.length;x ){
rect(x*w,height-invMonteCarloCounts[x],w-1,invMonteCarloCounts[x]);
}
fill(255,0,0,150);
for (int x = 0; x < randomCounts.length; x ){
rect(x*w,height-randomCounts[x],w-1,randomCounts[x]);
}
}
void mousePressed(){
for (int x = 0; x < randomCounts.length; x ){
randomCounts[x] = 0;
gaussianCounts[x] = 0;
monteCarloCounts[x] = 0;
invMonteCarloCounts[x] = 0;
}
}
Этот код, опять же, работает нормально. Я пытался сделать по существу то же самое в swift (что было немного безумно), и XCode не указывает на ошибки. Однако, когда я устанавливаю заставку в системных настройках, предварительный просмотр становится просто черным и перестает функционировать даже для других заставок, и фактически запуск заставки невозможен. Кажется, что он где-то застрял, что не позволяет ему фактически работать в движке.
Вот мой код swift:
import Foundation
import ScreenSaver
import GameplayKit
class RandomGraphView: ScreenSaverView {
private var randomCounts: [Int] = [500]
private var gaussianCounts: [Int] = [500]
private var shuffledCounts: [Int] = [500]
private var monteCarloCounts: [Int] = [500]
private var invMonteCarloCounts: [Int] = [500]
private func MonteCarlo() -> Int{
while true {
let r1 = Int.random(in: 1...360)
let r2 = Int.random(in: 1...360)
if r2<r1 {
return r1
}
}
}
private func invMonteCarlo() -> Int{
while true {
let r1 = Int.random(in: 1...360)
let r2 = Int.random(in: 1...360)
if r2>r1 {
return r1
}
}
}
private func gaussian() -> Int{
let gaussianD6 = GKGaussianDistribution(lowestValue: 1, highestValue: 360)
return gaussianD6.nextInt()
}
private func shuffled() -> Int{
let shuffledD6 = GKShuffledDistribution(lowestValue: 1, highestValue: 360)
return shuffledD6.nextInt()
}
private func pullNumbers(){
let randIndex = Int.random(in: 1...360)
let gaussIndex = gaussian()
let shuffIndex = shuffled()
let monteCarloIndex = MonteCarlo()
let invMonteCarloIndex = invMonteCarlo()
randomCounts[randIndex] =1
gaussianCounts[gaussIndex] =1
shuffledCounts[shuffIndex] =1
monteCarloCounts[monteCarloIndex] =1
invMonteCarloCounts[invMonteCarloIndex] =1
}
private func drawRandomBars(){
for n in 1...360{
let countBarRect = NSRect(x:(n-1)*4,y: 900, width:4, height: randomCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.red.setFill()
countBar.fill()
}
}
private func drawGaussianBars(){
for n in 1...360{
let countBarRect = NSRect(x: (n-1)*4, y: 900, width: 4, height: gaussianCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.green.setFill()
countBar.fill()
}
}
private func drawShuffledBars(){
for n in 1...360{
let countBarRect = NSRect(x: (n-1)*4, y: 900, width: 4, height: shuffledCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.systemBrown.setFill()
countBar.fill()
}
}
private func drawMonteCarloBars(){
for n in 1...360{
let countBarRect = NSRect(x: (n-1)*4, y: 900, width: 4, height: monteCarloCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.magenta.setFill()
countBar.fill()
}
}
private func drawInverseMonteCarloBars(){
for n in 1...360{
let countBarRect = NSRect(x: (n-1)*4, y: 900, width: 4, height: invMonteCarloCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.systemIndigo.setFill()
countBar.fill()
}
}
private func drawBackground(_ color:NSColor){
let background = NSBezierPath(rect: bounds)
color.setFill()
background.fill()
}
override init?(frame: NSRect, isPreview: Bool){
super.init(frame: frame, isPreview: isPreview)
}
@available(*, unavailable)
required init?(coder decoder: NSCoder){
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: NSRect){
drawBackground(.white)
pullNumbers()
drawRandomBars()
drawGaussianBars()
drawShuffledBars()
drawMonteCarloBars()
drawInverseMonteCarloBars()
}
override func animateOneFrame(){
super.animateOneFrame()
}
}
Извините за длинный код, я действительно понятия не имею, что я делаю не так. Я скопировал большую часть своих сценариев из этого руководства, которое работает отлично.
Ответ №1:
Вы должны установить needsDisplay в animateOneFrame, например:
override func animateOneFrame(){
needsDisplay = true
}
Ответ №2:
Эта строка
private var randomCounts: [Int] = [500]
не эквивалентно
randomCounts = new int[500];
Первый создает массив с одним числом 500 внутри, тогда как последний создает массив из 500 целых чисел (я не специалист по обработке / Java, но я предполагаю, что они инициализированы в 0). Таким образом, ваша программа будет аварийно завершать работу, когда randIndex
, gaussIndex
, и т.д. больше 0, потому что индекс будет вне пределов.
Вместо этого вы, вероятно, хотели использовать init(повторение:count:): private var randomCounts: [Int] = Array(repeating: 0, count: 500)
.
Чтобы избежать такого рода проблем в целом, вы можете улучшить свой код, не записывая 1...360
везде, а вместо этого используя randomCounts.count
для ссылки на длину массива. Аналогично, вместо for n in 1...360
, используйте что-то вроде for (n, height) in monteCarloCounts.enumerated()
.
Комментарии:
1. Спасибо за вашу помощь. Я немного разобрался с проблемой с массивами, прежде чем увидел ваш ответ, так что это больше не сбой, но он все еще не отображается.
2. Вам следует отредактировать свой вопрос, включив в него обновленный код и больше информации о том, что вы пробовали для отладки, иначе трудно помочь с небольшим количеством информации.