Jump to content

The Last Chapter


Aily
 Share

Recommended Posts

To avoid tunneling, you might try doing a greater number of physics updates, in smaller incrementations. You don't have much physics going on, so it seems like you could do that with no bad effects.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

To avoid tunneling, you might try doing a greater number of physics updates, in smaller incrementations. You don't have much physics going on, so it seems like you could do that with no bad effects.

 

Hm, this is good idea! I'll try it B)

"Better" is big enemy of "good"

Link to comment
Share on other sites

I tried the demo , and the game is really beautifull.

Thes ground smoke effects when walking, jumping is just great ; and the gameplay is fluid and fine.

It would be cool to find some horizontal flying ennemies like in traditionnal platform games where you have to be carefull before jumping ! Put it on steam and i'll buy it ;)

 

I found that similar filters about Gimp also :

Gimp filters

 

Could you share some code ?

Like Entities loading and management for example ?

It's not to steal the code , but to see how to do ?

Stop toying and make games

Link to comment
Share on other sites

Could you share some code ?

Like Entities loading and management for example ?

It's not to steal the code , but to see how to do ?

 

It may be possible, but not effective without full media - when you can compile and run project.

 

I just can explain the basics :)

 

First of all i have base type (class), call it "node".

Node on create write itself to nodes list.

Node have empty (virtual) functions on_init(),on_update(),on_destroy(), etc...

Each game object is extends from node, so other game object types are like

 

type node_enemy extends node

type node_bullet extends node

type node_dust extends node

 

etc...

 

So i don't need to thinking about how each game object type will be "live" in game world, i need only add funtion on_update() to it, and write there all game object need to do.

 

Plus with this all base node type (struct in C) have helper functions like

attach_node() - it attaching node object to entity as entity user data

set_pos(pos:tvec3) - set body position (but each extended type can override this function and make it own calculations)

 

Like so, i have node_later_func type, wherre on create i can write any function pointer and delay, after wich time run it.

 

BASE NODE IS ROCK!

 

So standart callbacks only getentityuserdata, that always "node", and run it function on_collide()

 

here is my base node code:

 


Type node

Global nodes:TList=CreateList()

Field name$
'Field fullname$

Field on_off

Field wants_to_die

Field touch_sensor
Field see_sensor
Field body
Field mesh

Field is_near_player
Field player_side

Field magnetic
Field solid
Field end_level

Field punch

Field blue_key
Field green_key
Field red_key

Field run_later_time#
Field need_to_run_later

Field current_pos:tvec3

Method hide_show_by_switch()
	on_off=Not on_off
	on_hide_show_by_switch()
End Method

Method on_hide_show_by_switch()
	'override
End Method

Method attach_node(dest=0)
	If dest=0 dest=body

	setentityuserdata dest,Self

	For i=1 To countchildren(dest)
		child=getchild(dest,i)
		attach_node child
	Next
End Method


Method free()
	ListRemove nodes,Self
End Method

Method silent_free()
End Method

Method hit(pos:tvec3,force)
	on_hit pos,force
End Method

Method on_hit(pos:tvec3,force)

End Method

Method player_collide()
	on_player_collide()
End Method

Method on_player_collide()
End Method

Method read_mesh:node(mesh_name$)
	mesh=loadmesh("abstract::"+mesh_name+".gmf")
	Return Self
End Method

Method set_pos(pos:tvec3)
	positionentity body,pos,1
End Method

Method kill()
	wants_to_die=True
End Method

Method check_death()
	If wants_to_die death
End Method

Method death()
End Method

Method build_tree_for_child(mesh_)

	tmp=createpivot()
	setentitymatrix tmp,getentitymatrix(mesh_)

	For i=1 To countsurfaces(mesh_)
		surf=getsurface(mesh_,i)
		createbodytree surf,tmp
	Next

	entityparent tmp,body

	For i=1 To countchildren(mesh_)
		child=getchild(mesh_,i)
		build_tree_for_child(child)
	Next

End Method

Method build_tree()
	body=createpivot()
	build_tree_for_child(mesh)
End Method

Method New()
	on_off=True
	ListAddFirst nodes,Self
End Method

Method init()
	on_init
End Method

Method on_init()
End Method

Method run_later()
	' override
End Method

Method update()
	on_update
	is_near_player=False
	If need_to_run_later
		If run_later_time<0
			run_later
			need_to_run_later=False
		Else
			run_later_time:-appspd()
		End If
	End If
End Method

Method on_update()
End Method

Method clear()
End Method

Function update_scene()
	For n:node=EachIn nodes
		n.update
	Next
End Function

End Type

 

here is bullet node

 

Type node_bullet Extends node

Field life_time#
Field max_life#

Field power

Global player_bullet

Function init_bullets()
	player_bullet=loadmesh("abstract::player_bullet.gmf")
	'player_bullet=createsphere()
	'entitycolor player_bullet,vec4(.8,.5,0,1)
	rotatemesh player_bullet,vec3(90,90,0)
	hideentity player_bullet
End Function

Method on_init()
	body=createbodybox(1,.8,.5)
	'entityparent mesh,body
	entitytype body,phy.type_player_bullet
	setbodygravitymode body,0
	setbodymass body,.1
	sweptcollision body,True
	setentitycallback body,bullet_to,ENTITYCALLBACK_COLLISION
	attach_node
End Method

Method shot(pos:tvec3,dir,force)
	positionentity body,pos
	If dir=1
		rotateentity body,vec4(0,-90,0)
	Else
		rotateentity body,vec4(0,90,0)
	End If
	moveentity body,vec3(0,0,1.5)
	setbodyforce body,vec3(0,0,force),0
End Method

Method free_bullet()
	freeentity mesh
	freeentity body
	free
End Method

Method on_update()
	life_time:+appspeed()
	setentitymatrix mesh,getentitymatrix(body)
	If life_time>max_life
		free_bullet
	End If
End Method

Method destroy_bullet()
	'node_weapon_fire.respawn entityposition(body)
	node_explosion.gen2_at entityposition(body),0
	part.coin_hit entityposition(body)

	'node_dust.gen_hit_at entityposition(body)
	'node_post_collect.gen entityposition(body)
	setentitycallback body,Null,ENTITYCALLBACK_COLLISION
	free_bullet
End Method

End Type

 

And zone on load parse all scene GMF file, select each child name, and make such:

 

Function process_zone(lst:TList)

	Local n:node

	For sm:sub_mesh=EachIn lst

		Select sm.name
		Case "enemy"
			n=New node_enemy
			n.init
			n.set_pos entityposition(sm.mesh,1)
		Case "coin"
			n=New node_coin
			n.init
			n.set_pos entityposition(sm.mesh,1)
		Case "blue_key"
			n=New node_key
			n.blue_key=True
			n.init
			n.set_pos entityposition(sm.mesh,1)
		Case "red_key"
			n=New node_key
			n.red_key=True
			n.init
			n.set_pos entityposition(sm.mesh,1)
		Case "green_key"
			n=New node_key
			n.green_key=True
			n.init
			n.set_pos entityposition(sm.mesh,1)
		Case "player"
			player.init
			player.set_pos entityposition(sm.mesh,1)
		Case "metal"
			n=New node_metal
			n.mesh=sm.mesh
			n.init
		Case "beton"			
			n=New node_beton
			n.mesh=sm.mesh
			n.name=Replace(sm.fullname,"#","")
			n.init
		Case "enemy_limit"			
			n=New node_enemy_limits
			n.mesh=sm.mesh
			n.init
		Case "solid"			
			n=New node_beton
			n.mesh=sm.mesh
			n.name=Replace(sm.fullname,"#","")
			n.init
		Case "on/off"
			n=New node_switch
			n.name=sm.fullname
			n.mesh=sm.mesh
			n.init
		Case "on/off/blue"
			n=New node_switch
			n.name=sm.fullname
			n.mesh=sm.mesh
			n.blue_key=True
			n.init
		Case "on/off/green"
			n=New node_switch
			n.name=sm.fullname
			n.mesh=sm.mesh
			n.green_key=True
			n.init
		Case "on/off/red"
			n=New node_switch
			n.name=sm.fullname
			n.mesh=sm.mesh
			n.red_key=True
			n.init
		Case "state_off"
			node_state_off.add_off_nodes sm.fullname
		Case "opener"
			n=New node_opener
			n.name=Replace(sm.fullname,"#","")
			n.mesh=sm.mesh
			n.init
		Case "t_platform"
			n=New node_t_platform
			n.name=Replace(sm.fullname,"#","")
			n.mesh=sm.mesh
			n.init
		Case "inst"
			sub_child=findchild(mesh,sm.src_name)
			If sub_child
				nmesh=copyentity(sub_child)
				'entityviewrange nmesh,VIEWRANGE_INFINITE
				setentitymatrix nmesh,getentitymatrix(sm.mesh)
				hideentity sm.mesh
			End If
		Case "refract"
			wrld.r
				nmesh=copyentity(sm.mesh)
				hideentity sm.mesh
			wrld.m
		Case "grass"
			If Not gra.grass hideentity sm.mesh
		End Select

	Next

End Function

 

The best thing with Leadwerks is it simplify and quality, but(!!!) many people are forget that its good working with BlitzMax! BlitzMax is much simply, stable, lightweight than any C++, C#, Delphy, or else. METATRON, fortran and C and Delphy much faster than BlitzMax :D . I droped to writing my script system for game, because BlitzMax enough simple as scripting language, so when i need new game object (flying enemy for example), i need only to crete new node_flying_enemy, write it on_init() and on_update() functions, and put it to zone loading "select....end select" condition :D All other things are will be maked.

 

I'm using many timers in each object, and each timer extends from base node too. It's very handy at the end, when each game object is same.

 

I don't undarstanding, why Josh not maked such handy void node base class, that call on_update each time before update world.

 

P.S. Thanks to Arbuz for learning OOP basics ;):P

P.P.S. And ActionScript architecture with change function pointers on-the-fly

"Better" is big enemy of "good"

Link to comment
Share on other sites

And the main program is:

 

Framework leadwerks.engine
Import maxgui.drivers
Import brl.EventQueue

registerabstractpath AppDir

AppTitle="The Last Chapter"

Include "ini.bmx"
Include "app_start.bmx"
Include "random.bmx"
Include "gra.bmx"
Include "wrld.bmx"
Include "at.bmx"
Include "story.bmx"
Include "render.bmx"
Include "phy.bmx"
Include "pick.bmx"
Include "key.bmx"
Include "material.bmx"
Include "message.bmx"
Include "fonts.bmx"
Include "game.bmx"
Include "bkg.bmx"
Include "game_gui.bmx"
Include "game_time.bmx"
Include "player.bmx"
Include "zone.bmx"
Include "node.bmx"
Include "node_lc_rand.bmx"
Include "node_part.bmx"
Include "node_enemy.bmx"
Include "enemy_segment.bmx"
Include "node_coin.bmx"
Include "node_dust.bmx"
Include "node_post_collect.bmx"
Include "node_save.bmx"
Include "node_opener.bmx"
Include "node_t_platform.bmx"
Include "node_enemy_wake_ray.bmx"
Include "node_enemy_limits.bmx"
Include "node_beton.bmx"
Include "node_metal.bmx"
Include "node_end_level.bmx"
Include "node_fall_die.bmx"
Include "node_switch.bmx"
Include "node_state_off.bmx"
Include "node_key.bmx"
Include "node_bullet.bmx"
Include "weapon.bmx"
Include "node_weapon_fire.bmx"
Include "node_garbage.bmx"
Include "node_explosion.bmx"
Include "later_func.bmx"

app_start.run
game_time.init
gra.init
wrld.init
fonts.init

setshader 0
SetColor vec4(0,0,0,1)
DrawRect 0,0,gra.x,gra.y
Flip

render.init
game_gui.init
game.init

Local in:ini=ini.read_a("game")
zone.init in.get("start")

phy.init

Repeat
game.update
Forever

"Better" is big enemy of "good"

Link to comment
Share on other sites

Nice explanation Aily. I also use these types of techniques in my game engine.

 

I have an underlying GameObject class that contains lots of virtual functions including an Update function which all higher level objects inherit from. All update functions are registered as part of the construction of the class with an application event which is triggered in each iteration of the game loop; automatically calling the update functions of all game object derived objects which exist at the time; so I don't even need to call them directly. The update functions control, as you say, the functionality of the object.

 

Its a great way of working in an object oriented way and encapsulating functionality in an easily extendible way.

Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++

Link to comment
Share on other sites

Thanks a lot.

It could become some official new Game Framework for LE2.

I don't have BLitzMax so i'll stick lot more with C++ or C# , but the code is very inspiring , i had already the idea to do as well

the update() function also to otehr objects would inherit.

I'll dig that code and see what i can achieve with it.

Stop toying and make games

Link to comment
Share on other sites

  • 3 weeks later...

 

It could become some official new Game Framework for LE2.

 

 

Josh maked same in LUA scripts. So better was to do all game in LUA. But now - is not possible to move back, and i will finish it in Bmax. My next game will be in LUA.

"Better" is big enemy of "good"

Link to comment
Share on other sites

  • 3 months later...

Hi Aily... i am curious on how this project is coming along... its one of the few demos i have seen that truly has nice art and game mechanics and i enjoyed playing those 4 maps repeatedly... any progress on new maps? available for purchase yet? smile.png

  • Upvote 1

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

I agree with Mack, it looks great and plays very well.

  • Upvote 1

AMD Bulldozer FX-4 Quad Core 4100 Black Edition

2 x 4GB DDR3 1333Mhz Memory

Gigabyte GeForce GTX 550 Ti OC 1024MB GDDR5

Windows 7 Home 64 bit

 

BlitzMax 1.50 • Lua 5.1 MaxGUI 1.41 • UU3D Pro • MessiahStudio Pro • Silo Pro

3D Coat • ShaderMap Pro • Hexagon 2 • Photoshop, Gimp & Paint.NET

 

LE 2.5/3.4 • Skyline UE4 • CE3 SDK • Unity 5 • Esenthel Engine 2.0

 

Marleys Ghost's YouTube Channel Marleys Ghost's Blog

 

"I used to be alive like you .... then I took an arrow to the head"

Link to comment
Share on other sites

Hi Aily... i am curious on how this project is coming along... its one of the few demos i have seen that truly has nice art and game mechanics and i enjoyed playing those 4 maps repeatedly... any progress on new maps? available for purchase yet? smile.png

I agree with Mack, it looks great and plays very well.

Thanks guys, it bring me back to work on this game. Last time i'm some disapointed in gamedev, little loose trust in this money-making work, and work on another projects.

 

But now i realy want to continue it. Thanks for you support me ;)

"Better" is big enemy of "good"

Link to comment
Share on other sites

  • 1 month later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...