From 7321a1df947003dcc2aa588f95b13e1dba7340af Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Aug 15 2020 13:45:46 +0000 Subject: fractal, sokoban --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..42d8057 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/* +!/**/ +!*.* +!readme +*.o \ No newline at end of file diff --git a/data/levels/sokoban/001.level b/data/levels/sokoban/001.level new file mode 100644 index 0000000..4096e5d --- /dev/null +++ b/data/levels/sokoban/001.level @@ -0,0 +1,6 @@ +############### +#.. # +# BBB # +# # ### # +#. @ # +############### diff --git a/data/levels/sokoban/002.level b/data/levels/sokoban/002.level new file mode 100644 index 0000000..f6e4489 --- /dev/null +++ b/data/levels/sokoban/002.level @@ -0,0 +1,7 @@ + ########### + # @ # +## # # # # # +# B B B B ## +# ####### # +# ...##. # +############# diff --git a/data/levels/sokoban/009.level b/data/levels/sokoban/009.level new file mode 100644 index 0000000..e1c6841 --- /dev/null +++ b/data/levels/sokoban/009.level @@ -0,0 +1,9 @@ + #### + # ########### + #B ........ # + # #######B # + #B # # B # +## ##B #B # +# B B # # +# # @######## +######## diff --git a/data/sprite/box.png b/data/sprite/box.png new file mode 100644 index 0000000..704493f Binary files /dev/null and b/data/sprite/box.png differ diff --git a/data/sprite/bricks-tile.png b/data/sprite/bricks-tile.png new file mode 100644 index 0000000..edf0b7e Binary files /dev/null and b/data/sprite/bricks-tile.png differ diff --git a/data/sprite/dot.png b/data/sprite/dot.png new file mode 100644 index 0000000..3ab180f Binary files /dev/null and b/data/sprite/dot.png differ diff --git a/fractal.c b/fractal.c new file mode 100644 index 0000000..8f41a69 --- /dev/null +++ b/fractal.c @@ -0,0 +1,118 @@ + +#include +#include + + +Animation anim = 0; +unsigned char pixels[512][512][4]; +double r = 0.4, i = 0.6; +double mx, my, zmx, zmy; +double z = 1/128.0; +double cx = -2; +double cy = -2; + + +void hsvToRgb(double h, double s, double v, unsigned char *pixel) { + h -= floor(h/360)*360; + s /= 100; + v = v/100*255; + s = s > 0 ? (s < 1 ? s : 1) : 0; + v = v > 0 ? (v < 255 ? v : 255) : 0; + + h /= 60.0; + int i = (int)h; + double f = h - i; + int pp = v*(1 - s); + int qq = v*(1 - s*f); + int tt = v*(1 - s*(1 - f)); + + unsigned char p = (unsigned char)(pp > 0 ? (pp < 255 ? pp : 255) : 0); + unsigned char q = (unsigned char)(qq > 0 ? (qq < 255 ? qq : 255) : 0); + unsigned char t = (unsigned char)(tt > 0 ? (tt < 255 ? tt : 255) : 0); + unsigned char u = (unsigned char)v; + + switch(i) { + case 0: pixel[0] = u, pixel[1] = t, pixel[2] = p; break; + case 1: pixel[0] = q, pixel[1] = u, pixel[2] = p; break; + case 2: pixel[0] = p, pixel[1] = u, pixel[2] = t; break; + case 3: pixel[0] = p, pixel[1] = q, pixel[2] = u; break; + case 4: pixel[0] = t, pixel[1] = p, pixel[2] = u; break; + default: pixel[0] = u, pixel[1] = p, pixel[2] = q; break; + } + pixel[3] = 255; +} + + +void setColor(double x, unsigned char *pixel) { + double h0 = 240; + double h1 = 0; + double h = h0 + (h1 - h0)*x; + hsvToRgb(h, 100, 100, pixel); +} + + +void julia(double r, double i) { + for(int y = 0; y < 512; ++y) { + for(int x = 0; x < 512; ++x) { + double rr = x*z + cx; + double ii = y*z + cy; + int b; + for(b = 0; b < 64; ++b) { + if (rr*rr + ii*ii > 4) break; + double x = rr*rr - ii*ii + r; + ii = 2*rr*ii + i; + rr = x; + } + setColor(b/64.0, pixels[y][x]); + } + } + +} + + +void fractal() { + if (anim) animationDestroy(anim); + julia(r, i); + anim = createAnimationFromImageEx(512, 512, pixels, FALSE, FALSE, FALSE, FALSE); +} + + +void init() { + fractal(); +} + + +void draw() { + double dt = worldGetFrameTime(); + int changed = 0; + + if (mouseDown("middle")) { + r += (mouseX() - mx)*z/10; + i += (mouseY() - my)*z/10; + changed = 1; + } + + if (mouseDown("left") || mouseDown("right")) { + double k = pow(4, dt); + if (mouseDown("left")) k = 1/k; + cx += mouseX()*z*(1 - k); + cy += mouseY()*z*(1 - k); + z *= k; + changed = 1; + } + + mx = mouseX(); + my = mouseY(); + + if (changed) fractal(); + fill(colorByName("white")); + rectTextured(anim, 0, 0, 512, 512); +} + + +int main() { + worldSetInit(&init); + worldSetDraw(&draw); + worldSetFrameRateEx(1, 100); + worldRun(); +} diff --git a/sokoban.c b/sokoban.c new file mode 100644 index 0000000..0bd579f --- /dev/null +++ b/sokoban.c @@ -0,0 +1,178 @@ + +#include +#include +#include + +#include + + +Sprite player; +Group walls; +Group boxes; +Group places; + +Animation animPlayer; +Animation animWall; +Animation animBox; +Animation animPlace; + +Font font; + + +double speed = 256; + +char levels[256][1024]; +int levelsCount = 0; +int level = 0; + + +void loadLevel() { + if (level < 0) level = levelsCount - 1; + if (level >= levelsCount) level = 0; + + FILE *f = fopen(levels[level], "r"); + if (!f) { + messageBox("Cannot open level file"); + return; + } + + groupDestroyEach(walls); + groupDestroyEach(boxes); + groupDestroyEach(places); + + int c; + int x = 32; + int y = 32; + int maxX = 0, maxY = 0; + Sprite s; + do { + c = fgetc(f); + + if (c == '\n') { y += 64; x = 32; continue; } + + if (c == '.') { + s = createSpriteEx(x, y, 10, 10); + spriteSetAnimation(s, animPlace); + spriteSetColliderCircle(s, 0, 0, -1); + spriteSetDepth(s, 1); + groupAdd(places, s); + } else + if (c == '#') { + s = createSpriteEx(x, y, 64, 64); + spriteSetAnimation(s, animWall); + spriteSetMassLevel(s, 100); + groupAdd(walls, s); + if (maxX < x) maxX = x; + if (maxY < y) maxY = y; + } else + if (c == 'B') { + s = createSpriteEx(x, y, 62, 62); + spriteSetAnimation(s, animBox); + spriteSetColliderRectangle(s, 0, 0, 0, -1, -1, 16); + groupAdd(boxes, s); + } else + if (c == '@') { + spriteSetXY(player, x, y); + } + + x += 64; + } while (c != EOF); + fclose(f); + + worldSetWidth(maxX + 32); + worldSetHeight(maxY + 32); +} + + +void init() { + background(colorByName("black")); + + animPlayer = createAnimation("data/sprite/breadball.png"); + animWall = createAnimation("data/sprite/bricks-tile.png"); + animBox = createAnimation("data/sprite/box.png"); + animPlace = createAnimation("data/sprite/dot.png"); + + font = createFont("data/fonts/blackcry.ttf"); + textFont(font); + + player = createSpriteEx(0, 0, 62, 62); + spriteSetAnimation(player, animPlayer); + spriteSetColliderCircle(player, 0, 0, -1); + + walls = createGroup(); + boxes = createGroup(); + places = createGroup(); + + Directory dir = openDirectory("data/levels/sokoban"); + if (!dir || !directoryGetCount(dir)) { + messageBox("Cannot open levels directory"); + exit(1); + } + for(int i = 0; i < directoryGetCount(dir); ++i) { + const char *filename = directoryGet(dir, i); + int l = strlen(filename); + if (l >= 6 && strcmp(filename + l - 6, ".level") == 0) { + snprintf(levels[levelsCount], 1023, "data/levels/sokoban/%s", filename); + ++levelsCount; + } + } + closeDirectory(dir); + + loadLevel(); +} + + +void draw() { + double dt = worldGetFrameTime(); + + double x = spriteGetX(player); + double y = spriteGetY(player); + double step = speed*dt; + if (keyDown("left")) { + spriteSetMirrorX(player, -1); + spriteSetX(player, x - step); + } + if (keyDown("right")) { + spriteSetMirrorX(player, 1); + spriteSetX(player, x + step); + } + if (keyDown("up")) { + spriteSetY(player, y - step); + } + if (keyDown("down")) { + spriteSetY(player, y + step); + } + + if (keyWentDown("r")) { + loadLevel(); + } + if (keyWentDown("pageup")) { + --level; + loadLevel(); + } + if (keyWentDown("pagedown")) { + ++level; + loadLevel(); + } + + groupCollide(walls, player); + groupCollide(boxes, player); + groupCollideBetween(boxes); + groupCollideGroup(walls, boxes); + + drawSprites(); + + noFill(); + stroke(colorByName("white")); + textAlign(HALIGN_CENTER, VALIGN_BOTTOM); + text("R - restart level, PgUp - previous level, PgDown - next level", worldGetWidth()/2, worldGetHeight() - 10); +} + + +int main() { + worldSetInit(&init); + worldSetDraw(&draw); + worldSetFrameRateEx(10, 100); + worldRun(); + return 0; +}