# Paddle moved by gravity, elegance and passing vectors.

This is a little class I made today, I am wondering if anyone has any suggestions to streamline, etc. Also Lua is new to me and I am having trouble passing vectors to functions and using them in the functions. Any explanation on that would also be welcomed. And lastly a huge thank you to this forum, the wiki, and David Such’s tutorial for helping me get going!
Here is the Main “Class” (Are we calling them classes?)

``````function setup()
pColor = color(67, 132, 128, 255)
watch("Gravity.x")
watch("Gravity.y")
end

-- This function gets called once every frame
function draw()

background(0, 0, 0, 255)
rect(WIDTH/2,HEIGHT - 20, 80,15)

end

end
``````

And here is the Paddle class

``````Paddle = class()
-- Josh Knox
-- 01/01/13
--
-- This is a paddle class that moves based on gravity.
-- I would like to hear any suggestions as to the 'elegence' of the code.
--
-- I wanted to pass in posx and posy as position (vec2) but kept getting an nil error?
-- And self.pos.x doesn't seem to work
-- Anyone know why or how to pass in vector properly?

self.pWidth = pWidth
self.pHeight = pHeight
self.posx = posx
self.posy = posy
pos = vec2(posx,posy)
size = vec2(pWidth,pHeight)

self.pColor = pColor
end

checkGrav()

fill(pColor)
-- I really don't like having some of the varables self.blah or others not.
rect(pos.x,pos.y,self.pWidth,self.pHeight)

end
-- It just feels like there are alot of 'if's in this function...any ideas?
function checkGrav()
-- This function checks boundaries first to avoid 'bouncing' on the edges
if pos.x >= 0 and pos.x <= WIDTH - size.x then
if Gravity.x > 0 then
pos.x = pos.x + (20 * Gravity.x)
end
if Gravity.x < 0 then
pos.x = pos.x - (-20 * Gravity.x)
end
end

if pos.x < 0 then
pos.x = 0
end

if pos.x > WIDTH - size.x then
pos.x = WIDTH - size.x
end
end

-- Codea does not automatically call this method
end
``````

Passing vec2 to a function works fine. If you still cant do it, post your code that does not work and sby will tell you where you get it wrong.

``````function passMeAvec2(v)
print(v)
end
``````

The main issue that I see in your code is a confusion between the various types of variable. These are:

1. Global variables
2. Local variables
3. Instance variables

(These also apply to functions.)

Local and global variables are straightforward: a variable has a scope wherein it is defined and has meaning. Outside that scope, it is inaccessible. Unless otherwise stated, a variable has global scope in that it has meaning for the entire program. But a variable that is declared using `local` has scope only for the block in which it is defined.

(Where this can get slightly confusing is with reuse of variable names. So there can be variables with the same name but with different scopes. The rule is that the most recent declaration wins and all others are hidden.)

In your code you didn’t actually have any local variables so we’ll skip over that and pass to instance variables. When working with objects you can define variables that are bound to a particular instance of that object. In your code you have one object, `Paddle`, and one instance of that object, `paddle`. So `paddle` might have some attributes that are set for it (such as its position, size, colour) that could be different for a different instance of that object. If you had two paddles they could have different sizes. These are stored as instance variables and are prefixed with the word `self`. So in your code, `self.posx` is an example. Thus if you create two paddles, you can safely assign different positions to each.

However, in your code then not all things that should be instance variables are so. In particular, `pos` is a global variable. This means that if you had more than one paddle, all would be trying to use the same `pos` variable to store their position. This would cause chaos: each would be updating the same variable instead of their own position variables. So `pos` needs to be `self.pos`.

A similar story holds for functions. The `checkGrav` function should really be an instance function because it modifies instance variables. What it does to one paddle will be different to what it does to another paddle. The way to do this is to make it a method by defining it as `Paddle:checkGrav` and calling it as `self:checkGrav` (from within `Paddle:draw`, or `paddle:checkGrav` from the main program). What this does is to ensure that within that function call, the variable `self` refers to the instance of the object that is calling it. This means that `self.pos` now refers to the position of the paddle that is invoking the `checkGrav` routine.

Here’s my version of your code with the above put in place. As you see, I could pass in vectors with no problem so I don’t know what was causing the difficulties there. I also reduced the number of `if`s in the `checkGrav` routine since you were doing the same thing on the inner `if` (the check for `Gravity.x`: `-(-20*Gravity.x) = 20*Gravity.x`). The first `if` in that routine could skip the check but this would be an optimisation step: I don’t know if doing the `if` makes it faster than always updating `self.pos` and correcting for endpoints afterwards.

``````function setup()
pColor = color(67, 132, 128, 255)
watch("Gravity.x")
watch("Gravity.y")
end

-- This function gets called once every frame
function draw()

background(0, 0, 0, 255)
rect(WIDTH/2,HEIGHT - 20, 80,15)

end

-- Josh Knox
-- 01/01/13
--
-- This is a paddle class that moves based on gravity.
-- I would like to hear any suggestions as to the 'elegence' of the code.
--
-- I wanted to pass in posx and posy as position (vec2) but kept getting an nil error?
-- And self.pos.x doesn't seem to work
-- Anyone know why or how to pass in vector properly?

self.pos = pos
self.size = size
self.pColor = pColor
end

self:checkGrav()

fill(self.pColor)
-- I really don't like having some of the varables self.blah or others not.
rect(self.pos.x,self.pos.y,self.size.x,self.size.y)

end
-- It just feels like there are alot of 'if's in this function...any ideas?
-- This function checks boundaries first to avoid 'bouncing' on the edges
if self.pos.x >= 0 and self.pos.x <= WIDTH - self.size.x then
self.pos.x = self.pos.x + (20 * Gravity.x)
end

if self.pos.x < 0 then
self.pos.x = 0
end

if self.pos.x > WIDTH - self.size.x then
self.pos.x = WIDTH - self.size.x
end
end

-- Codea does not automatically call this method
end

``````

Thank you so much Andrew!

I think my problem with passing the vec2 was that you don’t have to declare a type for most variables in Lua. (Are the vectors we use in codea specific to codea?)

And thanks for the explanation of scoping, and class methods. I understand these concepts, but its just a matter of applying them in our environment.

Thanks again! I am off to try out these changes!

The vectors are a “userdata” and thus special to Codea - but only in that the code that deals with them is compiled in to the binary and thus faster than if defined in pure lua. You could emulate them in pure lua quite easily.

The thing to remember about functions and variables in lua is that everything is a pointer and so there are no types to declare: at the time when the variable is passed, lua does not know or care what the eventual type will be.