niin, tulinpa tässä vaan ajatelleeks semmosta nopeus kysymystä peleihin liittyen.
joissain avaruusräiskintäpeleissä, saattaa olla jopa 20 vihollista ja 100 kutia, helposti, kerralla ilmassa, siis ruudussa. jos oon vähäkään perillä niin eikös jokaista vihollista ja kutia pidä testata törmäyksien varalta keskenään??? se tekis noin esim noilla 20 vihollista ja 100 kutia niin 100 * 20. eikös??
eli noin 2000 testiä, ennen jokaista ruudunpäivitystä?? eikö??? ja ruutua pitäis päivittää väh. 30 kertaa sekunnissa. ja mun päähän ei mahdu että kuinka, miten, milä ihmeen keinolla mikään prosessori voi tehdä sen niin nopeasti. vai käytetäänkö siihen jotain ihme supernopeaa kiihdytettyä directX algoritmiä/functiota? pliiskertokaa
joissain avaruusräiskintäpeleissä, saattaa olla jopa 20 vihollista ja 100 kutia, helposti, kerralla ilmassa, siis ruudussa. jos oon vähäkään perillä niin eikös jokaista vihollista ja kutia pidä testata törmäyksien varalta keskenään??? se tekis noin esim noilla 20 vihollista ja 100 kutia niin 100 * 20. eikös??
eli noin 2000 testiä, ennen jokaista ruudunpäivitystä?? eikö??? ja ruutua pitäis päivittää väh. 30 kertaa sekunnissa. ja mun päähän ei mahdu että kuinka, miten, milä ihmeen keinolla mikään prosessori voi tehdä sen niin nopeasti. vai käytetäänkö siihen jotain ihme supernopeaa kiihdytettyä directX algoritmiä/functiota? pliiskertokaa
Vastaukset 13
Vanhimmat
Ensin tehdään ja testataan ja SITTEN näytetään ...
kuinka?? täytyyhän testit tehdä vaikka järjestystä muutettais miten?? ja tottakaihan ensin testaillaan, sitten vasta piirretään kun ollaan saatu selville mikä örkki on elossa ja mikä ei ja mikä kuti on vielä ruudussa ja mikä ei. sitten vsata piirretään, sitten vasta. en missään vaiheessa edellisessä viestissäni maininnut tätä järjestystä?? en.
tuskin tarvitsee testata, eiköhän se onnistu sillä että luodin rata on lineaarinen -> unohdetaan ampumisen jälkeen
vihollinen if luoti osuu kuole else pompi ja ammu
so simple?
Ota huomioon että megahertsin prosessorilla suoritetaan jo miljoona kellojaksoa sekunnissa. Nykykoneilla puhutaan miljardeista.
Perusoperaatiot joita tuossa törmäyksen laskemisessa tarvitaan eivät vie kovin montaa kellojaksoa, joten noilla kappalemäärillä ei vielä kummoista optimointia vaadita.
no sepä hyvä. ja vielä tuohon "kudin rata on lineaarinen" juttuun että eihän se auta mitään koska se on vaan yks bittikartta jonka vasen yläkulma on pisteessä x1,y1 ja oikea alakkulma on x2, y2. joten vaikka rata ois kuinka lineaarinen, täytyy tietää myös y akselin koordinaatit....
yksi tapa on piirtää luodit ensin ja sitten piirtää alus pikseli kerralaan ja vaikka reunoilta tarkistaa jos alla oleva pikseli on tietyn värinen niin räjähdys.
ymmärtääksen menetelmä kulkee nimellä "Pixel-Collision"
jaa. haluun vaan sanoa että jos vihollisia on esim edes 10, jokasen koko on 64X64 - 256X256 piksleiä, niin niiden pikselipiksleiltä kirjottaminen veis prosessorin kellojaksoja ainaki parin vuoden edestä. AIVAN. LIIAN. HIDASTA! en siis haluu olla ilkee mutta niin asia vaan on.
Käsittelemme taulukoita ja osoitteita taulukoihin ja ... - emme kuvia emme liioin pikseleitä.
ei, mee emme käsittele taulukoita, vaan RECT structia, joka sisältää bittikartan vasemman yläkulman ja oikean alakulman koordinaatit.
taulukoita. Vai olisiko joku muuttunut sitten eilisen?
De Smett'in C'stä vääntämisen aloitin jo silloin kun vielä mitään ei ollut.
"C-kieli! Eihän sillä voi edes merkkijonoja kästellä"
-Visionääro Petteri Järvinebn -
no täytyyhän se uskoa jos kerran joku noin iso kiho sanoo!
;D
jos oot niin ammattilainen niin autas tässä:
//////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
//INCLUDES
#define WIN32_LEAN_AND_MEAN
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//DEFINES
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 8
#define MAX_COLORS 256
#define BITMAP_ID 0x4D42
#define SHIP_WIDTH 64
#define SHIP_HEIGHT 64
#define ENEMY1_WIDTH 64
#define ENEMY1_HEIGHT 64
#define ENEMY2_WIDTH 128
#define ENEMY2_HEIGHT 128
#define ENEMY3_WIDTH 256
#define ENEMY3_HEIGHT 256
#define FIRE_WIDTH 64
#define FIRE_HEIGHT 64
#define MAX_FIRE 10
#define MAX_ENEMIES 10
#define FIRE_SPEED 5
#define GAME_SPEED 10
#define ENEMY2AT 10000
#define ENEMY3AT 100000
#define WINDOW_CLASS_NAME "WINCLASS1"
//MACROS
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
#define INIT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct);}
//BASIC UNSIGNED STUFF
typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned char UCHAR;
typedef unsigned char BYTE;
///////////////////////////////////////////////////////////////////////////////////////////////////////
//DIRECTDRAW STUFF
LPDIRECTDRAW lpdd = NULL; // dd object
LPDIRECTDRAW4 lpdd4 = NULL; // dd4 object
LPDIRECTDRAWSURFACE4 lpddsprimary = NULL; // dd primary surface
LPDIRECTDRAWSURFACE4 lpddsback = NULL; // dd back surface
LPDIRECTDRAWSURFACE4 spaceship = NULL;
LPDIRECTDRAWPALETTE lpddpal = NULL; // a pointer to the created dd palette
LPDIRECTDRAWCLIPPER lpddclipper = NULL; // dd clipper
PALETTEENTRY palette[256]; // color palette
DDSURFACEDESC2 ddsd; // a direct draw surface description struct
DWORD start_clock_count = 0; // used for timing
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//TYPES
typedef struct FIRE_TAG
{
int fire_sx;
int fire_sy;
int fire_bx;
int fire_by;
bool fire_state;
} FIRE, *FIRE_PTR;
typedef struct ENEMY1_TAG
{
int enemy1_sx;
int enemy1_sy;
int enemy1_bx;
int enemy1_by;
int enemy1_speed;
bool enemy1_state;
} ENEMY1, *ENEMY1_PTR;
typedef struct ENEMY2_TAG
{
int enemy2_sx;
int enemy2_sy;
int enemy2_bx;
int enemy2_by;
int enemy2_speed;
bool enemy2_state;
} ENEMY2, *ENEMY2_PTR;
typedef struct ENEMY3_TAG
{
int enemy3_sx;
int enemy3_sy;
int enemy3_bx;
int enemy3_by;
int enemy3_speed;
bool enemy3_state;
} ENEMY3, *ENEMY3_PTR;
typedef struct SHIP_TAG
{
int ship_sx;
int ship_sy;
int ship_bx;
int ship_by;
bool ship_state;
int ship_speed;
} SHIP, *SHIP_PTR;
typedef struct BITMAP_FILE_TAG
{
BITMAPFILEHEADER bitmapfileheader; // this contains the bitmapfile header
BITMAPINFOHEADER bitmapinfoheader; // this is all the info including the palette
PALETTEENTRY palette[256]; // we will store the palette here
UCHAR *buffer; // this is a pointer to the data
} BITMAP_FILE, *BITMAP_FILE_PTR;
///////////////////////////////////////////////////////////////////////////////////////////////
//GLOBALS
HWND main_hwnd;
HINSTANCE main_hinstance;
HDC main_hdc;
RECT srcrect;
RECT destrect;
char buffer[60];
int fire_amount = 0;
int enemy_amount = 0;
int score = 0;
int enemy_direction = 0;
int enemy_direction_change = 0;
int fire_index = 0;
int enemy_index = 0;
SHIP ship;
FIRE fire[MAX_FIRE];
ENEMY1 enemy1[MAX_ENEMIES];
ENEMY2 enemy2[MAX_ENEMIES];
ENEMY3 enemy3[MAX_ENEMIES];
BITMAP_FILE bitmap;
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//PROTOTYPES
void Quit();
inline void CreateFire();
inline void MoveFire();
inline void CreateEnemy();
inline void MoveEnemy();
LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE4 lpdds, int num_rects, LPRECT clip_list);
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds,int color);
int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height);
int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename);
int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap);
int Game_Init();
int Game_Main();
int Game_Shutdown();
///////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////
//CREATEFIRE
inline void CreateFire()
{
if (KEYDOWN(VK_SPACE) && fire_amount < MAX_FIRE)
{
if (fire_index = 5)
fire_index = 0;
fire[fire_index].fire_state = 1;
fire[fire_index].fire_sx = ship.ship_sx;
fire[fire_index].fire_by = ship.ship_sy;
fire[fire_index].fire_bx = fire[fire_index].fire_sx + FIRE_WIDTH;
fire[fire_index].fire_sy = fire[fire_index].fire_by - FIRE_HEIGHT;
fire_amount++;
fire_index++;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
//MOVEFIRE
inline void MoveFire()
{
for (int i = 0; i < MAX_FIRE; i++)
{
if (fire[i].fire_state = 1)
{
fire[i].fire_sy-= FIRE_SPEED;
fire[i].fire_by-= FIRE_SPEED;
if (fire[i].fire_by < 0)
fire[i].fire_state = 0;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//CREATEENEMY
inline void CreateEnemy()
{
if (enemy_amount < MAX_ENEMIES)
{
if (score < ENEMY2AT)
{
enemy1[enemy_index].enemy1_state = 1;
enemy1[enemy_index].enemy1_speed = score / 2000 + 1;
enemy1[enemy_index].enemy1_bx = rand()% (SCREEN_WIDTH - ENEMY1_WIDTH);
enemy1[enemy_index].enemy1_by = 0;
enemy1[enemy_index].enemy1_sx = enemy1[enemy_index].enemy1_bx - ENEMY1_WIDTH;
enemy1[enemy_index].enemy1_sy = enemy1[enemy_index].enemy1_by - ENEMY1_HEIGHT;
}
if (score > ENEMY2AT && score < ENEMY3AT)
{
enemy2[enemy_index].enemy2_state = 1;
enemy2[enemy_index].enemy2_speed = score / 20000 + 1;
enemy2[enemy_index].enemy2_bx = rand()% (SCREEN_WIDTH - ENEMY2_WIDTH);
enemy2[enemy_index].enemy2_by = 0;
enemy2[enemy_index].enemy2_sx = enemy2[enemy_index].enemy2_bx - ENEMY2_WIDTH;
enemy2[enemy_index].enemy2_sy = enemy2[enemy_index].enemy2_by - ENEMY2_HEIGHT;
}
if (score > ENEMY3AT)
{
enemy3[enemy_index].enemy3_state = 1;
enemy3[enemy_index].enemy3_speed = score / 200000 + 1;
enemy3[enemy_index].enemy3_bx = rand()% (SCREEN_WIDTH - ENEMY3_WIDTH);
enemy3[enemy_index].enemy3_by = 0;
enemy3[enemy_index].enemy3_sx = enemy3[enemy_index].enemy3_bx - ENEMY3_WIDTH;
enemy3[enemy_index].enemy3_sy = enemy3[enemy_index].enemy3_by - ENEMY3_HEIGHT;
}
enemy_amount++;
enemy_index++;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//MOVEENEMY
inline void MoveEnemy()
{
if (enemy_amount > 0)
{
if (score < ENEMY2AT)
{
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemy1[i].enemy1_state = 1)
{
if (enemy_direction_change = 5)
enemy_direction = rand()% 2;
if (enemy_direction = 0)
enemy1[i].enemy1_sx-= enemy1[i].enemy1_speed;
enemy1[i].enemy1_bx = enemy1[i].enemy1_sx + ENEMY1_WIDTH;
enemy1[i].enemy1_by-= enemy1[i].enemy1_speed;
enemy1[1].enemy1_sy = enemy1[i].enemy1_by - ENEMY1_HEIGHT;
if (enemy1[i].enemy1_sy > SCREEN_HEIGHT || enemy1[i].enemy1_sx > SCREEN_WIDTH || enemy1[i].enemy1_bx < 0)
enemy1[i].enemy1_state = 0;
if (enemy1[i].enemy1_sy > ship.ship_by && enemy1[i].enemy1_by < ship.ship_sy &&
enemy1[i].enemy1_sx > ship.ship_bx && enemy1[i].enemy1_bx < ship.ship_sx) // HIT!!!!!!!!
enemy1[i].enemy1_state = 0;
}
}
}
if (score > ENEMY2AT && score < ENEMY3AT)
{
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemy2[i].enemy2_state = 1)
{
if (enemy_direction_change = 5)
enemy_direction = rand()% 2;
if (enemy_direction = 0)
enemy2[i].enemy2_sx-= enemy2[i].enemy2_speed;
enemy2[i].enemy2_bx = enemy2[i].enemy2_sx + ENEMY2_WIDTH;
enemy2[i].enemy2_by-= enemy2[i].enemy2_speed;
enemy2[1].enemy2_sy = enemy2[i].enemy2_by - ENEMY2_HEIGHT;
if (enemy2[i].enemy2_sy > SCREEN_HEIGHT || enemy2[i].enemy2_sx > SCREEN_WIDTH || enemy2[i].enemy2_bx < 0)
enemy2[i].enemy2_state = 0;
if (enemy2[i].enemy2_sy > ship.ship_by && enemy2[i].enemy2_by < ship.ship_sy &&
enemy2[i].enemy2_sx > ship.ship_bx && enemy2[i].enemy2_bx < ship.ship_sx) // HIT!!!!!!!!
enemy2[i].enemy2_state = 0;
}
}
}
if (score > ENEMY3AT)
{
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemy3[i].enemy3_state = 1)
{
if (enemy_direction_change = 5)
enemy_direction = rand()% 2;
if (enemy_direction = 0)
enemy3[i].enemy3_sx-= enemy3[i].enemy3_speed;
enemy3[i].enemy3_bx = enemy3[i].enemy3_sx + ENEMY3_WIDTH;
enemy3[i].enemy3_by-= enemy3[i].enemy3_speed;
enemy3[1].enemy3_sy = enemy3[i].enemy3_by - ENEMY3_HEIGHT;
if (enemy3[i].enemy3_sy > SCREEN_HEIGHT ||enemy3[i].enemy3_sx > SCREEN_WIDTH || enemy3[i].enemy3_bx < 0)
enemy3[i].enemy3_state = 0;
if (enemy3[i].enemy3_sy > ship.ship_by && enemy3[i].enemy3_by < ship.ship_sy &&
enemy3[i].enemy3_sx > ship.ship_bx && enemy3[i].enemy3_bx < ship.ship_sx) // HIT!!!!!!!!
enemy3[i].enemy3_state = 0;
}
}
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//DDRAW_ATTACH_CLIPPER
LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE4 lpdds,
int num_rects,
LPRECT clip_list)
{
// this function creates a clipper from the sent clip list and attaches
// it to the sent surface
int index; // looping var
LPDIRECTDRAWCLIPPER lpddclipper; // pointer to the newly created dd clipper
LPRGNDATA region_data; // pointer to the region data that contains
// the header and clip list
// first create the direct draw clipper
if (FAILED(lpdd4->CreateClipper(0,&lpddclipper,NULL)))
return(NULL);
// now create the clip list from the sent data
// first allocate memory for region data
region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT));
// now copy the rects into region data
memcpy(region_data->Buffer, clip_list, sizeof(RECT)*num_rects);
// set up fields of header
region_data->rdh.dwSize = sizeof(RGNDATAHEADER);
region_data->rdh.iType = RDH_RECTANGLES;
region_data->rdh.nCount = num_rects;
region_data->rdh.nRgnSize = num_rects*sizeof(RECT);
region_data->rdh.rcBound.left = 64000;
region_data->rdh.rcBound.top = 64000;
region_data->rdh.rcBound.right = -64000;
region_data->rdh.rcBound.bottom = -64000;
// find bounds of all clipping regions
for (index=0; indexrdh.rcBound.left)
region_data->rdh.rcBound.left = clip_list[index].left;
if (clip_list[index].right > region_data->rdh.rcBound.right)
region_data->rdh.rcBound.right = clip_list[index].right;
if (clip_list[index].top < region_data->rdh.rcBound.top)
region_data->rdh.rcBound.top = clip_list[index].top;
if (clip_list[index].bottom > region_data->rdh.rcBound.bottom)
region_data->rdh.rcBound.bottom = clip_list[index].bottom;
} // end for index
// now we have computed the bounding rectangle region and set up the data
// now let's set the clipping list
if (FAILED(lpddclipper->SetClipList(region_data, 0)))
{
// release memory and return error
free(region_data);
return(NULL);
} // end if
// now attach the clipper to the surface
if (FAILED(lpdds->SetClipper(lpddclipper)))
{
// release memory and return error
free(region_data);
return(NULL);
} // end if
// all is well, so release memory and send back the pointer to the new clipper
free(region_data);
return(lpddclipper);
} // end DDraw_Attach_Clipper
////////////////////////////////////////////////////////////////////////////////////////////////////////
//LOAD_BITMAP_FILE
int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
{
// this function opens a bitmap file and loads the data into bitmap
HFILE file_handle; // the file handle
int index; // looping index
UCHAR *temp_buffer = NULL; // used to convert 24 bit images to 16 bit
OFSTRUCT file_data; // the file data information
// open the file if it exists
if ((file_handle = OpenFile(filename, &file_data, OF_READ))==-1)
{
//error
sprintf(buffer, "%s", "error opening file");
Quit();
return(0);
}
// now load the bitmap file header
_lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));
// test if this is a bitmap file
if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
{
// close the file
_lclose(file_handle);
// return error
sprintf(buffer, "%s", "file is not a bitmap");
Quit();
return(0);
} // end if
// now we know this is a bitmap, so read in all the sections
// first the bitmap infoheader
// now load the bitmap file header
_lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));
// now load the color palette if there is one
if (bitmap->bitmapinfoheader.biBitCount == 8)
{
_lread(file_handle, &bitmap->palette,MAX_COLORS*sizeof(PALETTEENTRY));
// now set all the flags in the palette correctly and fix the reversed
// BGR RGBQUAD data format
for (index=0; index < MAX_COLORS; index++)
{
// reverse the red and green fields
int temp_color = bitmap->palette[index].peRed;
bitmap->palette[index].peRed = bitmap->palette[index].peBlue;
bitmap->palette[index].peBlue = temp_color;
// always set the flags word to this
bitmap->palette[index].peFlags = PC_NOCOLLAPSE;
} // end for index
} // end if
// finally the image data itself
_lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);
// now read in the image, if the image is 8 or 16 bit then simply read it
// but if its 24 bit then read it into a temporary area and then convert
// it to a 16 bit image
if (bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16 ||
bitmap->bitmapinfoheader.biBitCount==24)
{
// delete the last image if there was one
if (bitmap->buffer)
free(bitmap->buffer);
// allocate the memory for the image
if (!(bitmap->buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
{
// close the file
_lclose(file_handle);
// return error
sprintf(buffer, "%s", "error closing file");
Quit();
return(0);
} // end if
// now read it in
_lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);
} // end if
else
{
// serious problem
sprintf(buffer, "%s", "too bad...");
Quit();
return(0);
} // end else
#if 0
// write the file info out
printf("\nfilename:%s \nsize=%d \nwidth=%d \nheight=%d \nbitsperpixel=%d \ncolors=%d \nimpcolors=%d",
filename,
bitmap->bitmapinfoheader.biSizeImage,
bitmap->bitmapinfoheader.biWidth,
bitmap->bitmapinfoheader.biHeight,
bitmap->bitmapinfoheader.biBitCount,
bitmap->bitmapinfoheader.biClrUsed,
bitmap->bitmapinfoheader.biClrImportant);
#endif
// close the file
_lclose(file_handle);
// flip the bitmap
Flip_Bitmap(bitmap->buffer,
bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8),
bitmap->bitmapinfoheader.biHeight);
// return success
return(1);
} // end Load_Bitmap_File
/////////////////////////////////////////////////////////////////////////////////////////////
//UNLOAD_BITMAP_FILE
int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
{
// this function releases all memory associated with "bitmap"
if (bitmap->buffer)
{
// release memory
free(bitmap->buffer);
// reset pointer
bitmap->buffer = NULL;
} // end if
// return success
return(1);
} // end Unload_Bitmap_File
///////////////////////////////////////////////////////////////////////////////////////////////////////
//FLIP_BITMAP
int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height)
{
// this function is used to flip bottom-up .BMP images
UCHAR *buffer; // used to perform the image processing
int index; // looping index
// allocate the temporary buffer
if (!(buffer = (UCHAR *)malloc(bytes_per_line*height)))
return(0);
// copy image to work area
memcpy(buffer,image,bytes_per_line*height);
// flip vertically
for (index=0; index < height; index++)
memcpy(&image[((height-1) - index)*bytes_per_line],
&buffer[index*bytes_per_line], bytes_per_line);
// release the memory
free(buffer);
// return success
return(1);
} // end Flip_Bitmap
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//DDRAW_FILL_SURFACE
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds,int color)
{
DDBLTFX ddbltfx; // this contains the DDBLTFX structure
// clear out the structure and set the size field
INIT(ddbltfx);
// set the dwfillcolor field to the desired color
ddbltfx.dwFillColor = color;
// ready to blt to surface
lpdds->Blt(NULL, // ptr to dest rectangle
NULL, // ptr to source surface, NA
NULL, // ptr to source rectangle, NA
DDBLT_COLORFILL | DDBLT_WAIT, // fill and wait
&ddbltfx); // ptr to DDBLTFX structure
// return success
return(1);
} // end DDraw_Fill_Surface
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int Game_Main()
{
if (KEYDOWN(VK_LEFT) && ship.ship_sx > 0)
{
ship.ship_sx--;
ship.ship_bx--;
}
if (KEYDOWN(VK_RIGHT) && ship.ship_bx < SCREEN_WIDTH)
{
ship.ship_bx++;
ship.ship_sx++;
}
if (KEYDOWN(VK_UP) && ship.ship_sy > 0)
{
ship.ship_sy--;
ship.ship_by--;
}
if (KEYDOWN(VK_DOWN) && ship.ship_by < SCREEN_HEIGHT)
{
ship.ship_by++;
ship.ship_sy++;
}
if (KEYDOWN(VK_ESCAPE))
SendMessage(main_hwnd,WM_CLOSE,0,0);
CreateFire();
CreateEnemy();
MoveFire();
MoveEnemy();
destrect.bottom = ship.ship_by;
destrect.left = ship.ship_sx;
destrect.right = ship.ship_bx;
destrect.top = ship.ship_sy;
if (FAILED(lpddsback->Blt(&destrect, spaceship, &srcrect, (DDBLT_WAIT | DDBLT_KEYSRC), NULL)))
{
//error
sprintf(buffer, "%s", "blitter error");
Quit();
return(0);
}
while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));
{
//error
sprintf(buffer, "%s", "flip error");
Quit();
return(0);
}
enemy_direction_change++;
if (enemy_direction_change = 6)
enemy_direction_change = 0;
Sleep(GAME_SPEED);
return(1);
} // end Game_Main
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int Game_Init()
{
RECT cliprect;
cliprect.bottom = SCREEN_HEIGHT;
cliprect.left = 0;
cliprect.right = SCREEN_WIDTH;
cliprect.top = 0;
if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL)))
{
// error
sprintf(buffer, "%s", "error creating lpdd");
Quit();
return(0);
}
if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4, (LPVOID *)&lpdd4)))
{
// error
sprintf(buffer, "%s", "error querying lpdd4");
Quit();
return(0);
}
if (lpdd)
{
lpdd->Release();
lpdd = NULL;
}
if (FAILED(lpdd4->SetCooperativeLevel(main_hwnd, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
{
// error
sprintf(buffer, "%s", "error setting cooperative level");
Quit();
return(0);
}
if (FAILED(lpdd4->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 0, 0)))
{
// error
sprintf(buffer, "%s", "error setting dispaly mode");
Quit();
return(0);
}
INIT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
if (FAILED(lpdd4->CreateSurface(&ddsd, &lpddsprimary, NULL)))
{
//error
sprintf(buffer, "%s", "error creating primary surface");
Quit();
return(0);
}
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
{
//error
sprintf(buffer, "%s", "error getting attached surface backbuffer");
Quit();
return(0);
}
for (int i = 0; i < MAX_COLORS; i++)
{
palette[i].peRed = rand()%256;
palette[i].peGreen = rand()%256;
palette[i].peBlue = rand()%256;
palette[i].peFlags = PC_NOCOLLAPSE;
}
palette[0].peRed = 0;
palette[0].peGreen = 0;
palette[0].peBlue = 0;
palette[0].peFlags = PC_NOCOLLAPSE;
palette[255].peRed = 255;
palette[255].peGreen = 255;
palette[255].peBlue = 255;
palette[255].peFlags = PC_NOCOLLAPSE;
if (FAILED(lpdd4->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, palette, &lpddpal, NULL)))
{
//error
sprintf(buffer, "%s", "error creating palette");
Quit();
return(0);
}
if (!Load_Bitmap_File(&bitmap, "spaceship.bmp"))
{
//error
sprintf(buffer, "%s", "error loading bitmap");
Quit();
return(0);
}
// load it's palette into directdraw
if (FAILED(lpddpal->SetEntries(0, 0, MAX_COLORS, bitmap.palette)))
{
//error
sprintf(buffer, "%s", "error setting palette entries");
Quit();
return(0);
}
if (FAILED(lpddsprimary->SetPalette(lpddpal)))
{
//error
sprintf(buffer, "%s", "error setting palette");
Quit();
return(0);
}
INIT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CKSRCBLT;
ddsd.dwWidth = SHIP_WIDTH;
ddsd.dwHeight = SHIP_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
if (FAILED(lpdd4->CreateSurface(&ddsd, &spaceship, NULL)))
{
//error
sprintf(buffer, "%s", "error creating spaceship surface");
Quit();
return(0);
}
// copy the bitmap image to the primary buffer line by line
// note this is a good candidate operation to make into a function - hint!
// lock the primary surface
if (FAILED(spaceship->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL)))
{
//error
sprintf(buffer, "%s", "error locking spaceship");
Quit();
}
// get video pointer to primary surfce
UCHAR *primary_buffer = (UCHAR *)ddsd.lpSurface;
// test if memory is linear
if (ddsd.lPitch == SHIP_WIDTH)
memcpy((void *)primary_buffer, (void *)bitmap.buffer, SHIP_WIDTH*SHIP_HEIGHT);
else
{ // non-linear
// make copy of source and destination addresses
UCHAR *dest_ptr = primary_buffer;
UCHAR *src_ptr = bitmap.buffer;
// memory is non-linear, copy line by line
for (int y=0; y < SHIP_HEIGHT; y++)
{
// copy line
memcpy((void *)dest_ptr, (void *)src_ptr, SHIP_WIDTH);
// advance pointers to next line
dest_ptr+=ddsd.lPitch;
src_ptr +=SHIP_WIDTH;
} // end for
} // end else
// now unlock the primary surface
if (FAILED(spaceship->Unlock(NULL)))
{
//error
sprintf(buffer, "%s", "error unlocking spaceship");
Quit();
return(0);
}
// unload the bitmap file, we no longer need it
Unload_Bitmap_File(&bitmap);
ship.ship_by = SCREEN_HEIGHT;
ship.ship_sx = (SCREEN_WIDTH / 2) - (SHIP_WIDTH / 2);
ship.ship_bx = ship.ship_sx + SHIP_WIDTH;
ship.ship_sy = ship.ship_by - SHIP_HEIGHT;
srcrect.bottom = SHIP_HEIGHT;
srcrect.left = 0;
srcrect.right = SHIP_WIDTH;
srcrect.top = 0;
lpddclipper = DDraw_Attach_Clipper(lpddsback, 1, &cliprect);
if (lpddclipper)
{
//error
sprintf(buffer, "%s", "error setting clipper");
Quit();
return(0);
}
return(0);
} // end Game_Init
/////////////////////////////////////////////////////////////////////////////////////////////////////
int Game_Shutdown()
{
if (lpddclipper)
{
lpddclipper->Release();
lpddclipper = NULL;
}
if (lpddpal)
{
lpddpal->Release();
lpddpal = NULL;
}
if (spaceship)
{
spaceship->Release();
spaceship = NULL;
}
if (lpddsback)
{
lpddsback->Release();
lpddsback = NULL;
}
if (lpddsprimary)
{
lpddsprimary->Release();
lpddsprimary = NULL;
}
if (lpdd4)
{
lpdd4->Release();
lpdd4 = NULL;
}
return(1);
} // end Game_Shutdown
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
//WINDOW PROCEDURE
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 success
return(0);
} break;
case WM_PAINT:
{
// simply validate the window
main_hdc = hdc = BeginPaint(hwnd,&ps);
// end painting
EndPaint(hwnd,&ps);
// return success
return(0);
} break;
case WM_DESTROY:
{
// kill the application, this sends a WM_QUIT message
PostQuitMessage(0);
// return success
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)
{
WNDCLASSEX winclass; // this will hold the class we create
HWND hwnd; // generic window handle
MSG msg; // generic message
// first fill in the window class stucture
winclass.cbSize = sizeof(WNDCLASSEX);
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;
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// register the window class
if (!RegisterClassEx(&winclass))
{
//error
sprintf(buffer, "%s", "error registering windows class");
Quit();
return(0);
}
// create the window
if (!(hwnd = CreateWindowEx(NULL, // extended style
WINDOW_CLASS_NAME, // class
"SPACE COMBAT", // title
WS_POPUP | WS_VISIBLE,
0,0, // initial x,y
SCREEN_WIDTH,SCREEN_HEIGHT, // initial width, height
NULL, // handle to parent
NULL, // handle to menu
hinstance,// instance of this application
NULL))) // extra creation parms
{
//error
sprintf(buffer, "%s", "error creating window");
Quit();
return(0);
}
ShowCursor( FALSE );
main_hwnd = hwnd;
main_hinstance = hinstance;
Game_Init();
// enter main event loop
while(TRUE)
{
// test if there is a message in queue, if so get it
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
// closedown game here
Game_Shutdown();
ShowCursor( TRUE );
// return to Windows like this
return(msg.wParam);
} // end WinMain
/////////////////////////////////////////////////////////////////////////////////////////////
//QUIT
void Quit()
{
MessageBox(NULL, buffer,
"CRITICAL ERROR OCCURED",
MB_OK | MB_ICONEXCLAMATION);
}
///////////////////////////////////////////////////END OF CODE
mikä vika tuossa on??
se kyllä kääntyy mutta kun ajan sen niin tulee virheikkuna (joka ei ole mun tekemä) DEBUG ERROR
jossa lukee tuon ohjelman polku ja nimi ja sitte jotain tämmöstä:
DAMAGE: after normal block(#42) at 0x00910170
press retry to debug application
ja tässä kohti on ok nappi. ja minä en tiijä missä on vika koska kun pistää debuggerin päälle ja pääsee tiettyyn kohtaan se ei enää vastaa.
osaatko auttaa?? pliiiiiiiiiiiiiiiiiis
:D
Sanoisin, että MINÄ teen mitä haluan ja MUUT tekevät mitä osaavat.
en nyt pyydä suoranaisesti korjaamaan tuota virhettä, vaan edes kertomaan mistä se johtuu, tai miten sen voi korjata. vai etkö osaa ;D ??