Draggable objects and design patterns

OK, I think I’m beginning to get it. It’s true that in class inheritance systems I’ve written, I do find myself writing little notes in the comments, “class X overrides function A, but classes Y and Z inherit it”, etc. I guess inheritance allows you to be more lazy, which can come back to haunt you.

I found these two articles quite useful for comparing component systems to inheritance. Although their examples are in C++ and C# respectively (the second one describes Unity’s component system), their discussion of the principles was very helpful for me in understanding the issues raised in this thread.

http://en.m.wikipedia.org/wiki/Composition_over_inheritance

http://www.udellgames.com/posts/entity-component-systems/

Quick review of Game Programming Patterns by Robert Nystrom

One more reading link. This one is excellent. It’s an entire book about software architecture (it’s called game programming patterns, but everything here is applicable to other coding projects). It’s free to read online, but I think I’m going to purchase it because it’s very good. This link is to the chapter on components, but the entire section on decoupling is relevant to this discussion, as are many of the other chapters (in fact, the entire book could be said to be about various strategies for decoupling, one way or another, ie the early chapters on the observer pattern and the command pattern). The examples are in C++ (I think?) which I don’t read, but the discussion still makes sense for me. It’s very engagingly written, and as a plus, the pages themselves are beautifully laid out (I really like the way footnotes are to the side of the main text body).

http://gameprogrammingpatterns.com/component.html

Check it out if you don’t already know it.

Thanks for the link. The book looks great, will read it.

@yojimbo2000 wow small world, I already have that book! I agree, it’s a great book, but make sure you know at least a little C++ or C before going into it so you are more likely to be able to use the examples in your own projects.

Good point, and good excuse to learn C++.

Haha yeah, that and Arduino.

arduino uses C

@TheSolderKing @Jmv38 One of the things I find valuable about the book is that he makes an argument that coders should tightening up our terminology slightly, so that we can describe our coding patterns to others more accurately without causing confusion. For instance, if you compare the chapter on Events to the one on Observers, he argues that “Event system”, “event manager” etc should be reserved for systems that cause an action to be held in a queue and triggered at a later point in time (ie decoupling over time). So what I’ve been calling my “event manager” so far, is not, according to Nystrom, an event manager. Because it triggers actions instantly, it’s actually an Observer pattern (if we follow the nomenclature that Nystrom argues for).

good point. Thanks.

Is there a way to wrap every function we write in our classes with that thing in LUA that let’s you pause execution of functions? I know you can’t do multi threading in codea, but this would be a means to say “execute 200 lines, then run whatever is in the event queue”. Does that make sense? There’s gotta be a way for codea to read a project tab, if you can save Project info to tab. Maybe write something in the first tab which should contain Main () and setup () and have it read every other tab and wrap each function in the other tabs with that thing that can pause instruction execution.

That would be possible. But it may clutter the memory is you have too many threads.
You would have to add in every function a call to a function that yields if the condition object.n>200 is true. Better to use os.clock>object.t0+0.001 or so.

About reading the Game Patterns book:
I have a problem with the state pattern: making a new class for each state of an object seems so… heavy? can anyone explain me what i am missing here?
http://gameprogrammingpatterns.com/state.html

Thanks!

One of the things I like about the book is that he isn’t particularly evangelical; he presents a range of different methods and implementations and is quite upfront about the shortcomings of different scenarios. So a full class-based FSM or hierarchical or stack based machine might be overkill for certain objects in the game (I’ve used this for the state of the entire game, though, game, game_over, splash_screen etc).

I suppose I would rather have lots of smaller classes than a few giant ones. For one project I’m working on a component system (based on his chapter on components) where each component in the game object is a class. To balance things out though in the complexity stakes, all objects in the game belong to a single class. So you have very simple, almost empty objects. I guess its method-oriented rather than object-oriented programming (I’ll post it at some point).

For AI behaviour, which I guess I’ve implemented as a kind of FSM, I use closures. Lighter and simpler than a full blown class, but with many of the benefits (remembering their internal variables, modularity etc). He also suggests, if you don’t need to remember variables, using virtual methods. This is something I haven’t really explored that much yet, but I guess you would implement it something like this: (EDIT added a second method and a state pointer to switch between 2 methods upon touch)

--# Main
-- Game object finite state manager using virtual methods
--touch screen to switch states
function setup()
    anInstance = MyClass{pos=vec2(WIDTH,HEIGHT)*0.5} --i didn't know til recently you could do this. () not needed if argument is just a table or a string. 
end

function draw()
    background(0)
    anInstance:update()    
end

function touched(touch)
    if touch.state == BEGAN then anInstance:setMoveState() end
end

virtual = {} --just a table, doesn't need to be a class

function virtual:move(t) --use the colon : syntax when defining method, so it can access self
    self.pos = self.pos + t.vel
end

function virtual:wave(t)
    local y = math.sin(self.pos.x/20)
    local x = -t.vel.x
    self.pos = self.pos + vec2(x,y)
end


--# MyClass
MyClass = class()

local states = {virtual.move, virtual.wave}

function MyClass:init(t)
    self.pos = t.pos
    self.state = 0
    self:setMoveState()
end

function MyClass:update()
  --  virtual.move(self, {vel = vec2(1,0)}) --nb have to use dot method with self as first argument when calling method
   -- self.move(self, {vel = vec2(1,0)}) --this works too
    self:move{vel = vec2(1,0)} --this is easiest
    ellipse(self.pos.x,self.pos.y, 30)
end

function MyClass:setMoveState()
    self.state = self.state + 1
    if self.state > #states then self.state = 1 end
    self.move = states[self.state] --is this an fsm pointer? a shallow copy? a mix-in?
end