Jump to content
A 2021 backup has been restored. Forums are closed and work in progress. Join our Discord server for more updates! ×
SoaH City Message Board

Post your screenshots thread


Rael0505

Recommended Posts

I0LZNdS.pngRecognize something? Yeah, the beta goggles. I implemented it in the game.

 

Nice. Are they used like the bubble shield? Do you lose them when you get hit?

 

Screenshot of a brand new stage in Sonic Adventure Emerald. When I say brand new this stage hasn't been in any version of the game.

utZuPgc.png

 

I like the design of your HUD, though I feel like it's too big for the viewport size...

 

 

 

 

Also, a little something I made with 4 hours, using the same Oficina Framework that I used to create the Mario you guys seen earlier on this same thread.

It's pretty obvious that it's a Flappy Bird clone, yeah, but I did it mostly because I was defied to; I did it with the purpose of showing that this game is NOT something special, and is NOT hard to make, if you're thinking about making your games, and that pure programming is hard.

 

Kq3mw03.png

c1r5aOP.png

uSsm8u3.png

 

If anyone's interested, I'd gladly provide a download link (x86_64 Linux only for now, I'm sorry. I might provide a 32-bit Windows executable soon, who knows) and the source code (though the source code runs over Oficina's library, which isn't opensource, at least for now; but it'd serve to show the algorithm itself).

Please notice I (thankfully) don't have the rights over Shitty Flappy Bird.

 

EDIT: I'll just drop the code anyway, I don't have to hide it. Prepare for bad programming.

#include <OficinaFramework/OficinaFramework.h>
using namespace OficinaFramework;
// 1m = 100px
#define M2P(x) (x*100.0f)
#define P2M(x) (x/100.0f)
// Fonte para o debugger
RenderingSystem::Texture* font_texture;
RenderingSystem::Font* font;
AudioSystem::SFX* sfx_coin,
                * sfx_shatter,
                * sfx_swooper;
RenderingSystem::Texture* m_pipe_texture;
const float m_gravity = 9800000.0f;
bool gameplaying = false;
int score = 0;
int best[5] = {0};
 
const float easy_speed   = 2.5f,
            normal_speed = 3.5f,
            hard_speed   = 5.0f,
            veryhard_speed  = 6.8f,
            ninja_speed = 10.0f;
float difficulty_speed = easy_speed;
 
int difficulty = 0;
 
float random_float()
{
    return ((float)rand() / RAND_MAX);
}
 
float generate_pipe_gap_center()
{
    switch(difficulty) {
    case 0:
        // Easy mode
        return (random_float() * 114.0f) + 183.0f;
    case 1:
        // Normal mode
        return (random_float() * 178.0f) + 119.0f;
    case 2:
    case 4:
        // Hard mode / Ninja mode
        return (random_float() * 242.0f) + 55.0f;
    case 3:
        // Very Hard mode
        //return (random_float() * 480.0f);
        //return (random_float() * 416.0f) + 32.0f;
        return (random_float() * 384.0f) + 64.0f;
    }
    // if by any change I someday make a training mode.
    return RenderingSystem::GetViewportSize().y / 2.0f;
}
 
class Pipe : public EntitySystem::DrawableEntity
{
private:
    bool spawned_friend = false;
    bool m_upside;
    bool scored = false;
public:
    Pipe(bool upside, float gapcenter)
    {
        SetName("Pipe");
        m_upside = upside;
        if(upside) {
            m_orientation = RenderingSystem::RENDER_NORMALLY;
            m_position.y = gapcenter + (difficulty == 4 ? 41.25f : ( difficulty == 0 ? 65.5f : 55.0f )  );
            //m_position.y = gapcenter + 55.0f;
        }
        else {
            m_orientation = RenderingSystem::RENDER_FLIP_Y;
            m_position.y = gapcenter - 480.0f - (difficulty == 4 ? 41.25f : ( difficulty == 0 ? 65.0f : 55.0f ) );
            //m_position.y = gapcenter - 480.0f - 55.0f;
        }
 
        m_position.x = RenderingSystem::GetViewportSize().x + 80.0f;
    }
 
    void Init() override {}
    void LoadContent() override {}
    void UnloadContent() override {}
 
    void Update() override
    {
        if(gameplaying)
            m_position.x -= difficulty_speed * TimingSystem::StepCorrection();
 
        if(m_position.x <= -80.0f)
            RemoveMe();
 
        // Adiciona mais. Apenas o cano de baixo executa esta ação
        if(m_upside && !spawned_friend
           && m_position.x <= (difficulty == 3 ? (640.0f - 512.0f)  :  (difficulty == 4 ? 64.0f : (640.0f - 256.0f))))
        {
            spawned_friend = true;
            float center_pipe = generate_pipe_gap_center();
            GetParent()->Add("_pipe", new Pipe(false, center_pipe));
            GetParent()->Add("_pipe", new Pipe(true, center_pipe));
        }
    }
 
    void Draw() override
    {
        m_pipe_texture->Draw(m_position, // Posição
                             m_pipe_texture->GetSize().toVec2(), // Tamanho do contêiner
                             vec2::Zero(), // Posição superior esquerda do sampler
                             m_pipe_texture->GetSize().toVec2(), // Tamanho do sampler
                             0.0f, // Ângulo
                             1.0f, // Transparência
                             vec2::Zero(), // Hotspot
                             Color4::MaskToColor4(WHITE), // Cor de pintura do sampler
                             m_orientation); // Orientação
    }
 
    void CountToScore()
    {
        if(m_upside && !scored && m_position.x <= 16.0f)
        {
            score++;
            scored = true;
            AudioSystem::PlaySFX(sfx_coin);
        }
    }
};
 
class Bird : public EntitySystem::DrawableEntity
{
private:
    RenderingSystem::Texture* m_bird_texture;
    float m_yspeed;
    float m_meteryspeed;
    const float m_terminalvelocity = 10000.0f;
    vec2 m_meterposition;
 
    // Hitbox do pássaro é um círculo, porque sou um cara legal.
    const float m_circle_r = 10.0f;
 
public:
    void Init() override
    {
        SetName("Bird");
        Reposition();
        SetDrawDepth(1.0f);
    }
 
    void LoadContent() override
    {
        m_bird_texture = RenderingSystem::TexturePool::LoadTexture("sprites/bird.png");
    }
 
    void UnloadContent() override
    {
        RenderingSystem::TexturePool::DisposeTexture(m_bird_texture);
    }
 
    void Update() override
    {
        // Aplicando gravidade
        // Como estamos lidando com uma quantidade variada de quadros
        // por segundo no jogo, a gravidade requer modelagem sobre as
        // leis de movimento uniformemente variado e a variação de tempo
        // entre os quadros.
 
        if(gameplaying)
        {
            // Por padrão, devemos converter o DeltaTime da Oficina de ms para s
            float m_delta_yspeed = m_gravity * (TimingSystem::GetDeltaTime() / 1000.0f);
            float m_meteryspeed_new = m_meteryspeed + m_delta_yspeed;
            clamp(m_meteryspeed, -m_terminalvelocity, m_terminalvelocity);
            m_meterposition.y += (TimingSystem::GetDeltaTime() / 1000.0f) * (m_meteryspeed + m_meteryspeed_new) / 2.0f;
            m_meteryspeed = m_meteryspeed_new;
            m_position = M2P(m_meterposition);
            m_yspeed = M2P(m_meteryspeed) / 100000.0f;
 
 
            // Impulso ao apertar o botão
            if(InputSystem::PressedButton(InputSystem::GamePadButton::A))
            {
                m_meteryspeed = -3550.0f;
                InputSystem::Rumble(0.5f, 250u);
                AudioSystem::PlaySFX(sfx_swooper);
            }
 
            // Efeito: altere o ângulo de acordo com a velocidade de queda
            // e subida
            m_angle = -22.5f + (45.0f * (m_yspeed + 3.0f) / 6.0f);
 
            // Detecção de colisão
            for(auto e : *GetParent())
            {
                if(e.second->GetName() == "Pipe")
                {
                    if(IsCollidingWithPipe(e.second->GetPosition())) {
                        gameplaying = false;
                        AudioSystem::PlaySFX(sfx_shatter);
                        if(score > best[difficulty]) best[difficulty] = score;
                    }
                    else
                    {
                        Pipe* p = (Pipe*)e.second;
                        p->CountToScore();
                    }
                }
            }
 
            // Não sair da play area
            if(m_meterposition.y < 0.0f)
                m_meterposition.y = 0.0f;
            if(m_position.y >= 480.0f + m_circle_r) {
                gameplaying = false;
                AudioSystem::PlaySFX(sfx_shatter);
                if(score > best[difficulty]) best[difficulty] = score;
            }
        }
        else
        {
            m_meteryspeed = m_yspeed = 0.0f;
        }
 
        // Output do debugger
        stringstream ss;
        ss << "Y Position (m):  " << m_meterposition.y << endl
           << "Y Position (px): " << m_position.y << endl
           << "Y Speed (m/s):   " << m_meteryspeed << endl
           << "Y Speed (px/ms): " << m_yspeed << endl
           << "Angle:           " << m_angle << endl;
        ScreenSystem::Debug_AddLine(ss.str());
    }
 
    void Draw() override
    {
        m_bird_texture->Draw(m_position, // Posição
                             m_bird_texture->GetSize().toVec2(), // Tamanho do contêiner
                             vec2::Zero(), // Posição superior esquerda do sampler
                             m_bird_texture->GetSize().toVec2(), // Tamanho do sampler
                             m_angle, // Ângulo
                             1.0f, // Transparência
                             (m_bird_texture->GetSize().toVec2() / 2.0f), // Hotspot
                             Color4::MaskToColor4(WHITE)); // Cor de pintura do sampler
    }
 
 
    bool IsCollidingWithPipe(vec2 pipePosition)
    {
        vec2 true_position = m_position;
        vec2 closest = true_position;
        clamp(closest.x, pipePosition.x, pipePosition.x + 64.0f);
        clamp(closest.y, pipePosition.y, pipePosition.y + 480.0f);
        vec2 delta(true_position.x - closest.x, true_position.y - closest.y);
        float squareDistance = (delta.x * delta.x) + (delta.y * delta.y);
        return (squareDistance <= (m_circle_r * m_circle_r));
    }
 
    void Reposition()
    {
        m_position = vec2(80.0f, RenderingSystem::GetViewportSize().y / 2.0f);
        m_meterposition = P2M(m_position);
        m_yspeed = m_meteryspeed = 0.0f;
    }
};
 
class PlayScreen : public ScreenSystem::Screen
{
    EntitySystem::DrawableEntityCollection drawables;
public:
    ~PlayScreen()
    {
    }
 
    void Initialize() override
    {
        SetActive(true);
        SetVisible(true);
        drawables.Add("_bird", new Bird);
        // Crie o primeiro
        float center_pipe = generate_pipe_gap_center();
        drawables.Add("_pipe", new Pipe(false, center_pipe));
        drawables.Add("_pipe", new Pipe(true, center_pipe));
        drawables.Init();
        InputSystem::StartJoystickRumbleSupport();
        ScreenSystem::Screen::Initialize();
    }
 
    void ReInitialize() override
    {
        for(auto e : drawables)
        {
            if(e.second->GetName() == "Pipe")
                e.second->RemoveMe();
            else if(e.second->GetName() == "Bird")
            {
                Bird* b = (Bird*)e.second;
                b->Reposition();
            }
        }
        float center_pipe = generate_pipe_gap_center();
        drawables.Add("_pipe", new Pipe(false, center_pipe));
        drawables.Add("_pipe", new Pipe(true, center_pipe));
        score = 0;
 
        switch(difficulty) {
        case 0:
            difficulty_speed = easy_speed;
            break;
        case 1:
            difficulty_speed = normal_speed;
            break;
        case 2:
            difficulty_speed = hard_speed;
            break;
        case 3:
            difficulty_speed = veryhard_speed;
            break;
        case 4:
            difficulty_speed = ninja_speed;
            break;
        }
 
        gameplaying = true;
    }
 
    void LoadContent() override
    {
        drawables.LoadContent();
        m_pipe_texture = RenderingSystem::TexturePool::LoadTexture("sprites/pipe.png");
        sfx_coin = AudioSystem::AudioPool::LoadSFX("sound/coin.ogg");
        sfx_shatter = AudioSystem::AudioPool::LoadSFX("sound/shatter.ogg");
        sfx_swooper = AudioSystem::AudioPool::LoadSFX("sound/swooper.ogg");
        ScreenSystem::Screen::LoadContent();
    }
 
    void UnloadContent() override
    {
        // Save high scores
        FILE* fp;
        fp = fopen("highscores.txt", "w");
        if(fp) {
            for(int i = 0; i < 5; i++)
                fprintf(fp, "%d\n", best[i]);
            fclose(fp);
        }
 
        drawables.UnloadContent();
        RenderingSystem::TexturePool::DisposeTexture(m_pipe_texture);
        AudioSystem::AudioPool::DisposeAudio(sfx_coin);
        AudioSystem::AudioPool::DisposeAudio(sfx_shatter);
        AudioSystem::AudioPool::DisposeAudio(sfx_swooper);
        InputSystem::StopJoystickRumbleSupport();
        ScreenSystem::Screen::UnloadContent();
    }
 
    void Update() override
    {
        drawables.Update();
        if(InputSystem::PressedButton(InputSystem::GamePadButton::LSHOULDER1))
        {
            ScreenSystem::SetDebug(!ScreenSystem::IsDebugActive());
        }
        else if(InputSystem::PressedButton(InputSystem::GamePadButton::START))
        {
            if(!gameplaying)
                ReInitialize();
        }
 
        if(!gameplaying)
        {
            if(InputSystem::PressedButton(InputSystem::GamePadButton::HAT_DOWN))
                if(difficulty < 4) difficulty++;
            if(InputSystem::PressedButton(InputSystem::GamePadButton::HAT_UP))
                if(difficulty > 0) difficulty--;
        }
    }
 
    void Draw() override
    {
        drawables.Draw();
        stringstream scoretext;
        scoretext << "Score: " << score;
        if(best[difficulty]) scoretext << endl << "Best:  " << best[difficulty];
        font->DrawString(vec2(320.0f,400.0f) - (font->MeasureString(scoretext.str(), 2.0f) / 2.0f),
                           scoretext.str(), 2.0f);
 
        if(!gameplaying) {
            vec2 difficultytext_halfsize = font->MeasureString("Difficulty:\nEasy\nNormal\nHard\nVery Hard\nNinja", 2.0f) / 2.0f;
            vec2 difficultytext_pos = vec2(RenderingSystem::GetViewportSize().toVec2().x / 2.0f, 66.0f) - difficultytext_halfsize;
 
            RenderingSystem::DrawRectangle(vec2(difficultytext_pos.x - (difficultytext_halfsize.x / 4.0f), difficultytext_pos.y + 30.0f + (22.0f * float(difficulty))),
                                           vec2(5.0f), 45.0f, WHITE, 0.7f);
 
            font->DrawString(difficultytext_pos, "Difficulty:\nEasy\nNormal\nHard\nVery Hard\nNinja", 2.0f);
 
            switch(InputSystem::GetType()) {
            case InputSystem::Type::KEYBOARD:
                font->DrawString(vec2(RenderingSystem::GetViewportSize().toVec2() / 2.0f) - (font->MeasureString("Press Enter to Retry", 4.0f) / 2.0f),
                        "Press Enter to Retry", 4.0f);
                font->DrawString(vec2(RenderingSystem::GetViewportSize().toVec2() / 2.0f) - (font->MeasureString("\n\n\n\n\nTip: Tap Space to make the bird jump", 1.0f) / 2.0f),
                        "\n\n\n\n\nTip: Tap Space to make the bird jump", 1.0f);
                break;
            case InputSystem::Type::XBOXPAD:
                font->DrawString(vec2(RenderingSystem::GetViewportSize().toVec2() / 2.0f) - (font->MeasureString("Press Start to Retry", 4.0f) / 2.0f),
                    "Press Start to Retry", 4.0f);
                font->DrawString(vec2(RenderingSystem::GetViewportSize().toVec2() / 2.0f) - (font->MeasureString("\n\n\n\n\nTip: Tap A to make the bird jump", 1.0f) / 2.0f),
                    "\n\n\n\n\nTip: Tap A to make the bird jump", 1.0f);
                break;
            case InputSystem::Type::JOYPAD:
                font->DrawString(vec2(RenderingSystem::GetViewportSize().toVec2() / 2.0f) - (font->MeasureString("Press Start to Retry", 4.0f) / 2.0f),
                    "Press Start to Retry", 4.0f);
                font->DrawString(vec2(RenderingSystem::GetViewportSize().toVec2() / 2.0f) - (font->MeasureString("\n\n\n\n\nTip: Tap Button 1 to make the bird jump", 1.0f) / 2.0f),
                    "\n\n\n\n\nTip: Tap Button 1 to make the bird jump", 1.0f);
                break;
            }
        }
    }
};
 
 
int main(int argc, char** argv)
{
    srand(time(NULL));
    std::list<string>* confv = new std::list<string>;
    confv->push_back("gamename=Shitty Bird");
    confv->push_back("resolution=640x480");
    confv->push_back("windowsize=640x480");
 
    EngineCore::Initialize(argc, argv, confv);
    IOSystem::AddToSearchPath("data");
    // Barra de espaço e botão "A" do controle funcionam para o mesmo propósito
    InputSystem::BindKey(SDLK_SPACE, InputSystem::GamePadButton::A);
    // Outros botões
    InputSystem::BindKey(SDLK_F1, InputSystem::GamePadButton::LSHOULDER1);
    InputSystem::BindKey(SDLK_RETURN, InputSystem::GamePadButton::START);
    InputSystem::BindKey(SDLK_DOWN, InputSystem::GamePadButton::HAT_DOWN);
    InputSystem::BindKey(SDLK_UP, InputSystem::GamePadButton::HAT_UP);
 
    // Coloca-se a fonte no debugger para que ele possa aparecer
    font_texture = RenderingSystem::TexturePool::LoadTexture("fonts/gohufont-6-11-pad1.png");
    font = new RenderingSystem::Font(font_texture, vec2dw(6,11), vec2b::One());
    ScreenSystem::Debug_SetFont(font);
    // Adiciona-se a tela de jogo
    ScreenSystem::AddScreen(new PlayScreen, 1.0f);
    RenderingSystem::SetLinearFiltering(false);
 
 
    // Load High Scores
    FILE* fp;
    fp = fopen("highscores.txt", "r");
    if(fp) {
        for(int i = 0; i < 5; i++)
            fscanf(fp, "%d", &best[i]);
        fclose(fp);
    }
 
 
    return EngineCore::DoGameLoop();
}

Edited by luksamuk
  • Like 1
Link to comment
Share on other sites

I'm not announcing anything with this but its something I'm trying out

bandicam_2014_09_03_00_07_27_966.png3D tile sets ahoy

 

I've also been rebuilding Havok Harbor into a single 3D model to help improve performance. The level was built like legos, so it was rendering the shadows of 12 billion separate rectangles at any given time in the original.

bandicam_2014_09_03_00_22_58_097.png

All the textures are mapped as well and look fine. I do this in my free time when I'm not working on other projects, so no clue when this will be done.

Edited by Highwire4
  • Like 4
Link to comment
Share on other sites

 

I've also been rebuilding Havok Harbor into a single 3D model to help improve performance. The level was built like legos, so it was rendering the shadows of 12 billion separate rectangles at any given time in the original.

 

Woah is it supposed to do that? There's no culling feature for shadows? 

 

Don't know much about 3D gaming, but that seems like a bad idea.

Link to comment
Share on other sites

Woah is it supposed to do that? There's no culling feature for shadows? 

 

Don't know much about 3D gaming, but that seems like a bad idea.

There is culling for shadows, and if you have a decent computer its usually not an issue, but for lower end computers and for a few special  cases it destroys the frame rate. Its just the sheer number of individual objects that are having lighting interact with them that's the problem. Literally every single container in the original is a separate model that has lights hitting it that have to be computed from all sides of that rectangle. Thats a lot of polygons and a lot of dynamic shadows that have to be accounted for in the engine, it can be very taxing on some computers. 

With the new method I'm doing now, I've more than halved the polygon count in the level and given the engine less work to do.

  • Like 1
Link to comment
Share on other sites

Bigger models are less taxing by far. If you build a level out of "legos" then each lego has 6 sides assuming we're talking about rectangles. Where if you build a single large model you only draw the sides actually seen by the player.

 

Well as far as I understand (I went to school for 3D stuff but I haven't touched it in like 3 years so I've forgotten some shit) at the same time one big model for the entire level can be detrimental too. If the scale is extremely big you're going to want to have sections that aren't loaded in all the time and/or if an object is far away to have different LOD for them just to save on memory. I mean you can easily get an engine to only draw out the parts it needs to. As well as if you're modeling a level where say you will only ever see 3 sides of the lego why bother modeling the other 3 sides at all?  I mean I guess there are pros and cons to each but like I said I haven't touched 3D in about 3-4 years now.

  • Like 2
Link to comment
Share on other sites

Having many models is bad as there are far too many sides that will cause loading times to be slow and for the game to run.. slow. Having too huge models, will cause glitches such as now loading in time, sudden slowdowns, and maybe freezes. It should be done stretch by stretch, it's how Sonic Team did it in Generations, Unleashed, Heroes and Adventure. A mid point between both I guess. 

Link to comment
Share on other sites

Well as far as I understand (I went to school for 3D stuff but I haven't touched it in like 3 years so I've forgotten some shit) at the same time one big model for the entire level can be detrimental too. If the scale is extremely big you're going to want to have sections that aren't loaded in all the time and/or if an object is far away to have different LOD for them just to save on memory. I mean you can easily get an engine to only draw out the parts it needs to. As well as if you're modeling a level where say you will only ever see 3 sides of the lego why bother modeling the other 3 sides at all?  I mean I guess there are pros and cons to each but like I said I haven't touched 3D in about 3-4 years now.

 

This is what I was getting at. Seems like for practicality the stage should be loaded in compartments as needed. This is why I asked about culling the shadows. It shouldn't be wasting time drawing shadows on surfaces that are impossible to see from any viewpoint anyway.

 

Then again, i have no clue how hard that is to implement. So if you can get the same result out of modeling the stage as one huge object, then that's a viable hack to the problem.

Link to comment
Share on other sites

pCCg7H1.png

Marvelous Mas (iz du name of du game) now has this little title card thingy, acepoints (those white squares that are the equivalent of coins/rings), an insta-shield-esque attack (das alotta hyphens), a functioning health bar epH3U50.png, and a lot of other kewl shiet. I should probably make a thread for this. Also, I'm hoping to release a 1 level (at least) demo for this game at SAGE 2015 Act 1. Inb4 graphics are too saturated, ugly straight line going through Mas, 0/10 Not bad - IGN.

  • Like 1
Link to comment
Share on other sites

Here's a video of my another hack(Sonic: Emerald Land). Showing a TropicalRevoid(Green Hill Zone) act1, the level is not 100% complete but is playable. So enjoy the video guys:

Comment and criticism welcome!

 

Although this is a hack and this kind of criticism must be approached very carefully, I feel like the music simply doesn't match the level, nor the game. All the music: Title Screen, Speed Sneakers, the level music.

It simply feels like it doesn't fit, and although this might be the instruments' fault, I feel like varying the instruments more won't solve the issue, but I have yet to hear this variation of instruments to be sure.

Link to comment
Share on other sites

Hey guys. I just joined this site and figured I'd start off with a few screenshots from the hack I've been working on.

 

This is Sonic: Super Deformed. So far, the people working on this are few in number. However, we are striving for quality. :)

 

Title Screen:

SSD_000-1.png

 

Summer Shoreline Zone:

SSZScreenshotmockup_zps8f8381a4.png

 

Mockup of level title cards (and older Summer Shoreline Zone artwork):

newtitlecardmockup.png

 

You can find more information about this hack on the Sonic Retro info page.

  • Like 12
Link to comment
Share on other sites

Welcome to the forums Hitaxas. The hack looks great so far, I wouldn't know if it was a hack if you hadn't told us.

FRIENDLY REMINDER TO BACK UP YOUR HARD RIVES

My computer died over the weekend and took EVERYTHING with it. I'm still sorting through what data I have and what data I've lost. I've got some basic data of Sonic Lost Adventure backed up but I don't know if it's up to date, meaning the source code for v1.2 could be lost. Blackshore Meltdown is currently unknown but I think it might be lost as well. If that is the case then development on that game is over. This soo sucks.

SO AGAIN. REMINDER TO BACK UP YOUR SHIT

  • Like 5
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...