#pragma warning(disable:4996)
#include <stdlib.h>
#include <stdio.h>
#include <easyx.h>
#include <math.h>
#include <time.h>
typedef int word;
#define SET 1
#define QUIT 2
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
struct Window {
word width;
word height;
HWND hwnd;
}win;
struct Button {
word top;
word bottom;
word left;
word right;
wchar_t* buf;
};
struct Scene {
Button* button;
}table, boot, setting;
struct Player {
double x;
double y;
word pos;
word cloth[4];
word thing[36][2];
word jump;
word direct;
word dy;
IMAGE img;
}player;
struct Block {
word hardness;
wchar_t name[16];
IMAGE img;
}block[256];
struct Thing {
word hardness;
wchar_t name[16];
IMAGE img;
}thing[256];
struct World {
word time;
word size;
};
struct Cache {
word id;
word block[3][256][256];
word flag[3][256][256];
}cache;
enum struct Id {
Air = 0,
Bedrock,
Soil,
Stone,
Wood,
Leaf,
Iron,
Diamond,
Coal
};
word count;
word sleep_time = 2500000;
word flush = 8;
IMAGE bg;
inline void init() {
win.width = 1024; win.height = 633;
win.hwnd = initgraph(win.width, win.height, EX_SHOWCONSOLE); SetWindowText(win.hwnd, L"Minecraft 1.3"); BeginBatchDraw();
table.button = new Button[3];
table.button[0].top = (word)(0.375 * win.height); table.button[0].bottom = (word)(0.5 * win.height); table.button[0].left = (word)(0.25 * win.width); table.button[0].right = (word)(0.75 * win.width); table.button[0].buf = new wchar_t[16]; lstrcpyW(table.button[0].buf, L"开始");
table.button[1].top = (word)(0.5625 * win.height); table.button[1].bottom = (word)(0.6875 * win.height); table.button[1].left = (word)(0.25 * win.width); table.button[1].right = (word)(0.75 * win.width); table.button[1].buf = new wchar_t[16]; lstrcpyW(table.button[1].buf, L"设置");
table.button[2].top = (word)(0.75 * win.height); table.button[2].bottom = (word)(0.875 * win.height); table.button[2].left = (word)(0.25 * win.width); table.button[2].right = (word)(0.75 * win.width); table.button[2].buf = new wchar_t[16]; lstrcpyW(table.button[2].buf, L"退出");
loadimage(&bg, L"image/bg.png"); loadimage(&player.img, L"image/player.png"); srand((unsigned int)time(NULL));
{
word id = (word)Id::Bedrock;
block[id].hardness = -1; thing[id].hardness = 0; lstrcpyW(block[id].name, L"bedrock"); lstrcpyW(thing[id].name, L"bedrock"); loadimage(&block[id].img, L"image/bedrock.png"); loadimage(&thing[id++].img, L"image/bedrock.png");
block[id].hardness = 0; thing[id].hardness = 0; lstrcpyW(block[id].name, L"soil"); lstrcpyW(thing[id].name, L"soil"); loadimage(&block[id].img, L"image/soil.png"); loadimage(&thing[id++].img, L"image/soil.png");
block[id].hardness = 1; thing[id].hardness = 0; lstrcpyW(block[id].name, L"stone"); lstrcpyW(thing[id].name, L"stone"); loadimage(&block[id].img, L"image/stone.png"); loadimage(&thing[id++].img, L"image/stone.png");
block[id].hardness = 0; thing[id].hardness = 0; lstrcpyW(block[id].name, L"wood"); lstrcpyW(thing[id].name, L"wood"); loadimage(&block[id].img, L"image/wood.png"); loadimage(&thing[id++].img, L"image/wood.png");
block[id].hardness = 0; thing[id].hardness = 0; lstrcpyW(block[id].name, L"leaf"); lstrcpyW(thing[id].name, L"leaf"); loadimage(&block[id].img, L"image/leaf.png"); loadimage(&thing[id++].img, L"image/leaf.png");
block[id].hardness = 2; thing[id].hardness = 0; lstrcpyW(block[id].name, L"iron"); lstrcpyW(thing[id].name, L"iron"); loadimage(&block[id].img, L"image/iron.png"); loadimage(&thing[id++].img, L"image/iron.png");
block[id].hardness = 3; thing[id].hardness = 0; lstrcpyW(block[id].name, L"diamond"); lstrcpyW(thing[id].name, L"diamond"); loadimage(&block[id].img, L"image/diamond.png"); loadimage(&thing[id++].img, L"image/diamond.png");
block[id].hardness = 1; thing[id].hardness = 0; lstrcpyW(block[id].name, L"coal"); lstrcpyW(thing[id].name, L"coal"); loadimage(&block[id].img, L"image/coal.png"); loadimage(&thing[id++].img, L"image/coal.png");
}
}
inline bool inrectangle(word x, word y, word top, word bottom, word left, word right) {
if (x > left && x < right && y > top && y < bottom) return true; else return false;
}
inline word welcome() {
setlinecolor(RGB(0, 0, 0)); settextcolor(RGB(255, 255, 255)); putimage(0, 0, &bg);
while (true) {
for (word i = 0; i < 3; i++) {
rectangle(table.button[i].left, table.button[i].top, table.button[i].right, table.button[i].bottom);
RECT r = { table.button[i].left, table.button[i].top, table.button[i].right, table.button[i].bottom };
drawtext(table.button[i].buf, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
FlushBatchDraw();
}
ExMessage message;
if (peekmessage(&message, EX_MOUSE) && message.lbutton) {
clearrectangle(0, 0, win.width, win.height);
FlushBatchDraw();
if (inrectangle(message.x, message.y, table.button[0].top, table.button[0].bottom, table.button[0].left, table.button[0].right)) return 0;
if (inrectangle(message.x, message.y, table.button[1].top, table.button[1].bottom, table.button[1].left, table.button[1].right)) return SET;
if (inrectangle(message.x, message.y, table.button[2].top, table.button[2].bottom, table.button[2].left, table.button[2].right)) return QUIT;
}
}
}
inline void build(word id) {
FILE* fp; char name[16]; sprintf(name, "world/%d.txt", id); fp = fopen(name, "w"); word world[256][256] = { 0 }; word flag[256][256] = { 0 };
for (word x = 0; x < 256; x++) {
world[255][x] = (word)Id::Bedrock; flag[255][x] = 1;
}
{
word cnt;
word type = rand() % 2;
switch (type) {
case 0: {
for (word i = 192; i < 255; i++) { for (word j = 0; j < 256; j++) { world[i][j] = (word)Id::Stone; flag[i][j] = 1; } }
for (word i = 188; i < 192; i++) { for (word j = 0; j < 256; j++) { world[i][j] = (word)Id::Soil; flag[i][j] = 1; } }
cnt = 16;
while (cnt--) {
word i = rand() % 16 + 191;
word j = rand() % 256;
world[i][j] = (word)Id::Coal;
}
cnt = 16;
while (cnt--) {
word i = rand() % 64 + 191;
word j = rand() % 256;
world[i][j] = (word)Id::Iron;
}
cnt = 2;
while (cnt--) {
word i = rand() % 8 + 247;
word j = rand() % 256;
world[i][j] = (word)Id::Diamond;
}
break;
}
case 1: {
for (word i = 192; i < 255; i++) { for (word j = 0; j < 256; j++) { world[i][j] = (word)Id::Stone; flag[i][j] = 1; } }
for (word i = 188; i < 192; i++) { for (word j = 0; j < 256; j++) { world[i][j] = (word)Id::Soil; flag[i][j] = 1; } }
for (word i = 4; i < 252; i += (rand() % 10 + 4)) {
world[187][i] = world[186][i] = world[185][i] = (word)Id::Wood;
world[182][i] = world[183][i - 1] = world[183][i] = world[183][i + 1] = world[184][i - 2] = world[184][i - 1] = world[184][i] = world[184][i + 1] = world[184][i + 2] = world[185][i - 1] = world[185][i + 1] = (word)Id::Leaf;
}
cnt = 16;
while (cnt--) {
word i = rand() % 16 + 191;
word j = rand() % 256;
world[i][j] = (word)Id::Coal;
}
cnt = 16;
while (cnt--) {
word i = rand() % 64 + 191;
word j = rand() % 256;
world[i][j] = (word)Id::Iron;
}
cnt = 2;
while (cnt--) {
word i = rand() % 8 + 247;
word j = rand() % 256;
world[i][j] = (word)Id::Diamond;
}
break;
}
}
}
for (word y = 0; y < 256; y++)for (word x = 0; x < 256; x++)fprintf(fp, "%d %d ", world[y][x], flag[y][x]); fclose(fp);
}
inline void init_block(word cid, word wid) {
FILE* fp; char name[16]; sprintf(name, "world/%d.txt", wid); fp = fopen(name, "r"); for (word i = 0; i < 256; i++) { for (word j = 0; j < 256; j++)fscanf(fp, "%d%d", &cache.block[cid][i][j], &cache.flag[cid][i][j]); }
}
inline void read() {
FILE* fp = fopen("player.txt", "r");
if (fp == NULL) { for (word i = -64; i < 64; i++) build(i); player.x = player.y = 0; cache.id = 0; }
else { fscanf(fp, "%lf%lf", &player.x, &player.y); for (word i = 0; i < 4; i++) fscanf(fp, "%d", &player.cloth[i]); for (word i = 0; i < 36; i++) fscanf(fp, "%d%d", &player.thing[i][0], &player.thing[i][1]); cache.id = (word)floor(player.x / 256.0); fclose(fp); }
init_block(0, cache.id - 1); init_block(1, cache.id); init_block(2, cache.id + 1);
}
inline void movecache(word a, word b) {
for (word i = 0; i < 256; i++) { for (word j = 0; j < 256; j++) { cache.block[a][i][j] = cache.block[b][i][j]; cache.flag[a][i][j] = cache.flag[b][i][j]; } }
}
inline void savecache(word id, word wid) {
FILE* fp; char name[16]; sprintf(name, "world/%d.txt", wid); fp = fopen(name, "w"); for (word i = 0; i < 256; i++) { for (word j = 0; j < 256; j++)fprintf(fp, "%d %d ", cache.block[id][i][j], cache.flag[id][i][j]); }fclose(fp);
}
inline void load() {
word px = word(player.x + 0.5);
if (px < cache.id * 256) {
savecache(2, cache.id + 1); movecache(2, 1); movecache(1, 0);
cache.id--;
FILE* fp; char name[16];
sprintf(name, "world/%d.txt", cache.id - 1); fp = fopen(name, "r");
if (fp == NULL) { build(cache.id - 1); fp = fopen(name, "r"); }
for (word i = 0; i < 256; i++) { for (word j = 0; j < 256; j++)fscanf(fp, "%d%d", &cache.block[0][i][j], &cache.flag[0][i][j]); }
fclose(fp);
}
if (px >= cache.id * 256 + 256) {
savecache(0, cache.id - 1); movecache(0, 1); movecache(1, 2);
cache.id++;
FILE* fp; char name[16];
sprintf(name, "world/%d.txt", cache.id + 1); fp = fopen(name, "r");
if (fp == NULL) { build(cache.id + 1); fp = fopen(name, "r"); }
for (word i = 0; i < 256; i++) { for (word j = 0; j < 256; j++)fscanf(fp, "%d%d", &cache.block[2][i][j], &cache.flag[2][i][j]); }
fclose(fp);
}
}
inline void craft() {
setlinecolor(RGB(127, 127, 127));
setfillcolor(RGB(127, 127, 127));
fillrectangle(0, 0, win.width, win.height);
for (word i = 0; i < 36; i++) {
;
}
return;
}
inline word input() {
if (KEYDOWN(VK_ESCAPE)) return QUIT;
if (KEYDOWN(VK_SPACE) && player.jump == 0) { player.x = (word)(player.x + (cache.id >= 0 ? 0.5 : -0.5)); player.y = (word)(player.y + 0.5); }
if (KEYDOWN(VK_RETURN)) {
craft();
}
if (KEYDOWN('P')) {
system("cls");
printf("x: %lf y: %lf\n", player.x, player.y);
printf("chunk: %d\n", cache.id);
}
if (KEYDOWN('A')) {
word c = 1;
word x;
if (cache.id >= 0) x = word(player.x + 0.4) - cache.id * 256;
else x = word(player.x - 0.6) - cache.id * 256;
if (x < 0) { c--; x += 256; }
if (cache.flag[c][(word)(player.y - 0.5)][x] == 0)player.x -= 0.1;
player.direct = -abs(player.direct);
}
if (KEYDOWN('D')) {
word c = 1;
word x;
if (cache.id >= 0) x = word(player.x + 0.6) - cache.id * 256;
else x = word(player.x - 0.4) - cache.id * 256;
if (x >= 256) { c++; x -= 256; }
if (cache.flag[c][(word)(player.y - 0.5)][x] == 0)player.x += 0.1;
player.direct = abs(player.direct);
}
if (KEYDOWN('W') && player.jump == 0) {
word c = 1;
word x;
if (cache.id >= 0) x = word(player.x + 0.5) - cache.id * 256;
else x = word(player.x - 0.5) - cache.id * 256;
if (x >= 256) { c++; x -= 256; }
if (x < 0) { c--; x += 256; }
if (cache.flag[c][(word)(player.y + 0.5)][x] != 0) player.jump = -80;
}
if (KEYDOWN('Q') && count % flush == 0) {
word c = 1;
word y = word(player.y + 0.5) + player.dy - 1;
word x;
if (cache.id >= 0) x = word(player.x + 0.5) - cache.id * 256 + player.direct;
else x = word(player.x - 0.5) - cache.id * 256 + player.direct;
if (x < 0) { x += 256; c--; } if (x >= 256) { x -= 256; c++; }
/*if (thing[player.thing[player.pos][0]].hardness >= block[cache.block[c][y][x]].hardness)*/ {
for (word i = 0; i < 36; i++) { if (player.thing[i][0] == cache.block[c][y][x]) { player.thing[i][1]++; goto broken; } }
for (word i = 0; i < 36; i++) { if (player.thing[i][0] == (word)Id::Air) { player.thing[i][0] = cache.block[c][y][x]; player.thing[i][1]++; goto broken; } }
broken: cache.block[c][y][x] = (word)Id::Air; cache.flag[c][y][x] = 0;
}
}
if (KEYDOWN(VK_UP) && count % flush == 0 && player.dy > -4) player.dy--;
if (KEYDOWN(VK_DOWN) && count % flush == 0 && player.dy < 4) player.dy++;
if (KEYDOWN(VK_LEFT) && count % flush == 0 && abs(player.direct - 1) <= 4) player.direct--;
if (KEYDOWN(VK_RIGHT) && count % flush == 0 && abs(player.direct + 1) <= 4) player.direct++;
if (KEYDOWN('1')) player.pos = 0;
if (KEYDOWN('2')) player.pos = 1;
if (KEYDOWN('3')) player.pos = 2;
if (KEYDOWN('4')) player.pos = 3;
if (KEYDOWN('5')) player.pos = 4;
if (KEYDOWN('6')) player.pos = 5;
if (KEYDOWN('7')) player.pos = 6;
if (KEYDOWN('8')) player.pos = 7;
if (KEYDOWN('9')) player.pos = 8;
word c = 1;
word x;
if (cache.id >= 0) x = word(player.x + 0.5) - cache.id * 256;
else x = word(player.x - 0.5) - cache.id * 256;
if (x >= 256) { c++; x -= 256; }
if (x < 0) { c--; x += 256; }
if (player.jump != 0) { if (cache.flag[c][(word)(player.y + (player.jump + 40) * 0.003)][x] == 0) player.y += (player.jump + 40) * 0.003; player.jump++; }
return 0;
}
inline void output() {
word top = (word)(player.y) - 12;
word left = (word)(player.x) - 17 - cache.id * 256;
word yy = (word)(((word)player.y - player.y - 1.5) * 32);
word xx = (word)(((word)player.x - player.x - 1.5) * 32);
setlinecolor(RGB(0, 191, 255));
setfillcolor(RGB(0, 191, 255));
fillrectangle(0, 0, win.width, win.height);
putimage(496, 304, &player.img);
for (word i = 0; i < 23; i++) {
if (top + i < 0 || top + i >= 256) continue;
for (word j = 0; j < 35; j++) {
if (left + j < 0) {
if (cache.block[0][top + i][left + j + 256] != (word)Id::Air)
putimage(xx + j * 32, yy + i * 32, &block[(unsigned)cache.block[0][top + i][left + j + 256]].img);
}
else if (left + j >= 256) {
if (cache.block[2][top + i][left + j - 256] != (word)Id::Air)
putimage(xx + j * 32, yy + i * 32, &block[(unsigned)cache.block[2][top + i][left + j - 256]].img);
}
else {
if (cache.block[1][top + i][left + j] != (word)Id::Air)
putimage(xx + j * 32, yy + i * 32, &block[(unsigned)cache.block[1][top + i][left + j]].img);
}
}
}
setlinecolor(RGB(0, 0, 0));
setfillcolor(RGB(0, 0, 0));
rectangle(player.direct * 32 + 496, player.dy * 32 + 304, player.direct * 32 + 527, player.dy * 32 + 335);
fillrectangle(30, win.height - 66, 337, win.height - 31);
setlinecolor(RGB(255, 255, 255));
setfillcolor(RGB(255, 255, 255));
for (word i = 0; i < 9; i++) {
if (player.pos == i) {
fillrectangle(30 + i * 34, win.height - 66, 65 + i * 34, win.height - 31);
}
if (player.thing[i][0] != (word)Id::Air) {
putimage(32 + i * 34, win.height - 64, &thing[player.thing[i][0]].img);
}
}
outtextxy(30, win.height - 30, thing[(word)player.thing[player.pos][0]].name);
FlushBatchDraw();
}
inline void close() {
EndBatchDraw(); closegraph();
FILE* fp = fopen("player.txt", "w"); fprintf(fp, "%lf %lf\n", player.x, player.y);
for (word i = 0; i < 4; i++) fprintf(fp, "%d ", player.cloth[i]); fprintf(fp, "\n");
for (word i = 0; i < 36; i++) fprintf(fp, "%d %d ", player.thing[i][0], player.thing[i][1]); fprintf(fp, "\n");
fclose(fp); savecache(0, cache.id - 1); savecache(1, cache.id); savecache(2, cache.id + 1);
}
int main() {
init();
{
word ret = welcome();
if (ret == SET);
if (ret == QUIT) goto CLOSE;
putimage(0, 0, &bg);
RECT r = { 0, 0, win.width, win.height };
drawtext(L"正在生成世界", &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
FlushBatchDraw();
}
read();
player.x = (word)(player.x + 0.5);
player.y = (word)(player.y + 0.5);
player.jump = 0;
player.pos = 0;
while (true) {
load();
{
word c = 1;
word x;
if (cache.id >= 0) x = word(player.x + 0.5) - cache.id * 256;
else x = word(player.x - 0.5) - cache.id * 256;
if (x < 0) { x += 256; c--; }
if (x >= 256) { x -= 256; c++; }
for (word tt = 0; tt < 3 && cache.flag[c][(word)(player.y + 0.1)][x] == 0 && player.jump == 0; tt++) {
player.y += 0.1;
}
}
if (input() == QUIT)goto CLOSE;
output();
for (word t = 0; t < sleep_time; t++);
count++;
}
CLOSE:
close();
return 0;
}