a basic platformer, key concepts.

BlitzMax Forums/BlitzMax Beginners Area/a basic platformer, key concepts.

Yahfree(Posted 2007) [#1]
whats the best way to do this? i'm going to have to knock out a basic tile-map editor to create the levels, but i'm then how would i read the levels? should i create a sort of color map, where each color is a different type of tile, and build the level programaticly?

i wouldnt think of creating a whole image for each level, that would make the final download huge with all the images in it.

what about creating a very small 'section' image where each little pixel is a different color, and the program would read it, that would be very small, and each little section would be interlinked, and once the player runs off one section, it would jump to the next, what about smooth transaction between these sections?

anyone willing to share some ideas? i just got BlitzMax less then a week ago, created a simple breakout clone for orientation, and now i'm gonna try to create something a little bigger for a learning project.


Big&(Posted 2007) [#2]
If you have a look here:
http://www.blitzbasic.com/codearcs/codearcs.php?code=823
Its for Blitz Basic but the concepts are all the same.

Best way would probably be to either write your data out to a file where each byte/word represents a block in your level and then read them into an array in your game or get the editor to save out data/array data you can include in your code.

Hope this helps.


smilertoo(Posted 2007) [#3]
FishED was coming on great, then it appeared to be abandoned.


Yahfree(Posted 2007) [#4]
hmm cool, thanks for the ideas, at the moment working on a tile system, and i set up basic player movement(jump, left, right) the player is a white cube at the moment, so are the tiles, i created 20x20 tiles, on a 800,600 screen so they match correctly,

then for griding when i create a tile i will declare it in a X/Y grid of X: 0-40 and Y: 0-30 then in the program it will take that number and times that by 20 (the tiles w/h) creating a grided x/y position on the screen.

now i need to come up with some way for the program to place the tiles based on some sort of level format..

so my future level editor will basicly spit out a chunk of code like this:
(1=solid 0 = air)
should be 39 chars by 29 chars (my grid size)
111111111111111111111111111111111111111
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
100000000000000000000000000000000000001
111111111111111111111111111111111111111
111111111111111111111111111111111111111


now i have some experience reading off of .txt files, but the less media i have to lug around the better, so what are my options for doing it programaticly? i'v seen some things like this done in data, but i don't know exactly how that works (have not tried it) any suggestions?


Amon(Posted 2007) [#5]

FishED was coming on great, then it appeared to be abandoned.



Yes, and when I bought it I never received any license info nor any replies to the several emails I sent the author.

As for a platformer take a look at this code I started and which a few guys helped me get working. You need a 32/32 pixel image for the player and tile.



SuperStrict


Graphics 800 , 600

Global Tiles:TImage = LoadImage("tile.png") 
Global Player:TImage = LoadImage("player1632.png") 



Const MAPWIDTH:Int = 800/32
Const MAPHEIGHT:Int = 600/32

Global Map:Int[MAPWIDTH , MAPHEIGHT]

Global PlayerX:Float
Global PlayerY:Float

Global Player_Width:Int = 16
Global Player_Height:Int = 32

Global CheckPlayerPosition:Int = 0

Global Direction:Int = -1

Global Jump:Int = 0
Const Gravity:Float = 0.2
Global JumpHeight:Float = 5.3
Global CanJump:Int = 1
Global Falling:Int = 0


ReadLevelData() ' We Read the level data

While Not KeyHit(KEY_ESCAPE)
	
	Cls
	
	DrawMap()
	CheckIfPlayerCollideWithTile()
	DrawPlayer()
	MovePLayer()
	DoJump()
	
	
	Flip
	
	
Wend

'######################################################
'#### Function DrawPLayer()							  #
'#### Draws Player to Screen and gets Player Position #
'######################################################
Function DrawPlayer()
	If CheckPlayerPosition = 0 
							   		
	For Local x:Int = 0 Until MAPWIDTH
		For Local y:Int = 0 Until MAPHEIGHT
			Select Map[x, y]
				Case 2
					PlayerX = getX(x) 
					PlayerY = getY(y) 
					CheckPlayerPosition = 1
			End Select
		Next
	Next
	EndIf
	DrawText "PlayerX = " +PlayerX , 0 , 20 
	
	DrawImage Player, PlayerX , PlayerY , 0	
End Function

'#################################################
'###	Function MovePLayer()					 #	
'## 	Moves Player and checks outer boundaries #	
'#################################################
Function MovePLayer()
	
	If KeyDown(KEY_LEFT) And Not KeyDown(KEY_RIGHT)
			Direction = 0
			PlayerX:-2
	ElseIf KeyDown(KEY_RIGHT) And Not KeyDown(KEY_LEFT)
			Direction = 1
			PlayerX:+2
	End If
	
	If PlayerX - 32 <= 0
		PlayerX:+2
	ElseIf PlayerX >= 800 - 32
		PlayerX:-2
	End If
End Function

'##########################################################
'### Function CheckIfPlayerCollideWithTile()			  #
'### Checks to see if the player has collided with a tile #
'### Checks also if the Player is falling                 #
'##########################################################
Function CheckIfPlayerCollideWithTile()
'#Region 
	Select Direction
		Case 1
		If Jump = 0
			If Map[(PlayerX - Player_Width) / 32 + 1, PlayerY / 32]= 1
				PlayerX:-2
			EndIf
		EndIf
		If Jump = 1 and PlayerX >= 784 - 32
			If Map[(PlayerX - Player_Width) / 32 + 1, PlayerY / 32]= 1
				PlayerX:-2
			EndIf
		End If
		Case 0
		If Jump = 0
			If Map[(PlayerX + Player_Width) / 32, PlayerY / 32]= 1
				PlayerX:+2
			End If
		EndIf
	End Select
		
'#End Region 

	If Falling = 1
		PlayerY:+3.2
		If Map[(PlayerX + Player_Width) / 32, PlayerY / 32 + 1]= 1 or Map[(PlayerX - Player_Width * 2) / 32 + 1, PlayerY / 32 + 1]= 1
			
			If (PlayerY mod 32.0) <= 6.4
			                             
				PlayerY = PlayerY - (PlayerY mod 32) 
					
						Jump = 0                        
						Falling = 0
						CanJump = 1
						JumpHeight = 5.5
								
			EndIf
		EndIf
	End If
	
	If not Map[(PlayerX + Player_Width) / 32, PlayerY / 32 + 1]and not Map[(PlayerX - Player_Width * 2) / 32 + 1, PlayerY / 32 + 1]
		If Jump = 0
			Falling = 1
		End If
	End If
	
	
		
End Function

'##############################################
'### Function DoJump()                        #
'### Makes our player jump                    #
'##############################################
Function DoJump()
	If KeyHit(KEY_SPACE) and CanJump = 1
		Jump = 1
		CanJump = 0
	End If
	
	If Jump = 1
		PlayerY:-JumpHeight
		JumpHeight:-Gravity
		If JumpHeight <= - 1.0 or PlayerY < 32
			Falling = 1
		EndIf
	End If
	
	
End Function

'########################################
'### Function DrawMap()                 #
'### We Draw the Map to screen          #
'########################################
Function DrawMap()
	For Local x:Int = 0 Until MAPWIDTH
		For Local y:Int = 0 Until MAPHEIGHT
			Select Map[x, y]
				Case 1
					DrawImage Tiles, x * 32, y * 32, 0
			End Select
		Next
	Next
End Function

'#######################################################
'### Function ReadLevelData()            			   #
'### We read the data stored in the defdata statements #
'#######################################################
Function ReadLevelData()
	For Local y:Int = 0 Until MAPHEIGHT
		For Local x:Int = 0 Until MAPWIDTH
			Local Data:Int
			ReadData Data
			Map[x, y]= Data
		Next
	Next
End Function

Function getX:Int(x:Int)
   Return 32 * x '+ offsetX
End Function

Function getY:Int(y:Int)
   Return 32 * y '+ offsetX
End Function

DefData 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
DefData 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
DefData 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1
DefData 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
DefData 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1
DefData 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
DefData 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1
DefData 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
DefData 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
DefData 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
DefData 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1
DefData 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
DefData 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1
DefData 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
DefData 1, 0, 0, 0, 2, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1
DefData 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
DefData 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
DefData 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



Yahfree(Posted 2007) [#6]
nice example Amon


Jesse(Posted 2007) [#7]
.


Jesse(Posted 2007) [#8]
.


Yahfree(Posted 2007) [#9]
Amon reads data with 'ReadData Data' how would you seperate them? like create different levels for example?


Amon(Posted 2007) [#10]
Hi Dude.

Use a label. eg

#Level1
DefData 0, 1, 0, 1

#Level2
DefData 1, 0, 1, 0

#level3
DefData 0, 0, 1, 1


Then when you need to read say Level 2, you simple use the RestoreData command.

eg.

RestoreData Level2


With Restoredata you can use the label name to jump to a certain set of defdata statements.

Hope that helps. :)


Yahfree(Posted 2007) [#11]
thanks.

slightly unrelated but why doesnt this NOT make 'Aliens' in the '0' spots?

'Create Alien Objects
For i=1 To 28
	For i2=1 To 7
		RestoreData LEVEL1
		Local Datastorage:Int
		ReadData Datastorage
		ALIEN_LAYOUT[i-1,i2-1] = Datastorage
		If ALIEN_LAYOUT[i-1,i2-1] >= 1
			Local Alien:TAlien = New TAlien
			Alien.Create i+1,i2+1,ALIEN_LAYOUT[i-1,i2-1]
		End If
	Next
Next

#LEVEL1
DefData 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
DefData 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
DefData 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
DefData 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
DefData 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DefData 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DefData 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DefData 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0



that makes a 28,7 grid of aliens, when it should work with the 0's making a more complex shape..


Amon(Posted 2007) [#12]
Try this.

'Create Alien Objects

RestoreData LEVEL1
For i=1 To 28
	For i2=1 To 7
		Local Datastorage:Int
		ReadData Datastorage
		ALIEN_LAYOUT[i, i2] = Datastorage
	Next
Next

For x = 1 To 28
	For y = 1 To 7
		If ALIEN_LAYOUT[i - 1, i2 - 1] >= 1
			Local Alien:TAlien = New TAlien
			Alien.Create x + 1, y + 1, ALIEN_LAYOUT[x, y] 
		End If
	Next
Next

#LEVEL1
DefData 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
DefData 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
DefData 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
DefData 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0
DefData 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DefData 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DefData 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DefData 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0


Here is a little test example to show you how to switch Levels.

SuperStrict


Graphics 800, 600

Global AlienArray:Int[10, 4] 

Global SelectLevel:Int = -1

RestoreData Level1

For Local y:Int = 0 Until 4
	For Local x:Int = 0 Until 10
		Local Data:Int
		ReadData Data
		AlienArray[x, y] = Data
	Next
Next

While Not KeyHit(KEY_ESCAPE) 
	Cls
		DrawAliens() 
		
		If KeyHit(KEY_1) 
			RestoreData Level1
				For Local y:Int = 0 Until 4
					For Local x:Int = 0 Until 10
						Local Data:Int
						ReadData Data
						AlienArray[x, y] = Data
					Next
				Next
		End If
		
		If KeyHit(KEY_2) 
			RestoreData Level2
				For Local y:Int = 0 Until 4
					For Local x:Int = 0 Until 10
						Local Data:Int
						ReadData Data
						AlienArray[x, y] = Data
					Next
				Next
		End If
		
	Flip
WEnd

Function DrawAliens() 
	
	For Local x:Int = 0 Until 10
		For Local y:Int = 0 Until 4
			If AlienArray[x, y] = 1
				SetColor 255, 255, 255
				DrawRect x * 50, y * 50, 20, 20
			EndIf
		Next
	Next

End Function


#Level1
DefData 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
DefData 0, 1, 1, 1, 1, 1, 1, 1, 1, 0
DefData 0, 0, 1, 1, 1, 1, 1, 1, 0, 0
DefData 0, 0, 0, 1, 1, 1, 1, 0, 0, 0

#Level2
DefData 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
DefData 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
DefData 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
DefData 0, 1, 0, 1, 0, 1, 0, 1, 0, 1



Yahfree(Posted 2007) [#13]
.

Thanks for your help amon


Yahfree(Posted 2007) [#14]
errr, i got it to work, was a small typo on one line!! oi i hate those very small bugs