2011年12月19日 星期一

[VC]給應用程式做個ICON

寫程式也寫了有兩年了,但是從來也沒給程式弄個ICON過。

原因主要有兩個…

第一,開發的幾乎都是嵌入式程式…
(給鬼看喔)


第二,再來就是Linux的常駐程式…

其他的話,就都是網路的程式了。
PHP、Flash、C#的小工具…

總之…是給鬼看喔!


以上屬於閒聊,主因是最近在弄作品集,想把之前做的DEMO遊戲弄得漂亮點。

遊戲程式弄成這樣…總是不太好吧

經過一番Google之後,找到了一個比較快的方法,在此作為筆記。

Step 1:
在Project哩,加入一個*.rc的檔案。

Step 2:
點兩下,或打開資源視窗,就會看到裡面有一個類似資料夾的東西。
Step 3:

準備一個 *.ico 的檔案。

Step 4:

使用筆記本編輯"*.rc"檔案,裡面會有一堆註解…其實都沒用,只要把下面兩行輸入即可。

#include "resource.h"
IDI_ICON1               ICON                    "icon2.ico"


Step 5:
Build好之後,就會看到Icon貼在程式上了,像遊戲多了吧!




2011年12月12日 星期一

[VC Debug] delete 引發的 0xfeeefeee [ heap memory ] 問題

因為有點時日沒碰C了,碰到了很久以前曾經發生過的問題。

問題點:
STACK * temp_stack=new STACK();
memcpy(temp_stack,this,sizeof(STACK));
delete temp_stack;

這三行程式碼,乍看之下好像沒甚麼不對。
可是當你按下Debug時,問題就來了。

其實解決分法就是...
用C的方法去做,如下:
STACK * temp_stack=(STACK *)malloc(sizeof(STACK));
memcpy(temp_stack,this,sizeof(STACK));
free(temp_stack);

問題點之二:
void operator =(datas & val)
{
  memcpy(this,&val,sizeof(datas));
};

解決方法就是別用memcpy...
雖然C歸C,C++歸C++。
但是有些在C上很好用的方法,用在C++上卻會出問題。
所以寫程式還是謹慎點。

順帶一提…Release程式是不會有這個問題的。
可是我有潔癖…

查資料時得到的豆知識
[ 0xCCCCCCCC ] 沒有被初始化的stack memory
[ 0xCDCDCDCD ] 沒有被初始化的heap memory
[ 0xFEEEFEEE ] 意指freefree, 就是已歸還的heap memory

2011年6月4日 星期六

捲筒式選單



雖然可能不是很實用,但是效果應該還不錯。

程式碼還蠻長的,所以只講重點囉。
首先是Initialization

畢竟計算3D的座標也是要靠CPU下去算,如果直接讓電腦算的話雖然會比較省事,但是效能會拖慢。

所以首先始先把座標遇先算好。
private function init():void {
    var theta:Number;
    for (var i:int = 0; i < 360; i++){
        theta = i * Math.PI / 180;
        var p:* = {  x: Math.cos(theta) * WIDTH_FIT, //預先算好360度的 x,y,z
                            y: Math.cos(theta) * HEIGHT_FIT,
                            z: Math.sin(theta) * HEIGHT_FIT,
                            rotationX: i + 90, //橫向時所需的旋轉角度
                            rotationY: -i - 90, //縱向時所需的旋轉角度
                            alpha: .6,    //滑鼠不在按鈕上時的alpha值
                            Alpha: 0.2 + (((HEIGHT_FIT - (Math.sin(theta) * HEIGHT_FIT)) / HEIGHT_FIT) * 0.5)}; //Button內層顏色的透明度,這裡是為了突顯3D效果
        position.push(p);
    }
}
座標算好之後就是產生按鈕 程式碼如下
private function BUTTON(theta:int,w:Number = 256, h:Number = 64, text:String = "123", textColor:uint = 0, color:uint = 0x33CC66, alpha:Number = 1):Button {
    var button:Button = new Button(w, h, text, textColor, color, alpha);
    _objects.push(button);
    button.index = (360 - theta + 269 + Shift) % 360;
    //直接把剛剛init產生出來的值填進去
    for (var str:String in position[button.index])
        if (ScrollMode == 'y'){
            if (str != 'x' && str != 'rotationY')
                button[str] = position[button.index][str];
        }else if (ScrollMode == 'x'){
                if (str != 'y' && str != 'rotationX')
                    button[str] = position[button.index][str];
            }
    button.addEventListener(MouseEvent.MOUSE_OUT, Move);
    Mouse.add(button, MouseEvent.MOUSE_OUT, {alpha: .6, filters: []}); //這個類就暫時先不提(要引入package.swc  因為蠻複雜的..以後再做整理),效果就是跟addEventListener一樣
    Mouse.add(button, MouseEvent.MOUSE_OVER, { alpha: .9, filters: [new GlowFilter(0xffffff, 0.9, 32, 32, 2)] } );
    return button;
}
其中有一個Mouse的類別,這是我為了方便製作按鈕而寫的類別。
但是因為實在是非常的複雜,而且還在建構中,尚不完全。
先附上swc檔,日後再做解說。
程式的重點大致上就這些,再來就是應用了。附上完整程式碼,有問題在留言吧。

2011年5月29日 星期日

圖片的鏡射處理

鏡射應該是遊戲設計裡常會用到的方法。

但是很遺憾,SDL似乎是沒有這個方法…

沒有這個方法的話就自己寫一個吧。

相較於降低品質,鏡射容易多了,所以同樣的事我也不做贅述。

依然是只有PNG和BMP
/** 
* Srite :類型-(SDL_Surface *)SDL圖片底層Struct,對像圖片(想轉成BMP的圖) 
* type :只有PNG或不是PNG兩種,有興趣的在自己擴充吧
*/
SDL_Surface* Sprite_Convey2Mirror( SDL_Surface* Sprite ,string type)
{
    SDL_Surface* Mirror;
    if ( type == "PNG" )
        Mirror = SDL_DisplayFormatAlpha( Sprite );
    else
        Mirror = SDL_DisplayFormat( Sprite );

    SDL_Color rgb1;

    Uint32 rgb3;

    #pragma omp parallel for
    for ( int j = 0;j < Mirror ->h - 1;++j )
    {
        for ( int i = 0;i < Mirror ->w - 1;++i )
        {
            rgb1 = GetRGB( Sprite, i, j );

            if ( type == "PNG" )
            rgb3 = SDL_MapRGBA( Sprite ->format, rgb1.r, rgb1.g, rgb1.b, rgb1.unused ); //取得目標顏色RGBA,包含alpha
            else
            rgb3 = SDL_MapRGB( Sprite ->format, rgb1.r, rgb1.g, rgb1.b );//取得目標顏色,不包含alpha

            putpixel( Mirror, Sprite ->w - i, j, rgb3 ); //這裡就是整個Function的重點,反方向把顏色撲回去,這個函式之後我再解釋
        }
    }
    return Mirror;
}

降低圖片品質

這個Function,主要是把已經讀進記憶體的圖片再做一次降低品質。

或許有人會想問,為什麼這樣做?

32bit的圖片是比較漂亮沒錯。但是也大大拖慢了CPU的處理速度,轉成24bit之後效能會大大提升。

當然也有缺點,就是會變得比較醜…

當然SDL支援的圖片不是只有PNG跟BMP格式。

但在這個Porject裡我只有用到這兩個格式,如有需要用到TGA格式…就Google一下吧.
/** 
* Srite :類型-(SDL_Surface *)SDL圖片底層Struct,對像圖片(想轉成BMP的圖) 
* color :整張圖片的顏色 0 ~ 0xff , -1為關閉,PS:如果圖片不是單色請設成-1 
* fade :0xff,代表不做漸層效果
* **/
SDL_Surface* Sprite_Convey2Lowbilt(SDL_Surface* Sprite, int color ,int fade ,int colorkey)
{
    SDL_Surface * temp = SDL_DisplayFormatAlpha( Sprite ); //首先複製一分一樣的圖片
    SDL_Color rgb1;
    Uint32 rgb3;
    Uint8 a, r, g, b;
    #pragma omp parallel for

    for ( int j = 0;j < temp->h ;++j )
    {
        for ( int i = 0;i < temp->w;++i )
        {
            rgb1 = GetRGB( Sprite, i, j );

            if ( rgb1.unused != 0 && rgb1.unused > 64)  // rgb1.unused 是透明度 0 ~ 0xff 這裡只偵測到超過一半才執行半透明混色
            {
                a = fade == 0xff ? fade : ( rgb1.unused - rgb1.unused / 10 ) ;
                if(color!=-1)
                {
                    rgb3 = ( 0xff << 0x18 ) + color;
                }else
                {
                    fuzzy( &rgb1, &a, &r, &g, &b );//取得顏色函式,這個涵式我在另外解說
                    rgb3 = ( 0xff << 0x18 ) + ( r << 0x10 ) + ( g << 0x8 ) + ( b );
                }
            }
            else
                rgb3 = ( 0xff << 0x18 ) + colorkey;//如果透明度超過,則加入colorkey的顏色

            putpixel( temp, i, j, rgb3 );//把rgb存到指定的點,這個涵式我會在另外解說
        }
    }
    temp = SDL_DisplayFormat( temp );  //最後再Format一次,即大功告成
    return temp;
}

2011年5月28日 星期六

SDL 開發心得

Simple DirectMedia Layer

簡稱SDL

這是一個能夠跨平台(跨平台多媒體),穿梭於Windows語Linux之間的函式庫,功能與DirectX近乎一樣。

當然在Linux下執行的話,一定能夠節省很多的設備成本;但反之,則會增加人力、開發成本。

當初選擇SDL開發的原因,就是因為他能在Windows下進行Debug,因此也節省了很多開發時間。

畢竟專案的程式開發人員只有一個人,從無到有也是費了一番工夫。

而今事過境遷,這項開發工作也因為我的離開中止了。

雖然不保證程式完全沒問題,但是為了不忘記自己寫的程式。

在此整理一下自己寫過的程式。

嘛…說是完全自己開發的,是沒錯。

但是因為這是我出社會的第二個Project,所以程式的寫法還是很幼稚。

C至C++還是有段距離,而當時小弟我對OOP也不甚了解,所以就寫了很多指標…

可能看還是有點難,就連我自己都要稍微想一下了。

望請砲火不要太強阿…