10.03.2019 - Round 1 results of our "A Love Letter For FreeBASIC" game dev competition have been published. Please be sure to check the results thread: http://games.freebasic.net/forum/index.php?topic=629.0. Don't forget that the competition is continuing with a round 2, lasting till 29th of April, 300 USD first prize. Stay tuned!

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - notthecheatr

Pages: [1]
1
Programming / Evolutionary AI
« on: August 31, 2009, 02:16:24 PM »
I remember reading about evolutionary AI ages ago but I don't know where and I haven't seen a whole lot about it.  I'm kind of interested in it and want to experiment with it.  My ultimate goal here is not a game, but merely a simulation.

The idea is to create free agents inside an environment, then have them respond and react to the environment based on electronic "DNA" which is modified over time so the agents can "evolve" to become more intelligent and work better over time.  This is applied in the game NERO (though I don't know how), and I've seen it discussed occasionally on AI websites.

My idea is to create a basic free agent object with electronic DNA which can be extended to whatever you need it for.  I want to eventually create a simulation with "dumb" predator objects and evolving prey objects which learn to become better at evading the predators.  Perhaps at some point the predators would also be evolvable so the system could produce feedback and constantly be evolving.  Anyways, that's the idea.

Does anyone have any ideas, resources, websites, code, anything relevant?

2
General Discussion / Hello there.
« on: August 28, 2009, 01:26:40 PM »
Well school just started again and I started missing you guys.

I can't promise I'm going to be anywhere near as active as I once was, but I'm back at least.  I'll be posting, maybe trying some games out (though I'm not planning to release any of my own in the near future, sorry :()

Anyways, I'm kind of back so hi guys.

4
General Discussion / WZzBzz Where have I been?!
« on: July 17, 2008, 07:01:01 PM »
For anyone who cares as to why I've been offline so long, there are a few reasons:

-Playing games and just generally enjoying summer vacation (by "enjoying" I mean "jacking off").
-Family is on a long trip.  I've been with only occasional internet access for a week and a half now.  Even now it's limited, although by Tuesday I should have plenty of internet access for the next two weeks, after which... back on the fritz.  Most of the time we're camping, except when we're at hotels for two weeks.  Anyways, I'll probably spend a lot of time playing games when I can :P

So basically, I'm mostly playing games when I have internet, and programming when I don't.  Hmm, I've been thinking of perhaps writing more fbn00b tutorials if I get the time, or something like that.  Other than that, I'll try to stay more active (and test out some or all of the games for the newest FBGD Report) but don't expect a whole lot out of me >.<  When summer vacation is over, I'll be back to school, where I'll no longer be able to do so much gaming so it'll be back to being fairly active in the community as always.

If anyone needs to reach me for any reason, the best way is probably via e-mail, and my e-mail address is of course TheMysteriousStrangerFromMars@yahoo.com.  Other than that, I'll try to check in at the forums from time to time (as I'm doing now) and I may write some tutorials or articles for QBE or something if I get (or make) the time.

So how are you all doing?

5
General Discussion / Riddle
« on: April 25, 2008, 03:30:26 PM »
Quote
I'm something you eat
and something you do.
I'm hidden in the file below
but only if you can find me.

OK, I'm no good at poetry.  Anyways.

Below is the file which contains the answer to the riddle.  Should be pretty simple, but let's see how long it takes you to figure it out  ;)  Have fun!

6
Programming / It's finally ready!
« on: April 22, 2008, 01:38:34 PM »
The long-promised, and in some cases long-awaited, Game Resource Archive (GRA) system!  After much debugging, fixing, writing documentation and example programs, and general mayhem, I've finally decided I'm ready to release.  I may add some more things later, but I can't keep adding things forever - eventually I've got to release.  Lachie particularly wants me to release it so he can use it for his game.

So here it is at long last.  Full HTML documentation is included, as well as plenty of examples.  There is also something called selectable file system which should be especially helpful to game writers;  it allows you to switch between loading from a GRA and loading from the file system, so while testing you can load from the disk (making it easier to make modifications to important files on the fly) and when you're ready to release you can put everything in a GRA.  Note that you can also copy files from GRA to disk, which is helpful if you have text files in the GRA and you want to be able to use FreeBASIC's text file routines (Input #, Line Input #, etc.)  There are tons of features and the best way to find out about them is to download the whole thing.

Enjoy!  Any bug reports/suggestions/requests/comments/etc. should be posted here.

http://notthecheatr.phatcode.net/downloads/gra.zip

7
General Discussion / Does this not rock?
« on: April 01, 2008, 09:51:59 AM »
http://mail.google.com/mail/help/customtime/index.html

Apparently there's a big debate over the ethics of this one, but I think the feature rocks and will start using gmail more now.  Shweet!

8
Programming / Probability Machine
« on: March 10, 2008, 12:32:58 PM »
(originally posted at http://www.freebasic.net/forum/viewtopic.php?t=10882)

This is a simple but hopefully useful probability machine.  Its main use would probably be in game AI systems, but it can be used for a lot of things.

This is an object that provides a simple way to do probability simulations and such.  It comes with documentation and an example.  I've spent all morning working on it, but I can't guarantee that there are no bugs left in it - if you find anything let me know.

http://notthecheatr.phatcode.net/downloads/ntc_AI_pm.zip

Coin-flipping Example:
Code: [Select]
''
''
'' ntc.AI probability machine - coin-flipping example
''
''

#Include "ntc/pm.bas"
Using ntc.AI.pm

Randomize Timer

Dim As pmObject probMachine = pmObject()

'Store how many times heads or tails is chosen
Dim As uInteger ht (1 To 2)

'How many times to flip?
Dim As uInteger numFlips

'Add two choices, each with a 50% chance
probMachine.addChoice(0.5)
probMachine.addChoice(0.5)

'Find out how many times to flip the coin
Print "How many flips do you want?"
Input numFlips

'Flip that many times
For i As uInteger = 1 To numFlips
  'We add 1 to the index because choose() returns 0 or 1.
  ht(probMachine.choose() + 1) += 1
Next i

'How many times was each chosen?
Print "Heads:  " + Str(ht(1))
Print "Tails:  " + Str(ht(2))

'Experimental probability
Print Str(ht(1)/numFlips)
Print Str(ht(2)/numFlips)

Sleep

9
General Discussion / BEST SITE EVAR?
« on: February 28, 2008, 04:48:41 PM »

10
Programming / Macros - the pros and cons
« on: January 23, 2008, 09:21:12 PM »
This was originally going to be a reply in my "Why OOP?" topic, talking about efficiency in loops, but I decided to make it a whole topic on its own.


One interesting way to make a pretense of using procedures when in reality doing no such thing is to use macros  :D

Code: [Select]
#macro MOVE_PARTICLE_TO(particle, x, y)
  particle._x = x
  particle._y = y
#endmacro

Type pticle
  As Integer _x, _y
End Type

Dim As pticle myparticle

MOVE_PARTICLE_TO(myparticle, 0, 0)
Print myparticle._x
Print myparticle._y
MOVE_PARTICLE_TO(myparticle, 23, 42)
Print myparticle._x
Print myparticle._y

Sleep

This can be used in loops without slowing things down, since it's not really a function call at all.  The one downside is that you don't have type checking, meaning you could do really weird things like

Code: [Select]
MOVE_PARTICLE_TO("this is a string, not a particle!!!", "hi, guys!", "this is a totally invalid place to move the particle to!  it's not even a number!")
where you pass arguments that are the wrong type and get weird errors for seemingly innocent lines of code.  Even worse, the first argument to the macro can be any type that has public members _x and _y - so for example, I could do

Code: [Select]
Type myrandomthing
  As String _x, _y
End Type

Dim As myrandomthing someObj

MOVE_PARTICLE_TO(someObj, "Hello, ", "World!")

Print someObj._x
Print someObj._y

Sleep

and it will compile just fine despite the fact that the object and parameters to the macro have nothing to do with particles or even positions.  Such is the facts of life when using the preprocessor, which does nothing more than a simple string replace and converts the above code to:

Code: [Select]
Type myrandomthing
  As String _x, _y
End Type

Dim As myrandomthing someObj

someObj._x = "Hello, "
someObj._y = "World!"

Print someObj._x
Print someObj._y

Sleep

which is of course perfectly valid, if odd, code.

Despite the weirdness, macros do have their uses, and keeping things fast (while somewhat clean-looking, as long as you're careful with it) could be one of them.

11
Game Dev / Why OOP?
« on: January 23, 2008, 02:19:07 PM »
OOP might be a really nice convention for programmers to adopt when writing their big projects that they're being paid to write, but why should a game programmer bother with it?  This is essentially the question asked by someone recently rather off-topically in a discussion.  Rather than start a heated debate on the pros and cons of OOP (though there were plenty of replies and it started getting there...) I'm going to try to answer that question here.

We start with the origin of procedural programming.  In the beginning, you didn't have procedures.  You basically had spaghetti code - along with capital letters, line numbers, and all that ugly stuff:

Code: [Select]
100 PRINT "I AM A DOOF."
200 GOTO 100

Although it doesn't matter much in a small program like that, it gets to be extremely difficult in large programs.  Hard to read, etc.  Even hard to write.

So programmers somewhere, one day, decided to do this:

Code: [Select]
Do
  Print "I am a Doof."
Loop

and furthermore, they even decided to do this:

Code: [Select]
Sub printDoof
  Print "I am a Doof."
End Sub

Do
  printDoof
Loop

How very structured of them!  Now for some, it may have been easiest to stick with the GOTO's.  Amazing though it may seem, there are still some programmers who use it.  I don't know how they can write anything useful (and really try to debug, or make any modifications to it) that way, but some do.  But for the most part, programmers today have adopted much more structured syntax.  Now it's no more powerful - you can still write the exact same code with GOTOs as you can procedurally - but it's much easier for we humans to understand, debug, modify, maintenance, etc.  So we use it.

With structured programming, someone eventually figured out a rather neat idea.  You see, your Subs and Functions might tend to get kind of long:

Code: [Select]
Sub moveSprite (sprite As FB.Image Ptr, x As Integer, y As Integer, vx As Integer, vy As Integer, suchandsuch As uInteger, thisthatandtheother As Byte)
  '...
End Sub

See what I mean?  You will be passing twenty different parameters to it, and eventually you realize it would be a lot easier if you could group these parameters together.  So here comes the concept of the UDT.  Put a bunch of variables in a single structure, like a package, then send the whole thing to the Sub, which means you only have to pass one (or maybe a couple) parameters, instead of twenty.

Code: [Select]
Type myUDT
  As Integer a, b, c, d, e, f, g, h, i, j
End Type

'Which do you like better?
Sub mySub1 (param1 As myUDT)
End Sub

Sub mySub2 (a As Integer, b As Integer, c As Integer, d As Integer ...)
End Sub

But there's another factor we need to look at.  That is scope.  In the beginning, everything was global.  That means
you would create a variable for your program

Code: [Select]
110 DIM A AS STRING = "I AM A DOOF."
120 PRINT A
130 GOTO 120

and the variable would be accessible everywhere.  Of course, that was because you didn't even have procedures yet, so it was practically pointless to hide anything from any other part of the program.  But once you had procedural programming, it became useful to make variables inside procedures that weren't necessarily accessible (in fact, didn't necessarily even exist) anywhere else.  Then you could have a variable called X in your main program and a variable called X in your procedure and they would be entirely different variables, and neither could access the other.  If the main program needed to give some information to the procedure that the procedure didn't have, it could simply pass a parameter to the procedure.  But this didn't always work, so we still had some global variables lying around:

Code: [Select]
Dim Shared As Integer mynumber

Sub mySub
  Print mynumber
End Sub

mynumber = 3
mySub
mynumber = 5
mySub

Now the same variable name is the same variable whether inside the procedure or out.  And many people thought this was great, because then you don't have to have a lot of parameters passed to and from your procedures (these people didn't know about UDTs yet, of course).

But there's just a little problem.  What if you have a global variable and you have twenty different procedures that access it, maybe even modify it, and who knows what happens then?  Maybe a bank program storing the balance of an account as a global variable.  A bug is bound to happen sometime somewhere, with all that code, and you suddenly realize that the balance is off - way off.  So which one of those twenty different procedures messed it up? And remember, this is a bank program, so it's probably made up of hundreds of lines of code, each of which might potentially access the account balance.  That means hours of debugging for you.  And in case you think I'm only talking about business programs - what about games?  What if you store the sprite position x and y in global variables, you have twenty different procedures moving the sprite around and drawing it on the screen, and you suddenly notice the sprite is going all over the place on the screen and it's not where it's supposed to be?  Then what?  So which of those procedures did it?

Scope solves this.  Only certain procedures can modify certain things, so you know which procedures to check and see if they modified it - and most of them don't, because you only let certain ones do it.  So what if those procedures need to modify it?  Then you pass things ByRef, and at least now you know which one did it.  But that's not always safe, so we could run into problems there.  Enter the UDT.  It solves the problem of too many parameters, and since you pass it as a parameter to the procedures, you don't have the problems of global variables.  Everything is in its proper scope, so you have one less thing to worry about.  Unfortunately, if the procedures want to modify the variables inside the UDT, you have to pass it ByRef.  And then you can have problems that way just like with global variables, because if you pass it ByRef to everything, you'll still have twenty procedures potentially modifying variables and messing things up.  Now what?  We need more scope rules!

This is what encapsulation is all about.  You put the variables inside a UDT, but make some of them Private.  What's that mean?  That means nobody else can access those variables!  They're hidden inside the UDT, so even if I pass the UDT to a procedure, the procedure can't access those variables.  In fact, even the procedure (or main program) that creates the UDT can't access the variables:

Code: [Select]
Type myUDT
  Public:
    As Integer a
  Private:
    As Integer b
End Type

Dim something As myUDT

'This is OK
something.a = 3
Print something.a

'This is NOT OK
something.b = 5
Print something.b

But of course that begs the question who CAN access the variables?  Because if nobody can access the variable at all, then what's the point?  In a sprite, you might hide the x and y variables so nobody can just move the sprite around whenever they want.  But if nobody can access the (x, y) variables, then how does ANYONE move the sprite?  And how would we know where to draw it?

This is why we add things called methods to the UDT.  It's the beginning of OOP.  It may seem a little strange, but it really solves a lot of problems.  Now only ONE procedure can modify the sprite's position, and if there's any bugs you know who did it!

Code: [Select]
Type mySprite
  Public:
    Declare Sub move (newx As Integer, newy As Integer)
    Declare Sub draw ()
  Private:
    As Integer x, y
End Type

Sub mySprite.move (newx As Integer, newy As Integer
  x = newx
  y = newy
End Sub

Sub mySprite.draw ()
  PSet (x, y), &hffffff
End Sub

Now you could just as easily do it like:

Code: [Select]
Type mySprite
    As Integer x, y
End Type

Sub moveSprite (tsprite As mySprite, newx As Integer, newy As Integer
  tsprite.x = newx
  tsprite.y = newy
End Sub

Sub drawSprite (tsprite As mySprite)
  PSet (tsprite.x, tsprite.y), &hffffff
End Sub

But then you lose the encapsulation and you still have scope issues because anyone else can access x and y.  This example also illustrates something else we need to examine: style.

You might not think it matters, but it does.  For example, although indentation doesn't really have any effect on what a program does, it's still a lot easier to read

Code: [Select]
If something = 1 Then
  Do
    Print "Hi"
  Loop While something = 1
End If

than

Code: [Select]
If something = 1 Then
Do
Print "Hi"
Loop While something = 1
End If

And there are other areas this applies.  Now if you have a UDT and a bunch of procedures that deal with that UDT specifically, it eventually becomes logical that those subs should be part of that UDT, rather than separate entities.  It also simulates real life;  for example, in the corporate structure, your executive gives out tasks for his employees to do.  The boss doesn't balance finances using the employee, he tells his employee to do it!  So likewise it seems much more logical to tell the sprite to draw itself, rather than to tell a procedure to draw a sprite using the UDT that contains it.  Or a map object, for example:

Code: [Select]
Type mapType
  As Integer x, y
  As Any Ptr tiles
End Type

Declare Sub loadMap (filename As String, map As mapType)
Declare Sub drawMap (map As mapType)
Declare Sub moveMap (map As mapType, x As Integer, y As Integer)

Notice anything about all these subs?  They all have a parameter called "map As mapType"!  But if you use OOP, you don't have that.  In fact, you can just call the subs "map.load, map.move, and map.draw" instead of "loadMap, drawMap, and moveMap".  Nor do you pass a map parameter to them;  they're part of a map object, so they have a hidden parameter passed to them.

Hopefully you're getting an idea of why OOP makes sense.  It's really just another abstraction which takes some ideas to the next level.  UDTs don't exist in real life;  neither do procedures for that matter.  At the low level, the variables are separate, the procedures in the UDTs are not "part of" anything at all, and all procedures are really just Goto statements (actually, it's a little better than that but I won't go into the details).  But OOP saves you from scoping problems, allows you to work much more easily, and makes your code look nicer and more logical too!

But OOP goes beyond making code nicer and more logical.  It makes a lot of things simpler, and generally lets you do some very interesting things you otherwise couldn't do.  For example, strings.  Normally the + is used to add two numbers, but what if you want to use it to concatenate two strings?  That's what operator overloading is for!  If you make a string object, you can use the + operator for the object and it does something totally different!  You can do this with pretty much all the other standard operators too.

And then there's RAII.

cha0s wrote a tutorial about RAII too, but some people might not understand it so well.  What it basically means is, when you create an object the object keeps track of all the resources it needs.  Take for example a buffer in memory.  If you create a buffer (say, to store your map data) then you need to use a pointer, and you need to Allocate/ReAllocate/DeAllocate.  Now what if you forget to DeAllocate?  You may eventually get memory leaks and problems!  But if you put it inside an object, the object will automatically allocate the memory it needs when it needs it, and as soon as the object is destroyed (which will be at the end of the program or at the end of the procedure it's created in, depending on the scope) it will automatically deallocate the memory, thus ensuring you won't get any leaks (or wasted memory) by forgetting to deallocate a buffer when you're done with it.

This is done with Constructors and Destructors, which are two special kinds of procedures that are called automatically as soon as the object is created or destroyed.  The other nice thing about them is that they let you set the object up, make sure the object is valid before you call any other methods.  For example, you might want to draw your map, but what if you forgot to load it?  Then the pointer to the buffer containing the map data is invalid and when you try to draw the map your program will likely crash.  But if you have a Constructor, which gets called automatically no matter what, then it can set a special flag inside the object explaining that the map has not been loaded so it shouldn't be used.  You can also allocate the pointer, so when the map loading routine needs to reallocate there's something to reallocate (and of course the destructor will deallocate it):

Code: [Select]
Type mapType
  Public:
    Declare Constructor ()
    Declare Destructor ()

    Declare Sub load (filename As String)
    Declare Sub draw ()
    Declare Sub move (newx As Integer, newy As Integer)
  Private:
    As uByte Ptr _map_data
    As uInteger _map_width, map_height
    As Integer _x, _y
End Type

Now if we were to call draw() without a constructor, it would check the buffer at _map_data for tiles to draw.  But the map hasn't been loaded yet, so the buffer is empty!  This could very well cause a crash!  But if the constructor is used, the constructor sets everything up ahead of time so no errors can occur.

Now of course in practice, you would be very careful not to call draw() until you call load().  But if you forget, or make a mistake, setting things up this way can save you a lot of trouble.

Another thing OOP lets you do is Properties.  Now as I said earlier we want to hide all the variables inside the object where nobody else can access them, because otherwise we can have problems.  But always using a sub to access the variables may seem rather uncomforable.  This is why we use properties.  They seem like variables, and they act just like variables - for example, if x is a property of myUDT, then you can do

Code: [Select]
myUDT.x = 3
Print myUDT.x

but in reality, properties are actually a special kind of procedure, meaning when you try to modify a variable you aren't just directly modifying it, you're actually instructing the object to modify it.  This way, for example if you had a property map.x the map could redraw itself automatically when you modify map.x.  This wouldn't happen if you tried to modify the variable directly, but since a property is really a sub in disguise you can do that.  This way, you avoid the scope problems but you don't have to use the rather uncomfortable sub just to modify things.

Of course, how you do things is entirely up to you.  It might be easier at first not to use properties, operators, or even constructors and destructors.  These things are just special extras that come with the OOP paradigm.  You may want to start out just using methods and keeping all variables Private.  It's still much safer and smarter than using UDTs with everything public.  And you'll start to get a feel for OOP, and maybe even learn to enjoy it and prefer it to just plain procedural programming.

OOP is not the be-all and end-all solution to everything.  I don't use OOP everywhere, by any means - but I do use it whenever I can, because it can save me a lot of trouble and make sure I do things right.  And by the way, OOP and procedural programming can be done side-by-side.  As I said, I don't use OOP for everything - for some things, a plain old-fashioned function or sub will work just fine.  But when it's possible, when it's useful, when it makes things easier, safer, and cleaner, I use OOP.

12
Programming / ScaleHalf
« on: January 22, 2008, 03:58:20 PM »
This takes an image and scales it to one-fourth its original size (one half on each dimension);  works best if the original dimensions are even, otherwise an extra row of pixels might be ignored.  Only 32-bit colour supported, since it's much easier (I can just grab a whole uInteger at a time from the buffer, rather than trying to figure out the individual r, g, and b components byte-by-byte - and don't even think about 16-bit, too darned complicated.  I'm not an assembly wizard, sorry!)

The example program loads two 800x600x32 images (named "img.bmp" and "test.bmp" - if you've tried my Special FX objects you can use the same images) and scales them down one or more times (it asks how many times you want it to repeat the procedure - anything higher than 9 is unnoticeable, though).

Code: [Select]
#Include Once "fbgfx.bi"

Function scalehalf (origImg As FB.Image Ptr) As FB.Image Ptr

'If the image isn't 32-bit, forget it
If origImg->Bpp <> 4 Then Return 0

'Get width and height of original image
Dim As uInteger w = origImg->Width, h = origImg->Height

'If they're too small, exit
If w = 1 Then Return 0
If h = 1 Then Return 0

'Second image will be first divided by two;  shifting is always faster than dividing, and it does the same thing
Dim As uInteger nw = w Shr 1, nh = h Shr 1

'Create the second image
Dim As FB.Image Ptr newimg = ImageCreate(nw, nh, 0, 32)

'Get pointers directly to the image data
Dim As uInteger Ptr origPixels = CPtr(uInteger Ptr, origImg + 1)
Dim As uInteger Ptr newPixels = CPtr(uInteger Ptr, newImg + 1)

'Pixel values of every four pixels
Dim As uInteger p1, p2, p3, p4

'Totals for Alpha/Green and Red/Blue (calculated simultaneously for higher speed)
Dim As uInteger agTotal, rbTotal

'Amount to add to the integer pointer each time - divide the pitch by four to get
'uIntegers per line (pitch = bytes per line, uInteger = 4 bytes - addo is Shr 1 instead because
'it needs to be Shl 1 later, this way we don't need to do it inside the loop (don't ask me why
'this is the case, I can't remember)
Dim As uInteger addo = (origImg->Pitch) Shr 1, addn = (newimg->Pitch) Shr 2

  'For each row
  For y As uInteger = 0 To (nh-1)
    'For each column
    For x As uInteger = 0 To (nw-1)
      'Get the first two pixels - we multiply by 2 (that's what Shl 1 does) because the original image
      'has two pixels in each dimension for every one the destination image has
      p1 = origPixels[(x Shl 1)]
      p2 = origPixels[(x Shl 1)+1]

      'If the second two are outside of the image, just use the first two again
      If y >= nh-1 Then
      p3 = origPixels[(x Shl 1)]
        p4 = origPixels[(x Shl 1)+1]
      Else
        p3 = origPixels[(x Shl 1)+(addo)]
        p4 = origPixels[(x Shl 1)+(addo)+1]
      End If
     
      'We calculate red and blue together - since they're a byte apart each, they cannot possibly mix
      'This is faster than the other way.
      rbTotal = (p1 And &hff00ff) + (p2 And &hff00ff) + (p3 And &hff00ff) + (p4 And &hff00ff)
      'Take the average
      rbTotal Shr= 2
     'And throw out the carry bits, keeping only the bits in their proper range
      rbTotal And= &hff00ff
     
      'Now calculate green and alpha together;  this one we have to shift over 8 bits or else alpha might
      'overflow through the top
      agTotal = ((p1 And &hff00ff00) Shr 8) + ((p2 And &hff00ff00) Shr 8) + ((p3 And &hff00ff00) Shr 8) + ((p4 And &hff00ff00) Shr 8)
      'Get average
      agTotal Shr= 2
      'Once again throw out the carry bits
      agTotal And= &hff00ff
      'And shift it back up 8 bits to where it was before
      agTotal Shl= 8
     
      'Add the two results together to get the new pixel value
      newPixels[x] = rbTotal + agTotal
    Next x

    'Add the correct amount to each pointer
    origPixels += addo
    newPixels += addn
  Next y
Return newimg
End Function

Sub scaleDraw (todraw As FB.Image Ptr, x As Integer = 0, y As Integer = 0, times As uInteger = 1)
Dim As FB.Image Ptr newimg = 0, img2 = 0

If times = 0 Then
Put (x, y), todraw
Exit Sub
EndIf

newimg = scalehalf(todraw)

If times > 1 Then
While times > 1
times -= 1
img2 = scalehalf(newimg)
If img2 = 0 Then Exit While
Swap newimg, img2
ImageDestroy(img2)
img2 = 0
Wend
End If

If newimg <> 0 Then Put (x, y), newimg, PSet

ImageDestroy(newimg)
If img2 <> 0 Then ImageDestroy(img2)
End Sub

Sub loadDraw (fname As String, x As Integer = 0, y As Integer = 0, times As uInteger = 1)
Dim As FB.Image Ptr myimg = ImageCreate(800, 600, 0, 32)
BLoad fname, myimg

scaleDraw(myimg, x, y, times)

ImageDestroy(myimg)
End Sub

Dim As Single t0
Dim As Single t1

Dim As uInteger ntimes

Print "How many times shall I scale the images down?"
Input ntimes

ScreenRes 800, 600, 32

t0 = timer

loadDraw("test.bmp", 0, 0, ntimes)
loadDraw("img.bmp", 400, 0, ntimes)

t1 = Timer

Draw String (0, 500), "Quarter-scaled two 800x600 images " + Str(ntimes) + " times in " + Str(t1-t0) + " seconds."

Sleep

End

Half of that's just the example program;  if you want to scale your images in half you only need the sub scaleHalf() function which takes an image buffer pointer and returns an image buffer pointer (doesn't modify the original).  The whole thing's well-commented, though likely if you don't have a good understanding of fbgfx none of it will make sense to you.  Suffice to say that if you have an image buffer myimg and you want to make it a quarter of its total size, then draw it, you would do it like this:

Code: [Select]
Dim As FB.Image Ptr newimg = scalehalf(myimg)

Put (0, 0), myimg

And that's all you need to know!

Enjoy, and I wouldn't mind getting some feedback, comments, errata, etc.

13
Game Dev / Special FX Objects
« on: January 15, 2008, 04:11:56 PM »
Here are some nice special FX objects I made, perfect for games or whatever you like.

Includes:
--Fader
--Dissolver
--Blixer (Block mixer - wait till you see it, you'll understand better then)
More may be added later, depending on how many people like them.

http://notthecheatr.phatcode.net/downloads/ntc.specialfx.zip

Source, documentation, binaries, and images used in the example programs included.  Enjoy!  Feedback, comments, etc. would be nice.

14
Game Dev / Features
« on: December 30, 2007, 04:52:22 PM »
I myself like as many features as possible in a game engine, I say the more cool stuff you can do the better.  But when it's just one man doing the engine, with things going slow as heck, I sometimes wonder... which things do you perceive as being hugely important?  Obviously some of these things need to be there no matter what, but which things do I really need to put a lot of effort into and which can I slack on, make a lazy, quick-and-dirty job of?

-Scripting
-GUI
-Particles
-Map editor
-Battle engine?

I guess I'm curious how different people do things, what seems to be the most likely/best method for doing things.  So many things to do, which are the most important and which are the least?

15
Game Dev / My Lighting Object
« on: December 27, 2007, 10:24:01 PM »
Another plug for it  ;D

http://notthecheatr.phatcode.net/downloads/lighting_example.zip

Not yet finished, but it's getting there.  Might be useful for something anyways.  The main thing I'm working on now is global ambient lighting, this will make it possible to have for example dark caves.  Coming up, not here yet.  I'll update when I can.

Pages: [1]