I had this Swift code in Xcode which worked perfectly:
var obstacles = [SKSpriteNode]()
obstacles.append(SKSpriteNode(imageNamed: "Rectangle"))
But I wanted to add an element to this array obstacles in order to have something like obstacles[i].newElement, so I tested this:
class obstacle: SKSpriteNode
{
var isActive = false
}
var obstacles = [obstacle]()
obstacles.append(SKSpriteNode(imageNamed: "Rectangle"))
obstacles[i].isActive = true
But I have an error with the line obstacles.append(SKSpriteNode(imageNamed: "Rectangle"))
which is: "missing argumentent for parameter 'size' in call", the thing is that I hadn't this error before and I don't know what is the problem.
If you could help me, thanks
You have declared the obstacles array as containing instances of obstacle, but you are trying to append an instance of its superclass, SKSpriteNode. Just change that to create an instance of obstacle instead:
obstacles.append(obstacle(imageNamed: "Rectangle"))
Remember that if you have a base class A and a subclass of it B : A, you can pass an instance of B where A is expected, but you cannot pass A where B is expected
Side note: by convention, type names in swift start with an uppercase - I suggest you to keep that convention - so it's better to rename your class as Obstacle
If you created an Array and specified that the type is Obstacle, you must add an Obstacle object.
Related
Hi this is my first time making a question so hopefully i have done this right :)
In my code Im trying to make a Arraylist that is within a class that only holds floats so I made this: (some information is taken away to make it easier to read)
class object {
private ArrayList yc=new ArrayList<Float>();
private ArrayList xc=new ArrayList<Float>();
object(float xer,float yer,float rer){
xc.add(10.0);
x=xer;
y=yer;
r=rer;
}
void update(){
print(xc.get(0))
x=xc.get(0);
}
}
everything else except x=xc.get(0) works outside of the class this assignment works but inside the class it doesn't
hope this makes sense thanks.
It seems like when you initialised the variable xc you specified the type of the ArrayList to Float. However, when declaring xc, you did not specify the type.
When you try to assign variable x with xc.get(0), you are basically assigning any Object to variable x that was declared as a Float.
To solve this issue you can declare your variable xc specifying the type of the ArrayList: private ArrayList<Float> xc = new ArrayList<Float>();
Also, processing offers the helper class FloatList as well if this suits your program.
This should solve your issue, depending on the rest of your code.
Wasn't exactly sure how to title this, but I need to count up how many enemies a player killed before they die and respawn for my point and health system.
My idea is to set up a variable that gets 1 added to it on each collide and then when the player is killed it takes the amount of that stored score variable and uses it for the point and for my health system, which is to move something up on the screen up.
Some super pseudo code would look like:
var storedPlayerScore = 0
var HealthPlus = SKAction.moveBy(CGVectorMake(0, (10 * storedPlayerScore)), duration: 0.05)
I've got both of those defined in my Gamescene.
and then down in my didbegincontact I'd just do like storedplayerscore++ whenever the two correct objects collide.
So before when I was just making sure the health going up worked, I had a number in where the stored variable was, but when I use this it gives me "Gamescene.type doesn't have a variable named storedPlayerScore"
Am I on the right track here? How do I clear the error I'm getting?
You are trying to access something on the type itself rather than on an instance of that type.
class GameScene {
var storedPlayerScore: Int = 0
}
var score1 = GameScene.storedPlayerScore // Error
let myGameScene = GameScene()
var score2 = myGameScene.storedPlayerScore // Works
This confusion is probably brought on by the names you're choosing for your variables. In your code above, you have a variable called HealthPlus which is named with a capital first letter. That makes it look like a type instead of an instance. The convention for variable names is start with a lowercase letter, while type declarations start with a capital letter. So it should be healthPlus instead.
I'm fairly new to lua and have the following problem with an assignment from a class:
We currently extend lua to support objects and inheritance. The Syntax for that is
Class{'MyClass',
attribute1 = String,
attribute2 = Number
}
Class{'MySubClass', MyClass,
attribute3 = Number
}
This works perfectly fine. The real problem lies within the next task: We should support "recursive types", that means a call like
Class{'MyClass', attribute = MyClass}
should result in an class with a field of the same type as the class. When this "class-constructor" is called the variable MyClass is nil, thats why the parameter table doesnt't have an entry attribute. How is it possible to access this attribute?
My first thought was using some kind of nil-table which gets returned every time the global __index is called with an unset key. This nil-table should behave like the normal nil, but can be checked for in the "class-constructor". The problem with this approach are comparisons like nil == unknown. This should return true, but as the __eq meta method of the nil-table is never called we cannot return true.
Is there another approach I'm currently just ignoring? Any hint is greatly appreciated.
Thanks in advance.
Edit:
Here the relevant part of the "testfile". The test by which the code is rated in class is another one and gets published later.
three = 3
print( three == 3 , "Should be true")
print( unknown == nil , "Should be true" )
Class{'AClass', name = String, ref = AClass}
function AClass:write()
print("AClass:write(), name of AClass:", self.name)
end
aclass = AClass:create("A. Class")
aclass:write()
Since MyClass is just a lookup in the global table (_G), you could mess with its metatable's __index to return a newly-defined MyClass object (which you would later need to fill with the details).
However, while feasible, such an implementation is
wildly unsafe, as you could end up with an undefined class (or worse, you may end up inadvertantly creating an infinite lookup loop. Trust me, I've been there)
very hard to debug, as every _G lookup for a non-existing variable will now return a newly created class object instead of nil (this problem could somewhat be reduced by requiring that class names start with an uppercase character)
If you go that route, be sure to also override __newindex.
How about providing the argument in string form?
Class{'MyClass', attribute = 'MyClass'}
Detect strings inside the implementation of Class and process them with _G[string] after creating the class
Or alternatively, use a function to delay the lookup:
Class{'MyClass', attribute = function() return MyClass end}
I am not sure is this is correct behaviour or if its unintended. I have setup StealthFighter so that it returns a class type computed property variable called ammunition.
func globalTests() {
println("globalTests")
println("AMMUNITION: \(StealthFighter.ammunition)")
var myStealthFighter = StealthFighter()
println("MISSILES: \(myStealthFighter.missiles)")
println("AMMUNITION: \(myStealthFighter.ammunition)") // ERROR
}
class StealthFighter {
class var ammunition:Int {
return 500;
}
var missiles: Int = 5
}
When directly accessing the class StealthFighter this works fine and returns 500 as expected. But if I create and instance myStealthFighter and then try and access the class property on the instance I get the error: 'StealthFighter' does not have a member named 'ammunition' I can't find any mention of this, I am assuming from this that class properties are accessible only via the class? and not on any instances created from it? I just want to make sure I am understanding this correctly ...
EDIT:
So I have probably worded the type variable name wrong as it should probably be maxAmmunition to signify that StealthFighters can only take 500 rounds. I can see the point, if you want the maxAmmunition for the class then you ask the class.
As #Kreiri and #0x7fffffff points out it does seem that you can ask the instance what the class ammunition (or maxAmmunition) is by using dynamicType.
println("CLASS - AMMUNITION: \(StealthFighter.ammunition)")
var myStealthFighter = StealthFighter()
println("INSTA - AMMUNITION: \(myStealthFighter.dynamicType.ammunition)")
.
// OUTPUT
// CLASS - AMMUNITION: 500
// INSTA - AMMUNITION: 500
Your assumption is correct. Type variables are only meant to be accessed directly from the class. If you want to get at them from an instance, you can do so by accessing the dynamicType property on your instance, like so.
let theFighter = StealthFighter()
let missiles = theFighter.dynamicType.missiles
println(missiles)
However, I don't think that this is the correct approach for you to be taking here. Assuming that you want to have one class "StealthFighter", and possibly multiple instances of that class, each with the ability to have its own number of missiles independent of the others, you should probably make this an instance variable by simply ditching the class keyword.
dynamicType allows access instance’s runtime type as a value, so accessing class property from instance would look like this:
var myStealthFighter = StealthFighter()
myStealthFighter.dynamicType.ammunition
Works in playground, at least.
These properties are known as Type properties in swift. It should be called on its type ie class name, not on instance. Type properties holds same value across all the instances of the class just like static constant in C.
Querying and Setting Type Properties
Type properties are queried and set with dot syntax, just like instance properties. However, type properties are queried and set on the type, not on an instance of that type
Excerpt from : swift programming language
Swift 4:
var myStealthFighter = StealthFighter()
type(of: myStealthFighter).ammunition
Yes. This is a correct behaviour. These Type Properties can only be accessed over the Type and are not available on the instance itself.
In the Swift Book from Apple it is described in the section "Type Properties" (Page 205).
Swift Type Properties
“Unlike stored instance properties, you must always give stored type properties a default value. This is because the type itself does not have an initializer that can assign a value to a stored type property at initialization time"
I have another odd problem with Objective C inheritance. I have a protocol called IGameObject, a class GameObject that inherits from NSObject and IGameObject and finally a Player that inherits from GameObject..
The problem is that when I assign a Player* to a IGameObject*, this produces an error, but it works ok when I assign a Player* to a GameObject*. I haven't seen that this is not possible in all I have read. Here the code:
-(IGameObject*) clone
{
Player* p=(Player*) 0xFFfFFFFF;
//Throws an error saying that Cannont initialise a variable of type IGameObject with an value of Player*
IGameObject* go=p;
//This works perfectly
GameObject* go2=p;
return [[Player alloc] initWithGameObject:self];
}
Could anybody guess what is happening?
Thanks in advance.
When returning (or declaring) a type that is only known by its interface, don't treat it as an object pointer. Instead, use:
-(id<IGameObject>) clone {
And:
id<IGameObject> go=p;
This should clear up that warning.
Sidenote: Why in the world are you assigning p to a memory address?!
You cannot create a pointer to a protocol
IGameObject* go=p;
is meaningless.