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
/* __ / | (___| ___ ___ ___ ___ |\ |___)| )|___)(_/_ | ) | \ |__ |__/ |__ / / |__/ __/ | * * * 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
