Bouldermax competition!

BlitzMax Forums/BlitzMax Programming/Bouldermax competition!

Ok, who's in? It's a large one for sure.. :P

The objectives:
- Make the classic Boulderdash in BMax (you may use top-notch gfx tho, no reason to use pre-1985 gfx)
- should naturally include the classic ingredients: Rockford, amoebas, fireflies, squares, hard walls, soft walls, earth, diamonds, rocks, stone -> diamond converting walls.
- no modules other than the ones that come standard with BMax (it should work for everyone who just downloads bmax for the first time, with recent syncmod tho)
- no MaxGUI for essential parts, e.g. if you want to run it on a canvas in a window, make an alternative version. It should work for all BMax users.

No prize money, just eternal fame and you might actually save a coin or two for not hanging out in the pub by doing this! (perhaps BRL can brag a bit about it on the frontpage, being examples of what can be done with a standard BMax?)

I like this idea, except for the no loading part. Change that and I may compete.

Well, you could see it as a subcompetition: what gfx could you produce only using blitz commands. But I rather wait for other comments about this subject.

I will be interested to see the results, but sounds like too much work for a mini compo so I'm not competing.

I really want to do a boulderdash game eventually but I am a little bit put off by the having no media angle. How are you supposed to come up with better graphics than the originals if you can't even use any bitmaps at all? Although, I suppose you can use Data statements?

hm.. I might drop that line then, tho it'd be fun to see what ppl could do just with scripts 'n such.

Award extra points for not loading media?

Hey, a bit like my mushroom collector in B3D? :P

If you say no media... does that mean the level data must be embedded in the game as well ?

Anyways... what if the game must be able to run with no media but if it is supplied it can use it ?

That way those who cant get hold of good media can still be judged on a level pegging with those who can ?

Or.. come up with a standard spec for the media and you can have two compo's. One can be for the artists in here to generate the best graphics/sounds/music and another for the programmers to code the game itself ?

Still sounds like a big compo.. what is the time frame ?

For me, no loading would limit it a lot. Mind you I don't have time to enter but I'll watch the contest with interest. I always wanted to make one of these games.

No time frame decided. But I've done some attempts to make a Boulderdash myself, the basics were usually done in one day, including some simple gfx, and simple map generation. In the end it's just updating each x,y coord of a map according to its content, stuff like that is done rather quickly.

But if there's too much moaning about no-loading, then I guess I'll drop it..

what about if you allow for incbin'd stuff, and limit the exe size to 2 megs or something?

Dunno whether size is very important here. *if* there would be a no-loading rule it would purely be to have an additional competition: media-generation using blitz commands. But if that'll scare ppl, then the only competition left is the dash code itself. Whether one uses 100kB media or 4MB, I don't think that's much of an issue. Naturally, for sake of challenge, if there are two entries with identical quality then the game with the least amount of media is preferred.

I persnally think any media restriction rules will scare away contenders but them maybe not having those rules will scare away "hardcore" contenders - who knows which number is the biggest.

What are you judging exactly? The code only or the whole game. If the "game" then identical quality "gamplay" but better media should win. Why would you judge gameplay only anyway?

From an outsider point of view I'd like to see some great boulderdash games and some interesting twists and it'll make them a lot more interesting to test if they have nice media imho. Then the compo can be talked about on lots of gaming blogs where it might only get a few mentions if the media is all code-generated and thus potentially a bit pap-looking.

btw my framework isn't a module and it uses standard Blitz Max modules so it could be used, yay!

btw my framework isn't a module and it uses standard Blitz Max modules so it could be used, yay!


Only if you wanted your users to distribute the full source. I think the module restrictions were designed to allow anyone who wants to to download the source of the game and compile it. Otherwise the MaxGUI restrictions make no sense.

I have to finish work on another shader pack over the weekend and then it's back to my ongoing project, so I doubt I'd enter. The media restrictions wouldn't put me off though. The module restrictions might though, as I prefer to use HGE to Max2D.

Oh, I didn't have the intention to be the jury or something, I rather compete with a B.D. of my own. I rather think the audience should vote. I'm only here to kickstart a competition because otherwise nothing ever happens here. The 256byte challenge was quite fruitful, perhaps this one could be as well.
But if I'd be the jury I think I would formost look at the artwork and polish and how it plays. Technically the game isn't hard to make and gfx also aren't supercomplex, we're not talking RPG's, shooters, or platformers here.
And, as you know me, a good tune is important .. :P

btw, about your framework: the idea is that ppl post full sources and optionally a link to required media, not just compiled .exe files. So I dunno whether your framework is non-public or not, but I might forsee a problem then.. :P

btw, about the gameplay and media thing: All I was meaning to say that when two games have the same overall quality (gameplay, media etc.) then the game with less media is more impressive, from a technical/art point of view. Same drill as those 64kB competitions @ demo parties. They're usually far more impressive than "ordinary" demo competitions.
Or another one: what's more impressive: Second Reality on PC, or on C64?

But I estimate the chance of have two or more equal-quality games zip anyway, so I wouldn't worry about it.

First: The graphics...they are some sprites created using BM-commands:


Now the code...a bit unstructured - but for about an hour of coding I think its ok.

You may use it as base for your version of the competitions game. So some "untalented" (more than I ;D) may come around with the rules too. Because everything is "scripted" - you can easily change colors etc.

SuperStrict

Function DrawScrew(x:Int,y:Int)
  SetColor 100,100,100
  DrawOval(x-1,y-1,10,10)
  For Local i:Int=1 To 8
    Local col:Int=150+i*10
	SetColor col,col,col
	DrawOval(x+i/2,y+i/2,8-i,8-i)
	SetColor 70,70,70;DrawLine(x+1,y+2,x+5,y+6)	
	SetColor 200,200,200;DrawLine(x+3,y+2,x+6,y+5)	
  Next
End Function

Graphics 640,480
SetBlend ALPHABLEND
Const BlockW:Int=40, BlockH:Int=40

'border block
SetColor 140,140,140
DrawRect(0,0,BlockW,BlockH)
DrawScrew(5,5);			DrawScrew(BlockW-12,5)
DrawScrew(5,BlockH-12);	DrawScrew(BlockW-12,BlockH-12)
SetAlpha 0.5;SetColor 255,255,255; 	DrawLine(1,1,BlockW,1,True); DrawLine(1,1,1,BlockH,True)
SetAlpha 0.25;SetColor 0,0,0;		DrawLine(BlockW-1,1,BlockW-1,BlockH,True); DrawLine(1,BlockH-1,BlockW,BlockH-1,True)
SetAlpha 1.0;SetColor 255,255,255
Global gfx_BorderBlock:Timage= TImage.Create(BlockW,BlockH,1,0,0,0,0); gfx_BorderBlock.pixmaps[0] = GrabPixmap(0,0,BlockW,BlockH)
'''

'bg
SetColor 120,100,40
DrawRect(0,0,BlockW,BlockH)
For Local i:Int=1 To BlockH Step 6
  Local rndInt:Int = Rand(30)
  SetColor rndInt+90,rndInt+70,rndInt+50
  For Local j:Int = 1 To BlockW Step 5
    SetAlpha 0.5
	DrawOval(i+Rand(2),j,Rand(10),Rand(5))
  Next
Next
SetAlpha 1.0;SetColor 255,255,255
Global gfx_BgBlock:Timage= TImage.Create(BlockW,BlockH,1,0,0,0,0); gfx_BgBlock.pixmaps[0] = GrabPixmap(0,0,BlockW,BlockH)
'''

'diamond
SetColor 0,0,0
DrawRect(0,0,BlockW,BlockH)
Local j:Int=0
For Local i:Int = 1 To (BlockW / 2)
   j:+1
   SetColor j*5+100,Rand(50)+200,Rand(50)+200
   DrawLine(BlockW/2 -i,j,BlockW/2 +i,j,True)
   DrawLine(BlockW/2 -i,BlockH-j,BlockW/2 +i,BlockH-j,True)
Next
   Local k:Int = 0
   SetColor 255,255,255   
   While k<>3
   If k=1 Then k=2
   SetAlpha 0.5
   DrawLine(BlockW/2,1,BlockW/2 +(k-1)*20,BlockH/2,True)
   DrawLine(BlockW/2,BlockH,BlockW/2 +(k-1)*20,BlockH/2,True)
   SetAlpha 0.75
   DrawLine(BlockW/2,1,BlockW/2 +(k-1)*14,BlockH/2,True)
   DrawLine(BlockW/2,BlockH,BlockW/2 +(k-1)*14,BlockH/2,True)
   SetAlpha 0.90
   DrawLine(BlockW/2,1,BlockW/2 +(k-1)*7,BlockH/2,True)
   DrawLine(BlockW/2,BlockH,BlockW/2 +(k-1)*7,BlockH/2,True)
   k:+1
  Wend
SetAlpha 1.0;SetColor 255,255,255
Global gfx_Diamond:Timage= TImage.Create(BlockW,BlockH,1,0,0,0,0); gfx_Diamond.pixmaps[0] = GrabPixmap(0,0,BlockW,BlockH)
'''
'ball
SetColor 0,0,0
DrawRect(0,0,BlockW,BlockH)
For Local i:Int =1 To BlockW/2
  SetAlpha 1
  Local j:Int=i*1.5
  SetColor j*2+80,j+80,j*0.8+80
  DrawOval(i,i,(20-i)*2,(20-i)*2)
  SetColor 0,0,0
  SetAlpha Rand(5)*0.05
  For Local k:Int =0 To 15
  DrawOval(Rand(BlockW),Rand(BlockH),Rand(3),Rand(3))
  Next
Next
SetAlpha 1.0;SetColor 255,255,255
Global gfx_Ball:Timage= TImage.Create(BlockW,BlockH,1,0,0,0,0); gfx_Ball.pixmaps[0] = GrabPixmap(0,0,BlockW,BlockH)
'''
'player
SetColor 0,0,0
DrawRect(0,0,BlockW,BlockH)
 SetColor 100,80,40; 	DrawOval(BlockW/2-BlockW/4,BlockH-8,BlockW/2,BlockH/3) 			'shoe
 SetColor 50,40,15; 	DrawLine(BlockW/2,BlockH-8,BlockW/2,BlockH) 					'shoe middle
 SetColor 70,55,25; 	DrawLine(BlockW/2-1,BlockH-8,BlockW/2-1,BlockH) 				'shoe middle
 SetColor 90,130,220;   DrawOval(BlockW/2-BlockW/4-1,BlockH/2+1,BlockW/2+2,BlockH/3)	'arms
 SetColor 50,90,180;    DrawOval(BlockW/2-BlockW/4+1,BlockH/2+1,BlockW/2-2,BlockH/3)	'arm bordering (to make it different to body)
 SetColor 240,210,110;  DrawOval(BlockW/2-BlockW/4,BlockH/2-10,5,5) 		'ear (left)
						DrawOval(BlockW/2+BlockW/4-5,BlockH/2-10,5,5) 		'ear (right)
 SetColor 200,170,80;   DrawOval(BlockW/2-BlockW/4+1,BlockH/2-9,3,3) 		'ear (left)
						DrawOval(BlockW/2+BlockW/4-4,BlockH/2-9,3,3) 		'ear (right)
 SetColor 240,210,110;  DrawOval(BlockW/2-BlockW/4,BlockH/2+10,4,4) 		'hand (left)
						DrawOval(BlockW/2+BlockW/4-4,BlockH/2+10,4,4) 		'hand (right)
 SetColor 100,140,240;  DrawOval(BlockW/2-BlockW/4+2,BlockH/2,BlockW/2-4,BlockH/3+2)	'body
 SetColor 50,70,120																		'dots on body
 For Local i:Int = 0 To 2
						Plot(BlockW/2-2 ,BlockH/2+4+i*3); Plot(BlockW/2+1 ,BlockH/2+4+i*3)
 Next
 SetColor 240,210,110;  DrawOval(BlockW/2-BlockW/4,BlockH/2-10,BlockW/2,BlockH/3) 		'head
 SetColor 250,220,130;  DrawOval(BlockW/2-4,BlockH/2-6,8,7)								'nose
 SetColor 200,140,240;  DrawOval(BlockW/2-2,BlockH/2-4,4,3)								'nose
 SetColor 20,20,100;	DrawOval(BlockW/2-BlockW/4 + 4,BlockH/2-10+3,3,3)				'eyes
 						DrawOval(BlockW/2+BlockW/4 - 7,BlockH/2-10+3,3,3)
SetAlpha 1.0;SetColor 255,255,255
Global gfx_Player:Timage= TImage.Create(BlockW,BlockH,1,0,0,0,0); gfx_Player.pixmaps[0] = GrabPixmap(0,0,BlockW,BlockH)
'''
'bug
SetColor 0,0,0
DrawRect(0,0,BlockW,BlockH)
 SetColor 100,100,100;  DrawLine(BlockW/2-12,4,BlockW/2+13,BlockH/3*2)				'legs top
						DrawLine(BlockW/2-14,BlockH/3+1,BlockW/2+16,BlockH/3+1)		'legs middle
						DrawLine(BlockW/2-13,BlockH/3*2,BlockW/2+15,4)				'legs bottom
 SetViewport(0,0,BlockW/2,BlockH)
 For Local i:Int = 0 To BlockW/3
 SetColor 180+i*5,100+i*5,80+i*5;  DrawOval(BlockW/2-BlockW/4+i,2,BlockW/2-i,BlockH/3*2+3)	'body
 Next
 SetViewport(0+BlockW/2,0,BlockW/2,BlockH)
 For Local i:Int = 0 To BlockW/3
 SetColor 180+i*5,100+i*5,80+i*5;  DrawOval(BlockW/2-8,2,BlockW/2-i,BlockH/3*2+3)	'body other half
 Next
 SetViewport(0,0,640,480)
 SetColor 150,70,50;  DrawLine(BlockW/2+1,2,BlockW/2+1,BlockH/3*2+3)		'body half segmenter
 SetColor 160,80,60;   DrawLine(BlockW/2,2,BlockW/2,BlockH/3*2+3)			'body half segmenter
 SetColor 100,100,100;  DrawOval(BlockW/2-7,BlockH/3*2-1,16,12)				'teeth
 SetColor 0,0,0; 		DrawOval(BlockW/2-4,BlockH/3*2+1,10,12)				'teeth center (cut)
 SetColor 160,160,160;  DrawOval(BlockW/2-5,BlockH/3*2-1,12,6)				'head
 SetColor 0,0,0;  		DrawOval(BlockW/2-5+2,BlockH/3*2+1,2,2)						'eye
 						DrawOval(BlockW/2+5-2,BlockH/3*2+1,2,2)						'eye
SetAlpha 1.0;SetColor 255,255,255
Global gfx_Bug:Timage= TImage.Create(BlockW,BlockH,1,0,0,0,0); gfx_Bug.pixmaps[0] = GrabPixmap(0,0,BlockW,BlockH)
'''

'key
SetColor 0,0,0
DrawRect(0,0,BlockW,BlockH)
 SetColor 255,190,30;   DrawOval(BlockW/2+BlockW*0.15,BlockH*0.45,BlockW*0.25,BlockH*0.4) 'ring
 						DrawRect(BlockW/2-BlockW*0.20,BlockH*0.6,BlockW*0.4,BlockH*0.10)
 						DrawRect(BlockW/2-BlockW*0.20,BlockH*0.6,3,BlockH*0.20) 		 'beard
 						DrawRect(BlockW/2-BlockW*0.10,BlockH*0.6,3,BlockH*0.15) 		 'beard
 SetColor 0,0,0;   		DrawOval(BlockW/2+BlockW*0.15+3,BlockH*0.45+2,BlockW*0.25-6,BlockH*0.4-4) 'ring cut
SetAlpha 1.0;SetColor 255,255,255
Global gfx_Key:Timage= TImage.Create(BlockW,BlockH,1,0,0,0,0); gfx_Key.pixmaps[0] = GrabPixmap(0,0,BlockW,BlockH)
'''
SetBlend ALPHABLEND
'entry
SetColor 0,0,0
DrawRect(0,0,BlockW,BlockH)
 SetColor 80,30,10;   	DrawRect(0,0,BlockW,BlockH)
SetAlpha 0.5;SetColor 255,255,255; 	DrawLine(1,1,BlockW,1,True); DrawLine(1,1,1,BlockH,True)
SetAlpha 0.5;SetColor 0,0,0;		DrawLine(BlockW-1,1,BlockW-1,BlockH,True); DrawLine(1,BlockH-1,BlockW,BlockH-1,True)
SetAlpha 1.0
 SetColor 150,150,150;  DrawOval(BlockW/2+BlockW*0.15-3,BlockH*0.45-3,BlockW*0.25,BlockH*0.4) 'ring
 						DrawRect(BlockW/2-BlockW*0.20-3,BlockH*0.6-3,BlockW*0.4,BlockH*0.10)
 						DrawRect(BlockW/2-BlockW*0.20-3,BlockH*0.6-3,3,BlockH*0.20) 		 'beard
 						DrawRect(BlockW/2-BlockW*0.10-3,BlockH*0.6-3,3,BlockH*0.15) 		 'beard
 SetColor 80,30,10; 	DrawOval(BlockW/2+BlockW*0.15+3-3,BlockH*0.45+2-3,BlockW*0.25-6,BlockH*0.4-4) 'ring cut
SetAlpha 1.0;SetColor 255,255,255
Global gfx_Entry:Timage= TImage.Create(BlockW,BlockH,1,0,0,0,0); gfx_Entry.pixmaps[0] = GrabPixmap(0,0,BlockW,BlockH)
'''
'entryOpen
SetColor 0,0,0
DrawRect(0,0,BlockW,BlockH)
j = 0
For Local i:Int = 0 To BlockW/2-1
 j:+ 1*(BlockW/BlockH)
 SetColor Rnd(155)+50,Rnd(155)+50,Rnd(155)+40
 DrawRect(i,i,BlockW-i*2, BlockH-j*2)
Next
SetAlpha 1.0;SetColor 255,255,255
Global gfx_EntryOpen:Timage= TImage.Create(BlockW,BlockH,1,0,0,0,0); gfx_EntryOpen.pixmaps[0] = GrabPixmap(0,0,BlockW,BlockH)
'''
SetBlend ALPHABLEND

Repeat
Cls
For Local i:Int = 4 To 14
  DrawImage (gfx_BorderBlock, i*BlockW,0)
  DrawImage (gfx_BgBlock, i*BlockW,BlockH+1)
  DrawImage (gfx_Diamond, i*BlockW,BlockH*2+1)
  DrawImage (gfx_Ball, i*BlockW,BlockH*3+1)
  DrawImage (gfx_Player, i*BlockW,BlockH*4+1)
  DrawImage (gfx_Bug, i*BlockW,BlockH*5+1)
  DrawImage (gfx_Key, i*BlockW,BlockH*6+1)
  DrawImage (gfx_Entry, i*BlockW,BlockH*7+1)
  DrawImage (gfx_EntryOpen, i*BlockW,BlockH*8+1)
Next
DrawText("Border:",5,BlockH*1-20)
DrawText("BgBlock/Earth:",5,BlockH*2-20)
DrawText("Diamonds:",5,BlockH*3-20)
DrawText("Ball:",5,BlockH*4-20)
DrawText("Player:",5,BlockH*5-20)
DrawText("Bugs:",5,BlockH*6-20)
DrawText("Key:",5,BlockH*7-20)
DrawText("Entry (Key needed):",5,BlockH*8-20)
DrawText("Entry (open):",5,BlockH*9-20)
Flip
Until KeyHit(27)



bye
MB

^^ now that is some cool code... 8)

wow great code for drawing the graphics!

Ah yes thanks for the clarification about the source beeing freeware - you are correct that my framework should be used in that case.

CS_TBL: I see what you mean on the media thing now.

So.. is anyone entering this competion ?
Do we get to see any Work in progress stuff anytime soon ?
I might just get distracted from what Im working on and give it a go myself.

Maybe if CS_TBL setup a mini website for it with details and entries?

I don't have a mini website. :P Everyone may do so nonetheless. See me only as 'bringer of the idea', not as 'master of ceremonies' or 'owner of the competition'.

As for the rules, I guess I'll drop the no-loaded-media thing then eh..

why? gfx is provided (see some postings before) - so although untalented scripters could produce a nice gameplay...

Without doing much gfx-coding you can use your time straight to produce the game(play)... faster coding - faster results.


bye
MB

The majority requested to drop that rule.. democracy!

It might be a bit to though for me yet, but I'll give it a shot. I do think you shouldn't drop the no-loaded-media thing! The lazy people can allways use MichaelB's awesome code ;)

There are more ppl who wanted to drop it than that there are ppl who liked the restriction, note that you can still generate all your gfx if you like.. it's not forbidden to *not* load anything..

Yea you're probably right, but I allready spent a few hours creating the graphics with Max2D. Maybe it could be worth a small bonus?

Well, that's up to those who'll judge I guess. Perhaps taking votesheets is wise, or perhaps asking several experienced/respected forum members to act as jury?

How about if the people in the competition vote? Everyone have one vote and voting on your own entry is forbidden.

I'm a bit interested in this compo. When will it start? I have a busy schedule but I haven't done some coding in ages...

That voting thing could also be an idea yea. (all of us in the Green room :D ) Compo starts any day.. there's no deadline set, perhaps if enough ppl "sign-up" here we could set a democratic deadline?

How about this? We start at June 1, or a couple of days later if someone doesn't want to rush things. The semi official end date is on July 1. Give or take a couple of days. Voting begins soon after and the winner is announced on August 1.

No need for exact date and time for it. Just don't cheat too much and everyone will be happy. :)
It's ok if someone really-really-pretty-please-with-sugar-on-top needs and extra day or two. As long as things isn't delayed too much.

Sigh, I wish I could enter this, but it would be WAY too much of a distraction. The problem with making games as your day job is there is no time to enter competitions for fun :-(

The basic algo (all the AI things) could be done in a weekend tho. I know, I've done so .. with ripped MSX gfx.. the only things I've never done are enemies (fireflies/squares) and amoebae.

Boulderdash- hmm.... if I was free for a couple days this would take 2 days thereabouts.

Been a while since i've been free for that long though!

So... Are we doing this? Anyone started yet?

lol... I have made a start... I dont get much free time so Ive managed about 4 hours so far.. and in fact after about 2.5 hours coding I decided to scratch the code and start again !
Not much to show for my efforts so far. I have loads of behind the scenes code done but nothing to show for my efforts except a bunch of debug statements.
Its not pretty either.. its just a single big source file.. and as Im in a bit of a rush there arnt anywhere near as many comments as I like.
Im planning of having an inbuilt editor so maybe when I have that part working(ish) I may post my code so-far and see if anyone fancy's designing some levels for it as Im just a coder and have never been good at the design side of things.

I haven't started yet. But I might give it a shot this weekend.
Anyone else? It's not much of a competition if there is only two coders competing. :)

I'm trying to make the AI for the fireflys now, but it's all pretty buggy.

Nnaturally I think I give it a shot.. I think that the amoebae are the most tricky to do btw. The fireflies and squares are actually quite simple.

I thought that to first. The problem is I never played the classic boulder dash, only clones, so I don't really know how they behave. The firefly moves clock-wise by the sides of the map right? But when he is moving to the left, en the player diggs a hole beneath him, will he start moveing down? (wich means he will be moving counter clock-wise)

-iirc- It's following walls at the left side from the perspective of the object, so 'left hand', if you get my point.

Ok I get it, it shouldn't be to hard indeed, thanks for making it clear.

I'm afraid I won't be able to complete my entry, since I'm leaving on vacation the day after tomorrow. I thought I would be able to complete it but problems popped up and I've been very busy with exams lately. I will just post my entry, that is not even half completed here, I don't think it's far enough to be counted in the competition but you guys may decide.

There are quite some bugs in it, escpecially the primitive collision detection of the boulders, I'm planning to totally rewright that part, also the boulders dont fall of to the left and right, that's something I will still have to add if I find some time. The AI of fire flys is done but there is no collision detection with them and the player yet. Graphics 100% created with the DrawRect command :P There are 3 colorschemes so far and if I, sometime, am going to create new levels I will probably add more so that every level has it's own colorscheme :)

There are 2 levels that can be quite fun, the 3th one is more a small test for the firefly AI.
So, here's the code:
SuperStrict

'---------------------------------------------
' Global variables
'---------------------------------------------
Const TileW       : Int = 32 ' *!* NOTE: IF THIS GETS CHANGED IMAGES WON'T BE RIGHT ANYMORE *!*
Const TileH       : Int = 32 ' *!* NOTE: IF THIS GETS CHANGED IMAGES WON'T BE RIGHT ANYMORE *!*
Const PlayerSpeed : Int = 4  ' *!* NOTE: MUST BE DEVIDABLE BY TILE WIDTH AND HEIGHT *!*
Const TotalMaps   : Int = 3

Const DIRT     : Int = 1
Const SOFTWALL : Int = 2
Const HARDWALL : Int = 3
Const ROCK     : Int = 4
Const DIAMOND  : Int = 5
Const DOOR     : Int = 6
Const FIREFLY  : Int = 7

Global Dirt_Img     : TImage
Global Boulder_Img  : TImage
Global Player_Img   : TImage
Global HardWall_Img : TImage
Global SoftWall_Img : TImage
Global Amoeba_Img   : TImage
Global Diamond_Img  : TImage
Global Door_Img	  : TImage
Global FireFly_Img  : TImage

Global PlayerMoving    : Int
Global PlayerDirection : Int
Global PlayerFrame     : Int = 2
Global PlayerX         : Int
Global PlayerY         : Int
Global PlayerMapX      : Int
Global PlayerMapY      : Int
Global PlayerDiamonds  : Int
Global DiamondsNeeded  : Int
Global PlayerScore     : Int
Global PlayerLives     : Int = 3
Global TimeLeft        : Int = 2000
Global CurrentFrame    : Int
Global LastUpdate      : Int        ' For animation
Global UpdateTime      : Int = 100  ' For animation

Global CurrentMap : Int = 0
Global Maps       : TMap[]


Global MapXOffset : Int           ' For scrolling
Global MapYOffset : Int           ' For scrolling
Global vpx        : Float = 0.0   ' Starting X location of viewport
Global vpy        : Float = 32.0  ' Starting Y location of viewport

Global Boulder      : TBoulder
Global Boulder_List : TList
Global FFly         : TFireFly
Global FireFly_List : TList


'---------------------------------------------
' Map type
'---------------------------------------------
Type TMap
	Field name           : String
	Field colorScheme    : Int
	Field width          : Int
	Field height         : Int 
	Field map            : Int[,]
	Field startX         : Int
	Field startY         : Int
	Field scrollSpacer   : Int
	Field time           : Int
	Field diamondsNeeded : Int
	Field diamondValue   : Int
	Field originalMap    : Int[,]
	
	Function Create:TMap()
		Local m:TMap = New TMap
		m.scrollSpacer = 2
		Return m
	EndFunction
	
	Method Draw()
		Local x:Int, y:Int, newx:Int, newy:Int
		
		' Loop trough the map
		For x=0 To width-1
			newx = x*TileW - MapXOffset + vpx
			For y=0 To height-1
				newy = y*TileH - MapYOffset + vpy
				
				' Draw the correct image
				If map[x,y] = DIRT Then
					DrawImage(Dirt_Img, newx, newy)
					
				ElseIf map[x,y] = SOFTWALL Then
					DrawImage(SoftWall_Img, newx, newy)
					
				ElseIf map[x,y] = HARDWALL Then
					DrawImage(HardWall_Img, newx, newy)
					
				ElseIf map[x,y] = DIAMOND Then
					DrawImage(Diamond_Img, newx, newy, CurrentFrame)
				
				ElseIf map[x,y] = DOOR Then
					If PlayerDiamonds >= diamondsNeeded
						DrawImage(Door_Img, newx, newy, CurrentFrame)
					Else
						DrawImage(Door_Img, newx, newy, 0)
					EndIf
				EndIf
				
			Next
		Next
	EndMethod
		
EndType

'---------------------------------------------
' Boulder type
'---------------------------------------------
Type TBoulder
	Field x       : Float
	Field y       : Float
	Field speed   : Int
	Field mapX    : Int
	Field mapY    : Int
	Field moveing : Int
	Field falling : Int
	
	Function Create:TBoulder(xpos:Int, ypos:Int)
		Local b:TBoulder = New TBoulder
		b.x     = xpos * TileW
		b.y     = ypos * TileH
		b.mapX  = xpos
		b.mapY  = ypos
		b.speed = 8
		ListAddLast(Boulder_List, b)
		Return b
	EndFunction
	
	Method Fall()
		If Maps[CurrentMap].map[mapX,mapY+1] = DIRT Or Maps[CurrentMap].map[mapX,mapY+1] = SOFTWALL Or Maps[CurrentMap].map[mapX,mapY+1] = ROCK Or ..
		   Maps[CurrentMap].map[mapX,mapY+1] = HARDWALL Or Maps[CurrentMap].map[mapX,mapY+1] = DIAMOND Or (PlayerMapY = mapY+1 And PlayerMapX = mapX) Then
			Return
		Else
			falling = True
			y :+ speed
			mapY = y/TileH
			mapX = x/TileW
			Maps[CurrentMap].map[mapX, mapY] = ROCK	
			If Maps[CurrentMap].map[mapX, mapY-1] = ROCK Then Maps[CurrentMap].map[mapX, mapY-1] = 0
			
			' Check to kill player
			If (mapX = PlayerMapX And mapY+1 = PlayerMapY)
				Kill_Player("You were crushed by a boulder!")
			EndIf
			' Check to kill firefly
			If Maps[CurrentMap].map[mapX, mapY] = FIREFLY Or Maps[CurrentMap].map[mapX, mapY+1] = FIREFLY
				Kill_Player("You crushed a firefly!")
			EndIf
		EndIf
	EndMethod
	
	Method Push:Int(dir:Int)
		If falling = False
			' Pushing right
			If dir = 4 Then
				If Maps[CurrentMap].map[mapX+1,mapY] = DIRT Or Maps[CurrentMap].map[mapX+1,mapY] = SOFTWALL Or Maps[CurrentMap].map[mapX+1,mapY] = ROCK Or ..
				   Maps[CurrentMap].map[mapX+1,mapY] = HARDWALL Or Maps[CurrentMap].map[mapX+1,mapY] = DIAMOND Then
					moveing = False
					Return False
				' Move :)
				Else
					moveing = True
					x :+ PlayerSpeed
					mapY = y/TileH
					mapX = x/TileW
					Maps[CurrentMap].map[mapX, mapY] = ROCK
					'If Maps[CurrentMap].map[mapX-1, mapY] = ROCK Then Maps[CurrentMap].map[mapX-1, mapY] = 0
					Return True
				EndIf
			' Pushing left
			ElseIf dir = 3 Then
				If Maps[CurrentMap].map[mapX-1,mapY] = DIRT Or Maps[CurrentMap].map[mapX-1,mapY] = SOFTWALL Or Maps[CurrentMap].map[mapX-1,mapY] = ROCK Or ..
				   Maps[CurrentMap].map[mapX-1,mapY] = HARDWALL Or Maps[CurrentMap].map[mapX-1,mapY] = DIAMOND Then
					If (x) Mod TileW <> 0
						x :- PlayerSpeed
					EndIf
					moveing = False
					Return False
				' Move :)
				Else
					moveing = True
					x :- PlayerSpeed
					mapY = y/TileH
					mapX = x/TileW
					Maps[CurrentMap].map[mapX, mapY] = ROCK
					'If Maps[CurrentMap].map[mapX+1, mapY] = ROCK Then Maps[CurrentMap].map[mapX+1, mapY] = 0
					Return True
				EndIf
			EndIf
		Else
			Return False
		EndIf
	EndMethod
		
	
	Method Draw()
		' Update position
		mapX = x/TileW
		mapY = y/TileH

		' Check if we have to kill player
		If mapX = PlayerMapX And mapY = PlayerMapY
			Kill_Player("You were crushed by a boulder!")
		EndIf
			
		' Check if boulder is one a correct position
		If (x) Mod TileW = 0 And (y) Mod TileH = 0
			mapX = x/TileW
			mapY = y/TileH
			If Maps[CurrentMap].map[mapX,mapY+1] = DIRT Or Maps[CurrentMap].map[mapX,mapY+1] = SOFTWALL Or Maps[CurrentMap].map[mapX,mapY+1] = ROCK Or ..
			   Maps[CurrentMap].map[mapX,mapY+1] = HARDWALL Or Maps[CurrentMap].map[mapX,mapY+1] = DIAMOND Or (PlayerMapY = mapY+1 And PlayerMapX = mapX)
				falling = False
			Else
				falling = True
				Fall()
			EndIf
		ElseIf (y) Mod TileH <> 0
			Fall()
		
		ElseIf (x) Mod TileW <> 0
			Push(PlayerDirection)
		EndIf
		
		DrawImage(Boulder_Img, x-MapXOffset+vpx, y-MapYOffset+vpy)
	EndMethod
EndType

'---------------------------------------------
' FireFly type
'---------------------------------------------
Type TFireFly	
	Field x         : Int
	Field y         : Int
	Field speed     : Int
	Field mapX      : Int
	Field mapY      : Int
	Field direction : Int
	Field move      : Int
	
	Function Create:TFireFly(xpos:Int, ypos:Int)
		Local f:TFireFly = New TFireFly
		f.x     = xpos * TileW
		f.y     = ypos * TileH
		f.mapX  = xpos
		f.mapY  = ypos
		f.speed = 4
		f.direction = 4
		ListAddLast(FireFly_List, f)
		Return f
	EndFunction
	
	Method Draw()
		' Update position
		mapX = x/TileW
		mapY = y/TileH
		Maps[CurrentMap].map[mapX,mapY] = FIREFLY
		If Maps[CurrentMap].map[mapX,mapY-1] = FIREFLY Then Maps[CurrentMap].map[mapX,mapY-1] = 0
		If Maps[CurrentMap].map[mapX,mapY+1] = FIREFLY Then Maps[CurrentMap].map[mapX,mapY+1] = 0
		If Maps[CurrentMap].map[mapX-1,mapY] = FIREFLY Then Maps[CurrentMap].map[mapX-1,mapY] = 0
		If Maps[CurrentMap].map[mapX+1,mapY] = FIREFLY Then Maps[CurrentMap].map[mapX+1,mapY] = 0
		
		' Check if we arrived at position
		If (x) Mod TileW = 0 And (y) Mod TileH = 0
			Select direction
				' North
				Case 1
					' We want to turn left
					If Maps[CurrentMap].map[mapX-1,mapY] = 0
						direction = 3
						move = True
						x :- speed
					' Now we want to go straight
					ElseIf Maps[CurrentMap].map[mapX,mapY-1] = 0
						direction = 1
						move = True
						y :- speed
					' Try to go right
					ElseIf Maps[CurrentMap].map[mapX+1,mapY] = 0
						direction = 4
						move = True
						x :+ speed
					' Just head same way back
					Else
						direction = 2
						move = True
						y :+ speed
					EndIf
				
				' South
				Case 2
					' We want to turn right
					If Maps[CurrentMap].map[mapX+1,mapY] = 0
						direction = 4
						move = True
						x :+ speed
					' Now we want to go straight
					ElseIf Maps[CurrentMap].map[mapX,mapY+1] = 0
						direction = 2
						move = True
						y :+ speed
					' Try to go left
					ElseIf Maps[CurrentMap].map[mapX-1,mapY] = 0
						direction = 3
						move = True
						x :- speed
					' Head same way back
					Else
						direction = 1
						move = True
						y :- speed
					EndIf
					
				' West
				Case 3
					' We want to move down
					If Maps[CurrentMap].map[mapX,mapY+1] = 0
						direction = 2
						move = True
						y :+ speed
					' Go straight
					ElseIf Maps[CurrentMap].map[mapX-1,mapY] = 0
						direction = 3
						move = True
						x :- speed
					' Try up
					ElseIf Maps[CurrentMap].map[mapX,mapY-1] = 0
						direction = 1
						move = True
						y :- speed
					' Same way back
					Else
						direction = 4
						move = True
						x :+ speed
					EndIf
				
				' East
				Case 4
					' Priority to up
					If Maps[CurrentMap].map[mapX,mapY-1] = 0
						direction = 1
						move = True
						y :- speed
					' Straight
					ElseIf Maps[CurrentMap].map[mapX+1,mapY] = 0
						direction = 4
						move = True
						x :+ speed
					' Try down
					ElseIf Maps[CurrentMap].map[mapX,mapY+1] = 0
						direction = 2
						move = True
						y :+ speed
					' Same way back
					Else
						direction = 3
						move = True
						x :- speed
					EndIf
			EndSelect
		Else
			Select direction
				' North
				Case 1
					direction = 1
					move = True
					y :- speed
					
				' South
				Case 2
					direction = 2
					move = True
					y :+ speed
					
				' West
				Case 3
					direction = 3
					move = True
					x :- speed
					
				' East
				Case 4
					direction = 4
					move = True
					x :+ speed
			EndSelect
		EndIf
	
		DrawImage(FireFly_Img, x-MapXOffset+vpx, y-MapYOffset+vpy, CurrentFrame)
	EndMethod
EndType
	

'---------------------------------------------
' Setup the graphics
'---------------------------------------------
Graphics 800, 600
AppTitle = "Bouldermax"
SeedRnd(MilliSecs())
Boulder_List = CreateList()
FireFly_List = CreateList()


'---------------------------------------------
' Start
'---------------------------------------------
Load_Maps()
Load_Boulders()
Create_Images(Maps[CurrentMap].colorScheme)
MapXOffset = 0
MapYOffset = 0
PlayerX = Maps[CurrentMap].startX*TileW + vpx
PlayerY = Maps[CurrentMap].startY*TileH + vpy
Maps[CurrentMap].time = Maps[CurrentMap].time*1000 + MilliSecs()


'---------------------------------------------
' Main loop
'---------------------------------------------
Repeat

	'********************
	' Update
	'********************
	Handle_Input()
	If PlayerLives =< 0 Then Notify "Game Over" ; End
	If MilliSecs() >= LastUpdate + UpdateTime
		LastUpdate = MilliSecs() + UpdateTime
		If CurrentFrame = 0 
			CurrentFrame = 1
		ElseIf CurrentFrame = 1
			CurrentFrame = 0
		EndIf
	EndIf
	If TimeLeft <= 0
		Notify "You ran out of time!"
		End
	EndIf
		
	
	'********************
	' Draw
	'********************
	Maps[CurrentMap].Draw()
	DrawImage(Player_Img, PlayerX, PlayerY, PlayerFrame)
	Draw_Boulders()
	
	'********************
	' GUI
	'********************
	SetColor 0, 0, 0
	DrawRect(0, 0, GraphicsWidth(), vpy)
	DrawRect(0, 0, vpx, GraphicsHeight())
	SetColor 255, 255, 255
	DrawText "Diamonds: " + PlayerDiamonds + "/" + Maps[CurrentMap].DiamondsNeeded, 10, 10
	DrawText "Lives: " + PlayerLives, 180, 10
	TimeLeft = (Maps[CurrentMap].time/1000)-(MilliSecs()/1000)
	DrawText "Time: " + TimeLeft, 360, 10
	DrawText "Score: " + PlayerScore, 540, 10

	
	'********************
	' Update screen
	'********************
	Flip
	Cls
	
Until KeyHit(KEY_ESCAPE)



'------------------------------------------------------
' Function: Handle_Input()
'------------------------------------------------------
Function Handle_Input()
	
	Maps[CurrentMap].map[PlayerMapX, PlayerMapY] = 0
	
	' Check if we have arrived at a correct horizontal position
	If (PlayerX+MapXOffset) Mod TileW = 0 And (PlayerY+MapYOffset) Mod TileH = 0
	 	PlayerMoving = False
		' Update cords
		PlayerMapX = (PlayerX+MapXOffset-vpx)/TileW
		PlayerMapY = (PlayerY+MapYOffset-vpy)/TileH
		
		' Check position
		If Maps[CurrentMap].map[PlayerMapX, PlayerMapY] = DIRT Then
			Maps[CurrentMap].map[PlayerMapX, PlayerMapY] = 0
		ElseIf Maps[CurrentMap].map[PlayerMapX, PlayerMapY] = DIAMOND Then 
			Maps[CurrentMap].map[PlayerMapX, PlayerMapY] = 0
			PlayerDiamonds :+ 1
			PlayerScore :+ Maps[CurrentMap].diamondValue
		ElseIf Maps[CurrentMap].map[PlayerMapX, PlayerMapY] = DOOR And PlayerDiamonds >= Maps[CurrentMap].diamondsNeeded Then
			Notify "Level Completed!"
			CurrentMap :+ 1
			Load_Boulders()
			Create_Images(Maps[CurrentMap].colorScheme)
			MapXOffset = 0
			MapYOffset = 0
			PlayerX = Maps[CurrentMap].startX*TileW + vpx
			PlayerY = Maps[CurrentMap].startY*TileH + vpy
			PlayerMapX = (PlayerX+MapXOffset-vpx)/TileW
			PlayerMapY = (PlayerY+MapYOffset-vpy)/TileH
			PlayerDiamonds = 0
			PlayerScore :+ TimeLeft
			Maps[CurrentMap].time  = Maps[CurrentMap].time*1000 + MilliSecs()
		EndIf
		
	Else
		PlayerMoving = True
		' If we are moving left
		If PlayerDirection = 3
			Move_Player(3)
		' For moving right
		ElseIf PlayerDirection = 4
			Move_Player(4)
		' For moving up
		ElseIf PlayerDirection = 1
			Move_Player(1)
		' For moving down
		ElseIf PlayerDirection = 2
			Move_Player(2)
		EndIf	
	EndIf
	
	' Check if we are not moving
	If PlayerMoving = False
		' Movement with arrows
		If KeyDown(KEY_UP)
			Move_Player(1)
		ElseIf KeyDown(KEY_DOWN)  
			Move_Player(2)
		ElseIf KeyDown(KEY_LEFT)  
			Move_Player(3)
		ElseIf KeyDown(KEY_RIGHT) 
			Move_Player(4)
		EndIf
	EndIf

EndFunction

'------------------------------------------------------
'   Fuction: Move_Player(...)
'   Purpose: Makes the player move one square
' Arguments: Dir: The direction to move the player
'------------------------------------------------------
Function Move_Player(Dir:Int)

	' Check direction
	Select Dir
			
		' Move up
		Case 1
			' Check collision
			If Maps[CurrentMap].map[PlayerMapX, PlayerMapY-1] = HARDWALL Or Maps[CurrentMap].map[PlayerMapX, PlayerMapY-1] = SOFTWALL Or ..
			   Maps[CurrentMap].map[PlayerMapX, PlayerMapY-1] = ROCK Then
				PlayerMoving = False
				
			' Move
			Else
				PlayerMoving = True
				PlayerDirection = 1
				
				' Check if we are in the middle of the screen
				If PlayerY =< GraphicsHeight()/2 - Maps[CurrentMap].scrollSpacer*TileH Then
					' Check if the map is not at it's edge
					If MapYOffset > 0
						MapYOffset :- PlayerSpeed
					Else
						PlayerY :- PlayerSpeed
					EndIf
				Else
					PlayerY :- PlayerSpeed
				EndIf
			EndIf
		
		' Move down
		Case 2
			' Check collision
			If Maps[CurrentMap].map[PlayerMapX, PlayerMapY+1] = HARDWALL Or Maps[CurrentMap].map[PlayerMapX, PlayerMapY+1] = SOFTWALL Or ..
			   Maps[CurrentMap].map[PlayerMapX, PlayerMapY+1] = ROCK Then
				PlayerMoving = False
				
			Else
				PlayerMoving = True
				PlayerDirection = 2
				
				' Check if we are in the middle of the screen
				If PlayerY >= GraphicsHeight()/2 + Maps[CurrentMap].scrollSpacer*TileH Then
					' Check if the map is not at it's edge
					If MapYOffset < Maps[CurrentMap].height*TileH Then
						MapYOffset :+ PlayerSpeed
					Else
						PlayerY :+ PlayerSpeed
					EndIf
				Else
					PlayerY :+ PlayerSpeed
				EndIf
				PlayerFrame = 2
			EndIf
		
		' Move left
		Case 3
			' Check collision
			If Maps[CurrentMap].map[PlayerMapX-1, PlayerMapY] = HARDWALL Or Maps[CurrentMap].map[PlayerMapX-1, PlayerMapY] = SOFTWALL Then
				PlayerMoving = False
				
			' Can we push a rock?
			ElseIf Maps[CurrentMap].map[PlayerMapX-1, PlayerMapY] = ROCK And (PlayerX+MapXOffset) Mod TileW = 0 Then
				' Select the correct boulder
				For Boulder = EachIn(Boulder_List)
					If Boulder.mapX = PlayerMapX - 1 And Boulder.mapY = PlayerMapY Then
												
						' If we can push him
						If Boulder.Push(3) = True Then
							
							' Just move the player, boulder will join in
							PlayerMoving = True
							PlayerDirection = 3
							
							' Check if we are in the middle of the screen
							If PlayerX =< GraphicsWidth()/2 - Maps[CurrentMap].scrollSpacer*TileW Then
								' Check if the map is not at it's edge
								If MapXOffset > 0 Then
									MapXOffset :- PlayerSpeed
								Else
									PlayerX :- PlayerSpeed
								EndIf
							Else
								PlayerX :- PlayerSpeed
							EndIf
							PlayerFrame = 0
						
						Else
							PlayerMoving = False
						EndIf
							
					EndIf
				Next
				
			Else
				PlayerMoving = True
				PlayerDirection = 3
				
				' Check if we are in the middle of the screen
				If PlayerX =< GraphicsWidth()/2 - Maps[CurrentMap].scrollSpacer*TileW Then
					' Check if the map is not at it's edge
					If MapXOffset > 0 Then
						MapXOffset :- PlayerSpeed
					Else
						PlayerX :- PlayerSpeed
					EndIf
				Else
					PlayerX :- PlayerSpeed
				EndIf
				PlayerFrame = 0
			EndIf
		
		' Move right
		Case 4
			' Check collision
			If Maps[CurrentMap].map[PlayerMapX+1, PlayerMapY] = HARDWALL Or Maps[CurrentMap].map[PlayerMapX+1, PlayerMapY] = SOFTWALL Then
				PlayerMoving = False
				
			' Can we push a rock?
			ElseIf Maps[CurrentMap].map[PlayerMapX+1, PlayerMapY] = ROCK And (PlayerX+MapXOffset) Mod TileW = 0 Then
				' Select the correct boulder
				For Boulder = EachIn(Boulder_List)
					If Boulder.mapX = PlayerMapX + 1 And Boulder.mapY = PlayerMapY Then
								
						' If we can push him
						If Boulder.Push(4) = True Then
							
							' Just move the player, boulder will join in
							PlayerMoving = True
							PlayerDirection = 4
							
							' Check if we are in the middle of the screen
							If PlayerX >= GraphicsWidth()/2 + Maps[CurrentMap].scrollSpacer*TileW Then
								' Check if the map is not at it's edge
								If MapXOffset < Maps[CurrentMap].width*TileW Then
									MapXOffset :+ PlayerSpeed
								Else
									PlayerX :+ PlayerSpeed
								EndIf
							Else
								PlayerX :+ PlayerSpeed
							EndIf
							PlayerFrame = 1
						
						Else
							PlayerMoving = False
						EndIf
							
					EndIf
				Next
				
			Else
				PlayerMoving = True
				PlayerDirection = 4
				
				' Check if we are in the middle of the screen
				If PlayerX >= GraphicsWidth()/2 + Maps[CurrentMap].scrollSpacer*TileW Then
					' Check if the map is not at it's edge
					If MapXOffset < Maps[CurrentMap].width*TileW Then
						MapXOffset :+ PlayerSpeed
					Else
						PlayerX :+ PlayerSpeed
					EndIf
				Else
					PlayerX :+ PlayerSpeed
				EndIf
				PlayerFrame = 1
			EndIf
			
	EndSelect
			
EndFunction


'------------------------------------------------------
'   Fuction: Kill_Player()
'   Purpose: Kills the player
' Arguments: Reason$: Message to print to the player
'------------------------------------------------------
Function Kill_Player(reason:String)
	
	PlayerLives :- 1
	ClearList(Boulder_List)
	ClearList(FireFly_List)
	Notify reason
	PlayerDiamonds = 0
	If PlayerLives > 0
		PlayerX = Maps[CurrentMap].startX*TileW + vpx
		PlayerY = Maps[CurrentMap].startY*TileH + vpy
		MapXOffset = 0
		MapYOffset = 0
		
		For Local x:Int=0 To Maps[CurrentMap].width-1
			For Local y:Int=0 To Maps[CurrentMap].height-1
				Maps[CurrentMap].map[x,y] = Maps[CurrentMap].originalMap[x,y]
				
				' Create boulders
				If Maps[CurrentMap].map[x,y] = ROCK Then
					Boulder = TBoulder.Create(x, y)
				EndIf
				' Create fireflys
				If Maps[CurrentMap].map[x,y] = FIREFLY Then
					FFly = TFireFly.Create(x, y)
				EndIf
			Next
		Next
	Else
		Notify "Game Over" ; End
	EndIf
	
EndFunction


'------------------------------------------------------
'   Fuction: Draw_Boulders()
'   Purpose: Draw and update all boulders
'------------------------------------------------------
Function Draw_Boulders()
	
	Local x:Int, y:Int

	' Loop trough all boulders
	For Boulder = EachIn(Boulder_List)
		Boulder.Draw()
	Next
	' Loop trough fireflys
	For FFly = EachIn(FireFly_List)
		FFly.Draw()
	Next

EndFunction


'------------------------------------------------------
'   Fuction: Load_Boulders()
'   Purpose: Loads in the boulders
'------------------------------------------------------
Function Load_Boulders()
		
		ClearList(Boulder_List)
		
		For Local x:Int = 0 To Maps[CurrentMap].width-1
			For Local y:Int = 0 To Maps[CurrentMap].height-1
				' Create boulders
				If Maps[CurrentMap].map[x,y] = ROCK Then
					Boulder = TBoulder.Create(x, y)
				
				' Create fireflys
				ElseIf Maps[CurrentMap].map[x,y] = FIREFLY Then
					FFly = TFireFly.Create(x, y)
				EndIf
			Next
		Next
		
EndFunction


'------------------------------------------------------
'   Fuction: Load_Map()
'   Purpose: Loads in a defdata defined map
'------------------------------------------------------
Function Load_Maps()
	
	Local title:String, x:Int, y:Int, i:Int
	
	' Create map packet
	Maps = New TMap[TotalMaps]
	
	For i=0 To TotalMaps-1
		' Create
		Maps[i] = TMap.Create()
		
		' Read the map title and check
		ReadData Maps[i].name
	
		' Load in the rest of the map data
		ReadData Maps[i].width 
		ReadData Maps[i].height
		ReadData Maps[i].diamondsNeeded
		ReadData Maps[i].time
		ReadData Maps[i].colorScheme
		ReadData Maps[i].startX
		ReadData Maps[i].startY
		ReadData Maps[i].diamondValue
		Maps[i].map         = New Int[Maps[i].width, Maps[i].height]
		Maps[i].originalMap = New Int[Maps[i].width, Maps[i].height]
		
		' Load tiles
		For y=0 To Maps[i].height-1
			For x=0 To Maps[i].width-1
				ReadData Maps[i].map[x,y]
				Maps[i].originalMap[x,y] = Maps[i].map[x,y]
			Next
		Next
	Next
	
EndFunction


'------------------------------------------------------
'   Fuction: Create_Images(...)
'   Purpose: Creates the tile images
' Arguments: ColorScheme: The colorscheme to use
'  Comments: ColorScheme:
'			1=Classic: Brownish
' 			2= Nature: Greenish-Pinkish
'			3=Fiction: Purpleish-Pinkish
'------------------------------------------------------
Function Create_Images(Colorscheme:Int)
	
	Local mainR:Int, mainG:Int, mainB:Int
	Local dirtR:Int, dirtG:Int, dirtB:Int
	Local glanceR:Int, glanceG:Int, glanceB:Int
	
	' Setup the right colorscheme
	Select Colorscheme
		
		Case 1
			mainR = 100 ; mainG = 100 ; mainB = 100
			dirtR = 163 ; dirtG = 110 ; dirtB = 48
			glanceR = 255 ; glanceG = 255 ; glanceB = 255
			
		Case 2
			mainR = 222 ; mainG = 155 ; mainB = 146
			dirtR = 130 ; dirtG = 110 ; dirtB = 11
			glanceR = 137 ; glanceG = 198 ; glanceB = 101
			
		Case 3
			mainR = 157 ; mainG = 84  ; mainB = 196
			dirtR = 210 ; dirtG = 136 ; dirtB = 126
			glanceR = 255 ; glanceG = 255 ; glanceB = 255
			
	EndSelect
	
	HardWall_Img = Null
	SoftWall_Img = Null
	Player_Img   = Null
	Amoeba_Img   = Null
	Door_Img     = Null
	Boulder_Img  = Null
	Dirt_Img     = Null
	Diamond_Img  = Null
	
	' --> Hard wall
	' Base
	SetColor mainR, mainG, mainB
	DrawRect(0, 0, TileW, TileH)
	' Black shadows
	SetColor 0, 0, 0
	DrawRect(4, 6, 8, 2)        ; DrawRect(8, 8, 4, 4)        ; DrawRect(TileW-12, 6, 8, 2)        ; DrawRect(TileW-8, 8, 4, 4)
	DrawRect(4, TileH-12, 8, 2) ; DrawRect(8, TileH-10, 4, 4) ; DrawRect(TileW-12, TileH-12, 8, 2) ; DrawRect(TileW-8, TileH-10, 4, 4)
	' White glance
	SetColor 255, 255, 255
	DrawRect(4, 10, 4, 2) ; DrawRect(TileW-12, 10, 4, 2) ; DrawRect(4, TileH-8, 4, 2) ; DrawRect(TileW-12, TileH-8, 4, 2)
	' Update image
	SetColor 255, 255, 255
	If Not HardWall_Img Then HardWall_Img = TImage.Create(TileW, TileH, 1, 0, 0, 0, 0)
	HardWall_Img.pixmaps[0] = GrabPixmap(0, 0, TileW, TileH)
	Cls
	
	' --> Soft wall
	' Base
	SetColor 0, 0, 0
	DrawRect(0, 0, TileW, TileH)
	' Briks of scheme's main color
	SetColor mainR, mainG, mainB
	DrawRect(4, 2, 4, 4)  ; DrawRect(8, 4, 8, 2)   ; DrawRect(20, 2, 4, 4)  ; DrawRect(24, 4, 8, 2)
	DrawRect(0, 12, 8, 2) ; DrawRect(12, 10, 4, 4) ; DrawRect(16, 12, 8, 2) ; DrawRect(28, 10, 4, 4)
	DrawRect(4, 18, 4, 4) ; DrawRect(8, 20, 8, 2)  ; DrawRect(20, 18, 4, 4) ; DrawRect(24, 20, 8, 2)
	DrawRect(0, 28, 8, 2) ; DrawRect(12, 26, 4, 4) ; DrawRect(16, 28, 8, 2) ; DrawRect(28, 26, 4, 4)
	' White glance
	SetColor 255, 255, 255
	DrawRect(4, 0, 12, 2)  ; DrawRect(8, 2, 8, 2)    ; DrawRect(20, 0, 12, 2)  ; DrawRect(24, 2, 8, 2)
	DrawRect(0, 8, 8, 4)   ; DrawRect(12, 8, 12, 2)  ; DrawRect(16, 10, 8, 2)  ; DrawRect(28, 8, 4, 2) 
	DrawRect(4, 16, 12, 2) ; DrawRect(8, 18, 8, 2)   ; DrawRect(20, 16, 12, 2) ; DrawRect(24, 18, 8, 2) 
	DrawRect(0, 24, 8, 4)  ; DrawRect(12, 24, 12, 2) ; DrawRect(16, 26, 8, 2)  ; DrawRect(28, 24, 4, 2)
	' Update iamge
	SetColor 255, 255, 255
	If Not SoftWall_Img Then SoftWall_Img = TImage.Create(TileW, TileH, 1, 0, 0, 0, 0)
	SoftWall_Img.pixmaps[0] = GrabPixmap(0, 0, TileW, TileH)
	Cls
	
	' --> Diamond
	' Base
	SetColor 0, 0, 0
	DrawRect(0, 0, TileW, TileH)
	' Stripes of main color
	SetColor mainR, mainG, mainB
	DrawRect(12, 0, 4, 2)  ; DrawRect(12, 2, 8, 2)      ; DrawRect(8, 4, 12, 2)  ; DrawRect(24, 10, 4, 2)      ; DrawRect(20, 6, 4, 2)
	DrawRect(0, 12, 4, 2)  ; DrawRect(4, 8, 4, 2)       ; DrawRect(4, 14, 28, 2) ; DrawRect(28, 18, 4, 2)      ; DrawRect(0, 16, 4, 2)
	DrawRect(4, 20, 20, 2) ; DrawRect(8, TileH-8, 4, 2) ; DrawRect(24, 22, 4, 2) ; DrawRect(20, TileH-6, 4, 2) ; DrawRect(16, TileH-4, 4, 2)
	' Stripes of dirt
	SetColor dirtR, dirtG, dirtB
	DrawRect(12, 2, 4, 2) ; DrawRect(8, 6, 12, 2)  ; DrawRect(4, 12, 24, 2)      ; DrawRect(0, 14, 4, 2)       ; DrawRect(0, 18, 4, 2)
	DrawRect(4, 10, 4, 2) ; DrawRect(4, 22, 20, 2) ; DrawRect(12, TileH-2, 8, 2) ; DrawRect(12, TileH-4, 4, 2) ; DrawRect(8, TileH-6, 4, 2)
	' White glance
	SetColor 255, 255, 255
	DrawRect(4, 16, 28, 2) ; DrawRect(4, 18, 24, 2) ; DrawRect(24, 20, 4, 2) ; DrawRect(20, TileH-8, 4, 2)
	' Update image
	SetColor 255, 255, 255
	If Not Diamond_Img Then Diamond_Img = TImage.Create(TileW, TileH, 2, 0, 0, 0, 0)
	Diamond_Img.pixmaps[0] = GrabPixmap(0, 0, TileW, TileH)
	Cls
	
	' --> Diamond second frame
	' Base
	DrawImage(Diamond_Img, 0, 0, 0)
	' Ajust the glance a lil
	SetColor 255, 255, 255
	DrawRect(8, 8, 16, 2) ; DrawRect(12, 6, 8, 2) ; DrawRect(12, 24, 12, 2) ; DrawRect(12, 26, 8, 2)
	' Add some black shadow anim updatezorz
	SetColor 0, 0, 0
	DrawRect(4, 16, 28, 2) ; DrawRect(24, 20, 4, 2)
	' Update image
	SetColor 255, 255, 255
	Diamond_Img.pixmaps[1] = GrabPixmap(0, 0, TileW, TileH)
	Cls
	
	' --> Amoeba
	' Base
	SetColor 141, 204, 104
	DrawRect(0, 0, TileW, TileH)
	' Pink border
	SetColor 222, 155, 146
	DrawRect(TileW/2-10, 0, 4, 2)       ; DrawRect(TileW/2-6, 2, 4, 2)       ; DrawRect(TileW/2-2, 4, 4, 2)       ; DrawRect(TileW/2+2, 2, 4, 2)       ; DrawRect(TileW/2+6, 0, 4, 2)
	DrawRect(0, TileH/3, 4, 2)
	DrawRect(TileW-8, TileH/3, 4, 2)    ; DrawRect(TileW-4, TileH/3-2, 4, 2) ; DrawRect(TileW-4, TileH/3+2, 4, 2)
	DrawRect(TileW/2-10, TileH-2, 4, 2) ; DrawRect(TileW/2-6, TileH-4, 4, 2) ; DrawRect(TileW/2-2, TileH-6, 4, 2) ; DrawRect(TileW/2+2, TileH-4, 4, 2) ; DrawRect(TileW/2+6, TileH-2, 4, 2)
	' Dark grey filling
	SetColor 0, 0, 0
	DrawRect(TileW/2-6, 0, 12, 2);DrawRect(TileW/2-2, 2, 4, 2)
	DrawRect(TileW-4, TileH/3, 4, 2)
	DrawRect(TileW/2-6, TileH-2, 12, 2);DrawRect(TileW/2-2, TileH-4, 4, 2)
	' Update image
	SetColor 255, 255, 255
	If Not Amoeba_Img Then Amoeba_Img = TImage.Create(TileW, TileH, 1, 0, 0, 0, 0)
	Amoeba_Img.pixmaps[0] = GrabPixmap(0, 0, TileW, TileH)
	Cls
	
	' --> Boulder
	' Base
	SetColor mainR, mainG, mainB
	DrawRect(0, 0, TileW, TileH)
	' Shine
	SetColor glanceR, glanceG, glanceB
	DrawRect(0, 4, 4, 2)   ; DrawRect(4, 2, 4, 2)   ; DrawRect(8, 0, 12, 2) ; DrawRect(12, 2, 12, 2) ; DrawRect(20, 4, 8, 6)
	DrawRect(28, 6, 4, 10) ; DrawRect(24, 12, 4, 2) ; DrawRect(16, 4, 4, 2)
	' Bit of dirt on it
	SetColor dirtR, dirtG, dirtB
	DrawRect(TileW-4, TileH/2, 4, 4)    ; DrawRect(TileW-12, 10, 4, 2)     ; DrawRect(TileW-12, 14, 4, 2) ; DrawRect(8, 12, 8, 2)
	DrawRect(4, 4, 4, 2)                ; DrawRect(8, 6, 4, 2)             ; DrawRect(12, 8, 4, 2)        ; DrawRect(16, 6, 4, 2)
	DrawRect(TileW-12, TileH/2+2, 4, 2) ; DrawRect(TileW/2, TileH-4, 4, 2) ; DrawRect(4, 10, 4, 2)
	' Black shadows
	SetColor 0, 0, 0
	DrawRect(TileW/2-4, TileH-4, 4, 2) ; DrawRect(12, TileH-8, 4, 2) ; DrawRect(8, TileH-10, 4, 2) ; DrawRect(4, TileH-12, 4, 2)
	DrawRect(8, 18, 4, 2)              ; DrawRect(4, 16, 4, 2)
	' Black to make it round
	SetColor 0, 0, 0
	DrawRect(0, 0, 8, 2)             ; DrawRect(0, 2, 4, 2)             ; DrawRect(TileW-12, 0, 12, 2) ; DrawRect(TileW-8, 2, 8, 2) 
	DrawRect(0, TileH-2, 12, 2)      ; DrawRect(0, TileH-4, 8, 2)       ; DrawRect(0, TileH-6, 4, 2)   ; DrawRect(TileW-12, TileH-2, 12, 2)
	DrawRect(TileW-8, TileH-4, 8, 2) ; DrawRect(TileW-4, TileH-8, 4, 8) ; DrawRect(TileW-4, 4, 4, 2)
	' Update image
	SetColor 255, 255, 255
	If Not Boulder_Img Then Boulder_Img = TImage.Create(TileW, TileH, 1, 0, 0, 0, 0)
	Boulder_Img.pixmaps[0] = GrabPixmap(0, 0, TileW, TileH)
	Cls
	
	' --> Player sides
	' Head of main color
	SetColor mainR, mainG, mainB 
	DrawRect(TileW-30+ 4, TileH-28+ 2, 16, 8) ; DrawRect(TileW-30+ 0, TileH-28+ 4, 4, 4) ; DrawRect(TileW-30+ 8, TileH-28+ 0, 8, 12)
	' Body
	DrawRect(TileW-30+ 8, TileH-28+ 12, 8, 16)
	' Cloths
	SetColor glanceR, glanceG, glanceB
	DrawRect(TileW-30+ 8, TileH-28+ 12, 8, 2) ; DrawRect(TileW-30+ 8, TileH-28+ 16, 8, 2) ; DrawRect(TileW-30+ 8, TileH-28+ 20, 8, 2) ; DrawRect(TileW-30+ 4, TileH-28+ 14, 4, 2)
	' Legs, dirty ;)
	SetColor dirtR, dirtG, dirtB ; DrawRect(TileW-30+ 4, TileH-28+ 22, 12, 4)
	' Eye: black
	SetColor 0, 0, 0 ; DrawRect(TileW-30+ 4, TileH-28+ 4, 4, 4)
	' Update image
	SetColor 255, 255, 255
	If Not Player_Img Then Player_Img = TImage.Create(TileW, TileH, 3, 0, 0, 0, 0)
	Player_Img.pixmaps[0] = GrabPixmap(0, 0, TileW, TileH)
	Player_Img.pixmaps[1] = XFlipPixmap(Player_Img.pixmaps[0])
	Cls
	
	' --> Player front
	' Head: main color
	SetColor mainR, mainG, mainB
	DrawRect(8, 2, 4, 10) ; DrawRect(20, 2, 4, 10) ; DrawRect(4, 6, 24, 4)  ; DrawRect(12, 4, 8, 20)
	' Arms & body: main color
	DrawRect(8, 14, 16, 2) ; DrawRect(4, 16, 4, 2) ; DrawRect(24, 16, 4, 2) 
	' Dirty pants :P
	SetColor dirtR, dirtG, dirtB
	DrawRect(8, 24, 4, 10) ; DrawRect(20, 24, 4, 10)
	' Glancy shirt & shoes
	SetColor glanceR, glanceG, glanceB
	DrawRect(12, 16, 8, 2) ; DrawRect(12, 20, 8, 2) ; DrawRect(12, 24, 8, 2) ; DrawRect(4, 18, 4, 2) ; DrawRect(24, 18, 4, 2)
	DrawRect(4, 30, 8, 2)  ; DrawRect(20, 30, 8, 2)
	' Black eyes
	SetColor 0, 0, 0
	DrawRect(8, 6, 4, 4) ; DrawRect(20, 6, 4, 4)
	' Update image
	SetColor 255, 255, 255
	Player_Img.pixmaps[2] = GrabPixmap(0, 0, TileW, TileH)
	Cls
	
	' --> Dirt
	' Base
	SetColor dirtR, dirtG, dirtB
	DrawRect(0, 0, TileW, TileH)
	' Black to make detail
	SetColor 0, 0, 0
	DrawRect(0, 0, 8, 2)        ; DrawRect(8, 2, 4, 2)         ; DrawRect(14, 0, 4, 2)             ; DrawRect(14, 2, 4, 2) 
	DrawRect(TileW-8, 0, 4, 4)  ; DrawRect(TileW-12, 2, 4, 2)  ; DrawRect(0, 4, 4, 2)              ; DrawRect(TileW-4, 4, 4, 2)
	DrawRect(TileW-4, 10, 4, 2) ; DrawRect(TileW-4, 14, 4, 2)  ; DrawRect(TileW-4, 18, 4, 2)       ; DrawRect(TileW-4, 26, 4, 2) 
	DrawRect(TileW-4, 30, 4, 2) ; DrawRect(TileW-8, 28, 4, 4)  ; DrawRect(TileW-12, TileH-2, 4, 2) ; DrawRect(6, TileH-2, 6, 2)
	DrawRect(0, TileH-8, 4, 2)  ; DrawRect(0, TileH/3+4, 4, 2) ; DrawRect(0, TileH/3+8, 4, 2)    
	' Contast with primary color
	SetColor mainR, mainG, mainB
	DrawRect(8, 4, 4, 2)               ; DrawRect(TileW-8, 4, 4, 2)
	DrawRect(0, TileH/3+2, 4, 2)       ; DrawRect(4, TileH/3, 4, 2)
	DrawRect(10, TileH/3+2, 8, 2)      ; DrawRect(18, TileH/3, 4, 2)         ; DrawRect(TileW-16, TileH/3+10, 4, 2) ; DrawRect(TileW-16, TileH/3+14, 4, 2)
	DrawRect(TileW-8, TileH/3+4, 4, 2) ; DrawRect(TileW-8, TileH/3+12, 4, 2) ; DrawRect(TileW-8, TileH/3+16, 4, 2)
	DrawRect(4, TileH/2+4, 4, 8)       ; DrawRect(TileH-6, TileW+12, 4, 2)
	' Black grey shadows
	SetColor 0, 0, 0
	DrawRect(8, 6, 4, 2)          ; DrawRect(TileW-8, 6, 4, 2)    ; DrawRect(10, TileH/3, 4, 2)    ; DrawRect(24, TileH/3-4, 4, 2)
	DrawRect(4, TileH/3-2, 4, 2)  ; DrawRect(4, TileH/3+4, 4, 2)  ; DrawRect(20, TileH/3+2, 4, 2)  ; DrawRect(20, TileH/3-2, 4, 2)
	DrawRect(8, TileH/2+4, 4, 2)  ; DrawRect(12, TileH/2+6, 4, 2) ; DrawRect(16, TileH/2+8, 4, 2)  ; DrawRect(20, TileH/2+10, 4, 2)
	DrawRect(4, TileH/2+12, 4, 2) ; DrawRect(8, TileH/2+14, 8, 1) ; DrawRect(12, TileH/2+12, 4, 2)
	' Update image
	SetColor 255, 255, 255
	If Not Dirt_Img Then Dirt_Img = TImage.Create(TileW, TileH, 1, 0, 0, 0, 0)
	Dirt_Img.pixmaps[0] = GrabPixmap(0, 0, TileW, TileH)
	Cls
	
	' --> Door (2 framed animation)
	' Base closed
	SetColor 0, 0, 0
	DrawRect(0, 0, TileW, TileH)
	' Borders
	SetColor mainR, mainG, mainB
	DrawRect(0, 0, 32, 4) ; DrawRect(0, 0, 4, 32) ; DrawRect(0, 28, 32, 4) ; DrawRect(28, 0, 4, 32)
	' Update 1st frame
	SetColor 255, 255, 255
	If Not Door_Img Then Door_Img = TImage.Create(TileW, TileH, 2, 0, 0, 0, 0)
	Door_Img.pixmaps[0] = GrabPixmap(0, 0, TileW, TileH)
	Cls
	' Base open = titanium wall
	DrawImage(HardWall_Img, 0, 0)
	' Borders
	SetColor mainR, mainG, mainB
	DrawRect(0, 0, 32, 4) ; DrawRect(0, 0, 4, 32) ; DrawRect(0, 28, 32, 4) ; DrawRect(28, 0, 4, 32)
	' Update 1st frame
	SetColor 255, 255, 255
	Door_Img.pixmaps[1] = GrabPixmap(0, 0, TileW, TileH)
	Cls
	
	' --> Fire Fly (2 framed animation)
	' Base: black
	SetColor 0, 0, 0
	DrawRect(TileW, TileH, 0, 0)
	' White border
	SetColor 255, 255, 255
	DrawRect(0, 0, 32, 4) ; DrawRect(0, 0, 4, 32) ; DrawRect(28, 0, 4, 32) ; DrawRect(0, 28, 32, 4)
	' Main filling
	SetColor mainR, mainG, mainB
	DrawRect(4, 4, 24, 4) ; DrawRect(4, 4, 4, 24) ; DrawRect(24, 4, 4, 24) ; DrawRect(4, 24, 24, 4) ; DrawRect(12, 12, 8, 8)
	' Update 1st frame
	SetColor 255, 255, 255
	If Not FireFly_Img Then FireFly_Img = TImage.Create(TileW, TileH, 2, 0, 0, 0, 0)
	FireFly_Img.pixmaps[0] = GrabPixmap(0, 0, TileW, TileH)
	Cls
	' Second frame switches black and main color:)
	' Base, old image
	DrawImage(FireFly_Img, 0, 0)
	' Swap main color one ring up !*! test: also swapping outer and innder border
	SetColor mainR, mainG, mainB
	DrawRect(8, 8, 16, 4) ; DrawRect(8, 8, 4, 16) ; DrawRect(20, 8, 4, 16) ; DrawRect(8, 20, 16, 4)
	DrawRect(0, 0, 32, 4) ; DrawRect(0, 0, 4, 32) ; DrawRect(28, 0, 4, 32) ; DrawRect(0, 28, 32, 4)
	' Draw black on purples old place !*! test: also swapping outer and innder border
	SetColor 0, 0, 0
	DrawRect(4, 4, 24, 4) ; DrawRect(4, 4, 4, 24) ; DrawRect(24, 4, 4, 24) ; DrawRect(4, 24, 24, 4) ; DrawRect(12, 12, 8, 8)
	' Update 2nd frame
	SetColor 255, 255, 255
	FireFly_Img.pixmaps[1] = GrabPixmap(0, 0, TileW, TileH)
	Cls
	
EndFunction

	

'##############################
' Maps
' 0 = Black
' 1 = Sand
' 2 = Softwall
' 3 = HardWall
' 4 = Boulder
' 5 = Diamond
' 6 = Door
' 7 = FireFly
'##############################
'	    Title         Width  Height	  Needed diamonds	    Time (seconds)  Colorscheme			  Start X  Start Y  Diamond Value
DefData "Intro",       40,    22,       12,                150,             1,           3,     2,       10
DefData 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
DefData 3, 1, 1, 1, 1, 1, 1, 0, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 4, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 4, 1, 1, 1, 3
DefData 3, 1, 4, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 1, 1, 4, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 3
DefData 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 4, 1, 4, 1, 1, 4, 1, 1, 1, 1, 1, 1, 4, 1, 4, 1, 3
DefData 3, 4, 1, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 4, 1, 1, 4, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 3
DefData 3, 4, 1, 0, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 4, 1, 4, 4, 3
DefData 3, 1, 1, 1, 0, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 4, 1, 0, 4, 1, 1, 1, 1, 1, 1, 4, 1, 4, 4, 3
DefData 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 4, 1, 4, 1, 3
DefData 3, 1, 0, 1, 1, 1, 1, 1, 1, 5, 1, 1, 0, 1, 1, 1, 4, 1, 1, 5, 1, 0, 1, 1, 1, 1, 4, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3
DefData 3, 1, 1, 5, 1, 1, 1, 4, 0, 4, 1, 1, 1, 5, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 3
DefData 3, 1, 1, 1, 4, 0, 4, 0, 1, 4, 1, 1, 1, 1, 4, 1, 1, 4, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3
DefData 3, 1, 1, 1, 1, 4, 0, 1, 1, 4, 1, 1, 0, 0, 1, 1, 1, 1, 4, 1, 1, 4, 4, 4, 1, 1, 1, 1, 1, 1, 4, 4, 4, 1, 1, 1, 1, 4, 1, 3
DefData 3, 1, 4, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 5, 1, 1, 4, 1, 1, 4, 1, 4, 5, 1, 1, 1, 1, 1, 4, 1, 4, 5, 1, 1, 5, 0, 1, 3
DefData 3, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 4, 0, 4, 1, 1, 1, 1, 1, 1, 4, 0, 4, 1, 1, 1, 1, 4, 3
DefData 3, 1, 0, 4, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3
DefData 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 4, 1, 1, 4, 1, 1, 1, 1, 3
DefData 3, 0, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 4, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 4, 4, 1, 6, 3
DefData 3, 0, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 4, 4, 1, 1, 3
DefData 3, 1, 0, 1, 1, 4, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 4, 1, 4, 5, 1, 1, 1, 4, 1, 1, 3
DefData 3, 1, 1, 1, 1, 4, 5, 1, 0, 1, 1, 1, 1, 4, 1, 1, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 4, 5, 1, 1, 1, 1, 1, 4, 3
DefData 3, 1, 5, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 4, 1, 1, 1, 1, 4, 1, 3
DefData 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3

'	    Title         Width  Height	  Needed diamonds	    Time (seconds)  Colorscheme			  Start X  Start Y  Diamond Value
DefData "Maze",		40,	   22,      23,                150,            3,            3,      2,       15
DefData 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
DefData 3, 4, 1, 2, 2, 1, 0, 4, 4, 1, 2, 1, 1, 1, 4, 2, 4, 1, 1, 4, 1, 1, 1, 1, 2, 1, 1, 1, 4, 1, 1, 1, 1, 1, 4, 2, 1, 5, 1, 3
DefData 3, 1, 1, 1, 2, 1, 5, 1, 4, 1, 2, 1, 1, 1, 2, 2, 2, 1, 1, 2, 0, 4, 1, 1, 1, 1, 4, 1, 1, 4, 1, 4, 1, 1, 1, 2, 1, 2, 4, 3
DefData 3, 1, 1, 1, 1, 2, 1, 0, 4, 5, 1, 1, 4, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 4, 1, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 3
DefData 3, 5, 1, 2, 1, 1, 2, 4, 2, 4, 1, 1, 4, 1, 1, 1, 1, 2, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 4, 1, 1, 4, 4, 1, 1, 1, 1, 1, 2, 3
DefData 3, 4, 1, 2, 1, 1, 1, 2, 1, 1, 4, 1, 2, 2, 1, 1, 4, 1, 1, 2, 5, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 4, 4, 1, 1, 1, 1, 1, 2, 3
DefData 3, 4, 4, 1, 1, 4, 1, 1, 1, 1, 2, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 4, 1, 1, 4, 4, 1, 1, 1, 1, 1, 1, 4, 1, 5, 2, 2, 1, 1, 3
DefData 3, 1, 1, 4, 1, 2, 2, 1, 1, 4, 1, 4, 4, 1, 1, 1, 2, 1, 1, 1, 1, 4, 1, 1, 4, 4, 1, 1, 1, 1, 1, 1, 2, 1, 4, 1, 2, 1, 4, 3
DefData 3, 1, 1, 2, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 5, 1, 4, 1, 1, 2, 2, 4, 1, 1, 1, 4, 1, 2, 1, 2, 4, 1, 1, 2, 4, 1, 1, 5, 4, 3
DefData 3, 4, 0, 4, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 5, 1, 4, 1, 1, 2, 2, 4, 1, 1, 1, 4, 1, 1, 5, 1, 2, 1, 1, 1, 2, 1, 1, 4, 2, 3
DefData 3, 1, 4, 1, 2, 2, 1, 1, 1, 1, 1, 4, 4, 2, 4, 1, 1, 5, 1, 2, 1, 2, 4, 1, 1, 1, 2, 4, 1, 1, 1, 2, 4, 1, 1, 5, 1, 4, 1, 3
DefData 3, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 4, 4, 2, 4, 1, 1, 4, 1, 2, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 4, 1, 2, 2, 1, 1, 4, 2, 1, 3
DefData 3, 1, 2, 1, 4, 1, 4, 1, 2, 1, 1, 1, 2, 2, 4, 1, 1, 4, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 4, 1, 1, 3
DefData 3, 1, 2, 1, 4, 1, 4, 1, 2, 1, 5, 1, 2, 1, 2, 4, 1, 1, 2, 4, 1, 1, 1, 1, 4, 1, 1, 4, 1, 4, 4, 1, 1, 1, 1, 1, 2, 1, 1, 3
DefData 3, 2, 1, 1, 2, 4, 2, 4, 1, 1, 4, 1, 1, 1, 1, 2, 1, 1, 1, 5, 1, 1, 1, 2, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 5, 3
DefData 3, 2, 1, 1, 1, 2, 2, 4, 1, 1, 2, 1, 5, 1, 1, 1, 2, 4, 1, 1, 4, 1, 4, 1, 1, 1, 4, 1, 1, 2, 4, 1, 1, 1, 1, 1, 1, 2, 1, 3
DefData 3, 2, 1, 5, 1, 1, 1, 1, 4, 1, 2, 2, 1, 1, 4, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 2, 4, 1, 1, 1, 1, 1, 1, 2, 1, 3
DefData 3, 1, 1, 4, 1, 1, 1, 1, 2, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 4, 1, 4, 4, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 4, 1, 2, 1, 1, 1, 3
DefData 3, 4, 1, 2, 2, 1, 1, 4, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 4, 1, 4, 4, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 4, 5, 1, 1, 4, 1, 6
DefData 3, 2, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 4, 1, 4, 5, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 2, 2, 1, 1, 2, 4, 1, 1, 5, 1, 2, 1, 3
DefData 3, 4, 4, 1, 1, 1, 2, 1, 1, 1, 1, 1, 4, 1, 4, 5, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 4, 1, 2, 5, 1, 5, 1, 4, 2, 1, 4, 1, 1, 3
DefData 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3

'	    Title         Width  Height	  Needed diamonds	    Time (seconds)  Colorscheme			  Start X  Start Y  Diamond Value
DefData "Rooms",        40,   10,      0,                 100,            2,           1,       1,        20
DefData 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
DefData 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3
DefData 3, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3
DefData 3, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3
DefData 3, 1, 1, 1, 1, 1, 7, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3
DefData 3, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3
DefData 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3
DefData 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3
DefData 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3
DefData 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3

Just paste and run

It's probably the most complex thing I have ever coded lol. Please leave a comment

Nice start Conard.

I'm not going to be able to compete in this one. This time of year is always very busy for me.

I am interested if anyone is going to produce sound without media.

The no-media rule has been dropped eh.


I am interested if anyone is going to produce sound without media.



It's possible. i've done it- but as CS_TBL said, that rule got dropped.

The droppings have been requested .. :P


I am interested if anyone is going to produce sound without media.

It's possible. i've done it- but as CS_TBL said, that rule got dropped.



Shame that rule has been dropped; it was the challenging bit.

So Cygnus; how did you do it? Did you use a load of inline Data, or generate the wave envelopes from code?

aye.. I was just about to start figuring out how to do some sort of sounds without any media.
any hints ? :)

Conard - I had a quick go with your code last night.. thats a pretty good start. Nice Graphics too.

@MichaelB - fantastic piece of coding for one hour...... I'm not worthy {;-) , even if they dropped the 'no-loading' pre-requisite - I reckon the judge(s) would be somewhat swayed by an individuals coding prowess wrt image creation.

Of course image generation is more impressive than image loading, esp. when the images are good. Most ppl here however requested to drop that rule. Perhaps after this challenge a new game challenge with *everything* in code, no media etc.. perhaps a simpler game type..


So Cygnus; how did you do it? Did you use a load of inline Data, or generate the wave envelopes from code?



generate a Wave file in memory. Load it using standard commands.

I dont have the game in blitzmax but check out the mushroom collector B3D game which uses the blitz3D version of my sound system to do the same thing.