Enviado em 06/10/2016 - 19:13h
Olá povo do VOL, como sou um pouco novo nesses trem de games tô aqui de novo para perguntar como funciona um sistema de mapa com tiles ,já procurei bastante no Groogre mas não conseguir encontrar nada que me esclarece-se ( Denovo :( ).
int map[15][20] = {
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
...
for ( int i = 0; i <= 15; i ++ ){
for ( int j = 0; j <= 20; j++ ){
if ( map[i][j] == 1 ){
. . . .
} else if ( map[i][j] == 0 ) {
. . . .
}
}
}
...
Enviado em 06/10/2016 - 21:07h
SDL_Rect destino;
for ( int i = 0; i <= 15; i ++ ){
for ( int j = 0; j <= 20; j++ )
if (mapa[i][j] == 1){
destino.x = j * tilesize;
destino.y = i * tilesize;
destino.w = tilesize;
destino.h = tilesize;
....agora aqui vem o código de desenhar na tela e jogar em 'destino'
}
}
SDL_Rect destino, fonte;
for ( int i = 0; i <= 15; i ++ ){
for ( int j = 0; j <= 20; j++ )
if (mapa[i][j] == 1){
//código antigo
destino.x = j * tilesize;
destino.y = i * tilesize;
destino.w = tilesize;
destino.h = tilesize;
//código novo
//veja que aqui são as coordenadas da imagem do tile na textura de tiles
fonte = (SDL_Rect){20,40,tilesize,tilesize};
//fiz numa linha só pra facilitar, mas até aqui você está familiarizado com esse tipo de coisa
//.. desenha-se normalmente o tile na tela
SDL_RenderCopy(renderer,texturaDeTiles, &fonte, &destino);
}
}
//compile com g++ testeColisao testeColisao.cpp -lm -lSDL2
#include <vector>
#include <cmath>
#include <SDL2/SDL.h>
//estrutura que representa um vetor matematico, usado para posicionar objetos
struct Vect
{
float x, y;
Vect (float _x=0, float _y=0)
{
x = _x;
y = _y;
}
};
struct Entidade
{
Vect posicao;
Vect vel; // velocidade da entidade/jogador/objeto do jogo
SDL_Rect retangulo;
std::vector<int> solidos;//aqui fica os tiles sólidos
Entidade ( int w, int h )
{
retangulo.x = retangulo.y = 0;
retangulo.w = w;
retangulo.h = h;
//somente um tile sólido e é o tile '1'
solidos.push_back(1);
}
// verifica se na posição 'p' do 'mapa' é um tile sólido
// retorna true caso sim e false caso não
bool ehSolido ( int mapa[15][20], int tilesize, Vect p )
{
//coordenadas de 'p' no 'mapa'
int x, y;
//converte de posição no espaço p.x para posição no mapa
x = int(p.x)/tilesize;
//converte de posição no espaço p.y para posição no mapa
y = int(p.y)/tilesize;
// só lembrando que a posição no mapa começa em zero
// se for negativo está fora do mapa
if (x < 0)
return false;
if (y < 0)
return false;
// se for maior que o mapa está fora do mapa
if (x >= 20)
return false;
if (y >= 15)
return false;
// se não está dentro do mapa,
// então basta verificar se o tile na posição x,y
// é um tile sólido, que está no vetor de tiles sólidos
for (unsigned i = 0; i < solidos.size(); i++)
if (mapa[y][x] == solidos.at(i))
return true;
// se não achou nenhum sólido na posição x,y...
return false;
}
// detecta colisão horizontal com o mapa
bool colisaoHorizontal ( int mapa[15][20], int tilesize )
{
//se não está movendo então não colide
if (vel.x == 0)
return false;
//se está movendo para direita
//para colisão à direita do jogador e à esquerda do tile
if (vel.x > 0)
{
Vect p;
//aqui eu não usarei o x e y do retangulo, mas apenas a posicao
//pega o canto direito superior do retangulo
p.x = posicao.x + retangulo.w;
p.y = posicao.y;
//observe que este é um ponto de colisão com o tile
//poderia ter vários outros pontos de colisão como um std::vector
//e então você verificaria colisão em todos eles
//mas por facilidade vou usar os 4 cantos do retangulo como
//pontos de colisão com os tiles
//Então verifica se é sólido (se colidiu)
if (ehSolido(mapa,tilesize,p))
{
//processa a colisão movendo o retangulo para fora do tile em 'p'
// só precisa mover ele na direção contrária à da velocidade
// então aqui move ele para esquerda
int x = (int(p.x)/tilesize)*tilesize;
//é assim, converte para posição no mapa int(p.x)/tilesize e depois
//reconverte para posição no mundo do jogo, só que numa posição onde tem um tile
//logo abaixo define a nova posição
posicao.x = p.x - retangulo.w + (x - int(p.x));
//subtrai retangulo.w de p.x pois senão fizer isso o jogador fica dentro do tile
//agora aqui vem o segredo, diminuir 1 de posicao.x e convertê-lo
posicao.x = floor(posicao.x) - 1;
//esse -1 evita que a entidade fique dentro do tile sólido e não posssa
//deslizar por ele, tipo caminhar sobre ele, e não ficar dentro do tile
//agora faz a velocidade x ser 0 para parar o movimento do jogador
vel.x = 0;
return true;
}
//senão continua verificando no lado direito do retangulo
//pega o canto direito inferior do retangulo
p.x = posicao.x + retangulo.w;
p.y = posicao.y + retangulo.h;
//Então verifica se é sólido (se colidiu)
if (ehSolido(mapa,tilesize,p))
{
// faz o mesmo de antes
int x = (int(p.x)/tilesize)*tilesize;
posicao.x = p.x - retangulo.w + (x - int(p.x));
posicao.x = floor(posicao.x) - 1;
vel.x = 0;
return true;
}
}
// para colisão à esquerda do jogador e a direita do tile
else
{
Vect p;
//pega o canto esquerdo superior
p.x = posicao.x;
p.y = posicao.y;
//Então verifica se é sólido (se colidiu)
if (ehSolido(mapa,tilesize,p))
{
// agora aqui o processo muda um pouco
// mesmo assim merece atenção, segue
int x = (int(p.x)/tilesize + 1)*tilesize;
//observe que aqui tem um +1 entre os parenteses
//ele serve para pegar o tile mais a direita da posicao.x
//pois em p.x está um tile sólido
//aqui vem a reposição do jogador, observe que removi apenas o retangulo.w
posicao.x = p.x + (x - int(p.x));
posicao.x = floor(posicao.x);
//zera a velocidade no eixo X
vel.x = 0;
return true;
}
//pega o canto esquerdo inferior
p.x = posicao.x;
p.y = posicao.y + retangulo.h;
//Então verifica se é sólido (se colidiu)
if (ehSolido(mapa,tilesize,p))
{
// agora aqui o processo do de cima
int x = (int(p.x)/tilesize + 1)*tilesize;
posicao.x = p.x + (x - int(p.x));
posicao.x = floor(posicao.x);
vel.x = 0;
return true;
}
}
return false;
}
bool colisaoVertical ( int mapa[15][20], int tilesize )
{
if (vel.y == 0)
return false;
// para colisão em baixo do jogador e em cima do tile
if (vel.y > 0)
{
Vect p;
//pega o canto esquerdo inferior
p.x = posicao.x;
p.y = posicao.y + retangulo.h;
//verifica se é sólido
if (ehSolido(mapa,tilesize,p))
{
//mesmo processo do colisaoHorizontal na parte vel.x > 0
//a diferença é que aqui é aplicado nno eixo vertical (Y)
int y = (int(p.y)/tilesize)*tilesize;
posicao.y = p.y - retangulo.h + (y - int(p.y));
posicao.y = floor(posicao.y) - 1;
vel.y = 0;
return true;
}
//pega o canto direito inferior
p.x = posicao.x + retangulo.w;
p.y = posicao.y + retangulo.h;
//verifica se é sólido
if (ehSolido(mapa,tilesize,p))
{
//mesmo processo acima
int y = (int(p.y)/tilesize)*tilesize;
posicao.y = p.y - retangulo.h + (y - int(p.y));
posicao.y = floor(posicao.y) - 1;
vel.y = 0;
return true;
}
}
// para colisão em cima do jogador e embaixo do tile
else
{
Vect p;
//pega o canto esquerdo superior
p.x = posicao.x;
p.y = posicao.y;
if (ehSolido(mapa,tilesize,p))
{
//mesmo processo do colsiaoHorizontal só que no eixo Y
int y = (int(p.y)/tilesize + 1)*tilesize;
posicao.y = p.y + (y - int(p.y));
posicao.y = floor(posicao.y);
vel.y = 0;
return true;
}
//pega o canto esquerdo superior
p.x = posicao.x + retangulo.w;
p.y = posicao.y;
if (ehSolido(mapa,tilesize,p))
{
//mesmo processo do colsiaoHorizontal só que no eixo Y
int y = (int(p.y)/tilesize + 1)*tilesize;
posicao.y = p.y + (y - int(p.y));
posicao.y = floor(posicao.y);
vel.y = 0;
return true;
}
}
return false;
}
void desenha ( SDL_Renderer * renderer, int r, int g, int b, int a=255 )
{
retangulo.x = int(posicao.x);
retangulo.y = int(posicao.y);
SDL_SetRenderDrawColor(renderer, r,g,b,a);
SDL_RenderFillRect(renderer, &retangulo);
}
};
int main ( int argc, char **argv )
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Event event;
SDL_Window * window = SDL_CreateWindow("Exemplo",0,0,640,480, SDL_WINDOW_SHOWN);
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
int tilesize = 32;
int mapa[15][20] =
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
0,1,1,1,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1,0,
0,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,
0,0,0,1,0,1,1,1,1,0,0,0,1,1,0,0,0,0,1,0,
0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,0,
1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
//A altura e largura do joagdor não pode ser maior que tilesize
//pois senão ele vai atravessar alguns tiles
//mas você pode adicionar mais alguns pontos de colisão a cada tilesize pixels
//na largura e altura
Entidade jogador(15,31);
int done = 0;
bool right = false, left = false, up = false, down = false;
while(!done)
{
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
done = 1;
if (event.type == SDL_KEYUP)
{
switch (event.key.keysym.sym)
{
case SDLK_RIGHT:
right = false;
break;
case SDLK_LEFT:
left = false;
break;
case SDLK_DOWN:
down = false;
break;
case SDLK_UP:
up = false;
break;
}
}
if (event.type == SDL_KEYDOWN)
{
switch (event.key.keysym.sym)
{
case SDLK_RIGHT:
right = true;
break;
case SDLK_LEFT:
left = true;
break;
case SDLK_DOWN:
down = true;
break;
case SDLK_UP:
up = true;
break;
}
}
}
//aqui o jogador move 5 pixels para esquerda ou direita, cima ou baixo
//ele não pode mover com velocidade maior que tilesize
//pois se fizer isso vai atravesar as paredes de tiles
if (right)
jogador.vel.x = 5;
else if (left)
jogador.vel.x = -5;
else
jogador.vel.x = 0;//faz parar em X
//primeiro move...
jogador.posicao.x += jogador.vel.x;
//depois colide horizontalmente
jogador.colisaoHorizontal(mapa,tilesize);
if (down)
jogador.vel.y = 5;
else if (up)
jogador.vel.y = -5;
else
jogador.vel.y = 0;
//primeiro move...
jogador.posicao.y += jogador.vel.y;
//depois colide verticalmente
jogador.colisaoVertical(mapa,tilesize);
//Observe que para a colisão de fato funcionar tem que mover
//o joagdor em um eixo por vez. Se mover nos dois eixos antes
//de colidir então dará erro, tente isso se quiser ver como é.
SDL_SetRenderDrawColor(renderer,128,128,128,255);
SDL_RenderClear(renderer);
for (int i = 0; i < 15; i++)
for (int j = 0; j < 20; j++)
if (mapa[i][j] == 1)
{
SDL_SetRenderDrawColor(renderer,0,255,0,255);
SDL_Rect tile = {j*tilesize,i*tilesize,tilesize,tilesize};
SDL_RenderFillRect(renderer, &tile);
}
jogador.desenha(renderer, 255,255,0,255);
SDL_RenderPresent(renderer);
SDL_Delay(60);
}
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0;
}
Enviado em 06/10/2016 - 23:51h
Obrigado por responder tão rápido o tópico cê é muito gente boa
SDL_Rect destino, fonte;
for ( int i = 0; i <= 15; i ++ ){
for ( int j = 0; j <= 20; j++ )
if (mapa[i][j] == 1){
//código antigo
destino.x = j * tilesize;
destino.y = i * tilesize;
destino.w = tilesize;
destino.h = tilesize;
//código novo
//veja que aqui são as coordenadas da imagem do tile na textura de tiles
fonte = (SDL_Rect){20,40,tilesize,tilesize};
//fiz numa linha só pra facilitar, mas até aqui você está familiarizado com esse tipo de coisa
//.. desenha-se normalmente o tile na tela
SDL_RenderCopy(renderer,texturaDeTiles, &fonte, &destino);
}
}
Asterisk - Configurando Ramais, Plano de Discagem e URA Simples
A Desinformação em Época da Tecnologia de Informação
O que você está ouvindo agora? (4641)
Referência não definida g++ (3)
[Tcl/Tk] Mostrar conexões de rede ativas
[Shell Script] Bashblog v3.0 - cria um microblog em HTML5
[Shell Script] Manutenção e limpeza do Linux
[Shell Script] ebook-cli - gerencia livros digitais entre PC e leitores ebooks
[Shell Script] AptList v1.1 - instalação de pacotes DEB a partir de uma lista