Organization
Blitz3D Forums/Blitz3D Programming/Organization
| ||
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
|
| ||
| 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. |
| ||
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 |
| ||
| take all of your global camera variable and make a global type out of it. |
| ||
| Sounds good. |
| ||
| 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. |
| ||
| 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? |
| ||
| Create a separate Type for the Gun and Ammo. |
| ||
| 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? |
| ||
| 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. |
| ||
| Ok. Although I think I will keep the "object" type - I haven't run into problems yet. |
| ||
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. |
| ||
| Ok. Thanks. Also - I have another problem. Do you have ANY clue on how to use ODE? |
| ||
| I'll start writing a tutorial for you on ODE As you asked me to do yesterday (I think yesteryday). |
| ||
| 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. |
| ||
| 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! |
| ||
| 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") |
| ||
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
|