圖片隨機的移動? |
尚未結案
|
enu
中階會員 發表:36 回覆:93 積分:55 註冊:2003-10-22 發送簡訊給我 |
|
nlj859
資深會員 發表:139 回覆:375 積分:322 註冊:2004-03-20 發送簡訊給我 |
Hello enu, 請參考底下做法:
*在form上隨機跳躍
假設你的from大小是640x480.
為何要減掉Image1->Width和Image1->Height?
原因是因為不要讓圖片超出form外面.
void __fastcall TForm1::Timer1Timer(TObject *Sender) { Image1->Left=random(640-Image1->Width); Image1->Top=random(480-Image1->Height); }* 米字型跳躍: void __fastcall TForm1::Timer1Timer(TObject *Sender) { int i=random(9) 1; switch (i) { case 1: Image1->Left=0; Image1->Top=0; break; case 2: Image1->Left=100; Image1->Top=0; break; case 3: Image1->Left=200; Image1->Top=0; break; case 4: Image1->Left=0; Image1->Top=100; break; case 5: Image1->Left=100; Image1->Top=100; break; case 6: Image1->Left=200; Image1->Top=100; break; case 7: Image1->Left=0; Image1->Top=200; break; case 8: Image1->Left=100; Image1->Top=200; break; case 9: Image1->Left=200; Image1->Top=200; } }* 怎麼算出1公分? 我以小畫家去看,32x32剛好是1mx1cm void __fastcall TForm1::Timer1Timer(TObject *Sender) { Image1->Left =32; } void __fastcall TForm1::FormCreate(TObject *Sender) { Image1->Left=0; }發表人 - nlj859 於 2004/08/07 19:20:08 |
enu
中階會員 發表:36 回覆:93 積分:55 註冊:2003-10-22 發送簡訊給我 |
|
nlj859
資深會員 發表:139 回覆:375 積分:322 註冊:2004-03-20 發送簡訊給我 |
|
richtop
資深會員 發表:122 回覆:646 積分:468 註冊:2003-06-10 發送簡訊給我 |
enu 您好: 試試看下列方式是否會比較接近,(Form的Scaled屬性要是true)
void __fastcall TForm1::Button1Click(TObject *Sender) { int n = Form1->PixelsPerInch; float pixelsPerCM = (float)n/2.54; // 1 inch = 2.54 cm Form1->Canvas->Rectangle(0, 0, pixelsPerCM, pixelsPerCM); ShowMessage(pixelsPerCM); }RichTop 敬上 =====***** 把數學當工具,可以解決問題;將數學變能力,能夠發現並解決問題! =====##### |
enu
中階會員 發表:36 回覆:93 積分:55 註冊:2003-10-22 發送簡訊給我 |
首先感謝nlj859和richtop先生,
從nlj859所提供的資料中也發現了richtop的方法在不同的顯示(如1024×768或800×600),其所呈現的長度亦不同。 小弟再將問題明確的描述一下,看是否有那位先進可以再提供些建議:
一個image(38×38)的小圖片在全螢幕下移動,其可能移動的方向有45、90、135、180、225、270、315、360度等方向(如"米"字型),而其可能移動的距離是1、5 、10、15cm等,但是同一個方向、同一個距離如果已經走過,就不能再走(當然也不能超出form的範圍),直到所有可能移動的方向、距離均走過則停止。
感謝nlj859和richtop先生,小弟根據您們的建議試了幾天,但還是搞不定!不知道還有沒有先進肯指點一下,感激不儘!謝謝!
|
nlj859
資深會員 發表:139 回覆:375 積分:322 註冊:2004-03-20 發送簡訊給我 |
引言: 首先感謝nlj859和richtop先生, 從nlj859所提供的資料中也發現了richtop的方法在不同的顯示(如1024×768或800×600),其所呈現的長度亦不同。 我在兩部電腦中試過都是以1024x768的解析度,但是以小畫家來試時一個是32x32,另一個是37x37,我不太曉得這是不是解析度的關係. 小弟再將問題明確的描述一下,看是否有那位先進可以再提供些建議: 一個image(38×38)的小圖片在全螢幕下移動,其可能移動的方向有45、90、135、180、225、270、315、360度等方向(如"米"字型),而其可能移動的距離是1、5 、10、15cm等,但是同一個方向、同一個距離如果已經走過,就不能再走(當然也不能超出form的範圍),直到所有可能移動的方向、距離均走過則停止。 感謝nlj859和richtop先生,小弟根據您們的建議試了幾天,但還是搞不定!不知道還有沒有先進肯指點一下,感激不儘!謝謝!Hello enu, 現在既然知道你有8個方向且各有4種可能的走法,所以你可以陣列去記錄走過的位置,如bool Direction[8][4];一開始初始值均為false,走過記錄為true. 當然每次走之前要先確認是true還是false. 希望這些建議對你有所幫助. |
richtop
資深會員 發表:122 回覆:646 積分:468 註冊:2003-06-10 發送簡訊給我 |
enu 您好: 嘗試用Windows API:GetDeviceCaps(.),去計算其在目前解析度下,一公分的pixel數(僅算寬度部分),請參考,如下:
void __fastcall TForm1::Button2Click(TObject *Sender) { AnsiString msg; int vSize = GetDeviceCaps(Form1->Canvas->Handle, HORZSIZE); // screen width in mm. int vRes = GetDeviceCaps(Form1->Canvas->Handle, HORZRES ); // pixels of screen width. float pixelsPerCM = (float) vRes *10.0 / vSize; msg.printf("width %d in mm,\npixels: %d,\nPixelsPerCM=%5.2f", vSize, vRes, pixelsPerCM); Form1->Canvas->Rectangle(0, 100, pixelsPerCM, 100 pixelsPerCM); ShowMessage(msg); }這也就是說,如果您的目標是要不管在任何解析度下,螢幕上圖片的長度用尺量的結果都要是一公分的話,那麼上述的計算應該就是了。 至於您的圖片,也可以試著在螢幕上量一量是不是接近一公分,以方便判斷是哪一個環節出了問題。 假設上述算法可行,但圖片大小不準,則可以將該Image的長寬重設(令Image->Stretch=true),如此便能在螢幕上出現一個大小接近一公分的正方形。 希望對您能有幫助。 還有您所謂:"但是同一個方向、同一個距離如果已經走過,就不能再走",我不太了解,那是不是往右走一公分之後,就不能再往右走一公分了? RichTop 敬上 =====***** 把數學當工具,可以解決問題;將數學變能力,能夠發現並解決問題! =====##### |
enu
中階會員 發表:36 回覆:93 積分:55 註冊:2003-10-22 發送簡訊給我 |
|
nlj859
資深會員 發表:139 回覆:375 積分:322 註冊:2004-03-20 發送簡訊給我 |
|
richtop
資深會員 發表:122 回覆:646 積分:468 註冊:2003-06-10 發送簡訊給我 |
enu 您好: 問題似乎比較清楚了。
不過還有一個疑問要請教:
是不是Image只有 (方向) x (可能的距離) = (8) x (4) = 32 走法,且走過一次就不能再有相同的走法;在隨機且不跑出Form範圍內,看最後Image會在哪裡? 如果是這樣,那可以一個int陣列來存走過的方向與距離,
方向:當成十進位數,比方1-8。
距離:當成個位數,表示某一距離,比方1-4,其中1,2,3,4分別表示1,5,10,15cm。 所以沿方向3走5cm,就能寫成: 3*10 + 2 = 32,(各方向與距離值都不同)
將之存入int path[32]中。
至於可能的方向與要走的距離就隨機產生,比對已經存在path[]中的值,就知道有沒有重複。 這是在方向與可能的距離均有限的情形下,所作的權宜。 其實nlj859的方法能適用於一般的情形,看看您的需要來選擇。 不過我想把真正的走法規則確認之後,這個問題應該能得到解決的。
|
enu
中階會員 發表:36 回覆:93 積分:55 註冊:2003-10-22 發送簡訊給我 |
謝謝nlj859和richtop先生,經由您們的建議,問題解法似手更明確了。 先回答nlj859先生所提的問題,距離的選擇就是固定幾種,而往右走1cm之後,就不能再往右走1cm了,但可以往左走1cm,只要往左走1cm之前並未走過(前提是random剛好產生往左走1cm);此外,切到別方向時,並非回到原點,而是以之前產生的位置繼續走下去,所以才必須注意random後的方向和距離是否超出form的範圍。 小弟的問題應該如richtop先生所整理的,Image只有 (方向) x (可能的距離) = (8) x (4) = 32 走法,且走過一次就不能再有相同的走法;在隨機且不跑出Form範圍內。 如果是這樣,應該如何做比較適當呢?懇請賜教了!感激不儘!
|
richtop
資深會員 發表:122 回覆:646 積分:468 註冊:2003-06-10 發送簡訊給我 |
enu 您好: 因為還要完成其他事,所以寫了下列的版本供您參考,沒有完全測試過!
就請您自個兒看看,是否能提供您問題解答的參考。 <>< class="code">
//---------------------------------------------------------------------------
struct Direction
{ int dir;
int toGo;
};
Direction dirs[32];
int distance[] = {1,5,10,15}; void init()
{ int index=0;
for (int d=0; d<8; d )
{ for (int k=0; k<4; k )
{ dirs[index].dir = d;
dirs[index].toGo = distance[k];
index ;
}
}
} // 方向定義(順時針方向): 0:東,1:東北,2:北,...,依此類推。
int shiftX[]={ 1, 1, 0,-1,-1,-1, 0, 1};
int shiftY[]={ 0,-1,-1,-1, 0, 1, 1, 1}; void getDxDy(int& dx, int& dy, Direction d, float scale=1) // 取x,y方向的相對位移分量
{ dx = d.toGo * shiftX[ d.dir ] * scale;
dy = d.toGo * shiftY[ d.dir ] * scale;
}
void exchange(int times) // 隨機交換times次
{ int index;
Direction temp; for (int k=0; k
|
nlj859
資深會員 發表:139 回覆:375 積分:322 註冊:2004-03-20 發送簡訊給我 |
Hello enu, 請參考底下程式碼:
程式假設是以1024x768的大小
Unit1.cpp
#includeUnit1.h #ifndef Unit1H #define Unit1H //--------------------------------------------------------------------------- #include有一個問題就是: 因為照你的需求來講,"走過的就不能再走"&"不能超出Form的大小", 但"如果是它走到邊邊角角的位置時,這下發現,死了,以無法回頭,因為可以回頭的那些方法都已經被走過了",那這下程式就永遠走不出去了,永遠沒辦法把8*4=32種走完. 所以當它走到邊邊角角時就很有可能停住不動了. 提供參考. 寫的不好,請多見諒 發表人 - |
enu
中階會員 發表:36 回覆:93 積分:55 註冊:2003-10-22 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |