How would I be able to change the window's opacity from a slider?
I made the code, but I'm stuck on where to go from here.
#!/usr/bin/python
import gtk
class app(gtk.Window):
def __init__(self):
super(app, self).__init__()
self.set_position(gtk.WIN_POS_CENTER)
self.set_title("Opacity Slider Test")
self.set_decorated(True)
self.set_has_frame(False)
self.set_resizable(False)
self.set_default_size(320, 50)
self.connect("destroy", gtk.main_quit)
vbox = gtk.VBox(spacing=4)
hbox = gtk.HBox(spacing=4)
scale = gtk.HScale()
scale.set_range(0, 100)
scale.set_size_request(320, 25)
scale.connect("value-changed", self.opacity_slider)
vbox.add(scale)
self.add(vbox)
self.show_all()
def opacity_slider(self, w):
app()
gtk.main()
#!/usr/bin/python
import gtk
class app(gtk.Window):
def __init__(self):
super(app, self).__init__()
self.set_position(gtk.WIN_POS_CENTER)
self.set_title("Opacity Slider Test")
self.set_decorated(True)
self.set_has_frame(False)
self.set_resizable(False)
self.set_default_size(320, 50)
self.connect("destroy", gtk.main_quit)
vbox = gtk.VBox(spacing=4)
hbox = gtk.HBox(spacing=4)
scale = gtk.HScale()
scale.set_range(0, 100)
scale.set_size_request(320, 25)
scale.set_value(100)
scale.connect("value-changed", self.opacity_slider)
vbox.add(scale)
opacity = gtk.Label()
opacity.set_label("Change Opacity")
vbox.add(opacity)
self.add(vbox)
self.show_all()
def opacity_slider(self, w):
self.set_opacity(w.get_value()/100.0)
app()
gtk.main()
Related
On macOS Big Sur, running JDK 17 and JavaFX 18, when you have an irregular clipping region, the clipped image ends up badly pixelated when printed.
The pixelation happens both on actual paper (on my Epson printer), as well as when saved to a PDF (using macOSs innate "Save to PDF" feature).
If you have a clip region with a Rectangle, there is no pixelation, everything looks smooth and crisp.
Note, that it must be a Rectangle, a rectangular Polygon has problems as well.
This is a screen shot of the actual screen rendering:
Next is a screen shot of viewing the resulting PDF.
You can see both the text and lines are pixelated within the circle.
Seems to me that its rendering the node in to the "PDF resolution", which is 72 DPI (not actual printer resolution), and then masking the region using a bitmap operation rather than actually clipping the content to the irregular border. But it special cases the Rectangle and clips to that.
Is there anything that can be done about this?
Below is a sample demonstrating this.
package pkg;
import javafx.application.Application;
import javafx.print.PrinterJob;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class App extends Application {
Pane printPane;
#Override
public void start(Stage stage) {
var scene = new Scene(getView(), 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
private Pane getView() {
var flowPane = new FlowPane(getCirclePane(), getRectPane());
var b = new Button("Print");
printPane = flowPane;
b.setOnAction((t) -> {
var job = PrinterJob.createPrinterJob();
if (job != null && job.showPrintDialog(null)) {
if (job.printPage(printPane)) {
job.endJob();
}
}
});
var bp = new BorderPane();
bp.setCenter(flowPane);
bp.setBottom(b);
return bp;
}
private Pane getCirclePane() {
var pane = new Pane();
var circle = new Circle(100, 100, 45);
pane.setClip(circle);
var text = new Text(75, 100, "Circle");
pane.getChildren().add(text);
for (int i = 0; i < 10; i++) {
double ox = i * 25;
pane.getChildren().add(new Line(ox, 200, ox + 25, 0));
pane.getChildren().add(new Line(ox, 0, ox + 25, 200));
}
return pane;
}
private Pane getRectPane() {
var pane = new Pane();
var rect = new Rectangle(50, 50, 200, 125);
pane.setClip(rect);
var text = new Text(125, 100, "Rectangle");
pane.getChildren().add(text);
for (int i = 0; i < 10; i++) {
double ox = i * 25;
pane.getChildren().add(new Line(ox, 200, ox + 25, 0));
pane.getChildren().add(new Line(ox, 0, ox + 25, 200));
}
return pane;
}
}
Update:
I came up with this as a workaround.
Simply, that which I can't clip, I can paint over.
I create a new rect the size of the overall scene, then use Shape.subtract(...) to punch a hole in it in the shape of my clip region. I fill this new shape with my background color. Then I put this in a new pane, and use a Stack pane to layer it on top of my master. It's imperfect, and a little bit fiddly, and it chafes having to do this. But it works and is easy to explain.
So, using the circle as an example:
private Pane getCirclePane() {
var pane = new Pane();
var circle = new Circle(100, 100, 45);
var text = new Text(75, 100, "Circle");
pane.getChildren().add(text);
for (int i = 0; i < 10; i++) {
double ox = i * 25;
pane.getChildren().add(new Line(ox, 200, ox + 25, 0));
pane.getChildren().add(new Line(ox, 0, ox + 25, 200));
}
Rectangle rect = new Rectangle(0, 0, 250, 200);
Shape overlay = Shape.subtract(rect, circle);
overlay.setFill(Color.WHITE);
Pane overlayPane = new Pane();
overlayPane.getChildren().add(overlay);
pane = new StackPane(pane, overlayPane);
return pane;
}
As an interim workaround, you may be able to adapt the approach seen here; it uses Shape.subtract() to create a suitable matte that functions like the corresponding clip.
var c = new Circle(100, 100, 80);
var r = new Rectangle(250, 200);
Shape matte = Shape.subtract(r, c);
matte.setFill(Color.WHITE);
pane.getChildren().add(matte);
As printed:
As tested:
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.print.PrinterJob;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class App extends Application {
#Override
public void start(Stage stage) {
var scene = new Scene(getView());
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
private Pane getView() {
final var printBox = new HBox(8, getCirclePane(), getRectPane());
var b = new Button("Print");
b.setOnAction((t) -> {
var job = PrinterJob.createPrinterJob();
if (job != null && job.showPrintDialog(null)) {
if (job.printPage(printBox)) {
job.endJob();
}
}
});
var bp = new BorderPane();
bp.setCenter(printBox);
bp.setBottom(b);
BorderPane.setAlignment(b, Pos.BOTTOM_CENTER);
return bp;
}
private Pane getCirclePane() {
var pane = new Pane();
var text = new Text(80, 100, "Circle");
pane.getChildren().add(text);
addPattern(pane);
var c = new Circle(100, 100, 80);
var r = new Rectangle(250, 200);
Shape matte = Shape.subtract(r, c);
matte.setFill(Color.WHITE);
pane.getChildren().add(matte);
return pane;
}
private Pane getRectPane() {
var pane = new Pane();
var rect = new Rectangle(50, 50, 200, 125);
pane.setClip(rect);
var text = new Text(125, 100, "Rectangle");
pane.getChildren().add(text);
addPattern(pane);
return pane;
}
private void addPattern(Pane pane) {
for (int i = 0; i < 10; i++) {
double ox = i * 25;
pane.getChildren().add(new Line(ox, 200, ox + 25, 0));
pane.getChildren().add(new Line(ox, 0, ox + 25, 200));
}
}
}
I am have a problem in the process of my GUI. I have 3 window which is the main window -> 2nd window -> 3rd window then exit. It works well when clicking the button going to 2nd window, but if I clicked the button to window 3 it crushes.
The whole process crushes without saying any error.
This is my Code for the first window:
from window2 import *
from window3 import *
class Ui_MainWindow(object):
def openWindow2(self):
self.window = QtWidgets.QMainWindow()
self.ui = Ui_MainWindow2()
self.ui.setupUi2(self.window)
MainWindow.hide()
self.window.show()
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(637, 309)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(230, 90, 341, 16))
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(520, 230, 75, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.openWindow2)
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
This is the code for the 2nd window:
from window3 import *
class Ui_MainWindow2(object):
def openWindow3(self):
self.window = QtWidgets.QMainWindow()
self.ui = Ui_MainWindow3()
self.ui.setupUi3(self.window)
MainWindow.hide()
self.window.show()
def setupUi2(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(481, 242)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(340, 180, 75, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.openWindow3)
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(210, 100, 61, 16))
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow2()
ui.setupUi2(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
This is the code for the 3rd window:
from window1 import *
from window2 import *
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow3(object):
def setupUi3(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(397, 319)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(180, 110, 47, 13))
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(290, 250, 75, 23))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow3()
ui.setupUi3(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Can someone tell me why the process crushes in the 2nd window when button clicked and why it cannot proceed to the 3rd window?
Try it:
window1.py
from window2 import *
from window3 import *
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def openWindow2(self):
self.window = QtWidgets.QMainWindow()
self.ui = Ui_MainWindow2(self.window) # +++ self.window
self.ui.setupUi2(self.window)
MainWindow.hide()
self.window.show()
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(637, 309)
MainWindow.setWindowTitle('Window 1')
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(230, 90, 341, 16))
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton("Button 1", self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(520, 230, 75, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.openWindow2)
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
window2.py
from window3 import *
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow2(object):
def __init__(self, window2, *args, **kwargs): # +++
super(Ui_MainWindow2, self).__init__(*args, **kwargs) # +++
self.window2 = window2 # +++
def openWindow3(self):
self.window = QtWidgets.QMainWindow()
self.ui = Ui_MainWindow3()
self.ui.setupUi3(self.window)
# MainWindow.hide() # ---
self.window2.hide() # +++
self.window.show()
def setupUi2(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(481, 242)
MainWindow.setWindowTitle('Window 2')
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton("Button 2", self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(340, 180, 75, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.openWindow3)
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(210, 100, 61, 16))
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow2()
ui.setupUi2(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
window3.py
from window1 import *
from window2 import *
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow3(object):
def setupUi3(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(397, 319)
MainWindow.setWindowTitle('Window 3')
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(180, 110, 47, 13))
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton("Button 3", self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(290, 250, 75, 23))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow3()
ui.setupUi3(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Update
window1.py
from window2 import *
from window3 import *
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def openWindow2(self):
self.window = QtWidgets.QMainWindow()
self.ui = Ui_MainWindow2(self.window) # +++ self.window
self.ui.setupUi2(self.window)
MainWindow.hide()
self.window.show()
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(637, 309)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(230, 90, 341, 16))
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(520, 230, 75, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.openWindow2)
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Window 1"))
self.pushButton.setText(_translate("MainWindow", "Button 1"))
#...
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
window2.py
from window3 import *
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow2(object):
def __init__(self, window2, *args, **kwargs): # +++
super(Ui_MainWindow2, self).__init__(*args, **kwargs) # +++
self.window2 = window2 # +++
def openWindow3(self):
self.window = QtWidgets.QMainWindow()
self.ui = Ui_MainWindow3()
self.ui.setupUi3(self.window)
# MainWindow.hide() # ---
self.window2.hide() # +++
self.window.show()
def setupUi2(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(481, 242)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(340, 180, 75, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.openWindow3)
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(210, 100, 61, 16))
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Window 2"))
self.pushButton.setText(_translate("MainWindow", "Button 2"))
#...
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow2()
ui.setupUi2(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
window3.py
from window1 import *
from window2 import *
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow3(object):
def setupUi3(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(397, 319)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(180, 110, 47, 13))
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(280, 250, 95, 23))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.pushButton.clicked.connect(MainWindow.close) # +++
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Window 3"))
self.pushButton.setText(_translate("MainWindow", "Button 3 (Quit)"))
#...
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow3()
ui.setupUi3(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
I am using the below to create a gradient view that is visible in IB:
import UIKit
import QuartzCore
#IBDesignable
class FAUGradientView: UIView {
#IBInspectable var firstColor:UIColor = UIColor.clear
#IBInspectable var secondColor:UIColor = UIColor.clear
#IBInspectable var startPoint:CGPoint = CGPoint(x: 0.0, y: 1.0)
#IBInspectable var endPoint:CGPoint = CGPoint(x: 1.0, y:0.0)
var gradientLayer:CAGradientLayer!
override func draw(_ rect: CGRect) {
super.draw(rect)
gradientLayer = CAGradientLayer()
self.gradientLayer.colors = [firstColor, secondColor]
self.gradientLayer.startPoint = self.startPoint
self.gradientLayer.endPoint = self.endPoint
self.gradientLayer.frame = self.frame
self.layer.addSublayer(self.gradientLayer)
}
}
However, what I get in IB is a solid black view, not a view with a two color gradient, as seen below:
Solved it. They need to be cgColors, but XCode doesn't give you a single error to indicate that.
[firstColor.cgColor, secondColor.cgColor]
The above fixes the issue.
Works well, but;
self.gradientLayer.frame = self.frame
should be
self.gradientLayer.frame = self.bounds
or you can get some very odd draw offsets depending on where the view is within the parent
I am working with the joint method in spritekit, but once I join two sprites it seems to change the physics bodies. I have two rectangles joined at a corner and when they fold, I would expect the blue rectangle to sit on top of the white triangle, but this is the result. How do I maintain their physics bodies, so they don't overlap?
import SpriteKit
class GameScene: SKScene {
let character = SKSpriteNode(color: SKColor.whiteColor(), size: CGSizeMake(150, 30))
let character2 = SKSpriteNode(color: SKColor.blueColor(), size: CGSizeMake(150, 30))
let character3 = SKSpriteNode(color: SKColor.greenColor(), size: CGSizeMake(50, 300))
let screenSize: CGRect = UIScreen.mainScreen().bounds
override func didMoveToView(view: SKView) {
// let scene = GameScene(size: SKView.frame)
let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
borderBody.friction = 5
self.physicsBody = borderBody
self.physicsWorld.gravity = CGVectorMake(0.0, -1.0)
character.position = CGPointMake(550, 400)
character2.position = CGPointMake(400, 400)
character3.position = CGPointMake(400, 100)
character.physicsBody = SKPhysicsBody(rectangleOfSize: character.size)
character2.physicsBody = SKPhysicsBody(rectangleOfSize: character2.size)
character3.physicsBody = SKPhysicsBody(rectangleOfSize: character3.size)
self.character.physicsBody!.dynamic = true
self.character2.physicsBody!.dynamic = true
self.character3.physicsBody!.dynamic = true
self.addChild(character)
self.addChild(character2)
self.addChild(character3)
var myJoint = SKPhysicsJointPin.jointWithBodyA(character2.physicsBody, bodyB: character.physicsBody, anchor: CGPoint(x: CGRectGetMaxX(self.character2.frame), y: CGRectGetMinY(self.character.frame)))
self.physicsWorld.addJoint(myJoint)
var myJoint2 = SKPhysicsJointPin.jointWithBodyA(character2.physicsBody, bodyB: character.physicsBody, anchor: CGPoint(x: CGRectGetMaxX(self.character2.frame), y: CGRectGetMaxY(self.character.frame)))
//self.physicsWorld.addJoint(myJoint2)
}
Does anyone know what the code would be to make a background image that would cover the whole GameScene.swift
This is my code atm -
import SpriteKit
class GameScene: SKScene {
let playbutton = SKSpriteNode (imageNamed: "play")
let score = SKSpriteNode (imageNamed: "score")
var background = SKSpriteNode (imageNamed: "background")
override func didMoveToView(view: SKView) {
func loadBackGround()
{
background = SKSpriteNode(imageNamed: "background")
background.name = "background"
background.zPosition = 1.0
background.size = self.scene.size
scene.addChild(background)
}
self.playbutton.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
self.addChild(self.playbutton)
self.score.position = CGPointMake(CGRectGetMidX(self.frame), 100)
self.addChild(self.score)
You may have to be more specific (iOS Game, Mac Game...), but I think something like this should work:
var bgImage:SKSpriteNode
func loadBackGround()
{
bgImage = SKSpriteNode(imageNamed: "BACKGROUND IMAGE NAME")
bgImage.name = "bg"
bg.size = self.scene.size
scene.addChild(bg)
}
(you can use it outside of a function of course)
EDIT: Try this code:
import SpriteKit
class GameScene: SKScene {
let playbutton = SKSpriteNode (imageNamed: "play")
let score = SKSpriteNode (imageNamed: "score")
var background = SKSpriteNode ()
func loadBackGround() // You define the function and what it does
{
background = SKSpriteNode(imageNamed: "background")
background.name = "background"
background.size = self.scene.size
scene.addChild(background)
}
override func didMoveToView(view: SKView) {
loadBackGround() // You call the function you defined
self.playbutton.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
self.addChild(self.playbutton)
self.score.position = CGPointMake(CGRectGetMidX(self.frame), 100)
self.addChild(self.score)
}
This is the way I use:
override init(size: CGSize) {
super.init(size: size)
anchorPoint = CGPoint(x: 0.5, y: 0.5)
let background = SKSpriteNode(imageNamed: "Background")
addChild(background)
}
This loads the background image from the asset catalog and places it in the scene. Because the scene’s anchorPoint is (0.5, 0.5), the background image will always be centered on the screen on both 3.5-inch and 4-inch devices.
I get this from a good tutorial: How to Make a Game Like Candy Crush with Swift Tutorial: Part 1