Ir ao conteúdo
  • Cadastre-se

C Sistema Solar (Allegro 4)


Posts recomendados

Para quem quiser testar (configure a resolução da tela que está em Fullscreen 1024x768) ou sugerir melhorias estou postando meu programa do sistema solar.

 

Deixei o tamanho dos planetas e estrela em escala, acho que fica mais interessante assim para comparar. Para mover a tela é só usar as setas.

 

Está rodando ok, mas o compilador está mostrando esse warning nas linhas das cores. O que pode ser?

 

Sistema.c(22) : warning C4761: integral size mismatch in argument; conversion supplied

 

Sistema.c

 

#include <allegro.h>
#include <math.h>
#include "sistema.h"

int main(){
    TELA     *T = iniciar(&tela);
    PLANETA  *P	= planetas;
    SATELITE *S	= satelites;
    ESTRELA  *E	= &sol;

    E->x = T->largura/2;
    E->y = T->altura/2 - 200;

    do{		
        controle(E);

        circlefill(
            T->buffer,
            E->x,
            E->y,
            E->raio/FTR,
            E->cor);

        P = atualiza(P,E);
        orbitar(T->buffer,P,E,TRUE,NULL);

        do{
            S = atualiza(S,P);
            if(S->id == P->id){
                orbitar(T->buffer,S,P,TRUE,E);
            }
        }while(S++->id != Netuno);

        S = satelites;

        if(P++->id == Netuno){
            draw_sprite(screen,T->buffer,0,0);
            clear_bitmap(T->buffer);
            P = planetas;
            S = satelites;
            draw_sprite(T->buffer,T->estrelas,0,0);
        }

        textprintf_ex(
            T->buffer,
            font,
            0,
            P->id*10,
            makecol(0,255,0),
            -1,
            "%10s | %.2fkm/s | %d",
            planome[P->id],
            P->velocidade,
            P->voltas);
    }while(!key[KEY_ESC]);
    sair(T);
    return 0;
}
END_OF_MAIN();

SATELITE *atualiza(SATELITE *satelite, CORPO *corpo){
    satelite->velocidade = 
        sqrt(G * corpo->massa/(1000 * satelite->distancia))/1000;

    satelite->angulo += satelite->velocidade / 50;

    if(satelite->voltas > 10000) satelite->voltas = 0;
    if(satelite->angulo > 360){
        satelite->angulo = 0;
        satelite->voltas++;
    }
    satelite->x = 
        (corpo->raio/FTR + satelite->distancia/FTD) * 
        cos(RAD(satelite->angulo));

    satelite->y = 
        (corpo->raio/FTR + satelite->distancia/FTD) * 
        sin(RAD(satelite->angulo));

    return satelite;
}

TELA *iniciar(TELA *tela){
    int i = 500;
    srand(time(0));
    allegro_init();
    install_keyboard();
    set_color_depth(32);
    set_gfx_mode(tela->gfxm,tela->largura,tela->altura,0,0);
    tela->estrelas = create_bitmap(tela->largura,tela->altura);
    tela->buffer = create_bitmap(tela->largura,tela->altura);
    clear_bitmap(tela->estrelas);

    while(i--){
        putpixel(tela->estrelas,
            rand() % tela->largura,
            rand() % tela->altura,
            makecol(255,255,255));
    }
    return tela;
};

void sair(TELA *buffer){
    destroy_bitmap(buffer->buffer);
    destroy_bitmap(buffer->estrelas);
    allegro_exit();
}

void orbitar(BITMAP *buffer, 
    SATELITE *satelite, 
    CORPO *corpo, 
    int mostra_orbita,
    ESTRELA *estrela){

    int eX = 0;
    int eY = 0;

    if(estrela != NULL){
        eX = estrela->x;
        eY = estrela->y;
    }

    if(mostra_orbita && estrela == NULL){
        circle(buffer,
            eX + corpo->x,
            eY + corpo->y,
            corpo->raio/FTR + satelite->distancia/FTD,
            makecol(30,30,30));
    }
    circlefill(buffer,
        eX + corpo->x + satelite->x * (eX ? 1.5 : 1),
        eY + corpo->y + satelite->y * (eY ? 1.5 : 1),
        satelite->raio/FTR,
        satelite->cor);	

    if(satelite->id == Saturno && !corpo->id){
        ellipsefill(buffer,
            eX + corpo->x + satelite->x * (eX ? 1.5 : 1),
            eY + corpo->y + satelite->y * (eY ? 1.5 : 1),
            satelite->raio/FTR*2,
            satelite->raio/FTR/3,
            0x737373);	
    }
}

void controle(ESTRELA *estrela){
    if(key[KEY_RIGHT]) estrela->x-=10;
    if(key[KEY_LEFT]) estrela->x+=10;
    if(key[KEY_UP]) estrela->y+=10;
    if(key[KEY_DOWN]) estrela->y-=10;
}

 

sistema.h

 

#include <allegro.h>
#include <math.h>

#ifndef SISTEMA_H
#define SISTEMA_H

#define FTR	2E+03
#define FTD	3E+06
#define RAD(x)((x)*AL_PI/180)
#define G 6.67E-11

typedef struct _corpo   PLANETA;
typedef struct _corpo   ESTRELA;
typedef struct _corpo   CORPO;
typedef struct _corpo   SATELITE;
typedef struct _tela    TELA;

enum Planetas{
    Mercurio,Venus,Terra,Marte,
    Jupiter,Saturno,Urano,Netuno};

const char *planome[] = {
    "Mercurio","Venus","Terra","Marte",
    "Jupiter", "Saturno","Urano","Netuno"
};

struct _tela{
    int largura;
    int altura;
    int gfxm;
    BITMAP *buffer;
    BITMAP *estrelas;
};

struct _tela tela = {
    1024,
    768,
    GFX_AUTODETECT_FULLSCREEN
};

struct _corpo{
    float massa;    //Kg
    float raio;     //Km
    float distancia;//Km
    long cor;
    int id;
    float angulo;
    float x;
    float y;
    float velocidade;//km/s
    int voltas;
};

TELA *iniciar(TELA *);
SATELITE *atualiza(SATELITE *, CORPO *);
void orbitar(BITMAP *, SATELITE *, CORPO *, int,ESTRELA *);
void sair(TELA *);
void controle(ESTRELA *);

ESTRELA sol     = {1.99E+30, 6.96E+05, 0, 0xff8000};
ESTRELA vega    = {4.25E+30, 1.96E+06, 0, 0xd9dbee};
ESTRELA capella = {5.11E+30, 8.33E+06, 0, 0xffffff}; 

PLANETA planetas[] = {
    {3.30E+23, 2.44E+03, 5.79E+07, 0xa9a9a9, Mercurio},
    {4.67E+24, 6.05E+03, 1.08E+08, 0xe18c00, Venus},
    {5.97E+24, 6.37E+03, 1.50E+08, 0x4682b4, Terra},
    {6.39E+23, 3.39E+03, 2.28E+08, 0xff0000, Marte},
    {1.90E+27, 6.99E+04, 7.79E+08, 0xf4a460, Jupiter},
    {5.68E+26, 5.82E+04, 1.43E+09, 0xa9a9a9, Saturno},
    {8.68E+25, 2.56E+04, 2.78E+09, 0xadd8e6, Urano},
    {1.02E+26, 2.46E+04, 4.50E+09, 0x4682b4, Netuno},
};

SATELITE satelites[] = {
    {7.34E+22, 1.74E+03, 3.84E+05, 0xf2f2f2, Terra,0},	/* Lua */
    {1.08E+03, 5.000000, 9.38E+03, 0xf2f2f2, Marte,0},	/* Fobos */
    {1.40E+15, 6.200000, 6.38E+03, 0xf2f2f2, Marte,0},	/* Deimos */
    {8.90E+22, 1.82E+03, 4.21E+05, 0xcccc00, Jupiter,0},/* Io */
    {4.80E+22, 1.56E+03, 6.70E+05, 0xd9dbee, Jupiter,0},/* Europa */
    {1.48E+23, 2.63E+03, 1.07E+06, 0xc0c4e4, Jupiter,0},/* Ganimedes */
    {1.08E+23, 2.41E+03, 1.89E+06, 0xb35900, Jupiter,0},/* Calisto */
    {1.34E+23, 2.57E+03, 1.22E+06, 0x00cc44, Saturno,0},/* Titã */
    {2.14E+22, 1.35E+03, 3.55E+05, 0xc0d6e4, Netuno,0}	/* Tritão */
};
#endif

 

  • Curtir 1
  • Amei 1
Link para o post
Compartilhar em outros sites

pena não ter os números de linha... Podia ter dito qual era :) Não tenho como compilar isso aqui, mas tem muitos campos short ou char ou unsigned então alguma variável na expressão está sendo convertida para algo menor nessa linha. É comum com as coordenadas

adicionado 0 minutos depois

Poste algumas imagens do programa... 🤔

Link para o post
Compartilhar em outros sites

@arfneto Os warnings são nas linhas do parâmetro color de circle/circlefull, p.ex nesta com makecol(30,30,30).

 

circle(buffer,
    eX + corpo->x,
    eY + corpo->y,
    corpo->raio/FTR + satelite->distancia/FTD,
    makecol(30,30,30));

 

Algumas imagens,

 

sistema01.png.dbc0565ebe91163e27d7bd4513840355.png

 

 

Fundo sem as estrelas para facilitar a visualização na imagem das luas orbitando os planetas,

 

sistema02.png.fde892115da3af709b7700db43235384.png

 

 

Júpiter orbitando uma estrela bem maior que o Sol para comparar a escala,

 

sistema03.png.0608f6a3c0b4a05c95ddc8decc6f3fec.png

  • Obrigado 1
Link para o post
Compartilhar em outros sites
7 horas atrás, Midori disse:

circle(
  buffer,
  eX + corpo->x,
  eY + corpo->y,
  corpo->raio/FTR + satelite->distancia/FTD,
  makecol(30,30,30)
);

 

 

Então... use um cast em cada um dos parâmetros de acordo com o esperado pela rotina.

 

  • Curtir 1
Link para o post
Compartilhar em outros sites

 

Fiz uma correção nesta função para o tempo de órbita ficar na proporção correta,

 

SATELITE *atualiza(SATELITE *satelite, CORPO *corpo){
    float orbita;
    float periodo;

    satelite->velocidade = 
        sqrt(G * corpo->massa/(1000 * satelite->distancia))/1000;

    orbita = 2 * AL_PI * satelite->distancia;
    periodo = orbita/satelite->velocidade/86400;
    satelite->angulo += (2 * AL_PI)/periodo;

    if(satelite->voltas > 10000) satelite->voltas = 0;
    if(satelite->angulo > 2 * AL_PI){
        satelite->angulo = 0;
        satelite->voltas++;
    }

    satelite->x = 
        (corpo->raio/FTR + satelite->distancia/FTD) * 
        cos(satelite->angulo);
	
    satelite->y = 
        (corpo->raio/FTR + satelite->distancia/FTD) * 
        sin(satelite->angulo);

    return satelite;
}

 

18 horas atrás, arfneto disse:

Então... use um cast em cada um dos parâmetros de acordo com o esperado pela rotina.

Com cast resolveu.

 

  • Curtir 1
Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora


Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

GRÁTIS: ebook Redes Wi-Fi

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!