Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: C: Kasvava lima

T.M. [18.07.2006 23:35:31]

#

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <SDL/SDL.h>
#include <math.h>


// Load object files:
//   Dev-Cpp\Lib\libSDL.a


// Ikkunan koko:
int leveys = 640;
int korkeus = 480;


void putpixel(SDL_Surface *screen, int x, int y, Uint32 color);
void imagefilledrect(SDL_Surface *screen, int x1, int y1, int x2, int y2, Uint32 color);


void scan_possible(Uint8 *data, Uint8 *pos, int lev, int kor){
    // Kasvava lima by T.M. - www.HC-Codes.net
    int x, y;
	for(y = 0; y < kor; y++){
		for(x = 0; x < lev; x++){
			if(data[y*lev+x] == 1){
				if(y > 0) if(data[(y-1)*lev+x] == 0) pos[(y-1)*lev+x] = 1;
				if(x < lev-1) if(data[y*lev+x+1] == 0) pos[y*lev+x+1] = 1;
				if(y < kor-1) if(data[(y+1)*lev+x] == 0) pos[(y+1)*lev+x] = 1;
				if(x > 0) if(data[y*lev+x-1] == 0) pos[y*lev+x-1] = 1;
			}
		}
	}
}

void grow_random(Uint8 *data, Uint8 *pos, int lev, int kor, int ran){
    // Kasvava lima by T.M. - www.HC-Codes.net
    int x, y;
    Uint8 *m = data;
    Uint8 *p = pos;
	for(y = 0; y < kor; y++){
		for(x = 0; x < lev; x++){
			if(*p == 1){
				if(rand()%ran == 0){
					*m = 1;
				}
			}
            p++;
            m++;
		}
	}
}



int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow){
    if(SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0){
		printf("Unable to init SDL: %s\n", SDL_GetError());
		exit(1);
	}
    SDL_WM_SetCaption("Kasvava lima - TM", NULL);

	atexit(SDL_Quit);
	SDL_Surface *screen;
    SDL_Event event;

	screen = SDL_SetVideoMode(leveys, korkeus, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
	if(screen == NULL){
		printf("Unable to set video mode: %s\n", SDL_GetError());
		exit(1);
	}
	int done = 0;

    Uint8* nappi;
    int mouse;
    int mx, my;

    int areagrow = 0; // Laskuri sille mikä etsii mahdolliset kasvatuspisteet
    int growrandom = 0; // Laskuri sille mikä kasvattaa limaa

    int areagrow_speed = 10; // Kuinka usein uusi kasvatettava alue etsitään (suurempi harvemmin)
    int growrandom_speed = 0; // Kuinka usein aluetta kasvatetaan (suurempi harvemmin)

    int grow_amount = 40; // Kuinka paljon lima kasvaa kerralla, (pienempi useammin) pitää olla vähintään 1

    // Kuinka suuri alue limalle:
    int lev = 160;
    int kor = 120;
    int koko = 4; // Liman neliön koko

    int kr = 8; // Kuinka iso alue pyyhitään pois D-näppäimellä

    // Varataan muistia limalle:
    Uint8 *pos = (Uint8 *)malloc(sizeof(Uint8) * lev * kor); // Alue josta löytyy paikat mihin voidaan kasvattaa limaa
    Uint8 *data = (Uint8 *)malloc(sizeof(Uint8) * lev * kor); // Alue josta löytyy kasvava lima ja muut esteet.

    // Nollataan varatut muistit, ettei tule yllätyksiä:
    memset(pos, 0, sizeof(Uint8) * lev * kor);
    memset(data, 0, sizeof(Uint8) * lev * kor);

    int x, y;
    int px, py; // Lasketut hiiren koordinaatit (esim: mx/koko)

    Uint32 vari;

    bool show_growareas = 0; // Näppäimen S painalluksen valvoja

	while(done == 0){
		while(SDL_PollEvent(&event)){
			if(event.type == SDL_QUIT) done = 1;
			if(event.type == SDL_KEYDOWN) if(event.key.keysym.sym == SDLK_ESCAPE) done = 1;
		}

        SDL_FillRect(screen, NULL, 0);
        mouse = SDL_GetMouseState(&mx, &my);
        nappi = SDL_GetKeyState(NULL);

        // Lasketaan sen neliön sijainti jonka päällä hiiri on:
        px = mx/koko;
        py = my/koko;
        // Varmistetaan ettei mennä yli reunojen:
        if(px > lev-1) px = lev-1;
        if(py > kor-1) py = kor-1;

        // Jos painetaan hiiren vasenta nappia, luodaan yksi limapiste:
        if(mouse & SDL_BUTTON(1)){
            data[py*lev+px] = 1;
        }
        // Jos painetaan hiiren oikeata nappia, luodaan yksi seinä:
        if(mouse & SDL_BUTTON(3)){
            data[py*lev+px] = 255;
        }

        // Jos painetaan näppäintä "D":
        if(nappi[SDLK_d]){
            // Poistetaan ison neliön verran limaa:
            for(y = -kr; y < kr; y++){
                for(x = -kr; x < kr; x++){
                    // Tarkistetaan ettei piirretä yli reunojen:
                    if(py+y > -1 && py+y < kor && px+x > -1 && px+x < lev){
                        if(data[(py+y)*lev+px+x] == 1) data[(py+y)*lev+px+x] = 0;
                    }
                }
            }
        }

        show_growareas = 0;
        if(nappi[SDLK_s]){
            show_growareas = 1;
        }

        for(y = 0; y < kor; y++){
            for(x = 0; x < lev; x++){
                vari = 0; // Tausta musta
                if(data[y*lev+x] == 1){
                    vari = 0x888800; // Lima vihreä
                }else if(data[y*lev+x] == 255){
                    vari = 0xDDDDDD; // Seinä harmaa
                }
                if(show_growareas){
                    if(!vari){
                        if(pos[y*lev+x] == 1){
                            vari = 0x000088;
                        }
                    }
                }
                if(vari){
                    // Piirretään neliö:
                    imagefilledrect(screen, x*koko, y*koko, x*koko+koko-1, y*koko+koko-1, vari);
                }
            }
        }

        if(areagrow > areagrow_speed){
            // Nollataan liman mahdollisten kasvatuskohtien muisti:
            memset(pos, 0, sizeof(Uint8) * lev * kor);
            // Etsitään mahdolliset liman kasvatuskohdat:
            scan_possible(data, pos, lev, kor);
            areagrow = 0;
        }
        if(growrandom > growrandom_speed){
            // Kasvatetaan limaa:
            grow_random(data, pos, lev, kor, grow_amount);
            growrandom = 0;
        }

        areagrow++;
        growrandom++;

        SDL_Delay(10);
        SDL_Flip(screen);
    }
	return 0;
}




inline void putpixel(SDL_Surface *screen, int x, int y, Uint32 color){
    bool draw = 1;
    if(x > leveys-1) draw = 0; else if(y > korkeus-1) draw = 0; else if(x < 0) draw = 0; else if(y < 0) draw = 0;
    if(draw){
        Uint8 *p = (Uint8 *)screen->pixels;
        *(Uint32 *)(p + y * screen->pitch + (x << 2)) = color;
    }
}

void imagefilledrect(SDL_Surface *screen, int x1, int y1, int x2, int y2, Uint32 color){
    int x, y, tx, ty;
    if(x2 < x1){ tx = x2; x2 = x1; x1 = tx; }
    if(y2 < y1){ ty = y2; y2 = y1; y1 = ty; }
    for(y = y1; y <= y2; y++){
        for(x = x1; x <= x2; x++){
            putpixel(screen, x, y, color);
        }
    }
}

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta