[+] Juego plataformista en C++

Iniciado por Regexp, 8 Junio 2015, 19:10 PM

0 Miembros y 1 Visitante están viendo este tema.

Regexp

Buenas, soy nuevo en esta comunidad y hoy quiero traer un aporte. EL siguiente código lo hice hace un par de meses a manera de prueba de SFML y Box2D. Más que un juego completo (niveles, menús, etc), se buscaba aplicar los conceptos básicos de las herramientas antes mencionadas.

SFML: es una librería que proporciona una capa a OpenGL para trabajar gráficos. Además de esto, da también otras características interesantes relacionadas con multimedia (sonido, por ejemplo) y networking (para juegos online). Es open source y además multiplataforma (puede, de hecho, compilarse para Android utilizando las herramientas correspondientes). Pagina principal: http://www.sfml-dev.org/

Box2D: es un engine para simulación física en dos dimensiones, proporciona una serie de características útiles. También es open source y además es multiplataforma. Pagina del proyecto: http://box2d.org/ (Un dato interesante es que es utilizado en varios Game Engines, dado que es muy eficiente en sus algoritmos)

Como funciona: en primera instancia se lleva acabo un paralelismo entre pixeles y metros. Al momento de proporcionar información a los objetos de Box2D se hace la conversión correspondiente, y al dibujar en pantalla se hace exactamente lo mismo.

Qué tener en cuenta del codigo fuente
1. El juego se hizo bajo Windows con Visual Studio, por lo tanto, para compilarlo en otras plataformas habría que hacer un par de cambios menores (una o dos líneas)
2. No es un juego completo, pero pienso que ilustra varios conceptos básicos como la pila de cuerpos de un mundo (Box2D) y los métodos más frecuentes de SFML, como crear sprites, renderizarlos, tomar teclas por pantalla, etc.
3. Para poder compilar es obviamente necesario tener las clases mencionadas arriba, en las páginas oficiales encontrarán información acorde a diferentes IDE y SO.

Enlace de descarga para codigo fuente dado que son varios archivos he decidido ponerlo en mediafire, y aquí, nada más el main.cpp
http://www.mediafire.com/download/0j8ab99e9fyzhkn/pltaformista.tar.gz
El comprimido contiene:
main.cpp
Player.cpp / Player.h (objeto que representa el jugador)
Blocks.cpp / Blocks.h (objeto que representa plataformas)
Constants.h (constantes que se usan a lo largo del resto del código)

Acá el main.cpp
Código (cpp) [Seleccionar]
/*   __                          
/  |                        
(___| ___  ___  ___       ___
|\   |___)|   )|___)(_/_ |   )
| \  |__  |__/ |__   / / |__/
 __/         |    
*
*
* Este software se ha dado tal como es, el autor no se hace responsable
* del uso que le pueda dar el usuario final. Así mismo se da el derecho
* de editar, distribuir y utilizar el código a conveniencia, siempre y
* cuando se de crédito al autor.
*
*
*/


#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")

#include <iostream>
#include <Box2D/Box2D.h>
#include <SFML/Graphics.hpp>
#include <sstream>
#include <ctime>
#include "Constants.h"
#include "Block.h"
#include "Player.h"
#include <stdio.h>
#include <Windows.h>




using namespace std;

int main() {
sf::Clock clock;
sf::Time time; //Esto es para que el simulador fisico se haga proporcional a los segundos que transcurren por frame
//Inicializamos la camara del juego
sf::View camera;
camera.reset( sf::FloatRect(0,0, (int)width, (int)height) );
camera.setViewport( sf::FloatRect(0, 0, 1.0f, 1.0f) );
float cameraPosition;


//Inicializacion de Box2D
b2World* world = new b2World(gravity);

//Inicializacion del App
sf::RenderWindow App(sf::VideoMode(width, height, 30), "Juego prueba");
App.setKeyRepeatEnabled(true);
App.setFramerateLimit(90);
App.setView(camera);
sf::Event Event;


Player player(world, 32, 32, sf::Vector2f(30, 30), "playerSprite.png"); //Inicializamos un "jugador"
// Recordar hacer clase nivel/mundo que controle eventos independientemente!



std::vector<Block> bloques;
// Este vector de bloques va a contener plataformas y objetos
sf::Texture grass;
grass.loadFromFile("grass.png");
grass.setRepeated(true);
grass.setSmooth(true);

bloques.push_back(Block(world, 3000.0f, 50.0f, sf::Vector2f(-200, height - 50.0f), .5f, false, 0, 0, &grass));
//Esto es un suelo!


sf::Texture bricks;
bricks.loadFromFile("bricks.jpg");
bricks.setRepeated(true);
bricks.setSmooth(true);

bloques.push_back(Block(world, 400.0f, 49.0f, sf::Vector2f(300, 300), .5f, false, .5f, 0, &bricks));
bloques.push_back(Block(world, 400.0f, 49.0f, sf::Vector2f(850, 100), .5f, false, .5f, 0, &bricks));
// Inicializamos algunas plataformas

//Agregamos un objeto dinamico...
sf::Texture box;
box.loadFromFile("box.png");
box.setSmooth(true);
bloques.push_back(Block(world, 100.0f, 100.0f, sf::Vector2f(450, 150), .5f, true, .5f,  0.0f, &box));

//Inicializamos el fondo del escenario (estatico)
sf::Texture bgTexture;
bgTexture.loadFromFile("desert.png");
bgTexture.setSmooth(true);

sf::Sprite bgImg;
bgImg.setTexture(bgTexture);
bgImg.setPosition( sf::Vector2f( 0, 0 ) );


// Game loop
while (App.isOpen())
{
clock.restart();
// Manejo de eventos
while (App.pollEvent(Event))
{
// Si cierra la ventana se cierra el juego
if (Event.type == sf::Event::Closed)
App.close();

// Eventos de teclado
if (Event.type == sf::Event::KeyPressed)
{
//Todo esto se puede cambiar por un switch! recordar cambiar!!
if (Event.key.code == sf::Keyboard::D)
player.Run("right");

if (Event.key.code == sf::Keyboard::A)
player.Run("left");

if (Event.key.code == sf::Keyboard::W)
player.Jump();

}

if (Event.type == sf::Event::KeyReleased)
player.Stop();


}

//Limpia Pantalla
App.clear();

// DIbuja fondo del escenario
App.draw(bgImg);

// Dibuja objetos
for (int i = 0; i < int(bloques.size()); i++)
{
App.draw( bloques[i].GetShape() );
}

//Dibuja el player
App.draw( player.GetSprite() );



//Los muestra en pantalla
App.display();

// Hace update fisico al mundo
time = clock.getElapsedTime();
world->Step(time.asSeconds(), velocityIterations, positionIterations);


for (int i = 0; i < int(bloques.size()); i++)
{
bloques[i].Update();
}
player.Update();
player.UpdateSprite();

// Movemos la camara para que tenga de centro al objeto player!!
cameraPosition = player.dimentions().x + player.screenPosition().x - width/2;
if (cameraPosition < 0)
cameraPosition = 0;

camera.reset( sf::FloatRect( cameraPosition, 0, (int)width, (int)height ) );
App.setView(camera);
// Ponemos el fondo donde se pueda ver....
bgImg.setPosition( sf::Vector2f( cameraPosition, bgImg.getPosition().y ) );

}



return 0;
}



Screenshot

El bloque que está arriba, puede empujarse, caer, etc.. y luego usarlo como plataforma. El resto de las plataformas no se mueven, son estáticas.

Bueno, eso es todo por ahora, acepto sugerencias y críticas. Si hay algunas personas interesadas, haré un tutorial (o más) detallado(s) sobre este tema.

Saludos  ::)
No todo el que deambula está perdido

engel lex

te recomiendo probar angel engine 2d :P seguro te ayuda mucho! ya que une todas las librerías y resume codigo... alguna vez lo usé y te resume mucho trabajo en relacion a SFML

http://angel2d.com/
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

0xFer

se ve interesante, gracias por el aporte  :laugh:
Código (java) [Seleccionar]
int getRandomNumber(){
    return 4; //chosen by fair dice roll
              //guaranteed to be random
}

Kaxperday

Todos aquellos que empiezan en el foro deberían de dejarse de mensajes como "ayuda jackear wifi del vecino" y hacer aportaciones desde el mensaje 1 XDDD

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

Regexp

Me alegra que les haya gustado. Si necesitan ayuda para probarlo/compilarlo solo avisen por acá. En linux es muchísimo mas facil poner a funcionar el Box2D y el SFML. Quizá sea la mala costumbre que te da Windows de querer configurar siempre los IDE para cualquier cosa por pequeña que sea. Ultimamente en linux me ha gustado más compilar directamente por consola con bash o con CMake.

Cita de: engel lex en  8 Junio 2015, 19:14 PM
te recomiendo probar angel engine 2d :P seguro te ayuda mucho! ya que une todas las librerías y resume codigo... alguna vez lo usé y te resume mucho trabajo en relacion a SFML

http://angel2d.com/

Lo tendré en cuenta engel lex, hay varios proyectos interesantes por ahí que se pueden realizar. Investigaré sobre ello, gracias ;)


Saludos
No todo el que deambula está perdido