diff --git a/__pycache__/block.cpython-310.pyc b/__pycache__/block.cpython-310.pyc index 257d829..7528ad7 100644 Binary files a/__pycache__/block.cpython-310.pyc and b/__pycache__/block.cpython-310.pyc differ diff --git a/__pycache__/chunk.cpython-310.pyc b/__pycache__/chunk.cpython-310.pyc index d970184..4d1dece 100644 Binary files a/__pycache__/chunk.cpython-310.pyc and b/__pycache__/chunk.cpython-310.pyc differ diff --git a/__pycache__/perlin.cpython-310.pyc b/__pycache__/perlin.cpython-310.pyc index b2b2046..6184a91 100644 Binary files a/__pycache__/perlin.cpython-310.pyc and b/__pycache__/perlin.cpython-310.pyc differ diff --git a/__pycache__/perlin3d.cpython-310.pyc b/__pycache__/perlin3d.cpython-310.pyc new file mode 100644 index 0000000..5d4d295 Binary files /dev/null and b/__pycache__/perlin3d.cpython-310.pyc differ diff --git a/__pycache__/renderer.cpython-310.pyc b/__pycache__/renderer.cpython-310.pyc index 8d17575..999141b 100644 Binary files a/__pycache__/renderer.cpython-310.pyc and b/__pycache__/renderer.cpython-310.pyc differ diff --git a/__pycache__/world.cpython-310.pyc b/__pycache__/world.cpython-310.pyc index fc3b939..7f77b35 100644 Binary files a/__pycache__/world.cpython-310.pyc and b/__pycache__/world.cpython-310.pyc differ diff --git a/block.py b/block.py index 486ad37..16a8efe 100644 --- a/block.py +++ b/block.py @@ -25,4 +25,44 @@ class BlockDirt(Block): class BlockGrass(Block): def __init__(self): - super().__init__(3, 10, BlockType.GRASS) \ No newline at end of file + super().__init__(3, 10, BlockType.GRASS) + +class BlockCoal(Block): + def __init__(self): + super().__init__(4, 25, BlockType.STONE) + +class BlockIron(Block): + def __init__(self): + super().__init__(5, 30, BlockType.STONE) + +class BlockGold(Block): + def __init__(self): + super().__init__(6, 35, BlockType.STONE) + +class BlockDiamond(Block): + def __init__(self): + super().__init__(7, 40, BlockType.STONE) + +class BlockLog(Block): + def __init__(self): + super().__init__(8, 10, BlockType.WOOD) + +class BlockLeaf(Block): + def __init__(self): + super().__init__(9, 10, BlockType.NONE) + +BLOCKS_ID = [ + lambda: BlockAir(), + lambda: BlockStone(), + lambda: BlockDirt(), + lambda: BlockGrass(), + lambda: BlockCoal(), + lambda: BlockIron(), + lambda: BlockGold(), + lambda: BlockDiamond(), + lambda: BlockLog(), + lambda: BlockLeaf(), +] + +def with_id(id): + return BLOCKS_ID[id]() \ No newline at end of file diff --git a/chunk.py b/chunk.py index dc36e25..389ad63 100644 --- a/chunk.py +++ b/chunk.py @@ -1,20 +1,82 @@ -import block, perlin +import block, perlin, perlin3d CHUNK_WIDTH = 32 CHUNK_HEIGHT = 32 +SURFACE_CHUNK = 2 + +class StructureType: + SURFACE = 0 + +class Structure: + def __init__(self, width, height, blocks, struct_type): + self.width = width + self.height = height + self.blocks = blocks + self.struct_type = struct_type + + def get(self, x, y): + return self.blocks[x + self.width * y] + +structures = [ + Structure(3, 5, [9, 9, 9, 9, 9, 9, 0, 8, 0, 0, 8, 0, 0, 8, 0], StructureType.SURFACE), # TREE +] + class Chunk: - def gen_block(self, x: int, y: int): - height = int(100 + perlin.noise2d(x, 0.1) * 10) + def get_height(self, x): + return int(90 + perlin3d.noise2(x / 10, 0.1) * 10) + + def gen_block(self, x: int, y: int, height): + stone = 4 + perlin3d.noise2(x, 0.5 ) * 2 if y < height: return block.BlockAir() if y == height: return block.BlockGrass() - if y > height and y < height + 4: return block.BlockDirt() + if y < height + stone: return block.BlockDirt() + if y >= height + stone: + cave = perlin3d.noise3(x / 20, y / 20, 0.05) > 0 + if cave: return block.BlockAir() + if perlin3d.noise3(x / 5, y / 5, 0.05) > 0.4: return block.BlockCoal() + if perlin3d.noise3(x / 5, y / 5, 1.05) > 0.41: return block.BlockIron() + if perlin3d.noise3(x / 5, y / 5, 2.05) > 0.42: return block.BlockGold() + if perlin3d.noise3(x / 15, y / 15, 3.05) > 0.47: return block.BlockDiamond() + + return block.BlockStone() + return block.BlockAir() - return block.BlockStone() def get(self, x: int, y: int) -> block.Block(id): return self.blocks[x + CHUNK_WIDTH * y] + + def apply_strucutre(self, struct, x, y): + for i in range(struct.width): + if x + i >= CHUNK_WIDTH: continue + for j in range(struct.height): + if y + j >= CHUNK_HEIGHT: continue + if struct.blocks[i + j * struct.width] == 0: continue + + self.blocks[x + i + CHUNK_WIDTH * (y + j)] = block.with_id(struct.blocks[i + j * struct.width]) + + def apply_surface(self, struct): + if self.y > SURFACE_CHUNK: + return + + for i in range(struct.width // 2, CHUNK_WIDTH): + if i % struct.width != 0: continue + + if perlin3d.noise2(i, self.x / 10) > 0: + self.apply_strucutre(struct, i, self.get_height(self.x * CHUNK_WIDTH + i + 1) - self.y * CHUNK_HEIGHT - struct.height) def __init__(self, x: int, y: int): - self.blocks = [self.gen_block(i % CHUNK_WIDTH + x * CHUNK_WIDTH, i // CHUNK_WIDTH + y * CHUNK_HEIGHT) for i in range(CHUNK_WIDTH * CHUNK_HEIGHT)] + self.x = x + self.y = y + self.blocks = [0 for i in range(CHUNK_WIDTH * CHUNK_HEIGHT)] + x *= CHUNK_WIDTH + y *= CHUNK_HEIGHT + for i in range(CHUNK_WIDTH): + height = self.get_height(i + x) + for j in range(CHUNK_HEIGHT): + self.blocks[i + j * CHUNK_WIDTH] = self.gen_block(i + x, j + y, height) + + for structure in structures: + if structure.struct_type == StructureType.SURFACE: + self.apply_surface(structure) \ No newline at end of file diff --git a/perlin3d.py b/perlin3d.py new file mode 100644 index 0000000..04dc2d5 --- /dev/null +++ b/perlin3d.py @@ -0,0 +1,470 @@ +""" +// + + +// + + + + + + + + +/* + * This implementation is "Improved Noise" as presented by + * Ken Perlin at Siggraph 2002. The 3D function is a direct port + * of his Java reference code which was once publicly available + * on www.noisemachine.com (although I cleaned it up, made it + * faster and made the code more readable), but the 1D, 2D and + * 4D functions were implemented from scratch by me. + * + * This is a backport to C of my improved noise class in C++ + * which was included in the Aqsis renderer project. + * It is highly reusable without source code modifications. + * + */""" + +def FADE(t): + return ( t * t * t * ( t * ( t * 6 - 15 ) + 10 ) ) + +def LERP(t, a, b): + return ((a) + (t)*((b)-(a))) + +def FASTFLOOR(x): + return (int(x)) if (int(x) < (x)) else (int(x) - 1) + +#define FADE(t) ( t * t * t * ( t * ( t * 6 - 15 ) + 10 ) ) + +#define FASTFLOOR(x) ( ((int)(x)<(x)) ? ((int)x) : ((int)x-1 ) ) +#define LERP(t, a, b) ((a) + (t)*((b)-(a))) + + + + + +"""/* + * Permutation table. This is just a random jumble of all numbers 0-255, + * repeated twice to avoid wrapping the index at 255 for each lookup. + * This needs to be exactly the same for all instances on all platforms, + * so it's easiest to just keep it as static explicit data. + * This also removes the need for any initialisation of this class. + * + * Note that making this an int[] instead of a char[] might make the + * code run faster on platforms with a high penalty for unaligned single + * byte addressing. Intel x86 is generally single-byte-friendly, but + * some other CPUs are faster with 4-aligned reads. + * However, a char[] is smaller, which avoids cache trashing, and that + * is probably the most important aspect on most architectures. + * This array is accessed a *lot* by the noise functions. + * A vector-valued noise over 3D accesses it 96 times, and a + * float-valued 4D noise 64 times. We want this to fit in the cache! + */""" +perm = [151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, + 151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 +] + + + +"""* + * Helper functions to compute gradients-dot-residualvectors (1D to 4D) + * Note that these generate gradients of more than unit length. To make + * a close match with the value range of classic Perlin noise, the final + * noise values need to be rescaled. To match the RenderMan noise in a + * statistical sense, the approximate scaling values (empirically + * determined from test renderings) are: + * 1D noise needs rescaling with 0.188 + * 2D noise needs rescaling with 0.507 + * 3D noise needs rescaling with 0.936 + * 4D noise needs rescaling with 0.87 + * Note that these noise functions are the most practical and useful + * signed version of Perlin noise. To return values according to the + * RenderMan specification from the SL noise() and pnoise() functions, + * the noise values need to be scaled and offset to [0,1], like this: + * float SLnoise = (noise3(x,y,z) + 1.0) * 0.5 + *""" + +def grad1(hash: int, x: float): + h = hash & 15 + grad = 1.0 + (h & 7) + if h & 8 > 0: grad = -grad + return grad * x + +def grad2( hash: int, x: float, y: float ): + h = hash & 7 + u = x if h<4 else y + v = y if h<4 else x + return (-u if h & 1 > 0 else u) + (-2.0*v if (h&2) else 2.0*v) + +def grad3( hash: int, x: float, y: float , z: float ): + h = hash & 15 + u = x if h<8 else y + v = y if h<4 else (x if (h==12 or h==14) else z) + return (-u if (h&1 > 0) else u) + (-v if (h&2 > 0) else v) + +def grad4( hash, x, y, z, t ): + h = hash & 31 + u = x if h<24 else y + v = y if h<16 else z + w = z if h<8 else t + return (-u if (h&1 > 0) else u) + (-v if (h&2>0) else v) + (-w if (h&4>0) else w) + + + + +def noise1( x ): + ix0 = FASTFLOOR( x ) + fx0 = x - ix0 + fx1 = fx0 - 1.0 + ix1 = ( ix0+1 ) & 0xff + ix0 = ix0 & 0xff + + s = FADE( fx0 ) + + n0 = grad1( perm[ ix0 ], fx0 ) + n1 = grad1( perm[ ix1 ], fx1 ) + return 0.188 * ( LERP( s, n0, n1 ) ) + + + + +def pnoise1( x, px ): + ix0 = FASTFLOOR( x ) + fx0 = x - ix0 + fx1 = fx0 - 1.0 + ix1 = (( ix0 + 1 ) % px) & 0xff + ix0 = ( ix0 % px ) & 0xff + + s = FADE( fx0 ) + + n0 = grad1( perm[ ix0 ], fx0 ) + n1 = grad1( perm[ ix1 ], fx1 ) + return 0.188 * ( LERP( s, n0, n1 ) ) + + + + + +def noise2( x, y ): + ix0 = FASTFLOOR( x ) + iy0 = FASTFLOOR( y ) + fx0 = x - ix0 + fy0 = y - iy0 + fx1 = fx0 - 1.0 + fy1 = fy0 - 1.0 + ix1 = (ix0 + 1) & 0xff + iy1 = (iy0 + 1) & 0xff + ix0 = ix0 & 0xff + iy0 = iy0 & 0xff + + t = FADE( fy0 ) + s = FADE( fx0 ) + + nx0 = grad2(perm[ix0 + perm[iy0]], fx0, fy0) + nx1 = grad2(perm[ix0 + perm[iy1]], fx0, fy1) + n0 = LERP( t, nx0, nx1 ) + + nx0 = grad2(perm[ix1 + perm[iy0]], fx1, fy0) + nx1 = grad2(perm[ix1 + perm[iy1]], fx1, fy1) + n1 = LERP(t, nx0, nx1) + + return 0.507 * ( LERP( s, n0, n1 ) ) + + + + +def pnoise2( x, y, px, py ): + ix0 = FASTFLOOR( x ) + iy0 = FASTFLOOR( y ) + fx0 = x - ix0 + fy0 = y - iy0 + fx1 = fx0 - 1.0 + fy1 = fy0 - 1.0 + ix1 = (( ix0 + 1 ) % px) & 0xff + iy1 = (( iy0 + 1 ) % py) & 0xff + ix0 = ( ix0 % px ) & 0xff + iy0 = ( iy0 % py ) & 0xff + + t = FADE( fy0 ) + s = FADE( fx0 ) + + nx0 = grad2(perm[ix0 + perm[iy0]], fx0, fy0) + nx1 = grad2(perm[ix0 + perm[iy1]], fx0, fy1) + n0 = LERP( t, nx0, nx1 ) + + nx0 = grad2(perm[ix1 + perm[iy0]], fx1, fy0) + nx1 = grad2(perm[ix1 + perm[iy1]], fx1, fy1) + n1 = LERP(t, nx0, nx1) + + return 0.507 * ( LERP( s, n0, n1 ) ) + + + + +def noise3( x, y, z ): + ix0 = FASTFLOOR( x ) + iy0 = FASTFLOOR( y ) + iz0 = FASTFLOOR( z ) + fx0 = x - ix0 + fy0 = y - iy0 + fz0 = z - iz0 + fx1 = fx0 - 1.0 + fy1 = fy0 - 1.0 + fz1 = fz0 - 1.0 + ix1 = ( ix0 + 1 ) & 0xff + iy1 = ( iy0 + 1 ) & 0xff + iz1 = ( iz0 + 1 ) & 0xff + ix0 = ix0 & 0xff + iy0 = iy0 & 0xff + iz0 = iz0 & 0xff + + r = FADE( fz0 ) + t = FADE( fy0 ) + s = FADE( fx0 ) + + nxy0 = grad3(perm[ix0 + perm[iy0 + perm[iz0]]], fx0, fy0, fz0) + nxy1 = grad3(perm[ix0 + perm[iy0 + perm[iz1]]], fx0, fy0, fz1) + nx0 = LERP( r, nxy0, nxy1 ) + + nxy0 = grad3(perm[ix0 + perm[iy1 + perm[iz0]]], fx0, fy1, fz0) + nxy1 = grad3(perm[ix0 + perm[iy1 + perm[iz1]]], fx0, fy1, fz1) + nx1 = LERP( r, nxy0, nxy1 ) + + n0 = LERP( t, nx0, nx1 ) + + nxy0 = grad3(perm[ix1 + perm[iy0 + perm[iz0]]], fx1, fy0, fz0) + nxy1 = grad3(perm[ix1 + perm[iy0 + perm[iz1]]], fx1, fy0, fz1) + nx0 = LERP( r, nxy0, nxy1 ) + + nxy0 = grad3(perm[ix1 + perm[iy1 + perm[iz0]]], fx1, fy1, fz0) + nxy1 = grad3(perm[ix1 + perm[iy1 + perm[iz1]]], fx1, fy1, fz1) + nx1 = LERP( r, nxy0, nxy1 ) + + n1 = LERP( t, nx0, nx1 ) + + return 0.936 * ( LERP( s, n0, n1 ) ) + + + + +def pnoise3( x, y, z, px, py, pz ): + ix0 = FASTFLOOR( x ) + iy0 = FASTFLOOR( y ) + iz0 = FASTFLOOR( z ) + fx0 = x - ix0 + fy0 = y - iy0 + fz0 = z - iz0 + fx1 = fx0 - 1.0 + fy1 = fy0 - 1.0 + fz1 = fz0 - 1.0 + ix1 = (( ix0 + 1 ) % px ) & 0xff + iy1 = (( iy0 + 1 ) % py ) & 0xff + iz1 = (( iz0 + 1 ) % pz ) & 0xff + ix0 = ( ix0 % px ) & 0xff + iy0 = ( iy0 % py ) & 0xff + iz0 = ( iz0 % pz ) & 0xff + + r = FADE( fz0 ) + t = FADE( fy0 ) + s = FADE( fx0 ) + + nxy0 = grad3(perm[ix0 + perm[iy0 + perm[iz0]]], fx0, fy0, fz0) + nxy1 = grad3(perm[ix0 + perm[iy0 + perm[iz1]]], fx0, fy0, fz1) + nx0 = LERP( r, nxy0, nxy1 ) + + nxy0 = grad3(perm[ix0 + perm[iy1 + perm[iz0]]], fx0, fy1, fz0) + nxy1 = grad3(perm[ix0 + perm[iy1 + perm[iz1]]], fx0, fy1, fz1) + nx1 = LERP( r, nxy0, nxy1 ) + + n0 = LERP( t, nx0, nx1 ) + + nxy0 = grad3(perm[ix1 + perm[iy0 + perm[iz0]]], fx1, fy0, fz0) + nxy1 = grad3(perm[ix1 + perm[iy0 + perm[iz1]]], fx1, fy0, fz1) + nx0 = LERP( r, nxy0, nxy1 ) + + nxy0 = grad3(perm[ix1 + perm[iy1 + perm[iz0]]], fx1, fy1, fz0) + nxy1 = grad3(perm[ix1 + perm[iy1 + perm[iz1]]], fx1, fy1, fz1) + nx1 = LERP( r, nxy0, nxy1 ) + + n1 = LERP( t, nx0, nx1 ) + + return 0.936 * ( LERP( s, n0, n1 ) ) + + + + + + +def noise4( x, y, z, w ): + ix0 = FASTFLOOR( x ) + iy0 = FASTFLOOR( y ) + iz0 = FASTFLOOR( z ) + iw0 = FASTFLOOR( w ) + fx0 = x - ix0 + fy0 = y - iy0 + fz0 = z - iz0 + fw0 = w - iw0 + fx1 = fx0 - 1.0 + fy1 = fy0 - 1.0 + fz1 = fz0 - 1.0 + fw1 = fw0 - 1.0 + ix1 = ( ix0 + 1 ) & 0xff + iy1 = ( iy0 + 1 ) & 0xff + iz1 = ( iz0 + 1 ) & 0xff + iw1 = ( iw0 + 1 ) & 0xff + ix0 = ix0 & 0xff + iy0 = iy0 & 0xff + iz0 = iz0 & 0xff + iw0 = iw0 & 0xff + + q = FADE( fw0 ) + r = FADE( fz0 ) + t = FADE( fy0 ) + s = FADE( fx0 ) + + nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx0, fy0, fz0, fw0) + nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx0, fy0, fz0, fw1) + nxy0 = LERP( q, nxyz0, nxyz1 ) + + nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx0, fy0, fz1, fw0) + nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx0, fy0, fz1, fw1) + nxy1 = LERP( q, nxyz0, nxyz1 ) + + nx0 = LERP ( r, nxy0, nxy1 ) + + nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx0, fy1, fz0, fw0) + nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx0, fy1, fz0, fw1) + nxy0 = LERP( q, nxyz0, nxyz1 ) + + nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx0, fy1, fz1, fw0) + nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx0, fy1, fz1, fw1) + nxy1 = LERP( q, nxyz0, nxyz1 ) + + nx1 = LERP ( r, nxy0, nxy1 ) + + n0 = LERP( t, nx0, nx1 ) + + nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx1, fy0, fz0, fw0) + nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx1, fy0, fz0, fw1) + nxy0 = LERP( q, nxyz0, nxyz1 ) + + nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx1, fy0, fz1, fw0) + nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx1, fy0, fz1, fw1) + nxy1 = LERP( q, nxyz0, nxyz1 ) + + nx0 = LERP ( r, nxy0, nxy1 ) + + nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx1, fy1, fz0, fw0) + nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx1, fy1, fz0, fw1) + nxy0 = LERP( q, nxyz0, nxyz1 ) + + nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx1, fy1, fz1, fw0) + nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx1, fy1, fz1, fw1) + nxy1 = LERP( q, nxyz0, nxyz1 ) + + nx1 = LERP ( r, nxy0, nxy1 ) + + n1 = LERP( t, nx0, nx1 ) + + return 0.87 * ( LERP( s, n0, n1 ) ) + + + + + +def pnoise4( x, y, z, w, px, py, pz, pw ): + ix0 = FASTFLOOR( x ) + iy0 = FASTFLOOR( y ) + iz0 = FASTFLOOR( z ) + iw0 = FASTFLOOR( w ) + fx0 = x - ix0 + fy0 = y - iy0 + fz0 = z - iz0 + fw0 = w - iw0 + fx1 = fx0 - 1.0 + fy1 = fy0 - 1.0 + fz1 = fz0 - 1.0 + fw1 = fw0 - 1.0 + ix1 = (( ix0 + 1 ) % px ) & 0xff + iy1 = (( iy0 + 1 ) % py ) & 0xff + iz1 = (( iz0 + 1 ) % pz ) & 0xff + iw1 = (( iw0 + 1 ) % pw ) & 0xff + ix0 = ( ix0 % px ) & 0xff + iy0 = ( iy0 % py ) & 0xff + iz0 = ( iz0 % pz ) & 0xff + iw0 = ( iw0 % pw ) & 0xff + + q = FADE( fw0 ) + r = FADE( fz0 ) + t = FADE( fy0 ) + s = FADE( fx0 ) + + nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx0, fy0, fz0, fw0) + nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx0, fy0, fz0, fw1) + nxy0 = LERP( q, nxyz0, nxyz1 ) + + nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx0, fy0, fz1, fw0) + nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx0, fy0, fz1, fw1) + nxy1 = LERP( q, nxyz0, nxyz1 ) + + nx0 = LERP ( r, nxy0, nxy1 ) + + nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx0, fy1, fz0, fw0) + nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx0, fy1, fz0, fw1) + nxy0 = LERP( q, nxyz0, nxyz1 ) + + nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx0, fy1, fz1, fw0) + nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx0, fy1, fz1, fw1) + nxy1 = LERP( q, nxyz0, nxyz1 ) + + nx1 = LERP ( r, nxy0, nxy1 ) + + n0 = LERP( t, nx0, nx1 ) + + nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx1, fy0, fz0, fw0) + nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx1, fy0, fz0, fw1) + nxy0 = LERP( q, nxyz0, nxyz1 ) + + nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx1, fy0, fz1, fw0) + nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx1, fy0, fz1, fw1) + nxy1 = LERP( q, nxyz0, nxyz1 ) + + nx0 = LERP ( r, nxy0, nxy1 ) + + nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx1, fy1, fz0, fw0) + nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx1, fy1, fz0, fw1) + nxy0 = LERP( q, nxyz0, nxyz1 ) + + nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx1, fy1, fz1, fw0) + nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx1, fy1, fz1, fw1) + nxy1 = LERP( q, nxyz0, nxyz1 ) + + nx1 = LERP ( r, nxy0, nxy1 ) + + n1 = LERP( t, nx0, nx1 ) + + return 0.87 * ( LERP( s, n0, n1 ) ) \ No newline at end of file diff --git a/renderer.py b/renderer.py index 5480395..00fa797 100644 --- a/renderer.py +++ b/renderer.py @@ -4,6 +4,7 @@ import random import threading import time from world import World +import sys RENDER_WIDTH, RENDER_HEIGHT = 640 // 32 + 1, 480 // 32 + 1 FPS = 20 @@ -14,6 +15,21 @@ class Camera: self.y: int = y class Renderer: + def key_press(self, event: tk.Event): + if event.keysym == "Escape": + self.running = False + self.keys[event.keysym] = True + + def key_release(self, event: tk.Event): + if event.keysym in self.keys: + self.keys[event.keysym] = False + + def is_down(self, key): + if not (key in self.keys): + return 0 + + return 1 if self.keys[key] else 0 + def render(self): offset_x, offset_y = self.camera.x % 32, self.camera.y % 32 index = 0 @@ -25,14 +41,18 @@ class Renderer: self.camera.y // 32 + index // RENDER_WIDTH ).id]) index += 1 - pass + + def update(self): + move_x = self.is_down("Right") - self.is_down("Left") + move_y = self.is_down("Down") - self.is_down("Up") + self.camera.x += move_x * 10 + self.camera.y += move_y * 10 def update_thread(self): while self.running: + self.update() self.render() - self.camera.x += 8 time.sleep(1 / FPS) - pass def __init__(self): self.running = True @@ -43,11 +63,19 @@ class Renderer: self.camera = Camera(90 * 32, 90 * 32) self.world = World(self.camera.x // 32, self.camera.y // 32) + self.keys = {} + self.sprites = [ "sprites/air.png", "sprites/stone.png", "sprites/dirt.png", - "sprites/grass.png" + "sprites/grass.png", + "sprites/coal.png", + "sprites/iron.png", + "sprites/gold.png", + "sprites/diamond.png", + "sprites/log.png", + "sprites/leaf.png", ] self.sprites = [ @@ -65,5 +93,8 @@ class Renderer: self.tupdate = threading.Thread(target=self.update_thread) self.tupdate.start() + self.window.bind("", self.key_press) + self.window.bind("", self.key_release) + self.window.mainloop() self.running = False \ No newline at end of file diff --git a/sprites/coal.png b/sprites/coal.png new file mode 100644 index 0000000..8d0380d Binary files /dev/null and b/sprites/coal.png differ diff --git a/sprites/diamond.png b/sprites/diamond.png new file mode 100644 index 0000000..65a4317 Binary files /dev/null and b/sprites/diamond.png differ diff --git a/sprites/gold.png b/sprites/gold.png new file mode 100644 index 0000000..cd0ecf7 Binary files /dev/null and b/sprites/gold.png differ diff --git a/sprites/iron.png b/sprites/iron.png new file mode 100644 index 0000000..53a4275 Binary files /dev/null and b/sprites/iron.png differ diff --git a/sprites/leaf.png b/sprites/leaf.png new file mode 100644 index 0000000..779dc5d Binary files /dev/null and b/sprites/leaf.png differ diff --git a/sprites/log.png b/sprites/log.png new file mode 100644 index 0000000..ab56f35 Binary files /dev/null and b/sprites/log.png differ