Types, room.chair
Blitz3D Forums/Blitz3D Beginners Area/Types, room.chair
| ||
Right, I have been programmign in Blitz3D for years now, and use types quite often. I understand how to use them, but always had a question, and maybe I am missing something. In example used in the doc's is: room.chair = New chair What is the first 'chair' for? Why didn't mark make blitz do: room = New chair being, make a new type of chair in the room list. |
| ||
yeah, I don't get that either lol |
| ||
Because that would declaring "room" as an interger varible and then assigning the "new chair" handle to it.... which would be a MAV.. I think ;) |
| ||
So I guess: room$ is a variable that uses the format of a string room.chair is a variable that uses the format of a 'chair'? the '.chair' replacing the '$' |
| ||
the '.chair' replacing the '$' That's it exactly. There are three built-in variable types ( integer, float, string ) and user defined ones, such as chair. A variable's type is determined when it is explicitly declared, with Global or Local, or whenever the compiler first sees the variable in your code. So if the variable room, of type chair, has been declared or already appeared earlier in the code you can simply say room = New chair And as long as I'm in lecture mode, the return type of a function is determined in the same way: Function f#( ) ; will return a float Function g.chair( ) ; will return a chair, whatever that is. |
| ||
Ah, so I an do it the way I want by first declaring the room as a variable type 'chair'Type chair Field Name$ Field Height End Type Global room.chair room = New chair room\Name = "Nice Chair" room = New chair room\Name = "Bad Chair" For room = Each chair Print room\Name Next WaitKey() I guess its abit easyer for readbility to keep the .chair in there all the time, so you can remember its a type. So if I use a function and return whole type entry, how do I then access the fields in that returned entry? |
| ||
I guess its abit easyer for readbility to keep the .chair in there all the time, so you can remember its a type Only because for some unknown reason youve called a Chair "Room". If you had called it "GlobalChair" or "AChair" or "MyChair" or "LocalChair" or heaven forbid "Chair" it would be a lot better.Calling it something not Chair related is bad enough, but to call it something that might contain Chairs is stupid |
| ||
Its called 'room' becuase thats the example given in the official docs and I didn't want to add to the confusion. Which also makes sence, as its keeping a collection of 'chairs' in a list called 'room' |
| ||
So if I use a function and return whole type entry, how do I then access the fields in that returned entry? Type chair Field Name$ Field Height End Type Global room.chair ; Create a new chair type-instance, set it's name and return it to the variable "room" room = CreateChair("Nice chair") room = CreateChair("Bad chair") For room = Each chair Print room\Name Next WaitKey() Function CreateChair.chair(Name$) Local a.chair = New chair a\Name=Name$ Return a End Function Here the creation of a chair type-instance and settings it's name is done within the function CreateChair, which returns the chair as a type-instance and gives it to the variable "room". Afterwards, you can access the room's fields the same way as if you had created the type-instance in the main code. |
| ||
Excellent. Is there anything else about types I should know? As I said I have used them for years, but nothing more as a simple in/out database. |
| ||
Excellent. Is there anything else about types I should know? Depends. I don't know what else you already know about them.Er, you can have types within types - that can be pretty useful. |
| ||
its keeping a collection of 'chairs' in a list called 'room' Hence Chairs[] should be a field of Room, and not that a chair should be called Room Its called 'room' becuase thats the example given in the official docs Then it is one of the things that was possible adding to your confusion about types. It a really really stupid way to name an instance of "Chair", because as you have just shown it confusing the issue between "Is A", and "Contains A".ARoom may Conatian A Chair, and as such any Type TRoom can have fields of lists of Chairs or Arrays of chairs, or pointers to Banks of chair, in short in may conatin Chairs. A Chair on the other hand Is Not A room, it is in no way similar to a room (Cept they both might have fleas in them), and shouldnt be called A room at all |
| ||
So how do you use types in types, and what use / benifit do they have? |
| ||
Its a bit like Inheritance. Imagine you have a type called SpaceShip. Type Spaceship field name$ field topspeed% end type All Spaceships will have these attributes but might also have some other specific to themself. For instance, your CargoShip might have a 'Cargo_hold' attribute when your Fighter might not. You *could* give the Fighter a Cargo_hold value of 0. Alternatively you can create a Type CargoShip field basic_cargo.ships field cargo_hold end type type fighter field basic_fighter.ships field missiles% end type. Your Fighter and your CargoShips now only have the ir specific attributes PLUS the basic attributes. This is a small example but imagine if EVERY ship had to have a field for EVERY possible attribute. In additiom, changing the base structure automatically gets updated to each ship type. |
| ||
how would I put data and get data back from the fighters name$ for example? Would there be any additional things in code, or would it just count it as another field? |
| ||
You use myfighter.basic_fighter.name. |
| ||
That would be myfighter\basic_fighter\name in blitz3D. ;) |
| ||
Ooops. You're right. It's been too long. |
| ||
I have used inheritance alot in my current project and I couldn't emphisize how important types in types are. Especially when the game is very dynamic. Here's one example of my type structurePlayer Ship | | PlayersShip Weapon | | \ / WeaponMount | WeaponBullet For example the WeaponBullet object has a field Parent.WeaponMount, WeaponMount has a field Parent.Weapon and Owner.PlayersShip, PlayerShip has fields Parent.Ship and Owner.Player . So when going through the bullets, to find out which Player shot this bullet, I code Shooter.Player=This\Parent\Owner\Owner . Why have PlayerShip and Ship as different types? Say the Ship type has attributes maxShields, mass, maxSpeed etc. Those fields are static information that does not change for this ship type. So the PlayerShip type has fields ShieldCharge etc. which is dynamic information. Always separate static and dynamic information to types of their own. You save memory and have some strictness in your code. But what about going downwards in the hierarchy? There are two options. Let's think the PlayerShip can have several WeaponMounts. This can be done by having a field in PlayerShip WeaponMounts.WeaponMount[7] Which is a collection of pointers to WeaponMounts this PlayerShip has. This of course restricts the amount of weapons to eight. What about limitless amount? Object chain! Type PlayerShip Field Parent.Ship Field Owner.Player Field PosX# Field PosY# Field WeaponMounts.WPChain End Type Type WeaponMount Field Parent.Weapon Field Owner.PlayerShip Field FireCoolOff% End Type Type WPChain Field Obj.WeaponMount Field NextWP.WPChain EndType P1.PlayerShip = New PlayerShip W1.WeaponMount = New WeaponMount W1C.WPChain = New WPChain W1C\Obj = W1 P1\WeaponMounts = W1C W2.WeaponMount = New WeaponMount W2C.WPChain = New WPChain W2C\Obj = W2 W1C\NextWP = W2C Now going through the weapons of certain PlayerShip is easy. Local WPC.WPChain = P1\WeaponMounts While WPC<>null ; do what you want with WPC\Obj WPC = WPC\NextWP Wend I could go on and on about this. |
| ||
i still dont understand how to use types inside of types. ahhh headache! |
| ||
Hey, say I have 3 space ships, and each ship has 5 guns (gun information is stored as a child type of the main parent space ship type). How do I retrieve gun information only for the second space ship? When I using something like: for P1.PlayerShip = Each PlayerShip Select P1\ShipNumber Case 2 for P1\WeaponMounts.WeaponMount = Each WeaponMount *PLAYER 2'S GUNS ONLY* Next End Select Next But it brings back info for all the weaponmount child types not just ones on P1. I see in Jasu's example he doesn't use the for/next loop, but instead stores the next weapon in the sequence and loop through 'manually'. But wouldn't that break if I deleted one of the middle ones and break the chain? Whats the best way to do this? |
| ||
You're confusing the issue talking about 'just ones on P1'. P1 is the loop variable so takes on the value of all ships over the loops. The reason you are getting all weapon mounts is that you are using each, which means 'loop through every weapon mount type'. So youre logic is saying 'find ship 2, then loop through every weapon mount, regardless of who it belongs to'. The trouble is B3D has only 1 list for each type.. ideally you would like a separate list of weaponmounts belonging to each ship, right? There are a few ways round this. 1)Each weapon mount has a field identifying the ship it belongs to. 2)Create separate weapon mount types, WeaponMounbt1, WeaponMount2 etc, one for each ship, thereby giving you more than 1 list. 3)Create arrays of weapon mounts for each ship, which store only the weapon mounts on that ship. 4)Implement your own lists enabling you to have 1 per ship. The inherent '1 list per type' in B3D makes basic stuff simpler, but you're hitting the limitations of the language. |
| ||
ah, I guess this is the reasoning behind BlitzMax's decision not to automatically put things in lists? So you can have multiple user defined lists. I think I will go with Fix number 1 please :) |
| ||
I guess this is the reasoning behind BlitzMax's decision not to automatically put things in lists? I guess you're correct. I was tempted to put '5)Get BlitzMax' in my previous post, but I didn't want to go off topic! |
| ||
:) |
| ||
So if you can't retrieve a type inside a type, whats the point in using types within types? You might as well just keep them seperate and link them together with a pointer field? Edit: *Click* that magical thing just happened when I finally realised the answer....there is no spoon! :) |
| ||
It that playership example Jasu posted really the only way to retrieve types in a type? It essentially involved each weapon manually linking to the next one, if the chain is broken, such as a weapon is removed, then all the links in all the weapons need updating in the chain (which might be hard to find as there no longer linked) It just seems there should be an easyer way? |
| ||
There are simpler, less dynamic ways like using a type array within a type. For example .. const MaxWeapons = 5 type Weapon field Blah field Blah2 end type Type Ship field Mesh field Blah field Weapon.Weapon[ MaxWeapons-1 ] End type It really depends on how complex you need your ship / weapon type structures to be. How does your game work in terms of the weapons? Is there a finite number of weapon slots? When and how do they get removed? When removed do you default to the next avalable weapon? Do you always have at least one weapon? Etc .. |
| ||
Remember OBJECT and HANDLE commands. |
| ||
Yes, use blitz arrays within a type if the amount of child types is finite. For 'infinite' type lists, the pointer chain is the only way to go. I hope you didn't misunderstand what I mean about these pointer chains. If you, say, remove a weapon object, it doesn't break the chain. It's just that one of the objects in the weapons chain is pointing at null. The weapons and the list of weapons are completely different types. Deleting objects from the pointer chain is a bit difficult (link of the last object has to be changed before deleting). As I was implementing this into my game, I noticed that simply deleting the whole list and recreating it from scratch was faster than modifying it. It of course depends hugely on what are you using it for. |