Lainasin kirjastosta kirjan, Inside Peliohjelmointi. Kirjan mukana tuli Visual C++ 6.0. Nyt on kuitenkin eteen tullut nolo ongelma: en tiedä mistä .lib ja .h tiedostot saadan linkitettyä ohjelmaan. Älkää sanoko "lue ohjeista", sillä en jostain syystä löytänyt muuta kuin juttua MFC:n hienoudesta.
Voisiko joku ystävällisesti kertoa paikan mistä voisi .h ja .lib tiedostoja lisäillä projektiin?
, kiittäen Queq
Visual C++:n juurihakemisto lienee jotain tämän tyylistä:
C:\Program Files\Microsoft Visual Studio\VC98
Se sisältää Include-hakemiston (.h-tiedostot) ja Lib-hakemiston (.lib-tiedostot).
Toisaalta, perus-.h-tiedostoja ei yleensä tarvitse lisäillä muuten kuin esikääntäjän direktiivillä (#include), ja perus-.lib-tiedostot ovat automaagisesti uudessa projektissa mukana.
Mutta eikö jostain kuitenkin pidä määritellä mitkä .lib tiedostot halutaan käyttöön, vai osaako kääntäjä etsiä sen itse..?
Pistä vielä linkitykset <sulkeisiin>, eikä " "
Joo, kiitoksia nyt selvisi. Hämäsi hieman kun Visual C++ toimii aivan erilailla kuin muut käyttämäni kääntäjät.
Eipäs muuten selvinnytkään. Kuvitellaan, että yritän kääntää vaikka Inside Peiohjelmointi kirjan ensimmäisen osan freakout.cpp koodia.
Olen nyt tehnyt muistaakseni näin (en pääse sitä toiselta tietokoneelta tarkistamaan): New File -> New Project > Win32 Aplication > Tyhjä projekti. Saan eteeni tyhjän projektin. Sieltä vasemmasta palkista hiiren kanssa lisään (Add file) lisään freakout.cpp:n. Nyt painan Compile. Eteeni tulee 2 varoitusta, että tiedostossa blacbox.h/cpp on virhe, vaikka siellä virhettä ei olekkaan. Eli teenkö jotain väärin? Edes yksinkertainen helloworld ohjelma ei kääntynyt, vaikka tein juuri näin.
Kysykää jos haluatte tietää jotain mitä yllä olevasta vaikea selkoisesta selvityksestä ei löydy?
No mitkä virheet/varoitukset?
Millasta "Hello World":ä oot kääntämässä? Koodia? Millainen tuo freakout.cpp on? Tarkista tarviiko se jonkun erityisen kirjaston.
No niin, tällä kertaa hello wordi kääntyi, vikana oli ollut inhimillinen virhe edellisellä kerralla. Mutta tuo freakout.cpp ei käänny:
2 erro(s)
e:\oppaat\c++\inside peliohjelmointi\koodit\luku01\blackbox.h(34) error c2146: syntax error missing ';' before identifier 'lpdd'
e:\oppaat\c++\inside peliohjelmointi\koodit\luku01\blackbox.h(34) fatal error c1004: unexpected end of the file found
Tuo blackbox.h on kirjantekijän oma kirjasto, jonka hän otti mukaan ensimmäiseen esimerkkiin. Ja ei opiskelu oikein suju, jos ei edes ensimmäistä esimerkkiä saa käännettyä.
EDI: välilyönti puuttui... :)
Voisin vielä lisätä filut:
// FREAKOUT.CPP - break game demo // INCLUDES /////////////////////////////////////////////////// #define WIN32_LEAN_AND_MEAN // include all macros #define INITGUID // include all GUIDs #include <windows.h> // include important windows stuff #include <windowsx.h> #include <mmsystem.h> #include <iostream.h> // include important C/C++ stuff #include <conio.h> #include <stdlib.h> #include <malloc.h> #include <memory.h> #include <string.h> #include <stdarg.h> #include <stdio.h> #include <math.h> #include <io.h> #include <fcntl.h> #include <ddraw.h> // directX includes #include "blackbox.h" // game library includes // DEFINES //////////////////////////////////////////////////// // defines for windows #define WINDOW_CLASS_NAME "WIN3DCLASS" // class name #define WINDOW_WIDTH 640 // size of window #define WINDOW_HEIGHT 480 // states for game loop #define GAME_STATE_INIT 0 #define GAME_STATE_START_LEVEL 1 #define GAME_STATE_RUN 2 #define GAME_STATE_SHUTDOWN 3 #define GAME_STATE_EXIT 4 // block defines #define NUM_BLOCK_ROWS 6 #define NUM_BLOCK_COLUMNS 8 #define BLOCK_WIDTH 64 #define BLOCK_HEIGHT 16 #define BLOCK_ORIGIN_X 8 #define BLOCK_ORIGIN_Y 8 #define BLOCK_X_GAP 80 #define BLOCK_Y_GAP 32 // paddle defines #define PADDLE_START_X (SCREEN_WIDTH/2 - 16) #define PADDLE_START_Y (SCREEN_HEIGHT - 32); #define PADDLE_WIDTH 32 #define PADDLE_HEIGHT 8 #define PADDLE_COLOR 191 // ball defines #define BALL_START_Y (SCREEN_HEIGHT/2) #define BALL_SIZE 4 // PROTOTYPES ///////////////////////////////////////////////// // game console int Game_Init(void *parms=NULL); int Game_Shutdown(void *parms=NULL); int Game_Main(void *parms=NULL); // GLOBALS //////////////////////////////////////////////////// HWND main_window_handle = NULL; // save the window handle HINSTANCE main_instance = NULL; // save the instance int game_state = GAME_STATE_INIT; // starting state int paddle_x = 0, paddle_y = 0; // tracks position of paddle int ball_x = 0, ball_y = 0; // tracks position of ball int ball_dx = 0, ball_dy = 0; // velocity of ball int score = 0; // the score int level = 1; // the current level int blocks_hit = 0; // tracks number of blocks hit // this contains the game grid data UCHAR blocks[NUM_BLOCK_ROWS][NUM_BLOCK_COLUMNS]; // FUNCTIONS ////////////////////////////////////////////////// LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // this is the main message handler of the system PAINTSTRUCT ps; // used in WM_PAINT HDC hdc; // handle to a device context // what is the message switch(msg) { case WM_CREATE: { // do initialization stuff here return(0); } break; case WM_PAINT: { // start painting hdc = BeginPaint(hwnd,&ps); // the window is now validated // end painting EndPaint(hwnd,&ps); return(0); } break; case WM_DESTROY: { // kill the application PostQuitMessage(0); return(0); } break; default:break; } // end switch // process any messages that we didn't take care of return (DefWindowProc(hwnd, msg, wparam, lparam)); } // end WinProc // WINMAIN //////////////////////////////////////////////////// int WINAPI WinMain( HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) { // this is the winmain function WNDCLASS winclass; // this will hold the class we create HWND hwnd; // generic window handle MSG msg; // generic message HDC hdc; // generic dc PAINTSTRUCT ps; // generic paintstruct // first fill in the window class stucture winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; winclass.lpfnWndProc = WindowProc; winclass.cbClsExtra = 0; winclass.cbWndExtra = 0; winclass.hInstance = hinstance; winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); winclass.hCursor = LoadCursor(NULL, IDC_ARROW); winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); winclass.lpszMenuName = NULL; winclass.lpszClassName = WINDOW_CLASS_NAME; // register the window class if (!RegisterClass(&winclass)) return(0); // create the window, note the use of WS_POPUP if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, // class "WIN3D Game Console", // title WS_POPUP | WS_VISIBLE, 0,0, // initial x,y GetSystemMetrics(SM_CXSCREEN), // intial width GetSystemMetrics(SM_CYSCREEN), // initial height NULL, // handle to parent NULL, // handle to menu hinstance,// instance NULL))) // creation parms return(0); // hide mouse ShowCursor(FALSE); // save the window handle and instance in a global main_window_handle = hwnd; main_instance = hinstance; // perform all game console specific initialization Game_Init(); // enter main event loop while(1) { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { // test if this is a quit if (msg.message == WM_QUIT) break; // translate any accelerator keys TranslateMessage(&msg); // send the message to the window proc DispatchMessage(&msg); } // end if // main game processing goes here Game_Main(); } // end while // shutdown game and release all resources Game_Shutdown(); // show mouse ShowCursor(TRUE); // return to Windows like this return(msg.wParam); } // end WinMain // T3DX GAME PROGRAMMING CONSOLE FUNCTIONS //////////////////// int Game_Init(void *parms) { // this function is where you do all the initialization // for your game // return success return(1); } // end Game_Init /////////////////////////////////////////////////////////////// int Game_Shutdown(void *parms) { // this function is where you shutdown your game and // release all resources that you allocated // return success return(1); } // end Game_Shutdown /////////////////////////////////////////////////////////////// void Init_Blocks(void) { // initialize the block field for (int row=0; row < NUM_BLOCK_ROWS; row++) for (int col=0; col < NUM_BLOCK_COLUMNS; col++) blocks[row][col] = row*16+col*3+16; } // end Init_Blocks /////////////////////////////////////////////////////////////// void Draw_Blocks(void) { // this function draws all the blocks in row major form int x1 = BLOCK_ORIGIN_X, // used to track current position y1 = BLOCK_ORIGIN_Y; // draw all the blocks for (int row=0; row < NUM_BLOCK_ROWS; row++) { // reset column position x1 = BLOCK_ORIGIN_X; // draw this row of blocks for (int col=0; col < NUM_BLOCK_COLUMNS; col++) { // draw next block (if there is one) if (blocks[row][col]!=0) { // draw block Draw_Rectangle(x1-4,y1+4, x1+BLOCK_WIDTH-4,y1+BLOCK_HEIGHT+4,0); Draw_Rectangle(x1,y1,x1+BLOCK_WIDTH, y1+BLOCK_HEIGHT,blocks[row][col]); } // end if // advance column position x1+=BLOCK_X_GAP; } // end for col // advance to next row position y1+=BLOCK_Y_GAP; } // end for row } // end Draw_Blocks /////////////////////////////////////////////////////////////// void Process_Ball(void) { // this function tests if the ball has hit a block or the paddle // if so, the ball is bounced and the block is removed from // the playfield note: very cheesy collision algorithm :) // first test for ball block collisions // the algorithm basically tests the ball against each // block's bounding box this is inefficient, but easy to // implement, later we'll see a better way int x1 = BLOCK_ORIGIN_X, // current rendering position y1 = BLOCK_ORIGIN_Y; int ball_cx = ball_x+(BALL_SIZE/2), // computer center of ball ball_cy = ball_y+(BALL_SIZE/2); // test of the ball has hit the paddle if (ball_y > (SCREEN_HEIGHT/2) && ball_dy > 0) { // extract leading edge of ball int x = ball_x+(BALL_SIZE/2); int y = ball_y+(BALL_SIZE/2); // test for collision with paddle if ((x >= paddle_x && x <= paddle_x+PADDLE_WIDTH) && (y >= paddle_y && y <= paddle_y+PADDLE_HEIGHT)) { // reflect ball ball_dy=-ball_dy; // push ball out of paddle since it made contact ball_y+=ball_dy; // add a little english to ball based on motion of paddle if (KEY_DOWN(VK_RIGHT)) ball_dx-=(rand()%3); else if (KEY_DOWN(VK_LEFT)) ball_dx+=(rand()%3); else ball_dx+=(-1+rand()%3); // test if there are no blocks, if so send a message // to game loop to start another level if (blocks_hit >= (NUM_BLOCK_ROWS*NUM_BLOCK_COLUMNS)) { game_state = GAME_STATE_START_LEVEL; level++; } // end if // make a little noise MessageBeep(MB_OK); // return return; } // end if } // end if // now scan thru all the blocks and see of ball hit blocks for (int row=0; row < NUM_BLOCK_ROWS; row++) { // reset column position x1 = BLOCK_ORIGIN_X; // scan this row of blocks for (int col=0; col < NUM_BLOCK_COLUMNS; col++) { // if there is a block here then test it against ball if (blocks[row][col]!=0) { // test ball against bounding box of block if ((ball_cx > x1) && (ball_cx < x1+BLOCK_WIDTH) && (ball_cy > y1) && (ball_cy < y1+BLOCK_HEIGHT)) { // remove the block blocks[row][col] = 0; // increment global block counter, so we know // when to start another level up blocks_hit++; // bounce the ball ball_dy=-ball_dy; // add a little english ball_dx+=(-1+rand()%3); // make a little noise MessageBeep(MB_OK); // add some points score+=5*(level+(abs(ball_dx))); // that's it -- no more block return; } // end if } // end if // advance column position x1+=BLOCK_X_GAP; } // end for col // advance to next row position y1+=BLOCK_Y_GAP; } // end for row } // end Process_Ball /////////////////////////////////////////////////////////////// int Game_Main(void *parms) { // this is the workhorse of your game it will be called // continuously in real-time this is like main() in C // all the calls for you game go here! char buffer[80]; // used to print text // what state is the game in? if (game_state == GAME_STATE_INIT) { // initialize everything here graphics DD_Init(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP); // seed the random number generator // so game is different each play srand(Start_Clock()); // set the paddle position here to the middle bottom paddle_x = PADDLE_START_X; paddle_y = PADDLE_START_Y; // set ball position and velocity ball_x = 8+rand()%(SCREEN_WIDTH-16); ball_y = BALL_START_Y; ball_dx = -4 + rand()%(8+1); ball_dy = 6 + rand()%2; // transition to start level state game_state = GAME_STATE_START_LEVEL; } // end if //////////////////////////////////////////////////////////////// else if (game_state == GAME_STATE_START_LEVEL) { // get a new level ready to run // initialize the blocks Init_Blocks(); // reset block counter blocks_hit = 0; // transition to run state game_state = GAME_STATE_RUN; } // end if /////////////////////////////////////////////////////////////// else if (game_state == GAME_STATE_RUN) { // start the timing clock Start_Clock(); // clear drawing surface for the next frame of animation Draw_Rectangle(0,0,SCREEN_WIDTH-1, SCREEN_HEIGHT-1,200); // move the paddle if (KEY_DOWN(VK_RIGHT)) { // move paddle to right paddle_x+=8; // make sure paddle doesn't go off screen if (paddle_x > (SCREEN_WIDTH-PADDLE_WIDTH)) paddle_x = SCREEN_WIDTH-PADDLE_WIDTH; } // end if else if (KEY_DOWN(VK_LEFT)) { // move paddle to right paddle_x-=8; // make sure paddle doesn't go off screen if (paddle_x < 0) paddle_x = 0; } // end if // draw blocks Draw_Blocks(); // move the ball ball_x+=ball_dx; ball_y+=ball_dy; // keep ball on screen, if the ball hits the edge of // screen then bounce it by reflecting its velocity if (ball_x > (SCREEN_WIDTH - BALL_SIZE) || ball_x < 0) { // reflect x-axis velocity ball_dx=-ball_dx; // update position ball_x+=ball_dx; } // end if // now y-axis if (ball_y < 0) { // reflect y-axis velocity ball_dy=-ball_dy; // update position ball_y+=ball_dy; } // end if else // penalize player for missing the ball if (ball_y > (SCREEN_HEIGHT - BALL_SIZE)) { // reflect y-axis velocity ball_dy=-ball_dy; // update position ball_y+=ball_dy; // minus the score score-=100; } // end if // next watch out for ball velocity getting out of hand if (ball_dx > 8) ball_dx = 8; else if (ball_dx < -8) ball_dx = -8; // test if ball hit any blocks or the paddle Process_Ball(); // draw the paddle and shadow Draw_Rectangle(paddle_x-8, paddle_y+8, paddle_x+PADDLE_WIDTH-8, paddle_y+PADDLE_HEIGHT+8,0); Draw_Rectangle(paddle_x, paddle_y, paddle_x+PADDLE_WIDTH, paddle_y+PADDLE_HEIGHT,PADDLE_COLOR); // draw the ball Draw_Rectangle(ball_x-4, ball_y+4, ball_x+BALL_SIZE-4, ball_y+BALL_SIZE+4, 0); Draw_Rectangle(ball_x, ball_y, ball_x+BALL_SIZE, ball_y+BALL_SIZE, 255); // draw the info sprintf(buffer,"F R E A K O U T Score %d Level %d",score,level); Draw_Text_GDI(buffer, 8,SCREEN_HEIGHT-16, 127); // flip the surfaces DD_Flip(); // sync to 33ish fps Wait_Clock(30); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE)) { // send message to windows to exit PostMessage(main_window_handle, WM_DESTROY,0,0); // set exit state game_state = GAME_STATE_SHUTDOWN; } // end if } // end if /////////////////////////////////////////////////////////////// else if (game_state == GAME_STATE_SHUTDOWN) { // in this state shut everything down and release resources DD_Shutdown(); // switch to exit state game_state = GAME_STATE_EXIT; } // end if // return success return(1); } // end Game_Main ///////////////////////////////////////////////////////////////
// BLACKBOX.H - Header file for demo game engine library // watch for multiple inclusions #ifndef BLACKBOX #define BLACKBOX // DEFINES //////////////////////////////////////////////////// // default screen size #define SCREEN_WIDTH 640 // size of screen #define SCREEN_HEIGHT 480 #define SCREEN_BPP 8 // bits per pixel #define MAX_COLORS 256 // maximum colors // MACROS ///////////////////////////////////////////////////// // these read the keyboard asynchronously #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) #define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1) // initializes a direct draw struct #define DD_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); } // TYPES ////////////////////////////////////////////////////// // basic unsigned types typedef unsigned short USHORT; typedef unsigned short WORD; typedef unsigned char UCHAR; typedef unsigned char BYTE; // EXTERNALS ////////////////////////////////////////////////// extern LPDIRECTDRAW4 lpdd; // dd object extern LPDIRECTDRAWSURFACE4 lpddsprimary; // dd primary surface extern LPDIRECTDRAWSURFACE4 lpddsback; // dd back surface extern LPDIRECTDRAWPALETTE lpddpal; // a pointer to the created dd palette extern LPDIRECTDRAWCLIPPER lpddclipper; // dd clipper extern PALETTEENTRY palette[256]; // color palette extern PALETTEENTRY save_palette[256]; // used to save palettes extern DDSURFACEDESC2 ddsd; // a direct draw surface description struct extern DDBLTFX ddbltfx; // used to fill extern DDSCAPS2 ddscaps; // a direct draw surface capabilities struct extern HRESULT ddrval; // result back from dd calls extern DWORD start_clock_count; // used for timing // these defined the general clipping rectangle extern int min_clip_x, // clipping rectangle max_clip_x, min_clip_y, max_clip_y; // these are overwritten globally by DD_Init() extern int screen_width, // width of screen screen_height, // height of screen screen_bpp; // bits per pixel // PROTOTYPES ///////////////////////////////////////////////// // DirectDraw functions int DD_Init(int width, int height, int bpp); int DD_Shutdown(void); LPDIRECTDRAWCLIPPER DD_Attach_Clipper(LPDIRECTDRAWSURFACE4 lpdds, int num_rects, LPRECT clip_list); int DD_Flip(void); int DD_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds,int color); // general utility functions DWORD Start_Clock(void); DWORD Get_Clock(void); DWORD Wait_Clock(DWORD count); // graphics functions int Draw_Rectangle(int x1, int y1, int x2, int y2, int color,LPDIRECTDRAWSURFACE4 lpdds=lpddsback); // gdi functions int Draw_Text_GDI(char *text, int x,int y,COLORREF color, LPDIRECTDRAWSURFACE4 lpdds=lpddsback); int Draw_Text_GDI(char *text, int x,int y,int color, LPDIRECTDRAWSURFACE4 lpdds=lpddsback); #endif
lainaus:
#include <ddraw.h> // directX includes
Onko sulla DirectX asennettuna?
Pitää asentaa DirectX SDK, joka tulee myös kirjan mukana. Sen jälkeen pitää laittaa kääntäjän hakupolut kohdalleen, eli:
tools > options > directories
sinne pitää lisätä "include files" kohtaan polku directx sdk:n INCLUDE -kansioon, ja "library files" kohtaan polku sdk:n kansioon LIB. ja siirrä ne molemmat nuolien avulla ensimmäiseksi riviksi.
(esim. c:\OHJELMATIEDOSTOT\DIRECTX7A SDK\DXF\INCLUDE)
tämä tarvii tehdä vain kerran, eli kun asentaa sdk:n, mutta seuraava on tehtävä joka projektille:
project > settings > link
"lisää object/library mobules" kohdassa olevan .lib listan perään ne directx-kirjastot joita käytät projektissa
(esim. ddraw.lib)
Eipä toimi vieläkään, mutta ajattelin, että ehkä hieman helpompaakin voisi yrittää kääntää:
http://koti.mbnet.fi/php-m/ongelma/
Kaiken järjen mukaan tässä ei pitäisi lisätä mitään .lib tiedostoja linkkeriin? Voisiko vika olla tietokoneessa? Sillä joskus apachea asentaessani tietokone valitti jotain odbc.dll ja odbc32.dll vikoja ja puuttumisia, ja jostain Visual C++:n valikosta olin näkevinäni nämä tiedostot. Tietokoneestani puuttuu mm. hh.exe joka on windowsin help tiedostojen lukemiseen.
Teitkö nyt siis Win32-console-projektin vai tavallisen Win32-projektin?
"Teitkö nyt siis Win32-console-projektin vai tavallisen Win32-projektin?" Hups, olin tehnyt vahingossa konsoli projektin. No nyt sentään se kääntyi, mutta freakout ei vieläkään...
Ootkos asentanu ne kaikki asetukset DirectX SDKoolle oikein, että mistä löytää kirjastotiedostot esim.
edit:
:-D Ilmeisesti kuvien perusteella ainaki
Kirjan CD:ltäkö DX-SDK:n asensit?
Jos ei siitä muuten olisi liikaa vaivaa, voisin mielelläni ottaa nuo kirjan kaikki esimerkit jos sattuu joskus tarvitsemaan (esim. sähköpostilla, löytyy profiilista).
lainaus:
Kirjan CD:ltäkö DX-SDK:n asensit?
Jos ei siitä muuten olisi liikaa vaivaa, voisin mielelläni ottaa nuo kirjan kaikki esimerkit jos sattuu joskus tarvitsemaan (esim. sähköpostilla, löytyy profiilista).
Ajattelin ladata tiedostot nettiin väliaikaisesti ja lähettää URL tänne, mutta tiedosto olisi 100 MT suuri (MBnet 50 MT rajoitus). Ja sähköpostini tukee vain >2mt tiedostoja...
Ehm.. siis pelkät esimerkit? Miten se nyt niin, vai sisältääkö grafiikatkin?
Esimerkit = Kirjan esimerkki koodit? No, voin yrittää karsia kaikki kuvat yms. jos sellaisia löytyy, mutta tuskin koko siitä paljon pienenee.
Aihe on jo aika vanha, joten et voi enää vastata siihen.