* VC++ API DirectX 2D library & Engine - 1 - Start~ 안녕하세요^-^ 최인균입니다~. 예전에 VB 으로 타자프로그램 만들기 강좌를 썻었는데^^ 이번에는 VC++ API DirectX 2D library & Engine 만들기 강좌를 준비해 보았습니다 일단 첫번째 시간이니까.. 여러가지 기초적인 것들을 알아보죠. library.....이게 무엇인가요?.. 물론 아시는분은 쫙 밑으로 내리셔도 됩니다.~.하핫 영어사전에서 찾아보면..흠흠..도서관이라는 뜻이군요 흠..저도 프로그래밍에서 쓰이는 lib(줄여서 이렇게 쓰겠습니다.)가 어떤뜻인지 잘 모릅니다.^-^; 프로그래밍 하시는분이면 알겠지만. ddutil 이나 dxutil 같은 파일이라고 생각하시면 쉽습니다. 바이블이라고 생각하셔도 되겠네요^^..바이블이란 책은 꽤 두껍고 내용이많습니다 그러나 바이블의 용도는 모르는것이 있을때 찾아보는것이죠 라이브러리도 마찬가지입니다. 필요할때 라이브러리의 제작해놓은 함수를 쓰면됩니다. 없을때는?.직접 만드셔야곘죠^-^. 예를 들자면 제가 2d 그래픽 라이브러리 하나를 제작했다고 합니다. 제가 만든 LoadPicture 란 함수 하나만 쓰면 jpg, bmp 로 된파일을 다 불러올수있다고 합시다. 그러면 그 LoadPicture 란 함수는 어?.어쩌지 pcx 파일도 불러 들여야되는데 할때만 고쳐주면 되는것입니다. 그 이외일때는 lib 파일로 만들어서 ddraw.lib 같은거 추가해놓고 쓰듯이 그렇게 추가해놓고쓰면 되는것입니다. 물론 cpp 와 h 파일을 수정해야될때를 위해 남겨두어야겠죠 Engine..이놈은 엔진이라고 읽죠^-^ 엔진이란 그런 라이브러리의 집합체라고 알고있습니다. 그래픽, 인풋, 쇼, 뮤직, AI , 파티클, 네트윅 등.. 이런 라이브러리가 모여서 하나의 엔진이 되는것이죠. 그 엔진은 만들 게임에 따라 충분히 많이 달라지기 마련입니다. 그래픽 엔진이라고 하면 256 칼라인지 16bit 인지 또한 여러가지 특수효과, 어떤 그래픽 특수효과가 들어가는지 bmp 파일을 이용할것이지, pcx 를 이용하는지 아니면 자체포멧을 이용하는지, 등등... 뮤직엔진같은것도 이게임에서 mp3 를 사용하겠다, wav, mid 를 사용하겠다 또 압축방식에 따라 달라질수있겠죠^^. 그렇기 때문에 엔진 제작하는건 상당히 어려운일입니다. 여러가지 고려할점이 많죠..가장 크게 재활용성이라든지.. 이 강좌에서 말씀드리고 싶은건 실제로 엔진을 제작하는것보다 그 방법을 알려드리고자 하는것입니다^^ 어느정도 수준의 프로그래머 분이시라면 그 방법만 알면 혼자서 하실수있으실것이라고 생각합니다^^ 물론 실제 제가 제작한 엔진을 설명을 위해 약간 보여드리긴 하겠지만.. 이상해서요..걱정이네요^^. 막상 이렇게 쓰는데요.. 제가 글을 잘 못쓰거든요..실력도 별로없고.. 여러분이 도와주시면 감사하겠습니다.^^ 그럼 다음강좌는 .lib 파일 만들기~ 를 하겠습니다^-^..기대해주세요. p.s 의문이나 요청하실것 있으시면 dingpong@hanmail.net 로 메일주세요^-^. * VC++ API DirectX 2D library & Engine - 2 - Lib 파일 만들기 안녕하세요^^ 2번째 입니다 오늘은 약속했던데로..lib 파일을 만들어서 써보도록 하겠습니다^-^ lib 파일은 어떻게 만드느냐?. 흠..우선 dxutil.cpp 와 dxutil.h 파일을 준비합시다 직접 내용을 작성해도 좋겠지만^^ 그건 다음에 엔진 내용에 들어갈 부분을 설명하면서 하도록 합시다^-^ 강좌에 그림을 껴넣을려고 했는데;.그게 힘들더라고요 sdk 방에 Common 이란방에 있군요^-^ 우선 vc++ 을 켠후에 new 를 눌러 프로젝트를 시작합시다 거기서 맨 밑에 Win32 static library 라고 있는데 그걸로 하시면 됩니다. 다른 옵션없이 그냥 넘기시면 되고요 자 그럼 FileView 를 보시면 소스파일이랑 헤더파일 부분이 있을껍니다 거기다가 소스파일 부분에는 dxutil.cpp 를 추가 하시고 헤더파일부분에는 dxutil.h 를 추가한다음에 f5 로 실행하는게 아니라~! f7로 하셔야합니다 dxutil.h 가 같은방에 있지않을때 에러가 나니 조심하세요^-^ 자 그럼 lib 파일이 있을껍니다. 디버깅방에 가보면. ^-^;..그럼 lib 파일이 완성된겁니다 이제 이것을 이용해야겠죠? 자기가 작업하고있는 방에 lib 란 디렉토리와 include 란 디렉토리를 만듭니다 lib 디렉토리에는 지금 만든 lib 파일을 넣으시면 되고요 include 라는 폴더에는 dxutil.h 파일을 넣으세요^-^ 그다음에 . 메뉴 - Tools - Options 에 탭바에 보면 - Directories 라는거에가봅시다 먼저 include files 라고 되어있을껍니다.. 콤보박스에요 밑에 에디터 박스가 있을땐데 빈공간 에다가 더블클릭하면 왼쪽에 ... 되있는 커맨드 박스를 눌러서 경로지정을 해줍니다 include 파일이니까 우리가만든 include 폴더를 추가시켜주고 include files 라도 써져있는 콤보박스를 드롭다운시켜 Library filas 에 가서 같은 방법으로 lib 폴더를 추가 시켜줍니다. p.s 이미지 참고 바랍니다. 자 그럼 됬습니다. * 주위 : lib 파일을 만들고 지금 하는건 win 32 어플리케이션으로만든 일반적인 프로젝트에 적용하는것을 말합니다^^. 이제 마지막으로 메뉴 - Project - Settings - Link 탭에 가보시면 여러가지가있는데 그중에 Option/library modules : 라고써져있는 밑에 박스에다가 앞이나 뒤에다가 자신이 만들었던 lib 파일 이름을 써줍니다 만약 dxutil.lib 였다면 그렇게 추가해줍니다 다른방법으로는 코딩상에 #pragma comment(lib, "dxutil.lib") 이런식으로 써주면 위에것과 마찬가지로 추가하는것과 같은역활을 해줍니다. 나중에 lib 들이 많아지면 어떤 라이브러리를 추가시켰는지 모르겠다면 저렇게 코딩상으로 써주는게 훨씬 알아보긴 좋겠죠^-^; 이렇게 추가를 했으면 dxutil.cpp 와 dxutil.h 가 추가되있지않아도 추가되있는것이니. 그냥 있는것처럼 하시고 쓰시면 됩니다^-^. 그럼 이번강좌는 이만 쓰겠습니다 질문은 메일로 보내주세요^-^.감사합니다. * VC++ API DirectX 2D library & Engine - 3 - 2d Engine 그래픽 라이브러리 설계 - 1 - 3번째 시간입니다^-^ 자 이제..실제로 제작하는것만 남았네요>_< 좀 빨리 진행하는 듯한 느낌이 있네요.. 궁금하신건 질문 하시래두^-^;..아무도 않하시네요 저는 여러분이 제작하실수있도록 처음에 방향만 잡아주는 역활을 하고자 합니다.-. 음..서론은 짧게 해두고요..본론으로 들어가서... 그래픽 라이브러리를 제작해보도록 합시당^-^ ddraw 가 directx 의 70,80% 를 차지하고있는것과 마찬가지로 그래픽엔진이 엔진중에 가장 어렵기도하고 시간이 많이걸리는 부분이기도 합니다. 실제로 화면에 나타내어 주는부분이니까요^^ 저는 ddutil 에 있는 함수들을 제 그래픽엔진 안에 넣어버렸습니다; 왜냐하면?.실력이 않되니까요^-^;.하핫..자체 압축 스프라이트연구를 하다가 그만두고(..).여러가지 하다보니까 ^-^;.시간이없어서 일단 이렇게 해두고 썻는데 그게 계속 이렇게 됬네요.. 2d 그래픽 엔진.cpp 와 h를 제작한후에..흠 일단 헤더파일 부분을 설명드리겠습니다 #ifndef __2D_ENGINE_H__ #define __2D_ENGINE_H__ #define WIN32_LEAN_AND_MEAN #define NODEFAULTLIB #include #include //directdraw #include #include //dirextinput #include #include #include #include #include #include //directshow #include #include #include "InputEngine.h" //인풋라이브러리 #include "ShowEngine.h" //쇼라이브러리 #include "File.h" //파일라이브러리 #include "MusicEngine.h" //뮤직라이브러리 #include "ase.h" #include ////////////////////////////////////////////////////////////////// // DEFINE //////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// #define SCREEN_WIDTH 640 // size of screen #define SCREEN_HEIGHT 480 #define SCREEN_BPP 16 // bits per pixel #define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } #define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } } #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } ////////////////////////////////////////////////////////////////// // 전역 변수, 만든날짜 2001.11.13 // 수정한 날짜 2001.11.28 // 추가 //static int g_bpp; //static LONG g_screenWidth; //static LONG g_screenHeight; ////////////////////////////////////////////////////////////////// extern LPDIRECTDRAW7 lpDD; extern LPDIRECTDRAWSURFACE7 lpDDSF; //앞면 extern LPDIRECTDRAWSURFACE7 lpDDBF; //뒷면 extern LPDIRECTDRAWSURFACE7 lpDDOF; //오프스크린 extern LPDIRECTDRAWSURFACE7 lpDDOFMAP; extern LPDIRECTDRAWCLIPPER lpddclipper; // dd clipper static int g_bpp; static LONG g_screenWidth; static LONG g_screenHeight; #pragma comment(lib, "ddraw.lib") #pragma comment(lib, "winmm.lib") ////////////////////////////////////////////////////////////////// // 이미지 구조체, 만든날짜 2001.11.13 // 수정한 날짜 2001.11.28 // ---------------------------------------------------------------- // <구조체 설명> // 이미지를 로드하고 찍을때 필요한 구조체이다. // ---------------------------------------------------------------- // // <수정내용> // 1. 20일 startx 와 starty 를 추가하였다. 이것은 이미지가 로드된곳의 // RECT 의 처음 시작값이다. RIGHT 와 BOTTOM 값은 이미지의 넓이와 // 높이를 더한값으로 설정하였다 // 2. 칼라키 값을 넣음 // 3. MAX 값을 넣고 이미지 로드 함수를 좀더 간단하게 만들고 // 버퍼 셋팅함수에 매개변수를 좀더 넣었다. ////////////////////////////////////////////////////////////////// typedef struct { LPDIRECTDRAWSURFACE7 *buf; // 그림 이미지가 담겨진 메모리 int width; // 이미지 폭 int height; // 이미지 높이 int startx; // rect 시작값 x int starty; // rect 시작값 y int Maxx; // 이미지전체 x int Maxy; // 이미지전체 y COLORREF rgb; // 칼라키값 } IMG_BUFFER; ////////////////////////////////////////////////////////////////// // 함수 원형(Prototype) 선언 ///////////////////////////////////// ////////////////////////////////////////////////////////////////// class Engine { public: IDirectDrawSurface7* DDLoadBitmap(IDirectDraw7 *pdd, LPCTSTR szBitmap, int dx, int dy ); HRESULT DDReLoadBitmap(IDirectDrawSurface7 * pdds, LPCSTR szBitmap); IDirectDrawPalette* DDLoadPalette(IDirectDraw7 * pdd, LPCSTR szBitmap); HRESULT LoadImages(IMG_BUFFER *img, char *file_name); bool PutClippingImage(int x, int y, IMG_BUFFER *img); bool PutImage(int x, int y, IMG_BUFFER *img); bool CreateSurface(IMG_BUFFER *img); bool PutColorKeyImage(int x, int y, IMG_BUFFER *img); bool PutClippingColorKeyImage(int x, int y, IMG_BUFFER *img); HRESULT DDSetColorKey(IDirectDrawSurface7 * pdds, COLORREF rgb); HRESULT Clear_Surface(IDirectDrawSurface7 * pdds); void IMG_BUFFERSetting(IMG_BUFFER *IMG_Name, LPDIRECTDRAWSURFACE7 *Buffer, int Width, int Height, int StartX, int StartY, int MaxX, int MaxY, COLORREF rgb); void PutText(int x, int y, COLORREF rgb, char *str, ...); HRESULT CreateFullMode(HWND hWnd, DWORD width, DWORD height, DWORD bpp); HRESULT Present(); Engine() {}; ~Engine() {}; private: DWORD DDColorMatch(IDirectDrawSurface7 *pdds, COLORREF rgb); bool SetBpp(void); HRESULT DDCopyBitmap(IDirectDrawSurface7 *pdds, HBITMAP hbm, int x, int y, int dx, int dy); }; #endif 이것이 풀소스 입니다. 흠..별건없구....클레스를 이용했고요...재활용성을 위해서 이 헤더파일만 main 에서 include 시키면 다 되게 만들어놨습니다^^ 다른엔진과도 연결되게~ 저 위에 주석을 잘 봐주세요 ////////////////////////////////////////////////////////////////// // 이미지 구조체, 만든날짜 2001.11.13 // 수정한 날짜 2001.11.28 // ---------------------------------------------------------------- 라고 되어있는...흠..엔진에서는 주석이 참 중요하답니다 여러분은 프로그램을 짜시면 1달뒤나 2달뒤에 보시면 그것을 완전히 해석할수있으신지 궁금하세요^-^ 엔진은 두고두고 써야하기때문입니다. 1년이든 2년이든 그냥 lib 파일로 만들어 두고 쓰는게 아니라 cpp 와 h 파일도 보관해서 바꿔가면서 써야하기때문에 이게 언제만든것인지 어떤내용을 수정했고 어떤기능을 갖고있으며 수정해야할점은 무엇이고 어떻게 사용해야하며 단점은 무엇이고 장점은 무엇인지...등..쓸수있는한 쓰시는게 좋죠^-^;.모든 함수마다 마찬가지 라고생각합니다..사람마다 의견의 차이가 있을수있지만 주석많이달아야 한다는게 않좋다는사람은 못봤네요^-^; 주석밑에 있는 IMG_BUFFER 이 구조체는 제가 임의로 만든구조체 입니다. 이 구조체를 셋팅함으로써 인자에 이구조체만 넣으면 그림이 화면에 출력될수있도록 했어요. int width; // 이미지넓이 int height; // 이미지 높이 int startx; // rect 시작값 x int starty; // rect 시작값 y int Maxx; // 이미지전체 x int Maxy; // 이미지전체 y COLORREF rgb; // 칼라키값 이미지 넓이, 높이란 찍을 이미지의 높이 넓이 입니다. 밑에 이미지전체,x,y 랑 헤깔리실수가있는데, 그림이 하나있어도 절반만 찍고싶을때가 있고 만약 1024*768 짜리 그림이 있는데 640*480 모드면 이미지넓이 높이에는 640*480 을써주시면 되는것입니다.^-^.이해가 가셨는지. rect 의 시작값이 란것은 찍을 그림이 어디있느냐죠. 그러니까 이미지넓이,높이 * rect의 시작값으로 해서 찍어주는겁니다. 왜 rect의 시작값이 들어갔냐하면 애니메이션같은것을 해줄때 rect의 시작값만 바꿔주면 되는것입니다 만약 64*64그림에 1024*64 짜리 애니메이션그림이 있다고하면 이미지넓이에는 64*64 rect의 시작값x는 64*i 뭐 이런식으로 해주면 애니메이션이 되겠죠. 찍는 시작값만 계속 바뀌니까요^-^. 이미지 전체값은 말그대로 이미지 전체 x,y 값을 넣어주시면 되고 칼라키값까지 아예 넣어버렸습니다. 칼라키값을 설정않할 그림이라면 RGB(0,0,0) 이라고 셋팅해주시면 됩니다^-^. IDirectDrawSurface7* DDLoadBitmap(IDirectDraw7 *pdd, LPCTSTR szBitmap, int dx, int dy ); HRESULT DDReLoadBitmap(IDirectDrawSurface7 * pdds, LPCSTR szBitmap); IDirectDrawPalette* DDLoadPalette(IDirectDraw7 * pdd, LPCSTR szBitmap); HRESULT DDSetColorKey(IDirectDrawSurface7 * pdds, COLORREF rgb); 이정도가 ddutil 에서 뽑아온 함수네요^-^.무슨기능을 하고있는진 여러분께서 아실꺼라고 생각합니다^-^. bool PutClippingImage(int x, int y, IMG_BUFFER *img); bool PutImage(int x, int y, IMG_BUFFER *img); bool PutColorKeyImage(int x, int y, IMG_BUFFER *img); bool PutClippingColorKeyImage(int x, int y, IMG_BUFFER *img); 이 4개의 함수가 그림을 찍어주는 함수입니다 화면상의 찍어줄 x,y 값과 img 버퍼값만 넣어주면 되죠 이 4개를 만들어둔이유는 클리핑을 할지않할지, 칼라키를 적용시켜야하는 그림인지 아닌지에 따라 4개를 나눴습니다.이해 가시죠?.^-^ void IMG_BUFFERSetting(IMG_BUFFER *IMG_Name, LPDIRECTDRAWSURFACE7 *Buffer, int Width, int Height, int StartX, int StartY, int MaxX, int MaxY, COLORREF rgb); 이함수가 img 버퍼 셋팅을 위한 함수입니다. 인자를 보면 아실꺼라고 생각합니다. 위에 img 버퍼 구조체 설명드릴때 순서대로 인자가 들어있습니다^-^ HRESULT LoadImages(IMG_BUFFER *img, char *file_name); 이함수를 씀으로써 이미지 파일을 로드 합니다^-^ 역시 img 버퍼 구조체 값이랑 파일이름이 팔요합니다 흐음.이로써 h 파일은 설명 다드린것같네요^-^; 엔진은 자신이 설계하기 마련입니다. 제것을 보시고 이해를 하신다면 여러분께서 직접 제작하실수있으실 꺼라고 생각합니다 제 소스파일을 올리고 분석을 하니 이상한 부분이 많네요- 재활용성을 잘 생각하시고 여러분께서 설계해 보세요! 우리 게임에는 어떤 함수가 필요하고 뭐 광원효과가 번쩍번쩍 나야하고 알파플랜딩이 자유자제로 되야하구 그런것들이요^-^ 지금부터 연습장에 정리해두시고 차차 고쳐 나간다면 좋아질꺼라고 생각합니다^^ 고수분들께서는 보시고 막 뭐라고 하실것같은.ㅠ_ㅠ 이만 허접 프로그래머 인균이는 물러나겠습니다^-^. * VC++ API DirectX 2D library & Engine - 4 - 2d Engine 그래픽 라이브러리 설계 - 2 - 안녕하세요^^ 4번째 강좌입니다.. 흠...저번시간에는 2d 그래픽 h 파일에 대해 알아봤으니 이번시간에는 cpp 파일에 대한걸 알아봅시다 cpp 파일에는 어떤내용이 들어갔는지 하나씩 설명해 드리겠습니다^^ 중요한 부분만 설명드리고요^-^..전체 소스를 올려드리겠습니다. #include "2DEngine.h" // 전역변수 LPDIRECTDRAW7 lpDD = NULL; LPDIRECTDRAWSURFACE7 lpDDSF = NULL; //앞면 LPDIRECTDRAWSURFACE7 lpDDBF = NULL; //뒷면 LPDIRECTDRAWSURFACE7 lpDDOF = NULL; //오프스크린 여기서는 DDraw 를 설정할때 반드시 있어야할 서페이스와 DRAW 객체입니다. 다른 오프스크린..유동적인것은 필요에 따라서 Main 에다가 쓰시면 될것이고 여기서 선언해놓은건 꼭필요한것입니다 하지만 lpDDOF 가 꼭필요한건 아니고^-^..오프스크린을 하나 여유있게생성해둔것입니다. extern Engine Eng; 상속이라고하나...잘은 모르겠습니다^-^ 전 예전에 이런고민을 했습니다. 프로그래밍 짜다보니까 main.cpp 와 main.h 파일에만 소스가 있는것이었습니다. 즉 cpp 를 분할해서 프로그래밍을 하는방법을 몰랐죠..클레스 개념도 잘못랐을때요^^ 그때 클래스는 알게되었고..저 소스는 이 cpp 와 저 cpp 를연결해서 이 cpp 에있는 클래스 함수와 변수를 이용할수있게해주는것입니다^^; 이해가 잘 않가시는분들은 꼭 말씀해 주시길 바랍니다>_< Engine Eng; 메인.cpp 에는 include 밑에 이렇게 써주시고 함수안에다가 Eng. 하시면 구조체처럼 class 에 등록되어있는 함수랑 변수들이 보일것입니다^-^..그렇게 사용하시면 됩니다. ///////////////////////////////////////////////////////////////////// /////////////////////// 16bit 칼라제어 /////////////////////////////// ///////////////////////////////////////////////////////////////////// bool Engine::SetBpp(void) 16bit 칼라제어란건 그냥 제가 붙인 주석이고요.. 16bit 2d 엔진이기때문에 그래픽카드에따라서 5,6,5 모드가 될수있고 5,5,5모드가 될수있는데 그건 설명하자면 길기때문에 모르시는분들은 16bit 강좌부터 보시길바랍니다^-^ ///////////////////////////////////////////////////////////////////// /////////////////////// 글자를 찍어줌 /////////////////////////////// ///////////////////////////////////////////////////////////////////// void Engine::PutText(int x, int y, COLORREF rgb, char *str, ...) 말그대로 글자를 찍어주는함수입니다. 매개변수는 찍어주는 x,y 좌표 그다음에 rgb값(RGB(0,0,0)이렇게..)그다음에 출력할 문자를넣어주면 됩니다 //////////////////////////////////////////////////////////////////////// //////////////// 다이렉트 드로우를 초기화하고 만듬 ///////////////////// //////////////////////////////////////////////////////////////////////// HRESULT Engine::CreateFullMode(HWND hWnd, DWORD width, DWORD height, DWORD bpp) 주석에 써있는그대로입니다.^^ WinMain 함수안에서 쓰이죠. 전 WinInit 함수를 먼저 불러왔습니다. 윈도우클레스 등록하고 만들고..그런기능을 하죠 그다음에 Eng.CreateFullMode(hWnd, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_BPP)) 이런식으로 불러온다면 되겠죠^-^ /////////////////////////////////////////////////////////////////////// /////////////////////////// Flip 함수 ///////////////////////////////// /////////////////////////////////////////////////////////////////////// HRESULT Engine::Present() 말그대로 Flip 함수입니다^^ ////////////////////////////////////////////////////////////////////////// ///////////////////// DDUtil 함수..이미지를 불러온다 ///////////////////// ////////////////////////////////////////////////////////////////////////// IDirectDrawSurface7* Engine::DDLoadBitmap(IDirectDraw7 * pdd, LPCSTR szBitmap, int dx, int dy) ////////////////////////////////////////////////////////////////////////// ///////////////////// DDUtil 함수..이미지를 다시 불러온다 //////////////// ////////////////////////////////////////////////////////////////////////// HRESULT Engine::DDReLoadBitmap(IDirectDrawSurface7 * pdds, LPCSTR szBitmap) ////////////////////////////////////////////////////////////////////////// ///////////////////// DDUtil 함수..이미지를 카피한다 ///////////////////// ////////////////////////////////////////////////////////////////////////// HRESULT Engine::DDCopyBitmap(IDirectDrawSurface7 * pdds, HBITMAP hbm, int x, int y, int dx, int dy) ////////////////////////////////////////////////////////////////////////// ///////////////////// DDUtil 함수..팔래트를 만든다.. ///////////////////// ////////////////////////////////////////////////////////////////////////// IDirectDrawPalette* Engine::DDLoadPalette(IDirectDraw7 * pdd, LPCSTR szBitmap) {////////////////////////////////////////////////////////////////////////// ///////////////////// DDUtil 함수. /////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// DWORD Engine::DDColorMatch(IDirectDrawSurface7 * pdds, COLORREF rgb) { 모두 아실꺼라고 생각됩니다^-^.주석에 써있죠~ ////////////////////////////////////////////////////////////////////////// ///////////////////// Surface 만 생성해주는 함수 ///////////////////////// // 주위사항 : // 제작일 : 11월 22일 // 수정일 : 00월 00일 // 수정내용 : // 문제점 : 아직 완벽한지 모르겠음, 최적화 않시킴 /////////////////////////////////////////////////////////////////////////// bool Engine::CreateSurface(IMG_BUFFER *img) { 주석에써있는그대로입니다. surface 를 생성하되 그 surface 에 그림을 불러오진않습니다. 이런 함수는 어느때 쓰이냐 하면... 임시버퍼가 될수있고^^..백서페이스처럼... 알파블랜딩같은 효과를 이서페이스에 해줄수도있습니다^-^ /////////////////////////////////////////////////////////////////////////// ///////////////////// 이미지 로드 함수 //////////////////////////////////// // 주위사항 : ddutil 이 필요함 DDLoadBitmap 함수를 쓰기위함 // 제작일 : 11월 21일 // 수정일 : 11월 27일 // 수정내용 : 칼라키값을 여기서 설정할수있음. 칼라키값이없게하려면 // RGB(0,0,0) 으로 설정함 // 문제점 : 아직 완벽한지 모르겠음, 최적화 않시킴 /////////////////////////////////////////////////////////////////////////// HRESULT Engine::LoadImages(IMG_BUFFER *img, char *file_name) { 이미지 로드 함수입니다. 전 강좌시간에 설명드린것이전부입니다^-^ img_buffer 만 알면 별로 다른건없을것입니다. /////////////////////////////////////////////////////////////////////////// //////////////// 이미지 출력 함수(클리핑 않됨, 칼라키 않됨) ///////////////// // 주위사항 : Img 변수를 우선 셋팅 해줘야함 // 제작일 : 11월 21일 // 수정일 : 00월 00일 // 수정내용 : // 문제점 : 불완전함, 최적화 않시킴 /////////////////////////////////////////////////////////////////////////// bool Engine::PutImage(int x, int y, IMG_BUFFER *img) { bool Engine::PutClippingImage(int x, int y, IMG_BUFFER *img) { bool Engine::PutColorKeyImage(int x, int y, IMG_BUFFER *img) { bool Engine::PutClippingColorKeyImage(int x, int y, IMG_BUFFER *img) { 이것도 전시간에 설명드렸을겁니다^^ /////////////////////////////////////////////////////////////////////////// /////////// IMG_BUFFER 구조체 변수를 초기화해준다. //////////////////////// // 주위사항 : IMG_BUFFER 구조체가 필요. 매개변수 잘볼것 // 제작일 : 11월 20일 // 수정일 : 00월 00일 // 수정내용 : // 문제점 : IMG_BUFFER 구조체 에만 사용할수있다는것이 단점 // 매개변수로 받은 것으로 구조체를 어떻게 생성할수있을까?. // 그렇게 된다면 범용적으로 사용할수있을텐데... // 사용법 : 인자 : imgbuffer, 서페이스, 이미지하나당rect, 출발, 최대 /////////////////////////////////////////////////////////////////////////// void Engine::IMG_BUFFERSetting(IMG_BUFFER *IMG_Name, LPDIRECTDRAWSURFACE7 *Buffer, int Width, int Height, int StartX, int StartY, int MaxX, int MaxY, COLORREF rgb) { IMG_Name->buf = Buffer; IMG_Name->width = Width; IMG_Name->height = Height; IMG_Name->startx = StartX; IMG_Name->starty = StartY; IMG_Name->Maxx = MaxX; IMG_Name->Maxy = MaxY; IMG_Name->rgb = rgb; // 칼라키값 } 음...소스까지 보자면 별거없죠? 그냥 넣어주는것입니다.; 전 img_buffer 인자값대신에 char 값을넘겨와서 그 char 값으로 img_buffer 로 자동생성해주도록 만들고 싶었는데 템플릿을 이용해야한다고해서요^-^ img_buffer 은 main 에서 미리 설정해야곘죠?.오프스크린하나마다 img_buffer하나 /////////////////////////////////////////////////////////////////////////// //////// 칼라키를 찍어주는 함수를 사용하기위해 칼라키를 지정해준다///////// // 주위사항 : 칼라키를 적용해서 찍어주기전에 이 함수를 사용할것 // 제작일 : 11월 21일 // 수정일 : 00월 00일 // 수정내용 : // 문제점 : DDUtil 에서 따온 함수 /////////////////////////////////////////////////////////////////////////// HRESULT Engine::DDSetColorKey(IDirectDrawSurface7 * pdds, COLORREF rgb) { /////////////////////////////////////////////////////////////////////////// ///////////////// 면을 초기화해준다 까만색으로... ///////////////////////// // 주위사항 : 잘못찍으면 깜빡임이 생길수도있음 // 제작일 : 11월 21일 // 수정일 : 00월 00일 // 수정내용 : // 문제점 : 다른색으로는 아직 지원않됨 /////////////////////////////////////////////////////////////////////////// HRESULT Engine::Clear_Surface(IDirectDrawSurface7 * pdds) { 모두 간단한 함수들입니다 알파블랜딩이나, 페이드인페이드아웃, 반투명, 압축텍스쳐같은 기술은없는^-^.간단한 라이브러리입니다 어떻게..괜찮으셨는지모르곘네요^^ 그럼 안녕히 계세요^-^ * VC++ API DirectX 2D library & Engine - 5 - 그래픽라이브러리를 통해 그림을 찍어보자! 안녕하세요..5번째입니다. 이번시간에는 지금까지 공부했던 그래픽 라이브러리를 실제로 main 에서어떻게 이용하느냐를 설명드리겠습니다. 우선 메인에서 Engine Eng; 이렇게 상속(?)이란걸 받습니다^-^ 전에 설명 드렸을것입니다. 이부분에 대해서는요 LPDIRECTDRAWSURFACE7 lpDDOFCHAR = NULL; //케릭터 오프스크린 하나를 만들어줍니다 IMG_BUFFER Char; img_buffer 도 하나 만들어줍니다. Eng.IMG_BUFFERSetting(&Char, &lpDDOFCHAR, 32, 32, 32, 32, 64, 128, RGB(255,0,255)); //케릭터 img_buffer 를 셋팅하는 함수를 통해 char 이라는 img_buffer 을 셋팅해줍니다. 이부분에 대해서는 h 파일설명 할때 자세히 해드렸을것입니다. 다시 설명드리자면 64 * 128 짜리 그림에서 32*32의 크기로 32*32 되는지점에있는 그림을 그린다. 라는말입니다. 뒤는 칼라키값이고요 Eng.LoadImages(&Char, "char2.bmp"); char 버퍼에다가 char2.bmp 라는 그림파일을 로드합니다 소멸하는 부분에는 if(lpDDOFCHAR) SAFE_RELEASE(lpDDOFCHAR); 이렇게 써주면 됩니다^^ Eng.PutClippingColorKeyImage(CharX,CharY, &Char); //케릭터 찍어주는 루프문에서 이렇게 써주시면 그림이 찍힙니다 클리핑을하면서 칼라키를 넣은 이미지를 찍는 함수죠 CharX 값과 CharY 값으로 찍어줍니다. 이정도면 된것같습니다^-^; 여러분께서 많이 연구해보세요>_< 그럼 이만... * VC++ API DirectX 2D library & Engine - 6 - Input Lib 분석!~ - 1 - 안녕하세요^^ 강좌가 많이 늦어졌습니다 요즘 프로그래밍 공부하느라 시험공부하느라 정신이없어서.ㅠ_ㅠ 여러분의 조언과 충고가 저에겐 큰 힘이 된답니다^-^. 오늘 자료를 찾다 이런자료를 봤어요. 미국이나 해외의 프로그래머들은 4년제 대학은 기본이고 자기 직업(프로그래머) 말고도 다른전공이 있을정도로 교육열이 높다고요 저도 역시 대학을 가기 위해 열심히 공부해야겠다는 생각이;; 머릿말은 이만 줄이고^-^.;...본문으로 들어가보죠 오늘은 Input 에 대해서 알아보도록 합시다 제가 만든 라이브러리의 Input 를 먼저 설명드리겠습니다 제가 구현한건 굉장히 간단합니다. 소스 보시면 알수있으실듯 싶습니다 마우스는 input 에서 제어를 하지않고 키보드만 제어합니다 마우스는 제가 생각하기에 API 가 훨씬 낫더군요;;간편하기도 하고 그건 개인적 취향 , 아니면 실력이겠죠^^; 음..추천책을 말씀드리고 싶네요 민프레스에서 나온 Tricks of the WINDOWS Game Programming Gurus 책을 보신다면 이 강좌를 보실필요없으실듯^-^;..왜냐하면 저도 그책 보고 한것이거든요 다른것도 좋지만 input 부분도 잘 설명되있는듯 합니다. 먼저 헤더파일을 보면서 설명드리겠습니다. #include "2DEngine.h" extern LPDIRECTINPUT lpDIP; //인풋 extern LPDIRECTINPUTDEVICE lpDIPD; //인풋 extern LPDIRECTINPUTDEVICE lpdimouse; // dinput mouse #pragma comment(lib, "dinput.lib") 다 아실꺼라 생각합니다 엇..그런데 마우스 라는 이름의 디바이스 객체가 있네요 제 실수군요!..너그러히 용서해 주시길;.마우스를 구현했다가 남은 찌꺼기같네요^^ 이제 클래스밖에 볼께 없는데..보면 class InputEngine { public: HRESULT InputCreate(HINSTANCE hInstance, HWND hWnd); void KeyInput(); void MouseInput(); bool ESC; //ESC bool LEFT; //왼쪽 화살표 bool RIGHT; //오른쪽 화살표 bool UP; //위쪽 화살표 bool DOWN; //아래쪽 화살표 bool SPACE; //스페이스바 bool LCTRL; //왼쪽콘트롤 bool LALT; //왼쪽알트 중략... int mouse_x, mouse_y; // used to track mouse InputEngine() {Zero();}; ~InputEngine() {}; private: void Zero(); }; InputCreate(HINSTANCE hInstance, HWND hWnd); 이 함수는 인풋 객체를 만드는것이겠죠?^^ KeyInput() 키보드 입력... MouseInput() 마우스 입력(?).크헉;.실수;; 나머지 밑에 bool 형 변수들이 쫙 있을겁니다 이건...키보드 업과 다운을 체크하기위한것이죠; 방법이 여러가지 있겠지만 전 이런 노가다 적인 방법이며 쉬운방법을 선택했습니다;;. 더 좋은방법 있으신분 가르쳐주세요~ 음...이 bool 변수는 키보드의 down, up 를 체크합니다 그부분은 cpp 파일을 보시면 알것입니다^-^ 후..분석해 보니 헤더파일엔 별 내용이 없는것같네요 괜히 쓴걸지도 모른다는 생각이^-^;.하핫 다음강좌때는 input.cpp 파일을 보도록 하죠! 그럼 이만... * 타자 프로그램 만들기 강좌입니다..[VB] 안녕하세요.. 있던걸 지워가지구-_-..다시올립니다..^^;; 어떻게 공부를 할꺼냐 하면은요.. 왕초보자도 함께 따라할수있도록 주석...을 달듯 설명을 할 것입니다^^. 질문은 메일로 보내주세요^^ 잘봐주세요~" p.s 소스는 따로 메일 주시길 바랍니다 dingpong@hanmail.net * 타자 프로그램 만들기 강좌입니다..[로고] 안녕하세요(--) (__).. 먼저 타자프로그램 프로젝트를 열어서 제가 설명해 드리는것과 번갈아 가면서 보시거나 새프로젝트를 열으셔서 따라하셔도 됩니다..그냥 보셔도 상관없구요~ 자아..그럼...제일먼저....로고를 짜야겠죠?.. 처음 실행하면 짜짠..음악과 뜨는-_-;;; 프로젝트에 보시면 맨 아래서 두번째에 있는 폼입니다. 흐음..다른건 없구여..먼저...ctrl + t 를 눌러주세요..그리구..한 3초?..있으시면. 제목표시줄에 구성요소란게 뜨는데요. 한 중간조금위...정도 스크롤바를 내리시다보면 microsoft Multimedia Control 6.0 (SP3) 에 체크박스에 표시를 해주시고~ 또 밑으로 내려서 microsoft Windows Common Controls 6.0 에도 체크를 해주세요 그리구 확인을 꾸욱...눌러주세요^^; 그럼 왼쪽에 도구상자 보시면 몇개의 콘트롤이 생겼을꺼에요. 그중 음악...같이 표시되있는고...그러니까 마우스를 갖다 댔을때 MMControl 이라구 나오는걸 클릭하신다음 폼에 대충 그리세요~..그린것을 선택한다음 이름을 mid1 로 바꿉시다~... 흐음..그리구 타이머를 하나 추가하셔서 interval 을 2500으로 하세요 이 2500이란 값은 2.5초만에 작동하게 하는겁니다 1000이 1초거든요^^; 왜 2.5초만에 작동하게 하냐구요?..실행해 보시면 아시겠지만 로고송(-_-)이 나오는데 2.5초면 딱 끊기 적당하기 때문에입니다^^;..2.5초가 지나면 로고는 사라지구 메뉴가 뜨게 할꺼거든요. 2개를 다 추가하셨으면 폼 아무대나 레이블을 설치합니다..되도록 왼쪽이 좋습니다 속성을 안정해 주면 왼쪽으로 정렬되기 때문이죠..글씨가. 오른쪽에 레이블을 두면 거기다 입력해야 되는데 짤리겠죠? 레이블에 속성을 보시면 autosize 라는게 있을겁니다. 4번째에요.. 그걸 true로 바꿔주세요... 이것은 무슨기능을 하냐하면 말그대로 오토사이트 자동으로 사이즈를 지정해 준다는 겁니다.. 만약 label1.caption 에 "나는 천재다"란 값이 들어가면 label1의 사이트는 나는 천재다 란 글씨가 딱 맞도록 사이즈가 자동적으로 정해진다는 이야기입니다~ 추가 하셨으면 저같이 라인도 넣구...등등..해서 꾸미셔도 괜찮습니다. 속성에 font에서 색깔두 바꿔주셔도 좋구요^^ 이제 코딩한걸 봅시다. Private Sub Form_Load() mid1.FileName = App.Path + "\Start.wav" mid1.Command = "open" mid1.Command = "play" Label1.Caption = "타자 연습" + Chr(13) + Chr(13) + " 프로그램 Ver 1.2" Label2.Caption = "제작 : 최인균" Label3.Caption = "이 프로그램은 공개 프로그램 입니다." End Sub Private Sub Timer1_Timer() Unload muloag mumain.Show End Sub 흠..짧죠? 폼로드..즉 이 폼이 처음 실행될때 처리되는 이벤트입니다.. 먼저 첫번째줄.... Filename 라는건 말그대로 파일이름입니다;... 첫번째 줄이 하는일은 Start.wav 란 wav 음악파일을 찾는거죠....찾는건가-_-; 어째뜬 그런역활을 합니다. app.path 는 경로를 나타내죠 이 프로젝트가 저장되어있는경로 경로에다가 \하구 파일이름.확장자 하니까 된거죠?..무슨말인지 아셨나요? mid1은 MMcontrol 이름이죠?..아까 바꿨잖아요^^; 두번째 command 이게 뭔지는저도 잘;..그러나 명령을 주는기능을 하는 메소드 같습니다..메소드(맞나?)는..책을 찾아보시면 뭐라고 나올것입니다 .뒤에 붙는거죠 다 그런지는 저도-_-;.. "open"즉...Start.wav 파일은 여는 명령어 입니다..이 MMControl에요.. 그다음은 "play" 재생하기 시작합니다~ 네번째줄..그럼 label1.caption 에는 저것이 들어가구.. label2에는 ~~~~가 label3에는 ~~~~~~가 들어갑니당^^;; 보시면 알꺼에요..제 소스를.. Private Sub Timer1_Timer() Unload muloag mumain.Show End Sub 이것을 알아보면 timer1이 실행되면 일어나는 이벤트를 의미합니다 첫먼째줄은 unload 말그대로 unload 시킵니다 muloag 를..말이죠. 이 로고 폼을 unload 시킵니다 unload me 라고 사용할수도 있죠 그 다음에 메인 폼을 show 합니다. 불러오는 거죠^^; 오늘은 이만 마치겠습니다. 내일은 아마..메인메뉴에 대해서 강좌를 하겠습니다. 기대해주세요~ 질문이나 기타 잘못된점이 있다고 생각돼시는 분들은~~ dingpong@hanmail.net 를 이용해 주시길~~" * 타자 프로그램 만들기 강좌 입니다..[메인메뉴] '상' 안녕하세요.^^...세번째 시간입니다~.. 오늘도 신나게 만들어 보자구요(--..).. 하아..그럼 어제 한 로고는 다 만드셨나요?.. 질문이 하나도 않들어와서.... 흐음..다 이해 하셨을까.. ^^;...그런줄 알고 복습은 않하구 그냥 넘어가도록 하겠습니다. 아..오늘은 뭘 만들어볼까요?....전 시간에 예고했듯이.. 메인메뉴를 그럼 만들어 봅시다! 준비를 해야겠죠?^^...준비부터 하시길. 그리고 계속 읽어주세요~ 앞으로 설명할 것들은 설명할께 조금 많기 때문에..강좌 하나로는 설명이 부족할꺼 같아요..그래서 상,중,하 같이 나눠서 진행하도록 하겠습니다 자세히 설명 드리는거라서 어쩔수 없으니..이해해주세요^^; 메인메뉴는....프로젝트 탐색기에서 맨 밑에 있는 폼입니다.~ mumain이라고 되어있죠? 아..딱 뜨자마자..복잡하게 생겼죠?;..그러나 알고보면 대단히 간단하답니다~ 아..이게 왜이렇게 복잡하냐 하면....파일 - 설정 과 연결되었기 때문입니다. 실행해 보시구 메뉴에서 파일로 가셔서 설정을 누르시면 메인메뉴 폼안에 또 사운드 설정이 나오죠?...사운드 설정..이것때문에 이렇게 복잡하게 된것이죠. 설정하는 방법은 여러가지인데..여기서는 이런방법을 쓴다는거죠.^^; 우선..메뉴를 짜봅시다...메뉴는..작업표시줄 밑에..있는거라는거 다 아시죠?^^ Ctrl + e 를 누르셔도 되구 도구창에서 2번째줄에 왼쪽에서 세번째것이 메뉴편집기 입니다..또 메뉴에서 메뉴편집기를 띄우려면 도구 - 메뉴 편집기를 선택하시면 돼겠죠^^;...흐음....이건 어떤 프로그램을 만들던지 거의 꼭 필요한 것이니 마스터 하시는게 좋습니다.~ 여기서는 자주 사용되는 기능들만 설명하도록 하죠~ 아..따라하시는 분들도 계실테구..보면서 하시는 분들도 계실텐데..어떻게 설명해야 좋을지;...일단....보면서 하시는분들 위주로 설명이 가겠습니다;.... 먼저 이 강좌와 소스를 보시며 이해를 하신다음에 않보고 혼자 만들어 보세요^^.. 흐음...본격적으로 들어가죠-_-;; 맨 위에..caption 이란게 있습니다..바로 이름이죠^^;..label 같은곳에도 똑같은 속성이 있죠? 그 밑에 name 는....label 같은곳에도 마찬가지로 name 입니다 나중에 코딩하게 될때 여기 써있는 이름으로 찾아서 코딩하는거죠~ 다른 콘트롤 과도 비슷합니다^^; 그리고...밑에 보시면 화살표 표시가 4개 있을꺼에요..위아래양옆으로..돼있는.. 이게 뭘 의미하냐 하면..하위와 상위의 개념을 나타낸 겁니다. 보시면 알겠지만 맨위에 파일이 있습니다. 그다음에 "..."하구 설정이란게 있는데 이 ... 이 나타내는 건 하위란 것입니다. 그 위에있는 파일이란것의 하위죠....한번씩 만들어서 해보세요~..그럼 그방 이해가 갈꺼에요..위 아래는...위로 옮기구 아래로 옮기구 할때 사용됩니다^^; 이것도 직접 실습해 보시면 금방 이해가 갈꺼에요.. 이렇게 해서...제가 만들어 놓은것같이 만들어보세요^^; name는 자신이 알아볼수 있도록 하시면 더욱 좋습니다~ 다 돼셨나요?...^^ 이젠 폼을 짜보도록 하죠.. 우선 왼쪽 도구 상자에 보시면 사운드라고 적혀있는 뭐라고 할까....그런 모양같이 생긴 콘트롤이 하나 보일것입니다 제어판에서 많이 보이는.. 이름이 TabStrip 라구..그것을 선택하여 적절히 배치하시구 다음에 맨 아래있는 시간 등을 표시할 것은 도구상자에 보시면 StatusBar 이라구 돼어있는 겁니다..비슷하게 생긴거 찾아보세요^^;..배치하시고 또한.."메뉴로"라고 적힌 커맨드 박스를 적절히 하나 배치하시구 그 외에 보이는 데로 한번 배치해 보세요.. 몇개인지 알려드리자면 MMControl 이 9개구...각각 mid2~10까지 줬습니다 네임을요...그리구 타이머가 11개...시간은 1초에 한번씩 작동하게 되어 있는것 같습니당.. 타이머 1만 1250이네요. 프레임 2개랑 라디오버튼 체크박스를 적절히 배치하시기 바랍니다...제가 한것같이요^^; 그외...또 빠진게 있나?...흠...소스보시고 적절히 모두 배치해주세요(죄송--) (__) 하아..오늘은 폼짜는 걸루 마칠께요~ 내일은 코딩을 하죠^^..... 그럼 이만~ * 타자 프로그램 만들기 강좌 입니다..[메인메뉴] '하' 4번째 시간입니다^^.. 오늘은 메인메뉴의 코딩을 알아보죠~ Dim a As Integer Dim cnt As Byte Dim CNT1 As Byte Dim cnt2 As Byte Dim cnt3 As Byte Dim cnt4 As Byte Dim cnt5 As Byte Dim cnt6 As Byte Dim cnt7 As Byte Dim aaa As Byte Dim bbb As Byte Dim ccc As Byte 우선 변수를 선언합니다.. 그 위에 as 뭐뭐뭐 라고 붙는건 영역이라구 해야하나?;;..저도 초보라.. 흐음...그런걸 설정하는겁니다..책에 나와있는곳 많을꺼에요` Private Sub Command1_Click() mid2.Visible = False mid2.Enabled = False mid3.Visible = False mid3.Enabled = False mid4.Visible = False mid4.Enabled = False mid5.Visible = False mid5.Enabled = False mid6.Visible = False mid6.Enabled = False mid7.Visible = False mid7.Enabled = False mid8.Visible = False mid8.Enabled = False mid9.Visible = False mid9.Enabled = False mid10.Visible = False mid10.Enabled = False Picture1.Visible = True Picture1.Enabled = True Command1.Enabled = False Command1.Visible = False TabStrip1.Enabled = False TabStrip1.Visible = False Frame1.Visible = False Frame1.Enabled = False Frame2.Visible = False Frame2.Enabled = False End Sub 커맨드1 을 클릭했을때 일어나는 이벤트....메뉴로 가는 이벤트죠. 뭐..특별한건 보이지 않구..visible 란건...true면 보이구 false 면 않보이게 하는겁니다. enabled 는...활성화입니다..true면 쓸수있는상태구 false면 쓰지 못하게 됩니다. 메뉴로란걸 클릭하면 사운드에 필요한것들은 모두 못쓰게.. 안보이게 해야겠죠..?..그런기능을 합니다^^; Private Sub Form_Load() Timer3.Enabled = True Timer4.Enabled = True Timer2.Enabled = True Timer5.Enabled = True Timer6.Enabled = True Timer7.Enabled = True Timer8.Enabled = True Timer9.Enabled = True mid2.Visible = False mid2.Enabled = False mid3.Visible = False mid3.Enabled = False mid4.Visible = False mid4.Enabled = False mid5.Visible = False mid5.Enabled = False mid6.Visible = False mid6.Enabled = False mid7.Visible = False mid7.Enabled = False mid8.Visible = False mid8.Enabled = False mid9.Visible = False mid9.Enabled = False mid10.Visible = False mid10.Enabled = False Command1.Enabled = False Command1.Visible = False TabStrip1.Enabled = False TabStrip1.Visible = False Frame1.Visible = False Frame1.Enabled = False Frame2.Visible = False Frame2.Enabled = False Timer1.Enabled = False If Option5.Value = True Then Frame1.Enabled = True End If If Option6.Value = True Then Frame1.Enabled = False Option1.Enabled = False Option2.Enabled = False Option3.Enabled = False Option4.Enabled = False Option7.Enabled = False Option8.Enabled = False Option9.Enabled = False Option10.Enabled = False mid2.Command = "close" mid4.Command = "close" mid5.Command = "close" mid6.Command = "close" mid7.Command = "close" mid8.Command = "close" mid9.Command = "close" mid10.Command = "close" End If If Option1.Value = True Then mid2.FileName = App.Path + "\Toheart.mid" mid2.Command = "open" mid2.Command = "play" End If If Option2.Value = True Then mid4.FileName = App.Path + "\31.mid" mid4.Command = "open" mid4.Command = "play" End If If Option3.Value = True Then mid5.FileName = App.Path + "\11.mid" mid5.Command = "open" mid5.Command = "play" End If If Option4.Value = True Then mid6.FileName = App.Path + "\2-02 Ahead on Our Way Midi.mid" mid6.Command = "open" mid6.Command = "play" End If If Option5.Value = True Then Frame1.Enabled = True End If If Option7.Value = True Then mid7.FileName = App.Path + "\12.mid" mid7.Command = "open" mid7.Command = "play" End If If Option8.Value = True Then mid8.FileName = App.Path + "\34.mid" mid8.Command = "open" mid8.Command = "play" End If If Option9.Value = True Then mid9.FileName = App.Path + "\Hero.mid" mid9.Command = "open" mid9.Command = "play" End If If Option10.Value = True Then mid10.FileName = App.Path + "\Yestrday.mid" mid10.Command = "open" mid10.Command = "play" End If mid3.FileName = App.Path + "\End.wav" mid3.Command = "open" End Sub 후..길군요.. 뭐..역시 특별한건 보이지 않는군요.....저번 로고 강좌때..음악파일 재생하는거 설명해 드렸죠?,..밑에껀 그거고요... 위에껀..If Option1.Value = True Then 이부분을 보자면 option1 이 value = true 체크되어 있으면.. 무슨무슨 음악파일이 연주된다..이런뜻입니다^^; 특별한건 보이지 않으니..그냥 넘어갑니다~ Private Sub mu111_Click() Form1.Show End Sub mu111 이란...전 mu111을 이슬비로 정해줬습니다..메뉴 편집기의 네임에서요~ 그래서 메뉴의 이슬비를 클릭하면 이슬비 폼인 form1 이 show 불러오게 했습니다 나머지 것도 다 비슷한거구요..메뉴에서 어떤걸 선택하면 어떤것이 불러와지게~ Private Sub muend_Click() a = MsgBox("종료하시겠습니까?", vbCritical + vbYesNo, "종료") If a = vbYes Then mid2.Command = "close" mid4.Command = "close" mid5.Command = "close" mid6.Command = "close" mid7.Command = "close" mid8.Command = "close" mid9.Command = "close" mid10.Command = "close" mid3.Command = "play" Timer1.Enabled = True Else Exit Sub End If muend는 전 메뉴에서 종료로.... 이것은 그 종료를 누르면 일어나는 이벤트 입니당. vbcritical 이나 vbyesno나..종류가 많습니다.. 하나하나씩 설명드리긴 많기때문에 상당히 곤란합니다 관련 도서를 찾아보시길 바랍니다;....vbcritical 은...실행해 보시면 알겠지만..경고표시힙니다 빨간색...x표시..vbyesno는...예..아니요 가 나오게 하는겁니다` 이해가 가셨나요?. 종료를 누르면....나머지 미디재생기는 다 닫구..미디3만 play합니다.. 미디3은..여기서 실행해 보시면 알껍니다^^;..무슨 효과음인지. Private Sub muhelp1_Click() MsgBox "이 프로그램은 누구나 쉽게 이용할수 있게" + Chr(13) + Chr(13) _ + "만들었습니다.^^ 그래서 도움말은 생략하겠습니다." + Chr(13) + Chr(13) _ + "궁금하신점이 있으시면 메일로 보내주세요." + Chr(13) + Chr(13) _ + "도움주신분 : 모레컴퓨터학원의 김선생님, 그리고 나의 가족들" End Sub 흐음..여기서 chr(13)은 엔터를 나타내는겁니다.. Private Sub Timer2_Timer() If Option1.Value = True Then cnt = cnt + 1 If cnt = 175 Then mid2.Command = "close" mid2.Command = "open" mid2.Command = "play" cnt = 0 End If End If End Sub 많은데 이한가지만 설명드리겠습니다.. 그러니까 option1 이 표시되어있으면 cnt = cnt + 1 가 됩니다. cnt 는 timer2가 실행될때마다 1씩 올라간다는 뜻이죠. 만약 cnt = 175 가 돼면... 미디2 를 닫고 다시 연다음 재생하구 cnt = 0 이 된다. sndplaysound api 를 이용하면 음악파일재생이야..쉽지만.. 여기선 미디콘트롤로 합니다.. 이 미디2에 들어있는 음악파일은 시간이 2분 50초 정도 될것입니다. 2분 40초면....다 재생된다면 cnt = 170이 될것입니다..그럼노래 가 끝나겠죠?...끝나고 나서 가만히 있으면 않돼죠..여기서 중요한건 반복재생입니다. 노래가 끝났어두 계속 타이머가 1초에 한번씩 실행돼다가 175랑 같아지면 다시 처음부터 재생합니다~. 무슨뜻인지 알겠죠?^^; 아아..그외에...별로 중요한거니... 어려운건 보이지 않는군요.. 메일주세요..모르시는거 있으면.. dingpong@hanmail.net...주저하지 마시구요~>. 오늘은 조금 설명이 미흡했더라도 이해해주세요;... 아..지금 너무 졸리네요..좋은밤 되시길.. * 타자 프로그램 만들기 강좌 입니다..[이슬비] '상' 안녕하세요^^.. 오늘도 어김없이..강좌를 올립니다~.. 아..오늘부터 본격적인 타자 프로그램을 짜게 돼겠네요~.. 이제부터 어려워 지니까요..정신 바짝 차리구.... 천천히..이해를 하면서 읽어주세요~ 먼저 제 타자프로그램 프로젝트를 불러오신다음에 form1 파일을 열어보세요 이게 이슬비 게임입니다^^;...자...다르말 생략하구...짜보기나 하죠^^;;; 타이머의 interval 을 100 이하로 둡니다. 여기서 타이머가 하는일이 굉장히 많습니다.. 말하자면.... 내려오는 단어의 중복확인, 단계를 넘어가게 해줌...단어가 라인까지 떨어지면 남은갯수가 1 내려가는기능 등입니다~.. 제가 이걸 만들땐 알고리즘을 몰라서 이렇게 복잡하게 썻는데.... 알고리즘이 생각나시는분은 마음대로 쓰셔도 좋습니다^^....이건... 별로 좋은 알고리즘이 아니거든요;...외우려 하지말구 이해를 해주세요~ 우선 폼에 콘트롤 들을 잘 배치합니다^^..그정도는 할수있으시죠? 그다음에 코딩을 한번 살펴보도록 하죠~..여기서 중요한건 코딩이니까요. Dim 낱말(200), i, 맞춘갯수(10), 점수(10), 이름(10), 순위(10), 난이도(10), cnt, J, 영문(100), 종류(10) 선언을 해줍니다 변수들을...낱말(200)이나 맞춘갯수(10)이라는건 배열을 말하는겁니다..만약 낱말(1) = "xx" 낱말(2) = "yy" label1.caption = 낱말(2) 라고 하면 label1에는 yy가 찍힙니다...무슨뜻인지 알겠죠?... 흐음....또 예를 들자면..낱말(200)에서 200은 교실에서 출석번호마지막을말합니다~ 그래서 1번 누구누구 2번 누구누구 이렇게 지정해 주는거죠^^; 그래서 200명이 한 교실에서 수업을 받는-_-;;..헉..이상한 비유인가요?.. 모르시겠으면 바로 메일주세요^^..... Private Sub Command1_Click() Randomize 커맨드 1을 시작하기 입니다..click는 그러니까 시작하기를 눌렀을때 일어나는 이벤트이겠죠?....시작하기를 눌렀으면 단어가 나와야 합니다. 여기서는 Randomize 라고 되어있는데 보통 Randomize Timer 이라고 씁니다. 제가 잘 모르고 쓴거죠... Randomize 라고 써도 작동돼는것 같긴 합니다만^^; 이건 흐음..뭐라고 설명해야 쉬울까요..그러니까 커맨드 1을 찍을때마다 타이머가 바뀐다는 뜻입니다...그러니까...이걸 않쓰고 쓰면..맨처음 시작할때 나오는 단어가 종료하고 다시 시작하면 그 단어가 또 나오고 또 나오고...맨처음에.. 그런데 이것을 쓰면 시작하기 누를때마다 맨처음에 나오는 단어들이 달라집니다^^; 역시 모르시겠으면 메일을; Label4.Caption = 0 Label5.Caption = 10 label4는 맞춘갯수죠...시작하기 눌렀으니까 초기화 0을...label5는 틀린갯수입니다 초기화값이 10이죠^^;...10개가 밑으로 내려오면 게임이 끝나게 설정해 놨습니다 해보시면 알꺼에요~ 충분히 해보시고 강좌 봐주세요..그래야 이해가 빠르니까요~ For i = 0 To 6 If Command5.Enabled = False Then a = Int(Rnd(1) * 200) Label1(i).Caption = 낱말(a) ElseIf Command6.Enabled = False Then a = Int(Rnd(1) * 100) Label1(i).Caption = 영문(a) Label1(i).Top = 0 End If Next 흐음..조금 어려운게 나왔네요... 처음에 폼을 짤때 label1은 배열로 6개를 만들어 줘야합니다..배열로 만드는 방법은 label1을 복사하기 눌러서 붙여넣기를 하면 배열로 만들꺼냐구 물어보는데 거기서 예 라구 하면 배열이 됩니다. 배열이 돼면..label1(0), label1(1)이렇게 써지게 돼죠^^;...여기서 배열을 쓴 까닭은 그래야 소스코드량과 코딩하기 편하기 때문입니다. 6개의 레이블에서 동시에 단어가 떨어지게 해놨습니다. for i = 0 to 6..i 에 0에서 6까지 한번씩 대입합니다 If Command5.Enabled = False Then 커맨드 5는 한글타자 입니다~..한글타자로 선택되어있지 않으면 이란 뜻이겠죠. 이건... 선택되어있다면 enabled = true 니까요.. a = Int(Rnd(1) * 200) Label1(i).Caption = 낱말(a) a 에는 랜덤으로 1 부터 200가지수중 한가지를 뽑아냅니다. 단어를 골구로 나오게 할 까닭이죠...비유를 하자면 교실에서 수업하는데 선생님께서 200명의 학생중 한 학생에게 책을 읽으라고 시키는거..정도? 0부터 6까지 label1 배열에는 낱말(a)가 들어갑니다. ^^; 낱말(a) 는 랜덤으로 뽑아낸 단어겠죠. 낱말(200)은 배열이구 a 는 랜덤값이니... ElseIf Command6.Enabled = False Then a = Int(Rnd(1) * 100) Label1(i).Caption = 영문(a) elseif 는 또한 만약...무엇무엇 조건입니다...또한 만약 커맨드6은 영어..영어가 선택되어있다면...영어단어는 100개를 넣었기 떄문에 100까지숫자중 하나를 랜덤으 로 뽑아내구 그걸 배열에 대입해 영어단어 6개를 뽑아냅니다..label1(0) ~ (6)까지. Label1(i).Top = 0 End If Next 시작하기를 눌었으니 label1을 맨 위부터 단어가 나오게 해야겠죠 end if 는 위에 if 문을 끝내기 위한 겁니다. end if 를 않써주면 에러가 나게 됩니다 단 elseif 는 end if 를 않써줘도 됩니다. 그러나 elseif만 쓰면 역시 에러가 생기기 됩니다 elseif 는 if 안에 들어가야합니다. next는 for 문을 끝내기 위한겁니다.. Command1.Enabled = False Command2.Enabled = True 시작버튼을 눌렀으면 시작하기는 또 누르지 못하게 하구 중지버튼을 누를수있게합니 다..For i = 0 To 6 Label1(i).Visible = True Next 이건..저위에 써줘도 돼는데..괜히 코드만 늘리게 됐군요.. 어째뜬...label1(0) ~ (6)까지를 보이게 만듭니다..visible 를 false로 하면 보이지 않게 만드는 속성입니다. Timer1.Enabled = True Text1.SetFocus Frame1.Visible = False Frame1.Enabled = False Text2.Visible = False Text2.Enabled = False 타이머를 실행하게 하고. 커서를 text1로 옮깁니다 왜냐하면 시작눌렀으면 바로 쳐야되게 때문에 편하게 하기 위해서라고 할수있죠...사용자 편의;....시작하기 눌렀는데 커서가 다른곳에 있다면 다시 마우스옮겨서 text1로 옮겨야하기 떄문이죠. frame1 그러니까 난이도를 결정하는 프레임을 않보이게, 못쓰게 만듭니다. text2..이름을 못입력하게 만듭니다..이름창이 보이지않게 만듭니다. If Command5.Enabled = True Then If Command6.Enabled = True Then MsgBox "타자 종류를 선택해 주세요." + Chr(13) + Chr(13) _ + "맨 밑에 한글과 영어중 선택해 주세요", vbCritical 한글타자와 영어타자 모두 선택이 돼어있지 않을때 메세지 박스로 출력합니다..타자 종류를 선택해 주세요." + Chr(13) + Chr(13) _ + "맨 밑에 한글과 영어중 선택해 주세요", vbCritical 를....말이죠 chr(13)이나 vbcritical 은 저번 강좌때 설명드렸을것입니다 경고표시가 나오게 하는것이죠..그리고 _ 이것이나 + 는 빼먹으면 않됍니다 제가 chr(13)을 2개넣은 이유는 한칸만 띄면 너무 붙어있어..보기 않좋기 때문이죠^^:.. Frame1.Visible = True Frame1.Enabled = True Command1.Enabled = True Command2.Enabled = False Text2.Visible = True Text2.Enabled = True End If End If Label9.Caption = Text2.Text 한글,영어 모두 선택이 되어있지 않다면 난이도를 보이게 만들고 조정할수있으며 시작버튼을 사용할수있게 만들고 중지버튼을 사용못하게 한다. 이름입력텍스트를 보이게 만들고 쓸수있게 만든다. 그리고 if를 닫아준다..아까 두개를 열었기 때문에 2개를 닫아준다. label9.caption 에는 이름을 복사한다. 흐음..이해가 다 돼셨을까.. Private Sub Command2_Click() Randomize Command1.Enabled = True Command2.Enabled = False Timer1.Enabled = False 중지버튼을 클릭했을때의 이벤트....첫줄은 아까 설명드렸고. 중지버튼을 누르면 또 중지버튼을 못누르게 만들고 시작버튼을 누를수 있게 만든다 중지니까 타이머를 멈추게 한다. For i = 0 To 6 Label1(i).Visible = False a = Int(Rnd(1) * 200) Label1(i).Caption = 낱말(a) a = Int(Rnd(1) * 100) Label1(i).Caption = 영문(a) Label1(i).Top = 0 Next 단어가 않보이게 만들고 다시 랜덤으로 낱말과 영어를 뽑아낸다. Frame1.Visible = True Frame1.Enabled = True Text2.Visible = True Text2.Enabled = True Label6.Visible = True Label6.Enabled = True 중지버튼을 눌렀으니 난이도 조절을 보이게 하고 쓸수있게 만들며 이름입력이 보이게 하구 이름을 입력할수있게 하며.. "이름 :"이란 label을 보이게 만든다. Private Sub Command3_Click() Unload Me End Sub 메뉴로란 커맨드 버튼을 눌렀을때의 이벤트이다. 이슬비 창을 unload 시킨다..즉 종료 시킨다..이슬비 창만.. 그럼 원래 떠있던 메인메뉴의 창만 남게된다. 흐음..오늘은 여기까지 할께요.. 내일 또 이어집니다..많이 기대해 주시고..^^.. 이해하기 어려운 부분이 있으면 dingpong@hanmail.net으로 메일주세요 그럼 이만.. * 타자 프로그램 만들기 강좌 입니다..[이슬비] '중' 안녕하세요; 많이 늦어서 죄송합니다..고등학교 입시때문에 바뻐서요;..요즘 그럼 빨리 시작하죠. 저번 시간과 이어...흠..... 이슬비의 코드에 대해 설명드리겠습니다~ Private Sub Command4_Click() 흐음..여기 있는건..구지 설명드리지 않겠습니다.. 왜냐하면..여기 있는건 정보처리기능사나 할때 쓰는거지. 여기서 쓸만한게 아니기 때문입니다. 임시 방편용으로 그냥 짠것이기 때문에 구지..길게..어렵게 설명보실필요 없다고 생각합니다. 흐음..db 쪽도 나중에 따로 강좌를 올리겠습니다.. 여기 들어갈것을....그것을 봐주세요...... 정보처리기능사실기에서 여기 있는거 거의다 나옵니다. Private Sub Command4_Click() 에 나와있는거요.. Private Sub Command5_Click() 을 알아봅시당.. Randomize Command1.Enabled = True Command2.Enabled = False Randomize 는 저번에 설명 드렸을 것입니다...시작하기 버튼을 사용할수있게 하고.. 중단하기 버튼을 사용 못하게 하구요.. Text1.IMEMode = vbIMEModeHangul '한글 옆에 주석처럼 만약 영어로 키보드가 되어있다면 한글로 바꾸는 것입니다 가끔 시작할때 보면 시작 누르고서 치니까 영어로 나왔을때 있으시겠죠? 그걸 방지하는 겁니다....저도 모르는거라 설명드릴순 없고요.. 저도 따온거랍니다^^;..나중에 알게되면 설명 드리겠습니다..정말 죄송합니다. 그 밑으로..낱말(1) = "" 이렇게 200번 까지 있죠? 흐음.....우선 그 위에 이 소스코드를 붙이세요.. Open App.Path & "\낱말.txt" For Input As #1 Close #1 text 파일을 열어서 input 입력하구 닫아주는겁니다. app.path 는 경로를 나타내구. 그리고 입력한다음 닫아주는 겁니다. 이전에 있던 낱말(1) = "" ~ 200번까지는 잘라내기 하셔서.. 소스가 있는방에 텍스트 파일 하나를 추가하셔서 이름을 낱말로 해주시고 그 안에다 붙여넣기 하시구 저장 해주세요. 그럼 끝납니다...그렇게 간단히 될껄...1~200번까지 여기 쓰면 너무 복잡하겠죠? 제가 잘 몰랐을때 짠거라서; ^^;;...그다음 보죠. For i = 0 To 6 a = Int(Rnd(1) * 200) Label1(i).Caption = 낱말(a) Label1(i).Visible = False Label1(i).Top = 0 Next 전 한글이나 영문을 눌렀을때 label1(0) ~ (6) 까지 단어가 랜덤으로 들어가게 해놨습니다. 저번에 설명드렸으니 보시면 이젠 알겠죠? 0에서 6까지 i 에다 넣는다 한번씩. a 는 1에서 200까지 수중 랜덤으로 하나 구한다 0일때 하나 1일때 하나 6일때까지 하나씩..... 그걸..label(0) 에서 6까지 한번씩 넣구.. 일단 label 들은 보이지 않게한다. 그리구 label은..시작할수있게 높이를 0으로 둔다. 이겁니다^^; Label4.Caption = 0 Label5.Caption = 10 Timer1.Enabled = False Command5.Enabled = False Command6.Enabled = True Label10.Caption = "1단계" 맞춘갯수는 0으로 틀린갯수도 초기화수인 0으로. 타이머는 일단 돌아가지 않게..왜냐하면 한글 누르면 돌아가는게 아니라. 시작 누르면 돌아가게 해야겠죠?...그리고 한글을 눌렀으면 또 한글은 못눌르게 하고 영어는 누를수있게. label10은 단계를 나타내주는 레이블입니다. 1단계 2단계...보시면 알껍니다^^; 눌렀으니 1단계로... 이젠..Private Sub Command6_Click() 을 알아봅시다 영문이란걸 눌렀을때의 이벤트죠^^ Randomize Command1.Enabled = True Command2.Enabled = False 흐음..랜덤하구.. 영어를 눌렀으니 위와 마찬가지로 시작버튼은 누를수 있게...중지버튼은 못누르게 해야겠죠.. Text1.IMEMode = vbIMEModeAlpha '영문 이건 주석과 같이 영문으로 바꾸는것! 설명은 위에 했습니당~ Open App.Path & "\영문.txt" For Input As #1 Close #1 여기서도 낱말 대신 여기있던 영문을 잘라내기 하구 텍스트 영문 으로 만들고 붙여넣기해서 하시면 ^^;..더 좋습니다 Label10.Caption = "1단계" For i = 0 To 6 a = Int(Rnd(1) * 100) Label1(i).Caption = 영문(a) Label1(i).Visible = False Label1(i).Top = 0 Next Label4.Caption = 0 Label5.Caption = 10 Timer1.Enabled = False Command5.Enabled = True Command6.Enabled = False 아까와 같습니다 단 맨밑에는 True 와 false 가 아까 한글이랑 달라졌죠. Private Sub Command7_Click() MsgBox "< 이슬비 도움말 >" + Chr(13) + Chr(13) _ + "이슬비도 제가 자작한 프로그램 입니다." + Chr(13) + Chr(13) _ + "처음에 시작할때 맨 밑에있는 한글과 영문중에서 선택해 주세요." + Chr(13) + Chr(13) _ + "난이도 조절도 해주세요. 그리고 프로그램을 끄면 점수가 지워집니다." + Chr(13) + Chr(13) _ + "점수계산을 포함해 문제가 많군요. 앞으로 계속 버전업할 생각입니다." + Chr(13) + Chr(13) _ + "맞춘갯수에 따라 11단계로 나누어 집니다." + Chr(13) + Chr(13) _ + "즐겁게 하세요..^^" + Chr(13) + Chr(13) End Sub 도움말을 눌렀을때..입니다. chr(13)은 엔터의 효과가^^; 나머지는 msgbox msdn 같은걸 참고하세요~ Private Sub Form_Load() Command1.Enabled = True Command2.Enabled = False Command5.Enabled = True End Sub 폼로드...맨처음에..폼이 뜰때의 이벤트죠. 시작버튼은 누를수있게. 중지버튼은 못누르게. 한글버튼은 누를수 있게 되어있군요. Private Sub Text1_KeyPress(KeyAscii As Integer) 이 이벤트는 가장 핵심이죠. 어떤 키가 입력됐을때 생기는 이벤트를 말합니다. Randomize Label7.Caption = Text1.Text If KeyAscii = 13 Or KeyAscii = 32 Then 랜덤하구.. label7은 확인하는거죠... text1 에 입력돼는거랑 같게 합니다.그래야 확인할수있겠죠 그리고 밑에껀.. 맡약에. 키ascii 가 13 이나 32 이면 이란 거죠..keyascii 13 은 엔터 32면 스페이스 입니다 엔터나 스페이스가 눌러졌을때 일어나는 이벤트를 밑에 코딩하게 되죠 For i = 0 To 6 If Label1(i).Caption = Trim(Text1.Text) Then Label4.Caption = Label4.Caption + 1 Label1(i).Top = 0 0부터 6까지 대입하구 처음엔 i 에 0이 들어오겠죠. label1(0)의 이름이 = text1.text 와 같으면 trim 은 잘 모르겠네요-_- 죄송합니다..월요일날 알아서 올리죠..죄송-_-;; 흐음..text1.text 는 입력한거니까 맞으면 그와 똑같은 위에서 내려오는 단어가 없어져야겠죠? 맞은 갯수는 +1 씩돼고 맞으면 다시 맨위에서부터 시작해야겠죠? 그런겁니다~ If Command5.Enabled = False Then a = Int(Rnd(1) * 200) Label1(i).Caption = 낱말(a) If Label1(i).Caption = "" Then a = Int(Rnd(1) * 200) Label1(i).Caption = 낱말(a) End If ElseIf Command6.Enabled = False Then a = Int(Rnd(1) * 100) Label1(i).Caption = 영문(a) End If 만약에 한글버튼이 눌러져 있스면.. a 는 레이블에다 랜덤으로 낱말을 넣고 레이블 캡션이 없다면 다시 넣구. 영어가 눌러져 있다면. 영어를 넣게 됩니당. 무슨말인지 아시겠죠? 사정이 있어서 오늘은 이것밖에 못쓰겠네요.. 그럼 안녕히 계세요~ * 타자 프로그램 만들기 강좌 입니다..[이슬비] '하' 안녕하세요~...오늘은 끝까지 해야하니 갈 길이 급하군요..헥헥.. Next Text1.Text = "" Text1.SetFocus 맞거나 틀리거나...전에 썻던 단어는 지워져야겠죠? 그래야 다음에 단어를 쓸수있으니까 그다음에 만약을 대비해서 마우스 포인터가 text1로 가게 해놨습니다. 그래야 칠수있으니까요^^; If Command5.Enabled = False Then If Label4.Caption = 30 Then Timer1.Enabled = False 만약에 한글커맨드 버튼이 눌러져 있고 만약에 label4 즉..맞은갯수가 30과 같다면.. timer1은 멈춘다...왜냐하면 메세지 박스가 출력 됐을땐.. 칠수없게..만든다...쉬는사람도 있다...단계가 넘어갈때마다.. 이것은 단계를 넘어가게 하는 이벤트의 코딩입니다 MsgBox "2단계" Label10.Caption = "2단계" For i = 0 To 6 a = Int(Rnd(1) * 200) Label1(i).Caption = 낱말(a) Label1(i).Top = 0 Next Timer1.Enabled = True 차례로....메세지 박스에는 2단계라는 걸 표시하게 하구 단계를 표시해 주는 label10에도 2단계로... 아까 위에 한글을 눌렀을때니까....2단계로 넘어가면 다시 새로운 단어가 맨위에서부터 시작돼게 한다.. for 문을 next로 끝내주고 타이머를 다시 시작하게 합니다. 즉 이 이벤트는 30개를 맞추면 2단계로 넘어가게 하는것이죠 밑에것도 맞춘 갯수만 달라지고 3,4,5,6,......으로 넘어가게 하는 코딩이구 다 같은 원리이죠^^;. If Command6.Enabled = False Then If Label4.Caption = 30 Then Timer1.Enabled = False 흐음..만약 영어를 눌렀고... 맞춘갯수가 30이라면... 위와같고..단 영어가 틀릴 뿐이죠.. 낱말 대신 영어를 넣고... 똑같죠^^;......이해가가시죠? 쭉내려와서..end if 로 닫아주고.. Private Sub Timer1_Timer() Randomize Timer1.Enabled = True 또 핵심부분인 타이머에 있는 코딩에 대해 알아보죠~ 랜덤으로 하고..... 세번째 줄은 필요없네요-_-; 흠..먼저 단계에 따라 내려오는 속도가 다르게 하는 코딩을 알아보겠습니다~ 초급자 중급자 상급자 다 따로해야하니 더 복잡해 졌군요. For i = 0 To 6 Label1(i).Visible = True If Option1 = True Then If Label10.Caption = "1단계" Then Label1(i).Top = Label1(i).Top + Int(Rnd(5) * 25) 타이머가 실행됐으면 레이블을 모두 보이게 해주고 만약 option1 은 상급자죠 상급자가 표시되어있으면 즉 상급자로 타자연습을 하고 있을때 label10..이 1단계로 있으면 레이블의 높이는 rnd 랜덤으로 5 에서 25정도로 떨어진다. 즉 5에서 25중의 숫자를 골라서 점점 밑으로 내려오게돼죠. 무슨말인지 아시죠?.. ElseIf Label10.Caption = "2단계" Then Label1(i).Top = Label1(i).Top + Int(Rnd(10) * 30) 이런것도 다 똑같습니다. 2단계만 10에서 30중의 숫자로 떨어진다.....숫자가 좀 높아졌죠? 속도가 빨라진다는 얘기입니다. 그럼 밑에것도 다 아시리라 믿고 넘어갑니다..모르시면 메일 ^^.. ElseIf Option2 = True Then If Label10.Caption = "1단계" Then 이건 중급자를 눌렀을때.. ElseIf Option3 = True Then If Label10.Caption = "1단계" Then 이건 초급자겠죠^^; For i = 0 To 6 If Label1(i).Top > 5880 Then Label5.Caption = Label5.Caption - 1 Label1(i).Top = 0 다시 for 문 돌려서.. 이번엔 단어가 밑에 라인까지 떨어지면 틀린갯수가 하나씩 줄어드는 이벤트 입니다...label1.top 가 5880 보다 커지면. 틀린갯수는 -1 이 되고 그 레이블은 다시 맨위로 올라간다 폼에 크기게 따라 전 5880이지만 다르게 하셔도 상관없습니다^^; If Command5.Enabled = False Then a = Int(Rnd(1) * 200) Label1(i).Caption = 낱말(a) 떨어진 레이블에 다시 단어를 넣어줘야겠죠? 다시 단어를 넣는 겁니다` ElseIf Command6.Enabled = False Then a = Int(Rnd(1) * 100) Label1(i).Caption = 영문(a) 흐음....한글 눌렀을땐 한글을 넣어줘야되고 영문일땐 영어를 넣어주는것만 다르겠죠~.. ElseIf Label5.Caption = 0 Then Command1.Enabled = True Command2.Enabled = False Timer1.Enabled = False Label1(i).Visible = False MsgBox "Game over" Exit Sub ElseIf Label5.Caption < 0 Then Label5.Caption = 0 End If Next 한꺼번에 설명드리죠 만약 틀린갯수가 0이되면. 시작하기는 누를수 있게 되고 중단하기는 누를수 없게된다..왜냐하면 다시 시작할수도 있기때문에.. 타이머를 돌아가지 않게 하고. 단어가 들어있는 레이블도 보이지 않게한다. 메세지박스에는 게임 오버..즉 게임이 종료됐다는걸 알리기 위한 메세지 가 뜨게한다. 만약 틀린갯수가 0보다 작아지면 틀린갯수는 0이된다..왜냐하면. 어쩌다 틀린갯수가 1개 남은 상태에서 단어 2개가 같이 라인을 넘어가면 틀린갯수가 -1 이 돼기때문이다 써주면 좋고 않써주면 그만인; for 문 닫아주고. 그 다음은 단어의 중복확인 입니다. 한꺼번에 같은 단어가 2개가 들어가지 않게합니다. 내려오는 단어중 같은 단어가 없게하는것이죠. If Command5.Enabled = False Then If Label1(0).Caption = Label1(1).Caption Then a = Int(Rnd(1) * 200) Label1(0).Caption = 낱말(a) a = Int(Rnd(1) * 200) Label1(1).Caption = 낱말(a) End If 한글일때 중복확인입니다. 0 하고 1하고 같으면 둘다 다시 랜덤으로 다른 단어를 뽑아줍니다. 무슨말인지 이제..이해가 가실꺼라고 생각합니다. 않가시면 역시 메일을.~ 밑에것도 마찬가지 입니다. 흐음...이로서 이슬비는 끝났네요..마지막에 설명이 조금 부족했나요? 특별히 설명할께 없는 부분이라... 점점 어려워질 껍니다..그만큼 길어지구.... 앞으로도 잘 지켜봐주세요~ p.s 낱말을 넣는곳에서 에러가 생겼습니다 그냥 낱말(0) ~ (200)으로 해두시고 추후에 설명드리겠습니다 * 타자 프로그램 만들기 강좌 입니다..[짧은글] '상' 안녕하세요^^ 오랫만에 쓰는것 같군요..죄송합니다... 흐음...오늘은.form3 에 있는 짧은글에 대해 알아보도록 합시다^^ 이런말 하기는 부끄럽지만 제 타자프로그램은 게임에 지나치게 치중해서 짧은글이나 긴글에 너무 소홀한 프로그램입니다.. 그래도 모르시는 분들이 보셔서 응용해서 더 좋은프로그램을 만들어 주시길 바랄 뿐입니다.. 우선 폼을 볼까요..제가 만든 타자프로그램 폼들이 다 설명하기 까다로울 정도로 복잡하죠;;. 그냥 눈에 보이시는대로 배치하시면 되구...폼 배치 주위사항이라면.. textbox 밑에있는건 배열로 잡아주셔야합니다 배열로 잡는건 저번에 설명 드렸듯이...레이블하나를 적당한 크기로 textbox 맨왼쪽에 배치하신다음에 복사하기 해서 붙여넣기 하면 배열로 작성할 꺼냐고 물어보게 됩니다 그래서 예 하면 배열로 돼게 됩니다.. 콘트롤 배치는 설명할꺼 없겠죠?..그냥 눈에 보이는대로 배치하시면 돼니.. 중요한 코딩을 알아보죠~ 코딩이 그리 길진않구...중간정도 돼는군요.. Dim 문장(100), v, k, c, d Dim cnt As Byte 변수를 선언해 줍니다... byte 는 범위가 255인가?..254인가까지 입니다-_-;..죄송... 그런건.....일반 책에 많이 나오니 참고하시길 바랍니다. msdn 이나... Private Sub Command1_Click() Text1.IMEMode = vbIMEModeHangul '한글 Command1.Enabled = False Command2.Enabled = True Command3.Enabled = True 시작하기를 눌렀을때의 이벤트 입니다.. 시작하기를 눌렀으면 만약 영어로 되어있으면 쓰기 불편하니 한글로 바꿔줍니다. 그리고 시작하기를 눌렀으면 다시 누르지 못하게 중지버튼이랑 메뉴 버튼은 누를수 있게 해줍니다. Label6.Visible = True Timer1.Enabled = True Text1.SetFocus label6..쳐야할 단어가 나타날 레이블입니다..맨 위에있는.. 시작하기를 누르면 보고 칠수있게 레이블이 보이도록 해줍니다. 그리고 타이머가 돌아가게 하구...시작하기 하면 칠수있게 text1에 마우스 포인터가 가게합니다.. For i = 0 To k Label1(i).Caption = "x" Label1(i).FontSize = Text1.FontSize Label1(i).Visible = True Timer2.Enabled = False 약간 복잡합니다. 여기서....k 란 label6의 글자의 길이입니다. 즉..글자의 길이만큼 대입을 해서 글자의 길이만큼 밑에 배열로 잡은것에.. x 란 글자가 나오게 합니다...나중에 맞으면 o 로 바뀌게 코딩을 해야겠죠 레이블 배열의 글자크기와 텍스트1의 글자크기가 같게합니다 x가 무슨글자를 나타내는지....비슷하게 하기 위함이죠. 레이블의 배열을 글자수만큼 보이게 해줍니다. 타이머2를 멈춥니다. Next Timer3.Enabled = True cnt = 0 아까 for 문을 next 로 닫아주고.. 타이머3을 돌려주고 cnt 변수를 0으로 해줍니다. Private Sub Command2_Click() Command1.Enabled = True Command2.Enabled = False Command3.Enabled = True Label6.Visible = False Timer1.Enabled = False For i = 0 To k Label1(i).Visible = False Next Timer2.Enabled = False Timer3.Enabled = False cnt = 0 End Sub 흠...중지버튼을 눌렀을때...이벤트입니다. 시작버튼을 사용가능하게 중지버튼 사용 못하게 메뉴버튼 사용하게... 쳐야할 단어가 나오는 레이블이 않보이게 하고 타이머1이 않보이게. 배열로 잡은것들이 안보이게....위에 레이블 글자 수만큼... 타이머를 다 닫아주고 cnt = 0 으로 해준다. Private Sub Command3_Click() Unload Me End Sub 메뉴로 를 누르면 짧은글 연습 폼을 unload 시킨다. 원래 메뉴 폼이 떠 있기 때문에 이 폼만 닫아주면 메뉴가 뜬것처럼 보인다. 흠.....오늘은 여기까지 하겠습니다.. 봐주셔서 감사합니다.. 다음엔 짧은글 하편을 하겠습니다.기대해주세요... * 타자 프로그램 만들기 강좌 입니다..[짧은글] '하' 안녕하세요^^ 짧은글을 배우는 2번째 시간입니다^^.. 이어서 계속..소스를 분석해보도록 하죠~ Private Sub Form_Load() 문장(1) = ""~ (100) 앞에서 나온 이슬비의 낱말, 영문과 같은것입니다. 위에서 문장을 배열로 100개를 잡아줬으니 1에서 100까지 100개의 낱말을 넣습니다.. 그래서 랜덤으로 뽑아내죠~ a = Int(Rnd(1) * 100) Label6.Caption = 문장(a) Command1.Enabled = True Command2.Enabled = False Command3.Enabled = True Label6.Visible = False 맨 위에 2줄이 랜덤으로 문장을 뽑아내는것입니다... 앞에서 많이 설명드렸으니 아시겠죠?... 폼이 처음 시작되면 시작은 누를수있게...중지는 못누르게 메뉴 버튼은 누를수 있도록 합니다... 그리고 쳐야할 문장이 나오는 label6은 보이지않게 합니다.. k = Len(문장(a)) v = Text1.Text k 에는 위에 랜덤으로 뽑아낸 한 문장의 길이를 저장합니다. len은 글자의 길이를 구하는 함수입니다... v 에는 text1의 text를 넣습니다. For i = 0 To k Label1(i).Visible = False Timer3.Enabled = False Next i = 0 부터 k만큼 돌려줍니다..for문을.... k는 위에서 구한 글자수입니다...글자수만큼 밑에 x 를 집어넣기 위함이죠 글자수만큼....맨 처음 시작했으니 일단 보이지 않게 해야겠죠.. 그리고 타이머3을 멈춰줍니다...next로 닫아주고.. Timer2.Enabled = False Label13.Caption = 0 타이머 2도 멈춰주시고 label13은 0으로.. label13은...지금까지 엔터나 스페이스를 쳤던 횟수를 나타냅니다. 즉...몇번 쳤냐를 나타내죠..실행시켜 보시면 알겠지만.. 틀리거나 맞거나 하면 왼쪽의 label13이 하나씩올라가고 맞으면 오른쪽레이블의 숫자가 올라갑니다...맞은갯수를 표시하는것이죠.. 몇분의..몇..이렇게....label13은 앞에것입니다~ mid.FileName = App.Path + "\THEME ME.wav" mid.Command = "open" MM콘트롤의 이름은 mid 입니다... 일단 오픈만 해놓습니다..왜냐하면 이 효과음은.... 나중에 엔터를 쳤을때 나게해야돼기때문입니다~ Private Sub Text1_KeyPress(KeyAscii As Integer) 다음은 핵심부분인 keypress 이벤트를 알아보죠.. 이것두 이슬비에서 설명드렸듯이 text1에 어떤 키가 입력돼면 일어나는 이벤트입니다^^.. Timer2.Enabled = True Label2.Caption = Text1.Text 타이머 2를 돌아가게 하고 label2 에는 입력하는 text1.text 와 같게합니다 확인란이죠`..그러니..같게~.. If KeyAscii = 13 Then If Trim(Text1.Text) <> "" Then If cnt <> 0 Then 첫줄은....그러니까 13..만약에...엔터키가 입력되면 이죠 두번째 줄은 만약..text1.text 가 ""..아무것도 입력되있지 <>...않다면... 세번째 줄은..cnt가..<>..0이 아니면.. timer3이 실행되고 있다면 cnt 는 0이 아니겠죠.. 이 cnt 는 나중에 타자속도를 구할때 사용됩니다..1초마다 + 1로 되죠... Select Case cnt Case 1 To 2 c = 2 Case 3 To 4 c = 1.9 Case 5 To 6 c = 1.8 Case 6 To 7 c = 1.7 Case 8 To 9 c = 1.6 Case 10 To 11 c = 1.5 Case 12 To 13 c = 1.4 Case 14 To 15 c = 1.3 Case 16 To 17 c = 1.2 Case 18 To 19 c = 1.1 Case 20 To 21 c = 1 End Select 이것은....cnt 에 따라 c를 주는겁니다.. 이것모두 타자 속도를 구하는데 사용됩니다... 전 타자 속도를 구하는 공식을 몰랐기 때문에..제 나름대로 만든겁니다 오차가 생기더라도..이해해주세요....어디서 구할수가 없었어가지고요.. cnt 가 1에서 2 사이면 c = 2로 주고...이런겁니다.. 즉....cnt 가 높을수록 c 는 낮아지게됩니다.. 시간이 많이 흐를수록 c 는 낮다는 말이죠^^:; Label10.Caption = Round(((k / cnt) * 60) * c * -1) * -1 label10은 타수죠....k 는 글자수...글자수 / 시간이 돼겠죠. 그 다음에 1분이 60초니까 60을 곱해주고...거기다 위에서 구한 c를 곱해주고 -1을 곱해주고.. 또..그 구한값에 -1을 곱해줍니다.. 대충이런데..수학 잘하시는분은 아시겠지만..전 몰라서..ㅠ_ㅠ... 대충 타수구하는 공식입니다..앞에 round는 반올림이죠.... 소수로 나올수있기때문에 반올림.....저도 어떤뜻인지는 모릅니다;.어디서 줏어들어 가지구..마구 쓴것이거든요..정확한것이 아니기때문에...아셔봤자.... 좋으실것이 없다고 생각합니다..ㅠ_ㅠ.....죄송합니다..정확한걸 알려드려야하는데. 죄송합니다.(__) (--).... If Label12.Caption < Label10.Caption Then Label12.Caption = Label10.Caption mid.Command = "prev" mid.Command = "play" End If 만약에 label12가 label10 보다 작으면 label10이 크면 이죠.. label12는 최대타수인데..최대타수보다 그냥 타수가 더 크다면.. 그 타수가 최대타수가 되야겠죠....그래서 2번째 줄에..최대타수에.. 그냥 타수를 넣는것입니다..그 다음에...엔터를 쳤으니..효과음을 재생해 줍니다...prev는 처음으로 감아 주는것입니다.. Label13.Caption = Label13.Caption + 1 For i = 0 To k Label1(i).Caption = "" Next 엔터를 쳤으니까....label13 즉...친 문장수.....친 문장수/맞은문장수로 나타내죠~ 그중에 친문장수 label13 은 +1을 해줍니다.. 그리고 글자수만큼 다시 돌려주고....label1(i)에 아무것도 넣지 않습니다.. 그리고 닫아줍니다.. If Label6.Caption = Trim(Text1.Text) Then Label4.Caption = Label4.Caption + 1 a = Int(Rnd(1) * 100) Label6.Caption = 문장(a) text1에 입력된 내용이..즉 사용자가 친 문장이 label6..쳐야할 문장과 같으면 즉...맞았을때의 이벤트죠...label4..맞은갯수입니다...맞은갯수는 + 1 해주고 문장은 다시 랜덤으로 구해서 label6에 넣어줍니다.. If Label6.Caption = "" Then a = Int(Rnd(1) * 100) Label6.Caption = 문장(a) End If 그리고쳐야할 문장이 나타날 label6에 아무것도 입력되어있지 않다면... 랜덤으로 문장을 구해서 넣어줍니다.. k = Len(문장(a)) For i = 0 To k Label1(i).Caption = "x" Next Label8.Caption = "맞았다" 엔터를 쳐서 문장이 새로운게 다시 나왔을테니..다시 그 문장의 길이를 구하여 k 에 넣어줍니다.. 그리고 그 글자수만큼 for 문을 돌려서 x 표시를 하게 해줍니다... 그리고 label8에는 맞았다란 단어가 나오도록 합니다..맞았으니까요.. ElseIf v <> Label6.Caption Then Label8.Caption = "틀렸다" a = Int(Rnd(1) * 100) Label6.Caption = 문장(a) If Label6.Caption = "" Then a = Int(Rnd(1) * 100) Label6.Caption = 문장(a) End If k = Len(문장(a)) 아까와 비슷합니다 틀렸을때의 이벤트죠.... text1.text를 저정함 v 가 label6과같지 않다면. label6에 틀렸다가 출력되게하고...랜덤으로 다시 문장을 뽑아서 label6에 넣어줍니다..매번 다른문장이 나오게하기 위함이죠... 그리고 위와 마찬가지로 label6에 아무것도 입력되어있지 않다면 랜덤으로 넣어줍니다..문장을.. 또한...틀렸을경우에도 새로운 문장이 나타나기때문에 그 길이를 다시구해. k 로 넣어줍니다.. For i = 0 To k Label1(i).Caption = "x" Beep Next End If End If Text1.Text = "" Text1.SetFocus cnt = 0 End If End If 또 글자수만큼 x 를 넣어주고..beep 삐 소리가 나도록 해줍니다.. 틀렸으니^^;...for 문 닫아주고..if .문 2개 닫아주고...text1.text 는 = "" 아무것도 없게....마우스 포인터도 text1로.... cnt = 0 으로...if 문 2개 닫아주고.. Private Sub Timer1_Timer() k = Len(Label6.Caption) For i = 0 To k If Left(Text1.Text, i + 1) = Left(Label6.Caption, i + 1) Then Label1(i).Caption = "o" End If Next For i = 0 To k If Left(Text1.Text, i + 1) <> Left(Label6.Caption, i + 1) Then Label1(i).Caption = "x" End If Next k는 쳐야할 단어의 길이... 밑에2개는 o, x 를 표시하는 겁니다.. left 함수도 알아야하고.... left함수까지 설명드리긴...좀 그렇고...msdn 같은곳을 참고하시길 바랍니다.. text1.text 의 왼쪽부터 i 가 0일땐...1 과 label6의 첫번째와 비교합니다. 그래서 같으면 label1(0)엔 o 가출력됩니다.. 밑엔 x 랑 <> 표시만 다르게됩니다. Private Sub Timer3_Timer() cnt = cnt + 1 End Sub timer3은 1초마다 실행되나까 1초마다 cnt 는 + 1씩 됩니다. 하아..끝났군요.. 쉽죠?...만약 모르시겠으시면..dingpong@hitel.net으로 메일 꼭 주세요..언제든지 1년후라도 상관없어요^^;.....그럼 많이 봐주시고 많이 질문해주세요 그럼 다음에 보죠^^.... p.s 여기서 timer2는 필요없을꺼 같군요..내용을확인해 보고서야..아무것도 없다는걸 알았습니다..ㅠ_ㅠ * 타자 프로그램 만들기 강좌 입니다..[긴글] '상' 안녕하세요^^... 이번 강좌는..흠...긴글만들기에 대해 써보겠습니당.. 우선 폼을 봅시다~..^^ 조금 복잡합니다...이 긴글폼도 메인메뉴 폼과 마찬가지루 섞여있기 때문입니다. 긴글 종류 선택하는것과...치는것이 섞여있어서 그렇습니다.. 종류선택하는버튼 보이죠?...치는것두 보이구... 즉..폼이 로드되면....다른건 보이지 않지만....긴글종류..고르는건 보이게 됩니다...그중 하나 선택하면...그 종류 고르는건...보이지 않게하고.. 치게 하는걸...보여주면 되는겁니다.... 제가 이렇게 한 이유는 종류 고르는걸 다른폼에서 불러와서 하구..그러기 더 복잡하기 때문입니다..그래서 한 폼안에서 다 해결한거죠.. 이게 더 만들기 쉽고요.. 앞에..긴글 종류를 선택할 5개의 커맨드 버튼이 있고요..뒤엔...흐음.. 전시간에 배웠던 짧은글을 길게 만든거라고 보면 되겠군요 짧은글을 여러개 만든다는 생각으로 폼을 짜봅시다~..^^;; 흐음..폼 다 알아봤지요?..그럼 코딩을 차근차근봅시당.. Dim 긴글, k, rr Private Sub Command1_Click() Timer1.Enabled = True Command1.Enabled = False Command2.Enabled = True 변수를 선언합니다..긴글이란..변수를... 그리고 k ,rr 이건 나중에 나오면 설명 드리죠.. 긴글변수는 말그대로 길글을 저장하려고 쓴 변수입니다.. 일단 어떤 글을 긴글이란 변수에 저장한다음 그걸 출력하는거죠.. 무슨말인지 아시겠죠?..... 그다음....커맨드1 클릭했을때의 이벤트군요..흠흠... 커맨드1은 시작하기 버튼입니다.. 시작하기 버튼을 누르면...타이머가 돌아가게 하고.. 시작을 눌렀으니 시작은 다시 못누르게 하고 중단하기는 누를수있게합니다.. For i = 0 To 3 lb(i).Visible = True Text1(i).Visible = True lb(i).Enabled = True Text1(i).Enabled = True Next ib란..폼을 보시면 알겠지만...쳐야할 긴글이 나올 레이블의 배열입니다.. 맨위에줄은 ib(0) 그다음은 ib(1) ib란건 제가 임의로 label 의이름을 바꾼것입니다 별 뜻은 없고요..... 그러니까 4개니까 0~ 3까지죠..0,1,2,3... 이렇게 배열로 잡은 이유는 변하게 하기 위해서입니다 배열로 잡지않으면...for 문돌려서 위에서처럼 보이게할때.. label1.visible = true label2.visible = true label3.visible = true label4.visible = true label5.visible = true ......... 많으면 많을수록 코딩만 늘어나겠죠?....그런것 때문에 for 문을쓰기위해서 배열로 잡은것입니다.. 0에서 3까지의 레이블을 보이게..합니다 시작했으니..쳐야돼니까.. 당연히 보여야 칠수있겠죠.. 입력할수있는 텍스트 박스 4개를 보이게 합니다... 레이블을 활성화 시키고 텍스트박스도 활성화 시킵니다....for 문 닫아주고.. Text1(0).SetFocus For i = 0 To 26 Label2(i).Caption = "x" Label3(i).Caption = "x" Label4(i).Caption = "x" Label5(i).Caption = "x" Label2(i).Visible = True Label3(i).Visible = True Label4(i).Visible = True Label5(i).Visible = True Next 치기 편하게 text1에 마우스포인터를 이동시키고... 27개만큼 밑에..0,x를 표시하는 레이블에 x를 넣어줍니다..방금 시작했으니... 다 맞지 않으니..다 x 겠죠...그리고 검사하는 레이블들은 다 보이게 해줍니다. Command4.Visible = False Command4.Enabled = False command5.Visible = False command5.Enabled = False Command6.Visible = False Command6.Enabled = False Command7.Visible = False Command7.Enabled = False Command8.Visible = False Command8.Enabled = False Command9.Enabled = True Command9.Visible = True 4,5,6,7,8 은 종류를선택하는 커맨드버튼입니다. 커맨드9는 글종류 로 가게하는 커맨드 버튼입니다.. 밑에 4개중 맨 오른쪽꺼이죠.. 시작하면 또 종류 고르는게 나오면 않돼니....커맨드버튼 5개는 않보이게해주고 비활성화 시키고....쓸수없게....글종류메뉴로는 다시 갈수있게 해준다. Private Sub Command2_Click() Timer1.Enabled = False Command1.Enabled = True Command2.Enabled = False 중단하기 버튼을 눌렀을때의 이벤트입니다.. 중단하기를 했으니까..타이머가 돌아가지 않게 하고... 시작하기를 누를수있게한다.. For i = 0 To 3 lb(i).Visible = False Text1(i).Visible = True lb(i).Enabled = False Text1(i).Enabled = True Text1(i).Text = "" Next 흐음....중단하기니까...텍스트 입력만..가능하게 해줍니다.. 쳐야할 레이블은 보이지 않는다.. For i = 0 To 26 Label2(i).Visible = False Label3(i).Visible = False Label4(i).Visible = False Label5(i).Visible = False Next 중단하기를 했으니...0,x 를 표시하는것도 모두 않보이게 해줍니다.. Private Sub Command3_Click() Unload Me End Sub 메뉴로란 걸 누르면 긴글을 닫아줍니다.. 하아..오늘은 짧지만 이만 줄이겠습니다 너무 졸려서요-_-;;;..죄송... 다음엔 많이 쓰겠습니다..기대해주세요^^... * 타자 프로그램 만들기 강좌 입니다..[긴글] '중' 안녕하세요^^ 늦었네요;..죄송합니다. 흐음..그럼 계속 이어서 긴글소스코드를 보도록 하죠~ Private Sub Command4_Click() 긴글 = " 서울 시내의 제법 번화한 도로변이 대개 그러하듯이 지금 그가 높은 의자에 앉아있는 곳의 대기 속에도 온갖 소리들이 가득 차 있었다. 물론 그 곳은 길거리인지라 차량들의 엔진 소리와 차바퀴가 바닥에 마찰되는 소리, 소리라기보다 소음에 가까운 것들이 주종을 이루고 있긴 했지만 그래도 약간의 주의만 기울인다면 그 외의 더 많은 종류의 소리도 들을 수 있었다. 말하자면 길거리에 앉아 있어야 하는 직업을 가지고 있는 그는 이제 약간의 경력에 의해 시끄러운 자동차들의 소음 속에 파묻혀 있는, 그래서 간간이 단편적으로 드러나는 행인들의 말소리들, 그들의 몸이 내는 소리들, 하여튼 사람들이 만나고 헤어지고 살아가면서 내는 모든 소리들을 놓치지 않고 들을 수 있었다. 그러나 하루 종일 울리는 높운 데시벨의 소리들은 그의 청각 기관을 멍멍하게 했고 머리 속 더 깊이 파고들어서 가끔 두통을 일으켰다. 그러한 시달림 때문인지 아니면 실제로 어떤 이물질 때문인지 귓속이 근지러움을 느낀 그는 한 손에는 배차 시간표를 들고 오른쪽 새끼손가락으로 역시 오른쪽의 귓속을 후볐다. 그러나 귓속의 기묘한 고통은 그의 손가락 끝이 닿을 수 있는 곳 너머에 있었다. < 끝 >" 흐음...위에서 선언해준 긴글이란 변수에다가 이런 글을 넣은것입니다 전에했던 이슬비나 짧은글에서 배열로 된 변수에다가 각각의 낱말, 문장을 넣은것과 마찬가지입니다... For i = 0 To 3 lb(i).Caption = Mid(긴글, k, 27) k = k + 27 Next i = 0 에서 3까지..즉 4번돌리죠..0,1,2,3 ib는 쳐야할 글자가 나와야할 레이블입니다... 그 레이블의 맨위 즉 0 이들어갔을떄....는..그 레이블의 이름이 긴글 전체에서 k 즉..뭐라고 설명해야할까..시작해야할 글자의 번호수?.. 거기서 27개씩 짜른다른 말입니다. 앗..저도 까먹었군요..-_-;;; 다음시간에 자세히 알아서 보충으로 올리겠습니다..지금까지 빼먹었던 것들이랑 정말로 죄송합니다.; For i = 0 To 3 lb(i).Visible = False Text1(i).Visible = True lb(i).Enabled = False Text1(i).Enabled = True Next 위에 구지 next 닫지말구 여기선 for 쓰지말구 그냥 해두 돼는데; 나누다 보니 이렇게 코딩만 많아지는군요;..... 똑같이 0에서 3까지 대입합니다.. 흠..이건...쳐야할 단어가 나오는 레이블 lb는 보이지 않게하고 치는곳... textbox는 보이게 합니다...처음에 긴글 종류를 선택하고 나면... 쳐야할곳은 나오게 하구.....이제 시작하기를 눌러야 쳐야할 단어까지 보이게 해야하니까요..구지 이렇게 않하셔두 됩니다~.. 그냥 textbox도 않보이게 하셔두 돼구요~ Command8.Enabled = False Command7.Enabled = False Command6.Enabled = False command5.Enabled = False Command4.Enabled = False Command7.Visible = False command5.Visible = False Command6.Visible = False Command4.Visible = False Command8.Visible = False 글종류를 나타내는 command 4~8 까지 5개를 쓰지못하도록, 않보이게 해줍니다 이 코딩은 command4 를 눌렀을때니까...4는 '소리에 대한 몽상'이란 긴글을 이미 선택했으니 또 글종류를 선택 못하게 하는것이죠 Label1.Visible = False Label1.Enabled = False Command1.Enabled = True Command2.Enabled = False label1..즉 '긴글 연습 종류 고르기' 란 caption 이 있는 레이블을 보이지 않게 합니다...그리고 시작하기를 사용할수있게 중단하기는 사용하지 못하도록. Timer1.Enabled = False Command1.Visible = True Command2.Visible = True Command3.Visible = True Command3.Enabled = True Command1.Enabled = True Command2.Enabled = False 타이머는 일단 멈춰있게합니다..시작하면 돌아가게 해야겠죠 위에쓴걸 또 쓴게있군요..실수입니다;..코딩상의.. 시작하기와 중단하기 메뉴란 command 를 보이게 해주고 단 중단하기는 사용하지 못하도록 해줍니다. For i = 0 To 26 Label2(i).Visible = True Label2(i).Enabled = True Label3(i).Visible = True Label3(i).Enabled = True Label4(i).Visible = True Label4(i).Enabled = True Label5(i).Visible = True Label5(i).Enabled = True Next o,x 가 나오는 레이블들 입니다. 보이게 해줍니다.... 나중에 시작하기 할때 보이게 해줘도 상관은 없습니다. Command9.Enabled = True Command9.Visible = True 위에서 빠트렸는데...command9 글종류 고르는것을 보이도록..사용할수있도록... 이제...밑에것은..다 비슷비슷합니다..거의 똑같죠.. 구지 길게..설명 않해드려도 다 이해가실껍니다.. 이해 않가시는 부분이 있으면 개인적으로 dingpong@hitel.net 으로 메일을 보내주시고요.~...command4~8까지의 설명이 끝났습니다. Private Sub Command9_Click() Label1.Visible = True Label1.Enabled = True Command1.Enabled = True Command2.Enabled = False command9 를 클릭했을때의 이벤트 입니다. 글종류를 선택했으니까.....맨 처음에 메인메뉴에서 긴글을 선택해서 들어왔을때.. 와 똑같이 폼을 해야겠죠... '긴글 연습 종류 고르기' caption 를 가진 레이블을 보이게 해주고.. 시작하기를 누를수 있게..중단하기는 못누르게..이건 별로 필요가 없을꺼 같군요. For i = 0 To 26 Label2(i).Caption = "x" Label3(i).Caption = "x" Label4(i).Caption = "x" Label5(i).Caption = "x" Label2(i).Visible = False Label3(i).Visible = False Label4(i).Visible = False Label5(i).Visible = False Next o,x를 표시하는 레이블이 다 x 로...초기화 그리고 다 보이지 않게. For i = 0 To 3 Text1(i).Text = "" Next 입력하는 textbox 가 다 초기화루..아무것도 없게 k = 1 말그대로 k = 1 로.. Command4.Visible = True Command4.Enabled = True command5.Visible = True command5.Enabled = True Command6.Visible = True Command6.Enabled = True Command7.Visible = True Command7.Enabled = True Command8.Visible = True Command8.Enabled = True 글종류인 command4~8을 보이게하구 사용할수있게 한다. For i = 0 To 3 lb(i).Visible = False lb(i).Enabled = False Text1(i).Visible = False Text1(i).Enabled = False Next 쳐야할단어가 나오는 lb 즉 label을 보이지않게.. text1 도...보이지 않구 사용할수없게...사용자가 치는곳~ For i = 0 To 26 Label2(i).Caption = "x" Label3(i).Caption = "x" Label4(i).Caption = "x" Label5(i).Caption = "x" Next 아까 했는데..제가 실수로 또썼군요-_-;;초보때 짠거라서; 지금도 초보지만;... o,x 가 나오는 레이블을 다 x 로... Command1.Visible = False Command2.Visible = False Command3.Visible = False Command9.Visible = False Command1.Enabled = False Command2.Enabled = False Command3.Enabled = False Command9.Enabled = False 시작, 중단하기, 메뉴, 글종류 선택을 보이지않구 사용할수없게합니다. 흠...이번 강좌는 이번으로 마치겠습니다. 계속 봐주시는 여러분께 감사드립니다. 다음엔...긴글 '하'편하고 부족한부분들을 따로 설명 드리겠습니다 다른곳에서도 빠트린게 있는거 같아서요. 늦게 올려서 죄송합니다 * 타자 프로그램 만들기 강좌 입니다..[긴글] '하' 하아..늦었군요..죄송합니다 오늘부터 시험기간이라..시간이 남는군요..하하(--;;). 에..저번시간에는~~~~..글종류 선택까지 했나요?; 이번에는 폼 로드부터 알아보도록하죠~ Private Sub Form_Load() Command1.Enabled = True Command2.Enabled = False Timer1.Enabled = False For i = 0 To 3 lb(i).Visible = False Text1(i).Visible = False lb(i).Enabled = False Text1(i).Enabled = False Next 폼 로드는 처음 이 긴글을 켰을때 발생하는 이벤트 입니다 시작하는 돼도록해야겠죠^^ 타이머는 멈춰있구.....입력하는 텍스트박스랑 레이블이랑은 않보이고. 사용할수없게 합니다. 생각해 보세요^^..그런것들은 command1 을 클릭했을때. 즉 시작을 눌렀을때 보이고 쓸수있도록 해야겠죠~ For i = 0 To 26 Label2(i).Visible = False Label2(i).Enabled = False Label3(i).Visible = False Label3(i).Enabled = False Label4(i).Visible = False Label4(i).Enabled = False Label5(i).Visible = False Label5(i).Enabled = False Next 이것도 마찬가지~ o,x 가 나오는 레이블을 모두 않보이게..사용할수없게 Command1.Visible = False Command2.Visible = False Command3.Visible = False Command3.Enabled = False Command1.Enabled = False Command2.Enabled = False k = 1 Command9.Visible = False Command9.Enabled = False End Sub 흠...위에선 설명 않했지만.. 처음 시작했을때는 글종류가 보여야 하기 때문에... 시작하기 그런버튼은 모두 없애주고... 글종류 했을때의 것들만 보이도록 사용할수있도록 해줘야합니다. Private Sub Text1_KeyPress(Index As Integer, KeyAscii As Integer) If rr = -1 Then If KeyAscii = 13 Then Text1(0).Text = "" Text1(1).Text = "" Text1(2).Text = "" Text1(3).Text = "" For i = 0 To 3 lb(i).Caption = Mid(긴글, k, 27) k = k + 27 Next End If End If 다음은 중요한 keypress 부분..어떤 특정한 키가 눌렸을때의 이벤트를 코딩하는 곳이죠. 만약에 rr = -1 이면.....rr 은 밑에서 설명드리겠습니다. 그리고 keyascii =13 이면...13이면 엔터키입니다. 그럼 치는곳을 초기화 시킨다..아무것도 없게... 그리고 1 부터 3까지 돌려서 쳐야할 단어가 나오는 곳에 긴글을 27개씩 짤라서 넣는다. 이런뜻입니다. 즉 이것은 4번째 치는곳..즉 끝에서 엔터키를 눌렀을때. 쳤던 단어가 다 없어지고 쳐야할 문장이 나와야할 곳에. 그 뒤에 문장이 나온다는 뜻이죠. If KeyAscii = 13 Then rr = rr + 1 Text1(rr).SetFocus If rr = 3 Then rr = -1 End If End If 엔터키를 누를때마다 rr 은 + 1 씩 됩니다. 그리고 마우스커서는 한칸 밑으로 내려가게 되고요 rr = 3 즉....맨 마지막칸에서 엔터를 쳤을때. rr = -1 이 되도록합니다 모르시겠으면 메일을 띄어주세요... For i = 0 To 26 If Left(Text1(0).Text, i + 1) = Left(lb(0).Caption, i + 1) Then Label2(i).Caption = "o" End If Next For i = 0 To 26 If Left(Text1(0).Text, i + 1) <> Left(lb(0).Caption, i + 1) Then Label2(i).Caption = "x" End If Next For i = 0 To 26 If Left(Text1(1).Text, i + 1) = Left(lb(1).Caption, i + 1) Then Label3(i).Caption = "o" End If Next For i = 0 To 26 If Left(Text1(1).Text, i + 1) <> Left(lb(1).Caption, i + 1) Then Label3(i).Caption = "x" End If Next For i = 0 To 26 If Left(Text1(2).Text, i + 1) = Left(lb(2).Caption, i + 1) Then Label4(i).Caption = "o" End If Next For i = 0 To 26 If Left(Text1(2).Text, i + 1) <> Left(lb(2).Caption, i + 1) Then Label4(i).Caption = "x" End If Next For i = 0 To 26 If Left(Text1(3).Text, i + 1) = Left(lb(3).Caption, i + 1) Then Label5(i).Caption = "o" End If Next For i = 0 To 26 If Left(Text1(3).Text, i + 1) <> Left(lb(3).Caption, i + 1) Then Label5(i).Caption = "x" End If Next End Sub 긴데...별거 아닙니다. o,x 를 나타내는것이죠. 하나씩 풀이해보면... 맨마지막에 있는걸로 해보겠습니다. 0에서 26까지 돌리고... if text1(3)의 왼쪽에서 i +1 번째가 ( +1 을 하는이유는 0 부터 돌렸기 때문에).. lb(3)즉 쳐야할단어의 i+1 번째가 같지 않다면. label5(i)번째에는 x 를 출력해라. 그런뜻입니다.. 역시 이해가 않가시면 메일을 꼭 보내주세요 지금까지 메일이 한통도 않오네요ㅠ_ㅠ.. 에....위로의 한마디라도 보내주시면..더 잘쓸수 있을텐데요+_+ 보충설명은 추후에-_-;..하하.. 그럼 시험공부하러...^^...도움이 돼셨으면 좋겠네요 * 타자 프로그램 만들기 강좌 입니다..[타자검정] 안녕하세요^^ 많이 늦었지요?;..헉헉. 이해해주시리라 믿고^^. 오늘은 타자 검정에 대해 알아보도록 하죠. 타자 검정은 긴글과 아주 흡사합니다..다만 다른것은. 시간이 가면서 그 시간이 돼면 끝나게 하는것만 하면 돼죠. 여기서는 지원하지 않는 기능인 몇타 쳤는지 정확도가 몇인지까지. 나오게 하면 정말 좋겠죠?. 타이머를 하나 추가하시고.. 1초에 한번씩 돌아가도록 해줍시다~ 폼에도 텍스트박스하나 넣고 100이라고 text 를 넣어주세요. 밑에..남은시간 몇초를 표시할 레이블하고요. 그리고 소스 코딩하는곳 일반에 dim gg 라고 변수를 하나 잡아줍시다. 이 gg 는 시간을 잴때 사용하는 변수라고 하겠습니다. 처음에 시작을 누르면 100이 입력돼있는 textbox 에 입력돼있는 숫자가 gg 에 들어가도록 해줍니다. 그리고 그 textbox는 숨겨줘야겠죠 timer2가 핵심부분이라 그부분만 하도록 하겠습니다. gg = gg - 1 Label6.Caption = gg If Label6.Caption = 0 Then MsgBox "시간이 다 되었습니다." Text1(0).SetFocus Timer1.Enabled = False Command1.Enabled = True 이 타이머는 1초마다 한번씩 작동하니까 gg 즉..처음에 입력돼있는 숫자에 - 1 씩 해줍니다. 그것이 0 이 돼면은. 시간이 다 돼었다는 메세지 박스를 띄우게 돼죠. 그리고 text1(0)번째에 마우스 커서가 가게 해주고요.. 시간이 다 돼었기때문에 text1의 작동을 멈춰줍니다. 그리고 시작하기를 누를수있게 해주고요. For i = 0 To 3 lb(i).Visible = False Text1(i).Visible = True lb(i).Enabled = False Text1(i).Enabled = True Text1(i).Text = "" Next 입력하는 textbox랑 쳐야할 단어가 나오는 lb 라는 label을 않보이게 해줍니다. 그리고 textbox 는 칠수있게 하고 아무것도 없게 초기화해 줍니다. For i = 0 To 26 Label2(i).Visible = False Label3(i).Visible = False Label4(i).Visible = False Label5(i).Visible = False Next 0,X 로 표시되는 부분을 않보이게 해줍니다. Timer2.Enabled = False Label6.Visible = False Label7.Visible = False Label8.Visible = False End If 타이머의 작동을 멈추고... 남은 초가 나오는 레이블을 않보이게 해줍니다. 설명은 끝났습니다. 제가 만든건 아주 기초적인 것밖에 않됩니다. htt처럼 하는데..제 프로그래밍 실력으로는 않돼더군요 여러분이 노력하셔서^^..한번 해보시길 바랍니다. 그럼 열심히하세요. * 타자 프로그램 만들기 강좌 입니다..[전쟁] '상' 안녕하세요^^ 이번에도 꽤 늦게됬네요 죄송합니다 이번시간부터는 전쟁에 대해서 알아보죠.. 비주얼베이직을 틀으시고 ^^..제가 만든 타자프로그램 중에 전쟁을 봐주세요. 음..보시면 조금 복잡하실 껍니다. 위에 타이머두 많구.. 제가 만들었지만 4개월 이상 됐기때문에-_- 저도 그냥 봐서는 뭐가 뭔지 잘 모르겠군요 거기있는 MMcontrol 은 맞았을때 틀렸을때 띵 소리를 나게 하기 위해 2개가 들어갔습니다^^; 효과음 타이머들은. 각각 틀렸을때, 맞았을때 효과음을 내구. 막대가 밀리게 하구 앞으로 오게 하구.. 그리고 적군을 몇명 피해 입기헤 했습니다. 원군이 왔습니다..등.. 을 출력하게 하는 역활을 합니다.. 제 알고리즘이 약간 이상할지 모르겠네요^^;.하핫 저도 초보라.. 난이도도 보이구.. 여기서 팁을 가르쳐 드리자면.. command button 에 색을 넣을려구 하면.. 그냥 색만 바꿔선 색이 않들어 가죠? command 속성에 보면 style 라는것이 있는데 그것을 1-그래픽 으로 바꾸고 색을 바꿔주게 되면 커맨드 버튼에 색이 바뀌게 됩니다^^ 다 아시는건가-_-a 1.1 이하버전에선 설명이 않나오지만 1.2 버전부터는 원군이 왔습니다. 피해를 입혔습니다 등의 설명을 집어넣어 (달리기도 마찬가지) 소스가 더 볶잡해 졌죠..노가다를 해야 했기 때문에;.하하 실행시켜 보시고..어떻게 동작하는지 익혀 봅시다. 실행시켜 보시면...단어가 맞으면 오른쪽에서 단어가 나가서 막대에 딱 맞구 뒤로 밀려나죠?.. 오른쪽에서 단어를 나가게해서. 맞으면 없어지구 막대가 밀리게 하는 알고리즘..이게 핵심입니다. 그리고 틀리게 돼면 반대쪽에서 단어가 나와서 막대를 앞으로 밀어주죠? 충돌이벤트라는것을..개념을 알아야합니다 이건 게임같은곳에선 필수죠. RPG 를 예를 들자면...RPG에서 충돌이벤트를 잘못 설정해 주면 벽에 부딫혔는데 계속 앞으로 갈수있게 된다..이건 말도 않돼죠? 벽에 부딫혔으면 더 앞으로 나갈수없게 만든다.. 이렇게 되야하구요 슈팅게임에서도....if 적 비행기 = 미사일 then 이면. 적 비행기는 = 죽음 뭐 이런싣으로 해야겠죠? 하핫..그게 중요합니다... 설명은 이쯤 해두고요...우선 오늘은 폼을 배치해 봅시다. 그리구..사용법을 익히구요 그럼 이만^^ *