Visual C++ ile Görsel Programlama 5 (Win32)
Visual C++ ile Görsel Programlama 5 ( Zamanlayıcı ve Haraket )
Visual C++ ile Görsel Programlama 5 ( Zamanlayıcı ve Haraket )
Basit bir iki boyutlu Oyun yazmaya geçmeden önce son öğreneceğimiz
Zamanlayıcı olacak ; kod sayfasında baş kısımda tanımlama yapıyoruz.
#define ID_ZAMAN 100
ZAMAN isimli bir değişken tanımlıyoruz. daha sonra WM_CREATE mesajı içersinde
SetTimer komutu ile bu değişkeni zamanlayıcı yapıyoruz.
case WM_CREATE:
SetTimer( hWnd, ID_ZAMAN, 1000,
NULL );
break;
Bu işlemi yaptıktan sonra bu zamanlayıcı otomatik olarak her saniyede bir kez WM_TIMER isimli bir mesaj gönderir.(1000birim=1 saniye) zamanlayıcıyı 5 saniyelik yapmak isteseydik bu değeri 5000 yapacaktık.
WM_TIMER: //Zamanlayıcı mesajı
wParam: // birden fazla zamanlayıcı kullanılırsa bu değer zamanlayıcı
adını veren sayıyı taşır. ( ID_ZAMAN= 100 değerini verir)
lParam: // (TIMERPROC *) lParam; Zamanlayıcı için ayrı bir
LRESULT CALLBACK düzenlenmişse bunun adını verir (adres olarak)
buna bir örnek verirsek şu şekilde yazabiliriz. iki tane zamanlayıcımız olduğunu düşünelim. ID_ZAMAN ve ID_ZAMAN2 bu durumda:
case
ID_ZAMAN2: } |
devamlı olmasını istediğimiz olayları yukarda kırmızı ile işaretlenen noktaya
yazacağız. Eğer buraya bir mesaj kutusu koysaydık her saniyede bir kez mesaj
kutusu açılacaktı. Aşağıdaki gibi yazabilirsiniz.
case ID_ZAMAN:
MessageBox(NULL,"zaman
geldi","mesaj başlığı",MB_OK);
break;
Şimdi de bunu kullanarak pencere üzerinde kayan bir resim gösteren bir uygulama yapalım. Bir önceki derste resim eklemeyi gösteren projeye zamanlayıcı eklemek isteseydik değişkenlerin karışık görünmemesi için #define ID_ZAMAN 120 isimli tanımayı da resource.h içersine yazacaktık. sol taraftan dosya adına çift tıklayıp bunu yazdıktan sonra SourceFiles kısmındaki ana kod sayfasına tıklayıp geri dönüyoruz.
Eğer Microsoft'tan başka bir firmanın derleyicisini kullanıyorsanız. #define satırını kodun en başına yazabilirsiniz. aşağıdaki şekilde.
#include <windows.h>
#define ID_ZAMAN 120
Biz buradaki kodu yeni bir proje için yazdık Pencere üzerinde haraket eden bir küre oluşacaktır. küre sağa doğru saniyede 10 birim gitmektedir.
#include "windows.h" #define ID_ZAMAN 120 const char Classismi[] = "pencere"; int yeriX=0; //cismin X ekseninde yeri int yeriY=0; //cismin Y ekseninde yeri LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc; // çizim için gerekli tanımlamalar PAINTSTRUCT ps; RECT anakare; switch(msg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: //zamanlayıcıyı imha et KillTimer(hwnd, ID_ZAMAN); PostQuitMessage(0); break; case WM_CREATE: //zamanlayıcıyı belirle SetTimer( hwnd, ID_ZAMAN, 500, NULL ); break; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &anakare); FillRect(hdc, &anakare, (HBRUSH)(LTGRAY_BRUSH)); Ellipse(hdc,yeriX,yeriY,yeriX+30,yeriY+30); yeriX=yeriX+10; EndPaint(hwnd, &ps); break; case WM_TIMER: hdc=GetDC(hwnd); GetClientRect(hwnd, &anakare); FillRect(hdc, &anakare, (HBRUSH)(LTGRAY_BRUSH)); Ellipse(hdc,yeriX,yeriY,yeriX+30,yeriY+30); yeriX=yeriX+10; ReleaseDC(hwnd,hdc); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; HWND hwnd; MSG Msg; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = Classismi; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Pencere tanımlama hatası!", "Hata!", MB_ICONEXCLAMATION | MB_OK); return 0; } hwnd = CreateWindow(Classismi,"Pencere başlığı",WS_OVERLAPPEDWINDOW, 200, 200, 300, 200,NULL, NULL, hInstance, NULL); ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } |
yukardaki kod içersinde önemli olan nokta WM_TIMER kısmı ama WM_PAINT kısmını da inceleyelim.
case WM_PAINT: case WM_TIMER: |
Aslında komutu sadece WM_TIMER içine yazmamız gerekiyordu, ama eğer WM_PAINT içersinde benzer bir çizim kodu yazmazsak pencereye tazeleme mesajı geldiğinde bir saniye süre ile pencere tamamen beyaz olur. bunu görmek için case WM_PAINT ile break; arasını silebilirsiniz.
Bu projede Her saniye çizimi yeniden yapıyoruz. Ana pencereyi her seferinde gri renge boyayıp daireyi tekrar çiziyoruz, Fakat daire her çizimde farklı bir noktaya çizildiği için haraket ediyormuş gibi görünüyor.Bu yöntemde çizdiğimiz daireyi ana pencereden silmenin bir yolu yoktur. Birçok oyunda her an tüm sahne yeniden çizilir. saniyede kaç kere çizildiği ise FPS (frame per second) ismi ile tanımlanır. Yeni çıkan üç boyutlu oyunların bu kadar hızlı (ve pahalı) kartlar istemesinin sebebi budur. Saniyede birçok kere gördüğünüz cisimleri yeniden yeniden çizmektedirler.
Konuyu anladık mı ?
Uygulama sorusu: Bu uygulamayı geliştirin. Yuvarlak cisim sağ kenara çarpınca
geri gitsin.
Ekleyen: drekon
Kapalı
Eklediğim Dersler
Ders Kategorileri
Yeni Dersler (Tutorials)
- Armor Modelleme
Ekleyen: Dereli - Ücretsiz Zbrush Dersi.
Ekleyen: BurakB - Corona Render ile Salon Görselleştirme
Ekleyen: barcelona1988 - Tek Bir Resimle Nasıl Sinematik Görüntü Ala Biliriz?
Ekleyen: PixlandPictures - After Effects - Script kullanmadan karakter rigleme
Ekleyen: PixlandPictures - 3dsmax landscape_ Making of Part1
Ekleyen: altıneldiven - Oyun yapımı dersleri 5 - Unity3D Sahne Duzeni
Ekleyen: drekon