赞
踩
以下为源代码,不知是否有错,敬请谅解。
#include "codingtang.h" #include<cstdlib> #include<ctime> using namespace std; #define RESOLUTION_W 1024 #define RESOLUTION_H 768 #define INVALID_BLOCK_ID -1 const int blockCount = 10; const int tileSize = 32; const int screenTileWidth = RESOLUTION_W / tileSize; const int screenTileHeight = RESOLUTION_H / tileSize; Window window; enum blockType { BEDROCK, GRASS, DIRT, STONE, DIAMOND, COAL, IRON, GOLD, REDSTONE, EMERALD }; typedef struct Block { int id; } Block; void renderTexture(string &texture, int w, int h, int x, int y, Rect &clip) { Rect dest; dest.x = x; dest.y = y; dest.h = h; dest.w = w; window.drawImageEx(texture.c_str(), &clip, &dest); } struct MCWorld { string blockSprites; Rect blockClips[blockCount]; Block map[screenTileWidth][screenTileHeight]; void init() { // Load Spritesheet sections into SDL_Rects blockSprites = "blocks.png"; // Load each block in the sheet into a SDL_Rect clip int x = 0; int y = 0; for(int i=0;i<blockCount;i++) { blockClips[i].x = x; blockClips[i].y = y; blockClips[i].w = 16; blockClips[i].h = 16; // if last block on the X axis (for a 64x64 spritesheet) if(x == 48) { // Move to the first block on the row below x = 0; y += 16; } else { // Move to the next block on the current row x += 16; } } // init map tiles to NULL for(int tileY=0;tileY<screenTileHeight;tileY++) { for(int tileX=0;tileX<screenTileWidth;tileX++) { map[tileX][tileY].id = INVALID_BLOCK_ID; } } } void create() { const int bedrockLayerStart = screenTileHeight-1; // 1 layer bedrock const int stoneLayerStart = bedrockLayerStart-3; // 3 layers stone const int dirtLayerStart = stoneLayerStart-1; // 1 layer dirt const int grassLayerStart = dirtLayerStart-1; // 1 layer grass blockType id; for(int y=grassLayerStart;y<screenTileHeight;y++) { switch(y) { case grassLayerStart: id = blockType::GRASS; break; case dirtLayerStart: id = blockType::DIRT; break; case stoneLayerStart: id = blockType::STONE; break; case bedrockLayerStart: id = blockType::BEDROCK; break; default: break; } for(int x=0;x<screenTileWidth;x++) { map[x][y].id = id; } } } void draw() { // Sky window.drawColor(128, 192, 255, 255); window.fillRect(0, 0, RESOLUTION_W, RESOLUTION_H); // Blocks for(int y=0;y<screenTileHeight;y++) { for(int x=0;x<screenTileWidth;x++) { if(map[x][y].id != INVALID_BLOCK_ID) { // if grass/dirt is above grass, make the grass below dirt if(map[x][y].id == blockType::GRASS && y-1 >= 0) { if(map[x][y-1].id != INVALID_BLOCK_ID) { map[x][y].id = blockType::DIRT; } } // render if(map[x][y].id != INVALID_BLOCK_ID) renderTexture(blockSprites, tileSize, tileSize, x*tileSize, y*tileSize, blockClips[map[x][y].id]); } } } } // X and Y of where the player is trying to go bool collision(int x, int y) { return map[x][y].id != INVALID_BLOCK_ID || map[x][y+1].id != INVALID_BLOCK_ID; } void destroyBlock(int x, int y) { if(y != screenTileHeight-1) { map[x][y].id = INVALID_BLOCK_ID; } } void createBlock(int id, int x, int y, int playerX, int playerY) { // Player collision if((y == playerY || y == playerY+1) && x == playerX) { return; } // Check if block to build upon for(int xOffset=-1;xOffset<=1;xOffset++) { if(map[x+xOffset][y].id != INVALID_BLOCK_ID) { if(map[x][y].id == INVALID_BLOCK_ID) { map[x][y].id = id; } } } for(int yOffset=-1;yOffset<=1;yOffset++) { if(map[x][y+yOffset].id != INVALID_BLOCK_ID) { if(map[x][y].id == INVALID_BLOCK_ID) { map[x][y].id = id; } } } } }; struct MCPlayer { string playerSprites; Rect playerClips[3]; int playerForward, playerRight, playerLeft, currentSprite; int x; int y; // Load spritesheet into SDL_Rects void init() { playerSprites = "player.png"; // Load each player sprite in the sheet into a SDL_Rect clip for(int i=0;i<3;i++) { playerClips[i].x = i*16; playerClips[i].y = 0; playerClips[i].w = 16; playerClips[i].h = 32; } playerForward = 0; playerRight = 1; playerLeft = 2; } // Create player at (20, 22) void create() { x = (screenTileWidth/2); y = (screenTileHeight-8); currentSprite = playerForward; } void draw() { renderTexture(playerSprites, tileSize, tileSize*2, x*tileSize, y*tileSize, playerClips[currentSprite]); } void moveUp() { if(y-1 >= 0) { y -= 1; if(currentSprite != playerForward) resetSprite(); } } void moveDown() { if(y+1 <= screenTileHeight-3) { y += 1; if(currentSprite != playerForward) resetSprite(); } } void moveLeft() { if(x-1 >= 0) { x -= 1; if(currentSprite != playerLeft) currentSprite = playerLeft; } } void moveRight() { if(x+1 <= screenTileWidth-1) { x += 1; if(currentSprite != playerRight) currentSprite = playerRight; } else { x = 0; } } void resetSprite() { currentSprite = playerForward; } }; struct MCInventory { string inventorySprites; Rect hotbar, hbOverlay; blockType hbSelection; void init() { inventorySprites = "inventory.png"; hotbar.x = 0; hotbar.y = 0; hotbar.w = 160; hotbar.h = 16; hbOverlay.x = 160; hbOverlay.y = 0; hbOverlay.h = 16; hbOverlay.w = 16; hbSelection = blockType::BEDROCK; } void create() { } void draw() { renderTexture(inventorySprites, tileSize*10, tileSize, (RESOLUTION_W/2)-(tileSize*5), 0, hotbar); renderTexture(inventorySprites, tileSize, tileSize, (RESOLUTION_W/2)-(tileSize*5) + (tileSize*hbSelection), 0, hbOverlay); return; } }; int main(){ window = createWindow(RESOLUTION_W,RESOLUTION_H); // 1024 * 768 MCWorld world; MCPlayer player; MCInventory inventory; world.init(); player.init(); inventory.init(); world.create(); player.create(); inventory.create(); world.draw(); player.draw(); inventory.draw(); bool quit = false; bool falling = false; int fallTimer = 0; while(!quit) { Event e; if(pollEvent(&e)) { // Keyboard Events if(e.type == CDT_KEYDOWN) { switch(e.keyCode) { case KEY_SPACE: if(!falling) { if(!world.collision(player.x, player.y-1)) { player.moveUp(); falling = true; } } break; case CDT_KEY_d: if(!world.collision(player.x+1, player.y)) { player.moveRight(); if(!world.collision(player.x, player.y+1)) falling = true; } break; case CDT_KEY_a: if(!world.collision(player.x-1, player.y)) { player.moveLeft(); if(!world.collision(player.x, player.y+1)) falling = true; } break; case CDT_KEY_1: inventory.hbSelection = blockType::BEDROCK; break; case CDT_KEY_2: inventory.hbSelection = blockType::GRASS; break; case CDT_KEY_3: inventory.hbSelection = blockType::DIRT; break; case CDT_KEY_4: inventory.hbSelection = blockType::STONE; break; case CDT_KEY_5: inventory.hbSelection = blockType::DIAMOND; break; case CDT_KEY_6: inventory.hbSelection = blockType::COAL; break; case CDT_KEY_7: inventory.hbSelection = blockType::IRON; break; case CDT_KEY_8: inventory.hbSelection = blockType::GOLD; break; case CDT_KEY_9: inventory.hbSelection = blockType::REDSTONE; break; case CDT_KEY_0: inventory.hbSelection = blockType::EMERALD; break; } } if(e.type == CDT_KEY_UP) { if(e.keyCode == CDT_KEY_a || e.keyCode == CDT_KEY_d) { player.resetSprite(); } } // Mouse Events if(e.type == CDT_MOUSEBUTTONDOWN) { int x = (e.button.x - (e.button.x % tileSize))/tileSize; int y = (e.button.y - (e.button.y % tileSize))/tileSize; if(e.button.button == CDT_BUTTON_RIGHT) { world.destroyBlock(x, y); } if(e.button.button == CDT_BUTTON_LEFT) { world.createBlock(inventory.hbSelection, x, y, player.x, player.y); } } } if(falling) { fallTimer++; if(fallTimer == 20) { if(!world.collision(player.x, player.y+1)) { player.moveDown(); fallTimer = 0; } else { falling = false; fallTimer = 0; } } } // Rerender world.draw(); player.draw(); inventory.draw(); window.present(); // Don't set cpu on fire sleep(1); } return 0; } ———————————————— 版权声明:本文为CSDN博主「m0_751885https://blog.csdn.net/m0_75188587/article/details/128047874
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。