Vandal

¿Cómo funciona un videojuego?

Lugar: · 1 mensajes · Colección
Enviar mensajeAgregar amigoVer relación
#1  Enviado: 21:40 22/05/2019  Editado: 22:11 22/05/2019 (1 vez)

Hola gente.

Estoy metido en un proyecto y no encuentro información de cómo funciona un videojuego (el software) de los videojuegos comerciales. Alguien podría decirme como funcionan internamente o dónde puedo buscar?

Muchas gracias
eloras
Lugar: · 25 mensajes · Colección
Enviar mensajeAgregar amigoVer relación
#2  Enviado: 14:47 24/05/2019

¿Por qué te metes en un proyecto sobre un videojuego si no sabes ni por dónde empezar?
...
¿Cómo funciona un videojuego?
Es una pregunta demasiado general como para encontrar respuesta en un foro... No sé hacia donde lo quieres enfocar, pero para saber algo de cualquier tema tienes que estudiar, sí o sí...
Para saber cómo funcionan internamente (motores, apartado gráfico, etc) debes tener formación en informática y empezar sabiendo cómo funciona un ordenador, bases de datos y un largo etc...

Como diría el gran José Mota: "Manolete, ¡si no sabes torear pa qué te metes!"
Lugar: · 1651 mensajes · Colección
Xbox LiveEnviar mensajeAgregar amigoVer relación
#3  Enviado: 16:40 24/05/2019

Normalmente, lo metes en la consola/pc y juegas, aunque últimamente tienes que descargar primero 2mil parches.
Lugar: · 164 mensajes · Colección
Enviar mensajeAgregar amigoVer relación
#4  Enviado: 20:16 27/05/2019  Editado: 20:35 27/05/2019 (4 veces)

mira, un juego como siempre se han hecho (programacion) se hace normalmente en un lenguaje de programacion (el mas usado siempre ha sido el C/C++ pero puede ser Pascal, Visual Basic o algun otro que te guste mas ....personalmente te recomiendo el C/C++ pero hay que estudiar y practicar bastante para lograr resultados buenos)

Codeas el Codigo fuente, normalmente Funciones y una Funcion principal que es donde empieza el programa y vas creando un bucle de dibujado continuo.....donde vas dibujando cada FRAME grafico y proyectandolos en pantalla en plan animacion..... luego el juego en si, lleva algunas funciones de calculo de posiciones de elementos del jugador o enemigos, colisiones, scrolls de pantalla, explosiones, transiciones de pantalla, efectos graficos o animaciones AVI que todo son funciones que realizan una o varias tareas en cascada y simplemente modifican cosas del buffer grafico primario (pantalla) y luego tambien, la propia logica de funcionamiento del juego, captura de teclado o joystick, etc etc....despues tambien cosas tecnicas como por ejemplo ingeniartelas para poder GUARDAR y CARGAR PARTIDAS recuperando el status de juego que habia cuando la guardaste la partida etc..... el tema de multijugador online es para echarle de comer aparte ya que requiere tecnicas de programacion avanzadas como programacion Cliente/Servidor, Peticiones HTTP o programacion de Sockets

yo estoy escribiendo un libro de como estoy programando Stardust en RAD Studio 10.3 RIO

solo como ejemplo de codigo, esto es un trocito de stardust:


// limpia la pantalla pintando el FONDO como background

TABLERO->Canvas->Brush->Color = clBlack;
TABLERO->Picture->LoadFromFile(".\\gfx\\fondo_interface2.bmp");
//TABLERO->Canvas->Draw(0, 0, Fondo->Picture->Graphic);

  /* try {
  int cont = FIELD_ACTUAL;
for (int y = 0; y < 15; ++y)
 {
for (int x = 0; x < 12; ++x)
{

 celda[x][y].rect = UNIVERSE[cont].celda[x][y].rect;
 celda[x][y].flag = UNIVERSE[cont].celda[x][y].flag;
 celda[x][y].icon = UNIVERSE[cont].celda[x][y].icon;
 celda[x][y].owner = UNIVERSE[cont].celda[x][y].owner;
 celda[x][y].energy_level = UNIVERSE[cont].celda[x][y].energy_level;
 celda[x][y].faction = UNIVERSE[cont].celda[x][y].faction;
 celda[x][y].cargo[0] = UNIVERSE[cont].celda[x][y].cargo[0];
}
 }
} catch (...) {
ShowMessage("Error COPYING celda structure to screen!! Exitting Program");
Form1->Close();
 }   */

for (int y = 0; y < 15; ++y)
{
for (int x = 0; x < 12; ++x)
{

TPoint pos = PosPt(x, y);
/* --> */   celda[x][y].rect = TRect(pos.x, pos.y, pos.x + hexbitmap1->Width, pos.y + hexbitmap1->Height);
//celda[x][y].flag = false;

if(color == 1) TABLERO->Canvas->Draw(pos.x, pos.y, hexbitmap1->Picture->Graphic);
else if(color == 2) TABLERO->Canvas->Draw(pos.x, pos.y, Image20->Picture->Graphic);

if(y%2 == 0) TABLERO->Canvas->Draw(pos.x, pos.y, small_hex_orange->Picture->Graphic);

switch(celda[x][y].icon)
{
case 0:
 // THIS MEANS THE CELL IS EMPTY
 //TABLERO->Canvas->Draw(pos.x, pos.y, Image14->Picture->Graphic);
 break;
case 1:
 TABLERO->Canvas->Draw(pos.x, pos.y, Image1->Picture->Graphic);  break;
case 2:
 TABLERO->Canvas->Draw(pos.x, pos.y, Image2->Picture->Graphic);  break;
case 3:
 TABLERO->Canvas->Draw(pos.x, pos.y, Image3->Picture->Graphic);  break;
case 4:
 TABLERO->Canvas->Draw(pos.x, pos.y, Image4->Picture->Graphic);  break;
case 5:
 TABLERO->Canvas->Draw(pos.x, pos.y, Image5->Picture->Graphic);  break;
case 6:
 TABLERO->Canvas->Draw(pos.x, pos.y, Image6->Picture->Graphic);  break;
case 7:
 TABLERO->Canvas->Draw(pos.x, pos.y, Image7->Picture->Graphic);  break;

case 8:
 TABLERO->Canvas->Draw(pos.x, pos.y, Image8->Picture->Graphic);  break;
case 9:
 TABLERO->Canvas->Draw(pos.x, pos.y, Image9->Picture->Graphic);  break;
case 10:
 TABLERO->Canvas->Draw(pos.x, pos.y, Image10->Picture->Graphic); break;
case 11:
 TABLERO->Canvas->Draw(pos.x, pos.y, Image11->Picture->Graphic); break;
case 12:
 TABLERO->Canvas->Draw(pos.x, pos.y, Image12->Picture->Graphic); break;
case 13:
 TABLERO->Canvas->Draw(pos.x, pos.y, Image13->Picture->Graphic); break;
case 14:
 TABLERO->Canvas->Draw(pos.x, pos.y, hex_small_friend->Picture->Graphic); break;
case 15:
 TABLERO->Canvas->Draw(pos.x, pos.y, hex_small_sp->Picture->Graphic); break;
case 16:
 TABLERO->Canvas->Draw(pos.x, pos.y, Image_black_hole->Picture->Graphic); break;
case 17:
 TABLERO->Canvas->Draw(pos.x, pos.y, hex_space_station->Picture->Graphic); break;
case 18:
 TABLERO->Canvas->Draw(pos.x, pos.y, hex_lambda->Picture->Graphic); break;

}

if(x == CELLSEL.x && y == CELLSEL.y)
{
celda[CELLSEL.x][CELLSEL.y].rect = TRect(pos.x, pos.y, pos.x + hexbitmap1->Width, pos.y + hexbitmap1->Height);
TABLERO->Canvas->Draw(pos.x, pos.y, CELLLSEL->Picture->Graphic);
             }

if(celda[x][y].owner == 7 && celda[x][y].icon == 0)
{
  celda[x][y].owner = 0;
}

if(celda[x][y].owner == 7)  //owner = 7 es el PC (IA)
{

  TABLERO->Canvas->Draw(pos.x + 10, pos.y, small_IA_ICON->Picture->Graphic);
  TABLERO->Canvas->Draw(pos.x+10, pos.y+10, box_mini->Picture->Graphic);
  if(celda[x][y].energy_level > 200) TABLERO->Canvas->Draw(pos.x+10, pos.y + 10, energia_full->Picture->Graphic);
  else if(celda[x][y].energy_level > 100 && celda[x][y].energy_level < 200) TABLERO->Canvas->Draw(pos.x+10, pos.y + 10, energia_medium->Picture->Graphic);
  else if(celda[x][y].energy_level <= 100) TABLERO->Canvas->Draw(pos.x+10, pos.y + 10, energia_low->Picture->Graphic);

  switch(celda[x][y].faction)
  {

case 1:
 if(celda[x][y].icon > 1 && celda[x][y].icon < 12)
 {
TABLERO->Canvas->Draw(pos.x +30, pos.y, small_boxie1->Picture->Graphic);
 }
  break;
case 2:
 if(celda[x][y].icon > 1 && celda[x][y].icon < 12)
 {
TABLERO->Canvas->Draw(pos.x +30, pos.y, small_boxie2->Picture->Graphic);
 }
  break;
case 3:
 if(celda[x][y].icon > 1 && celda[x][y].icon < 12)
 {
TABLERO->Canvas->Draw(pos.x +30, pos.y, small_boxie3->Picture->Graphic);
 }
  break;
case 4:
 if(celda[x][y].icon > 1 && celda[x][y].icon < 12)
 {
TABLERO->Canvas->Draw(pos.x +30, pos.y, small_boxie4->Picture->Graphic);
 }
  break;
case 5:
 if(celda[x][y].icon > 1 && celda[x][y].icon < 12)
 {
TABLERO->Canvas->Draw(pos.x +30, pos.y, small_boxie5->Picture->Graphic);
 }
  break;
case 6:
 if(celda[x][y].icon > 1 && celda[x][y].icon < 12)
 {
TABLERO->Canvas->Draw(pos.x +30, pos.y, small_boxie6->Picture->Graphic);
 }
  break;
case 7:
 if(celda[x][y].icon > 1 && celda[x][y].icon < 12)
 {
TABLERO->Canvas->Draw(pos.x +30, pos.y, small_boxie7->Picture->Graphic);
 }
  break;

  }

}

}
}

 if(my_position == true)
  {
  TPoint pos = PosPt(CELLSEL.x, CELLSEL.y);
  TABLERO->Canvas->Draw(pos.x - 200, pos.y, hex_youarehere->Picture->Graphic);
  }

   if(enable_panel_details_ship == True)
{

 TPoint pos = PosPt(CELLSEL.x, CELLSEL.y);
 celda[CELLSEL.x][CELLSEL.y].rect = TRect(pos.x, pos.y, pos.x + hexbitmap1->Width, pos.y + hexbitmap1->Height);

 if(CELLSEL.x >=8)
 {
if(CELLSEL.y == 14)
{ TABLERO->Canvas->Draw(pos.x -335, pos.y-130, panel_details_ship->Picture->Graphic);
  Label6->Left = pos.x - 335 + 190;
  Label6->Top = pos.y - 130 + 40;
  Label6->Visible = true;
  Label7->Left = pos.x - 335 + 200;
  Label7->Top = pos.y - 130 + 65;
  Label7->Visible = true;
 }
if(CELLSEL.y == 13)
{ TABLERO->Canvas->Draw(pos.x -335, pos.y-130, panel_details_ship->Picture->Graphic);
  Label6->Left = pos.x - 335 + 190;
  Label6->Top = pos.y - 130 + 40;
  Label6->Visible = true;
  Label7->Left = pos.x - 335 + 200;
  Label7->Top = pos.y - 130 + 65;
  Label7->Visible = true;
}
if(CELLSEL.y < 13)
{ TABLERO->Canvas->Draw(pos.x -335, pos.y, panel_details_ship->Picture->Graphic);
  Label6->Left = pos.x - 335 + 190;
  Label6->Top = pos.y + 40;
  Label6->Visible = true;
  Label7->Left = pos.x - 335 + 200;
  Label7->Top = pos.y + 65;
  Label7->Visible = true;
}
 }

 if(CELLSEL.x <8)
 {
if(CELLSEL.y == 14)
{ TABLERO->Canvas->Draw(pos.x +70, pos.y-130, panel_details_ship->Picture->Graphic);
  Label6->Left = pos.x  + 70 + 190;
  Label6->Top = pos.y - 130 + 40;
  Label6->Visible = true;
  Label7->Left = pos.x + 70 + 200;
  Label7->Top = pos.y - 130 + 65;
  Label7->Visible = true;
}
if(CELLSEL.y == 13)
{
TABLERO->Canvas->Draw(pos.x +70, pos.y-130, panel_details_ship->Picture->Graphic);
  Label6->Left = pos.x +70 + 190;
  Label6->Top = pos.y - 130 + 40;
  Label6->Visible = true;
  Label7->Left = pos.x + 70 + 200;
  Label7->Top = pos.y - 130 + 65;
  Label7->Visible = true;
}
if(CELLSEL.y < 13)
{ TABLERO->Canvas->Draw(pos.x + 70, pos.y, panel_details_ship->Picture->Graphic);
  Label6->Left = pos.x + 70 + 190;
  Label6->Top = pos.y + 40;
  Label6->Visible = true;
  Label7->Left = pos.x + 70 + 200;
  Label7->Top = pos.y + 65;
  Label7->Visible = true;
}
 }

 if(celda[CELLSEL.x][CELLSEL.y].cargo[0] == 0) Label6->Caption = "";
 if(celda[CELLSEL.x][CELLSEL.y].cargo[0] == 1) Label6->Caption = "Mineral (Gold)";

}

else {
 Label6->Visible = false;
 Label7->Visible = false;

               }

}
//---------------------------------------------------------------------------

void JUEGA_IA(void)
{
 Form1->TURN_ICON->Canvas->Draw(0,0, Form1->PCTURN->Picture->Graphic);
 Form1->TURN_ICON->Refresh();
 Form1->Timer4->Enabled = true;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
 stream=BASS_StreamCreateFile(FALSE,".\\music\\LuisJuniorOneDay.mp3",0,0,0);
 reproduciendo = BASS_StreamPlay(stream, false, BASS_SAMPLE_LOOP);
 BASS_SetVolume(100);

 Button1->Enabled = False;

// Cambia el volumen del stream al volumen actual
//trkbVolumen->Position = 0;
//trkbVolumenChange(this);

 if(MyConnection1->Connected == true)
 {
Image_serverconnect->Transparent = false;
Image_serverconnect->Picture->LoadFromFile(".\\gfx\\GREEN.bmp");
Image_serverconnect->Transparent = true;
ShowMessage("You're NOW CONNECTED to Qualinost Studio SERVER");
sButton5->Caption = "Disconnect";
sButton5->Refresh();
Form1->MyTable1->Close();
Form1->MyQuery1->SQL->Clear();
Form1->MyQuery1->SQL->Add("SELECT *");
Form1->MyQuery1->SQL->Add("FROM object_list");
Form1->MyTable1->TableName = "object_list";
Form1->MyTable1->Open();
//MyQuery1->ExecSQL();
 }


y lo que se ve en pantalla es esto:



pero te advierto que yo llevo desde que era un crio ya aprendiendo programacion

y luego estan motores como Unity o Unreal que obvian toda esta programacion que te he puesto ya que el propio motor lleva integrado todo para que el tema de juegos en Unity etc, sea poco mas que diseño visual del juego
edulord
Lugar: · 218 mensajes · Colección
BlogEnviar mensajeAgregar amigoVer relación
#5  Enviado: 12:08 28/05/2019

De forma terriblemente simplificada porque es un tema denso como pocos:

La principal diferencia de un videojuego respecto a otros tipos de software reside en su necesidad de dibujar la pantalla constantemente a una frecuencia altísima y, a poder ser, constante. En contraposición con otros tipos de software que muestran una pantalla estática hasta que algún evento desencadena algún cambio visual en esta.

Para lograr lo dicho, la mayor parte de motores y apis de programación manejan dos conceptos: funciones UPDATE y funciones DRAW.

- Las funciones Update son las que se encargan de actualizar la lógica del juego. Estas funciones procuran tener una frecuencia constante (30 llamadas por segundo, por ejemplo). Así, por ejemplo, en un juego de plataformas en el que el personaje se estuviera moviendo de derecha a izquierda, esta función tendría que saber cuánto tiempo ha pasado entre la llamada anterior y la actual (si son 30 veces por segundo, se intenta que sea 1/30 s) y desplazar al personaje la cantidad necesaria (s = s0 + v0*t).

- Las funciones Draw son las que se encargan de borrar la pantalla y generar un nuevo frame (redibujar la pantalla) según el estado de la lógica (en el ejemplo anterior, dibujar el frame con el personaje en la posición que el método Update calculó). Aunque idealmente estas funciones también deberían ser llamadas a una frecuencia constante, en la práctica son las que más varían su tiempo de ejecución (no es lo mismo colorear un pixel que renderizar un complejísimo modelo con millones de polígonos).

Al margen de esa organización del bucle de ejecución más o menos estándar, y tal vez también cómo organizar los inputs del usuario, a nivel puramente técnico no hay diferencias con respecto otro tipo de software.

Por último, puntualizar el comentario de Alpinador, en motores comerciales tipo Unity o Unreal, el código que describe la lógica y funcionamiento del juego lo escribes igual, el motor se encarga de automatizar y organizar un BILLÓN de cosas que es muy engorroso hacer a mano, pero programar el juego lo tienes que hacer de todas formas.

Saludos y te animo a que visites mi diario de desarrollo de un juego en
https://www.gamedev.net/blogs/blog/3679-virgil-alpha-development/
donde describo los pasos lógicos (e implementación) para construir un juego de moderada complejidad desde cero.
La pasión o emoción mostrada en una discursión es inversamente proporcional a la cantidad de información real disponible
Lugar: · 164 mensajes · Colección
Enviar mensajeAgregar amigoVer relación
#6  Enviado: 09:13 29/05/2019  Editado: 09:23 29/05/2019 (2 veces)

Darkseer1:

Luego tambien al programar el juego tienes que tener en cuenta algunas cosas que pueden suceder y dar al traste con la ejecucion del programa en cualquier momento....por ejemplo tienes que comprobar y tener cubierto el tema de "bounds" o limites de la pantalla o mapeado...para que el personaje o lo que sea no se salga fuera de los limites establecidos.....tambien cosas como por ejemplo llevar un control exhaustivo de lo que cargas en memoria en todo momento porque no puedes simplemente ir cargando cosas en la RAM y olvidarte de ellas.....en un programa dependiendo del nivel de juego o lo que sea se van descargando y cargando cosas en tiempo real.....o cosas como por ejemplo que vayas a escribir en un array de por ejemplo [5] elementos y escribas un posible elemento [6] que al no existir generaria un error o excepcion no controlada....son cosas que aprendes a base de equivocarte y solucionar errores si nadie te las enseña de primeras..... o simples cosas de mala logica del programa, crees que lo tienes programado bien pero en realidad no esta tan bien y entonces el funcionamiento del juego no es como tu planeaste que fuera....a veces estos fallos simplemente el juego no dice nada y sigue funcionando pero al no darte ningun error pues son muy dificiles de solucionar.....suelen darte horas y horas revisando palmo a palmo el codigo hasta descubrir porque no hace lo que se supone que debe hacer

una buena practica, es: tener todo el codigo fuente, graficos, sonidos etc estructurado en una misma carpeta y cuando tienes ya algo "bueno" que funciona bien y tal, aunque no este terminado te creas un fichero RAR con esa carpeta comprimido todo y le pones de nombre....MiPrograma_FECHA_FUNCIONANDO.rar.... y lo guardas en algun lugar donde si por lo que sea se te jode el codigo etc.....puedas volver a restaurar ese fichero con todo en el punto en que todo funcionaba (Copia Backup)
Buscar en el foro: En foro: Tipo:
Foro de Vandal
>
Flecha subir