Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Problemas Con Mi Tile Engine

Iniciado por CurveX, 15 de Julio de 2005, 08:15:08 PM

« anterior - próximo »

CurveX

 hola. estube haciendo algo parecido a un tile engine =)
y tengo un problema: cuando muevo la camara algunos tiles parece que "saltan" siguiendo la camara  :blink: . Digo algunos porque los otros parece que se mueven bien.
bueno aqui esta el archivo .zip (.exe y la imagen de los tiles).
tile_engine.zip

y aqui esta el codigo:

main.cpp

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <stdio.h>
#include <ddraw.h>
#include "grafics_my.h"

HINSTANCE hMainInstance;
HWND hMainWindow;
UCHAR * bmpBuffer;
LPBYTE BMPBuffer;
int iMap[MAP_WIDTH][MAP_HEIGHT];
cTile * Tile;
int Camx, Camy;
LPDIRECTDRAW7 lpdd7;
LPDIRECTDRAWSURFACE7 lpddsPrimary;
LPDIRECTDRAWSURFACE7 lpddsBack;
LPDIRECTDRAWSURFACE7 lpddsBMP;
LPDIRECTDRAWCLIPPER lpddClipper;
DDSURFACEDESC2 ddsd;
DDBLTFX fx;
//local variables (used in this file (main.cpp))
float dwStart, TotTime;
int TotFrames;
char fpsBuf[5], PosBufx[9], PosBufy[9];
HDC hDc;
RECT rcText = {5, 5, 100, 20};
RECT rcPosBufx = {5, 20, 100, 40};
RECT rcPosBufy = {5, 40, 100, 60};
int WINAPI WinMain(HINSTANCE hinstance,
                    HINSTANCE hPrevInstance,
                    LPSTR     lpCmdLine,
                    int       nCmdShow)
{
   WNDCLASSEX winclass;
   HWND hwnd;          
   MSG msg;            
   int x;              
   
   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_WINLOGO);
   winclass.hCursor =       LoadCursor(NULL, IDC_ARROW);
   winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
   winclass.lpszMenuName =  NULL;
   winclass.lpszClassName = "COOL_G";  
   winclass.hIconSm =       LoadIcon(NULL, IDI_WINLOGO);
   if (!RegisterClassEx(&winclass))
       return(0);

   hwnd = CreateWindowEx(NULL, "COOL_G", "COOL_GAME",
                               WS_POPUP | WS_VISIBLE, CW_USEDEFAULT,
                               CW_USEDEFAULT, 800, 600, NULL, NULL,
                                hinstance, NULL);                                              
   hMainWindow = hwnd;
   hMainInstance = hinstance;

   hDc = GetDC(hMainWindow);
   if (Initialize() && Initialize_game())
   {
       while (TRUE)
       {  
             dwStart = GetTickCount();
             if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
             {
                 if (msg.message == WM_QUIT)
                 break;
                 TranslateMessage(&msg);
                 DispatchMessage(&msg);
             }
             
             /*----------------draw here---------------*/
             check_input();                      
             draw_all_the_stuff();
             TotTime += (GetTickCount() - dwStart);
             TotFrames++;
             
             if (TotTime >= 1000)
             {
                itoa(TotFrames, fpsBuf, sizeof(fpsBuf));
                TotTime = 0;
                TotFrames = 0;
             }
             DrawText(hDc, fpsBuf, strlen(fpsBuf), &rcText, DT_BOTTOM);
             itoa(Camx, PosBufx, sizeof(PosBufx));
             itoa(Camy, PosBufy, sizeof(PosBufy));
             DrawText(hDc, PosBufx, strlen(PosBufx), &rcPosBufx, DT_BOTTOM);
             DrawText(hDc, PosBufy, strlen(PosBufy), &rcPosBufy, DT_BOTTOM);
            /*--------------------draw ends-------------*/  
       }
   }
   else
       MessageBox(hMainWindow, "Initialization failed!", "Error", MB_OK | MB_ICONEXCLAMATION);
   
   Shutdown();
   
   return(msg.wParam);
}




grafics_my.h

#define INIT_DXSTRUCT(dxstruct) { ZeroMemory(&dxstruct, sizeof(dxstruct)); dxstruct.dwSize = sizeof(dxstruct); }
#define KEYSTATE(key) ((GetAsyncKeyState(key) & 0x8000) ? TRUE : FALSE)
#define RGB_32(r, g, b)  ((r << 16) | (g << 8) | (b))
#define FPS 60;
#define MAP_WIDTH 40
#define MAP_HEIGHT 30
#define TILE_WIDTH 32
#define TILE_HEIGHT 32
class cTile
{
  public:
     RECT Location;
     bool WalkOn;
     int AnimSpeed;
     DWORD Flags;
     cTile * Next;
     
     void AnimateTile();
};
     
extern HINSTANCE hMainInstance;
extern HWND hMainWindow;
extern UCHAR * bmpBuffer;
extern LPBYTE BMPBuffer;
extern cTile * Tile;
extern int iMap[MAP_WIDTH][MAP_HEIGHT];
extern int Camx, Camy;
extern LPDIRECTDRAW7 lpdd7;
extern LPDIRECTDRAWSURFACE7 lpddsPrimary;
extern LPDIRECTDRAWSURFACE7 lpddsBack;
extern LPDIRECTDRAWSURFACE7 lpddsBMP;
extern LPDIRECTDRAWCLIPPER lpddClipper;
extern DDSURFACEDESC2 ddsd;
extern DDBLTFX fx;
int Initialize(void);
int Initialize_game(void);
inline void PlotPixel32(int x, int y, UINT color, UINT *buffer, int nPitch);
void draw_all_the_stuff(void);
void Shutdown(void);
void check_input(void);
void RenderMap(void);
void InitMap(void);
void InitTile(void);
HRESULT DDCopyBitmap(IDirectDrawSurface7 *pdds, HBITMAP hbm, int dx, int dy);
IDirectDrawSurface7 * CreateOffScreenSurface(IDirectDraw7 *pdd, int dx, int dy);
IDirectDrawSurface7 * DDLoadBitmap(IDirectDraw7 *pdd, LPCSTR szBitmap);
LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);



grafics_my.cpp (saque las funciones de inicializacion de directx y de inicializacion del bmp)

#include <windows.h>
#include <stdio.h>
#include <ddraw.h>
#include "grafics_my.h"
void InitTile()
{
             
    int i;
    RECT TempRect;
   
    for (i=0;i<4;i++)
    {  
        SetRect(&TempRect, 0, i*TILE_HEIGHT, TILE_WIDTH, i*TILE_HEIGHT+TILE_HEIGHT);
        Tile[i].Location = TempRect;
    }
}
int Initialize_game(void)
{
   
   Tile = new cTile[4];
   //int * iMap;
   //iMap = new int[300][300];
   
   InitTile();
   InitMap();
   
   Camx = 0;
   Camy = 0;
   
   return(true);
}
void InitMap(void)
{
    int x, y;
    for (x=0;x<MAP_WIDTH;x++)
    {  
        for (y=0;y<MAP_HEIGHT;y++)
        {
            iMap[x][y] = 1;
        }
    }
   
    for (x=0;x<20;x++)
    {    
        iMap[x][5] = 0;
        iMap[x][7] = 0;
    }
   
    iMap[11][12] = 2;
    iMap[11][13] = 2;
    iMap[11][14] = 2;
   
    iMap[10][13] = 3;
    iMap[rand()%MAP_WIDTH][rand()%MAP_HEIGHT] = 3;
    iMap[rand()%MAP_WIDTH][rand()%MAP_HEIGHT] = 3;
}
void RenderMap(void)
{
    int x, y, xStart, xEnd, yStart, yEnd;
    RECT rcDest = {0, 0, TILE_WIDTH, TILE_HEIGHT};
    xStart = Camx / TILE_WIDTH;
    yStart = Camx / TILE_HEIGHT;
   
    xEnd = xStart + 25;
    yEnd = yStart + 19;
   
    if (!Camx % TILE_WIDTH)
       xEnd --;
    else
    {
        rcDest.left -= (Camx % TILE_WIDTH);
        rcDest.right -= (Camx % TILE_WIDTH);
    }
   
    if (!Camy % TILE_HEIGHT)
       yEnd --;
    else
    {
        rcDest.top -= (Camy % TILE_HEIGHT);
        rcDest.bottom -= (Camy % TILE_HEIGHT);
    }
   
    if (xEnd > MAP_WIDTH)
       xEnd = MAP_WIDTH;
    if (yEnd > MAP_HEIGHT)
       yEnd = MAP_HEIGHT;
       
       
    for (x=xStart;x<=xEnd;x++)
    {
        for (y=yStart;y<=yEnd;y++)
        {
 
            lpddsBack->Blt(&rcDest, lpddsBMP, &Tile[iMap[x][y]].Location, DDBLT_WAIT, NULL);
           
            rcDest.top += TILE_HEIGHT;
            rcDest.bottom += TILE_HEIGHT;
        }
       rcDest.left += TILE_WIDTH;
       rcDest.right += TILE_WIDTH;
       rcDest.bottom -= ((yEnd - yStart + 1) << 5);
       rcDest.top -= ((yEnd - yStart + 1) << 5);
    }
   
}
void Shutdown(void)
{
   if (lpddsPrimary)
   {
       // kill the primary surface!
       lpddsPrimary->Release();
       lpddsPrimary = NULL;
   }
   if (lpdd7)
   {
       // blow away DirectDraw!
       lpdd7->Release();
       lpdd7 = NULL;
   }
   // destroy the window!
   CloseWindow(hMainWindow);
   // assassinate COM! :)
   CoUninitialize();
}
void draw_all_the_stuff(void)
{
   
    //Tile.AnimateTile();
    RenderMap();
   
   lpddsPrimary->Flip(NULL, DDFLIP_WAIT);
}
void check_input(void)
{
    if(KEYSTATE(VK_LEFT))
    {
       if (Camx - 5 >= 0)
          Camx -= 5;
    }
    else if(KEYSTATE(VK_RIGHT))
    {
       if (Camx <= ((MAP_WIDTH-20)*40 - 5))
          Camx += 5;
    }    
    else if (KEYSTATE(VK_UP))
    {
       if (Camy - 5 >= 0)
          Camy -= 5;
    }
    else if (KEYSTATE(VK_DOWN))
    {
       if (Camy < ((MAP_HEIGHT-20)*40 - 5))
          Camy += 5;
    }
   
    else if(KEYSTATE(VK_ESCAPE))
    {
       PostQuitMessage(0);
    }
   
   
}
   
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg,
                           WPARAM wparam, LPARAM lparam)
{
   return(DefWindowProc(hwnd, msg, wparam, lparam));
}
   


bueno espero que me ayuden a resolver estas cosas "paranormales" =)

Pogacha

 No será que esta mal esto ->
Citar   xStart = Camx / TILE_WIDTH;
    yStart = Camx / TILE_HEIGHT;

O sea ... tendria que venir así:
Citar   xStart = Camx / TILE_WIDTH;
    yStart = Camy / TILE_HEIGHT;

Ademas esto como se come:
Citar   if (!Camx % TILE_WIDTH)
Sera
Citarif( (Camx% TILE_WIDTH) == 0 )
Pues me queda en duda como se interpretará.

Otra cosa que no entiendo, perdon que me metá, es por que tienes la variable location en cada tile, se supone que se usan tiles para poder ahorrar memoria, y al location calcularlo segun x, y  ( preferiblemente usar i, j)

Saludos

PD: como repito lo de "O sea ...", parezco personaje de animación flash!

CurveX

 Pogacha
jeje gracias,  yStart = Camx / TILE_HEIGHT; era por eso =) y como no lo he notado  :)

pues ahora funciona bien =).

if (!Camx % TILE_WIDTH)

esto es: si el resto de la division es 0 entonces realiza el if.

y location es una RECT que contiene los vertices del rectangulo del tile en la imagen (.bmp). No es el tile que aparece en la pantalla sino el que esta en la imagen osea tileset.

Pogacha

 
Citarif (!Camx % TILE_WIDTH)
Decia por que se presta a confucion, no es lo mismo (!Camx)%TW que (!(Cmax%TW)) ... no es recomendable dejar cosas que visualmente puedan confundir ...


Citary location es una RECT que contiene los vertices del rectangulo del tile en la imagen (.bmp). No es el tile que aparece en la pantalla sino el que esta en la imagen osea tileset.
Me di cuenta mas tarde ... toda la razon del mundo, malinterprete tu codigo ...

Saludos

tamat

 joder pogacha, qué de tiempo libre tienes para leerte todo eso...
Por un stratos menos tenso






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.