I've been thinking about the design for a browser app on the HTML5 canvas that simulates a 2D robot zooming around, sensing the world around it. I decided to do this from scratch just for fun. I need shapes, like polygons, circles, and lines in order to model the robot and the world it lives in. These shapes need to be drawn with different appearance attributes, like border/fill style/width/color. I also need to have geometry functions to detect intersections and containment for the robot's sensors and so that the robot doesn't go inside stuff.

One idea for functions is to have two totally separate libraries, one to implement graphics (like drawShape(context, shape)) and one for geometry operations (like shapeIntersectsShape(shape1, shape2)). Or, in a more object-oriented approach, the shape objects themselves could implement methods to do their own graphics (shape.draw(context)) and geometry operations (shape1.intersects(shape2)).

Then there is the data itself: whether the data to draw a shape and the data to do geometric operations on that shape should be encapsulated within the same object, or be separate structures (where one would contain the other, or both be contained inside another structure).

How do existing applications that do graphics/geometry stuff deal with this? Is there one model that is best, or is each good for certain applications? Should the fact that I'm using Javascript instead of a more classical language change how I approach the design?

  • \$\begingroup\$ Of course, you could have the objects' own methods call the graphics library. It's another layer, but it keeps them separate in case you need to change the entire graphics library. \$\endgroup\$ – PixelArtDragon Jul 2 '13 at 20:02

Do not make shapes draw themselves. That is a huge problem with naive object-oriented design. Avoid coupling, even at the interface layer. The computer does not need a shape to be able to draw objects (it'll usually be working with more complex models only or sprites which are only loosely approximated by a shape for collision) nor does a shape need dependency on the graphics system in order to exist. The concept of a high-level shape and the concept of a low-level graphics API are entirely orthogonal.

You might have a helper library which can take a shape and the renderer and generate the right darawing commands for the shape. This way all the logic that needs this coupling between shapes and graphics is moved out to a separate place. Since you probably won't be drawing shapes for any reason besides debugging collisions, you might make this part of your DebugDraw system. (it's useful to have a module which can draw simple shapes and lines and overlay text to help debug physics, AI, and so on.)

Whether you use an OO approach is a matter of taste. I've been turned off to the OO approach for geometric shapes over the years, but that's me.

  • \$\begingroup\$ I can only +1 this having fallen into the same line of thinking some time back (fortunately I didn't take it too far). Having objects draw themselves will seriously impair your ability to do batching, instancing, maybe even state management, etc, for example. \$\endgroup\$ – Maximus Minimus Jul 2 '13 at 22:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.