Skocz do zawartości
Zamknięcie Forum PC LAB

Szanowny Użytkowniku,

Informujemy, że za 30 dni tj. 30 listopada 2024 r. serwis internetowy Forum PC LAB zostanie zamknięty.

Administrator Serwisu Forum PC LAB - Ringier Axel Springer Polska sp. z o.o. z siedzibą w Warszawie: wypowiada całość usług Serwisu Forum PC LAB z zachowaniem miesięcznego okresu wypowiedzenia.

Administrator Serwisu Forum PC LAB informuje, że:

  1. Z dniem 29 listopada 2024 r. zakończy się świadczenie wszystkich usług Serwisu Forum PC LAB. Ważną przyczyną uzasadniającą wypowiedzenie jest zamknięcie Serwisu Forum PC LAB
  2. Dotychczas zamowione przez Użytkownika usługi Serwisu Forum PC LAB będą świadczone w okresie wypowiedzenia tj. do dnia 29 listopada 2024 r.
  3. Po ogłoszeniu zamknięcia Serwisu Forum od dnia 30 października 2024 r. zakładanie nowych kont w serwisie Forum PC LAB nie będzie możliwe
  4. Wraz z zamknięciem Serwisu Forum PC LAB, tj. dnia 29 listopada 2024 r. nie będzie już dostępny katalog treści Forum PC LAB. Do tego czasu Użytkownicy Forum PC LAB mają dostęp do swoich treści w zakładce "Profil", gdzie mają możliwość ich skopiowania lub archiwizowania w formie screenshotów.
  5. Administrator danych osobowych Użytkowników - Ringier Axel Springer Polska sp. z o.o. z siedzibą w Warszawie zapewnia realizację praw podmiotów danych osobowych przez cały okres świadczenia usług Serwisu Forum PC LAB. Szczegółowe informacje znajdziesz w Polityce Prywatności

Administrator informuje, iż wraz z zamknięciem Serwisu Forum PC LAB, dane osobowe Użytkowników Serwisu Forum PC LAB zostaną trwale usunięte ze względu na brak podstawy ich dalszego przetwarzania. Proces trwałego usuwania danych z kopii zapasowych może przekroczyć termin zamknięcia Forum PC LAB o kilka miesięcy. Wyjątek może stanowić przetwarzanie danych użytkownika do czasu zakończenia toczących się postepowań.

Temat został przeniesiony do archiwum

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

Pulpit

[C] Podział na moduły

Rekomendowane odpowiedzi

Sz.P. ćwiczeniowiec ciągle mnie kara za to, że nie dzielę (poprawnie) programu na moduły :E Mam więc przykładowy kod, który chciałbym podzielić na moduły, żeby nie było np. "redeclaration" lub "undeclared" ;)

main.c

#include "include/config.h"

int main(int argc, char *args[])
{
   int IS_RUNNING = 1;

   init();
   load_files("images/bg.png");
   font = TTF_OpenFont("fonts/verdana.ttf", 28);
   message = TTF_RenderText_Solid(font, "Wcisnieto strzalke w dol", textColor);
   apply_surface(0, 0, image, screen);
   SDL_Flip(screen);

   // Petla glowna
   while (IS_RUNNING)
   {
       // Dopoki nie nacisniemy X lub ALT + F4
       while (SDL_PollEvent(&event) != SDL_QUIT)
       {
           if (event.type == SDL_KEYUP)
           {
               apply_surface(0, 150, message, screen);
               SDL_Flip(screen);
           }
       }
   }

   return 0;
}

init_functions.c

// Jak dam z include config.h to mam redeclaration, jak nie dam to mam undeclared
#include "include/config.h"

// Funkcja dodajaca zaladowany obraz na ekran
void apply_surface(int x, int y, SDL_Surface *source, SDL_Surface *destination)
{
   SDL_Rect offset;

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

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

// Funkcja ladujaca obrazy aby pasowaly do ustalonego BPP (bits per pixel)
SDL_Surface *load_image(char *filename)
{
   SDL_Surface *loaded_image = NULL;
   SDL_Surface *optimized_image = NULL;

   loaded_image = IMG_Load(filename);

   if (loaded_image != NULL)
   {
       optimized_image =  SDL_DisplayFormat(loaded_image);
       SDL_FreeSurface(loaded_image);
   }

   return optimized_image;
}

// Inicjalizacja bibliotek i okna
void init()
{
   SDL_Init(SDL_INIT_EVERYTHING);
   TTF_Init();

   screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
   SDL_WM_SetCaption("Statki v0.1", NULL);
}

// Funkcja wczytujaca plik o podanej nazwie
void load_files(char *filename)
{
   image = load_image(filename);
}

// Funkcja czyszczaca pamiec z zaladowanych plikow i zamykajaca okienko
void clean_up()
{
   SDL_FreeSurface(image);
   SDL_FreeSurface(message);

   TTF_Quit();
   SDL_Quit();
}

config.h

#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>

// Deklaracja wielkosci okienka oraz glebi kolorow
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

// === Prototypy funkcji ===
//
// Funkcje z init_functions.c
void apply_surface(int x, int y, SDL_Surface *source, SDL_Surface *destination);
SDL_Surface *load_image(char *filename);
void init();
void load_files(char *filename);
void clean_up();

// Zmienne obrazu
SDL_Surface *image = NULL;
SDL_Surface *message = NULL;
SDL_Surface *screen = NULL;

// Zmienne czcionek
TTF_Font *font = NULL;
SDL_Color textColor = {255, 255, 255};

// Zmienne zdarzeniowe
SDL_Event event;

Jak kompiluje taką strukturę projektu w CodeBlocks dostaję błędy typu

obj\Release\init_functions.o:init_functions.c:(.rdata+0xc): multiple definition of `SCREEN_WIDTH'

obj\Release\main.o:main.c:(.rdata+0x3c): first defined here

obj\Release\init_functions.o:init_functions.c:(.rdata+0x10): multiple definition of `SCREEN_HEIGHT'

Co jest logiczne, no bo w dwóch plikach inkluduję config.h. Pytanie brzmi, jak to powinno wyglądać poprawnie :hmm:

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

poczytaj sobie o #ifdef oraz #ifndef

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Czyli w main.c powinienem mieć

#include "include/config.h"

int main(){
   zmienna = 5;
   blabla(zmienna);
}

w init_functions.c

#include "include/config.h"

#ifndef _INCLUDE_CONFIG_H_
int zmienna;
#endif

void blabla(int x) {
// ...
}

 

include/config.h

#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>

extern int zmienna = 100;

void blabla(int x);

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

problemem jest definiowanie zmiennych (klas, itd) w plikach nagłówkowych; gdyby był jakiś sposób, za pomocą którego można by było w takim pliku nagłówkowym sprawdzić czy został już wcześniej użyty i odpuścić całą jego treść w takim wypadku, to by było świetnie

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Czyli jaki z tego wniosek płynie? Poza tym, że nic nie rozumiem w ciągu dalszym?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ok mam. W plikach .c w jednym (najlepiej main.c) powinienem zrobić deklaracje zmiennych i prototypów funkcji, we wszystkich .c mogę wtedy dołączać pliki nagłówkowe .h jednak każda zmienna jaka tam jest itd. musi mieć extern np.

main.c

#include "config.h"

int zmienna = 10;
void Funkcja();

int main()
{
   Funkcja();

   return 0;
}

funkcje.c

#include "config.h"

void Funkcja()
{
   printf("%d", zmienna);
}

config.h

#include <stdio.h>
extern int zmienna;
extern void Funkcja();

Nie jestem tylko pewien czy przy prototypach funkcji też trzeba dawać extern? :hmm:

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

#ifndef / #endif masz dać do pliku .h a nie .c - konkretnie tak

 

config.h

#ifndef _INCLUDE_CONFIG_H_
#define _INCLUDE_CONFIG_H_

// definicje
.
.
.
.

#endif

dzięki temu jak masz kilka #include "config.h" to kolejne już nie przedeklarują symboli

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Od razu się podepnę, jeżeli mam w bibliotece allegro stworzona bitmape, ktora jest kwadratem 50x50, o pozycji poczatkowej (lewy górny róg) 100, 100 (okienko ma 640x480) to jeżeli chce go przesunąć razem z myszką to mam

if (mouse_b)

{

box_x = mouse_x;

box_y = mouse_y;

}

Tylko, że to ustawia lewy górny róg pozycji boxa na pozycji myszki (przeskakuje), a ja chcę żeby przesuwało dokładnie względem pozycji myszki na boxie (jeżeli rozumiecie o co mi chodzi) czyli jeżeli kliknę na środku to mam przesuwać tak jak trzymam, a nie najpierw mi przesunie pozycję boxa lewy-górny-róg == pozycja myszki i dopiero potem względem tego mi przesuwa. Z tak późnej pory wychodzi mi tylko box_x = mouse_x+(mouse_x-box_x) jednak to nie działa poprawnie, a ja nie mogę ogarnąć tak prostego równania :E

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

po naciśnięciu guzika określasz początkowe x i y myszki, po przesunięciu myszki z guzikiem określasz aktualne x i y, z tego liczysz delta, przesuwasz obrazek o delta

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Problem w tym, że w allegro nie mogę się doszukać czegokolwiek pokroju onmousemotion().

Rozumiem to tak, że algorytm ma wyglądać:

1. Jeżeli myszka w kwadracie czyli: (x>box_x && x < box_x+szer) && (y>box_y && y < box_y+szer)

1. Jeżeli niewciśnięta

- mx_b = mx;

- my_b = my;

2. Jeżeli myszka wciśnięta

- box_x += mx-mx_b;

- box_y += my-my_b;

Tylko, że to mi będzie tylko raz zapamiętywało pozycje przed ruchem myszki (wnioskuję, że ruch myszki to będzie moment, w którym użytkownik wciśnie lewy przycisk myszki). Zakodowałem to tak

if ((mx > box_x && mx < box_x+100) && (my > box_y && my < box_y + 100))
{
   if (mb != 1)
   {
       mx_b = mx;
       my_b = my;
   }
   else
   {
       box_x = mx - mx_b;
       box_y = my - my_b;
   }
}

Jednak jest tak jak napisałem. Nie wiem jak sprawdzać czy myszka jest w ruchu :hmm:

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

allegro chodzi w pętli, więc jak naciśniesz guzik na obrazku zapamiętujesz że jest drag&drop; pętla idzie kolejny raz, widzisz w niej d&d, odczytujesz nowe położenie myszki, liczysz delta, przesuwasz obrazek; puszczasz guzik, było d&d to kolejny raz przesuwasz obrazek, nie było d&d to nic nie robisz

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×
×
  • Dodaj nową pozycję...