When going from GameScene to PlayScene using this code below, all works fine:
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if self.nodeAtPoint(location) == self.playButton1 {
var scene = PlayScene(size: self.size)
let skView = self.view as SKView!
skView.ignoresSiblingOrder = true
scene.scaleMode = .ResizeFill
scene.size = skView.bounds.size
skView.presentScene(scene)
}
}
But when i am going from PlayScene to GameScene using this code below, it gets zoomed in:
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
let skView = self.view as SKView!
skView.ignoresSiblingOrder = true
scene.scaleMode = .ResizeFill
scene.size = skView.bounds.size
skView.presentScene(scene)
}
Tried to Updated code:
var scene = GameScene(size: self.size)
let skView = self.view as SKView!
skView.ignoresSiblingOrder = true
scene.scaleMode = .ResizeFill
scene.size = skView.bounds.size
skView.presentScene(scene)
}
How come? Any suggestions?
In the first code snippet, you create the new scene of self.size which keeps the same size as the old one. But in the second one, you use another method to do that, and the size of the new scene is initialized from the file GameScene.sks whose size is 1024x768 by default.
EDIT:
Did you use
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {...}
to create your first scene in your GameViewController.swift? If so, try to replace this line with
let scene = GameScene(size: view.bounds.size)
I'm afraid the reason why your buttons get resized(zoomed) is that they are not in the right size at the first time you load GameScene, actually they are in a scene sized 1024x768. Your button is hard-coded as 400 width which is nearly the 1/3 of the scene width (1024pt). When you load GameScene again, its width now becomes the screen width, so you find buttons get resized. Print scene.size.width for more info.
I had the same problem.
For me the problem was that the scene size had changed to be much smaller when going back to the first scene.
Scene 1) GameMap Scene
Original Scene Size: (1024.0, 4096.0)
Original View Size : ( 320.0, 480.0)
Scene 2) GameLevel Scene
Original Scene Size: ( 320.0, 480.0)
Original View Size : ( 320.0, 480.0)
When Moving from Scene 1 to Scene 2 everything looked fine but when moving back from Scene 2 to Scene 1 The "Scene 1" size is changed to Scene 2's size
Scene 1) GameMap Scene -> After Going Back
Original Scene Size: ( 320.0, 480.0)
Original View Size : ( 320.0, 480.0)
My solution was to specifically change the size of the scene in "didMoveToView" and set the scaleMode of the "Scene 1" see below:
self.view?.bounds = CGRectMake(0, 0, Constants.screenWidth, Constants.screenHeight)
self.scene?.size = CGSizeMake(1024, 4096)
self.scaleMode = SKSceneScaleMode.AspectFill
Hope it helps
BR
BuD
Related
I have a camerNode position issue. I have included the code below + an attempt of resolving this with no progress. Essentially in my GameScene I have the camera locked perfectly onto the player when moving through the scene, I am actually trying to amend this so that the camera is slightly ahead of the player, this meaning my player is actually positioned on the left side of the screen, almost like an offset (+ 200) :) if this existed.
The Code:
class GameScene: SKScene, SKPhysicsContactDelegate {
// Create a constant cam as a SKCameraNode:
let cam = SKCameraNode()
override func didMove(to view: SKView) {
// vertical center of the screen:
screenCenterY = self.size.height / 2
// Assign the camera to the scene
self.camera = cam
//Add the camera itself to the scene's node tree"
self.addChild(self.camera!)
// Position the camera node above the game elements:
self.camera!.zPosition = 50
}
override func didSimulatePhysics() {
// Keep the camera locked at mid screen by default:
var cameraYPos = screenCenterY
cam.yScale = 1
cam.xScale = 1
// Follow the player:
if (player.position.y > screenCenterY) {
cameraYPos = player.position.y
cam.yScale = newScale
cam.xScale = newScale
}
// Camera Adjustment:
self.camera!.position = CGPoint(x: player.position.x, y: cameraYPos)
I initially thought that I could overcome this by changing the player to another SKSpriteNode.. i'e in my HUD class I could add a node and apply this code around? I could then refer back to my player class in which I already defined the position above my override func didMove.
let initialPlayerPosition = CGPoint(x: 50, y: 350)
I did try this and the GameScene started playing up, is there a better method for achieving this result? I assume the code could be changed to accommodate but I am still in the learning grounds of Xcode.
Never mind - solved it!
Camera adjustment statement - player.position.x + 200) :)
This does the trick!
I have a problem with exporting scene from SCNView.
In Xcode I made simple scene with light and one big, transparent box.
Colourful small boxes are generated inside running application.
Scene in SCNView looks like this:
I'm happy with this.
But if I export file by
#IBAction func exportDAE(_ sender: Any) {
if let scene = view3D.scene {
let panel = NSSavePanel()
panel.allowedFileTypes = ["dae"]
panel.runModal()
if let url = panel.url {
scene.write(to: url,
options: nil,
delegate: nil,
progressHandler: nil);
}
}
}
An error is thrown:
2019-12-02 13:27:16.450749+0100 ShowMeInstances[83949:14810790] errors encountered while discovering extensions: Error Domain=PlugInKit Code=13 "query cancelled" UserInfo={NSLocalizedDescription=query cancelled}
all small boxes are destroyed, only one big looks OK:
Sometimes materials are broken too: (those magenta destroyed boxes should have similar color to surrounded boxes:
In AppDelegate I defined:
var instancesNode: InstancesNode? = nil
which is inited by:
class InstancesNode: SCNNode {
typealias CoordUnit = Double
var instanceGenerator: InstanceGenerator<CoordUnit>?
init(with data: Data) throws {
self.instanceGenerator = try InstanceGenerator(from: data)
super.init()
for instance in instanceGenerator?.instances ?? [] {
let coords = instance.coordinates.map( {$0.value})
let color = getMaterialDiffuseColor(for: coords)
let coords3D = convertCoordinatesTo3D(coords)
let node = Instance3D(
name: instance.instanceName,
coordinates: coords3D,
color: color)
self.addChildNode(node)
}
}
.....
}
now Instance3D is inited by
class Instance3D: SCNNode {
init (name: String, coordinates: SCNVector3, color: NSColor) {
super.init()
self.name = name
let box = SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)
let material = SCNMaterial()
material.diffuse.contents = color
material.emission.contents = color
material.lightingModel = .lambert
material.metalness.contents = 0
material.shininess = 1
box.materials = [material]
self.position = coordinates
self.geometry = box
}
Everything is inserted into scene by
view3D.scene?.rootNode.addChildNode(instancesNode!)
in appDelegate. Without this line only big box and light are visible in view.
Also file cannot be imported by Blender, Blender silently and immediately explodes.
What could be a reason? Is it a feature or is it a bug?
When I generate just one Instance, generated box is OK, can import file to Blender, if two — only one is OK, Blender explodes. If i change box to sphere — one one sphere is visible in QuickLook
Definitely bug.
I can confirm. The following code, once exported from SceneKit in .dae format will crash Blender (and will cause an error in Meshlab, and not render correctly in Mac OS X's finder preview).
var radius = 0.0005
let s1 = SCNNode(geometry: SCNSphere(radius: CGFloat(radius)))
let s2 = SCNNode(geometry: SCNSphere(radius: CGFloat(radius)))
s1.position = SCNVector3(0,0,0)
s2.position = SCNVector3(1,0,0)
scene.rootNode.addChildNode(s1)
scene.rootNode.addChildNode(s2)
I've run into a simple problem, that I can not solve even after looking everywhere..
I made a grey table view, and at the top I have a cell with white background.
Is it possible to whenever the user refreshes, make it also white (on the top)?
Try this code
let refresh = UIRefreshControl()
let backgroundColor = UIColor.red
refresh.backgroundColor = backgroundColor
refresh.addTarget(self, action: #selector(self.refreshs), for: .valueChanged)
tableView.addSubview(refresh)
var frame = tableView.bounds
frame.origin.y = -frame.size.height
let backgroundView = UIView(frame: frame)
backgroundView.autoresizingMask = .flexibleWidth
backgroundView.backgroundColor = backgroundColor // background color pull to refresh
tableView.insertSubview(backgroundView, at: 0)
I'm new with Xamarin. I'm actually trying to set the background image of a view and stretch it.
The image is a 2048x1536 pixels png.
nfloat vpHeight = View.Bounds.Height;
nfloat vpWidth = View.Bounds.Width;
Console.WriteLine(vpWidth);
Console.WriteLine(vpHeight);
The above code will return me 1024x768 (it's a landscape position).
var img = UIImage.FromFile("pages/p1.png");
UIImageView imgView = new UIImageView(img);
imgView.ContentMode = UIViewContentMode.ScaleAspectFit;
var prevPage = new UIView()
{
Frame = new CoreGraphics.CGRect(0, 0, vpWidth, vpHeight)
};
prevPage.Add(imgView);
this is the code where I set the background, but the result is just the half of the image in x and y just like the image bellow:
So, how to make the image to adjust to the width and height of the view ?
ty !!
I would create an UIImageView as a background like so:
var img = UIImage.FromFile("pages/p1.png");
UIImageView imgView = new UIImageView(img);
imgView.ContentMode = UIViewContentMode.ScaleAspectFit;
then add this to whatever view you are using.
ContentMode can be used like so:
Update
I would add it to the prevPage like so:
var prevPage = new UIView()
{
Frame = new CoreGraphics.CGRect(0, 0, vpWidth, vpHeight)
};
var img = UIImage.FromFile("pages/p1.png");
UIImageView imgView = new UIImageView(new CGRect(0,0,vpWidth,vpHeight));
imgView.Image = img;
imgView.ContentMode = UIViewContentMode.ScaleAspectFit; // or ScaleAspectFill
prevPage.Add(imgView);
Also its worth noting that using the View.Bounds to position the view is bit clunky. I would take a look into Autolayout as you will encounter problems on different devices and orientations. These are some good tutorials on Autolayout they might be native code but you are looking for the relationships of the views rather than the code.
Raywenderlich tutorial
Other Tutorial
Any probs with autolayout just ask another question.
I would recommend you stay away from FromPatternImage unless you are really using a pattern.
For the lowest memory consumption and best UI performance, this is what I do:
1st) Resize your image using an image context to match the size of the view:
UIGraphics.BeginImageContext(View.Frame.Size);
UIImage.FromBundle("bg.jpg").Draw(View.Bounds);
var bgImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
2nd) Display the resized image in a UIImageView and send it to the lowest Z-order:
var uiImageView = new UIImageView(View.Frame);
uiImageView.Image = bgImage;
View.AddSubview(uiImageView);
View.SendSubviewToBack(uiImageView);
I am trying to draw a SKSpriteNode that is 30 tall and has the width of the viewport. This is the code (inside SKScene):
func floor() -> SKSpriteNode{
let floor = SKSpriteNode(color: SKColor.greenColor(), size: CGSizeMake(self.size.width, 20))
floor.position = CGPointMake(0, 0)
floor.physicsBody = SKPhysicsBody(rectangleOfSize: floor.size)
floor.physicsBody.dynamic = false
return floor
}
The sprite is added to the scene like this:
override func didMoveToView(view: SKView!){
if (!contentCreated){
self.createContents()
contentCreated = true
}
}
func createContents() {
self.backgroundColor = SKColor.blackColor()
self.scaleMode = SKSceneScaleMode.AspectFill
self.addChild(self.floor())
}
The sprite is 30 tall (seemingly), but the length seems to be half of the viewport in width instead of the full width. The code that creates this scene is:
var mainScene = MainScene(size: self.view.frame.size)
spriteView.presentScene(mainScene)
This code is inside a ViewController.
Does anyone know what might be going on?
The default anchorPoint of a sprite node is { 0.5, 0.5 }, which could result in the code above positioning only half of your sprite on the screen. Try setting the anchorPoint to { 0.0, 0.0 } and see if that helps.