2011
07.19

Script System

I didn’t post anything for long because I was busy on making my first iPhone app. But it didn’t go smoothly due to the lack of time and resources. Then I started taking care of my son on my own from June so I only have one or two hours spare time a day after my son sleep. Since the time is too short for working on engine, I decided to try the script system of LynxEngine. The script system is actually done for a while but I haven’t had chance to use it for making anything. I was using Lua as the script language and I thought that I can use it to write some simple games.

The first game I tried to make is a scrolling game, the background sprites are 2D and the character is 3D. Below is the video clip of this simple scrolling game and I used Lua script to create the whole game including the menus.

YouTube Preview Image

After finishing this simple game, I had a chance to look at Mono project and found it may be used as a better script system than current Lua based system. So I spent few days to collect related information online and finally got it done. Basically, I should be able to use any .NET language as the scripting language like C#, VB or Java but C# is the only managed language I am familiar with so I choose to use C#. The result is good, I can use C# to create the same game as I created by Lua and the OO nature of C# makes programming much easier and the code is also more readable.

Currently, both Lua and Mono coexist in LynxEngine but in the long term, I think I will move to Mono since it provides much better flexibility than Lua. I listed both C# and Lua script below and you can compare these two codes, I believe that most of you should like C# code more :)

As you can see from the video clip, there are few type of games I want to make using script. After I finish these type of games, I will put the executable file and script files here for downloading. Hopefully it wouldn’t take too long.

C# Script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Diagnostics;
using LynxEngine;
//----------------------------------------------
//  說明:   
//----------------------------------------------
public class CBGLayer
{
    public float ObjectWidth, ObjectHeight;
    public uint ObjectInterval;
    public float PosY;
    public uint NumObjects;
    public float ScrollingSpeed;
    public CDynamicObj[] Objects = null;
    public float[] Pos = null;
 
    public CBGLayer()            
    {
    }
 
    public void CreateObjects(
        CScene scene, 
        int n, 
        String name, 
        String filename, 
        CRenderableObj.DEPTHLAYERTYPE dl)
    {
        Objects = new CDynamicObj[n];
        Pos = new float[n];
        for (uint i=0; i < Objects.GetLength(0); i++)
        {
            Objects[i] = scene.CreateDynamicEntity();
            Objects[i].CreateSprite(name, filename, ObjectWidth, ObjectHeight);
            Objects[i].UpdateTransform();
            Objects[i].SetDepthLayer(dl);
            scene.AddDynamicObj(Objects[i]);
        }
    }
}
//----------------------------------------------
//  說明:   
//----------------------------------------------
class CPlayer : CDynamicObj
{
    public enum STATE
    {
        RUN = 0,
        JUMP,
        ATTACK1
    };
 
    public class CState        
    {
        public CSound Sound = null;
        public CAnimation Animation = null;
    }
 
    public STATE State;
    public CState [] States = null;
 
    public CPlayer(IntPtr ptr)
        : base(ptr)
    {
    }
 
    public void SetState(STATE state)
    {
        States[(uint)State].Sound.Stop();
 
        SetCurrentAnimation(States[(uint)state].Animation);
        States[(uint)state].Sound.Play();
        State = state;
    }
}
//----------------------------------------------
//  說明:   
//----------------------------------------------
public class CScrollingGamePage : CUIPage
{
    const int SCROLLING_GAME = 0;
    const int PHYSICS_GAME = 1;
    const int THIRDPERSON_GAME = 2;
    const int FPS_GAME = 3;
    const int GAME5 = 4;
    const int GAME6 = 5;
 
    bool GameConsoleIsRunning = false;
    CBGLayer[] BGLayers = new CBGLayer[4];
    CPlayer Player;
    CSound BGM;
    CVector2 [] BackgroundUV = new CVector2 [2];
    CScene Scene;
 
    new public void OnCreate()
    {
        Scene = GlobalVar.SceneSystem.AddScene();
        Scene.SetName("Scrolling Game Scene") ;
 
        CCamera Camera = Scene.CreateCamera();
        Camera.Create();
        Scene.SetCurrentCamera(Camera);
        CCameraContainer CameraContainer = (CCameraContainer)Camera.GetContainer();
 
        CVector3 CameraPos = new CVector3(10, 10, -35);
        CameraContainer.SetPosition(CameraPos);
        CVector3 CameraLookPos = new CVector3(10, 10, 0);
        CameraContainer.LookAt(CameraLookPos);
        CameraContainer.UpdateProjectionMatrix(
            (float)(GlobalVar.GraphicsSystem.GetBackbufferWidth()) / 
            (float)(GlobalVar.GraphicsSystem.GetBackbufferHeight()));
        CameraContainer.UpdateViewMatrix();
 
        Scene.LoadBackgroundTexture("../texture/scene/map00/background0.tga");
        BackgroundUV[0] = new CVector2();
        BackgroundUV[1] = new CVector2();
        BackgroundUV[0].x = 0.0f;   
        BackgroundUV[0].y = 0.0f;
        BackgroundUV[1].x = -0.5f;  
        BackgroundUV[1].y =  0.0f;
        Scene.SetBackgroundTextureUVOffset(
            BackgroundUV[0].x, BackgroundUV[0].y, 
            BackgroundUV[1].x, BackgroundUV[1].y);
 
        Player = new CPlayer(Scene.CreateDynamicEntity().GetPtr());                        
        Player.CreateModel("Player", "../model/dynobj/boy/boy.mdl");             
 
        Player.SetDepthLayer(CRenderableObj.DEPTHLAYERTYPE.DEPTH_LAYER_3);
        Player.Yaw(-90.0f, MATHORDER.LYNX_MATH_POST);
        Scene.AddDynamicObj((CDynamicObj)Player);            
 
        Player.States = new CPlayer.CState[3];
        Player.States[(uint)CPlayer.STATE.RUN] = new CPlayer.CState();
        Player.States[(uint)CPlayer.STATE.RUN].Animation = Player.LoadAnimation("../model/dynobj/boy/run.ani");
        Player.States[(uint)CPlayer.STATE.RUN].Sound = GlobalVar.SoundSystem.LoadSound("Run", "../sound/run.wav");
        Player.States[(uint)CPlayer.STATE.RUN].Sound.SetLoops(-1);
 
        Player.States[(uint)CPlayer.STATE.JUMP] = new CPlayer.CState();
        Player.States[(uint)CPlayer.STATE.JUMP].Animation = Player.LoadAnimation("../model/dynobj/boy/jump.ani");
        Player.States[(uint)CPlayer.STATE.JUMP].Sound = GlobalVar.SoundSystem.LoadSound("Jump", "../sound/jump.wav");
 
        Player.States[(uint)CPlayer.STATE.ATTACK1] = new CPlayer.CState();
        Player.States[(uint)CPlayer.STATE.ATTACK1].Animation = Player.LoadAnimation("../model/dynobj/boy/attack1.ani");
        Player.States[(uint)CPlayer.STATE.ATTACK1].Sound = GlobalVar.SoundSystem.LoadSound("Attack1", "../sound/attack1.wav");
 
        BGLayers[0] = new CBGLayer();
        BGLayers[0].ObjectWidth = 160;
        BGLayers[0].ObjectHeight = 320;
        BGLayers[0].ObjectInterval = 110;
        BGLayers[0].PosY = 320-35-320;    
        BGLayers[0].ScrollingSpeed = 1;
        BGLayers[0].CreateObjects(Scene, 6, "Tree", "../texture/scene/map00/tree_23.tga", CRenderableObj.DEPTHLAYERTYPE.DEPTH_LAYER_5);
 
        BGLayers[1] = new CBGLayer();
        BGLayers[1].ObjectWidth = 256;
        BGLayers[1].ObjectHeight = 256;
        BGLayers[1].ObjectInterval = 256;
        BGLayers[1].PosY = 320-35-256;    
        BGLayers[1].ScrollingSpeed = 2.5f;
        BGLayers[1].CreateObjects(Scene, 3, "Tree2", "../texture/scene/map00/tree_01.tga", CRenderableObj.DEPTHLAYERTYPE.DEPTH_LAYER_4);
 
        BGLayers[2] = new CBGLayer();
        BGLayers[2].ObjectWidth = 128;
        BGLayers[2].ObjectHeight = 64;
        BGLayers[2].ObjectInterval = 110;
        BGLayers[2].PosY = 320 - 22 - 64;
        BGLayers[2].ScrollingSpeed = 6.0f;
        BGLayers[2].CreateObjects(Scene, 6, "Bush", "../texture/scene/map00/bush_08.tga", CRenderableObj.DEPTHLAYERTYPE.DEPTH_LAYER_3);
 
        BGLayers[3] = new CBGLayer();
        BGLayers[3].ObjectWidth = 64;
        BGLayers[3].ObjectHeight = 64;
        BGLayers[3].ObjectInterval = 64;
        BGLayers[3].PosY = 320 - 40;
        BGLayers[3].ScrollingSpeed = 6.0f;
        BGLayers[3].CreateObjects(Scene, 9, "GroundTile", "../texture/scene/map00/ground.tga", CRenderableObj.DEPTHLAYERTYPE.DEPTH_LAYER_2);           
 
        BGM = GlobalVar.SoundSystem.LoadSound("BGM", "../sound/BGM.wav");
        BGM.SetLoops(-1);
 
        Scene.SetRenderMode(CScene.RENDERMODE.RENDER_SIMPLE);            
        Scene.SetSortMode(CScene.SORTMODE.SORT_BY_DEPTH_LAYER);
        Scene.Setup();
    }
    //----------------------------------------------
    //  說明:   
    //----------------------------------------------
    new public void OnInit()
    {
        GlobalVar.SystemMouse = (CMouse)(GlobalVar.InputSystem.FindDevice("System Mouse"));
        GlobalVar.Engine.DeleteLastUIPage();
        Player.SetState(CPlayer.STATE.RUN);
 
        for (int i = 0; i < BGLayers.GetLength(0); i++)
        {
            for (int j=0; j < BGLayers[i].Objects.GetLength(0); j++)                
            {
                BGLayers[i].Pos[j] = (int)(j*BGLayers[i].ObjectInterval);
            }
        }
 
        BGM.SetVolume(0.6f);
        BGM.Play();            
    }
    //----------------------------------------------
    //  說明:   
    //----------------------------------------------
    void AnimationLoop()      
    {
        if (GlobalVar.SystemMouse.ButtonStatus(CMouse.RBUTTON) && Player.State == CPlayer.STATE.RUN)
        {
            Player.SetState(CPlayer.STATE.JUMP);                
        }    
 
        if (GlobalVar.SystemMouse.ButtonStatus(CMouse.LBUTTON) && Player.State == CPlayer.STATE.RUN)
        {
            Player.SetState(CPlayer.STATE.ATTACK1);                
        }
 
        if (Player.State != CPlayer.STATE.RUN)
        {
            if (Player.IsCurrentAnimationStopped())
            {
                Player.SetState(CPlayer.STATE.RUN);                
            }
        }
    }
    //----------------------------------------------
    //  說明:   
    //----------------------------------------------
    new public void OnLoop(float step)
    {
        GlobalVar.SystemMouse.Poll();
 
        if (GlobalVar.GameConsoleSystem.IsRunning())
        {
            GameConsoleIsRunning = true;
            Player.States[(int)Player.State].Sound.Pause();
        }
        else
        {
            AnimationLoop();
 
            if (GameConsoleIsRunning)
            {
                if (!Player.States[(int)Player.State].Sound.IsPlaying())
                {
                    Player.States[(int)Player.State].Sound.Play();
                }
                GameConsoleIsRunning = false;
            }
 
            if (Player.State == CPlayer.STATE.RUN || Player.State == CPlayer.STATE.JUMP)
            {
                BackgroundUV[0].x += (step * 0.0003f);
                BackgroundUV[1].x += (step * 0.0003f);
                Scene.SetBackgroundTextureUVOffset(BackgroundUV[0].x, BackgroundUV[0].y, BackgroundUV[1].x, BackgroundUV[1].y);
 
                for (int i = 0; i < BGLayers.GetLength(0); i++)
                {
                    for (int j = 0; j < BGLayers[i].Objects.GetLength(0); j++)
                    {
                        BGLayers[i].Pos[j] -= (BGLayers[i].ScrollingSpeed * step);
                        if (BGLayers[i].Pos[j] < -BGLayers[i].ObjectWidth)
                            BGLayers[i].Pos[j] += (BGLayers[i].Objects.GetLength(0) * BGLayers[i].ObjectInterval);
 
                        CVector3 Pos = new CVector3(BGLayers[i].Pos[j], BGLayers[i].PosY, 0);
                        BGLayers[i].Objects[j].SetPosition(Pos);
                        BGLayers[i].Objects[j].UpdateTransform();
                    }
                }
            }
        }
    }
    //----------------------------------------------
    //  說明:   
    //----------------------------------------------
    new public void OnRender()
    {
        GlobalVar.Engine.Render();            
    }
    //----------------------------------------------
    //  說明:   
    //----------------------------------------------
    new public void OnQuit()
    {
        base.OnQuit();
    }
}

Lua Script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
Player  = {DynObj = 0, State = 0, States = {}}
 
Player.STATE = {}
Player.STATE.RUN     = 0
Player.STATE.JUMP    = 1
Player.STATE.ATTACK1 = 2
 
Scene = nil
BGLayer = {}
BackgroundUV = {u0 = 0.0, v0 = 0.0, u1 = -0.51, v1 = 0.0}
BGM = nil
GameConsoleIsRunning = false
 
------------------------------------------------
--  說明:   
------------------------------------------------
Player.SetState = function (state) 
    CSound_Cast(Player.States[Player.State].Sound):Stop()
 
    CDynamicObj_Cast(Player.DynObj):SetCurrentAnimation(Player.States[state].Animation)
    CSound_Cast(Player.States[state].Sound):Play()    
    Player.State = state 
end
------------------------------------------------
--  說明:   
------------------------------------------------
function BGLayer_Create (scene, layer, n, name, filename, depthlayer) 
    BGLayer[layer].NumObjects = n
    for i=0,BGLayer[layer].NumObjects-1 do
        DynamicObj = CDynamicObj_Cast(scene:CreateDynamicEntity())
        DynamicObj:CreateSprite(name, filename, BGLayer[layer].ObjectWidth, BGLayer[layer].ObjectHeight)        
        DynamicObj:UpdateTransform()
        DynamicObj:SetDepthLayer(depthlayer)
        scene:AddDynamicObj(GetObjectPointer(DynamicObj))  
        BGLayer[layer][i] = {}        
        BGLayer[layer][i].DynObj = GetObjectPointer(DynamicObj)
        BGLayer[layer][i].Pos = i*BGLayer[layer].ObjectWidth
    end    
end
------------------------------------------------
--  說明:   
------------------------------------------------
CScrollingGamePage.OnCreate = function () 
    CSampleScriptGame:ComputeScreenRatio()  
 
    Scene = CScene_Cast(CSceneSystem:AddScene())
    Scene:SetName(L"Scrolling Game Scene")  
 
    Camera = CCamera_Cast(Scene:CreateCamera())
    Camera:Create()
    Scene:SetCurrentCamera(GetObjectPointer(Camera))
    CameraContainer = CCameraContainer_Cast(Camera:GetContainer())
    CameraContainer:SetPosition(CVector3(10, 10, -35))
    CameraContainer:LookAt(10, 10, 0)
    CameraContainer:UpdateProjectionMatrix(
        CGraphicsSystem:GetBackbufferWidth()/
        CGraphicsSystem:GetBackbufferHeight())
    CameraContainer:UpdateViewMatrix()       
 
    Scene:LoadBackgroundTexture(L"../texture/scene/map00/background0.tga")
    Scene:SetBackgroundTextureUVOffset(BackgroundUV.u0, BackgroundUV.v0, BackgroundUV.u1, BackgroundUV.v1) 
 
    DynamicObj = CDynamicObj_Cast(Scene:CreateDynamicEntity())
    DynamicObj:CreateModel(L"Player", L"../model/dynobj/boy/boy.mdl")    
    DynamicObj:SetDepthLayer(CRenderableObj.DEPTHLAYERTYPE.DEPTH_LAYER_3)
    DynamicObj:Yaw(-90.0, 1)        
    Scene:AddDynamicObj(GetObjectPointer(DynamicObj))    
 
    Player.States[Player.STATE.RUN] = {}
    Player.States[Player.STATE.RUN].Animation = DynamicObj:LoadAnimation(L"../model/dynobj/boy/run.ani")
    Player.States[Player.STATE.RUN].Sound = CSoundSystem:LoadSound(L"Run", L"../sound/run.wav")
    CSound_Cast(Player.States[Player.STATE.RUN].Sound):SetLoops(-1)
    Player.DynObj = GetObjectPointer(DynamicObj)
 
    Player.States[Player.STATE.JUMP] = {}
    Player.States[Player.STATE.JUMP].Animation = DynamicObj:LoadAnimation(L"../model/dynobj/boy/jump.ani")
    Player.States[Player.STATE.JUMP].Sound = CSoundSystem:LoadSound(L"Jump", L"../sound/jump.wav")
 
    Player.States[Player.STATE.ATTACK1] = {}
    Player.States[Player.STATE.ATTACK1].Animation = DynamicObj:LoadAnimation(L"../model/dynobj/boy/attack1.ani")
    Player.States[Player.STATE.ATTACK1].Sound = CSoundSystem:LoadSound(L"Attack1", L"../sound/attack1.wav")      
 
    BGLayer[0] = {}
    BGLayer[0].ObjectWidth = 160    
    BGLayer[0].ObjectHeight = 320    
    BGLayer[0].ObjectInterval = 110    
    BGLayer[0].PosY = 320-35-320        
    BGLayer[0].ScrollingSpeed = 1
    BGLayer_Create(Scene, 0, 6, L"Tree", L"../texture/scene/map00/tree_23.tga", CRenderableObj.DEPTHLAYERTYPE.DEPTH_LAYER_5)
 
    BGLayer[1] = {}
    BGLayer[1].ObjectWidth = 256
    BGLayer[1].ObjectHeight = 256    
    BGLayer[1].ObjectInterval = 256      
    BGLayer[1].PosY = 320-35-256          
    BGLayer[1].ScrollingSpeed = 2.5  
    BGLayer_Create(Scene, 1, 3, L"Tree2", L"../texture/scene/map00/tree_01.tga", CRenderableObj.DEPTHLAYERTYPE.DEPTH_LAYER_4)    
 
    BGLayer[2] = {}
    BGLayer[2].ObjectWidth = 128  
    BGLayer[2].ObjectHeight = 64  
    BGLayer[2].ObjectInterval = 110     
    BGLayer[2].PosY = 320-22-64     
    BGLayer[2].ScrollingSpeed = 6
    BGLayer_Create(Scene, 2, 6, L"Bush", L"../texture/scene/map00/bush_08.tga", CRenderableObj.DEPTHLAYERTYPE.DEPTH_LAYER_1)        
 
    BGLayer[3] = {}
    BGLayer[3].ObjectWidth = 64 
    BGLayer[3].ObjectHeight = 64    
    BGLayer[3].ObjectInterval = 64 
    BGLayer[3].PosY = 320-40     
    BGLayer[3].ScrollingSpeed = 6  
    BGLayer_Create(Scene, 3, 9, L"GroundTile", L"../texture/scene/map00/ground.tga", CRenderableObj.DEPTHLAYERTYPE.DEPTH_LAYER_1)        
 
    BGM = (CSoundSystem:LoadSound(L"BGM", L"../sound/BGM.wav"))
    CSound_Cast(BGM):SetLoops(-1)
 
    Scene:SetRenderMode(CScene.RENDERMODE.RENDER_SIMPLE)    
    Scene:SetSortMode(CScene.SORTMODE.SORT_BY_DEPTH_LAYER)           
    Scene:Setup()
end
------------------------------------------------
--  說明:   
------------------------------------------------
CScrollingGamePage.OnInit = function ()          
    CEngine:DeleteLastUIPage()
    Player.SetState(Player.STATE.RUN)
 
    for i=0,3 do
        for j=0, BGLayer[i].NumObjects-1 do
            BGLayer[i][j].Pos = j*BGLayer[i].ObjectInterval
        end
    end  
 
    CSound_Cast(BGM):SetVolume(0.6)
    CSound_Cast(BGM):Play()
end
------------------------------------------------
--  說明:   
------------------------------------------------
MouseDevice = CMouse_Cast(CInputSystem:FindDevice(L"System Mouse"))
------------------------------------------------
--  說明:   
------------------------------------------------
CScrollingGamePage.AnimationLoop = function ()          
    if (MouseDevice:ButtonStatus(RBUTTON) == TRUE and Player.State == Player.STATE.RUN) then
        Player.SetState(Player.STATE.JUMP)        
    end
 
    if (MouseDevice:ButtonStatus(LBUTTON) == TRUE and Player.State == Player.STATE.RUN) then
        Player.SetState(Player.STATE.ATTACK1)        
    end
 
    if (Player.State ~= Player.STATE.RUN) then
        if (CDynamicObj_Cast(Player.DynObj):IsCurrentAnimationStopped() == TRUE) then
            Player.SetState(Player.STATE.RUN)        
        end
    end    
end
------------------------------------------------
--  說明:   
------------------------------------------------
CScrollingGamePage.OnLoop = function (step)      
    MouseDevice:Poll()
 
    if (CGameConsoleSystem:IsRunning() == TRUE) then
        GameConsoleIsRunning = true
        CSound_Cast(Player.States[Player.State].Sound):Pause()
    else
        CScrollingGamePage:AnimationLoop()    
 
        if (GameConsoleIsRunning == true) then
            if (CSound_Cast(Player.States[Player.State].Sound):IsPlaying() == FALSE) then
                CSound_Cast(Player.States[Player.State].Sound):Play()
            end
            GameConsoleIsRunning = false
        end
 
        if (Player.State == Player.STATE.RUN or Player.State == Player.STATE.JUMP) then    
            BackgroundUV.u0 = BackgroundUV.u0 + (step * 0.0003)
            BackgroundUV.u1 = BackgroundUV.u1 + (step * 0.0003)
            Scene:SetBackgroundTextureUVOffset(BackgroundUV.u0, BackgroundUV.v0, BackgroundUV.u1, BackgroundUV.v1)
 
            for i=0,3 do
                for j=0, BGLayer[i].NumObjects-1 do
                    BGLayer[i][j].Pos = BGLayer[i][j].Pos - BGLayer[i].ScrollingSpeed*step
                    if (BGLayer[i][j].Pos < -BGLayer[i].ObjectWidth) then
                        BGLayer[i][j].Pos = BGLayer[i][j].Pos + BGLayer[i].NumObjects*BGLayer[i].ObjectInterval 
                    end
                    DynObj = CDynamicObj_Cast(BGLayer[i][j].DynObj)
                    DynObj:SetPosition(CVector3(BGLayer[i][j].Pos, BGLayer[i].PosY, 0))
                    DynObj:UpdateTransform()
                end
            end   
        end
    end
end
------------------------------------------------
--  說明:   
------------------------------------------------
CScrollingGamePage.OnRender = function ()           
    CEngine:Render()
end
------------------------------------------------
--  說明:   
------------------------------------------------
CScrollingGamePage.OnQuit = function ()      
    CUIPage:OnQuit()
end
2011
02.21

iPhone Porting

As many of you may already know I was working on iPhone porting since last October. Now, the most part of engine has been ported to iPhone including two new renderer, OpenGL ES and OpenGL ES 2.0 renderer. There are still many shader need to be rewrote in GLSL but basically, the engine works well as PC version now. And the same scene edited in LynxEd can be output to PC or iPhone, each exporter is an individual plug-in. For the physics system, iPhone version will use Bullet for 3D physics and Box2D for 2D physics.

Since I also joined the Apple developer program so I can run the engine on my iPod with accelerometer, so I wrote a simple demo to combine the engine with accelerometer and it’s pretty interesting when running on real device. The fps number is a little low in the video clip because the demo actually output log to the console. Without the output, it can actually archive 60 fps.

YouTube Preview Image

Below is the other early video of the initial porting and it includes a small Box2D test.

YouTube Preview Image
2010
06.23

Recently, I was working on terrain again to improve the object paint brush. The object paint brush is used to paint the terrain with any object you selected. The improved brush will align the painted object to terrain surface automatically. After painting, the objects will attach to the terrain so even the user modify the terrain after painting, all painted objects can still align to the new terrain surface automatically.

I also added the height field physics shape for the terrain and some simple vertex shader code to implement the bending of grass when colliding with physics objects.

YouTube Preview Image

The video is a little chopping since my CPU is not powerful enough to run rendering, physics and capturing at the same time. There is one more video clip which was captured by fraps and it’s much more smooth.

YouTube Preview Image
2010
05.01

Physics Editing in LynxEd

Here is the video of physics editing in LynxEd. In LynxEd, the user can assign physics attribute to any object in the scene, add physical shape to object(for collision) then test the scene in the editor right the way. When add hull or tri-mesh shape, the user can choose which LOD geometry to generate from. There are still a lot things need to do for the physics. I am working on the physical joints now, basically, the user can create joint, connect objects in the editor just use mouse. There will be a physics editor which can do more complex job like fine tune the shape position, center of mass position, ragdoll setup, etc.

Stay tuned.

YouTube Preview Image
2010
04.30

Texture Animation Editor

YouTube Preview Image
2010
04.30
YouTube Preview Image
2010
01.03

Those are the all kind of resource editors in LynxEditor now. I have done those for long just didn’t have the time to post it. Of course I will add more resource editors in the future. Currently, I am working on game logic editor. Most of those editors provide drag and drop functionality and I think I will post anther video to show you that. There is the list of current resource editors :

  • Container Editor
  • Animation Editor
  • Animation Tree Editor
  • Texture Editor
  • Texture Animation Editor
  • Material Editor
  • Particle Editor

All Resource Editors

2009
12.31

It’s been 3 years…

It’s been 3 years since I built up this site and the project is still not good enough to be released :( . I am sorry about the slow progress but time is always not enough for me. As you may know, I have a full-time job and one 3 years old kid so my spare time is very limited and the things need to be done are so many. But I am still working on it, actually, I work on it every day even sometimes I only have less than one hour spare time. And fortunately, my job is GPU-related so everything I learned from my work can be used on this project.

Tomorrow is the new year, I truly hope I can release the first version in 2010 even it could be a very early stage version. And I hope everyone has spent attention on this site has a Happy New Year :)

MaterialEditor and ResourceBrowser

2009
12.13

Building Up the New Site.

I am building up the new site, the current site is the temporary site and I will upload the new site once it’s done. But I will keep posting news here from now.

2009
11.20

Adding DX11 Renderer

The video is NOT the DX11 demo for LynxEngine, it’s a DX11 tessellation demo I have done for my company and  a China game developer. But I start to implemet the DX11 renderer of LynxEngine and LynxEngine will skip DX10.

YouTube Preview Image