Best way to "move my character"
Blitz3D Forums/Blitz3D Beginners Area/Best way to "move my character"
| ||
Hey guys I was just wondering what the best\most effective way to move my animated object throughout my level. I have been studying the blitz example and it uses nodes, that were part of an array, but is there a more effective way of doing so without a huge array?? |
| ||
Could you use banks.. They are faster than arrays! |
| ||
Do you have an example of how to use banks?? |
| ||
Linked lists would probably make more sense. Umm.. banks are faster than arrays? I highly doubt that. Regardless, you should probably be more concerned with clean code and expandability than microoptimizations. |
| ||
Could you show me how to use lists, and link them in such a way that I could use them to move my character? |
| ||
Types ARE linked lists. Just use First, Before, After, and Last. |
| ||
Hey Wolron, I haven't really heard of First,Before,After, and last. I am very farmiliar with types though. Soo, could you kinda demonstrate what you mean buddy?? |
| ||
Type variable Parameters variable = any legal variable name Description If you know C prgramming, a TYPE is basically a STRUCT in Blitz Basic . . . See also: Field, End Type, New, Before, After, First, Last, Each, Insert, Delete. Example code usage: ; Define a crafts Type Type crafts Field x Field y Field dead Field graphic End Type ; Create 100 crafts, with the unique name of alien For t = 1 To 100 alien.crafts = New crafts alien\x = Rnd(0,640) alien\y = Rnd(0,480) alien\dead = 0 alien\graphic = 1 Next ; Move to the first object alien.crafts = First crafts Print alien\x Print alien\y Print alien\dead Print alien\graphic ; move to the next alien object alien = After alien Print alien\x Print alien\y Print alien\dead Print alien\graphic ; move to the last alien object alien.crafts = Last crafts Print alien\x Print alien\y Print alien\dead Print alien\graphic ; move to the second to the last alien object alien = Before alien Print alien\x Print alien\y Print alien\dead Print alien\graphic So, in your case: Graphics3D 800, 600 Type Node Field entity Field x#, y#, z# End Type For iter = 1 To 10 thisNode.Node = New Node thisNode\entity = CreateCube() ;CreatePivot() ;normally just an invisible pivot thisNode\x# = Rnd(-100, 100) thisNode\y# = 0 thisNode\z# = Rnd(-100, 100) PositionEntity thisNode\entity, thisNode\x#, thisNode\y#, thisNode\z# EntityColor thisNode\entity, iter * 20, 150, 150 ;note: can't be used with pivots Next myGuy = CreateCamera() grid_tex=CreateTexture( 32,32,8 ) ScaleTexture grid_tex,10,10 SetBuffer TextureBuffer( grid_tex ) Color 0,0,64:Rect 0,0,32,32 Color 0,0,255:Rect 0,0,32,32,False SetBuffer BackBuffer() grid_plane=CreatePlane() EntityTexture grid_plane,grid_tex MoveEntity grid_plane, 0, -1, 0 thisNode = First Node While Not KeyHit(1) If EntityDistance(myGuy, thisNode\entity) < 10 turnrate = 5 Else turnrate = 20 EndIf TurnEntity myGuy, 0, DeltaYaw(myGuy, thisNode\entity)/turnrate, 0 MoveEntity myGuy, 0, 0, .5 If EntityDistance(myGuy, thisNode\entity) < 2 If thisNode = Last Node Then thisNode = First Node thisNode = After thisNode EndIf RenderWorld() Flip Wend End |
| ||
Types ARE linked lists. Just use First, Before, After, and Last. Subtly incorrect. Blitz automatically creates a single, partially-accessible linked list for each defined type. If you implement your own linked lists, you can have the benefits of customizable linked lists, such as multiple lists per type and objects belonging to multiple lists. thisNode = First Node See? Only one list per type. If you want your animated objects to follow more than one path, you'll need a different solution. The conventional approach to "custom" linked lists is to add next (and usually prev) pointer fields to your type so that you can chain objects into lists, setting the pointers at ends of lists to NULL. You need only store a pointer to the first object to be able to access all the elements in its associated list. Type node Field x#, y#, z# Field nextNode.node End Type Function new_node.node(prevNode.node, x#, y#, z#) n.node = New node n\x = x : n\y = y : n\z = z If prevNode <> Null Then prevNode\nextNode = n ; update the node before us Return n End Function a1.node = new_node(Null, 1, 1, 1) ; new list a2.node = new_node(a1, 2, 2, 2) ; chain a1 to this node a3.node = new_node(a2, 2, 3, 3) ; ... b1.node = new_node(Null, 3, 2, 3) ; new list b2.node = new_node(b1, 2, 1, 2) ; chain b1 to this node b3.node = new_node(b2, 0, 0, 1) ; ... a.node = a1 b.node = b1 display_node_list(b) Function display_node_list(firstNode.node) currentNode.node = firstNode While currentNode <> Null Print currentNode\x + ", " + currentNode\y + ", " + currentNode\z currentNode = currentNode\nextNode ; advance to the next node Wend End Function You'll need a function to remove a node without breaking the list. You may end up adding functions to rearrange elements, treat your list as a queue or a stack, and other fun things. Although this is a fantastic solution, some of us are prone to over-engingeering. The next step is to separate the linked list logic from your type so you can reuse it with other types. Since there's no polymorphism in Blitz Basic, you'll need to copy your linked list functions anytime you need lists of a new type. I got tired of this and devised a different solution. |
| ||
OHHHH...my head is going 2 explode!!, well...maybe not, but this topic is really bewildering me, soo can you break the explanation of how to use linked lists for a beginner programmer?? |
| ||
A beginner programmer shan't be using linked lists. Stick to arrays until you get up to learning how to use Type. |
| ||
I think there's also a linked list approach using Banks. Since a Bank is a bit o' memory reserved of such-and-such size, you could create a linked lists with Banks. It probably would also need a function or two to manage, but I believe it could be done. (Whether it's a BETTER way of doing, I haven't checked). Start with a new Bank, specifying sufficient memory for the info you need to store in the Bank, and 4 additional bytes (ie an integer) at the end. The last 4 bytes are essentially reserved for storing the handle of the next Bank. Initially, the last 4 bytes will be Null (zero). Then, when you need to add another node in the list, you create a new Bank, and put its handle in that last reserved 4 bytes of the first Bank. Then, when it's time to go through the list, after getting the initial info from the first Bank, you check the last 4 bytes. If they are other than zero, then those bytes (the second/following Bank's handle) are used to access the info in the following Bank you created. This can be added to indefinitely, as long as you have enough memory. When you run through the list, if a node is no longer needed, you grab the last 4 bytes of that node's following Bank, and copy them to the last 4 bytes of the previous node, effectively "skipping over" the no-longer-needed node. The Bank thus no longer needed, can be Free'd. Because the handle of the folowing Bank was copied to the previous Bank, the list is maintained. You can always add to the node by adding more Banks. As an additional sophitication, you could also allocate an initial 4 bytes, to be used to store the Handle of a previous Bank (zero, of course, for the first node). With the handle of the previous Bank in the first 4 bytes of a given Bank, and the handle of a following Bank node (if any) in the last 4 bytes, you can navigate forward and backward through the node list as you please, deleting defunct nodes or inserting new ones. This is what can be done with Banks. To those who use Types, this procedure using Banks is parallel to what the family of "Type" commands do for you, in taking care of some of the adding/deleting/navigating functions for you, so you don't have to keep track of them. I think Types are perhaps more versatile than the Banks approach, in that you can have fields that can be any kind of variable, ie floating point, integer, strings, simple arrays, other Types, etc., whereas the Banks are pretty much integer-based (unless you get into using Chr$() functions, which, while possible, would probably be pretty hairy to implement). But, I just wanted to point out that linked lists CAN be done without using Types. |
| ||
Now my head's going to explode. Why on earth would someone want to reinvent Types with Banks? can you break the explanation of how to use linked lists for a beginner programmer? A (type) object is a collection of variables in memory. A pointer is a variable which describes another position in memory - that is, the location of another variable or object. In a linked list, one of the variables in your object acts as a pointer to another object - specifically the next object in the list. Type node Field nextNode.node End Type a1.node = New node a2.node = New node a3.node = New node ; chain them together a1\nextNode = a2 a2\nextNode = a3 ; now we only need to know about the first node to find the rest first_node.node = a1 second_node.node = a1\nextNode third_node.node = a1\nextNode\nextNode I hope this example is simple enough to showcase the general principle. When you understand it, look up at my previous example. If you still don't understand, let me know what it is you're having trouble with and I'll do my best to explain it. For reference, here are some explanitory articles on linked lists: http://en.wikipedia.org/wiki/Linked_list http://www.codeproject.com/cpp/linkedlist.asp |
| ||
Didn't say anyone would *want* to reinvent Types with Banks, just saying it's technically possible (and, with more overhead, to boot) Might be interesting to tackle the problem, just to see how practical it might be (or not be, as the case may turn out). |