Subscribe to gabehabe's on-topic ramblings        RSS Feed
-----

Time for a teaser: The code behind the engine!

Icon Leave Comment
Not gonna give it all away yet, it needs an extreme cleanup. My code is a total mess! :)

Instead, I'm gonna give you a few tasters. Ready? Good.

First off, a little collision detection for that map. This took a while to perfect, I gotta admit. In fact to be honest, there's still a lot of room for improvement. :)

My code is a fucking disgrace to mankind here, please don't hate me for it!
int map::collision_check_bottom(int x, int y) {
    x+=SPRITE_WIDTH;
    vector<SDL_Rect>::iterator it;
    vector<object*>::iterator it2;
    vector<exit*>::iterator it3;
    int i = 0;

    for(it3 = this->exits.begin(); it3 != this->exits.end(); ++it3, i++) {
        if(((*it3)->offset.y+(*it3)->offset.h>y-9&&(*it3)->offset.y+(*it3)->offset.h<y+6)&&((*it3)->offset.x<x&&(*it3)->offset.x+(*it3)->offset.w+SPRITE_WIDTH>x))return INT_MAX-i;
    }

    for(it = this->off_limits.begin(); it != this->off_limits.end(); ++it) {
        if((it->y+it->h>y-9&&it->y+it->h<y+6)&&(it->x<x&&it->x+it->w+SPRITE_WIDTH>x))return -1;
    }

    i = 0;
    for(it2 = this->objects.begin(); it2 != this->objects.end(); ++it2, i++) {
        if(((*it2)->offset.y+(*it2)->offset.h>y-9&&(*it2)->offset.y+(*it2)->offset.h<y+6)&&((*it2)->offset.x<x&&(*it2)->offset.x+(*it2)->offset.w+SPRITE_WIDTH>x))return i;
    }

    return -2;
}


Aaaaannndddd, another piece of the engine. This is the player movement function, which utilises that nasty looking collision detection. :)
bool player::move(int direction) { // 1=up, 2=down, 3=left, 4=right
    int movement = this->running ? (VELOCITY*2)-3 : VELOCITY;
    int x = 0;
    switch(direction) {
        case 1:
            x = this->the_map->collision_check_bottom(this->_x, this->_y-movement+SPRITE_HEIGHT-5);
            if(x == -2) {
                this->_y -= movement;
            } else if(x >= INT_MAX / 2) {
                this->the_map->change_map(INT_MAX - x);
            }
            this->state = this->state == UP_ONE ? UP_TWO : UP_ONE;
            break;
        case 2:
            x = this->the_map->collision_check_top(this->_x, this->_y-movement+SPRITE_HEIGHT-5);
            if(x == -2) {
                this->_y += movement;
            } else if(x >= INT_MAX / 2) {
                this->the_map->change_map(INT_MAX - x);
            }
            this->state = this->state == DOWN_ONE ? DOWN_TWO : DOWN_ONE;
            break;
        case 3:
            x = this->the_map->collision_check_right(this->_x-movement+SPRITE_WIDTH-5, this->_y);
            if(x == -2) {
                this->_x -= movement;
            } else if(x >= INT_MAX / 2) {
                this->the_map->change_map(INT_MAX - x);
            }
            this->state = this->state == LEFT_ONE ? LEFT_TWO : LEFT_ONE;
            break;
        case 4:
            x = this->the_map->collision_check_left(this->_x-movement+SPRITE_WIDTH-5, this->_y);
            if(x == -2) {
                this->_x += movement;
            } else if(x >= INT_MAX / 2) {
                this->the_map->change_map(INT_MAX - x);
            }
            this->state = this->state == RIGHT_ONE ? RIGHT_TWO : RIGHT_ONE;
            break;

        default: break;
    }

    ostringstream q;
    q << "UPDATE users ";
    q << "SET screen_id = " << this->the_map->get_id() << ", ";
    q << "x = " << this->_x << ", y = " << this->_y << ", state = " << this->state;
    q << " WHERE username = '" << this->username << "' LIMIT 1";
    mysql_query(this->_mysql, q.str().c_str());

    return true;
}


And lastly, I give you main, which is a nice example on how to use it -- this bit's not so nasty! :D
#include "game.h"
#include "functions.h"

int do_mysql(void* foo);

// must be global for the sake of accessing in the thread
game* the_game;
SDL_Surface* players;

int main(int argc, char *argv[]) {
    players = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH, RMASK, GMASK, BMASK, AMASK);

    the_game = new game(players);

    map* m1 = new map(1, the_game->get_screen());
    m1->set_player_location(180,220);
    m1->set_map(IMG_Load(".\\img\\map.png"));
    m1->add_object(new object(the_game->get_screen(), ".\\img\\house.jpg", 272, 137, 96, 64));

    map* m2 = new map(2, the_game->get_screen());
    m2->set_map(IMG_Load(".\\img\\map2.png"));
    m2->set_player_location(300,290);
    m2->add_object(new object(the_game->get_screen(), ".\\img\\bed.png", 160, 180, 42, 72, &dont_sleep, &do_sleep));
    m2->add_exit(new exit((SDL_Surface*)NULL, 300, 300, 25, 32, m1));

    m2->add_collidable(0, 0, 120, SCREEN_HEIGHT);
    m2->add_collidable(0, 0, SCREEN_WIDTH, 120);
    m2->add_collidable(0, 302, SCREEN_WIDTH, SCREEN_HEIGHT-305);
    m2->add_collidable(SCREEN_WIDTH-120, 0, 120, SCREEN_HEIGHT);

    m1->add_exit(new exit((SDL_Surface*)NULL, 306, 177, 25, 25, m2));

    map* main = new map(m1);

    the_game->add_map(main);
    the_game->add_map(m1);
    the_game->add_map(m2);

    the_game->do_intro();
    SDL_CreateThread(&do_mysql, NULL);

    the_game->do_main();

    return EXIT_SUCCESS;
}

I'll even be working on a code generator for that, along with a map editor - I plan to develop something similar to RPG Maker when the engine is more complete. Also, a lot of that can be made redundant: in the end, I'll be keeping those methods, but also developing a way to load maps, etc, straight from a database, storing much more stuff in the cloud - easier to update your games, smaller downloads for users, etc. :) :) :)

0 Comments On This Entry

 

August 2014

S M T W T F S
      1 2
3456789
10111213141516
17181920212223
24252627282930
31      

Request A Topic!

Want me to blog about something? Perhaps a language? A piece of software? A specific topic? Let me know! Even guests can post here on my blog!

If you would like to request a topic, please post a comment here and I'll get on it right away! smile.gif

Search My Blog

0 user(s) viewing

0 Guests
0 member(s)
0 anonymous member(s)

gabehabe's off-topic ramblings

Follow me on Twitter!
lol, my other blog died a horrible lonely death. Ah well.

Smiley of the [however often I change it]

IPB Image

Contact Me

e-mail: gabehabe@gmail.com

Google Talk: gabehabe@gmail.com
MSN: gabehabe@hotmail.com
Yahoo: gabehabe (rarely used)
AIM: gabehabe (rarely used)

Skype: gabehabe

Want me to work for you? [click]