Omnimaga

General Discussion => Technology and Development => Computer Projects and Ideas => Topic started by: miotatsu on November 21, 2009, 12:17:53 am

Title: piworld PC (old)
Post by: miotatsu on November 21, 2009, 12:17:53 am
Piworld PC Demo v0.2 download: http://www.megaupload.com/?d=R20BJLFT
source:
Code: [Select]
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_Mixer.h"
#include <string>
#include <fstream>
#include <sstream>

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

const int FRAMES_PER_SECOND = 20;

const int DOT_WIDTH = 20;
const int DOT_HEIGHT = 20;

const int LEVEL_WIDTH = 1280;
const int LEVEL_HEIGHT = 960;
int AREAX = 190;
int AREAY = 190;

const int TILE_WIDTH = 80;
const int TILE_HEIGHT = 80;
const int TOTAL_TILES = 192;
const int TILE_SPRITES = 12;

const int TILE_00 = 0;
const int TILE_01 = 1;
const int TILE_02 = 2;
const int TILE_03 = 3;
const int TILE_04 = 4;
const int TILE_05 = 5;
const int TILE_06 = 6;
const int TILE_07 = 7;
const int TILE_08 = 8;
const int TILE_09 = 9;
const int TILE_10 = 10;
const int TILE_11 = 11;

SDL_Surface *dot = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *tileSheet = NULL;

SDL_Rect clips[ TILE_SPRITES ];

SDL_Event event;

SDL_Rect camera = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };

Mix_Music *music = NULL;

class Tile
{
    private:
    SDL_Rect box;

    int type;

    public:
    Tile( int x, int y, int tileType );

    void show();

    int get_type();

    SDL_Rect get_box();
};

class Dot
{
    private:
    SDL_Rect box;

    int xVel, yVel;

    public:
    Dot();

    void handle_input();

    void move( Tile *tiles[] );

    void show();

    void set_camera();
};

class Timer
{
    private:
    int startTicks;

    int pausedTicks;

    bool paused;
    bool started;

    public:
    Timer();

    void start();
    void stop();
    void pause();
    void unpause();

    int get_ticks();

    bool is_started();
    bool is_paused();
};

SDL_Surface *load_image( std::string filename )
{
    SDL_Surface* loadedImage = NULL;

    SDL_Surface* optimizedImage = NULL;

    loadedImage = IMG_Load( filename.c_str() );

    if( loadedImage != NULL )
    {
        optimizedImage = SDL_DisplayFormat( loadedImage );

        SDL_FreeSurface( loadedImage );

        if( optimizedImage != NULL )
        {
            SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) );
        }
    }

    return optimizedImage;
}

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
    SDL_Rect offset;

    offset.x = x;
    offset.y = y;

    SDL_BlitSurface( source, clip, destination, &offset );
}

bool check_collision( SDL_Rect A, SDL_Rect B )
{
    int leftA, leftB;
    int rightA, rightB;
    int topA, topB;
    int bottomA, bottomB;

    leftA = A.x;
    rightA = A.x + A.w;
    topA = A.y;
    bottomA = A.y + A.h;

    leftB = B.x;
    rightB = B.x + B.w;
    topB = B.y;
    bottomB = B.y + B.h;

    if( bottomA <= topB )
    {
        return false;
    }

    if( topA >= bottomB )
    {
        return false;
    }

    if( rightA <= leftB )
    {
        return false;
    }

    if( leftA >= rightB )
    {
        return false;
    }

    return true;
}

bool init()
{
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
    {
        return false;
    }

    screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

    if( screen == NULL )
    {
        return false;
    }
    
    if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 )
    {
        return false;
    }

    return true;
}

bool load_files()
{
    dot = load_image( "Images/dot.png" );

    if( dot == NULL )
    {
        return false;
    }

    tileSheet = load_image( "Images/tiles.png" );

    if( tileSheet == NULL )
    {
        return false;
    }
    
    music = Mix_LoadMUS( "Music/Music1.mp3" );

    if( music == NULL )
    {
        return false;
    }

    return true;
}

void clean_up( Tile *tiles[] )
{
    SDL_FreeSurface( dot );
    SDL_FreeSurface( tileSheet );

    for( int t = 0; t < TOTAL_TILES; t++ )
    {
        delete tiles[ t ];
    }
    
    Mix_FreeMusic( music );

    Mix_CloseAudio();

    SDL_Quit();
}

void clip_tiles()
{
    clips[ TILE_00 ].x = 0;
    clips[ TILE_00 ].y = 0;
    clips[ TILE_00 ].w = TILE_WIDTH;
    clips[ TILE_00 ].h = TILE_HEIGHT;

    clips[ TILE_01 ].x = 0;
    clips[ TILE_01 ].y = 80;
    clips[ TILE_01 ].w = TILE_WIDTH;
    clips[ TILE_01 ].h = TILE_HEIGHT;

    clips[ TILE_02 ].x = 0;
    clips[ TILE_02 ].y = 160;
    clips[ TILE_02 ].w = TILE_WIDTH;
    clips[ TILE_02 ].h = TILE_HEIGHT;

    clips[ TILE_11 ].x = 80;
    clips[ TILE_11 ].y = 0;
    clips[ TILE_11 ].w = TILE_WIDTH;
    clips[ TILE_11 ].h = TILE_HEIGHT;

    clips[ TILE_10 ].x = 80;
    clips[ TILE_10 ].y = 80;
    clips[ TILE_10 ].w = TILE_WIDTH;
    clips[ TILE_10 ].h = TILE_HEIGHT;

    clips[ TILE_09 ].x = 80;
    clips[ TILE_09 ].y = 160;
    clips[ TILE_09 ].w = TILE_WIDTH;
    clips[ TILE_09 ].h = TILE_HEIGHT;

    clips[ TILE_04 ].x = 160;
    clips[ TILE_04 ].y = 0;
    clips[ TILE_04 ].w = TILE_WIDTH;
    clips[ TILE_04 ].h = TILE_HEIGHT;

    clips[ TILE_03 ].x = 160;
    clips[ TILE_03 ].y = 80;
    clips[ TILE_03 ].w = TILE_WIDTH;
    clips[ TILE_03 ].h = TILE_HEIGHT;

    clips[ TILE_08 ].x = 160;
    clips[ TILE_08 ].y = 160;
    clips[ TILE_08 ].w = TILE_WIDTH;
    clips[ TILE_08 ].h = TILE_HEIGHT;

    clips[ TILE_05 ].x = 240;
    clips[ TILE_05 ].y = 0;
    clips[ TILE_05 ].w = TILE_WIDTH;
    clips[ TILE_05 ].h = TILE_HEIGHT;

    clips[ TILE_06 ].x = 240;
    clips[ TILE_06 ].y = 80;
    clips[ TILE_06 ].w = TILE_WIDTH;
    clips[ TILE_06 ].h = TILE_HEIGHT;

    clips[ TILE_07 ].x = 240;
    clips[ TILE_07 ].y = 160;
    clips[ TILE_07 ].w = TILE_WIDTH;
    clips[ TILE_07 ].h = TILE_HEIGHT;
}

bool set_tiles( Tile *tiles[] )
{
    int x = 0, y = 0;

    std::ifstream map( "Maps/MAP1.map" );

    if( map == NULL )
    {
        return false;
    }

    for( int t = 0; t < TOTAL_TILES; t++ )
    {
        int tileType = -1;

        map >> tileType;

        if( map.fail() == true )
        {
            map.close();
            return false;
        }

        if( ( tileType >= 0 ) && ( tileType < TILE_SPRITES ) )
        {
            tiles[ t ] = new Tile( x, y, tileType );
        }
        else
        {
            map.close();
            return false;
        }

        x += TILE_WIDTH;

        if( x >= LEVEL_WIDTH )
        {
            x = 0;

            y += TILE_HEIGHT;
        }
    }

    map.close();

    return true;
}

bool touches_wall( SDL_Rect box, Tile *tiles[] )
{
    for( int t = 0; t < TOTAL_TILES; t++ )
    {
        if( ( tiles[ t ]->get_type() >= TILE_03 ) && ( tiles[ t ]->get_type() <= TILE_11 ) )
        {
            if( check_collision( box, tiles[ t ]->get_box() ) == true )
            {
                return true;
            }
        }
    }

    return false;
}

Tile::Tile( int x, int y, int tileType )
{
    box.x = x;
    box.y = y;

    box.w = TILE_WIDTH;
    box.h = TILE_HEIGHT;

    type = tileType;
}

void Tile::show()
{
    if( check_collision( camera, box ) == true )
    {
        apply_surface( box.x - camera.x, box.y - camera.y, tileSheet, screen, &clips[ type ] );
    }
}

int Tile::get_type()
{
    return type;
}

SDL_Rect Tile::get_box()
{
    return box;
}

Dot::Dot()
{
    box.x = 190;
    box.y = 190;
    box.w = DOT_WIDTH;
    box.h = DOT_HEIGHT;

    xVel = 0;
    yVel = 0;
}

void Dot::handle_input()
{
    if( event.type == SDL_KEYDOWN )
    {
        switch( event.key.keysym.sym )
        {
            case SDLK_UP: yVel -= DOT_HEIGHT / 2; break;
            case SDLK_DOWN: yVel += DOT_HEIGHT / 2; break;
            case SDLK_LEFT: xVel -= DOT_WIDTH / 2; break;
            case SDLK_RIGHT: xVel += DOT_WIDTH / 2; break;
        }
    }
    else if( event.type == SDL_KEYUP )
    {
        switch( event.key.keysym.sym )
        {
            case SDLK_UP: yVel += DOT_HEIGHT / 2; break;
            case SDLK_DOWN: yVel -= DOT_HEIGHT / 2; break;
            case SDLK_LEFT: xVel += DOT_WIDTH / 2; break;
            case SDLK_RIGHT: xVel -= DOT_WIDTH / 2; break;
        }
    }
}

void Dot::move( Tile *tiles[] )
{
    box.x += xVel;
    AREAX += xVel;

    if( ( box.x < 0 ) || ( box.x + DOT_WIDTH > LEVEL_WIDTH ) || touches_wall( box, tiles ) )
    {
        box.x -= xVel;
        AREAX -= xVel;
    }
    
    box.y += yVel;
    AREAY += yVel;

    if( ( box.y < 0 ) || ( box.y + DOT_HEIGHT > LEVEL_HEIGHT ) || touches_wall( box, tiles ) )
    {
        box.y -= yVel;
        AREAY -= yVel;
    }
            
        std::stringstream caption;
        caption << "DEMO " << box.x << "  " << box.y;
        SDL_WM_SetCaption( caption.str().c_str(), NULL );
    
}

void Dot::show()
{
    apply_surface( box.x - camera.x, box.y - camera.y, dot, screen );
}

void Dot::set_camera()
{
    if( ( AREAX >= SCREEN_WIDTH ) && ( box.x < LEVEL_WIDTH ) && ( xVel == 10 ) )
    {
        for( int SCROLL = 0; SCROLL < 650; SCROLL += 10 )
        {
             camera.x = SCROLL;
        }
        AREAX -= SCREEN_WIDTH;
    }
    
    if( ( AREAX <= -15 ) && ( box.x > 0 ) && ( xVel == -10 ) )    
    {
        for( int SCROLL = 650; SCROLL > -10; SCROLL -= 10 )
        {
             camera.x = SCROLL;
        }
        AREAX += SCREEN_WIDTH;
}

if( ( AREAY >= SCREEN_HEIGHT ) && ( box.y < LEVEL_HEIGHT ) && ( yVel == 10 ) )
{
    for( int SCROLL = 0; SCROLL < 490; SCROLL += 10 )
    {
         camera.y = SCROLL;
    }
    AREAY -= SCREEN_HEIGHT;
}

if( ( AREAY <= -15 ) && ( box.y > 0 ) && ( yVel == -10 ) )
{
    for( int SCROLL = 490; SCROLL > -10; SCROLL -= 10 )
    {
         camera.y = SCROLL;
    }
    AREAY += SCREEN_HEIGHT;
}

}

Timer::Timer()
{
    startTicks = 0;
    pausedTicks = 0;
    paused = false;
    started = false;
}

void Timer::start()
{
    started = true;

    paused = false;

    startTicks = SDL_GetTicks();
}

void Timer::stop()
{
    started = false;

    paused = false;
}

void Timer::pause()
{
    if( ( started == true ) && ( paused == false ) )
    {
        paused = true;

        pausedTicks = SDL_GetTicks() - startTicks;
    }
}

void Timer::unpause()
{
    if( paused == true )
    {
        paused = false;

        startTicks = SDL_GetTicks() - pausedTicks;

        pausedTicks = 0;
    }
}

int Timer::get_ticks()
{
    if( started == true )
    {
        if( paused == true )
        {
            return pausedTicks;
        }
        else
        {
            return SDL_GetTicks() - startTicks;
        }
    }

    return 0;
}

bool Timer::is_started()
{
    return started;
}

bool Timer::is_paused()
{
    return paused;
}

int main( int argc, char* args[] )
{
    bool quit = false;

    Dot myDot;

    Tile *tiles[ TOTAL_TILES ];

    Timer fps;

    if( init() == false )
    {
        return 1;
    }

    if( load_files() == false )
    {
        return 1;
    }

    clip_tiles();

    if( set_tiles( tiles ) == false )
    {
        return 1;
    }

    if( Mix_PlayMusic( music, -1 ) == -1 ) { return 1; }

    while( quit == false )
    {
        fps.start();

        while( SDL_PollEvent( &event ) )
        {
            myDot.handle_input();

            if( event.type == SDL_QUIT )
            {
                quit = true;
            }
        }

        myDot.move( tiles );

        myDot.set_camera();
        
        for( int t = 0; t < TOTAL_TILES; t++ )
        {
            tiles[ t ]->show();
        }

        myDot.show();

        if( SDL_Flip( screen ) == -1 )
        {
            return 1;
        }

        if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND )
        {
            SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );
        }
        
    }

    clean_up( tiles );

    return 0;
}
Title: Re: piworld PC
Post by: DJ Omnimaga on November 21, 2009, 02:39:13 pm
Cool, I hope you post some updates over here, not just ITS, though x.x. I doubt I would be able to help you much, though, since I don't know C and am not into compiling very much (as a non-Linux user, I kinda prefer when people give me the game exe if they want me to test)
Title: Re: piworld PC
Post by: miotatsu on November 21, 2009, 04:37:52 pm
i got this problem fixed, and now am working on getting a demo put together ^.^
Title: Re: piworld PC
Post by: Geekboy1011 on November 21, 2009, 05:53:56 pm
sweet XD
Title: Re: piworld PC
Post by: DJ Omnimaga on November 22, 2009, 12:40:11 am
Yay! It was kinda nice btw (after trying link on Skype), I can't wait to see it with other graphics and enemies around ^^

Btw, are u planning to have the same rooms and story as the calc version?
Title: Re: piworld PC
Post by: miotatsu on December 03, 2009, 12:17:51 am
The PC version will contain a much larger world but it will be based directly off of the calc version's current areas, new features in the PC version will include the ability to sail into the ocean and find new lands, a larger wilderness, and slightly modified areas to allow for a larger map expansion, it will also feature the ability to enter buildings and dungeons, there will be much more story line to the game and it won't be mainly focused on grinding, and it will continue off of the original piworld storyline (which as of now is not officially added into the calc version) and go into what will most likely become "Piworld II" which will most likely be my next calc project after piworld, also: i have decided on using a system where when you reach the side of the map it pauses, scrolls to the next screen and then continues, i currently have area changing working just fine, but i am having a very hard time with how to go about doing the pause&scroll part, right now im scrolling it internally, but i need to update the screen every loop which is easier said then done because of the way my code is set up, i plan on releasing a new demo /very/ soon and i will also post the source code on here again along with it, i would very much appreciate it if someone could help me out a little with the scrolling system (a spot in the credits awaits you ^.^)
Title: Re: piworld PC
Post by: DJ Omnimaga on December 03, 2009, 01:29:32 am
Nice, a bit like Zelda, The Windwaker, sort of?

Basically, I assume it will be like all piworld calc games merged into one?
Also glad to see more progress :)
Title: Re: piworld PC
Post by: miotatsu on December 03, 2009, 05:16:39 pm
it wont mainly be focused on sailing, the majority of the game will take place on land, but piworld in general is very heavily inspired by zelda so you can always expect similarities to a zelda game.
and yes, the pc version is going to be like all games in the series combined into one big game of epicness. i just need to finish a few small features, make some quick test sprites, and create a small starting world and i will release the next demo, it could be anywhere from later tonight to a few days depending on how things go.
Title: Re: piworld PC
Post by: DJ Omnimaga on December 03, 2009, 05:50:56 pm
Aaah ok. If you opt for sailing or travelling through very large fields, I recommend not making it as large as the Windwaker, though. I hated having to spend like 10 minutes early in the game to travel from an island to another
Title: Re: piworld PC
Post by: Tribal on December 05, 2009, 07:07:05 pm
Yay for demo v0.2!  :P

I hope this keeps progressing, it seems like it'll be quite fun.
Title: Re: piworld PC
Post by: miotatsu on December 05, 2009, 08:49:35 pm
indeed, i am wondering how i would go about a method to pause, scroll to the next screen, and then continue when you reach the side of the screen, as opposed to just panning the screen and then displaying it like i do now. today im going to start work on a map editor that deals with 40x40 and 40x40 tiles to go along with it
Title: Re: piworld PC
Post by: DJ Omnimaga on December 06, 2009, 12:15:36 am
Darn that ad pop up scared the shit out of me with the loud sounds x.x

Nice, though, I hope to see more progress soon :)

Keep us updated over here :)
Title: Re: piworld PC
Post by: Galandros on December 06, 2009, 05:28:15 pm
I am starting to comprehend a bit of C++ stuff just by some occasional code or documentation I see around...

Anyway what are the differences between the PC and calc versions?
Title: Re: piworld PC
Post by: miotatsu on December 06, 2009, 05:38:12 pm
right now the calc version has 6 areas, a warp tile, creatures to fight, npcs to talk to, and a Health display, as of now the PC version has only the basic core done to support map loading, collision detection and other events, and things of that sort, none of the content in the pc version is official yet except for the music.
Title: Re: piworld PC
Post by: miotatsu on December 23, 2009, 06:32:29 pm
I have some exciting news, today i received the source code for the BasiC++ project, as well as the source to an old program made by Acaceol. as of now i will be putting the development of Piworld and Piworld PC on hold for development of BasiC++ as i will be taking over that project. For those of you that don't know BasiC++ is a program that interprets code from a text file, it will be a way for people to easily program games for PC, the language is based directly off of Ti-Basic.
Title: Re: piworld PC
Post by: DJ Omnimaga on December 24, 2009, 01:06:45 am
Oooh nice to hear. I remember hearing about the BasicC++ thing. I might use it if it's close to TI-BASIC and has quite good speed in overall for 2D games
Title: Re: piworld PC
Post by: miotatsu on February 18, 2010, 11:45:35 pm
topic locked, going to make a new topic soon, and do the same to BasiC++, as well as a topic explaining why.