I wanna declare a record inside a class as follows:
class player (x, y)=
object(self)
type gun = {x:int; y:int; active:bool}
val guns = Array.create 5 {x=0; y=0; active=false}
....
but the compiler claim that this line is syntax error : type gun = {x:in ....
when declared outside the class like this
type : gun = {x:int; y:int; active:bool}
class player (x, y)=
object(self)
val guns = Array.create 5 {x=0; y=0; active=false}
....
the error is : unbound value gun.
so anyone know how to reach the same functionality with another way?
thank you!
********* solved***
Bizare now it's working when the type is declared outside, thank you
Why don't you define the type gun outside of the class definition?
Related
The program I'm writing is storing elements in a hash called grid of type Position => LivingBeing | Thing. This grid is stored on a Map and I would like this Map to return the position of an element of class Apple which is a subclass of Thing.
However, when using typeof() to get the class, I get LivingBeing | Thing instead of the subclass Apple
Here is the Map class:
class Map
##grid = {} of Position => LivingBeing | Thing
def initialize()
end
# Add an entity to the grid
def add_entity(new_entity : LivingBeing | Thing)
##grid[new_entity.position] = new_entity
end
# Return the position of an object of class "something"
def self.where_is?(something : Class)
# First attempt was to get the key by the value
# ##grid.key(something)
##grid.each do |position, thing|
# Returns "thing #<Apple:0x55f1772085c0> at Position(#x=1, #y=2) is (LivingBeing | Thing)"
puts "thing #{thing} at #{position} is #{typeof(thing)}"
position if typeof(thing) == something
end
end
Here the Thing class:
abstract class Thing
getter position
#name = "Unkown object"
def initialize(#position : Position)
end
end
class Apple < Thing
#name = "Apple"
end
Here the Position struct:
struct Position
getter x, y
def initialize(#x : Int32, #y : Int32)
end
end
And here is the test I try to make it pass:
it "gives a random thing location based on its class" do
world = Map.new()
apple = Apple.new(Position.new(1, 2))
puts "Apple type : #{typeof(apple)}" # Returns "Apple type : Apple"
world.add_entity(apple)
position = Map.where_is?(Apple)
position.should eq Position.new(1, 2)
end
Is there some class method or function which could give the Apple class?
Or is it a design issue?
Thank you for your answer !
You can use forall to solve this:
# Return the position of an object of class "something"
def self.where_is?(something : T.class) forall T
##grid.each do |position, thing|
return position if thing.is_a?(T)
end
end
and call it using Map.where_is? Apple just like you wish.
This works because the type variable T (introduced using forall T) can be inferred to be Apple from passing in the constant Apple which matches the T.class type restriction. T is then a constant you can use with is_a?.
One solution I have is this for my function:
# Return the position of an object of class "something"
def self.where_is?(something)
##grid.each do |position, thing|
return position if thing.is_a?(typeof(something))
end
end
And this for the test:
it "gives a random thing location" do
world = Map.new(4)
apple = Apple.new(Position.new(1, 2))
world.add_entity(apple)
position = Map.where_is?(Apple.new(Position.new(0, 0)))
position.should eq Position.new(1, 2)
end
I will use it like this if there is no other solution. But I would prefer to be able to search directly the class Apple instead of creating an instance of Apple
I would like to be able to do position = Map.where_is?(Apple) instead of
position = Map.where_is?(Apple.new(Position.new(0, 0)))
As # RX14 said, it looks like you want to check the run-time "type", i.e. .class. Here's an example:
class Apple
#name = "Apple"
end
def check(obj : Object)
obj.class == Apple
end
a=Apple.new
p check(a)
EDIT I have found a much easier way to do this in lua but the problem is method inheritance
basically the syntax would go like this
Object
object = {}
object.base = ?
object.value = 0
function object:create(x, y)
local copy
--copy table
if type(self) == "table" then
copy = {} for k, v in pairs(self) do copy[k] = v:create() end
else
copy = self
end
--set base
copy.base = self
--set copy vars
copy.x = x
copy.y = y
return copy
end
function object:update()
self.value = self.value + 1
end
Player
player = object:create()
player.value = 1
function player:create(x, y, size)
base:create(x, y) --inherit base event
end
--automaticly inherits update event since it is not redeclared
I'm not sure how to go about doing this though
Inheritance in Lua is basically implemented using metatables. In code:
function object:new (o)
o = o or {}
-- Put the rest of your create function code here
setmetatable(o, self)
self.__index = self
return o
end
function object:update()
self.value = self.value + 1
end
Now create an empty Player class that will be a subclass of your base Object class and will inherit all its behavior from it.
Player = Object:new()
Player is now an instance of Object. Instantiate a new Player object, p in order to inherit the new method from Object.
p = Player:new{x=1, y=2, size=3}
This time, however, when new executes, the self parameter will refer to player. Therefore, the metatable of p will be Player, whose value at index __index is also Player. So, p inherits from Player, which inherits from Object.
Now when you'll code:
p:create{x=10, y=20, size=100}
lua won't find a create field in p, so it will look into Player class; it won't find a create field there, too, so it will look into Object and there it will finds the original implementation of create. The same thing will happen with the update function.
Of course Player class can redefine any method inherited from its superclass, Object. So for example you can redefine -if you want- the create function:
function Player:create()
--New create code for Player
end
Now when you'll call p:create{x=10, y=20, size=190}, Lua will not access the Object class, because it finds the new create function in Player first.
You are making a reference to base directly, whereas, it is actually an attribute of your player object:
function player:create(x, y, size)
self.base:create(x, y)
end
So the title is a bit weird but i didnt know how to call it.
I am working on a FPS game and I am trying to make a simple weaponsystem. Every Player can have a primary and a secondary weapon. I am at the moment trying to write a script to change between the assigned primary/secondary weapons.
So at first I am doing this:
var primary : GameObject;
var secondary : GameObject;
So I have some GUI Buttons that when they get clicked they assign the desired weapon to the variables primary/secondary.
An code example:
function assignump45() {
primary = ump;
}
Now I want to write a function to switch between the primary and secondary weapon.
So I tried this:
function switchtoprimary(){
if(Input.GetKeyDown("2")){
primary.inv(); //makes the primary weapon invisible
secondary.vis(); //makes the primary weapon visible
}
}
Of course I get this error:
BCE0019: 'inv' is not a member of 'UnityEngine.GameObject'.
I know that what I wrote is wrong. So I tried to get the script of the primary/secondary weapons so I can disable/activate them:
var primscipt : umpscript = GameObject.Find(ump).GetComponent(umpscript);
This works BUT I can´t write for every weapon this kind of script because I then I need to write several combinations of switching between the weapons and that isn´t possible because i know there is a better solution..
I can´t do a if clause and then assign the primscript because the variable only would be assigned in the if clause..
What I need is something like this (doesn´t work of course^^).
var primscipt : primaryscriptstring = GameObject.Find(primarystring).GetComponent(primaryscriptstring);
So I could assign the variable primaryscriptstring with "umpscript" for example. the variable primarystring does work in this case
Are there any workarounds? I am pretty desperate at the moment :/
You'll probably want to create a Weapon class, and have your primary and secondary vars be Weapons, not GameObjects.
var primary : Weapon;
var secondary : Weapon;
Your Weapon.js file might look something like:
function vis () {
...
}
function inv () {
...
}
Then assuming you want to have every weapon type be an extended class of Weapon, you might create a UMP.js file for example and have its class extend Weapon like so:
#pragma strict
class UMP extends Weapon {
}
UMP then inherits all functions and vars from the Weapon class. So then, elsewhere in your code, the following line would work (assuming there's a GameObject named "UMP" somewhere that has the UMP component attached):
function assignump45() {
var ump : UMP = GameObject.Find("UMP").GetComponent(UMP);
primary = ump;
primary.vis();
}
Alternatively, you might not want to have every weapon type be an extended class, and just have one Weapon class for all weapons, in which case you wouldn't create a UMP.js file, and instead your code might look like:
function assignump45() {
var ump : Weapon = GameObject.Find("UMP").GetComponent(Weapon);
primary = ump;
primary.vis();
}
Instead of
primary.inv();
secondary.vis();
do
primary.SetActive(false);
secondary.SetActive(true);
The SetActive method works for any game object, so you don't have to worry about the specific type of weapon or script. See the Unity docs on this here.
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.
I might be missing something. I thought this would be a common question but extensive search on the web over a few days didn't turn up the answer I need. I am hoping to make a self-contained movie clip that would function wherever it is placed. However, it seems difficult to access instances defined in the movie clip from within a class that extends the movie clip.
Although I am coding in Flash Actionscript 2 (AS2), I wonder if the same issue exists for AS3.
In the following scenario, how do you access the instance "circle"?
A movie clip on the main timeline has an instance name "square". A class Square defined in Square.as extends this movie clip. Inside the movie clip, another movie clip is placed on the first frame, with instance name "circle". There is also a varialbe declared on the first frame var myName:String = "my name". The following code doesn't compile:
class Square extends MovieClip {
function Square() {
trace("Square.constructor, circle: " + circle);
trace(" --- myName: " + myName);
}
}
Compiler errors: There is no property with name 'circle'. (same for myName).
Adding this. in the reference doesn't help. Apparently, the compiler is looking for the varialbles in the class definition.
Using _level0.square.circle works, but that requires the class to know its own instance path. While _level0.square.myName doesn't produce compiler errors, it gives a value of undefined.
Referencing these variables in methods other than the constructor causes the same compiler errors.
Thanks much for your help.
I found a way to solve the problem, using eval(this).
class Square extends MovieClip {
var base:MovieClip;
function Square() {
base = eval(this);
trace("Square.constructor, circle: " + base.circle);
trace(" --- myName: " + base.myName);
onPress = procPress;
}
function procPress() {
trace("procPress: " + base.circle);
trace("procPress: " + base.myName);
}
}
No compiler errors. In the constructor, base.myName is still undefined (understandable). In the function procPress invoked by a click, base.myName has the correct value.