Organization

Blitz3D Forums/Blitz3D Programming/Organization

wizzlefish(Posted 2005) [#1]
I've completely restarted my current project, because of lack of organization. Although I have put together a new "template," I guess you could call it. Here'sa my coda:

;------------------------------;
;  O P E R A T I O N   6 0 0   ;
;    A No Enemies Production   ;
;    A sci-fi FPS-genre game   ;
;One of the first of its series;
;------------------------------;

;START-UP
.startup
Graphics3D 800,600
AppTitle "Operation 600"
SetBuffer BackBuffer()
AutoMidHandle True

;TYPES
.types

;player type
Type player
	Field pivot                             ;pivot entity
	Field camera                            ;camera entity
	Field x,y,z                             ;player's position
	Field health                            ;player health
	Field w_entity                          ;weapon entity
	Field w_ammo                            ;ammo in weapon
	Field w_type$                           ;type/name of weapon
	Field w_damage                          ;damage the weapon does
	Field w_offsetx, w_offsety, w_offsetz   ;weapon offset values
	Field running                           ;if the player is running or not (true/false)
End Typ

;object type
Type obj
	Field obj_type$                         ;enemy, car, box, etc.
	Field x,y,z                             ;object position
	Field e_weapon                          ;enemy's weapon - leave at "0" if not an enemy
	Field entity                            ;the actual mesh
	Field alpha#                            ;alpha of object
	Field shininess#                        ;shininess of object
	Field c_speed#                          ;car speed - leave at "0" if not a car
	Field c_wheels[4]                       ;car wheels - don't use if not a car
	Field x_vel#, y_vel#, z_vel#            ;velocity of the object
End Type 




;GLOBALS AND CONSTANTS
.globals

;CAMERA
Global cam_x#,cam_z#,cam_pitch#,cam_yaw#						;camera position
Global dest_cam_x#,dest_cam_z#,dest_cam_pitch#,dest_cam_yaw#	;camera destination




;MENU
Global mouse = LoadImage("media\menu\mouse.png")
Global glow = LoadImage("media\menu\glow.png")
Global title = LoadImage("media\menu\title1.png")
Global 




;MAINLOOP
While Not KeyDown(1)

	;do main loop stuff here

Wend



;INITIALIZING FUNCTIONS

;initilizes level
Function InitLevel(level) ;"level" is the level ID number. the level ID number is the number following the level mesh. "lvl0.op" - "0" would be level ID

	LoadLevel("lvl"+level+".op") ;if level=0, this would load "lvl0.op"
	
		
	
End Function

;UPDATING FUNCTIONS

;updates game/menu
Function UpdateLogic(logic$)

	Select logic$
		;game
		Case "game"
		
			;do game stuff
			
		Case "menu"
		
			UpdateMenu()
			
			RenderWorld
			UpdateWorld
			
			Flip 
			
	End Select 

End Function

;updates camera
Function UpdateCamera()
	
	;mouse look
	
	
	;camera move

End Function

;updates gun
Function UpdateGun(current_gun) ;"current_gun" is equal to the player's current gun set in "UpdateCamera()"

	;gun switch
	
	;gun shoot
	

End Function

;updates misc. actions
Function UpdateMiscActions()

	;do misc. stuff here

End Function

;updates all objects
Function UpdateObject()
	
	For o.obj = Each obj
	
		;do object stuff here
	
	Next 
		
End Function

;updates menu
Function UpdateMenu()
	
	;do menu stuff here

End Function 

;EXTERNAL FUNCTIONS 

;loads level
Function LoadLevel(filepath$)

	;load level here

End Function 



jfk EO-11110(Posted 2005) [#2]
your obj type still needs a lot of information. I suggest to do a systematic wrapping of all possible parameters, simply read trough the command reference and implement every possible thing (mainly trough entity control chapter, but not only). Things like Rotation, Scaling etc... but as I said, instead of torturing your brain when you try to think of everything neccessary, instead simply pick up everything in the command reference. Then you still may drop things that are not required.


wizzlefish(Posted 2005) [#3]
Yeah - I was thinking about the scale, rotation, etc. but I thought I didn't have to put that in the type. Here's the code for the "CreateObject" function:
;OBJECT FUNCTIONS

;creates an object
Function CreateObject(type_of_object$, name$, filepath$, x=0, y=0, z=0, alpha#=1.0, shininess#=0.0, xv#=0, yv#=0, zv#=0, scalex#=1, scaley#=1, scalez#=1, rx#, ry#, rz#)
	
	;create object
	newObject.obj = New obj
	
	newObject\obj_type$ = type_of_object$
	newObject\name$ = name$
	newObject\entity = LoadMesh(filepath$)
	newObject\x = x
	newObject\y = y
	newObject\z = z
	newObject\alpha# = alpha#
	newObject\shininess = shininess#
	newObject\x_vel# = xv#
	newObject\y_vel# = yv#
	newObject\z_vel# = zv#
	
	;build object
	EntityAlpha newObject\entity, alpha#
	EntityShininess newObject\entity, shininess#
	PositionEntity newObject\entity, newObject\x, newObject\y, newObject\z
	ScaleEntity newObject\entity, scalex#, scaley#, scalez#
	RotateEntity newObject\entity, rx#, ry#, rz#
	
End Function 



Clarks(Posted 2005) [#4]
take all of your global camera variable and make a global type out of it.


wizzlefish(Posted 2005) [#5]
Sounds good.


Techlord(Posted 2005) [#6]
Opto,

To help organize a project, I devised this set of generic Coding Conventions. This set of rules made it easier for me to recognize and document code.

But, its hard to follow the rules if you dont stick to your guns. If dont stick your guns, you will find yourself all wrapped up in speghetti code again and again.

Once you develop a some coding standards, you find it much easier to reuse code. You can also write coding wizards that generate code for you. In the end a little discipline will save lots of time.


wizzlefish(Posted 2005) [#7]
Well, I do have a problem with guns.

Here's my player type:
;player type
Type player
	Field pivot                             ;pivot entity
	Field camera                            ;camera entity
	Field x,y,z                             ;player's position
	Field health                            ;player health
	Field w_entity                          ;weapon entity
	Field w_ammo                            ;ammo in weapon
	Field w_type$                           ;type/name of weapon
	Field w_damage                          ;damage the weapon does
	Field w_offsetx, w_offsety, w_offsetz   ;weapon offset values
	Field running                           ;if the player is running or not (true/false)
End Type

There are 10 weapons. If each weapon has a different amount of ammo, and their ammo ONLY goes down if THAT gun is used, then how would I do that? I can't imaging making 10 fields called "Gun1_ammo", "Gun2_Ammo", etc. I also want to try to keep the amount of types as low as possible. Is there a way to go about doing this without creating a new type?


Techlord(Posted 2005) [#8]
Create a separate Type for the Gun and Ammo.


wizzlefish(Posted 2005) [#9]
I thought about that - do you think it would be easier? I heard from someone that I should just merge the player and his weapons together in one type.

Is there ANY possible solution besides creating another type?


Techlord(Posted 2005) [#10]
Opto,

You use as many Types you need to define each individual 'object'. You will have more flexibility. Simply find all the common properties for a 'gun' and make those the fields. By changing the values of the fields you can create a variety of guns. You apply this method to Ammo, Particles, Vehicles, Trees, etc.


wizzlefish(Posted 2005) [#11]
Ok. Although I think I will keep the "object" type - I haven't run into problems yet.


Techlord(Posted 2005) [#12]
Type Gun
	Field id%
	Field typeid%
	Field mesh%
	Field ammoid%
	Field ammocount%
	Field triggerspeed#
	Field state%
End Type

Type Ammo
	Field id%
	Field typeid%
	Field mesh%
	Field particleid[4] ;empty, load, muzzleflash, travel, impact;
	Field soundid[4];empty,load, muzzleflash, travel, impact;
	Field travelpattern%
	Field damageeffectid%
	Field state%	
End Type

Type DamageEffect
	Field id%
	Field typeid%
	Field range%
	Field mesh% ;collision mesh for area effect
	;Player damage;
	Field speed#
	Field health#
	Field power#
	Field effect ;graphics effect;
	Field state%
End Field


If a generic type meets your needs than go for it.


wizzlefish(Posted 2005) [#13]
Ok. Thanks.

Also - I have another problem.

Do you have ANY clue on how to use ODE?


Erroneouss(Posted 2005) [#14]
I'll start writing a tutorial for you on ODE
As you asked me to do yesterday (I think
yesteryday).


wizzlefish(Posted 2005) [#15]
OK - although don't write it just for me. Put it in the code archives, or submit it to the tutorials section on my forums.


wizzlefish(Posted 2005) [#16]
I JUST GOT IT!

A weapon could be under the "obj" type - and other fields could be added. As there are multiple objects and multiple weapons it'll all work out! And it shall reduce my type and function count by at least 2!


Techlord(Posted 2005) [#17]
Optomistic,

I'm curious as to why your concerned about the number of types and functions used. Surely, media will eatup up more disk space.

By separating your 'objects' you can employ them in other projects. Trust me, if your going to code a hobby or career, you will use your libraries in other projects.

I personally dont favor a generic object because they can easily introduce ambiguity in the data, unless you have a good means of management. Heres a generic object class I wrote that may find itself in PW3D and PPF2k4.
;A Generic Obj Class with upto 64 Properties

Const OBJ_MAX%= 100
Const OBJ_PROPERTY_MAX%=64

Type obj
	Field id%
	Field name$
	;generic properties;
	Field offset%,label$[OBJ_PROPERTY_MAX],value$[OBJ_PROPERTY_MAX] 
End Type
Dim obj.objID(OBJ_MAX%);id key pointer
Global objcount

Function objCreate(objname$)
	this.obj=New obj
	objcount=objcount+1
	this\ID%=objcount
	objID(this\ID%)=this
	this\name$=objname$
	Return this\id
End Function

Function objPropertyAdd%(ID,objpropertylabel$,objpropertyvalue$="")
	objID(ID)\offset=objID(ID)\offset+1
	If objID(ID)\offset>OBJ_MAX%
		RuntimeError(objID(ID)\name+" Properties Full")
	EndIf
	objID(ID)\label[objID(ID)\offset]=objpropertylabel$
	objID(ID)\value[objID(ID)\offset]=objpropertyvalue$
	Return objID(ID)\offset
End Function

Function objNameSet(ID,objname$)
	objID(ID)\name=objname 
End Function

Function objNameGet(ID)
	Return objID(ID)\name
End Function

Function objPropertyValueSet(ID,objpropertyoffset,objpropertyvalue$)
	objID(ID)\value$[objpropertyoffset]=objpropertyvalue$ 
End Function

Function objPropertyValueGet(ID,objpropertyoffset)
	Return objID(ID)\value[objpropertyoffset]
End Function

Function objPropertyValueGetByLabel(ID,objpropertylabel$)
	For objpropertyoffset = 0 To objID(ID)\offset
		If objID(ID)\label[objpropertyoffset] = objpropertylabel Return objID(ID)\value[objpropertyoffset]
	Next
End Function	

Function objPropertyLabelGetByOffset(ID,objpropertyoffset)
	Return objID(ID)\label[objpropertyoffset]
End Function	

Function objMimic(ID,objname$)
	this.obj=objID(objCreate(objName))
	this\offset%=objID(ID)\offset%
	For objpropertyoffset = 0 To OBJ_PROPERTY_MAX
		this\label$[objpropertyoffset]=objID(ID)\label$[objpropertyoffset]
		this\value$[objpropertyoffset]=objID(ID)\value$[objpropertyoffset]
	Next	
	Return this\id
End Function

;Create a New Ammo
ammo=objCreate("Ammo")
objPropertyAdd(ammo,"name","GoldBullet")
objPropertyAdd(ammo,"īd","1")
objPropertyAdd(ammo,"damagepoint","5")
objPropertyAdd(ammo,"damagearea","10")
objPropertyAdd(ammo,"max_distance","100")

;Create a New Gun
gun=objCreate("Gun")
objPropertyAdd(gun,"name","Blazer3000")
objPropertyAdd(gun,"īd","1")
objPropertyAdd(gun,"ammoid","1")
objPropertyAdd(gun,"ammo","100")
objPropertyAdd(gun,"recoil","0.5")



wizzlefish(Posted 2005) [#18]
Let me show you my Object type and "UpdateObject functions:
;object type
Type obj
	Field obj_type$                         ;enemy, car, box, etc.
	Field name$                             ;name of object ("box1", "Bob's Car", etc.
	Field x#,y#,z#                          ;object position
	Field e_weapon                          ;enemy's weapon - leave at "0" if not an enemy
	Field d_secure                          ;if the door is secure (true/false) - only for doors
	Field el_dest#                          ;the y dest. of the elevator - only for elevator
	Field entity                            ;the actual mesh
	Field alpha#                            ;alpha of object
	Field shininess#                        ;shininess of object
	Field c_speed#                          ;car speed - leave at "0" if not a car
	Field c_wheels[4]                       ;car wheels - don't use if not a car
	Field x_vel#, y_vel#, z_vel#            ;velocity of the object
	Field w_type$                           ;weapon name
	Field w_id                              ;weapon id
	Field w_damage                          ;damage the weapon does
	Field offsetx, offsety, offsetz         ;offset values
End Type


Function:
;updates all objects
Function UpdateObjects()
	
	For o.obj = Each obj
	For pl_o.user = Each user
	
		Select o\obj_type$
		
			Case "enemy
			
				;enemy AI
			
			Case "car"
				
				;update car
				
			Case "crate" 
					
				;update crate
			
			Case "glass"
			
				;update glass
				
			Case "weapon"
		
			
			Case "door"
				If obj\d_secure = True
					If door_rotation <= 90 And good_code = True And EntityDistance(pl_o\camera,o\entity)<=5 And MouseHit(2)
						door_rotation = door_rotation + 1
						RotateEntity o\entity, 0, door_rotation, 0
					EndIf 
				Else
					If door_rotation <= 90 And EntityCollided(pl_o\camera,DOOR_COL) And MouseHit(2)
						door_rotation = door_rotation + 1
						RotateEntity o\entity, 0, door_rotation, 0
					EndIf
				EndIf
					
			Case "keypad"
				If EntityDistance(p\camera, o\entity)<=5 And MouseHit(2)
					While good_code = False
						Rect 350, 250, 25, 25
						Locate 350, 250 
						code$ = Input("Insert code - ")
					
						If code = right_code
							good_code = True
						EndIf
					Wend
				EndIf 
				
			Case "elevator"
				
				If EntityCollided(p\camera, LIFT_COL) And o\y <= o\el_dest
					MoveEntity o\entity, 0, -0.5, 0
				EndIf 
					
				
			Case "oil"
			
				If picked = o\entity
					e.effect = New effect
					e\entity = CopyEntity(ex_1\entity)
					PositionEntity e\entity, px#, py#, pz#
					RotateEntity o\entity, 0, 0, 90
					MoveEntity o\entity, 0, 1.5, 0
					
					If EntityDistance(p\camera, o\entity)<=5
						p\health = p\health - 5
					EndIf 
					
				EndIf 
				
			Case "computer"
							
				;computer catch on fire
				
			Case "weapon"
			
				;update weapon
							
		End Select 
		
		EntityAlpha o\entity, o\alpha#
		EntityShininess o\entity, o\shininess#
		
			
	Next 
	Next 
		
End Function