Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <GL/freeglut.h>
- #include <list>
- #include <cmath>
- using namespace std;
- namespace ui{
- class obj{
- public:
- obj(){
- all.push_back(this);
- }
- virtual ~obj(){};
- double x, y;
- static list <obj*> all;
- static void (*drawRect)(int x, int y, int w, int h);
- static void (*drawStar)(int x, int y, int w, int h);
- static void draw(){
- for(obj *p: all)
- p->_draw();
- }
- static void onClick(int x, int y){
- for(obj *p: all)
- p->_onClick(x, y);
- }
- static void onTick(int ms){
- for(obj *p: all)
- p->_onTick(ms);
- }
- obj* place(int x, int y){
- this->x = x;
- this->y = y;
- return this;
- }
- virtual int contain(int x, int y) = 0;
- protected:
- virtual void _onClick(int x, int y) = 0;
- virtual void _draw() = 0;
- virtual void _onTick(int ms) = 0;
- };
- list <obj*> obj::all;
- class frame : public obj{
- public:
- frame() : obj() {}
- virtual ~frame() {}
- int w, h;
- frame* resize(int w, int h){
- this->w = w;
- this->h = h;
- return this;
- }
- protected:
- virtual int contain(int x, int y){
- if( x < this->x
- || x >= this->x + w
- || y < this->y
- || y >= this->y + h ){
- return 0;
- }
- else{
- return 1;
- }
- }
- virtual void _onClick(int x, int y){
- if(contain(x, y))
- _onHit(x, y);
- else
- _onMiss(x, y);
- }
- virtual void _onHit(int x, int y) = 0;
- virtual void _onMiss(int x, int y) = 0;
- };
- class button : public frame{
- public:
- button(void (*cb)()) :
- frame(), callback(cb)
- {}
- virtual ~button() {}
- void (*callback)();
- protected:
- virtual void _draw(){
- drawRect(x, y, w, h);
- }
- virtual void _onHit(int x, int y){
- callback();
- }
- virtual void _onMiss(int x, int y){
- }
- virtual void _onTick(int ms){
- }
- };
- class unit : public frame{
- public:
- unit() : frame() {}
- virtual ~unit() {}
- int speed;
- double dir_x, dir_y;
- int selected = 0;
- unit* accelerate(int speed){
- this->speed = speed;
- return this;
- }
- unit* rotate(int targ_x, int targ_y){
- int dx = targ_x - x;
- int dy = targ_y - y;
- double distance = sqrt(dx * dx + dy * dy);
- if(distance != 0){
- dir_x = dx / distance;
- dir_y = dy / distance;
- }
- else{
- dir_x = 0;
- dir_y = 0;
- }
- return this;
- }
- protected:
- virtual void _onHit(int x, int y){
- _toggleSelection();
- }
- virtual void _onMiss(int x, int y){
- _setOrder(x, y);
- }
- virtual void _onTick(int ms){
- _move(ms);
- _think(ms);
- }
- virtual void _toggleSelection(){
- selected = !selected;
- }
- virtual void _move(int ms){
- x += dir_x * speed * ms;
- y += dir_y * speed * ms;
- }
- virtual void _draw() = 0;
- virtual void _think(int ms) = 0;
- virtual void _setOrder(int x, int y) = 0;
- };
- class missile : public unit{
- public:
- missile() : unit() {}
- virtual ~missile() {}
- obj* target = nullptr;
- missile* launch(obj* target){
- this->target = target;
- return this;
- }
- protected:
- virtual void _setOrder(int x, int y){
- if(selected){
- target = nullptr;
- rotate(x, y);
- for(obj* o: all){
- if(o->contain(x, y)){
- launch(o);
- break;
- }
- }
- }
- }
- virtual void _think(int ms)
- {
- if(target){
- rotate(target->x, target->y);
- }
- }
- virtual void _draw(){
- drawStar(x, y, w, h);
- if(selected)
- drawRect(x, y, w, h);
- }
- };
- class fighter : public missile{
- public:
- fighter() : missile() {}
- virtual ~fighter() {}
- int reload_countdown = 0;
- int super_aggressive = 0;
- fighter* apocalypse(){
- super_aggressive = 1;
- return this;
- }
- protected:
- virtual void _think(int ms){
- missile::_think(ms);
- _tryFire();
- }
- virtual void _tryFire(){
- if(reload_countdown--)
- return;
- reload_countdown = 5;
- if(!super_aggressive){
- if(target){
- _fire(target);
- }
- }
- else{
- int shoots_count = 6;
- for(obj* o: all){
- shoots_count--;
- if(o == this)
- continue;
- _fire(o);
- if(!shoots_count)
- break;
- }
- }
- }
- virtual void _fire(obj* targ){
- (new missile())
- ->launch(targ)->accelerate(15)
- ->resize(10,10)->place(x, y);
- }
- };
- }
- namespace gl{
- void drawRect(int x, int y, int w, int h){
- glBegin(GL_LINE_LOOP);
- glVertex2f(x, y);
- glVertex2f(x, y + h);
- glVertex2f(x + w, y + h);
- glVertex2f(x + w, y);
- glEnd();
- }
- void drawStar(int x, int y, int w, int h){
- glBegin(GL_LINE_LOOP);
- glVertex2f(x, y + h);
- glVertex2f(x + w/2, y);
- glVertex2f(x + w, y + h);
- glVertex2f(x, y + h/3);
- glVertex2f(x + w, y + h/3);
- glEnd();
- }
- }
- void (*ui::obj::drawRect) (int, int, int, int) = gl::drawRect;
- void (*ui::obj::drawStar) (int, int, int, int) = gl::drawStar;
- void (*glutTFuncWrapper)(int);
- int main(int argc, char** argv){
- (new ui::button([](){cout << "Hello\n";}))
- ->resize(20, 20)->place(10, 10);
- (new ui::button([](){cout << "WOW, IT'S LAMBDA\n";}))
- ->resize(60, 60)->place(70, 30);
- (new ui::fighter())
- ->rotate(1, 1)->accelerate(1)->resize(30,30)->place(100,100);
- (new ui::fighter())
- ->rotate(1, .2)->accelerate(3)->resize(30,30)->place(200,200);
- (new ui::fighter())
- ->rotate(-1, .4)->accelerate(1)->resize(30,30)->place(200,100);
- (new ui::fighter())
- ->rotate(-.1, 1)->accelerate(2)->resize(30,30)->place(100,200);
- (new ui::fighter())
- ->apocalypse()->rotate(0, 0)->accelerate(1)->resize(30,30)->place(150,150);
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
- glutInitWindowSize(300, 300);
- glutInit(&argc, argv);
- glutCreateWindow("Fighter");
- glutDisplayFunc([](){
- glViewport(0, 0, 300, 300);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, 300, 300, 0, -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glClear(GL_COLOR_BUFFER_BIT);
- ui::obj::draw();
- glutSwapBuffers();
- });
- glutMouseFunc([](int key, int state, int x, int y){
- if (key == GLUT_LEFT_BUTTON
- && state == GLUT_DOWN){
- ui::obj::onClick(x, y);
- }
- });
- glutTFuncWrapper = [](int ID){
- glutTimerFunc(100, glutTFuncWrapper, 0);
- ui::obj::onTick(1);
- glutPostRedisplay();
- };
- glutTimerFunc(100, glutTFuncWrapper, 0);
- glutMainLoop();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement