What am I doing? :- /

BlitzMax Forums/BlitzMax Beginners Area/What am I doing? :- /

Amon_old(Posted 2004) [#1]
Using OOP code can someone show me how to create a moving player?

ie, moving, jumping ect.

I know how to code it without OOP but have no clue how to do it with OOP code.

strict


global mrrobot = loadanimimage("gfx\mrrobot.png",45,64,0,16,MASKEDIMAGE) ; setmaskcolor 255,255,255


type robot
	
	field x:int,y:int,s:int,g:float,h:float
	
		method init(x,y,s)
			
			x = 200
			y = 300
			s = 5
			g = 1.5
			h = 10
			
			
			
			return init()

		End Method
		
		function update(x,y,s)
			
				if keydown(KEY_LEFT)
					x = x - 2
				elseif keydown(KEY_RIGHT)
					x = x + 2
				EndIf
				
				if keyhit(KEY_SPACE)
						
					y = y - h
					h = h + g
						
				EndIf			
			
				if h = 0 then h = 10
			
		End Function
End Type

global r:robot = robot.init()

Graphics 640,480



I dont even know if the above will work. I tried compiling, got a black screen then went back to the protean IDE.


flying willy(Posted 2004) [#2]
Hi :)

you still need a normal while/wend main loop, and will have to call r.update() once every loop...


Amon_old(Posted 2004) [#3]
Yep, I know that bit. I'm just thinking if I'm going about the whole thing correctly.

Is the method() ok?
Is the function ok?

Am I correct in the way Im trying to code this?

Is this all OOP is, Just putting everything inside a method or a function and calling it from within the main loop?

Is it natural for there to be less code inside a main loop now that we have OOP ways of coding?

A lot of questions there, I hope you don't mind answering them.

Thx for the help anyway :)


flying willy(Posted 2004) [#4]
I'm still learning myself - haven't got much clue. I hope to get dirty with it but what with xmas looming, I've no time for me.

I do know that it is very natural to have your functions inside types now - and it is a very OO way of doing things. I like to think of them as little self contained machines of data and code.

OO is also about porting, and as you can imagine, it ports well when treated like that.

I'd like to know when to use methods and when to use functions though! I mean what is the difference?


Perturbatio(Posted 2004) [#5]
I'm tired, so I may be rambling a bit:

A function is global to the type rather than the instance of that type, it can be called without there being an instance of the type, which is why it's handy for Creating the type.

i.e.
type TmyType
    Field _Count:Int
    Field _X,_Y:Int

    Method Reset() 'this cannot be called until a type has been instantiated, and then it is only local to the type.
      _X = 200
      _Y = 200
      _Count = 0
    End Method

    Function Create:TmyType(x,y,count)'create a new instance of this type and return it
    local temp:TmyType = new TmyType
        temp._X = x
        temp._Y = y
        temp._Count = count
    return temp
    End Function
End Type
global myNewType:TmyType = TmyType.Create(10,10,100) 'this works fine
global myNewType2:TmyType
myNewType2.Reset() 'this will not work since myNewType2 is still null (it has not been instantiated).



flying willy(Posted 2004) [#6]
Thank you, that got my code working and made me understand at last that functions in types operate outside and on the type and methods are lil fings inside each instance.


FlameDuck(Posted 2004) [#7]
Is the method() ok?
Is the function ok?

Am I correct in the way Im trying to code this?
No and no. Sorry. It depends on what you want to do really. First of all, the init method takes 3 parameters, which it never uses. Second of all, it would be better IMHO to split Update() function into 3 different methods. An Update() method that actually does the math, and Jump() and Move() methods, that change the required variables, and then to have your input handler (the KeyDown calls) in your main loop, which would then look something like this (not tested):
Const LEFT = -2
Const RIGHT = 2 
Local r:Robot = new Robot
r.init
While Not KeyHit(KEY_ESCAPE)
  If KeyDown(KEY_LEFT)
    r.move(LEFT)
  ElseIf KeyDown(KEY_RIGHT)
    r.move(RIGHT)
  EndIf			

  If KeyDown(KEY_SPACE)
    r.jump()
  EndIf			
End While
Is this all OOP is, Just putting everything inside a method or a function and calling it from within the main loop?
No. OOP has many more possibilities than so. Search Google for 'Software Design Patterns' for a rough idea of some of the rather complex problems that OOP allows us to solve relatively simple.

Is it natural for there to be less code inside a main loop now that we have OOP ways of coding?
Yes. One of the big mantras of OOP is encapsulation, acheived through the principles of high coherency and low coupling. This means that one of your overall design goals should be to ensure that each type has a very specific responsability, and as few dependancies as possible. Break the problem into it's smallest components, and solve them one at a time - that way you get truely reusable code blocks, so you never have to start from scratch whenever you start a new project.


flying willy(Posted 2004) [#8]
If it's very specific, then arguably for most of the game it'll need to be new code... unless you are writing an application which commonly needs data handling and so forth...

I am trying to embrace it but it does seem overkill for some things.


FlameDuck(Posted 2004) [#9]
If it's very specific, then arguably for most of the game it'll need to be new code.
You misunderstand. It's not about writing very specific code -- it's about assigning a type very specific responsability.

Most of the game will probably need new code regardless, but when was the last time you wrote a function to store and retrive highscores persitently? Imagine that being expanded on.


Perturbatio(Posted 2004) [#10]
Bear in mind if you extend a type with a create function (as in my example), you will probably need to make a new create function for it, otherwise, you will be creating instances of it's parent rather than the one you want.


PetBom(Posted 2004) [#11]
Is this all OOP is, Just putting everything inside a method or a function and calling it from within the main loop?


No. I'd say OOP has very little to do with actual technique. OOP really is a different way of thinking about programming. It's more of a mindset. You can use an OOP capable language to create procedural code, that uses none of the key concepts of OO. To quote Allen Holub:


• People think that Object Orientation means objects,
classes, design patterns, UML diagrams, Java/C++,
etc.
• They’re wrong!
• OO is all about process!



Read his massive (and in my mind extremely funny) presentation on Object-Oriented Design which should give you an idea about what I mean with having an OO mindset. In the piece he really goes to town with some of the myths surrounding OO.

*EDIT*
Also read Marks excellent Intro to OO in the new BlitzMax>Tutorials forum.

//PetBom


AaronK(Posted 2004) [#12]
To add to Perturbatio's good explanation. It looks like in your init() you're wanting to return an object, because later you go robot.init() and assign that to a variable. For that to work, you must have an object to return. So in your init() function you need to new a new robot, and then initialise that object. As Perturbatio said, it's be something like

local newRobot:robot = new robot

Then initialise it with

newRobot.x = x
newRobot.y = y
etc, etc

THEN, you have to return it to the calling function (In this case your main program) by going

return newRobot

That would make the line

Global r:robot = robot.init()

Work as you intend. init() creates an object and then returns it to the line above

ASIDE: Your init() method should be a function instead because methods need objects to work on, but the point of your init() is to create an object - there isn't one at that point - so that won't work.


Aaron


ImaginaryHuman(Posted 2004) [#13]
Could somebody explain in simple terms what is the benefits of having a piece of code attached to a piece of data? Does it just come down to making it easier to think about things in terms of objects? Like, if I have 50 enemies on the screen, why would I necessarily want all of them to hair their own piece of duplicated code, rather than a single separate function to do stuff to them? Is it faster?


FlameDuck(Posted 2004) [#14]
Does it just come down to making it easier to think about things in terms of objects?
No that's just a nice bonus.

Like, if I have 50 enemies on the screen, why would I necessarily want all of them to hair their own piece of duplicated code, rather than a single separate function to do stuff to them?
Because they're different? There's that, or "Bad design decisions".

One of the most useful aspects of OOA&D is polymorphism. A scary buzzword compliant concept. It involves several different types that all implement the same interface (Blitz doesn't really support interfaces yet, but you can use Abstract methods instead - an abstract method is one that is not implemented in this type, but must instead be imlemented by the sub-class). Now all your enemies on-screen have some identical behavior, like move and shoot for example. So if you make a type that has abstract move() and shoot() methods, you can ensure that regardless of actual implementation the move() and shoot() methods will be implemented by all objects that extend that interface, thus you can itterate through them all simultaneously and have them all execute different move algorythms, from within the same loop without having to go Select alien.type etc...

Why else is this useful? Well one example is the Template Method Pattern which allows you to "Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure."

Now there's nothing new here, this is something you've done a million times over already, I'm sure. The difference here is that now it's being handled by the computer, rather than a hornets nest of If..Then..Else and/or Select..Case statements. It makes for more readable and manageable code.

Is it faster?
Nope. Actually it's technically slower, but not significantly so. The advantages by far out weigh the performance hit you might get.

I know as an ex-Amiga programmer it's hard to come to terms with not writting uber optimised code. Usually it's about striking a balance between making it fast, and making it managable, and so far processor speed is way ahead of human capacity to organize efficiently, and is increasing much faster than we are. Thus the side-effect is, we get less optimised code, but it crashes less often, and when it does we don't risk breaking something else while trying to fix it.

In theory. :o>


AaronK(Posted 2004) [#15]
Take a look at my Loderunner clone in the Showcase forum. I use polymorphism for moving. There is a base (Super) class called Human which implements stuff common to Enemies and Players, namely how to move based on it's direction and speed. Now that code is used by both enemies and players. Then there is an abstract method that use used to decide on where to move. All humans need to decide where to move, it's just that Enemies and Players do it differently. Players get their input from the keyboard, Enemies need to think about where to move, and in my Loderunner clone, that means they use A* to find a path. The results of the movement decision is a set of "state" that all humans share telling the human where to try to move to. Then in the actual move part, any common stuff is handled (Banging into sides, being able to walk up or down, moving along the bar, falling etc) and then specialisations of movement for the specific Humans. For instance, enemies when they've fallen into a hole, must not fall throgh it and wait. Humans can fall through holes if there is nothing below them.

OO is a paradigm, you can implement a lot of it with procedural functions, just passing in objects to the functions, but once you understand and use it a bit you see that it's very helpful in keeping your code together.

Inheritance is nice, because you can have methods, functions etc that take base class types and know how to handle derived classes automatically. As Mikkel said if you were using procedure stuff, you might have to do something like:

Select object.type
case enemy
MoveEnemy(object)
case human
MoveHuman(object)
End Select


With OO you would just go

object.move()


Another example in my Loderunner stuff is that I have a distance function type that knows how to calculate distances between two 'positions'. Now my AStar stuff just knows about that base type and calls a method for getting distance, but I can now derive different functions and ways of finding distances, and my AStar code doesn't have to change - at all cause I just pass it in a different function to use, as an object.



Aaron


ImaginaryHuman(Posted 2004) [#16]
Hmm, okay, interesting. Strangely I've had to rewrite this response comment several times for several reasons. Correct me if you think I'm wrong or I am not grasping this.

I can see how procedural code in general has a very fixed structure and although it can jump around based on various conditions it is still a pretty fixed model. Things flow in one direction, they have to go through specific pathways, everything has to be pre-thought-out and preconceived. Then all of those preconceptions are solidified into a hard-wired program, and of course the lower-level you get the more that is true because at the lowest level everything is very rigid and fixed.

Then you have this `orientation` of looking at things in a more individualized manner, which we happen to call things objects, where you try to decouple some of the functionality from being so locked in to a fixed structure. You try to go from a totally linear world to more of a non-linear world where you don't have to do everything in these fixed sequences in order to directly access the appropriate objects or get specific objects to do certain things. Objects give you more freedom to kind of move from a linear forwards-executing structure to a more non-linear structure of program excecution. And since we tend to think of things in the world as confined objects it's probably easier to map worldly imaginings onto an object-oriented view of things. Instead of there being one `center` to the program, there are now multiple cores (objects) each relatively individual and independent and able to go about it's business. I guess that's a step in a better direction.

But what beyond that? What is beyond that separation between objects? What about a model where objects are not so definitely separate from each other and can merge and un-merge at will? (yeah, object nookie ;-) What about objects that are sometimes objects and sometimes everything, like electrons that come in and out of finite existence? What about every object having an underlying unity through which they all share common ground? Isn't that an even more useful and realistic model than traditional OO? I don't want all my objects to be lonely little objects. No man is an island. ;-)


BlitzSupport(Posted 2004) [#17]
Alternative OO mantra: don't listen to FlameDuck -- just do what works.

There's no correct way to program. If it works, it's correct!

(Giggles and runs away.)


AaronK(Posted 2004) [#18]
I think OO programming is something a lot of us do within a procedural context without even knowing it. Before I'd even heard of OO development, I was implementing what I know now as virtual functions for my objects, in assembler on the Amiga. I think with games, after doing a few you soon realise that things fall into this paradigm easily and you tend to move in that path without knowing it. Having a language with this constructs built in, makes the job easier to implement. OO languages are just a tool for OO development, they aren't OO development in and of themselves.

Aaron


FlameDuck(Posted 2004) [#19]
But what beyond that? What is beyond that separation between objects?
To better answer that I refer you to Brucke Eckels book Thinking in Java which although obviously written for Java, has an excellent introduction to OO principles in the first couple of chapters, and much of it applies equally well to BlitzMAX.

Excerpt:
All programming languages provide abstractions. It can be argued that the complexity of the problems you’re able to solve is directly related to the kind and quality of abstraction. By “kind” I mean, “What is it that you are abstracting?” Assembly language is a small abstraction of the underlying machine. Many so-called “imperative” languages that followed (such as FORTRAN, BASIC, and C) were abstractions of assembly language. These languages are big improvements over assembly language, but their primary abstraction still requires you to think in terms of the structure of the computer rather than the structure of the problem you are trying to solve. The programmer must establish the association between the machine model (in the “solution space,” which is the place where you’re modeling that problem, such as a computer) and the model of the problem that is actually being solved (in the “problem space,” which is the place where the problem exists). The effort required to perform this mapping, and the fact that it is extrinsic to the programming language, produces programs that are difficult to write and expensive to maintain, and as a side effect created the entire “programming methods” industry.

The alternative to modeling the machine is to model the problem you’re trying to solve. Early languages such as LISP and APL chose particular views of the world (“All problems are ultimately lists” or “All problems are algorithmic,” respectively). PROLOG casts all problems into chains of decisions. Languages have been created for constraint-based programming and for programming exclusively by manipulating graphical symbols. (The latter proved to be too restrictive.) Each of these approaches is a good solution to the particular class of problem they’re designed to solve, but when you step outside of that domain they become awkward.

The object-oriented approach goes a step further by providing tools for the programmer to represent elements in the problem space. This representation is general enough that the programmer is not constrained to any particular type of problem. We refer to the elements in the problem space and their representations in the solution space as “objects.” (You will also need other objects that don’t have problem-space analogs.) The idea is that the program is allowed to adapt itself to the lingo of the problem by adding new types of objects, so when you read the code describing the solution, you’re reading words that also express the problem. This is a more flexible and powerful language abstraction than what we’ve had before. Thus, OOP allows you to describe the problem in terms of the problem, rather than in terms of the computer where the solution will run. There’s still a connection back to the computer: each object looks quite a bit like a little computer—it has a state, and it has operations that you can ask it to perform. However, this doesn’t seem like such a bad analogy to objects in the real world—they all have characteristics and behaviors.


I don't want all my objects to be lonely little objects. No man is an island. ;-)
Yeah you do. One of the great things about having 'atomic' objects is that it becomes very easy to test whether an object works (or not).

Besides you'll never get truely 'atomic' objects anyway, there will be co-dependant objects in any program, but by minimising this you create a program structure that is easier to maintain, and you can restrict rewrites of code to isolated objects, and still have a working program.

Instead of having to test your entire program at once, and praying it works, you can now test each individual parts functionality individually of other parts (unit test).

There's no correct way to program. If it works, it's correct!
Ofcourse. OOP is not about programming more correctly (after all, OOP is nothing but an abstraction). OOP is about programming smarter, letting the compiler handle many of the issues you might otherwise have to deal with manually.


AaronK(Posted 2004) [#20]
Yeah you do. One of the great things about having 'atomic' objects is that it becomes very easy to test whether an object works (or not).


Wider words have never been spoken. Unit testing is relatively new concept to me. I've managed to be a developer for yers without it. In the last couple of years though I have been pulled into this ideology and I must admit, while it seems at first to be a lot of work for nothing, the end result is very worth while. Especially down the track when you then realise that the maintenance you are doing on your software, and classes is minimal comnpared to what you used to do.

Also of course, these tests can be automated in most cases, so a build system is created to keep your code compiling and working consistently.

That makes me think...Maybe someone needs to design a nice unit testing framework for BlitzMax...I'll have a think about that.

Aaron


ImaginaryHuman(Posted 2004) [#21]
Hmm, ok, but what is beyond OO?


Hotcakes(Posted 2004) [#22]
Mind probe?


FlameDuck(Posted 2004) [#23]
Hmm, ok, but what is beyond OO?
They tell me it's 'Aspect Oriented Programming'.


BlitzSupport(Posted 2004) [#24]
Don't listen to 'em, Flamey!


ImaginaryHuman(Posted 2004) [#25]
Aspect oriented? :-)


AaronK(Posted 2004) [#26]
Yeah aspect, you know like pixel aspect ratio. If a pixel aspect ratio is 1.2 then it's 1.2 times as wide as it is high. With Aspect Oriented Programming, you widen your IDE and type longer lines, so there is less of them.


I HAVE NO IDEA!


Kanati(Posted 2004) [#27]
I *really* suggest you edit your post before the gestapo comes along and sees that Aaron. He hands out 1 week vacations from the forums for that kinda thing. But yer new... He'll probably just restate the rules this once. :)


GfK(Posted 2004) [#28]
I agree with Kanati. No room here for toilet-mouths.


Hotcakes(Posted 2004) [#29]
POO!


FlameDuck(Posted 2004) [#30]
No, it's POOH! Silly...


JAW(Posted 2004) [#31]
Thanks for the OO info guys. Most of the thread *ahem though I am tempted to join in the offtopicness* helped me understand some of the concepts a bit better. Flameduck THANK YOU. I've been looking for "Software Design Patterns" for a while but I didn't know exactly what they were called. I think I spent half a day on google searching similar words without finding much of anything.

I don't know why but I just bought BlitzMax (don't have a Mac) so I can start posting in the forums and looking at docs. I guess it's so I have BlitzMax (OH YEAHHH) now instead of spending the christmas money on say..food to keep me nourished. Thinking in JAVA can be downloaded for free. Check it out blitz dudes. I'll see what I can absorb from those first chapters
http://mindview.net/Books/DownloadSites/


Hotcakes(Posted 2004) [#32]
Hey JAW, have a close look at the very last forum on the BlitzMax forums page! ;]


JAW(Posted 2004) [#33]
BlitzMax Bug Reports? If you mean about the Windows Beta, I know. It's sitting on my desktop but I havn't gotten to it yet. I'm still recovering from some sickness and I'd rather just read up on some stuff at the moment. Reading makes my brain feel good.

**edit* ah firefox was messing up and not displaying the whole page for some reason. I just installed the latest daily build and it's ok now. Yeah the Betas forum...that's where I d'l it of course :)**