# Functions and multiple outputs

#### Wingnut

##### Well-known member
3rd Party Module Dev
Tutorial Author
I wonder why Eachin did that though. Maybe there's internal optimization and it assumes what the target is.
Be careful with Eachin, I'm not fond of it so I might have missed some detail about it but I've looked through the code this evening and can't find what could possibly be doing that.

I just do a normal FOR NEXT loop and the problem is gone.

#### Wingnut

##### Well-known member
3rd Party Module Dev
Tutorial Author
Seems to work

It might seem unusual to have data and code separate instead of methods but it will be helpful
when things grow.

Code:
``````Strict
Import mojo2
Const n:Int = 100
Global test:xy = New xy

Function Main:Int()
New Game()
Return 0
End

Class Game Extends App

Field canvas:Canvas
Field Obj:xy[n]

Method OnCreate:Int()
canvas = New Canvas() ; SetSwapInterval 1 ; SetUpdateRate 0
For Local i := 0 Until n ; Obj[i] = New xy ; initxy(Obj[i]) ; Next
Return 0
End

Method OnRender:Int()
canvas.Clear
For Local i := 0 Until n
canvas.DrawRect Obj[i].x,Obj[i].y,Obj[i].size,Obj[i].size    ' Draw

Obj[i] = movexy(Obj[i])                                ' Update

Next
canvas.Flush
Return 0
End

End

Class xy
Field x:Int
Field y:Int
Field vx:Int
Field vy:Int
Field size:Int
End

Function initxy:xy(p:xy)
p.size = 1 + Rnd(40) ; p.x = Rnd(640-p.size) ; p.y = Rnd(480-p.size)
p.vx = Rnd(1,4) ; If Rnd(1) >= 0.5 Then p.vx = -p.vx
p.vy = Rnd(1,4) ; If Rnd(1) >= 0.5 Then p.vy = -p.vy
Return p
End

Function movexy:xy(p:xy)
p.x = p.x + p.vx
If p.x < 0 Or p.x > (640-p.size) Then p.vx = -p.vx
p.y = p.y + p.vy
If p.y < 0 Or p.y > (480-p.size) Then p.vy = -p.vy
Return p
End``````

Last edited:

#### SLotman

##### Active member
3rd Party Module Dev
My first reaction was to do it in the WORST way possible!

Code:
``````Function TransformXandY:float[](wX:float, wY:float)
local s:float[2]
s[0] = (wX - 10)
s[1] = (wY - 10)
return s
End``````

#### Gerry Quinn

##### Active member
Tutorial Author
That's not a particularly bad way of doing it, IMO. You have a const method that returns a tuple and you avoid polluting your namespace with a return POD class. It's a useful tool to have in your repertoire anytime you are doing something like this that's not going to be all over your code. Even when it's something that may well end up refactored away.

Then again I've been know to return arrays of arrays, stacks of stacks, or a combination...

#### Podge

##### Member
Hey Jimmy,

I don't understand this:

Global test:xy = New xy

What does this do and why? What is xy? Howcome it is not declared as say an Int or a Float? What does "New xy" do?

I'd really appreciate if you could just give me an idiots explanation. I really don't get this type of programming. What the hell is xy? How does the compiler know what it is?

Global a:Int = 0 , that I get. What is xy and a New xy. And y

Cheers,
Podge.

PS: I am a qualified blacksmith and welder. If you have any stupid questions about those topics I would be happy to try and answer them

#### Wingnut

##### Well-known member
3rd Party Module Dev
Tutorial Author
No worries I'll try my best to explain!

Cerberus has a few handy types inbuilt such as Int, Float, String, and Bool. You know those already and each allows you to do what they do best.

But you can also grow your own type and that's what I do here:

Class xy
Field x:Int
Field y:Int
Field vx:Int
Field vy:Int
Field size:Int
End

To make one for youself you use types that already exist, in this case it's just a bunch of ints.
xy is just a name that I picked, much like int or string or pacman, and it could be anything. I picked xy because I first used it only to represent a 2d coordinate and to me it sounded good. A better name for this would have been "point" perhaps. As you see I added more stuff with time.

The reason that I defined a type named xy was becuase this allows me to talk about about these variables as a group and make the code simpler and more clear. You need to be a bit more wordy though when you use your own defined types, compared to the inbuilt ones. This is what makes it hard to grasp, becuase it looks so different even though it is not.

An int or string could be created simply like this:
Local a:Int
Global a:String

Global or local here tells where you can access the variables, it's the "scope" of the variables.

A customized type though needs a longer definition:
Global test:xy = New xy

Notice that the only additional word compared to primitive ones is "New xy" and that this might strike you as redudant as you already told the computer that you are creating a variable using Local or Global, and you've already told the type to use the type :xy. But this is how it is with non-primitives.

Look in the class and you see x y etc. That means that any variable that we assign this type now actually has all these things in it!
That means that we can access a part of it only if we want, using dot syntax like so:
test.x = 10
test.vy = 199

or we could treat it as a whole if we have same type:
test2 = test

I hope this clears things up, just ask if something is still muddy!

Last edited:

#### Podge

##### Member
No worries I'll try my best to explain!

Cerberus has a few handy types inbuilt such as Int, Float, String, and Bool. You know those already and each allows you to do what they do best.

But you can also grow your own type and that's what I do here:

Class xy
Field x:Int
Field y:Int
Field vx:Int
Field vy:Int
Field size:Int
End

To make one for youself you use types that already exist, in this case it's just a bunch of ints.
xy is just a name that I picked, much like int or string or pacman, and it could be anything. I picked xy because I first used it only to represent a 2d coordinate and to me it sounded good. A better name for this would have been "point" perhaps. As you see I added more stuff with time.

The reason that I defined a type named xy was becuase this allows me to talk about about these variables as a group and make the code simpler and more clear. You need to be a bit more wordy though when you use your own defined types, compared to the inbuilt ones. This is what makes it hard to grasp, becuase it looks so different even though it is not.

An int or string could be created simply like this:
Local a:Int
Global a:String

Global or local here tells where you can access the variables, it's the "scope" of the variables.

A customized type though needs a longer definition:
Global test:xy = New xy

Notice that the only additional word compared to primitive ones is "New xy" and that this might strike you as redudant as you already told the computer that you are creating a variable using Local or Global, and you've already told the type to use the type :xy. But this is how it is with non-primitives.

Look in the class and you see x y etc. That means that any variable that we assign this type now actually has all these things in it!
That means that we can access a part of it only if we want, using dot syntax like so:
test.x = 10
test.vy = 199

or we could treat it as a whole if we have same type:
test2 = test

I hope this clears things up, just ask if something is still muddy!
This is brilliant. Thank you for taking the time to explain this. It's a technique that I will be using. Very much appreciated!