I've creating an ANIMATION type that I use to store a single animation loop, then I assign multiple ANIMATIONS to a character and switch between these based on the state of the character.
Initialization looks something like this.
ANGEL = FILE_LOADANIM("/Animations/Ubi/", "angel" + UBI_INDEX + ".xml")
FATSPR = FILE_LOADANIM("/Animations/Ubi/", "fat" + UBI_INDEX + ".xml")
FIRESPR = FILE_LOADANIM("/Animations/Ubi/", "fire" + UBI_INDEX + ".xml")
HITSPR = FILE_LOADANIM("/Animations/Ubi/", "hit" + UBI_INDEX + ".xml")
STATE = UBIFALLSPR
Then I try doing a comparison something like this.
IF UBISTATE = UBIFALLSPR // THIS ALWAYS RETURNS FALSE :(
UBIPOSY%=UBIPOSY%+1
ENDIF
I'm guessing that when I do the assignment it is actually creating a new object and the comparison is just checking if they are the same object. Is there a way to do this as more of a BYREF style assignment and have my comparison come back as I expect?
The easiest way would be do to a comparison function in the type...
I'm trying to do a copy by reference though. I want to do something like this; of course this does not work it really is just doing a new object inside the function and then assigns that back to the passed in reference. I'm looking for an ASSIGN by reference functionality; I want variable A to point to the address of variable B, so that if I update attributes on A they are reflected in B and vice versa.
TYPE ANIMATION
SOME
VARIABLES
HERE
FUNCTION copy: foo AS ANIMATION
foo = self
return foo
ENDFUNCTION
ENDTYPE
When I tried to do that I received compiler errors
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_tempg.cpp:2:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_tempg.cpp:110: error: `DGInt __GLBASIC__::ANIMATION::copy' is not a static member of `class __GLBASIC__::ANIMATION'
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_tempg.cpp:110: error: `Anything' was not declared in this scope
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_tempg.cpp:111: error: expected `,' or `;' before '{' token
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp0.cpp:1:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp1.cpp:1:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp2.cpp:1:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp3.cpp:1:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp4.cpp:1:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp5.cpp:1:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
In file included from C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp6.cpp:1:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: `Anything' has not been declared
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:116: error: ISO C++ forbids declaration of `foo' with no type
*** FATAL ERROR - Please post this output in the forum
I don't really understand the question but the syntax is wrong for GLB. GLB needs to know what type you are returning from a function.
So this...
FUNCTION copy: foo AS ANIMATION
foo = self
return foo
ENDFUNCTION
becomes this...
FUNCTION copy AS ANIMATION: foo AS ANIMATION
foo = self
RETURN foo
ENDFUNCTION
which could be shortened to this...
FUNCTION copy AS ANIMATION:
RETURN self
ENDFUNCTION
Sorry; that was just some untested sample code, you are right that it should be slightly different, but the issue remains the same.
Here, I will try to provide a better example using the same function.
TYPE ANIMATION
VAR1
VAR2
FUNCTION copy AS ANIMATION:
RETURN self
ENDFUNCTION
FUNCTION init:
// set some vars here...
VAR1 = 1
VAR2 = 2
ENFUNCTION
ENDTYPE
A AS ANIMATION
B AS ANIMATION
A.init()
B = A.copy()
B.VAR1 = 3
PRINT A.VAR1, 0, 0
PRINT B.VAR1, 0, 200
This would print to the screen
1
3
This is because the B = A or B = A.copy() results in a new TYPE instance being created for B with a copy of the values from A. At the point in time that I make the copy; they look the same, but they are really clones, not 1 same object. Changes made to A do not update B and same for changes to B do not update A. This is a VALUE copy. I'm wanting a REFERENCE copy; so I would like B = A to really just mean that B POINTs TO A; just as we would do using pointer logic in C/C++.
Maybe this is possible only through some inlining of C++ code into my game, but I am hoping this is not the case and there is some type of simple pointer based assignment in GLBasic that i just am unaware of?
I tried to do this directly in C++ using INLINE like this
FUNCTION copyanim: a AS ANIMATION, b AS ANIMATION
INLINE
a = &b;
ENDINLINE
ENDFUNCTION
I expected this would actually work, but it fails to compile!
IncrediBuild skips: UpUpUbi.gbas, Globals.gbas, jolib2.gbas, Ubi.gbas, VolcanoIsland.gbas, xmlparser.gbas,
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp1.cpp: In function `DGInt __GLBASIC__::copyanim(__GLBASIC__::ANIMATION&, __GLBASIC__::ANIMATION&)':
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp1.cpp:115: error: no match for 'operator=' in 'a = +b'
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp.h:131: note: candidates are: __GLBASIC__::ANIMATION& __GLBASIC__::ANIMATION::operator=(const __GLBASIC__::ANIMATION&)
*** FATAL ERROR - Please post this output in the forum
Thats because there is no equality routine in the type when compiling :)
This just confuses me more. I'm not trying to do a comparison in my inline C++; I'm trying to do a simple pointer assignment.
Could you just not stick your ANIMATION types in an array, then use a State variable as an index?
Something like this...
TYPE ANIMATION
spriteBase%
currentFrame%
frames%[]
FUNCTION load: filename$
ENDFUNCTION
FUNCTION animate:
ENDFUNCTION
ENDTYPE
CONSTANT falling = 0
CONSTANT jumping = 1
GLOBAL state = falling
GLOBAL a[] AS ANIMATION
DIM a[2]
a[falling].load("falling.xml")
a[jumping].load("jumping.xml")
a[state].animate()
IF state=falling THEN blah...
Uhm
Function copy: a as T, b as T
a=b
Endfunction
Local a as T, b as T
b.val=100
copy(a,b)
this should work.
Ah. Silly me. You need a reference? What for?
Alias would generate a reference.
I ran into the 'how do a get a reference to a type' issue a year or so ago.
I have my own 'Font' type specifying settings for each one of my fonts (including the graphics file).
I also created my own 'Gui' type, and wanted each gui element to have a 'font' setting.
After researching this for a bit I realized GLBasic doesn't offer references, just copies.
So each of my gui elements (buttons, labels, etc) had a COPY of each font object, a huge memory waste.
(Only evident after making changes to the master font instance, and noticing the copies weren't changing too?!)
What I did (kinda kludgy) was instead store a font 'id' in each element, and have a font lookup based on id (or a font array and the id is the index).
I have used ALIAS in other situations, but wasn't clear or apparent it could be used in these situations.
One problem with Alias is that you cant copy and store the value in a variable, it will copy the what its pointing to instead.
So, do we need a new GLBasic command? (ie 'BYREF')
LOCAL one AS TFoo // Normal TFoo instance
LOCAL two AS TFoo // Normal TFoo instance
LOCAL three AS TFoo BYREF // Reference to a TFoo instance
one.parameter = 49
two = one
three = one
one.parameter = 72
DEBUG two.parameter // Prints "49"
DEBUG three.parameter // Prints "72"
[Edit] But what do you do if you reference 'three' before it has been assigned?
It would be 'null' and therefore you would need a new error 'BYREF Variable not assigned!' or something.
You can't really reference TFoo as its just a type definition.
For a comparison, you would have to write your own routine, something like :
TYPE Ta
a%;b%;c%
FUNCTION compare%:b AS Ta
IF self.a%=b.a% AND self.b%=b.b% AND self.c%=b.c%
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNCTION
ENDTYPE
I'm not trying to reference the type definition so much as I am trying to reference an INSTANCE of the the type definition. Like Slydog said; it is a huge waste of memory to have to create many copies in memory of the same object; this is what I'm trying to avoid. I'm releasing on so low end Android devices too so my memory is cherished resource.
@Kitty Hello,
I just tried the ALIAS command and it doesn't seem to work quite right. Maybe it has problems when trying to alias to TYPEs rather than a simple data type? but definitely was not correctly pointing to the object :(
ALIAS works correct for me:
QuoteLOCAL a AS Tmytype
ALIAS b AS a
This works too:
QuoteLOCAL a AS Tmytype
ALIAS b AS a.id
But ALIAS has one limitation, this does not work:
QuoteLOCAL a AS Tmytype
LOCAL b AS Tmytype
ALIAS b.a AS a
Did you try the last one or had problems with one of the other samples? Basically atm you can just store a pointer in a variable with normal datatype (you dont need to define it before the alias, its local by default), but you cant store the pointer in a type, which would be great.
Alias makes a variable that points to (=reference) whats right of the "as" argument. You cannot hold references in types. Also reference pointers might break if you point into an array element and reallocate the container (dimpush, dimdel, ...)
Here is my fully implemented TYPE
TYPE ANIMATION
ID // This is a unique identifier for this particular animation
ANIM_INDEX // This is the sprite index
CURR_FRAME
NUM_FRAMES
NAME$
STEPTIME% // delta step for fixed or absolute time to finish
LAST_UPDATE_TIME
TIMESTEPMODE
LOOPMODE
FUNCTION draw:x%,y%
DRAWANIM self.ANIM_INDEX, self.CURR_FRAME, x%, y%
ENDFUNCTION
FUNCTION init: index%, width%, height%, name$
self.ANIM_INDEX=index%
self.CURR_FRAME=0
LOCAL sx%,sy%
GETSPRITESIZE index, sx%, sy%
self.NUM_FRAMES = sx%/width%
self.NAME$=name$
self.STEPTIME%=100
self.LAST_UPDATE_TIME = MASTERTIMER
self.LOOPMODE=LOOPFOREVER
ENDFUNCTION
FUNCTION anim:
IF(GETTIMERALL() > (self.LAST_UPDATE_TIME + self.STEPTIME%))
self.CURR_FRAME = IIF(self.CURR_FRAME>=(self.NUM_FRAMES-1), 0, self.CURR_FRAME+1)
self.LAST_UPDATE_TIME = GETTIMERALL()
ENDIF
ENDFUNCTION
FUNCTION is_equal: an AS ANIMATION
IF an.ID = self.ID
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNCTION
ENDTYPE
I create my first TYPE like so
UBIFALLSPR = FILE_LOADANIM("/Animations/Ubi/", "falling" + UBI_INDEX + ".xml")
After this I do my alias
ALIAS UBISTATE AS UBIFALLSPR
In an update statement I call UBISTATE.anim() so that whatever I'm currently pointing to should animate.
When I call UBISTATE.draw(x,y) nothing shows up on screen.
If I do the same directly as UBIFALLSPR.draw(x,y) it shows up fine and is animating correctly (anim is still called on UBISTATE); so it seems something is being corrupted.