I don't think Var was a good idea.

BlitzMax Forums/BlitzMax Programming/I don't think Var was a good idea.

sswift(Posted 2006) [#1]
I don't think having functions in Max return multiple values was such a great idea. Var may have it's uses, but for retrutning multiple values, it seems like a dud, unless used very sparingly in very special cases.


Take this command for example:

Function GetHandle( x# Var,y# Var )


Now, I've just realised this returns the current drawing handle, not the handle for an image, like I was used to in BlitzPlus, but let's pretend it takes an image parameter for the sake of argument, and returns the handle of that image. Otherwise I'll have to rewrite my examples so they make sense. :-)


I want to have a set of methods in my sprites which returns the X1, Y1, X2 and Y2 for a sprite.


Ideally the code would be like this:

Method #X1()
Return X# - GetHandleX#(Image)
End Method


But because there is no GetHandleX# function, the code would be more like this:

Method #X1()
Local Temp#
Gethandle(Image, Temp#)
Return X# - Temp#
End Method


Now, if I were to actually take this to it's logical conclusion and be CONSISTENT with how Max works, then instead of having that method at all, instead I'd have somehting like:

Method GetCorners(X1# Var, Y1# Var, X2# Var, Y2# Var)
End Method


But how useful is that?

If I have the funciton return a single value, then I can do stuff like this:

If EntityX#()-EntityWidth#() < 0 Then Print "Offscreen!"

But if getting the position of an object or the width of an object requires me to call a function with two temporary variables which I then compare after, then I have to create an extra variable I may not need to hold the second value (or the first) and now I need like three lines of code to do what I could have done in one line of code before, in a manner which was much CLEARER before.

And the same would go for anyone trying to use my function there to get the position of the corners.


It just seems uneccessary, and more complicated than it needs to be. And for what? Where's the upside of doing it this way? That there's fewer functions to worry about?

That's just not worth it.


N(Posted 2006) [#2]
The way Max2D is written really doesn't utilize Var correctly. There should be getter and setter functions for the X/Y individually and the SetHandle/GetHandle should call them. But, instead, they decided to limit it.

My advice is to not use Max2D. It's poorly written and has a hideous tendency to smack you about with a jar of turtle balls.

Edit: My point is that Var isn't the thing you should pick on. It's Max2D's use of it.


Scott Shaver(Posted 2006) [#3]
The up side is that you get to choose if the value of a passed argument can be changed by the method/function.


Dreamora(Posted 2006) [#4]
Im sorry but the way BM does it with its var is actually the correct way in modern OO design.

The most modern languages already reflect this actual OO design rules (no C++ does not but it is not modern after all). There are "ref" / "out" in C# for example, others do have similar things. (pointers are not on this level, they are not typesafe and only because of that already outdated)

It has some good points:
1. The object given to var is already known and thus will be known after the function as well (consistency, you will learn the benefits of it when you try to find out why something does not do what you meant it to do)

2. You can have more than 1 return from a query actually. (returning arrays is still the most commonly used workaround which is just waste of memory and performance if you can use VAR)

There is nothing worse than 10 functions to return stuff you could have gotten with references with 1 single call.


get / set is a nice abstraction layer, but I don't think it is on the same level as VAR or similar mechanisms. It is nice for a modification of a single value ...


General:

The worst thing are people mixing all the stuff: giving data to an object, then modify the object itself, modifying a VAR object and then even returning something. This totally breaks any design rules and although it sounds harsh: this is plain stupid. Anyone doing that shouldn't call himself OO programmer, not even OO noob.

There are 3 types of "functions" you actually have:

Function: Takes parameters and changes one or more elements of the object it is called on. Does not return anything.

Procedure: Takes parameters. Calculates an output using this parameters and its own data. Does not modify object.

Query: Does not take parameters. Simply returns a variables value. Does not modify the object.

The later two can be seen as one if you take 0 parameters as a valid amount.


If these distiction is followed, many problems never arise or can be tracked down far faster because you know what and what can't cause a problem. First thought of it as crap and more work as well ... but after your software system has gotten some size and rotates around 50-200 classes you will start understanding why it is actually of use and will see its true power.

There should never be a function / method, that changes the object and calculates an output at the same time!


N(Posted 2006) [#5]
What if it calculates an output to tell you in what way the object was changed?


sswift(Posted 2006) [#6]
"There should never be a function / method, that changes the object and calculates an output at the same time!"


So I guess making a function WriteFile() which writes to a file object, and returns whether the operation was successful or not, is a no no?


N(Posted 2006) [#7]
I don't like standards preachers.


sswift(Posted 2006) [#8]
I dont like having to write 10 lines of code to do what one line of code could do, simply because if I write 10 lines of code, it's less likely that I will make a mistake.

I don't have a lot of bugs in my code.

I coded a whole game for lego. Near the end it was a pain in the ass figuring out where to add stuff, but that is because I didn't have time to go back and correct portions which I had not been able to plan out ahead of time, and so had chosen poor methods.

For example, I thought since C programmers often use a resource editor, and reference the objects in their game by the position in the resource file, that storing all my graphics in one big array and referencing it by number, instead of using seperate variables for different things, was a good idea. It turned out to be a nightmare, because as I added and deleted things, holes appeared in the array, and I had to move stuff around because I had all my menu items in one place in the array and I hadn't left enough room for all of them. Total nightmare.

But besides that, procedural programming, with only a few object oriented bits here and there where they make sense, has worked great. When I look at the source to Max's functions... all the types, and methods... It's all confusing as hell to read.

Even as I try to create a sprite type, with some methods for acessing the sprites, I'm sitting here wondering why I am doing this? Is ThisSprite = Sprite.Create() really that much better than ThisSprite = CreateSprite()?

Well, in the IDE, there is a code tab, and I can click the + to open up the sprite type and see all the functions associated with sprites that way. But then I notice a horrible flaw. While it shows all the functions and methods, it doesn't show any of the fields which can be accessed, so that only tells me half of what I can do with a sprite object.

And if it did not do that, then there would be all these _Variable names in there which are intended to be hidden from the user. And if the user goes to look at the type, there's all these functions and methods in there messing things up, and you have to scroll through them all and hope no field has been hidden in the middle that you might miss.

Wheras with the procedural method, the type is really neat. It's only got the variable names. And why wouldn't it? When I say New Type, I'm asking for a bunch of memory in the format I have specfied there. As far as I know, there's no functions included in that. The idea of having the functions inside the type declaration is hiding the true nature of the data structure.

It's just a mess. It makes things confusing. If OOP is so great and is supposed to prevent problems, then why is Windows a buggy mess?

Simpler code is better. There's less to remember. Less to rememebr means you can keep more of the important code in your head and keep track of how it interacts with other portions.

I also get the impression that OOP discourages commenting, cause none of Mark's code is commented. :-)


Azathoth(Posted 2006) [#9]
uh? C++ has references.

Anyway if you don't like using var, you can just return an array but it has to be all of the same type.


Dreamora(Posted 2006) [#10]
The why is windows a mess:
Its codebase is from Win95, was extended from 10 million codelines to far more than any other existing software system actually has.
Tousands of different people worked with it, many things have changed since then. Check the API, its a good sign of how old the core actually is ... No modern API would follow a that non-oo approach.

Software Design has evolved within the last 10-15 years more than any other science did the last 30+ years (beside a few exceptions) ... its like back when electricity "was invented".

Why do you think did MS originally plan to base Vista on .NET which is a secure core for modern software design? That idea was not just a funny idea of someone in a dark little room ;-)

Or why do you think there is Managed DirectX with a far cleaner OO design than the regular DirectX which is a mess as well? :-)


Its just that the programers are normally a lazy bunch ... they avoid to rewrite stuff from scratch if they have some old code that does the same ...
Thats why it takes forever.
At the moment we are even paying the price for those lazy peeps because they were even to lazy to get some hands on parallel computing paradigms and now most apps simply suck extremely with dual core (some even crash or break totally)


FlameDuck(Posted 2006) [#11]
If OOP is so great and is supposed to prevent problems, then why is Windows a buggy mess?
Because it's not OO.

Its codebase is from Win95, was extended from 10 million codelines to far more than any other existing software system actually has.
No it wasn't. It was 'extended' from WindowsNT.

Simpler code is better. There's less to remember.
You're right. And OO code is simpler. It's easier to read, understand and maintain (which would probably have been nice in your LEGO game).

I also get the impression that OOP discourages commenting, cause none of Mark's code is commented. :-)
Well that's odd since Marks code is distinctively not OO. There are some OO concepts, but large portions of the code is strictly procedural.


Jay Kyburz(Posted 2006) [#12]
I agree with sswift that OO can be allot more difficult to read and navigate and i am moving more and more toward simple code these days.

I like objects as a way of grouping logical blocks of code. I like the idea of an objects methods operating on itself. I steer away from unnecessary inheritance as i find it obfuscates things.

Oh and regarding the original topic.. i'm not sure if i understand what the issue is but Var is not needed to "return multiple values". All objects are passed by reference by default, if you wrap x and y in a type and pass them in you don't need the var keyword. Would be the same for you x1,y1,x2,y2 example.

I read your post a few times but i don't really understand what it is you are saying you don't like. I'm new to programming stuff.


Type tSize
	Field x:Int
	Field y:Int
End Type

Function ModifyObject (size:tsize)
	size.x = 10
	size.y = 20
End Function

Local big:tSize = New tSize

big.x = 100
big.y = 100

Print big.x+":"+big.y 

ModifyObject (big)

Print big.x+":"+big.y




sswift(Posted 2006) [#13]
Jay:
Yes, you can pass a type like that and modify it, but then you have to create a type to get those values back, and that can be inconvenient. If you're working with X and Y in your function and you want another function to alter them, creating a type just so you can pass them to a function is inconvenient.

What I am complaining about is how Var is mainly how it used by Mark in Max, and may be used by others.

Take for example GetViewPort. If I want to use that in my sprite system to determine that a sprite is outside of the viewport, I have to do the following:

Local X1, Y1, X2, Y2
GetViewPort(X1, Y1, X2, Y2)
If Sprite.X2 < X1 then Sprite is outside viewport

Whereas if there were a viewport function for each value I needed returned I could just do this:
If Sprite.X2 < GetViewPort_X1() then Sprite is outside viewport

Now, there's only a couple extra lines in this example, but that adds up, and requires me to make all these extra useless variables I don't need in each function just to get these values back so that I can perform a simple operation on them.

It just makes things messier, and there is no benefit other than having fewer functions, except possibly in some extreme cases.


Dreamora(Posted 2006) [#14]
I'm sorry sswift, but your latest post don't make much sense.
It seems like you simply need a little more experience with the possibilities of BM and how you can use them the best way. BM is not C++, is not JAVA nor is it a bloody procedural language like the old Blitz.

It has evolved quite some steps and it takes quite some time until one is used to the way BM works and handles stuff. (especially experienced B3D or C++ programmers will have a hard time as it works very different to both)

You bring up a thread or so per day with something where new users where bashed months ago for them, because its stuff that might have been this way in B3D or other languages, but all of them are simply not BM ...


Warren(Posted 2006) [#15]
If OOP is so great and is supposed to prevent problems, then why is Windows a buggy mess?

Windows is a mess? For a code base the size that it is, I'd say it's remarkably (if not astoundingly) stable.


sswift(Posted 2006) [#16]
"You bring up a thread or so per day with something where new users where bashed months ago for them"

Well you can thank the people managing the forums for deciding it was okay to purge all the old posts for me not being able to go back and read what people said about this stuff when Blitzmax first came out.

Also, I don't see how my latest post doesn't make sense. One example has three lines, and four variable the other has one line and no variables. What's not clear about that?


Koriolis(Posted 2006) [#17]
Not really interested in the "debate", but just spotted this
If OOP is so great and is supposed to prevent problems, then why is Windows a buggy mess
Since when is Windows OO based? There are high layers that range from *slightly* OO to really OO, but in the system in itself, I don't think you'll find much OO.

Overall I think you are simply overreacting to your frustration regarding your first steps in OO. Heck, you started a few days ago and you expect to have a really advised viex on it?
Also, you should stop thinking all the "new" features are OO. As a quick list that is often confused to be OO
- "Var" is not OO
- overloading is not *really* OO (though it's come kind of polymorphism, compile-time polymorphism)
- exceptions are not OO
If you want to bash something, be precise about what you're bashing.
And even when a language feature really is OO related and it smells like sh###, maybe it's just the implementation that sucks :) It's not like consistent language design was that easy.

This is really a recurring pattern, that's not even funny. You start learning OO features, and most of them don't even seem to make your life easier and feel like clutter. You yell and shout "WTF". Then some day it start to make sense, and you even realize some people were just being OO zealots. But by that time you've realized OO is indeed a usefull tool and way of thinking. I wish you to come to that point soon.


CS_TBL(Posted 2006) [#18]
This forum needs a knowledge-database based on all the questions that come around.

Questions like:
- how do I make a platformgame
- how do I load a map
- how do I shoot bullets from a sprite
- how do events work
- how do eventhooks work
- what's the diff between functions and methods
etc.

Some are in the manual, but if the manual was a real succes, ppl wouldn't have to ask here, so a generic knowledge database seems to be a must.
And it's not the tutorialsection, not the code-archive, not Wiki.. it should be something new, and it should be large, largeness, it should large! And it should be on this site, since ppl use this site probably as first and only reference..
Browsing older posts for possible answers on obvious questions is also annoying since not all titles are descriptive or even have sense-making answers on questions. Sorry to say so, but quite some ppl on the forum lack experience on certain matters. By far the biggest cultureclash comes from polling/game-people who try to give advice to event-people who ask for an event-solution. "oh well, let's create another Global variable here and there, and we can solve it.."

(sorry if some ppl feel offended, no intentions to shoot them :P)


Dreamora(Posted 2006) [#19]
Agreed!

Yes something like the TDN (torque dev network) would be great for Blitz and is definitely needed because of the ever growing size of the community. Mark wanted more users and made it crossplattform but somehow BRL forgot about a far better community based plattform than this board chaos.

A TDN like solution would also allow to manage all existing tutorials etc in a usefull way. At the moment the whole topic BM Tutorials / Manual is a large mess that often leads to google as there is no central place and thus to a lot time that is lost.

*yes I'm aware there is a tut section but this is a board, you can't create usefull tutorials in boards even if some do not agree. And linking to tuts is not a "central place" strategy*


CS_TBL(Posted 2006) [#20]
Also, a knowledge-database should be managed by either an admin/mod or a dedicated user. If everyone starts submitting a 'solution' you get something like the code-archives.. 50% useless nonmodular-code, 'my first experiment'-things etc.
Keyrule is that the solution is modular and as small as possible. There's no use showing how to create a complex algorithm if there's 1000 lines of overhead around it, and there's no use in using it when the whole thing isn't modular.. no-one's waiting on just another set of globals.
BMax-solutions, event-based, should work with eventhooks rather than using the global events..

Solutions should also come with a list of searchable keywords, so that 'window + maxgui' leads to another "solution" than 'window + iglass' or 'window + b3d'.


sswift(Posted 2006) [#21]
"Overall I think you are simply overreacting to your frustration regarding your first steps in OO. Heck, you started a few days ago and you expect to have a really advised viex on it?"


As I am coming at it from the point of how easy it is to grasp, I think I am in a very good position right now to make that determination actually.

When you have a lot of exposure to something, and know it well, working with it comes easy to you, and it might be very hard for you to then tell which parts of it might give trouble to newcomers.


Think of it like the Mac Interface vs the Windows Interface.

I could be an expert in the Windows Interface, and know it like the back of my hand, and know I can do anything I want to in it easily.

But that doesn't mean that the Windows Interface isn't poorly designed, or that it doesn't confuse the hell out of people who are trying to learn it because it does things in ways which are counterintuitive. For example, dragging a file to another location sometimes moves the file, and sometimes copies it.

As an experienced user, I know to look for the little plus sign to determine if the file is being moved or copied, so I might think there is no problem here. But in reality it is a bad design, because it is inconsistent, and goes against people's natural expectations.

As a new user, I can easily spot these inconsistencies and take notes about what I expected to happen, and what actually happened, and why I got confused. This can be used to improve it.

But if I had more experience with it, then I would unconciously do things the way the operating system expects them to be done and I would miss a lot of the things that would trip up people who are new to it and trying to do things the way one would naturally assume they should be done.


So that's why I have a problem with the lack of a delete command. When I allocate memory, I expect to have to free it when it needs to be freed. That is a natual expectation. BlitzMax goes against this natural expectation.

It is also inconsistent in that when I create a type, it frees it automatically. But when a user creates a sprite, it is not freed automatically, because the system will still have it in a list. They'll have to call a free function. That inconsistency is where my complaint lies.

If there were some kind of "free" method which got called when the user stoped referencing the sprite, that would allow me to make things more consistent. But that would also require the ability to have a sprite in a list, without that reference itself preventing the free method from being called.


"But by that time you've realized OO is indeed a usefull tool and way of thinking. I wish you to come to that point soon."

I'm not saying all OO stuff is bad. I consider the way I wrote many of my systems for Blitz to be OO. My gui system for example, refers to the gui things you create as "objects".

But I'm far from convinced for example, that methods are at all useful. One can make a function called CreateSprite just as easily as one can do Sprite.Create, only the former doesn't require me to make my type delclaration all messy with functions inside it, and it reads like a person would talk. People don't say "Pie make!" They say "Make pie!".

My view is programming should be as much like people speak as possible, within reason. A line of code should read like a sentance. Most of what I see in OO programming goes against that. Not all of it, but a lot.


CS_TBL(Posted 2006) [#22]
I really feel I programmed in exactly the same fashion in B+ than you do/did. Really, you'll get used to methods.

If you want CreateSprite instead of Sprite.create then simply make a wrapper. Best of both worlds..

Type Sprite
' fields 'n methods
End Type

Function CreateSprite:Sprite(args)
  local a:Sprite=new Sprite
  ' initialize vars
  Return a
End Function



taxlerendiosk(Posted 2006) [#23]
If there were some kind of "free" method which got called when the user stoped referencing the sprite, that would allow me to make things more consistent.


I may be misunderstanding you, but there is - Delete():
Type MyType
	Method Delete()
		Print "Goodbye!"
	End Method
End Type

Local mt:MyType = New MyType

mt = Null

GCCollect()

End



sswift(Posted 2006) [#24]
Denzil:
I thought something like that might exist, but as I mentioned, even if it did, there would still be a problem using Free in this case.


Global SpriteRenderList:TList = CreateList()
' If we're going to be consistent, why isn't this TList.Create()?

Type Sprite
	Function Create:Sprite()
		Local ThisSprite:Sprite = New Sprite
		ListAddLast SpriteRenderList, ThisSprite
	End Function
	
	Method Delete()
		ListRemove SpriteRenderList, Self
		Print "Goodbye!"
	End Method
End Type

Local mt:Sprite = Sprite.Create()

mt = Null

GCCollect()

End


Goodbye! is never printed, because the Delete method is never called, because the sprite still exists in the list.

So Delete() is not useful in this case, and the only way to fix this is to have a Free() method which does the removal of the sprite from the linked list.

But thanks for telling me about the Delete() method. I'm sure I'll find some use for it.


Koriolis(Posted 2006) [#25]
As I am coming at it from the point of how easy it is to grasp, I think I am in a very good position right now to make that determination actually.
Which determination? Of what makes sense? I don't think so. Of what is natural for someone with a strong procedural programming bias, sure.

As a new user, I can easily spot these inconsistencies and take notes about what I expected to happen, and what actually happened, and why I got confused. This can be used to improve it.
Sure. But I don't think that's necessarily a good argument anyway, because it works both ways. As a Windows user, when trying the Mac some things really didn't make sense to me. But after some time I have to admit the Mac interface really is better in lots of ways. Should I have just trust my "fresh eye" and just say the Mac interface is dumb? I don't think so.

So that's why I have a problem with the lack of a delete command. When I allocate memory, I expect to have to free it when it needs to be freed. That is a natual expectation. BlitzMax goes against this natural expectation.
What you request is a valid request, and is possible with weak references. It just happens that BlitzMa doesn't provide them. On the other hand, you have to wonder what you really mean by "when it needs to be freed". Really, what does it mean? If some code still holds a reference to some object, that should be because it's gonna use it again later. Using it if the objet is already deleted doesn't quite make sense.
(and again this issue has few to do with OO)

Also, you say "when I allocated memory". But you don't. You create objects. It will indeed require to allocate memory, and indeed it's what happens. But simply allocating memory is not a goal, you really don't care. Similarly, why would you care about freeing memory, really? The single and only benefit of freeing memory is due to the fact that we don't have infinite memory. Why would you care more, if the GC does it for you when needed?


It is also inconsistent in that when I create a type, it frees it automatically. But when a user creates a sprite, it is not freed automatically, because the system will still have it in a list. They'll have to call a free function. That inconsistency is where my complaint lies.
That's not a language inconsistency. That would be a design problem in the given sprite library. And is it really?


If there were some kind of "free" method which got called when the user stoped referencing the sprite, that would allow me to make things more consistent. But that would also require the ability to have a sprite in a list, without that reference itself preventing the free method from being called.
Post a feature request for weak references.

But I'm far from convinced for example, that methods are at all useful.
Then you really missed a central part of OO. A method can be overriden in derived classes. This simple fact makes a huge difference and is what makes BlitzMax really an OOP language. Overridable methods are like hook points, the derived class can change the implementation for that hook point, and keep the rest unchanged. What's more, the "modified" type (the derived type with overrident method) can still be passed to any function/method that expects to be passed object of the base class. This models an "Is a" relationship and allows extensive code factorization.
If there is a thing you need to know about OO, that's really that. Invest some time investigating that single feature, that will be time well spent.


taxlerendiosk(Posted 2006) [#26]
' If we're going to be consistent, why isn't this TList.Create()?

There's no initialization, you can just use "New TList" anyway (that's all CreateList does).


sswift(Posted 2006) [#27]
"That's not a language inconsistency. That would be a design problem in the given sprite library. And is it really?"

It's not a design problem. The sprite system has to keep a list of the sprites that exist so it can loop through them to render them. There's no ifs ands or buts about it.

As for language inconsistency, I say it is that because if my objects need to have a function called to be freed, and the Blitzmax ones don't, then that is inconsistent. If there is no mechanmism, like "weak references" for me to avoid this inconsistency, then the language should require functions to be called to free things to make up for it, so consistency is maintained.

Btw, speaking of inconsistency in the language...

Why, when I want to create a TList, instead of doing MyList:TList = TList.Create() do I have to do MyList:TList = CreateList() instead?

Maybe if I want to be consistent with Max itself, I shouldn't have Sprite.Create() but should go with CreateSprite() instead. And the same goes for PositionSprite() and other such functions.

This is what I hated about C. Not knowing which way to do something because there are 10 different ways it can be done. Sigh.


sswift(Posted 2006) [#28]
"There's no initialization, you can just use "New TList" anyway (that's all CreateList does). "

Perhaps, but it would be foolish to do that, because then you assume the modules will never change. And if they do, then you're opening up a potential world of hurt for yourself and anyone using your code.


sswift(Posted 2006) [#29]

Then you really missed a central part of OO. A method can be overriden in derived classes. This simple fact makes a huge difference and is what makes BlitzMax really an OOP language. Overridable methods are like hook points, the derived class can change the implementation for that hook point, and keep the rest unchanged. What's more, the "modified" type (the derived type with overrident method) can still be passed to any function/method that expects to be passed object of the base class. This models an "Is a" relationship and allows extensive code factorization.
If there is a thing you need to know about OO, that's really that. Invest some time investigating that single feature, that will be time well spent.




Well, I see how it can be useful to have a base monster class, and then have a method of the same name in each monster sub type for executing each monster's AI.

I just forgot about that use is all.

On the other hand, it's really not that difficult to have AI be an integer field and have the function that runs the AI check that value and run a specific set of AI with a case statement either.

But there are some more complicated cases where you might want a monster to have some specific fields to it.

On the other hand, is it worth all that extra mess just so some monsters don't have some fields they don't need?


I'm still not convinced this is a better way of doing things.



Post a feature request for weak references.



I don't even know how they are used.


Koriolis(Posted 2006) [#30]
Why, when I want to create a TList, instead of doing MyList:TList = TList.Create() do I have to do MyList:TList = CreateList() instead?
You don't have. They're the same. It's an obvious inconsistency that was introduced on purpose for the sole reason of allowing a totally procedural style. Mark probably tried to satisfy people that would never do OO, by providing a bunch of wrapper functions. Complain to the people that cryed against OO and probably made Mark feel he had to do that *grin*.


sswift(Posted 2006) [#31]
Koriolis:
Yeah, I just noticed that when looking at the help file. I was just about to post about it. I knew just how my post was going to start too.

It would have started: "Oh god..."

So I will start my post a different way.

Well CRAP.

Now I don't know how I should set up my sprite system. I'm not sure which way users of it would prefer to do these things.


Koriolis(Posted 2006) [#32]
On the other hand, it's really not that difficult to have AI be an integer field and have the function that runs the AI check that value and run a specific set of AI with a case statement either.
It's easy to write. Harder to read. A nightmare to maintain and extend.
And writing things like that requires you to have full control over the full code base. In short, code alone, for yourself. When working with other developpers on that kick ass AI code, the "big select" solution really doesn't work that well.

On the other hand, is it worth all that extra mess just so some monsters don't have some fields they don't need?
Well, that's an exponential problem (the 'monster' class should have each and every field that each and every monster would need). So yes. And I guess it all depends on how messy this really is.
To me OO is actually pretty natural. I mean, it's certainly closer to how we actually think as "normal persons". Problem is, it's not really how how experienced procedural programmers think. I've been there.


sswift(Posted 2006) [#33]
On a completely new topic:

Why do TImages have handle fields if they aren't used?

Type TImage Extends TData

	Field width,height,flags
	Field mask_r,mask_g,mask_b
	Field handle_x#,handle_y#


As far as I know, using SetHandle() sets a global handle for all future drawing operations to use. There is no way to specify a specific handle for an image. So why have fields for a handle in the image type?


Koriolis(Posted 2006) [#34]
I have not done the slightest real coding in BlitzMax yet so bear with me if I say stupid things, but it looks like 'handle' here means something totaly different from what you think. Looks like handle_x and handle_y refer to the logical center of the image. In short, it's just the coordinate of a point in the image (its center).


N(Posted 2006) [#35]
Function SetHandle( x#,y# )
Description Set drawing handle.
Information The drawing handle is a 2D offset subtracted from the x,y location of all drawing commands except DrawImage as Images have their own unique handles.
Unlike SetOrigin the drawing handle is subtracted before rotation and scale are applied providing a local origin.


Function SetImageHandle( image:TImage,x#,y# )
Description Set an image's handle to an arbitrary point.
Information An image's handle is subtracted from the coordinates of DrawImage before rotation and scale are applied.


Documentation came through this time. Amazing.


Dreamora(Posted 2006) [#36]
was too slow ...


sswift(Posted 2006) [#37]
Hey what do you know, they do have handles. :-)

I just didn't see any references to the handle in the type itself and saw the sethandle command and knew how the other set commands worked on images, so I didn't bother reading the help.

Well good, now I just have to decide if my sprites should have their own handles, or just use the handles provided by the images they use. Since i would have to reset the image handles to make the sprite handles work, and that would be bad, unless I reset it, maybe I should just use the image handle. Hm...


sswift(Posted 2006) [#38]
Does anyone know if Mark's binary tree thing attempts to balance the tree when a new node is inserted to make searches faster?

http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Tree/

I haven't decided yet if I will use a list I sort, or a binary tree yet for keeping the sprites in the same order as they need to be drawn in. Since the binary tree stuff isn't in the docs, it might confuse people who come across it in the code. I know I wouldn't know where to start looking to find the information on them.


sswift(Posted 2006) [#39]
Koriolis:
I was just reading the docs, and I came upon something about the Delete() method which I wanted to point out...

You said weak references would solve my problem with the lists. I don't know how you meant that, but I took it to mean that I could use the Delete() method to make sure the sprite is removed from the linked list (which is would be weak referenced to) when the last reference to it is removed.

But I just read the docs on the Delete method, and noticed that it says that you can't count on when it will be called. That means there would be a potentially nasty bug if I tried to remove the sprites from the list by detecting when all the other references are gone with Delete().

Since the list is the list of sprites to draw, and Delete() might not be called right away when the sprite's (strong) references go down to 0, the sprite might still be drawn after the user expects it to have been freed. As far as they're concerned all the references are gone... But the garbage man hasn't called the Delete method which will really free up the last reference to it.

So maybe weak references are a bad idea. So long as the garbage collector can't be counted on to arrive immediately after all references are gone anyway.


Koriolis(Posted 2006) [#40]
but I took it to mean that I could use the Delete() method to make sure the sprite is removed from the linked list
Not really. You never invoke Delete directly, hte GC does. Delete is not really a destructor like in C++ but more a finalizer like in Java.
A weak reference is simply a reference that is not taken into account to determine the reachability of an object, or said differently, it doesn't count in the "liveness" of an object.
So if an object has only a weak reference to it, when the GC determines if it must or not collect the object, the answer will be yes. The object is collected, and the weak reference is AUTOMATICALLY nulled out.


That means there would be a potentially nasty bug if I tried to remove the sprites from the list by detecting when all the other references are gone with Delete().

I don't follow you. When do you detect that? You don't, the GC does.

... But the garbage man hasn't called the Delete method which will really free up the last reference to it.
Well, that's the oter way around, but I get your point. Indeed, in most GC (as in BlitzMax, if we can call that a real GC) you have no guarantee as when the object is deleted. It's not determinist, for efficiency purpose. All the GC doesn is managing *memory* (and as a side effect, object liveness). I don't know how you feel it, but counting on having a reference set to Null to stop drawing a sprite just feels like not asuch a good idea and certainly not so natural.
All that comes down to the fact that Delete must only do some last chance clean up, and the GC used to manage memory and nothing more.
A GC that could delete object in a determinist way while still working in all cases (that is, even with cyclic references) would certainly be excellent. It's just very unlikely that we'll see soon any such GC not being totally inefficient.
Well again, BlitzMax doesn't support cyclic references... But that's another story.


Wiebo(Posted 2006) [#41]
While I was programming the basis of my Geometry Wars clone I was afraid of the GC not being fast enough as well. I've noticed that it indeed IS quick enough to get stuff deleted in time. Just looking at the listcount()'s and mem allocted it all is going just fine... The GC truly rocks, and I trust it to do wht it has to do. Play with it sswift, monitor your system resources, etc. I think you will see it does its job. Once I got my objects' updating and list removal methods in order all went like expected.


dmaz(Posted 2006) [#42]
sswift, a long time ago when I went from c to c++ my first reaction was pretty close to yours. I think as you work though this you'll see more and more things that will make you go "oh yeah, that's cool".

I don't think you should be worrying so much about how your users will be using your package. Just expect them to follow the proper rules and you should be ok. You should also encapsulate almost everything in your class. for instance, why do you have SpriteRenderList outside as global? It's bad practice to directly reference outside things inside your class. I would do something like this so your users can take full advantage of OO too.
Type Sprite
	Global RenderList:TList = New TList
	Global gid:Int = 0
	
	Field id:Int = gid    'this will be 0 for the first one not 1

	Method New()          'remember, this new gets called AFTER the normal new
		gid:+1
		ListAddLast RenderList, Self
	End Method
	
	Method Remove()
		ListRemove RenderList, Self
		Print "Removed id "+id+", "+CountList(RenderList)+" total sprites now remaing"
	End Method		
End Type

For Local i:Int = 1 To 5
	New Sprite
Next

For Local mt:Sprite = EachIn Sprite.RenderList
	If mt.id = 3
		mt.Remove
	Else
		Print "id> "+mt.id
	EndIf
Next

End



dmaz(Posted 2006) [#43]
ok, here is something weird. this does clean up but it seems something does hang around... check this out, is it a bug

Type Sprite
	Global SpriteRenderList:TList = New TList
	Global gid:Int = 0
	
	Field id:Int = gid

	Method New()
		gid:+1
		ListAddLast SpriteRenderList, Self
	End Method
	
	Method Delete()
		Print "REF CLEANED:id "+id
	End Method

	Method Remove()
		ListRemove SpriteRenderList, Self
		Print "Removed id "+id+", "+CountList(SpriteRenderList)+" total sprites now remaing"
	End Method
			
End Type

Local mt:Sprite = New Sprite
Local mt2:Sprite = New Sprite
Local mt3:Sprite = New Sprite

Print "id>"+mt.id
Print "id>"+mt2.id
Print "id>"+mt3.id

mt.Remove; mt=Null; GCCollect() 
mt2.Remove; mt2=Null; GCCollect()
mt3.Remove; mt3=Null; GCCollect()

GCCollect()
GCCollect()

End


here is the output

Building untitled2
Compiling:untitled2.bmx
flat assembler version 1.64
3 passes, 7074 bytes.
Linking:untitled2.debug.exe
Executing:untitled2.debug.exe
id>0
id>1
id>2
Removed id 0, 2 total sprites now remaing
Removed id 1, 1 total sprites now remaing
REF CLEANED:id 0
Removed id 2, 0 total sprites now remaing
REF CLEANED:id 1

Process complete


Any ideas or should a bug report be posted?


Nelvin(Posted 2006) [#44]
@sswift
your only small problem is, thinking in the wrong direction regarding resource/objectmanagement which results in the bad experience you currently got.

Garabage collection and managing your objects in whatever systems (spritelists/renderlists/collisionlists/managers) you like to use them are 2 completely different things.
garbage collection is exactly what its called - it's there to cleanup garbage/system resources *after* you released all references to an object.

So gc doesn't free you from writing "destructors" to remove f.i. your sprites out of your lists/managers, it just frees you from deleting the memory used by them after releasing the last reference.
An example why it still is very usable - given a sprite system you may put a lot of frames on a single texture for faster rending - now you may use the same texture instance for hundrets of sprites but you never have to think about when to free it, you just kill your sprites as you go and whenever all sprites using a texture are gone, the texture will be freed by the garbage collector (though delayed, i.e. whenever the gc cycle reaches the texture object).
You can of course manage texturs by yourself and inc/dec a referencecount each time a sprite got killed, but *that's* exactly what gc is made for.


Dreamora(Posted 2006) [#45]
dmaz: This indeed is strange ... I do not get a single one of those delete output in release build ...


sswift(Posted 2006) [#46]
dmaz:
At first I thought you were crazy, but then I noticed you used Global instead of Field for that list. I didn't know you could use Global inside a type. My initial thought was you were making one linked list for every sprite instance you created, which is obviously wrong.

Weibo and Koriolis:
It's clear you don't understand what I was saying.

Here look at this example:

SpriteList.TList = CreateList()
Type Sprite

   Function Create:Sprite(Image)
       Local ThisSprite:Sprite = New Sprite
       ThisSprite.Image = Image
       ListAddLast SpriteList, ThisSprite
       Return ThisSprite
   End Function

   Method Draw()
       ' Draw sprite here
   End Method

   Method Delete()
       ListRemove SpriteList, ThisSprite
   End Method

End Type

' Create sprites at start of level.
Sprite1:Sprite = Sprite.Create(Image)
Sprite2:Sprite = Sprite.Create(Image)

' Oh no, sprite 2 was killed!
Sprite2 = Null

' Does garbage collector run immediately?  No, we can't count on when it will run.

' It's the next frame!  Oh no!  Draw the sprites in the list!
For ThisSprite:Sprite = Each Sprite
    ThisSprite.Draw
Next

' Ahh!  Two sprites were drawn!

' Garbage collector finally gets around to running, which calls Sprite2's Delete Method, which finally removes it from the list of sprites to draw, which finally allows it to be freed.



Of course, this example all relies on the concept that the list of sprites is a set of "weak references". This example is pointing out a problem with using weak references as a way around the problem of allowing the user to avoid removing sprites from the linked list with a Sprite Free method. And that problem is that you can't count on when the garbage collector could be called, so when you think something should have had its last link severed, and it should have been removed from the list, it really hasn't been, because though the last strong link has been severed, the garbage collector hasn't gotten around to calling Sprite 2's Delete method, so the sprite is still in the list, and will still be drawn.

This example does NOT apply to BlitzMax as it currently stands! It was only an example of a potential problem with using weak references, if they are implemented in Max.


sswift(Posted 2006) [#47]
I don't know if it is leaving anything around... It might be simply failing to call the Delete method at times.

Type Sprite
	Global SpriteRenderList:TList = New TList
	Global gid:Int = 0
	
	Field id:Int = gid

	Method New()
		gid:+1
		ListAddLast SpriteRenderList, Self
	End Method
	
	Method Delete()
		Print "REF CLEANED:id "+id
	End Method

	Method Remove()
		ListRemove SpriteRenderList, Self
		Print "Removed id "+id+", "+CountList(SpriteRenderList)+" total sprites now remaing"
	End Method
			
End Type

Local mt:Sprite = New Sprite
Local mt2:Sprite = New Sprite
Local mt3:Sprite = New Sprite

Print "id>"+mt.id
Print "id>"+mt2.id
Print "id>"+mt3.id

Print CountList(Sprite.SpriteRenderList)
mt.Remove; mt=Null; GCCollect() 

Print CountList(Sprite.SpriteRenderList)
mt2.Remove; mt2=Null; GCCollect()

Print CountList(Sprite.SpriteRenderList)
mt3.Remove; mt3=Null; GCCollect()

Print CountList(Sprite.SpriteRenderList)

GCCollect()
GCCollect()

End



The list is empty at least. But that doesn't mean types haven't been left in ram.


Wiebo(Posted 2006) [#48]
Well ok, you just HAVE to be right don't you, oh almighty?? I suggest you read the docs first instead of jumping in an claiming you understand whats going on as its clear you do not. If you have to discover here that you can put globals in types its obvious you havent READ the docs, or the introduction to OO by Mark.


sswift(Posted 2006) [#49]
Wiebo:

I don't know what I did to upset you, and I don't know what I said that makes you think I feel I always have to be right.

I am fairly certain here that you did not understand my original post. I went back and read what you said again, and I still feel that I was right in that assessment.

What I was describing was a hypothetical situation based on what might happen if I attempted to use the Delete method in conjunction with weak references to remove a sprite from a linked list automatically.

If you did in fact understand this, then please explain where I have gone wrong in my example.


Also, I HAVE read the docs. I have been reading the docs for a week. The first thing I did was sit down and read the docs.

But there's a LOT of information there. It's not something one can absorb all at once, and I'm bound to miss things.



While I was programming the basis of my Geometry Wars clone I was afraid of the GC not being fast enough as well. I've noticed that it indeed IS quick enough to get stuff deleted in time. Just looking at the listcount()'s and mem allocted it all is going just fine... The GC truly rocks, and I trust it to do wht it has to do. Play with it sswift, monitor your system resources, etc. I think you will see it does its job. Once I got my objects' updating and list removal methods in order all went like expected.




This is your reply to my post. It sounds to me like you thought I was concerned with whether or not the GC would keep up with me freeing sprites in my sprite system under normal circumstances.

But I was not concerned with that. I was concerned with whether it would keep up in a hypothetical situation with weak references and gratuitous use of the delete method to remove sprites from the linked list automatically.

Indeed, as well as you know the GC, as we have seen here, we can't even count on it NOW to call the delete method every time, or even at all.

Nevermind in a situation with weak references where the docs say it might not be called immediately, and if it is NOT called immediately, and does not execute the delet emethod immediately, it will result in a bug.


sswift(Posted 2006) [#50]
Also, what introduction to OO by Mark? I can't find it in the docs.

You expect me to read this stuff, and I can't even find it when I know it exists!


Yan(Posted 2006) [#51]
Do want to borrow *my* glasses SSwift. ;o)

On the home page of the docs, click on 'Tutorials and Articles' and you'll find articles entitled:-

* BlitzMax Memory management
* Introduction to OO programming
* The first 5 'Nehe' OpenGL tutorials
* Writing custom stream handlers (advanced)


sswift(Posted 2006) [#52]
Clive:
I'm still lost here. Home page of the docs?

Are there some docs other than the help files?

Cause there's no specific home page to the help files. I'm clicking right now on the HELP branch, and it isn't bringing up anything. And there's no such thing on the USERGUIDE -> WELCOME branch. Nor on the LANGUAGE -> WELCOME branch.


And under the MANUALS tab of the website here, there's no BlitzMax docs either.


[edit]
I've looked all over the place on this website, on the wiki, in the help, even in the BlitzMax directory. I can't find these "docs" anywhere.
[/edit]


CS_TBL(Posted 2006) [#53]
mark's novel 'bout the OO-pirates and the princess:
http://www.blitzbasic.co.nz/Community/posts.php?topic=41805


tonyg(Posted 2006) [#54]
SSwift, In reference to the OOP pointed to by CliveTheComedicCamel, you don't need to bother.
It's as helpful as the rest of the doc.
Start BlitzMax.
You should have the Welcome to BlitzMax screen.
Select Tutorials and Articles.
Spookily enough it finishes with 'Stay tuned for Part2'.


sswift(Posted 2006) [#55]
Btw, weibo, something you might not understand about me... "I don't think Var was such a great idea" is not so much a statement, as an invitation to discuss it.

It's true I'm not happy with how it is used. And I still feel that the way Mark has used it isn't that great. I'd prefer multiple functions or something else where I can get just one parameter.

But I'm not posting about it because I want it changed. It's not going to get changed any time soon if ever.

Mainly, I am posting to get other people's ideas. Maybe there's a good way of using it? I don't know unless I ask. And declaring it stupid is my way of asking if anyone supports it, and why.

And I have learned some stuff from this thread. Quite a bit actually. Like how you can use Globals in types. And that there is a Delete() and a New() method. And we all learned just now that maybe we shouldn't count on these methods yet.

So it's a useful discussion, even if I sound like a pompous ass when I make blanket statements like that. I can't help it. :-) You'll jsut have to learn to live with it.


sswift(Posted 2006) [#56]
Tony:
I see now. I found out how to get to it too. You have to click the little house icon next to the back button to get to the home page.

That should really be linked to the topmost item in the help tree on the sidebar.


N(Posted 2006) [#57]
And declaring it stupid is my way of asking if anyone supports it, and why.


Wouldn't it have been better to just ask if anyone supports it and why, then? You young whippersnappers, sheesh.

And we all learned just now that maybe we shouldn't count on these methods yet.


I use a dispose method that is called either when the program ends or when an object is deleted (whichever comes first). You can rely on the New method, but relying on Delete in a managed environment is bad practice.

For one thing, you cannot guarantee that delete will be called within a given timeframe. Delete also isn't called when the program ends. So if you want to write something to a stream when the program ends and just so happen to place it in a delete method, you're out of luck.


sswift(Posted 2006) [#58]
Noel:

"Wouldn't it have been better to just ask if anyone supports it and why, then?"

I find my method gets more replies. :-)

Besides, you don't have a good debate unless you take a firm stance on the issue! This "I'm not sure var is a good idea but maybe it is, and I don't mean to incite any controversy over it" thing just isn't going to cut it. :-)


N(Posted 2006) [#59]
I find my method gets more replies. :-)


True. Most people have probably noticed that my rather 'provocative' means of getting information tends to spark up some debates and occasionally get me banned. Somehow, you seem to be immune to banning, even though you've been in violation of the TOS far more times than me. O_o


sswift(Posted 2006) [#60]
Now, I don't think that's true at all Noel!

What have I done to be in violation of the TOS? There was that one time recently when someone was deleting my paperboy thread. And I've posted a few threads complaining aobut the moderation in the past... But I don't rock the boat THAT much.

Also, maybe they realise that unlike you, I can't afford to keep buying a copy of Blitz every time I'm banned. :-)


N(Posted 2006) [#61]
Oh SURE you don't.


sswift(Posted 2006) [#62]
I'm afraid you'll have to provide examples. :-)

Also: See my edit above.


Admittedly, I don't know how often you rock the boat, so I can only assume you do it more often since you get banned, and I don't do it that often. :-)


Haramanai(Posted 2006) [#63]
Well from my point of view Var it's very usefull.
Very often you don't wand the inputs in the functions to get changed and sometimes you wand them to change Var gives you this choice.
Example :
Local number:Int = 1

Function getDouble:Int( number:Int)
	Return number*2
End Function

Function setDouble(number:Int Var)
	number:*2
End Function


Print number
Print getDouble( number )
Print number
setDouble( number )
Print number

What confused me was that the user types takes all the changes without Var.


sswift(Posted 2006) [#64]
Hara:
I think you mean "want" not "wand". :-)


Haramanai(Posted 2006) [#65]
Yes... After so many wand someone said to me that I have to write want.
Still learning the basics...

Does the above post solve your problem?


N(Posted 2006) [#66]
Also, maybe they realise that unlike you, I can't afford to keep buying a copy of Blitz every time I'm banned.


That's Amon. I've only ever bought two Blitz products: B3D and BMax. And I sold my copy of B3D.


Koriolis(Posted 2006) [#67]
even though you've been in violation of the TOS far more times than me
Noel, I have no idea how you can seriously have that feeling. Yes, SSift's technic to gain attention and to cause debate is somewhat childish and futile. It's certainly annoying in many ways, but that's about all, and I believe he's really listening to what is said.
He's not been personnaly attacking anyone.
On the other hand what you often call humor actually sounds like *bad* humor directed right toward fellow blitz users.

Now that's maybe a personal attack but you're a big boy *grin*. And it's not like you're going to care.


sswift(Posted 2006) [#68]
"That's Amon. I've only ever bought two Blitz products: B3D and BMax. And I sold my copy of B3D."


Hear that Weibo? I can be wrong!


Haramanai:
Honestly, no, because it's not really a "problem". I know how Var is used. I was only questioning how Mark chose to use it in the functions he provided with Blitzmax, and whether or not allowing Var to be used would lead to good programming practices.

I alrteady explained above, but I'll explain again.

If you have GetHandle() which returns to variables with Var, then you can't do this:

If (Image.X + GetHandleX()) > 0 then

Instead you have to create two temporary variables, pass them to GetHandle() and then do your if statement on one of them. It's a lot of extra work, just for the sake of having one GetHandle() function instead of a GetHandleX() function and a GetHandleY() function.

Granted, there might be some cases where using Var like this is more efficient. And maybe Mark is using it in a bad way and there are lots of good ways to use it. But if so, I can't think of many good ways to use it. And I am just worried that by having it available, people will misuse it just as Mark appears to have done.

Of course, some people might disagree with me that Mark has misused it at all. But as far as I'm concerned, if it makes more work for me, and makes me declare a bunch of extra variables to get the data, then it is a bad thing, until someone explains to me why it is otherwise.

Now, if I dig down into Max's source, I see that I might be able to do the following:

gc.Handle_X

So my handle example here might be a bad example, but Var is the subject not handle, and whether my handle example is good or not doesn't have bearing on how Var is or may be used.

Btw, I would personally not trust using gc.Handle_X myself. If it isn't in the docs, there's no guarantee it might not change. There is also no way to know if GetHandle() does something funny that needs to be done that just grabbing the handle like that won't do. Of course you can look at the code for GetHandle() to see that now maybe it doesn't do anyhting special. But who knows about later? If we're not intended to access it, and I take the docs to be the indicator of what is "finished" and intended to be accessed, I don't feel safe doing so. Also, a more important issue with that, is that users coming across that in my code won't be able to easily look it up to find out what it is doing, like they can with help file commands. That's a BIG problem. If the users of my code can't figure out what it is doing, that's bad. So I stick to the commands provided in the help file as much as possible. And that means being forced to use GetHandle(). Which means having to declare extra variables and getting the handle so I can add it to stuff, rather than just sticking GetHandleX() wherever I please. And that's annoying.

Hence my complaining.

But I really don't want to start this whole discussion over from scratch again. :-)


N(Posted 2006) [#69]
On the other hand what you often call humor actually sounds like *bad* humor directed right toward fellow blitz users.


I can't help it if you take everything far too seriously, Koriolis.


Koriolis(Posted 2006) [#70]
I actually agree on your concern about the use Mark does of 'Var'. But then it's not really that you "don't think Var was a good idea" but that you "don't think Var is wisely used". Be precise about what you bash, remember ;)


sswift(Posted 2006) [#71]
I think taking things too seriously is what is known as the Koriolis Effect.

Btw Koriolis, your name is spelled wrong. :-)


Koriolis(Posted 2006) [#72]
I can't help it if you take everything far too seriously, Koriolis.
I don't. You've not seen me go high and mighty about it, did you?
I just easily understand why people can get your post badly.
It's somewhat due to the medium. We're on a forum, you can't expect people to notice the subtle grin on your face, the one that in eal life would say "mocking on you gently".


Koriolis(Posted 2006) [#73]
Btw Koriolis, your name is spelled wrong.
Now you're mocking at me, RIGHT? Jesus chriiist. How dare you. You litlle....something.
I can't believe it, crap, crap, crap.

.
.
.


See? I'm too bad at written irony :D


sswift(Posted 2006) [#74]
"It's somewhat due to the medium. We're on a forum, you can't expect people to notice the subtle grin on your face, the one that in eal life would say "mocking on you gently"."


There was an article on Wired.com about that. It is rather unfortunate. And it is why I stick lots of smiley faces in my posts. So people know when I'm being a wiseass. Doesn't always work though.

I had one customer ask me what the little "colon dash parentheses thingy" was not to long ago actually. :-)


Koriolis(Posted 2006) [#75]
colon dash parentheses thingy
ROFL.


While we're at it what does that ROFL mean ;)


FlameDuck(Posted 2006) [#76]
There was an article on Wired.com about that. It is rather unfortunate.
The one about the study that said you had a no better than chance (50%) of determining the tone of an internet posting? That was rather interesting.


sswift(Posted 2006) [#77]
That was the one. :-)


Jay Kyburz(Posted 2006) [#78]
Hehe, What confused me about this whole thread is that i didn't event know about GetHandle and GetColor etc. I just looked them up now. They are the only example of this i have seen.

When I stated on my engine i wrote my own sptite system where each had its own pos, color, scale, etc.. I never get used the get functions at all, i just iterated through my sprites and used setRotation, SetAlpha, and DrawImage etc..

In your example your are using get handle to determine in the sprite in offscreen where i just examine the properties of my sprite.

If (self.image.x + self.pos.x) > 0 then ...

Oh.. and this is in a method of the sprite itself. Each sprite is asked to determine for itself if it is off screen or not before the render iterates over each.

oh, and i would probably store that value away so the math was not done every frame. (if self.leftbound > x) then im off screen - self.destroy()

It might not be as fast as possible but i like to think its neat and tidy :)


dmaz(Posted 2006) [#79]
dmaz:
At first I thought you were crazy, but then I noticed you used Global instead of Field for that list. I didn't know you could use Global inside a type. My initial thought was you were making one linked list for every sprite instance you created, which is obviously wrong.


sswift
yeah, I put a couple of neat things in that example. did notice how Sprite.id is initialize differently for each Sprite instance? Also, you already know about new() which I've haven't seen anybody have a problem with. delete() should work better than it does though. Also make note that a function is like a global procedure the class in that it operates on the type itself instead of an instance of the type. while a method requires an instance to exist. but as you now seem to be aware you will need a remove() which I think is way clearer than mt=null. When I code stuff like this I could care less about making mt null since the GC will clean that up. for instance, you might have somthing like

pointer:Sprite = New Sprite

but later you'll have a bunch in a list most likely that the user creates such as
badguys:TList = New TList
for i = 0 to 5
   si:Sprite = new Sprite
   si.x = blah blah
   ListAddLast badguys, si
next


then you later have
for si:Sprite = each in badguys
   ai stuff
next

see really only 2 var that the user would need to keep track of since most of them will probably be in lists. If it was my program I wouldn't do anything else with them. The nice now since Max has separate lists is that your internal class list includes all the sprites while the users badguys list only includes the ones he needs.

It kind of sounds like you're getting a handle on all this now, this might have all be redundant but whatever.


Wiebo(Posted 2006) [#80]
> Hear that Weibo? I can be wrong!

The day you spell my name correctly is the day I'll take your word for it. Also, sticking too many smileys in a post seems to me that you're making fun of the one you're talking to. Generation gap, (internet) cultural differences? Who knows, but that's how I see it...
totally off-topic now, I know, so I'll just stop here.