Blame sokoban.c

7321a1
7321a1
#include <stdio.h></stdio.h>
7321a1
#include <string.h></string.h>
7321a1
#include <stdlib.h></stdlib.h>
7321a1
7321a1
#include <helianthus.h></helianthus.h>
7321a1
7321a1
7321a1
Sprite player;
7321a1
Group walls;
7321a1
Group boxes;
7321a1
Group places;
7321a1
7321a1
Animation animPlayer;
7321a1
Animation animWall;
7321a1
Animation animBox;
7321a1
Animation animPlace;
7321a1
7321a1
Font font;
7321a1
7321a1
7321a1
double speed = 256;
7321a1
int level = 0;
7321a1
7321a1
7321a1
void loadLevel() {
b2119e
  FILE *f = NULL;
b2119e
  Directory dir = openDirectoryEx("data/levels/sokoban", "", ".level", FALSE, TRUE, FALSE);
b2119e
  if (dir) {
b2119e
    int count = directoryGetCount(dir);
b2119e
    if (count > 0) {
b2119e
      if (level >= count) level = 0;
b2119e
      if (level < 0) level = count - 1;
b2119e
      f = fopen(directoryGetFull(dir, level), "r");
b2119e
    }
b2119e
    closeDirectory(dir);
b2119e
  }
7321a1
7321a1
  if (!f) {
7321a1
    messageBox("Cannot open level file");
7321a1
    return;
7321a1
  }
7321a1
7321a1
  groupDestroyEach(walls);
7321a1
  groupDestroyEach(boxes);
7321a1
  groupDestroyEach(places);
7321a1
7321a1
  int c;
7321a1
  int x = 32;
7321a1
  int y = 32;
7321a1
  int maxX = 0, maxY = 0;
7321a1
  Sprite s;
7321a1
  do {
7321a1
    c = fgetc(f);
7321a1
7321a1
    if (c == '\n') { y += 64; x = 32; continue; }
7321a1
7321a1
    if (c == '.') {
348218
      s = createSpriteEx(x, y, 10, 10, animPlace);
7321a1
      spriteSetColliderCircle(s, 0, 0, -1);
7321a1
      spriteSetDepth(s, 1);
7321a1
      groupAdd(places, s);
7321a1
    } else
7321a1
    if (c == '#') {
348218
      s = createSpriteEx(x, y, 64, 64, animWall);
7321a1
      spriteSetMassLevel(s, 100);
7321a1
      groupAdd(walls, s);
7321a1
      if (maxX < x) maxX = x;
7321a1
      if (maxY < y) maxY = y;
7321a1
    } else
7321a1
    if (c == 'B') {
348218
      s = createSpriteEx(x, y, 62, 62, animBox);
7321a1
      spriteSetColliderRectangle(s, 0, 0, 0, -1, -1, 16);
7321a1
      groupAdd(boxes, s);
7321a1
    } else
7321a1
    if (c == '@') {
7321a1
      spriteSetXY(player, x, y);
7321a1
    }
7321a1
7321a1
    x += 64;
7321a1
  } while (c != EOF);
7321a1
  fclose(f);
7321a1
ef1455
  windowSetWidth(maxX + 32);
ef1455
  windowSetHeight(maxY + 32);
7321a1
}
7321a1
7321a1
7321a1
void init() {
7321a1
  background(colorByName("black"));
7321a1
7321a1
  animPlayer = createAnimation("data/sprite/breadball.png");
7321a1
  animWall = createAnimation("data/sprite/bricks-tile.png");
7321a1
  animBox = createAnimation("data/sprite/box.png");
7321a1
  animPlace = createAnimation("data/sprite/dot.png");
7321a1
7321a1
  font = createFont("data/fonts/blackcry.ttf");
7321a1
  textFont(font);
7321a1
348218
  player = createSpriteEx(0, 0, 62, 62, animPlayer);
7321a1
  spriteSetColliderCircle(player, 0, 0, -1);
7321a1
7321a1
  walls = createGroup();
7321a1
  boxes = createGroup();
7321a1
  places = createGroup();
7321a1
7321a1
  loadLevel();
7321a1
}
7321a1
7321a1
7321a1
void draw() {
ef1455
  double dt = windowGetFrameTime();
7321a1
7321a1
  double x = spriteGetX(player);
7321a1
  double y = spriteGetY(player);
7321a1
  double step = speed*dt;
7321a1
  if (keyDown("left")) {
7321a1
    spriteSetMirrorX(player, -1);
7321a1
    spriteSetX(player, x - step);
7321a1
  }
7321a1
  if (keyDown("right")) {
7321a1
    spriteSetMirrorX(player, 1);
7321a1
    spriteSetX(player, x + step);
7321a1
  }
7321a1
  if (keyDown("up")) {
7321a1
    spriteSetY(player, y - step);
7321a1
  }
7321a1
  if (keyDown("down")) {
7321a1
    spriteSetY(player, y + step);
7321a1
  }
7321a1
7321a1
  if (keyWentDown("r")) {
7321a1
      loadLevel();
7321a1
  }
7321a1
  if (keyWentDown("pageup")) {
7321a1
      --level;
7321a1
      loadLevel();
7321a1
  }
7321a1
  if (keyWentDown("pagedown")) {
7321a1
      ++level;
7321a1
      loadLevel();
7321a1
  }
7321a1
7321a1
  groupCollide(walls, player);
7321a1
  groupCollide(boxes, player);
7321a1
  groupCollideBetween(boxes);
7321a1
  groupCollideGroup(walls, boxes);
7321a1
7321a1
  drawSprites();
7321a1
7321a1
  noFill();
7321a1
  stroke(colorByName("white"));
7321a1
  textAlign(HALIGN_CENTER, VALIGN_BOTTOM);
ef1455
  text(windowGetWidth()/2, windowGetHeight() - 10, "R - restart level, PgUp - previous level, PgDown - next level");
7321a1
}
7321a1
7321a1
7321a1
int main() {
ef1455
  windowSetTitle("Sokoban");
ef1455
	windowSetInit(&init);
ef1455
	windowSetDraw(&draw);
ef1455
	windowSetFrameRateEx(10, 100);
ef1455
	windowRun();
7321a1
	return 0;
7321a1
}