Accessing types within functions

BlitzMax Forums/BlitzMax Beginners Area/Accessing types within functions

abelian_grape(Posted 2009) [#1]
So I did a forum search and couldn't find this anywhere else. Is there a reason why you can't use a type within a function? I've been using a book, Game Programming for Teens, and the author uses types within functions multiple times, but the code will not compile in the most recent version of BlitzMax. Perhaps an excerpt of my code will highlight my problem:

Function CheckPenguinCollisions(penguin.x, penguin.y, tree.x, tree.y)

If (ImagesCollide(penguinAnimation, penguin.x, penguin.y, 0, treeImage, tree.x, tree.y, 0))
penguin.x = 400
penguin.y = 300
EndIf
End Function

Earlier in the code, in the main game loop, I call the function CheckPenguinCollisions(penguin.x, penguin.y, tree.x, tree.y). I would like to write the function so I don't need to pass it any parameters and can just do all of my collision detection within one function. Any help is much appreciated!


_Skully(Posted 2009) [#2]
Ahh...

Unless the penguin is a global you will have to pass the penguin type to the function like this:

Function CheckPenguinCollisions(penguin:PenguinType, tree.x, tree.y)

If (ImagesCollide(penguinAnimation, penguin.x, penguin.y, 0, treeImage, tree.x, tree.y, 0))
penguin.x = 400
penguin.y = 300
EndIf
End Function


In this case penguinAnimation would have to be a global variable but it should probably be in the penguin type like penguin.animation

Cheers


Gabriel(Posted 2009) [#3]
Try

Function CheckPenguinCollisions(P:Penguin, T:Tree)
   If (ImagesCollide(penguinAnimation, P.x, P.y, 0, treeImage, T.x, T.y, 0))
      P.x = 400
      P.y = 300
   EndIf
End Function


I think that's what you wanted to do. I don't think your code would have been valid code in BlitzPlus either, but in BlitzMax the : operator is used to indicate the type of a variable where in BlitzPlus it was the . operator. BlitzMax does still use the . operator to access fields and methods, as I've done above.


abelian_grape(Posted 2009) [#4]
The code compiled but nothing seemed to happen...the penguin still passes through trees (his coordinate resets in the function is arbitrary and just to let me know it's actually doing something). Thank you for the help guys, but do you know what might cause it to not update the coordinates? Is it just treating everything as a local variable and then discarding the data when the function is done executing?


Gabriel(Posted 2009) [#5]
Well that depends on whether you're using our code or you're still using your code. In your code, you're passing in some integers by value, so nothing you do to those integers will mean anything outside that function. Parameters to a function are effectively just local variables.

EG:

Function DoSomething(X:Int, Y:Int, Z:Int)
End Function


Is pretty much the same as:

Function DoSomething()
   Local X:Int
   Local Y:Int
   Local Z:Int
End Function


Except that those variables have a value set to them when they're parameters. But still, they're local to the function.

In my code, and to a lesser extent in _Skully's code (he hasn't made tree an object, but I have) anything you do to your penguin (or your tree in my code) will stay done because the object is passed by reference and you're still dealing with the same object.


abelian_grape(Posted 2009) [#6]
I apologize, I should have been more clear. I did use essentially what you guys had just with the code updated. So my two types are TPenguin and TTree. And I also made penguinAnimation and treeImage global variables. Here is the updated code:

In the main loop:
CheckPenguinCollisions(penguin:TPenguin, tree:TTree)


In the function definitions:
Function CheckPenguinCollisions(penguin:TPenguin, tree:TTree)

If (ImagesCollide(penguinAnimation, penguin.x, penguin.y, 0, treeImage, tree.x, tree.y, 0))
     penguin.x = 400
     penguin.y = 300
EndIf

End Function



Who was John Galt?(Posted 2009) [#7]
Post complete runnable code and someone will be able to help.


abelian_grape(Posted 2009) [#8]
Well it's pretty long and the code was done piecemeal because it's my first game and first time programming in BASIC. I'd be happy to answer any questions. Thank you all for the continued help, I'm really excited about completing this.




abelian_grape(Posted 2009) [#9]
As you can see a lot of the code in the main loop could be relegated to functions if I could pass the various types (tree, penguin, driller penguin, etc.) to the functions.


abelian_grape(Posted 2009) [#10]
Any ideas?


H&K(Posted 2009) [#11]
hi,

Im not going to go through error checking you code, but some gerneral comments

You are using Types soly as variable holders, they are much much more than this. Any functin that is called (for example) MovePenguin() should really be PART of the type "Penguin", that is Method Move() inside Penguin
Penguin.Move
In this way the main passing values error pointed out by the others is nearly aways a non issue.

As a basic rule, ANY function that is being passed either a single whole instance, or a single whole instance plus a few secondary vaules shoud really be methods, and any function that is using the ALL the instances of the type (ie the iteration through the list), should be a function of that type. (And not a global function)


_Skully(Posted 2009) [#12]
Also,

Since all your "actors" have common variables you can do this:

type actor
	Global actors::Tlist=new Tlist
	Field x, y		'Penguin's x,y-coordinates
	Field vx, vy	'Penguin's velocity
	Field hp		'Penguin's hit points

	Method New()
		actors.addlast(self)
	End Method

	Method Move()
		x:+vx
		y:+vy
	End Method

	Function MoveAll()
		For local a:actor=eachin actors
			a.Move()
		Next
	End Function
end type

Type TPenguin extends actor
	Field frame		'Penguin's animation frame
End Type

Type Turtle extends actor
	Field frame		'Turtles animation frame
End Type




Who was John Galt?(Posted 2009) [#13]
I can't see anything wrong. Inside your collision function, do a cls, draw the images at their collision check positions and do a flip, then wait for a keypress. See what it shows you. I'm thinking maybe one of the images is blank or something?


abelian_grape(Posted 2009) [#14]
So I think I understand what you guys are saying in terms of turning the extraneous functions into type methods, but since I have no experience with them, on the face of it, it looks like it's not doing much else for me even if I make a general type like "actor" because every actor has different coordinates, velocities, hit points, frames, etc., so I'm curious as to what the advantage is to using this over what I have. Can anyone explain this more clearly?


H&K(Posted 2009) [#15]
Its part of the paridine of object programing.

In strickly old BAsic (say), you would go

"What does the program need to do next?"; Lets say the answer is move peguins forward.
So you would program to move all the peguins forward, then (say) you want to check which peguins have fallen in a hole.
So you program checking each penguin to see if it has fallen into a hole.
Then you want to remove the penguins that have fallen into a hole, so you program etc
Now each one of these is to you a seperate function, each function either goes tho your list of penguins, or is passed a penguin and the acts on it as needed ie moves forward etc

Now in a Object envionment you would go

"What are all the things I need a penguin to do, or have done to it?"
Well first I need it to move forward, and I need to see if it has fallen into a hole. And I need to remove it from play if it has fallen into a hole. etc
So you program the "object/class" Penguin, and you program all the things you think you might want to do to a penguin as methods. (Then you think, going thro the list of penguins really should be part of the object. So you Program a functio INSIDE the object to do this.

-----------------------------

Now what skully is saying is that a penguin is really a lot like a turtle, so he is making a sub object "actor" and has "penguin" and "turtle" inherit the things the have in common. (too be honest hes just using that as an example, and they could be the same class exactly; so when you look back dont think we are wrong, just realise we are making it simple.

What you want to do is find the most basic things all the "objects/actors" have in commom, (ie a graphic, a place on the screen, a place on the map) and make an object for that. Then anything that is different (static actor vrs dynamic for example) extend the base object


abelian_grape(Posted 2009) [#16]
Thank you all so much for the continued help and support, I'm learning so much from all of you. I think I finally got things working.