OOP question

BlitzMax Forums/BlitzMax Programming/OOP question

Cruis.In(Posted 2006) [#1]
hey every one, just a quick thing.

I made a Type for invisibility. It was coded a year ago so at the time i thought it was the best way to work. so for invisibility to work obviously i have to instance an object on that type and use its methods on an object i want invisible.

I have realised while doing AI this method won't be suitable. So ive moved all the methods of that type to my players ship type. The type which i Base the player ship off of, which is extended by an enemyship type for enemy ships.

So am I correct that by using SELF while programming the AI functions/routines/methods that I can get any object of the current type once the condition has been reached, to invoke the said invisible methods on the object that called it?

so say ship A is damaged and wants to go invisible, the code to go invsisible will only work on Ship A because his condition is met and only the instance of Ship A uses the code because I use self in the routine to go invisible, which by using SELF it provides a way for a method to refer to the instance of the type that called the method.


bradford6(Posted 2006) [#2]
if an instance of the type calls the method. self is assumed.

no need to use it in this scenario.

some code would help...


Gabriel(Posted 2006) [#3]
So am I correct that by using SELF while programming the AI functions/routines/methods that I can get any object of the current type once the condition has been reached, to invoke the said invisible methods on the object that called it?

Methods - yes, Functions - no. Methods are called by a type instance, functions are not. Since there is no type instance calling a function, there is no Self.

so say ship A is damaged and wants to go invisible, the code to go invsisible will only work on Ship A because his condition is met and only the instance of Ship A uses the code because I use self in the routine to go invisible, which by using SELF it provides a way for a method to refer to the instance of the type that called the method.

That's not the clearest explanation I've ever heard ;) But yes, If you call a method with :

ShipA.DoAI()



And your Type includes :

Type Ship
   
   Field Alpha:Float=1.0

   Method DoAI()
      If ConditionMet=True
         Self.MakeInvisible()
      End If
   End Method

   Method MakeInvisible()
      Self.Alpha=0
   End Method
   
End Type


Then yeah, it'll only happen on the ship you use when calling DoAI()

Of course, self isn't actually needed for the most part. You could have this instead :

Type Ship
   
   Field Alpha:Float=1.0

   Method DoAI()
      If ConditionMet=True
         MakeInvisible()
      End If
   End Method

   Method MakeInvisible()
      Alpha=0
   End Method
   
End Type


Self is sort of implied unless there are local variables ( or functions? ) with the same name.


Grey Alien(Posted 2006) [#4]
I have validly used self I'm sure, but I can't remember why? Perhaps it's when I have a local variable in a method called X or something, and then I want to access the type's X field so I've used self.x. But that would be pretty lame code...

Aha just searched my code, and the most common use is when I have extended TList and I want to loop through it so I do For Local o:TObject = eachin self for example.

Also sometimes I have a list of objects and I want the objects to reference the list, so when I make a new object via the list (say with a method called AddNewObject), I set a field on the object to be Self (which is the list). Then later I can get the object to remove itself from the list by looking at its field which references the list and then calling TheList.Remove(self) which removes the object. Hmm I'm probably not being very clear, but yeah it can be useful.

A final use is, say a method on a Type calls an external function that you've designed to work on that sort of type, and the function needs one of those types passed into it as a parameter, well you can pass the parameter in as self of course!


H&K(Posted 2006) [#5]
I use Self all the time, because in Blide self is an object name and so the memeber popup appears, also My create function call an allocate method that returns Self.

@ Cruis, I didnt try and answer your question, because I honestly did really understand what you ment. But as said above self within a method means "The object that called the method". IT dosnt work for function within a type, because they are called by the type and not an instance of the type. So even if you went object.AFunctionofTypeA, although it looks like you have called the function with object you havent you have called it with the type A.

Also, errrm dont now how to ask this. But how did you make a type for Invisability? Could you possibly post that type. ie the one from last year. Thanks


Cruis.In(Posted 2006) [#6]
what do you mean you don't know how to ask this?
it would most honour me to show you this code...

or is it because i ask ditsy stuff always...

however i feel you will be greatly disappointed... :)

and i will show you none the less.

i have since moved the methods over to my tplayership, because i dont think they need there own type. or need an object of the Type Tcloak to be able to perform them, just seems unneccessary and newbiesh :)

here it is

'-----------------------
'CLOAK TYPE
'-----------------------
Type Tcloak
	Field set_transparency:Float
	Field current_transparency:Float = GetAlpha()
	Field de_trans:Float = 0.007
	Field maxdetrans:Float = 0.007
	
	
	'if the Alpha is less than 1.0 it slowly decreases till its 0.3 (used in method draw)
	Method start()
		If current_transparency > set_transparency
			current_transparency :- de_trans 	* delta
		End If 
		
		If current_transparency < 0.3
			current_transparency = 0.3
		End If
	End Method 		
			
	'same as above
	Method uncloak()
		If current_transparency < 1.0
			current_transparency :+ de_trans 	*delta
		End If 
		
		If current_transparency > 1.0
			current_transparency = 1.0
		End If		
	End Method 			
	
	'cloaks the ship, sets start cloak to true, method START() can now be called
	'Which does the calculation to cloak(fade transparency) Only a cloakable ship can cloak, hence
	'cancloak must = true.
	Method Cloaking()
		If hi_thighgui.iskeyhit(KEY_C)  
			If ship.IsCloaked = False 
				If ship.CanCloak = True 
					If ship.Start_Cloak = False
						dSFX.Create(CloakFx, CloakShip, 2000)
						set_transparency = 0.3
						ship.start_cloak = True
						ship.start_DeCloak = False
					End If
				End If 
			End If 
		End If
	
		'I want decloak to be press shift(holddown) + C and this is the way it works
		'putting the hi_thighgui.iskeydown for C first, even though its the last button pressed, and the
		'key hit for shift last. Reversing has the opposite effect, C then shift to decloak.
		'reverses the process of Start(), when you press this the uncloak() method is called 	
		If hi_thighgui.iskeydown(KEY_C) 
				If ship.isCloaked = True 
				If ship.CanCloak = True 
					If ship.start_deCloak = False
						dSFX.Create(deCloakFx, deCloakShip, 2000)
						ship.start_DECLOAK = True
						ship.start_cloak = False 
					End If
				End If
			End If 
	 	End If 
		
	
		'if cloak is engaged by player, start the cloak process, and checks whether a decloak
		'process has been started by the player, if so, it won't start to cloak, until
		'that decloak process is finished.
		If ship.start_cloak = True And ship.start_decloak = False
			cloak.start()
		End If 
		
		'same as above, basic error checking, input handingling so that you can't push C, 
		'And shift C, To cloak decloak until one process has finished first.
		If ship.start_decloak = True And ship.start_cloak = False
			cloak.uncloak()
		End If 
	
		
		
	End Method

	'sets flags, the ship is now cloaked
	Function CloakShip()
		ship.isCloaked = True
	End Function
			
	Function deCloakShip()
		ship.isCloaked = False
	End Function
	
	
	
End Type
'-----------------------
'END OF CLOAK TYPE
'-----------------------



Cruis.In(Posted 2006) [#7]
also i realise now they didnt have to be methods, could have been functions, i dont think back then i knew that you could use Tcloak.Functioncall

so thats why i made them methods, then instance an object of Tcloak called cloak. Then put cloak.cloaking in my loop.

the method cloaking() controlled everything. The input from the player and then the call to the start() and uncloak() methods.

the cloakship() and decloakship() functions there are called in the methods start() and uncloak().

this here dSFX.Create(CloakFx, CloakShip, 2000)
that dsfx is delayed sound effects. so that cloakship() function is only called AFTER the sound effect is finished and completes the function of cloakship() which is to change the field "isCloaked" in tplayership to "True", so to finally set the state of being invisible/cloaked as true. Which helps with if the player presses c, shfit c multiple times, so one process doesnt start until a process is complete.

also guess i could take out the shift c now it aint neccessary and put keyhit key C for both, because they'll do different things because of the other conditions supplied. :)

its a cool effect. the AI ships slowly fades to invisible and slowly returns to visible. But the player only goes down to 0.3. You have to still see yourself after all!

want to see it in action? i can send my alpha :)


H&K(Posted 2006) [#8]
What I was tripping over, was how to say that you couldnt make a type for Invisability, because its not a noun. But I knew that you had made a type, so thought it simpler to just ask for it, then I would know what you ment. You have made a type for a Cloak, which is damb obvious now that I see it.

I take it this is one of the components in your component list for the ship? I had thought that these were all going to extend from Type Component? So as to be easyer stored in a tlist or array.


Cruis.In(Posted 2006) [#9]
which is damb obvious now that I see it.


is that you being angry?

by invisbility did you think i meant *invincible* which is God Mode type of thing? Cant be killed?

hmm you mean store all the parts of my ship is a list?

actually i havent made this an actual system that takes damage. I wrote some intuitive damage handling and repairs and stuff, i mentioned it in another thread, i am rather proud of it :)

but i should make this a system, so if its destroyed you cant cloak :)

by component list, you mean an "abstract" list right.
so far i only have engines,shields,weapons,radar, as actual components which can take damage and be repaired.

right now my basic GUI, courtesy highgui3 library, displays these systems taking damage, repairing and has buttons to focus repair efforts on a system. making system chosen repair faster.

also i forget there is powermanagement. so more engine power= more speed, better turning, more shield power = you know what

and when you take damage performance of the ship suffers, engine damage = top speed being reduced etc...


H&K(Posted 2006) [#10]
It was me being angry at myself for not realising what you ment.

No, I knew you ment invisability, I just didnt think on and Realise that you ment A device to give invisability.

hmm you mean store all the parts of my ship is a list

Yep, I thought you had desided that your ship type would be made of a Hull Type, and A Tlist (or Array) of compounents. (TCompounent).

Type TShip
Hull:Thull
CompounentList:Tlist

And then that each type of compounent would override the base turnon/turnoff/detroyed methods of the base type.


Cruis.In(Posted 2006) [#11]
ok my entire post just got deleted. oh my god how terrible I was right at the end.

Ill speak from the last thing I said and move back up...

relative to component objects. Currently the way I handle them is entirely abstract, without the creation of objects. So there is an engine_health variable, and max speed is calculated based on its health, so if it is damaged less than full health, the max speed is slower. Is it best to make each component an object, so then that if it is destroyed it can truly be destroyed, deleted, because you shouldn't be able to repair a destroyed system.

Or I could add if enginehealth < 0 then destroyed = true

and in my repair function I could put up front,
if destroyed = false, so that no repair code will execute once destroyed is true.

currently turning on/off systems is done with a button press, and booleans... so say

if keyhit key W
weapon systems = true
end if

and in firing weapons a check is first made,
if weapon systems = true

otherwise if false, nothing happens.

currently the code is separated by types.bmx
functions.bmx and etc... globals

i have my repair() as a standalone function, but ive been wondering if it isnt better for the future to put everything the ship Type can do to itself, inside the ship type as a method. Especially for AI programming.
because otherwise, repair() can only modify the fields of one object, because you have to refer to that object because its a function not a method...

ship.engine_health REPAIR IT
ship.system REPAIR it

so only the object SHIP would be getting repaired no matter who is damaged :)

finding lots of errors in the logic here.. :)


Grey Alien(Posted 2006) [#12]
ok my entire post just got deleted. oh my god how terrible I was right at the end.
I hate it when you acidentally erase your post before pressing Post, so for long ones I write them in notepad and then paste them in.