-
Wednesday, October 31, 2012
Sunday, October 28, 2012
Space Qube Updates
Here comes more in-developing screenshots and video of the game!
The main menu video.
The game part
The game part is simple, the player controls the space ship, flying toilet(?) or anything the player created to shoot as many aliens as he can to get highest score. Of course there are some power-ups the player can use to increase the weapon power, speed, etc. There are also couple of bosses are waiting for the player, beat them to get higher score and some rewards.
The workshop part
The workshop part contains a voxel model editor and browser. You can use browser to browse the voxel models uploaded by other players. You can also download and rate the uploaded voxel models then modify them or use them to play game. For creation part, you can create 16x16 or 32x32 size model in iPad but only 16x16 size model on iPhone/iPod since the screen size. The way you create voxel model is actually editing layers, and those layers will be composed. There are couple of tools you can use in model editor, I will upload a video later to show you how to use it to create a voxel model. After creating the voxel model, you can share them via the Internet, email or facebook. There will be an official website which list all uploaded voxel models and anyone with browser can view the uploaded voxel model from PC or iPad/iPhone.
This game will be free on iTunes store soon. Then we will port it to Windows 8, Windows Phone 8 and maybe Android. We are in crunch mode right now but I will try to post more video about the editor and gameplay soon. As usual, any suggestions, comments and questions are welcome. We still have time to adopt your opinions before submitting the build :)
標籤:
Indie Game,
Space Qube
Wednesday, October 24, 2012
Here Comes Our Hero
It's time for our hero showing up. He is the main character in Space Qube and will guide you through the game. If you need to buy any good item in Space Qube, he is the one you should look for :)
該是我們的英雄現身的時候了。他是Space Qube裡的主要角色,他會在遊戲中不時的出現並且帶領你完成遊戲。當你在遊戲中需要購買任何好用的道具時,找他就對了 :)
該是我們的英雄現身的時候了。他是Space Qube裡的主要角色,他會在遊戲中不時的出現並且帶領你完成遊戲。當你在遊戲中需要購買任何好用的道具時,找他就對了 :)
Recently, I and my son are getting a lot of fun from iron plastic beads. So I made a physical hero from the voxel data and he looks as cool as the virtual one.
最近我和我兒子都迷上了熨燙豆,所以我就用熨燙豆實體化了我們的英雄。實體化的英雄看起來跟遊戲中的英雄一樣酷呢。
I actually made a physical Space Qube logo as well, so let's take a picture together for the ending :)
其實我還實體化的遊戲logo,所以就來張大合照做為結束吧:)
標籤:
Indie Game,
Space Qube
Tuesday, October 23, 2012
Space Qube - My Upcoming Game
Below is the voxel model of the game logo, you can use mouse to rotate it. If you take a closer look at it, you will find it actually contains AO shading.
Do you find any clue from my last posted photo? Yes, Space Qube is a retro style shooting game which is based on voxel rendering. In this game, every character, power-up and even UI are all made by voxels. The best part is that the game includes an in-game model editor which allows the player to create their own model then share them via the Internet, Facebook and email. Using voxel to create model is like playing Lego brick, so the player can actually use voxels with different color to create anything they can image. The handmade Angry Bird toy on my previous post is actually created from the in-game editor :)
不知道大家有從之前照片中猜到了嗎?Space Qube是一款以voxel為基礎的復古射擊遊戲,遊戲中所有角色,道具甚至UI都是由voxel構成的喔。而遊戲中更內建了一個角色編輯器,可以讓玩家使用voxel來自由創作自己的角色,還可以透過網際網路,臉書或是電子郵件來分享自己創作的角色。使用voxel來建立模型就好像在玩積木一樣,所以玩家可以使用不同顏色的voxel來堆出任何想像得到的東西,之前照片中的Angry Bird玩具就是用遊戲中的編輯器做出來的喔 :)
This game is actually from a small game I made for my son. Because I was living in Canada alone for a long time and my son and wife were living in Taiwan. I usually talked with my son via Skype every morning before he went to the school. My son loves playing Lego brick but we can't play the bricks together since the geographic reason. The idea of using voxel rendering came up at that time so I wrote a small voxel editor on iPod. Therefore I and my son can play the bricks together via Skype. And I can also send him the model I made for him via the Internet.
其實這個遊戲本來是做給我兒子玩的一個小遊戲。因為之前有很長的一段時間,我都是一個人住在加拿大的,而我兒子跟老婆則住在台灣。每天早上我兒子上學前,我都會用Skype跟他視訊。我兒子很喜歡玩樂高積木,但我卻無法陪他一起玩,於是我就想到了使用voxel來做個小遊戲,這樣我們就能透過Skype一起玩積木了,而我幫他做的積木模型,也就可以透過網際網路傳給他玩了。
Louis is the artist of this game. We were talking about making a game together several times before but can never coordinate a time for it. This time, since I and Louis have quit our full-time job to focus on indie game developing, we finally have the chance to work together on our first game! And my artist friend Bic also gave me a lot of help at the beginning so I can finished the prototype.
So that's it for today, I will introduce you more features of this game in the future on this blog and thanks for your watching so far :D
今天就暫時先介紹到此,之後會在這再慢慢介紹更多遊戲的訊息跟技術給大家,感謝觀看 :D
Oh, there is one more thing. I created a new Twitter account for this game so you can follow it if you want to know the latest news about my game.
我最近為了這個遊戲建了一個新的Twitter帳號,之後會在上面隨時公佈一些開發消息喔。
標籤:
Indie Game,
Space Qube
Saturday, October 13, 2012
Handmade angry birds toy & some hints about my upcoming game
Handmade angry birds toy for my son but there are some hidden hints about my upcoming game on it :)
幫兒子做的手工憤怒鳥玩具,不過這裡面隱含了我即將完成的遊戲的一些線索喔 :)I will reveal more information about my upcoming game in a couple days and also hold an open beta registration on this blog in the near future, so keep tuned.
過幾天我就會開始陸續公佈一些遊戲的訊息了,之後應該還會在這裡開放Open Beta版本的註冊,Keep tuned.
標籤:
Indie Game,
Life,
Space Qube
Friday, July 27, 2012
I Am The Indie Game Developer Now!
下午交出了手機跟筆電還有badge之後,以後就不能再跑到公司印文件了,也沒有免費的手機跟3G了,更沒有免費電動可以打了:(。七年來每天工作的地方突然不用再去了,感覺還蠻不適應的。不過不論如何,總算走到了這一步,接下來終於要開始做我想了很久一直想要做的事-做自己想要做的遊戲!
是的,我就要成為一位獨立遊戲開發者了。至於為何想成為一位獨立遊戲開發者,我並沒有像一些獨立遊戲開發者一樣有很強烈的信念想要藉由遊戲來表達,對我而言,成為獨立遊戲開發者只是想快樂的開發遊戲而已。隨著年紀的增長,我慢慢理解到生命不但很短而且很渺小。年輕時總希望能做些轟轟烈烈的事,所以試著不斷挑戰console game跟引擎開發,但現在的我心境大為不同了。說起來也許很消極,但我慢慢覺得世上沒有任何人是不可被取代的,即使沒有了愛因斯坦還是會有人發現相對論的。因為這樣的想法,所以現在的我只想快樂的做自己想做的事,至於目標是渺小還是偉大,已經完全不重要了。即使是開發一個只賣0.99的小遊戲,只要做的開心,又能帶給玩家一段快樂的時光,也強過參與一個百人製作團隊的AAA大作。事實上跟兩三個志同道合的朋友一起開發遊戲,遠比在一個百人團隊中開發遊戲快樂多了。
其實從我開始工作以來,就一直斷斷續續在下班後做自己的遊戲,只是那時候還沒有獨立遊戲開發這個名詞。而那時的環境也很難讓 非主流的遊戲存活下來,直到Apple掀起了app的浪潮。雖然我個人不是很喜歡Steve Jobs的行事風格,但是多虧了Apple,現在任何非主流的遊戲只要方向正確,都能抓住足夠數量的玩家。我一直以來就喜歡看些非主流慢畫,也喜歡開發非主流遊戲,所以現在終於可以實現我的一些想法而不會餓肚子了 :)
這條路不知道我能走多久,不過我會盡力走下去的,而這個blog從今天起也會變成開始記錄我成為一位獨立遊戲開發者的生活點滴,只要時間允許的話,我會盡量把一些開發過程的大小事post上來的。Stay tuned!
標籤:
Indie Game,
Life
Wednesday, July 18, 2012
Standing Coding?
Those with a desk job, please stand up
Sitting Linked to Dying Early
Wednesday, June 20, 2012
Windows Phone 8
微軟今天公布了 Windows Phone 8, 果然如預期的一樣加入了native app的支援, 而且API會跟Win RT非常類似, 意思就是Windows 8 Metro App的開發者可以很容易的移植app到Windows phone 8上面了. 新的Windows Phone 8 SDK在今年夏天就會推出.
LynxEngine已經做了最基本的Windows 8移植 , 一直在等待微軟宣布新的Windows Phone 8之後就要移植上去, 看來再等兩個月就可以了. 正在開發中的遊戲iOS版一上架後, 我應該就會著手Windows 8及WP 8的移植了. 不過現在最大的問題不是移植, 而是如何忍住不要去碰移植的事而專心先開發遊戲啊! 將引擎移植到不同硬體上對我來說有著無法抗拒的魔力.....接下來真的要忍一下了, 只能利用休息時間來玩一下移植的遊戲了.
前幾天微軟宣布的surface雖然展示時的當機蠻糗的, 不過我基本上覺得還不錯, 當然為了移植應該或許也會買一台來玩玩. 基本上我對微軟的Win8及WP8目前是持正面的看法, 覺得應該會衝擊到Android的市場, 尤其是大廠的tablet, 山寨版的應該還是有低價優勢, 但也許他們會轉做山寨 Win8也不一定, 所以看來Android在tablet這塊上面很危險了.如果微軟能持續加強app的數量及品質, 應該是有機會跟iPad一較高下 .
Windows Phone 8相關的訊息可以看這裡.
LynxEngine已經做了最基本的Windows 8移植 , 一直在等待微軟宣布新的Windows Phone 8之後就要移植上去, 看來再等兩個月就可以了. 正在開發中的遊戲iOS版一上架後, 我應該就會著手Windows 8及WP 8的移植了. 不過現在最大的問題不是移植, 而是如何忍住不要去碰移植的事而專心先開發遊戲啊! 將引擎移植到不同硬體上對我來說有著無法抗拒的魔力.....接下來真的要忍一下了, 只能利用休息時間來玩一下移植的遊戲了.
前幾天微軟宣布的surface雖然展示時的當機蠻糗的, 不過我基本上覺得還不錯, 當然為了移植應該或許也會買一台來玩玩. 基本上我對微軟的Win8及WP8目前是持正面的看法, 覺得應該會衝擊到Android的市場, 尤其是大廠的tablet, 山寨版的應該還是有低價優勢, 但也許他們會轉做山寨 Win8也不一定, 所以看來Android在tablet這塊上面很危險了.如果微軟能持續加強app的數量及品質, 應該是有機會跟iPad一較高下 .
Windows Phone 8相關的訊息可以看這裡.
Monday, June 04, 2012
Some Updates....
又有好一陣子沒有更新blog了, 主要是因為這一陣子實在太忙了(每次藉口都一樣....). 因為最近為了之後搬家的事得開始準備打包了, 再加上房子的整修, 每個周末都忙得不可開交. 引擎的開發其實已經有一陣子沒有繼續了, 因為目前主要時間都放在兩個製作中的小遊戲上面.
這兩個製作中的遊戲當然是使用LynxEngin來開發的, 目前主要的target平台是iPhone/iPad, 但是將來應該有機會移植到多個平台上像是Android, Windows 8等. 最近剛裝了Windows 8的RC版, 比前一個版本又穩定了許多, 所以也將LynxEngine初步的移植上去了. 不過由於白天還要上班, 晚上大部分時間都要整理家裡, 所以遊戲的進度走走停停......, 好在再過一陣子就能全職的開發自己的遊戲了, 只是在這之前, 睡眠不足的日子可能還要再持續一陣子.
由於現在的移動平台遊戲幾乎都要與網路有所互動, 所以這一陣子也花了不少時間在以往不熟悉的網路programming上面. 這次為了完成一些需要的網路功能, PHP, MySQL, JavaScript, HTML5, WebGL跟Flash每一樣都得想辦法搞定. 以前從來沒想過自製遊戲會需要用到這些東西, 但現在這些東西似乎都變成必備技能了, 呵.
目前遊戲還在開發階段所以無法透露太多訊息, 等遊戲到了較接近完的階段時, 我一定會在這裡跟大家分享製作的過程及技術的, 請大家拭目以待囉 :)
標籤:
Indie Game,
Life
Sunday, May 06, 2012
Sunday, February 12, 2012
My Last GDC Presentation at GDC 2012
簡介
Following the release of DirectX 11 features for Unreal Engine 3 (UE3) last year, AMD has done a number of code submissions to further enhance graphics features in UE3. This presentation will cover each code submission in detail: tessellation, multi-monitor support, vertex shader-based Bokeh Depth of Field (DOF) and post-processing Anti-Aliasing.
Tessellation: Describes the new Phong tessellation mode that was added into UE3 as well as optimization options that were imported into the material editor. How to implement tessellation optimizations in the material editor without touching the shader code will also be covered.
Multi-monitor Support: The ever-improving affordability of LCD monitors combined with the level of performance found in recent GPUS are enabling more and more gamers to take full advantage of the PC Gaming experience by upgrading their system to a multi-monitor gaming setup like AMD Eyefinity. This presentation will describe how UE3 licensees can easily add multi-monitor support in their titles with minimal code changes. Considerations regarding Frustum updates and the scaling of on-screen elements such as HUD and menus will also be covered.
Vertex Shader Based Bokeh DOF: Last year, UE3 released a stunning DirectX 11 feature: Bokeh DOF. This feature makes use of the geometry shader to render a massive number of point sprites. Unfortunately the use of the Geometry Shader is subject to hardware limitations and can suffer from performance considerations that can impact the efficiency of this technique. This topic covers how the same effect was implemented using vertex shader and was made to work on both DX9 and DX11.
Post-processing AA: This topic will cover the new UE3 post-processing Fullscreen Anti-Aliasing features: FXAA and MLAA. We will focus on how to setup MLAA and what the differences are between MLAA and FXAA.
標籤:
Game Programming,
Working
Friday, February 03, 2012
Windows Phone 8 will Support Native Code
Wednesday, December 28, 2011
My Xmas Present
我不知道貢獻多少次錢給薩爾達時之笛這款遊戲了, 當年我的N64只有一張卡匣就是時之笛......, Game Cube也買了時之笛復刻版. 不過還是希望老任把風之指揮棒也重出在3DS上吧, 我會捧場的 :)
3DS內建的小遊戲比想像中有趣, AR的那個遊戲作的挺不錯的, 而且3D攝影的功能也蠻好玩的, 只是螢幕很小, 加上濾光片的角度有限, 玩的時候頭稍微亂動一下3D效果就跑掉了.... 而且打個十幾分鐘後再回來看電腦螢幕, 眼睛就會很不舒服. 不過整體而言, 還蠻不錯的, 尤其這個價格還算便宜, 感覺蠻划算的.
標籤:
Life
Saturday, December 10, 2011
在PC跟MAC間共用滑鼠/鍵盤
由於LynxEngine是一個跨平台的引擎, 所以我常常要在PC跟MAC上來回的工作. 目前我MAC的主要工作機器是MBP, 所以我都是外接螢幕再加上藍芽鍵盤/滑鼠來工作的, 每次都要來回切換輸入裝置實在很麻煩, 最沒效率的因為MAC鍵盤的配置跟PC鍵盤不同, 使用的時間又相對較少, 所以每次在MAC寫code時速度都會變慢很多.
這次回台灣渡假, 無意中發現台灣PC Home居然已經有賣這條j5 create JUC 400的線了, 而且還是24小時到貨, 二話不說買了一條. 目前使用了一個月, 非常的滿意, 在MAC上寫code的速度也增加了不少.這條線主要的功能就是讓使用者可以在PC跟PC或是PC跟MAC間共用鍵盤以及滑鼠, 同時還可以共用剪貼簿, 所以從PC上複製/移動資料夾到MAC也可以實現了! 另外附加的功能是還可以跟iPad/Android共用鍵盤/滑鼠喔.
非常推薦給同時有在開發PC跟MAC/iPhone遊戲的人.
標籤:
Game Programming
Thursday, November 10, 2011
Vertex Shader Based Bokeh DOF for UE3

最近半年都在幫UE3最佳化他們的DX11的部分還有增加一些AMD的新功能像是Eyefinity. 有一些更新已經被Epic整合進UE3了, 有一些則沒有. 今天剛丟出去的是原本只支援DX11的新功能-Bokeh DOF. 原本Epic是使用Geometry Shader來實作的, 但是因為輸出的point sprite數量很龐大, 很容易就超過了硬體能承受的頻寬而降低效能, 所以我將他移到了Vertex Shader來實現, 同時帶來另一個好處就是DX9的硬體也能使用這個特效了.
有UE3的授權的人請到這裡下載程式吧, 使用UDK的人就得等到Epic把他整合進去了, Epic是說他們之後會想整合進去, 至於何時就不清楚了......
標籤:
Game Programming,
Working
Wednesday, August 03, 2011
LynxEngine Update : Web Player
前幾天為了JNI而上網找了一些資料, 意外發現其實透過JAWT可以輕易將native的東西render到browser上, 這樣透過JNI來橋接native code跟java, 就可以一次解決Android跟Web兩個平台了. 花了一個晚上試了一下, 結果出奇的容易. 然後寫了個java wrapper把輸入訊號送到native就大功告成了.
把之前的Script Game放上瀏覽器, 可以順利的運作, Lua跟Mono都可以正確執行無誤. 等再把JNI部分全部完成後, 應該移植到Android就沒甚麼大問題了.
標籤:
LynxEngine
Sunday, July 17, 2011
LynxEngine Update : Script System
很久一段時間都沒有新文章了, 因為前一陣子一直在忙著做iPhone的遊戲, 引擎也就很少進展了. 但是由於人力, 以及時間等等因素, 案子進展的的很不順利. 接著六月開始我又得一個人帶小孩, 上下學接送, 洗澡樣樣得自己來所以忙到連iPhone遊戲的案子都沒時間作了. 於是只能趁小孩睡覺後的一兩個小時, 試試引擎的script system. 其實引擎的script系統早就玩成了, 之前是使用Lua為主, 但是從來沒用script來做過任何遊戲demo, 所以這一兩個小時的時間就正好用來試試script系統以及補強一些功能.
在修改了一些功能後, LnxEngine可以僅依靠Lua script完成整個遊戲的介面以及遊戲gameplay. 這次試作了一個橫向卷軸遊戲, 下面是遊戲的影片, 背景都是2D的sprite, 只有人物是3D的. 之後會繼續作作其他類型遊戲來試試看script system的能力.
之後上網看了一下Mono, 才發現Mono runtime 其實可以直接內嵌到應用程式中, 所以任何符合.Net 的bytecode, 就可以藉由Mono runtime來執行. 花了幾天時間上網查了一些資料, 發現整合Mono沒想像中的難, 不過原本的 C#+C++/CLI+Native的作法在Mono上卻行不通於是只好改用類似swig的作法來橋接Managed code跟Native code, 缺點是要花多一點時間來寫wrapper. 之後使用了C#來完成了之前用Lua作出的卷軸遊戲. 使用Mono最大的好處是, 任何能編譯成.Net bytecode的語言都可以用來作為引擎的script語言, C#, VB, JavaScript, Java都沒問題, 甚至Lua都有人作出bytecode編譯器, 所以彈性可以說是非常的高. 目前Lua與Mono是併存於LynxEngine中, 但將來應該會慢慢轉移到以Mono為主.
以下就列出C#以及Lua的code 作個比較, 相較起來Mono還是更有彈性.
C# script list
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
{
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 list
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
標籤:
LynxEngine
Wednesday, January 26, 2011
LynxEngine update : iPhone Accelerometer Test
好久一段時間沒有更新了, 主要是因為這段時間都在忙iPhone的移植.
前一陣子終於註冊了Apple Developer的會員所以終於可以在iPhone上直接跑程式了.而模擬器上不能用的陀螺儀功能就成了第一個想測試的東西. 所以就結合了陀螺儀功能跟引擎做了一個類似裸視3D的功能, 實際跑起來還蠻有趣的. 不過由於我用的是iPod所以可視角度蠻差的, iPhone4的可視角度就好很多.
前一陣子終於註冊了Apple Developer的會員所以終於可以在iPhone上直接跑程式了.而模擬器上不能用的陀螺儀功能就成了第一個想測試的東西. 所以就結合了陀螺儀功能跟引擎做了一個類似裸視3D的功能, 實際跑起來還蠻有趣的. 不過由於我用的是iPod所以可視角度蠻差的, iPhone4的可視角度就好很多.
標籤:
LynxEngine
Saturday, October 23, 2010
LynxEngine iPhone 2D Physics
之前發現了個不錯的2D物理引擎(Box2D), 所以臨時決定先將2D物理引擎加入iPhone版本中. 跟原先的物理引擎使用相同的程式介面, 所以很快便完成初步的整合. 接下來應該是要整合Bullet了.
Sunday, October 17, 2010
Subscribe to:
Posts (Atom)