#define WIN32_LEAN_AND_MEAN
#define WORLDX 40
#define WORLDY 40
#define SCREENX 20
#define SCREENY 15
#define UP 0
#define RIGHT 1
#define DOWN 2
#define LEFT 3
#define KEYSTATE(key) ((GetAsyncKeyState(key) & 0x8000) ? TRUE : FALSE)
#include <stdio.h>
#include <windows.h>
#include <windowsx.h>
#include <ddraw.h>
class CCamera{
public:
int height;
int width;
int dx;
int dy;
int x,y;
int maxcamerax,maxcameray;
DWORD color;
CCamera();
void Move(int direction);
};
class CHero{
public:
int height;
int width;
int dx;
int dy;
int x,y;
int tilex,tiley;
CHero();
RECT location;
};
LPDIRECTDRAW lpDD=NULL;
LPDIRECTDRAWSURFACE lpPrimary=NULL;
LPDIRECTDRAWSURFACE lpBackBuffer=NULL;
LPDIRECTDRAWSURFACE lpSecondary=NULL;
LPDIRECTDRAWSURFACE lpHero=NULL;
LPDIRECTDRAWCLIPPER lpClipper=NULL;
HINSTANCE hInstance;
RECT src,dest;
DDBLTFX ddbltfx;
HDC hdc;
CCamera Camera;
CHero Smiley;
CHero NPC;
RECT Tiles[]={
{0,0,32,32},
{32,0,64,32},
{64,0,96,32}
};
int x=0,y=0,start_x,start_y,end_x,end_y;
//Originally just a fill box but now the class holds the camera coordinates
CCamera::CCamera(){
height=width=32;
x=y=320;
dx=dy=5;
maxcamerax=((WORLDX-SCREENX)*32)-4;
maxcameray=((WORLDY-SCREENY)*32)-4;
};
CHero::CHero(){
height=width=32;
tilex=2;
tiley=3;
x=32;y=10;
dx=dy=5;
SetRect(&location,(tilex*32),(tiley*32),(tilex*32)+width,(tiley*32)+height);
};
void CCamera::Move(int direction){
switch(direction){
case UP:
if(Camera.y>4)
Camera.y-=Camera.dy;
break;
case RIGHT:
if(Camera.x<maxcamerax)
Camera.x+=Camera.dx;
break;
case DOWN:
if(Camera.y<maxcameray)
Camera.y+=Camera.dy;
break;
case LEFT:
if(Camera.x>4)
Camera.x-=Camera.dx;
break;
}
};
// excluded map array
long CALLBACK WindowProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);
// excluded direct draw start up
// excluded bitmap load function
void Draw_Hero(){
if(Smiley.x<0)
Smiley.x=0;
if(Smiley.y<0)
Smiley.y=0;
if(Smiley.x>=(640-Smiley.width))
Smiley.x=(640-Smiley.width);
if(Smiley.y>=(480-Smiley.height))
Smiley.y=(480-Smiley.height);
SetRect(&Smiley.location,(Smiley.tilex*32),(Smiley.tiley*32),(Smiley.tilex*32)+32,(Smiley.tiley*32)+32);
SetRect(&src,0,0,32,32);
lpBackBuffer->Blt(&Smiley.location,lpHero,&src,DDBLT_WAIT|DDBLT_KEYSRC,NULL);
}
void UpdateFrame(){
SetRect(&dest,0,0,32,32);
int xstart=Camera.x >>5;
int ystart=Camera.y >>5;
int xend=xstart+21;
int yend=ystart+16;
int xoffset=Camera.x&0x01F;
int yoffset=Camera.y&0x01F;
if(!xoffset)
xend--;
else
dest.left-=xoffset;dest.right-=xoffset;
if(!yoffset)
yend--;
else
dest.top-=yoffset;dest.bottom-=yoffset;
for(int y=ystart;y<yend;y++){
for(int x=xstart;x<xend;x++){
int tile=map[y][x];
lpBackBuffer->Blt(&dest,lpSecondary,&Tiles[tile],DDBLT_WAIT,NULL);
dest.left+=32;dest.right+=32;
}
dest.top+=32;dest.bottom+=32;dest.left=0-xoffset;dest.right=32-xoffset;
}
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){
MSG msg;
HWND hwnd;
WNDCLASS wc;
wc.style= CS_HREDRAW|CS_VREDRAW;
wc.hInstance=hInstance;
wc.lpfnWndProc=WindowProc;
wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hCursor=LoadCursor(hInstance,IDC_ARROW);
wc.hIcon=LoadIcon(hInstance,IDI_APPLICATION);
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.lpszClassName="Window";
wc.lpszMenuName=NULL;
RegisterClass(&wc);
hwnd=CreateWindowEx(WS_EX_TOPMOST,"Window","Test",WS_POPUP,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,nShowCmd);
UpdateWindow(hwnd);
ShowCursor(FALSE);
if(FAILED(DirectDraw(hwnd)))
return FALSE;
if(FAILED(LoadImage(lpSecondary,"grass.bmp")))
return FALSE;
if(FAILED(LoadImage(lpHero,"sprite.bmp")))
return FALSE;
ddbltfx.dwSize=sizeof(DDBLTFX);
ddbltfx.dwFillColor=0;
while(TRUE){
DWORD dwStart=GetTickCount();
if(KEYSTATE(VK_UP))
Smiley.y-=Smiley.dy;
if(KEYSTATE(VK_ESCAPE))
PostQuitMessage(0);
if(KEYSTATE(VK_DOWN))
Smiley.y+=Smiley.dy;
if(KEYSTATE(VK_LEFT))
Smiley.x-=Smiley.dx;
if(KEYSTATE(VK_RIGHT))
Smiley.x+=Smiley.dx;
if(KEYSTATE(VK_UP) && Smiley.y<=120 && Camera.y>4)
{
Smiley.dy=0;
Camera.Move(UP);
}
else if(KEYSTATE(VK_DOWN) && Smiley.y>=360 && Camera.y<Camera.maxcameray)
{
Smiley.dy=0;
Camera.Move(DOWN);
}
else
{
Smiley.dy=5;
}
if(KEYSTATE(VK_LEFT) && Smiley.x<=120 && Camera.x>4)
{
Smiley.dx=0;
Camera.Move(LEFT);
}
else if(KEYSTATE(VK_RIGHT) && Smiley.x>=480 && Camera.x<Camera.maxcamerax)
{
Smiley.dx=0;
Camera.Move(RIGHT);
}
else
{;
Smiley.dx=5;
}
if(KEYSTATE(VK_ESCAPE))
{
PostQuitMessage(0);
}
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
if(msg.message == WM_QUIT){
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UpdateFrame();
Draw_Hero();
lpPrimary->Flip(NULL,DDFLIP_WAIT);
};
return msg.wParam;
};
long CALLBACK WindowProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){
PAINTSTRUCT ps;
switch(message){
case WM_ACTIVATEAPP:
break;
case WM_PAINT:
BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
break;
case WM_DESTROY:
if(lpDD!=NULL){
if(lpPrimary!=NULL){
if(lpBackBuffer!=NULL)
lpBackBuffer->Release();
if(lpClipper!=NULL)
lpClipper->Release();
if(lpSecondary!=NULL)
lpSecondary->Release();
if(lpHero!=NULL)
lpHero->Release();
lpPrimary->Release();
};
lpDD->Release();
lpBackBuffer=NULL;
lpClipper=NULL;
lpSecondary=NULL;
lpPrimary=NULL;
lpDD=NULL;
};
ShowCursor(TRUE);
PostQuitMessage(0);
break;
default:
break;
};
return DefWindowProc(hwnd,message,wParam,lParam);
};
Tracking object locations
You need to combine the camera x and y coordinates. That means, to get the position of the npc on the screen, you need to do this:
screen_x_position+npc_x_position
and the same thing for y.
That way, if the screen x position is 0, and the npc x position is 50, they''re drawn at x position 50. If the npc is still at 50 and the camera position is -25, the npc is drawn at 25.
Hope this clears things up...
-Arek the Absolute
screen_x_position+npc_x_position
and the same thing for y.
That way, if the screen x position is 0, and the npc x position is 50, they''re drawn at x position 50. If the npc is still at 50 and the camera position is -25, the npc is drawn at 25.
Hope this clears things up...
-Arek the Absolute
-Arek the Absolute"The full quartet is pirates, ninjas, zombies, and robots. Create a game which involves all four, and you risk being blinded by the sheer level of coolness involved." - Superpig
Normally you would anchor your camera to your hero, that way you are actually moving your hero not the camera itself. The same principle applies to your NPC''s, they have a position (fine coords) just like your hero. To get them to stay on screen when the hero is moving, move them by the same amount in the same direction.
,Jay
,Jay
Yes I do realize most games anchor the camera... but I want to try and give the player more freedom and be less restricted to grided movement. I do realize that using this will make coding more complicated but I have lots of time on my hands.
Also wouldn''t it be the camera coordinates are subtracted from the npc position? Because if the object resides at (400,50) and the camera was at (250,0) the npc wouldn''t be on the screen. The result would be (650,50) which is out of bounds of my set screen: (640,480,32). 250*32=8000 pixels and I believe that (400,50) would be within that range...
Also wouldn''t it be the camera coordinates are subtracted from the npc position? Because if the object resides at (400,50) and the camera was at (250,0) the npc wouldn''t be on the screen. The result would be (650,50) which is out of bounds of my set screen: (640,480,32). 250*32=8000 pixels and I believe that (400,50) would be within that range...
If you store your npc''s/heros position as fine coords then you get complete freedom of movment even when achoring the camera.
Thats why your draw routines use a tileX and offsetX.
(TileX*TileWidth)+OffsetX = Fine Coord X
What I meant by moving NPC''s with respect to your camera/hero is that if a NPC is at 100,100 and your camera at 0,0. If you then move your camera by 200 pixels right your npc move off the screen, if you add 200 pixels to your NPC it seems to stay in place (with respect to the viewport).
But yes, you need to draw your NPC by using NPCX-CameraX =ScreenX.
Your screen is basicly just a viewport (window) onto the world you are creating.
,Jay
Thats why your draw routines use a tileX and offsetX.
(TileX*TileWidth)+OffsetX = Fine Coord X
What I meant by moving NPC''s with respect to your camera/hero is that if a NPC is at 100,100 and your camera at 0,0. If you then move your camera by 200 pixels right your npc move off the screen, if you add 200 pixels to your NPC it seems to stay in place (with respect to the viewport).
But yes, you need to draw your NPC by using NPCX-CameraX =ScreenX.
Your screen is basicly just a viewport (window) onto the world you are creating.
,Jay
Despite my best efforts... I lost my tile engine code when my computer crashed a few days ago... Luckily I had posted it all above (and in another post) and I recoded it into my project, only there''s one problem.... for some reason it crawls... as if its hanging up somewhere in the code.... It didn''t do this before when I wrote it but there''s no changes... could I have some build-up in memory or ram from it causing it to slow the program down???? I really have no idea what''s up with it...
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement