1
SFML projects / Incomplete Top-Down Game
« on: September 30, 2010, 08:09:33 pm »
For the past week or so, I've been developing a basic little top-down shooter game, primarily to (re)learn both C++ and SFML. I know for a fact that this code is far from perfect, and is probably in fact quite terrible. In hopes of getting criticism and feedback (constructive or otherwise), here it is:
Code: [Select]
#include <SFML/Graphics.hpp>
#include <SFML/Graphics/Image.hpp>
#include <SFML/Graphics/Color.hpp>
#include <vector>
#include <math.h>
#include <iostream>
using namespace sf;
using namespace std;
float angleTo(Vector2f, Vector2f);
const double PI = 3.141592;
enum eTypes { PLAYER, ENEMY, SCENERY };
class CEntity
{
protected:
static Image enemyImage_;
static Image playerImage_;
static Image wallImage_;
int health_;
Vector2f position_;
public:
Sprite sprite;
float speed;
static void loadImages(RenderWindow * App, string enemyFileName, string playerFileName, string wallFileName)
{
if (!enemyImage_.LoadFromFile(enemyFileName))
{
cout << "Failed to load enemy image." << endl;
App->Close();
}
if (!playerImage_.LoadFromFile(playerFileName))
{
cout << "Failed to load player image." << endl;
App->Close();
}
if (!wallImage_.LoadFromFile(wallFileName))
{
cout << "Failed to load wall image." << endl;
App->Close();
}
}
eTypes type;
CEntity(eTypes Type)
{
type = Type;
switch (type)
{
case eTypes::ENEMY:
sprite.SetImage(enemyImage_);
sprite.SetCenter(enemyImage_.GetWidth() / 2, enemyImage_.GetWidth() / 2);
break;
case eTypes::PLAYER:
sprite.SetImage(playerImage_);
sprite.SetCenter(playerImage_.GetWidth() / 2, playerImage_.GetWidth() / 2);
break;
case eTypes::SCENERY:
sprite.SetImage(wallImage_);
sprite.SetCenter(wallImage_.GetWidth() / 2, wallImage_.GetWidth() / 2);
break;
default:
break;
}
speed = 0.75f;
sprite.Scale(0.5f, 0.5f);
}
CEntity(eTypes Type, Vector2f Position)
{
type = Type;
switch (type)
{
case eTypes::ENEMY:
sprite.SetImage(enemyImage_);
sprite.SetCenter(enemyImage_.GetWidth() / 2, enemyImage_.GetWidth() / 2);
break;
case eTypes::PLAYER:
sprite.SetImage(playerImage_);
sprite.SetCenter(playerImage_.GetWidth() / 2, playerImage_.GetWidth() / 2);
break;
case eTypes::SCENERY:
sprite.SetImage(wallImage_);
sprite.SetCenter(wallImage_.GetWidth() / 2, wallImage_.GetWidth() / 2);
break;
default:
break;
}
speed = 0.75f;
position_ = sprite.TransformToLocal(Position);
sprite.SetPosition(position_);
sprite.Scale(0.5f, 0.5f);
}
void setPosition(Vector2f newPosition)
{
position_ = newPosition;
}
void move(Vector2f offset)
{
position_ += offset;
}
void faceAngle(float angle)
{
sprite.Rotate(-angle - sprite.GetRotation());
}
void facePoint(Vector2f target)
{
faceAngle(angleTo(position_, target));
}
void faceEntity(CEntity target)
{
facePoint(target.Position());
}
void update(float frameTime)
{
sprite.SetPosition(position_);
}
void setColor(Color color)
{
sprite.SetColor(color);
}
Vector2f Position() { return position_; }
};
Image CEntity::enemyImage_;
Image CEntity::playerImage_;
Image CEntity::wallImage_;
int sign(int v) { return v > 0 ? 1 : (v < 0 ? -1 : 0); }
void followPlayer(View& v, Vector2f target)
{
if (v.GetCenter() == target) { return; }
Vector2f transform = Vector2f(v.GetCenter().x - target.x, v.GetCenter().y - target.y);
float speed = sqrt(pow(target.x - v.GetCenter().x, 2) + pow(target.y - v.GetCenter().y, 2)) / 200.f;
transform = Vector2f(-sign((int)transform.x), -sign((int)transform.y));
v.Move(speed * transform.x, speed * transform.y);
return;
}
float angleTo(Vector2f a, Vector2f b)
{
return atan((b.y - a.y) / (b.x - a.x)) * 180/PI;
}
int main()
{
RenderWindow App(VideoMode(800, 600, 32), "Top-Down");
View v(Vector2f(400, 300), Vector2f(400, 300));
App.SetView(v);
App.ShowMouseCursor(false);
const Input & input = App.GetInput();
vector<CEntity> entities;
CEntity::loadImages(&App, "enemy.png", "player.png", "wall.png");
int level [100][100];
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
level[i][j] = 0;
}
}
Image iCrosshair = Image();
iCrosshair.LoadFromFile("crosshair.png");
Sprite sCrosshair = Sprite(iCrosshair);
sCrosshair.SetCenter(10.5, 10.5);
sCrosshair.SetBlendMode(Blend::Mode::Add);
entities.insert(entities.begin(), CEntity(eTypes::PLAYER, Vector2f(400,300)));
entities.insert(entities.end(), CEntity(eTypes::ENEMY, Vector2f(400, 300)));
CEntity *player = & entities[0];
player->setColor(Color::Color(255, 0, 0));
while (App.IsOpened())
{
Vector2f mousePos = App.ConvertCoords(input.GetMouseX(), input.GetMouseY());
sCrosshair.SetPosition(mousePos);
Event Event;
while (App.GetEvent(Event))
{
switch(Event.Type)
{
case Event::Closed:
App.Close();
case Event::KeyPressed:
if (Event.Key.Code == Key::Escape)
App.Close();
}
}
if (input.IsKeyDown(Key::Code::S))
player->move(Vector2f(0, player->speed));
if (input.IsKeyDown(Key::Code::W))
player->move(Vector2f(0, -player->speed));
if (input.IsKeyDown(Key::Code::D))
player->move(Vector2f(player->speed, 0));
if (input.IsKeyDown(Key::Code::A))
player->move(Vector2f(-player->speed, 0));
player->facePoint(mousePos);
for (int i = 0; i < entities.size(); i++)
{
entities[i].update(App.GetFrameTime());
}
App.Clear();
followPlayer(v, player->Position());
for (int i = 0; i < entities.size(); i++)
{
App.Draw(entities[i].sprite);
}
App.Draw(sCrosshair);
App.Display();
}
return EXIT_SUCCESS;
}