|
|
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 |
}
|