Created
September 4, 2014 14:30
-
-
Save Shitaro/6afa18c79d19b200ea14 to your computer and use it in GitHub Desktop.
The Game which I make now.This is still incomplete.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
export LD_LIBRARY_PATH=/usr/local/include/SFML/lib | |
clang++ -o main -std=c++11 -O3 -lsfml-system \ | |
-lsfml-graphics -lsfml-window -lsfml-audio "./main.cpp" && ./main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SFML/Window.hpp> | |
#include <SFML/Graphics.hpp> | |
#include <memory> | |
constexpr int windowWidth{800},windowHeight{600}; | |
constexpr float ballRadius{10.f},ballVelocity{8.f}; | |
constexpr float paddleWidth{60.f},paddleHeight{20.f},paddleVelocity{12.f}; | |
constexpr float blockWidth{60.f},blockHeight{20.f}; | |
constexpr int countBlocksX{11},countBlocksY{11}; | |
class Object; | |
class IObjectBuilder; | |
void buildParameter(const IObjectBuilder&); | |
// Player | |
struct Paddle{ | |
sf::RectangleShape shape; | |
sf::Vector2f velocity; | |
Paddle(float mX, float mY){ | |
shape.setPosition(mX,mY); | |
shape.setSize({paddleWidth,paddleHeight}); | |
shape.setFillColor(sf::Color::Green); | |
shape.setOrigin(paddleWidth/2.f,paddleHeight/2.f); | |
} | |
void update(){ | |
shape.move(velocity); | |
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Left)&&left()>0){ | |
velocity.x=-paddleVelocity; | |
} else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Right)&&right()<windowWidth){ | |
velocity.x=paddleVelocity; | |
} | |
else velocity.x=0; | |
} | |
float x(){return shape.getPosition().x;} | |
float y(){return shape.getPosition().y;} | |
float left(){return x()-shape.getSize().x/2.f;} | |
float right(){return x()+shape.getSize().x/2.f;} | |
float top(){return y()-shape.getSize().y/2.f;} | |
float bottom(){return y()+shape.getSize().y/2.f;} | |
}; | |
// Brocks | |
struct Brick{ | |
sf::RectangleShape shape; | |
bool destroyed{false}; | |
Brick(float mX, float mY){ | |
shape.setPosition(mX,mY); | |
shape.setSize({blockWidth,blockHeight}); | |
shape.setFillColor(sf::Color::Yellow); | |
shape.setOrigin(blockWidth/2.f,blockHeight/2.f); | |
} | |
float x(){return shape.getPosition().x;} | |
float y(){return shape.getPosition().y;} | |
float left(){return x()-shape.getSize().x/2.f;} | |
float right(){return x()+shape.getSize().x/2.f;} | |
float top(){return y()-shape.getSize().y/2.f;} | |
float bottom(){return y()+shape.getSize().y/2.f;} | |
}; | |
template<class T1,class T2> bool isIntersecting(T1& mA, T2& mB){ | |
return mA.right()>=mB.left() && mA.left()<=mB.right() | |
&& mA.bottom()>=mB.top() && mA.top()<=mB.bottom(); | |
} | |
// From here Builder pattern | |
class Object{ | |
public: | |
Object() | |
: charge{0.f},position{0.f,0.f},velocity{0.f,0.f},image{""} | |
{ | |
} | |
~Object(){ | |
} | |
void setPosition(const sf::Vector2f& position){ | |
this->position=position; | |
} | |
void setVelocity(const sf::Vector2f& velocity){ | |
this->velocity=velocity; | |
} | |
void setVelocityX(const float& Vx){ | |
velocity.x=Vx; | |
} | |
void setVelocityY(const float& Vy){ | |
velocity.y=Vy; | |
} | |
void setCharge(const float& charge){ | |
this->charge=charge; | |
} | |
void setImage(const std::string& image){ | |
this->image=image; | |
} | |
void setParameter(){ | |
tx.loadFromFile(image); | |
tx.setSmooth(true); | |
sprite.setTexture(tx); | |
sprite.setColor(sf::Color(255,255,255,255)); | |
sprite.setOrigin(sprite.getLocalBounds().width/2.0f,sprite.getLocalBounds().height/2.0f); | |
sprite.setPosition(position); | |
} | |
sf::Sprite getSprite() const{ | |
return sprite; | |
} | |
void update(){ | |
if(left()<0){ | |
velocity.x=ballVelocity; | |
} else if(right()>windowWidth){ | |
velocity.x=-ballVelocity; | |
} | |
if(top()<0){ | |
velocity.y=ballVelocity; | |
} else if(bottom()>windowHeight){ | |
velocity.y=-ballVelocity; | |
} | |
sprite.move(velocity); | |
} | |
float x() const{return sprite.getPosition().x;} | |
float y() const{return sprite.getPosition().y;} | |
float left() const{return x()-sprite.getLocalBounds().width/2.0f;} | |
float right() const{return x()+sprite.getLocalBounds().width/2.0f;} | |
float top() const{return y()-sprite.getLocalBounds().height/2.0f;} | |
float bottom() const{return y()+sprite.getLocalBounds().height/2.0f;} | |
private: | |
sf::Texture tx; | |
sf::Sprite sprite; | |
float charge; | |
sf::Vector2f position; | |
sf::Vector2f velocity; | |
std::string image; | |
}; | |
// Builder class | |
class IObjectBuilder{ | |
protected: | |
// Object* mObject; | |
std::unique_ptr<Object> mObject; | |
// std::shared_ptr<Object> mObject; | |
public: | |
virtual void buildPosition()=0; | |
virtual void buildVelocity()=0; | |
virtual void buildCharge()=0; | |
virtual void buildImage()=0; | |
virtual void buildParameter(){ | |
mObject->setParameter(); | |
} | |
// virtual void setKind()=0; // Not implemented. | |
Object* getResult() const{ | |
// return mObject; | |
return mObject.get(); | |
}; | |
void createObject(){ | |
// mObject=new Object(); | |
// mObject=std::make_shared<Object>(); | |
std::unique_ptr<Object> tmpObj(new Object()); | |
mObject=std::move(tmpObj); | |
} | |
}; | |
// Builder class which generates electric monopole. | |
class ElectroMonopoleBuilder | |
: public IObjectBuilder{ | |
public: | |
virtual void buildPosition() override{ | |
sf::Vector2f position{200,10}; | |
mObject->setPosition(position); | |
} | |
virtual void buildVelocity() override{ | |
sf::Vector2f velocity{10,10}; | |
mObject->setVelocity(velocity); | |
} | |
virtual void buildCharge() override{ | |
mObject->setCharge(-1.0f); | |
} | |
virtual void buildImage() override{ | |
std::string image{"electron.png"}; | |
mObject->setImage(image); | |
} | |
Object* getResult() const{ | |
// return mObject; | |
return mObject.get(); | |
} | |
}; | |
// ref.Effective C++ Item 23:Prefer non-member non-friend functions to member functions. | |
void buildParameter(IObjectBuilder& mIob){ | |
mIob.createObject(); | |
mIob.buildImage(); | |
mIob.buildPosition(); | |
mIob.buildVelocity(); | |
mIob.buildCharge(); | |
mIob.buildParameter(); | |
} | |
// Director class | |
class ObjectDirector{ | |
public: | |
void setObjectBuilder(IObjectBuilder* mIob){ | |
// void setObjectBuilder(const std::shared_ptr<IObjectBuilder>& mIob){ | |
// Iob=mIob; | |
// Iob.reset(mIob); | |
Iob=mIob; | |
} | |
Object* getObject() const{ | |
return Iob->getResult(); | |
} | |
void constructObject(){ | |
buildParameter(*Iob); | |
// Iob->createObject(); | |
// Iob->buildImage(); | |
// Iob->buildPosition(); | |
// Iob->buildVelocity(); | |
// Iob->buildCharge(); | |
// Iob->buildParameter(); | |
} | |
private: | |
IObjectBuilder* Iob; | |
// std::unique_ptr<IObjectBuilder> Iob; | |
// std::shared_ptr<IObjectBuilder> Iob; | |
}; | |
// Up to here Builder pattern. | |
void testCollision(Brick& mBrick,Object& mObject){ | |
if(!isIntersecting(mBrick,mObject)){ | |
return; | |
} | |
mBrick.destroyed=true; | |
float overlapLeft{mObject.right()-mBrick.left()}; | |
float overlapRight{mBrick.right()-mObject.left()}; | |
float overlapTop{mObject.bottom()-mBrick.top()}; | |
float overlapBottom{mBrick.bottom()-mObject.top()}; | |
bool ballFromLeft(std::abs(overlapLeft)<std::abs(overlapRight)); | |
bool ballFromTop(std::abs(overlapTop)<std::abs(overlapBottom)); | |
float minOverlapX{ballFromLeft?overlapLeft:overlapRight}; | |
float minOverlapY{ballFromTop?overlapTop:overlapBottom}; | |
if(std::abs(minOverlapX)<std::abs(minOverlapY)){ | |
// mObject.velocity.x=ballFromLeft?-ballVelocity:ballVelocity; | |
mObject.setVelocityX(ballFromLeft?-ballVelocity:ballVelocity); | |
} else{ | |
// mObject.velocity.y=ballFromTop?-ballVelocity:ballVelocity; | |
mObject.setVelocityY(ballFromTop?-ballVelocity:ballVelocity); | |
} | |
} | |
void testCollision(Paddle& mPaddle,Object& mObject){ | |
if(!isIntersecting(mPaddle,mObject)){ | |
return; | |
} | |
mObject.setVelocityY(-ballVelocity); | |
if(mObject.x()<mPaddle.x()){ | |
mObject.setVelocityX(-ballVelocity); | |
} else{ | |
mObject.setVelocityX(ballVelocity); | |
} | |
// debacking as following | |
time_t t=time(0); | |
struct tm * now=localtime(&t); | |
std::fprintf(stdout,"Hit paddle!%s\n",std::asctime(now)); | |
} | |
int main(){ | |
Paddle paddle{windowWidth/2,windowHeight/2}; | |
std::vector<Brick> bricks; | |
for(int iX{0};iX<countBlocksX;iX++){ | |
for(int iY{0};iY<countBlocksY;iY++){ | |
bricks.emplace_back((iX+1)*(blockWidth+3)+22,(iY+2)*(blockHeight+3)); | |
} | |
} | |
// Creation of the window | |
sf::RenderWindow window{{windowWidth,windowHeight},"Happy Block Bye-Bye"}; | |
window.setFramerateLimit(60); | |
// Show picture | |
sf::Texture tx2; | |
tx2.loadFromFile("BEC.jpg"); | |
tx2.setSmooth(true); | |
ObjectDirector objectDirector; | |
std::shared_ptr<IObjectBuilder> objBuilder=std::make_shared<ElectroMonopoleBuilder>(); | |
objectDirector.setObjectBuilder(objBuilder.get()); | |
// objectDirector.setObjectBuilder(objBuilder); | |
objectDirector.constructObject(); | |
// std::shared_ptr<Object> el; | |
// std::unique_ptr<Object> el; | |
// el.reset(objectDirector.getObject()); | |
auto el=objectDirector.getObject(); | |
// std::fprintf(stdout,"%s\n",typeid(el).name()); | |
// loop | |
while(true){ | |
// | |
window.clear(sf::Color::Black); | |
// If "Esc" is pressed, break out of the loop | |
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Escape)){ | |
break; | |
} | |
// Show my pokemon | |
sf::Sprite sprite2(tx2); | |
sprite2.setColor(sf::Color(255,255,255,128)); | |
sprite2.setOrigin(sprite2.getLocalBounds().width/2.0f,sprite2.getLocalBounds().height/2.0f); | |
sprite2.setPosition(420,430); | |
sprite2.setScale(0.7f,0.5f); | |
sprite2.setRotation(20); | |
window.draw(sprite2,sf::RenderStates(sf::BlendAdd)); | |
el->update(); | |
// el.update(); | |
window.draw(el->getSprite(),sf::RenderStates(sf::BlendAdd)); | |
// window.draw(el.getSprite(),sf::RenderStates(sf::BlendAdd)); | |
paddle.update(); | |
testCollision(paddle,*el); | |
for(auto& brick:bricks){ | |
testCollision(brick,*el); | |
// std::fprintf(stdout,"%s %s\n",typeid(brick).name(), typeid(el).name()); | |
} | |
bricks.erase(std::remove_if(begin(bricks),end(bricks),[](const Brick& mBrick){return mBrick.destroyed;}),std::end(bricks)); | |
window.draw(paddle.shape); | |
for(auto& brick:bricks){ | |
window.draw(brick.shape); | |
} | |
// show the window contents | |
window.display(); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment