Post

 Resources 

Console

Home | Profile | Active Topics | Members | Search | FAQ
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 VBGamer
 VBGamer
 Questions about code design
 New Topic  Reply to Topic
 Printer Friendly
Next Page
Author Previous Topic Topic Next Topic
Page: of 2

Sion
Warrior

Denmark
138 Posts

Posted - Aug 09 2004 :  1:09:12 PM  Show Profile  Visit Sion's Homepage  Click to see Sion's MSN Messenger address  Reply with Quote
I have a few questions concerning how the best code design is achived.

First off, the level of abstraction. What level of abstraction should be used?
Examples:
a) Unit1.CanSeeUnit(Unit2)
b) Unit1.CanSeeUnit(Xpos: 100, Ypos: 100, Width: 10, Height: 10)
c) The function in answer b) in a module, and then called by the function in a) from a class

Second, class or not class. Which functions should be contained within a class, and which should be accessed from a module?
Examples:
a) Unit1.CanSeeUnit(Unit2)
b) CanSeeUnit(Unit1,Unit2)

Third, parameters. How should class-parameters be passed?
Examples:
a) Sprite.ReCalc(State: ATTACK)
b) Sprite.State = ATTACK
Sprite.ReCalc()

Fourth, custom types. Should custom data types be passed to classes?
Examples:
a) Pos.X = 5
Pos.Y = 10
Unit.Pos = Pos
b) Unit.PosX = 5
Unit.PosY = 10

Fifth, level of class hierarchy. When dealing with classes, how much should the classes automate each other?
Examples:
a) Player.ReCalcArmies
b) For Each Army in Player
Army.ReCalcUnits
Next
c) For Each Army in Player
For Each Unit in Army
Unit.Recalc
Next
Next

I hope some experinced programmers will give me some input. You don't have to know the correct solution to the questions, and there may no be a single correct answer, but a few guidelines to designing code would be nice!
Of cause others are also invited to post any questions concerning code design that they may have.

Thanks in advance

Visit my personal blog at www.AndersNissen.com!

sdw
Warrior

USA
160 Posts

Posted - Aug 09 2004 :  1:22:37 PM  Show Profile  Visit sdw's Homepage  Click to see sdw's MSN Messenger address  Reply with Quote
Do whatever floats your boat.

Go to Top of Page

Sr. Guapo
Swordmaster

USA
272 Posts

Posted - Aug 09 2004 :  4:05:06 PM  Show Profile  Reply with Quote
Yeah, just do whatever makes it easier for you to use while still being functional. It isn't a bad idea to pick up some good habits, though, in case you ever work on a team or release code to others.

Edit: Woohoo!!! 250...

Edited by - Sr. Guapo on Aug 09 2004 4:05:51 PM
Go to Top of Page

Eric Coleman
Gladiator

USA
811 Posts

Posted - Aug 09 2004 :  5:49:44 PM  Show Profile  Visit Eric Coleman's Homepage  Reply with Quote
This is a good article to read http://www.geocities.com/tablizer/oopbad.htm There are a lot of links in the article, so to get the full whole idea you need to a lot of reading.

In the end, it all depends on your own preferences.

Read this, http://www.vb-helper.com/rant_vb_net_not_oo.html , more for its comparisons on design instead of a rant on vb.net.

quote:
Having more objects is not a goal. If creating more objects was a goal, you could do away with constants such as 37 and 12 and make objects instead. You could create an instance of the 12 object and an instance of the 37 object and then use the 12 object's Plus method to add then two together. In some weird sense, that would be more "object-oriented" but not in a particularly useful way.


Go to Top of Page

Lachlan87
Moderator

USA
160 Posts

Posted - Aug 10 2004 :  09:10:13 AM  Show Profile  Reply with Quote
The main thing is to try to be consistent. If the only way to give your player a laser gun is to write:

GiveWeapon(LaserGun, Player1)  


And the only way to give the player a machine gun is:

Player1.Weapon.Add(MachineGun)  


Then your not being consistent, and it will be hard for others (and yourself) to pick up on your coding scheme.


One of the things I like about programming things into objects is--and this will probably sound silly to you--because then I can "explore" them with the "intelli-sense" feature of visual studio. The bigger my projects get, the harder it is for me to remember the exact name of all my functions, variables, etc. If I have them all under more general objects, it cuts back on a lot of guess-work for me.

But I think if you are familliar with both procedural and OO programming, you will find that you get a kind of a feel for what would be best programmed which way. Of course, there will always be someone who will disagree with you, but if there was a "right" way to do everything, than there would be no art to programming at all.
Go to Top of Page

Eric Coleman
Gladiator

USA
811 Posts

Posted - Aug 10 2004 :  09:42:15 AM  Show Profile  Visit Eric Coleman's Homepage  Reply with Quote
Just a programming tip for you, You can use Intellisense for standard modules as well. Just type the name of the module, then a . and then you should see a list of properties, methods, and public variables and functions. Yes, you can use properties in standard modules.

For those that are OOP purists, just skip over this message. There is a point when OO design complicates things too much. When I was programming my game Gladiator I looked into using the skeletal animation code from source forge. It is called "Cally3D" or something like that. The demo's look nice, but when I downloaded the code it was extremly complicated. I studied it for a really long time trying to figure out exactly what was going on, but everything was so deeply hidden in many levels of abstraction it became useless to try to modify it to suit my needs. Even though OOP is supposed to encapsulate concepts, it failed miserably in this case. There was so much inheritance and overloading that given a single line of code you had to trace back through a large spider-web hierarchy of dependent classes.

I eventually realized that I was getting nowhere with the code, so I wrote my own version in a procedural format. It turned out to be a lot less code and a lot less complicated. Instead of treating scalars, vectors, and matrices as "objects", I treated them as numbers, which they are. Instead of a hundred different functions, I only needed a few.

Just so this isn't totally negative, if you don't understand the mathematics behind such stuff and you have no need to modify the code to suit your needs, then OOP is fine, just so long as you don't have to worry about it. Unfortunately, if you're programming a game, then you will have to worry about it.

Even though consistancy is important, I do think there is a middle ground for using both procedural and object oriented design in a program. For example, I used classes to wrap up the procedural code that I wrote for my particle system.
Go to Top of Page

Lachlan87
Moderator

USA
160 Posts

Posted - Aug 10 2004 :  12:26:05 PM  Show Profile  Reply with Quote
Thanks for the tip, I hadn't known that!

Go to Top of Page

cjb0087
Knave

Australia
76 Posts

Posted - Aug 11 2004 :  02:54:37 AM  Show Profile  Visit cjb0087's Homepage  Reply with Quote
forced OOP, the reason nobody(sane) likes java

www.bugsplat.tk
Go to Top of Page

Peter
Administrator

Canada
67 Posts

Posted - Aug 11 2004 :  3:40:13 PM  Show Profile  Visit Peter's Homepage  Reply with Quote
Basically, the point is to make your code as simple and elegant as you can get it. Before going nuts with classes try programming with user defined types and functions in modules, that actually gives you a pretty good idea of how to organize things, after it becomes a lot easier to create and organize classes in a meaningful and useful way.

Good luck with coding, its good to see people interested in not just writing code but writing good code =)

Talos Studios - VoodooVB - VB Gamer

Go to Top of Page

Sion
Warrior

Denmark
138 Posts

Posted - Aug 13 2004 :  08:59:04 AM  Show Profile  Visit Sion's Homepage  Click to see Sion's MSN Messenger address  Reply with Quote
Okay, thanks to everyone for the input.

The main reason I made this thread was because I thought some code design approaches would work better than others. Both in terms of clearity, matainability and efficientcy. I had also presumed that larger blocks of code should be called from modules instead being called from inside classes to avoid storing many instances of the same code block in memory, but you havn't mentioned that, so I guess it dosn't matter.

The sum of the answers must be that code design is equally good regardless of which designing approach that has been used. That code should be designed as needed, but the use of classes should be limited to instances where they provide a significiant advantage to avoid cluttering up the code with too many classes.

In relation to my design questions in the first post of the thread, I've decided to use the following design in my current game:

Abstraction:
quote:
a) Unit1.CanSeeUnit(Unit2)
b) Unit1.CanSeeUnit(Xpos: 100, Ypos: 100, Width: 10, Height: 10)
c) The function in answer b) in a module, and then called by the function in a) from a class

Chosen: c)
Clear and easy-to-use interface in classes while still keeping the larger blocks of code in modules, just in case that it is more memory efficiant.

Classes vs. modules:
quote:
a) Unit1.CanSeeUnit(Unit2)
b) CanSeeUnit(Unit1,Unit2)

Chosen: a)
Well, I already addressed this, but besides providing a clear class interface it's also more logical to use the [UNIT].[FUNCTION] notation. In my mind, anyway.

Parameters:
quote:
a) Sprite.ReCalc(State: ATTACK)
b) Sprite.State = ATTACK
Sprite.ReCalc()

Chosen: b)
Setting only one parameter at a time also provides a clearer class interface - both internally and externally. The different methods also seem a lot less complicated when most of the parameters have been set elsewhere.

Custom types:
quote:
a) Pos.X = 5
Pos.Y = 10
Unit.Pos = Pos
b) Unit.PosX = 5
Unit.PosY = 10

Chosen: b)
Using custom data types as parameters and returns from class functions can be very handy in some cases, but I've chosen not to use them. First of all, in many cases using UDTs as parameters just means creating a new variable, jamming all the data in it and then sending it as a parameter, where passing the data would be just as clear. Secondly, I've had some problems passing UDTs to and from classes, and it seems that UDTs would have to be replaced by small classes instead, and this is where things start getting complicated. Thirdly (does that word exist?) many of my parameters and returns are other classes which kind of eliminates this problem.

Class hierachy:
quote:
a) Player.ReCalcArmies
b) For Each Army in Player
Army.ReCalcUnits
Next
c) For Each Army in Player
For Each Unit in Army
Unit.Recalc
Next
Next

Chosen: a)
I've chosen to handle as few classes as possible from my main rutine. This will hopefully help keeping the overview of what's going on clear and keeping bugs at a minimum. I'll probably end up with units grouped into a class, and then use those grouped functions such as Enemies.RecalcUnits and Player.RecalcUnits.

That's it.

Visit my personal blog at www.AndersNissen.com!
Go to Top of Page

Lachlan87
Moderator

USA
160 Posts

Posted - Aug 13 2004 :  10:12:03 AM  Show Profile  Reply with Quote
quote:
Originally posted by Sion

I had also presumed that larger blocks of code should be called from modules instead being called from inside classes to avoid storing many instances of the same code block in memory


If you don't need a new copy of the function or variable for every instance of the object, declare it as Shared (in vb.net, not sure about vb6). That way VB will make all the objects share the function, instead of giving them their own copies. At any rate, that's how I was taught.
Go to Top of Page

Sion
Warrior

Denmark
138 Posts

Posted - Aug 31 2004 :  2:49:01 PM  Show Profile  Visit Sion's Homepage  Click to see Sion's MSN Messenger address  Reply with Quote
Which is the best (clearest and fastest) way to get events from classes in a collection?

I'm having a class named cUnits containing a number of cUnit-classes in a collection. I would like each of the cUnit-classes to raise events on special occations, but handling events from arrays or collections of events-raising classes are not very straight-forward in Visual Basic.

One approach is to use some Visual Basic modules, found on the Internet, that uses low-level functions to redirect events to allow multiple events to be handled. I am not sure, but I would guess that such techniques are CPU and/or RAM-expensive. And on top of that - it's not very pretty.

The approach I'm currently using is calling a public method instead of using events, and using this method as replacement for the regular event. This works fine and has an acceptable level of clearity.

But do anyone have other suggestions as to how this go about dealing with this problem?

Visit my personal blog at www.AndersNissen.com!
Go to Top of Page

Eric Coleman
Gladiator

USA
811 Posts

Posted - Aug 31 2004 :  8:18:25 PM  Show Profile  Visit Eric Coleman's Homepage  Reply with Quote
This answer assumes that you're using VB 6. Events in VB6 from activex classes are late bound. You may want to stick with calling public procedures (or friend procedures if you can.) You may want to read this, http://www.elitevb.com/content/01,0038,01/ for more information.
Go to Top of Page

Sion
Warrior

Denmark
138 Posts

Posted - Sep 01 2004 :  3:25:37 PM  Show Profile  Visit Sion's Homepage  Click to see Sion's MSN Messenger address  Reply with Quote
Yes, I'm using Visual Basic 6.0

Thanks for the link, Eric, it's very interesting reading. However it's waaay too advanced for me, and it's too much of an overkill in this specific case.

I think I'm just going to go with calling public methods, probably creating a public class to recieve the "events" to enable external event-handling.

You mention using a friend method to get the raised "events". It's funny, I've never ever used a friend method!
I don't know how it has slipped through, but I've never used it, and only seen it used in very very few occations. This even though I've been working with Visual Basic for nearly 6 years now!

Well, any blank spot in my Visual Basic knowledge needs to be filled immediately!

I found out - as you may already know - that friend-methods allow the local project to acces the method, but isn't accessable from external callers. This sort of a cross between the private and public method declarations.

Something very different from the other method declarations type is - surprisingly enough - speed. (This may not surprise Eric, as he recomended me to use a friend-method, but it surprised ME!). Appearently a friend-method is called ~8 times faster than its public counterparts. Holy moly, that's a lot. I should probably search my current project for methods that can be converted to friend
Description of the speed increase using friend can be found here: http://www.devx.com/vb2themax/Tip/18396

Visit my personal blog at www.AndersNissen.com!

Edited by - Sion on Sep 01 2004 3:33:43 PM
Go to Top of Page

Iodiplin
Knave

USA
67 Posts

Posted - Sep 02 2004 :  3:10:37 PM  Show Profile  Reply with Quote
Indeed, good code is essential. I have downloaded so many projects with useful content, and then disregarded them beceause they were so poorly programmed. I myself use only UDTs (I only use classes if I'm using someone elses code ). I can't count how many projects I've started and said "I'm going to be a good OOP programmer and uses classes." I would start with a huge list of classes. After a little while, I'd remove a few, and then some more. IN EVERY SINGLE CASE, I eventually removed ALL classes and went straight back to UDTs. I'm not saying OOP is bad, it's just not how my mind works.

At any rate, I have also come to find that commenting is not only a good habbit, it's a necessary practice at all times. I am consistently commenting all my code. There is not a single varaible in my projects that does not have a single quote directly after it (except for counter variables, perhaps ). When I go back to my code after a long break, it is much easier to become reaquainted.

I would like to say one final thing: keep your code looking nice. There's nothing like scrolling down a 100 page module and seeing good tabbing, even spacing, LOTS of spacing (to keep code easily legible) and well aligned code. Things like:

  
Dim a           As Single ' Angle of rotation  
Dim i           As Long   ' Counter  
Dim SpriteFrame As Long   ' Current sprite frame  
  


can simply make you feel more confident when seeing the code. It just makes you feel better. For me that is necessary considering sloppy code makes me feel depressed, seriously.

Just my 2c, but in my oppinion, you can ruin good code by writing it sloppily.

P.S. Sorry, I went a little off-topic.

Environment Makes All the Difference.
Go to Top of Page

sdw
Warrior

USA
160 Posts

Posted - Sep 02 2004 :  8:02:49 PM  Show Profile  Visit sdw's Homepage  Click to see sdw's MSN Messenger address  Reply with Quote
quote:
You mention using a friend method to get the raised "events". It's funny, I've never ever used a friend method!


Don't feel bad, neither have I! Up until now I have no idea it exist. Great find, and thanks for posting that. I wonder if Almar has any idea about this :)

quote:
At any rate, I have also come to find that commenting is not only a good habbit, it's a necessary practice at all times.

I actually don't comment unless it's for someone else's benefit, or if the comment says nothing more than "Left off here" or "my todo list". I like to use my own system of a Hungarian Notation with descriptive names. So instead of commenting after where the variable is declared, I would do it this way:
  
Dim sAngle as Single
Dim i as long
Dim lFrame as long
  

Because to me comments make things look sloppy. Although I absolutly agree that meaningful spacing between lines of code, tabbing, and dividing your code into blocks can help a great deal in reading your own code instead of putting all your code into one chunk.
Go to Top of Page
Page: of 2 Previous Topic Topic Next Topic  
Next Page
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
VBGamer © Go To Top Of Page
This page was generated in 0.17 seconds. Snitz Forums 2000

Copyright © 2002 - 2004 Eric Coleman, Peter Kuchnio , et. al.