From 3fe6eb2dd9ba21783899bbb9fb6ba50346cb478c Mon Sep 17 00:00:00 2001 From: DuCouscous Date: Mon, 6 Mar 2023 11:56:55 +0100 Subject: [PATCH] osef --- __pycache__/block.cpython-310.pyc | Bin 0 -> 1730 bytes __pycache__/chunk.cpython-310.pyc | Bin 0 -> 1259 bytes __pycache__/perlin.cpython-310.pyc | Bin 0 -> 1861 bytes __pycache__/renderer.cpython-310.pyc | Bin 0 -> 2662 bytes __pycache__/world.cpython-310.pyc | Bin 0 -> 1271 bytes block.py | 28 +++++++++++ chunk.py | 20 ++++++++ main.py | 3 ++ makefile | 2 + perlin.py | 65 +++++++++++++++++++++++++ renderer.py | 69 +++++++++++++++++++++++++++ sprites/air.png | Bin 0 -> 121 bytes sprites/dirt.png | Bin 0 -> 426 bytes sprites/grass.png | Bin 0 -> 576 bytes sprites/stone.png | Bin 0 -> 185 bytes world.py | 29 +++++++++++ 16 files changed, 216 insertions(+) create mode 100644 __pycache__/block.cpython-310.pyc create mode 100644 __pycache__/chunk.cpython-310.pyc create mode 100644 __pycache__/perlin.cpython-310.pyc create mode 100644 __pycache__/renderer.cpython-310.pyc create mode 100644 __pycache__/world.cpython-310.pyc create mode 100644 block.py create mode 100644 chunk.py create mode 100644 main.py create mode 100644 makefile create mode 100644 perlin.py create mode 100644 renderer.py create mode 100644 sprites/air.png create mode 100644 sprites/dirt.png create mode 100644 sprites/grass.png create mode 100644 sprites/stone.png create mode 100644 world.py diff --git a/__pycache__/block.cpython-310.pyc b/__pycache__/block.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..257d8297a7b846b91882c486266e6a3dc15486c3 GIT binary patch literal 1730 zcma)6%Wl&^6rJ&m9Vcx{fbxEc*CH&41Y3j(6m^#(f`nutnbzZqKpti6Ahjy1R^m5c znGfM7yk(VjcdR&P+%$!%DihtCIWu>z?>TquVZB}x81H`i=Bp>fFM^{(11!O^_i!u1 z2qX7kyIw@(83m+(B#<^fke|w36?wpcsQ_0TR=}aD0#_Z@z%?@mJm;`)<~yQUPwhs<(`SfOMGo2ty1HEWE3cn*I%8qyk;l2; zk6Ryx{j_C9$#9g>TFb*^)K3RFX6cvKtF8RQaM0=}k4$TwWj);7vMh*}QS(q}$zLel z`Z4Ae#4IuR0o;svsy^xs&v>bC6ilc72Kbv`&xZ~b=nxjZ)4`H?;dM<>Gb6jU-tBes ztwQIJCt+8ogL8(yfMplqcI1wT#f}FrcNDy51oFyuQ`s}vw+*_pa7|t4EbVRlvpkc@ z))7V3yMt~X$01M_zy&gpHMzau3Vk@;Mu#kSEvZ`uJ7sJYvqE(TxjoOd!zPq7KEf`* z@l-}Op|~U6$}vrO4>rFE{eXd~Fsc+d*%ClcevnbuliPG2$hz0$cE1{DQ2k9{Ze1uSd zedeADV7%P>sD7ve8C2UcWU>g?)bGT=y453fWKJ}JM{PkD1Pt}lp%piyb)hF;Wv0M+Ol&Hw-a literal 0 HcmV?d00001 diff --git a/__pycache__/chunk.cpython-310.pyc b/__pycache__/chunk.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d970184e7b3017b05b2c94b5ceb4f24deec52164 GIT binary patch literal 1259 zcmZuw%}yIZ44$9e%_f94r73^qP*q&QAwl$tC@rY~wTdc*s#4TymF`TEEy*s-PO5^! z2_(4oSWa-{5&8gqiMjTaSLmtsq~S-xl0Ej=Yy0zflgY^(0m}b&#W^G74;r_LgRu^r zE`bn4&@O3=PTHV?H5f48B!Ua)gb3%DH5@_fq~s1Ep45iVK!&K^CLfG-;Pf2`Ngxq{ zL{xIYByTx3nS+T&H^P)*Z^=`GQo>vh8)u)K41gBOH@(w3+Iy5iM5$p0NcH`9kqn_ z!kHluy97QDeQ;**EV;FzfEw-dpGd!64spyw?4jfv9>v;tds20y*ks})O67_$?w4*7 z?i&9!95v`S&@ob&cOl)j@sJ#t7 zZdZ4CU<$tgW$EiT~6Pkc=@ z)zHo{tpcBsfD3Gk*Fp-hW5N=+usF_i8AKbfd@dfr2NxF6G&uuYhzjw|lQV`%XUHY{ z!S-2w^bjSkp1`+i7KF){$lPi-N_Cj@_SVq0SeMD+ z^AXk{h~h{GL3tI{rP)o_KpBU_TDYnix1}woo?^-w6gL&DX3O~FOco%bU8IK(?iQ() zat7k!W={rz$pt|#5&bUe`5@TuH@hQ`%3=|VGY^_^?a~?+2{n(NXDBSd8-YD2d?5Tc rQyjDpFS?MO=JvMaDomwt2XCRl5AMrk{MAuwYxsmVU4b~vp;PQ1^Mnjd literal 0 HcmV?d00001 diff --git a/__pycache__/perlin.cpython-310.pyc b/__pycache__/perlin.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b2b2046f048575641e6635a470e5f006b1ae9816 GIT binary patch literal 1861 zcmZWp&2Aev5a!=XtF>gyju6|4izYyULIo1pMvsPDphnR{VHD}1fPlb|mup##q_w$} zVFeUWKzV__fqm?)Z_xMPwI|(r>Y1YXm1-2hMYvR(mS(oMYzUeBs?#u4Xd)?Qm6COcfb2W`uR1~c-Oq#V-i5D>`n z9cIx4=`+V(s~OkqcX2N8FWwf0JOcTHwS^Ziw>=*iMM@(7ecd_DM_ETt(tJ|T>>T9j zWR#69r0k;e)6|~kLU1%D|hl_oPWSc-W!$VkeN z;-3&KyW-bu#;nlXN-EduA7?zQR9GF%gpC}#s%W95RV{WctlB_Pt$NC4@}3RlhD`>W zgiYD%RqUjL-YEyqb#~2Xk&85cBhB})MDz#Ph^w*Ed?qm!Eb2tqnnOnL73*w|oj1>G znxTa1Fcfb=Wn9oP+ljB3-dN`&UwKvX2nz1%iAkTmG{L=HO=f#JcF;z0Ho|!D|4b!7LPbz1z1rqaRd|UV) z^B7;kl~9nyzv{i&#DDX2EhSto6K>dI5pEEtU#%9IJqoOZfe*Z(rN?v z7dx1{53`gyw;R|NaPW+qCy+mhE};z3391&6EvLBaY?Gq#LtwQ9i&+MN{Fvl*B6nad zOA=El1^_4(p+ufEPa%KQ9CTlI5oxF9E}XN4lio_iH_EdvXtSYbp*$-u6L=82S{$Vl zbCEsAz7Tqgo6jJBbl68w&h7J$}kF0QF&Sw>H1zrW0 z;4ydvUbAQhS8?$i$vd%u@;N~NM9jr33AXBu4b5`TwshlHyXP0(_|gi1DBadpUz8(lruI)!3aNxz|wii>(%N_8Yt{NO&ZU-9VX^^KohLGsF^?c&_ zMOPL_=&hdT$0VZ1-aZ6Wb({~1Y*&8)zk*02lF(7HpuURvmY^=%;&svDtw5D9Ut!}X zh`YOXLb7ER-Bsd_3OT3eT^ufcgAD-x9Lz^1pNw^zn=i3?n3zoS;Xd>MX)SJEkYgj% z%q-FV6(ZCxJ~{5CZ~Eb9ra{`!O7sdmsA$ML{OMk_fb#I(#CxM$Plnk(^-n>SY%+RQ S6yM+|M>AG&6wCNYBL4>j%T#p$ literal 0 HcmV?d00001 diff --git a/__pycache__/renderer.cpython-310.pyc b/__pycache__/renderer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d17575b6cbf264c1b5084b9de54d8375be3730b GIT binary patch literal 2662 zcmZ`*TW=Fb6rP#AdSfTymOwxhDyXn3C5Td}RD@6oH>r&x5(#NkWEs!KUdP@IvtvRc zN2&x;dEue|!08)*qHp~Reb}c;eTw=IDpC5K**FAHcQt3vnK^Sgw{JG9)gp%H@83Q3 zBxLL_5)MBOgj;BN2ShQ&drWeCMNjk{>GWOc^0MEPo*nn4Z@+;I@O64&zalHpaeovt zk`v04)q70&DtO6M@IuHMq)=5LRUl0&zQXF!9(H3(by0W^`ptG+1opGKUgw4PDAPSv z7kek5vNuiSI7kcagU5w*3oSnj65CTtp?K^l5j$(Ha+LcLr&k{K^9%oWvmfhb!Jij= zt3_6iAL0etZM2-W8}cD*u%Q5jCor4ipt^z)O}?x7ji-ZVZ-2x|QllraiapgKQlma30h>Ux`-E(U z+n!InOCGsJY8OD>dsm5W z=U{~<8!25AO5i;!)e665)9ih26y7GKv#bp^RMW(bR%ei|=Y?mIUYwJ9`mC8tzn?ve zO;%JN-dS3_^RV&g!Q$$D86_s}x3Y9CX%|7hp&{n7(vD5zNiS=y7a~!0Pg5{un60hl z74m zlG&87Hn`WokaP8^Asg{sW}PowI9>7UsIi7)+>xh*@lUf|Zbw<}Sf@Hmdz6@Z2BaPo zfgYr3lD73{)HzFp>aTz;{kZV*UL0=}&fVpeH{9C)v3X-}n~si~iU1;~+VXkGr}-rJ z-@5Mh%z<6|p(&L=G0(?DhgSFlMDbU^2E#{Umw|I$*=$vU%(1+u9O8|yT;;wH&=`>xyQ`$?g?nlsL9u~)-3qh(Mg&`D~?VPr=~ChY)9=*FRgBS zKiocdWl;v#u3mnA^_$DdEhLsEX?y#~xFa`N8r!bvahFQ8`B15? zn|V%MA2^pFCO}(3%g=zckv)&29d3|4MvR;x-^Kfjcq&#(EUUYkA|a#YPG&NDWoTNZ zaI=j##cd+yFH65X$HyrV-RLE`X=VM5n_tt06jq;2bN}7;#e+;3L+$(x6j-yD-vl$B zmHdRQl0T90(%bBy7I6`Hn~5?V>38C!-7zwH(rm4_bv8)VCzewF9ixqxL9C@0b`Tm1 zMSw0N2*MOWn3V{^tb`QmmUZJ8pZFJCxqvnSc=BGmrFZJSjg%&%q)0a{IF-dDq~A3IlLt!AqY;m!=2+7n-Tc`ZAy|?vcXjkz@5G8sv$-NSb7dwwFmA z+zqsxiq{85x{Y_v}wn^}3da(@KF)mD_x9lBM z);Xccd-&8RNu;Am+~9b#Tgz6KX7^YZpMwkMb%ZF^dI7R@ zmLGg?tHIWY{t|uqD#o~H#570f|^i||JIlW~)PJ|{E?Q8PFO N-YO4;%O}NA?>~$VJski5 literal 0 HcmV?d00001 diff --git a/__pycache__/world.cpython-310.pyc b/__pycache__/world.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc3b9391acd4b335269611897d816ce5b566ab0e GIT binary patch literal 1271 zcmZ8g%}x|S5bo-po*hIV~heS#AIXqiOD3U1KSO(%n$U;Dv;p> z58$1c$dMQEA^PfxSMY*WJ@RKys=B(Wr@Fqcy7RHICd0AvOX^rK_L~-$2m07^lwuB* zW*QQfLJTR7c`9N7+;NdogKSVLMMM>pE(H2UA%NX+4|Dcx%N3*&w>D5b((hM-jiI%81S%kMlviAXMW@H&wp!se5TZ>z4pD(b_clQK(x%cvOZ)-0o z8NA(Au zbRtXjTLNy!NR6X%a?=j7(vEuDE@x}T64Z{gH)zi}>kbAEzIf(qb(6v^RFtb|qlzGc z+bAJ#^EONaKMh3_c5l|KUg@d}ttp2#yFxKtCOX?wJc9-TCz@f3A$TI1ll4Q~@mH#Z zHX~n~9nquWJ$noP=>#6j1y(24OlhxU=)dCK2nN&&y})UV7R1vG?6&H1&ttt#M7Jhe zPK{EosZ^TlVM6w(Qd`62m}uRi_k|<3o;@$0TYd>mZe3f z>7=iz&On@4dSP+6X>2mcobetzC%NcpUGFox3;wuCY}6!7@V{v? B4_g2L literal 0 HcmV?d00001 diff --git a/block.py b/block.py new file mode 100644 index 0000000..486ad37 --- /dev/null +++ b/block.py @@ -0,0 +1,28 @@ +class BlockType: + NONE = 0 + STONE = 1 + WOOD = 2 + GRASS = 3 + +class Block: + def __init__(self, id: int, durability: int = 0, type: int = BlockType.NONE): + self.id: int = id + self.durability: int = durability + self.type: int = type + + +class BlockAir(Block): + def __init__(self): + super().__init__(0) + +class BlockStone(Block): + def __init__(self): + super().__init__(1, 20, BlockType.STONE) + +class BlockDirt(Block): + def __init__(self): + super().__init__(2, 10, BlockType.GRASS) + +class BlockGrass(Block): + def __init__(self): + super().__init__(3, 10, BlockType.GRASS) \ No newline at end of file diff --git a/chunk.py b/chunk.py new file mode 100644 index 0000000..dc36e25 --- /dev/null +++ b/chunk.py @@ -0,0 +1,20 @@ +import block, perlin + +CHUNK_WIDTH = 32 +CHUNK_HEIGHT = 32 + +class Chunk: + def gen_block(self, x: int, y: int): + height = int(100 + perlin.noise2d(x, 0.1) * 10) + + if y < height: return block.BlockAir() + if y == height: return block.BlockGrass() + if y > height and y < height + 4: return block.BlockDirt() + + return block.BlockStone() + + def get(self, x: int, y: int) -> block.Block(id): + return self.blocks[x + CHUNK_WIDTH * y] + + 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)] diff --git a/main.py b/main.py new file mode 100644 index 0000000..fb703d8 --- /dev/null +++ b/main.py @@ -0,0 +1,3 @@ +from renderer import Renderer + +Renderer() \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..fe28434 --- /dev/null +++ b/makefile @@ -0,0 +1,2 @@ +all : + python main.py \ No newline at end of file diff --git a/perlin.py b/perlin.py new file mode 100644 index 0000000..9b1029b --- /dev/null +++ b/perlin.py @@ -0,0 +1,65 @@ +import math, random + +W = 255 +H = 255 +background=(100,100,100) +gradtable = [ (0,0) for i in range(0,W*H) ] + +def precalc_gradtable(): + rnd = random.Random() + for i in range(0,H): + for j in range(0, W): + x = float((rnd.randint(1,2*W))-W)/W + y = float((rnd.randint(1,2*H))-H)/H + s = math.sqrt(x * x + y * y) + if s!=0: + x = x / s + y = y / s + else: + x = 0 + y = 0 + gradtable[i*H+j] = (x,y) + +#calculate dot product for v1 and v2 +def dot(v1,v2): + return ( (v1[0]*v2[0]) + (v1[1]*v2[1]) ) + +# get a pseudorandom gradient vector +def gradient(x,y): + + # normalize! + return gradtable[y*H+x] + +def s_curve(x): + return ( 3*x*x - 2*x*x*x ) + +def noise2d(x,y): + + x0 = math.floor(x) + y0 = math.floor(y) + x1 = x0 + 1.0 + y1 = y0 + 1.0 + + i_x0 = int(x0) + i_x1 = int(x1) + i_y0 = int(y0) + i_y1 = int(y1) + + s = dot(gradient(i_x0, i_y0),(x-x0, y-y0)) + t = dot(gradient(i_x1, i_y0),(x-x1, y-y0)) + u = dot(gradient(i_x0, i_y1),(x-x0, y-y1)) + v = dot(gradient(i_x1, i_y1),(x-x1, y-y1)) + + s_x = s_curve( x - x0 ) + a = s + s_x*t - s_x*s + b = u + s_x*v - s_x*u + + s_y = s_curve( y - y0 ) + z = a + s_y*b - s_y*a + + return z + +def col( a ): + return int(round((128-(128*a)))) + +precalc_gradtable() \ No newline at end of file diff --git a/renderer.py b/renderer.py new file mode 100644 index 0000000..5480395 --- /dev/null +++ b/renderer.py @@ -0,0 +1,69 @@ +import tkinter as tk +from PIL import Image,ImageTk +import random +import threading +import time +from world import World + +RENDER_WIDTH, RENDER_HEIGHT = 640 // 32 + 1, 480 // 32 + 1 +FPS = 20 + +class Camera: + def __init__(self, x: int, y: int): + self.x: int = x + self.y: int = y + +class Renderer: + def render(self): + offset_x, offset_y = self.camera.x % 32, self.camera.y % 32 + index = 0 + self.world.update_chunks(self.camera.x // 32, self.camera.y // 32) + for tile in self.tiles: + self.canvas.moveto(tile, 32 * (index % RENDER_WIDTH)- offset_x, 32 * (index // RENDER_WIDTH) - offset_y) + self.canvas.itemconfig(tile, image=self.sprites[self.world.get_block( + self.camera.x // 32 + index % RENDER_WIDTH, + self.camera.y // 32 + index // RENDER_WIDTH + ).id]) + index += 1 + pass + + def update_thread(self): + while self.running: + self.render() + self.camera.x += 8 + time.sleep(1 / FPS) + pass + + def __init__(self): + self.running = True + self.window = tk.Tk() + self.window.title("MC 2D") + self.window.geometry("640x480") + + self.camera = Camera(90 * 32, 90 * 32) + self.world = World(self.camera.x // 32, self.camera.y // 32) + + self.sprites = [ + "sprites/air.png", + "sprites/stone.png", + "sprites/dirt.png", + "sprites/grass.png" + ] + + self.sprites = [ + ImageTk.PhotoImage(Image.open(sprite)) for sprite in self.sprites + ] + + self.canvas = tk.Canvas(self.window, width=640, height=480, background="white") + self.canvas.pack() + + self.tiles = [ + self.canvas.create_image(32 * (i % RENDER_WIDTH) - 16, 32 * (i // RENDER_WIDTH) - 16, anchor="nw", image=self.sprites[random.randint(0, len(self.sprites) - 1)]) + for i in range(RENDER_WIDTH * RENDER_HEIGHT) + ] + + self.tupdate = threading.Thread(target=self.update_thread) + self.tupdate.start() + + self.window.mainloop() + self.running = False \ No newline at end of file diff --git a/sprites/air.png b/sprites/air.png new file mode 100644 index 0000000000000000000000000000000000000000..e318ab61481c3f7c6a4420fd678a5edfcea98bea GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzmSQK*5Dp-y;YjHK@(ny)977^n z-<~sMWKiHau%YR{@P6lG^R74)R~hS;nLh_AK?b4n4M&(ReGF+X0f~CL`njxgN@xNA DMZz7< literal 0 HcmV?d00001 diff --git a/sprites/dirt.png b/sprites/dirt.png new file mode 100644 index 0000000000000000000000000000000000000000..1c380767cdb2aca0cb30c8ed5ef6ff64263a28df GIT binary patch literal 426 zcmV;b0agBqP)wnjzE9l>bR0H1pN>aV=Kn545I^4M;UF(G-IYgN0>hJy9bd-}2!bqtZcfbD@J=BO4X~YRis2GSuyo_}M%t*XD zMGRd>TtQY8dH=}JC?iy`_P}&9w}E+Xm=VbaYlDt~=wh{J7|8t6aHRrnz|R8;yP6Lr zunVy+Bm(?8fmq7X%9;{v#~EY&nHe>)28`=~2kUYJBPxc*&B(%cmWqp+vZohZm=SZ` zup42xkf!;GXr}gWC!qdtwNlnd02L2aP*`AQ(TEqA&rva&a@hQUo|%lrUZ9k!;lsZl zO~XM(*8%jWaqdSXm_Z<;yCHh-r1(DK=t$O|nHX}ch&E|SS{&RoW7f2C( UZ*|!sr2qf`07*qoM6N<$f?Simh5!Hn literal 0 HcmV?d00001 diff --git a/sprites/grass.png b/sprites/grass.png new file mode 100644 index 0000000000000000000000000000000000000000..1b5ea951d160e3551155196be45f9d6c1e00e07f GIT binary patch literal 576 zcmV-G0>Ax;CNpnm-4rjr%k0d&ee-{B-uu5%E1ez914{6a zhd%;%1Rw%X32L2d5#KQ91E!~4B2RHI2iStF~xJ^%;HP2wka0SvFly#4-*)m|T^ zVe8{DDCjQEv)^7o6M~vXquQNqt*$k1dMCU){yh~9)HDcyVI|~e{Tah*NG*z4JUyot z#j?8z<>>&vE;TqmgX+W(Ft64JYnEJwyV1cNaEvZDFCw)?HC39@&K}jDaWXB=2$TR+W2-I ziZB`y6iTpcLT1Y`=MX7}09yo|Pi=Kx#Oz3Vd`#04WHY_;^^NO#PBj@~|XH z`2mnTyf0H~6M&68Btmf|rmrNx18Y5-hD|SBS7HM%>0tH(-#39z<8mdhp(FEv>v17n zjji|FKqMk}L)&^vKG|!_6Ojpvu%OLo$yQzb3T7<+PqL!5?xBBHY4H!La+;eElR^yu O0000xj-k)yp{>ft#2bX;zTnEmiF?z5FI5hlb zI3c=(VS=^?;{r{_3$t!BW}My6I9GT&0|=kVVO;%d_q9!|YhImSquRV=okFwCe|`>y d28Qd*c6YXk{qH`IIT>g-gQu&X%Q~loCICW4K Block: + return self.chunks[f"{x // CHUNK_WIDTH}:{y // CHUNK_HEIGHT}"].get(x % CHUNK_WIDTH, y % CHUNK_HEIGHT)