From 219eebbfb69a51e04376a50da27fffc21f06e3de Mon Sep 17 00:00:00 2001 From: Sander Schobers Date: Sun, 4 Jun 2023 20:47:55 +0200 Subject: [PATCH] Rendering different orientations of a tile. --- src/assets/images/tiles_grass_32.png | Bin 3087 -> 4896 bytes src/context.zig | 2 +- src/engine/assets.zig | 2 +- src/game/tile_map.zig | 34 +++++++++++++++++++++++ src/game_scene.zig | 40 +++++++++++++++++---------- src/main.zig | 2 +- 6 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/assets/images/tiles_grass_32.png b/src/assets/images/tiles_grass_32.png index e2896cfcfdad47de6d4f796f2a0d9cb1e1eb7f3b..79f8b8343e46dd53f60fdd32671792672f7b62aa 100644 GIT binary patch delta 4562 zcmaJ^cTm&K)(#*BLP_XFN+JqM5fm&)hakQ8Pz4lFBfLm&zt99k5k)|dE-g}|1W-Vl zQY1)~(1~>E5PBfw^3HrS-^~5vo|)a9ooCPN>@$0wbIxnt98pA^v7r_VgdYL|fmn33 zk)~&B%fEx+{Ml?e`2<{v2&Mtpp6Vdg%mXskGxa<#jBs^AFT{r%fY}+u)c$~`?8@ss z*i>!&Bo-wOWs4mbsS|-*6iB-5x#UXBC4@`YaS; zPuy%MgW6Lw1k7nBxzHU6x8`O?sy-fy`8(XJuTk{tGwml@Ya z2NoY&QS_1Xg~NT7I9H0xt_9U4sLYk#9T+rjSh_vy$*(Xj`C@$u|M)mCFmorV?M?dU z?qCu6DcDOEiN(At^ix);;Tv*kR{vBkT+kE6uOt*=kqQU{Sq%~3@ew9L0IPV(3%2M>*7m{oP zkr3H2UvGt|#|PeAuPg~$JUC1*ZT?`nqwS&R_*JT&kbT9IdOL8*WG&oY{iFexe`DKt z4IAy4Z=t91yUVmS;7c^f)*MJ9VC94bx z&jj|Zk9L$SJ`?84n@fXxPwTqf*qFn84qNz&gKN|uTNOrUE3_G`v(~8RM|r1gG(YLr zQ9|28v5BT|seJe&PwvNF*<1MLv2pwj$rqvH$}}U8AL}LG)NLi_-jLe&uC}mVvZ{$B_|#6Xb<)Sy zFfB!ny(-futV+L%*-os4buislupB?mJu?+t1_)EK)ir5wnml|%dBxl>BqXIQ4GvlK zR-S#YWKDimA@NZl)?#`N!1>%Qgc(ljTHWDKKB3!Of)T78f}UTA));PneQJa) z>Z3ECEb=oW#T2jPNzmQAkC0Q=?59%-{8c5e03UE!kQh;%?y@R;uP~gO5ke3zkgb8Ne8YrA(D{hfy9GSpZQYgl6}v9q`P4xA5ZgB?l(3qoJ{G} zr!^M5(%YS|hx#o7E^q@?w^t1lS z@qU2{r^h3#Y1Zceyf(OfFrFn(Z*H(935(+|>+!=<5oF?RTb*|m>;m3(D5uguU;HDs zVHecxviiezyL<&kTZBApB*HjN!^)w{O6902idfee32=SH8z$S+ES2pHDNqs-LG$~mH`Xu{j zx?ZNjSL_`&cV_O46)|6xMUbc!3i{_!6oMVH+8?mr81%yH08_s zgD?xeeBZvL@=puZpPrGX_frC5JSOcN#YAw!{~~7%>#|pBmlc|rz3FzhalD7Rc$G7^ zT_CNg2INk8x5*dpl}oafz%K5vL^%%nQ-E&^zkX9Im&AuOQl96dR!1qkSUQzu)Q21? zo1x1)w|vkX1|M#$wiYof@N|Tg+dW7QEXp6VqViO)h-xWa<~IikvTxtXDcd@nPD%#0 z4kk+ok2H#u^nDWtr6Me;%4EmFw0r=x z@#0L93SXZemC`=P)Ba^v*&(#CB;+Zow-8~Lu&W`2Yyg3!17eanE}Q@0XnF;~gYTF7PY9IUVI`d{mIDIXV^>uNf`BnYFGh9?I*3PG91 z2}I@QkHB;^UKD@B4>@%EcRjUww_6TX4_Y!G7<9ehea;v{bW6Hq?IOXQMA-Kku;gYwsnYLr z=ip7%IKz2t5c4S`l2OS_yCF<+6R(HNMq0Ts^S3?`#u{g+2~_G8r@) z&u$PSl3uog?iz8)T$B>HWMVrm2Fg0`@j8b*r|fc|-&sE+87a{t&)* zyDNj+KU$a{@&HB+H+!GdNbbyJmv?#hZd%C!#}$;X2euk@LMbVa?+RF)`YpNDxXlMo zZjiHH*G8<#D$DopiG4Z%40mrY%H4#j`UEh+bv#ZqQar<&FOp@77t+Kpbw1G(^@aCP z`h2!)k>-Y>eh{dFJ_|l*hZFFUwbQ0q^c249zjzX+2_!vhK1ie|=g@8Amp~jgky~#1R33G*vDSPlgZTz|g*f0O%cZpWsU z9N-9jwcBImo-EIuWv_Gr{Y8-9*K(s{uD!1C$jfHonWI8p^VGV;Vz4DameYC4K@v=2 zT8MXcoEBY&d5q-mfKB7BhIaFVOdOyvwo@lcnYY~3L$)2-LeS*dSr;p=UKeXtW1y3L zOCa=_JH0j^anFXem-@!{&GdScjs}cuHV1oN+&9K29K&Ek^Iv7+|Jr(upCG8)$%+HU z!T}&vjz?OTGHbRlOaFykU+r@EP%GB}Q?D3nR^u%K-#WP>E+gOw7 zQ^JgYgo-t%FFn6P-gbT#(YeWhM+k(wTmmk(`Kx2WI9iWiD&T?!B&^eLb^IiPd~&O4 z52I2Bw(EhWYst^4DY+&xn~du4ewLlse9;(@M)DUWn`wgsLPoSbYOOuw_-Ma?`1VZm zRa1xFKyryv50TPB6EUBn6P8-zZezOUXvQ;Oc}1c%IrSc+C_U(XrA}Sg-F+cU;rmq( zfiaZ)PC4(>-qIcWSq?%X%r?@!>G^d~m%$*f6HtqKYYY83P~iuv;_hyrY!cH*H^0-7 zib&?7{YDP3dam|VY0}|9;5Reo$1ccn%}xh0~?uAnw>`M+xyrK6uOTbGfTN#Zl3gr~smVBBz(fu*OIz z1YW7g#|e^2R`W`Td{NNPQ~hmtX*GrR@S(qH2MjR-hTp5*q^p3h1UN7$_RU+%-eo7A z3XA$yybPCN7{EU@&Re+^otU#K6E^^?LP}-YpHO=bs4r}({f}fo1+@85D&7yHN6xG7 ztUs+6?CGeL(wlKJBH_OaQW|TsZF=GgJz-?b#{1y#*zp)vZyAB~uLD1v1JlYq32wD0 z!t{4IZ`9vLzTTLd5y=%!BC5|ZJAAixzi8mCI^bX@b5rlyWxT?6= zjw2$Zr04Cj7iS|>)vQV!<9Qrzm$t_!|5+xc^x#QNlrPxkCp+ywJ!ls7xc!-*h-jXn zY>I3Tp zew2P>_O)hQ6s}dzl4wk0)dJ)i>NKvd+QdnpqifN6V5oS2QWbxyl>alSdX08%$JLq% z)YDp|HWg&eCjm3@0Mqt$1eJwK*z)AkhZ7xeQZHA ziRzvWYL^WpDYMIOo2YpcqVoP>_u46RZE#pY-Bb>muUUBDB$VPPyCP3LnoIW2m8u2# z?>)hVvxD+PHqK8m=2$V*>@5y2h&l;?oCSvICL3+p*WbZ?UmIf2#mSbGo*NYaOQP24 zSLmWH{hxyTcmMgngysLSY*8(ROHi;g#teSUcpcpbJO79GJ;W)qzu3rQmrWs;4P$n3 zIZ<)dr(@YGiVmx08FsP}xRCQhI4o!=`2FOabKa{6Hgs}?QY2st#jhF+(qabMHX8_{ zQ^t3>ScbHc7kQcIaDFfm&HjmiNY2;ZxX3CRcXcz*#1#{9h}V@8=2hq=EJ4YFG5w03 zCXK1lV=(--!8`b+Ke@q{LORu|Nb|JwnPn;Sy?rtZj8zxuXjS-uVR6ChViz_pacW2CfwWG-)X$uy*EyG3%D}R`!2bSQHf&QZ7o>X z9;ivWsbMcs)M)?3%!j?SkY~@a#$HwLA!0JXF-#E5`P$OFl=O?4#*6tByoH#O>pD{6 Q|M$P?Xc{8R)tw^#109T!82|tP delta 2739 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 F{|jBegZBUc diff --git a/src/context.zig b/src/context.zig index 34937e4..36eae93 100644 --- a/src/context.zig +++ b/src/context.zig @@ -14,7 +14,7 @@ pub const Context = struct { palette: Palette = undefined, shouldQuit: bool = false, showFPS: bool = true, - showDebug: bool = true, + showDebug: bool = false, scene: ?Scene = null, events: allegro.EventQueue, diff --git a/src/engine/assets.zig b/src/engine/assets.zig index b7863cf..6e69092 100644 --- a/src/engine/assets.zig +++ b/src/engine/assets.zig @@ -114,7 +114,7 @@ pub const Sprite = struct { var i: i32 = 0; while (i < n) : (i += 1) { const left = @mod(i, horizontal) * width; - const top = @divTrunc(i, horizontal) * width; + const top = @divTrunc(i, horizontal) * height; frames[@intCast(usize, i)] = try bitmap.sub(left, top, width, height); } diff --git a/src/game/tile_map.zig b/src/game/tile_map.zig index dd54559..9a8fc21 100644 --- a/src/game/tile_map.zig +++ b/src/game/tile_map.zig @@ -27,6 +27,22 @@ pub fn TileMap(comptime Value: type) type { } }; + pub const Ordinals = struct { + left: bool, + top: bool, + right: bool, + bottom: bool, + + pub fn count(self: Ordinals) usize { + var n: usize = 0; + if (self.left) n += 1; + if (self.top) n += 1; + if (self.right) n += 1; + if (self.bottom) n += 1; + return n; + } + }; + allocator: std.mem.Allocator, columns: std.AutoHashMap(i64, Column), @@ -64,6 +80,24 @@ pub fn TileMap(comptime Value: type) type { return null; } + pub fn getOrdinals(self: Self, x: i64, y: i64, ofType: Value) Ordinals { + return Ordinals{ + .left = self.isOfType(x - 1, y, ofType), + .top = self.isOfType(x, y - 1, ofType), + .right = self.isOfType(x + 1, y, ofType), + .bottom = self.isOfType(x, y + 1, ofType), + }; + } + + pub fn isOfType(self: Self, x: i64, y: i64, ofType: Value) bool { + if (self.get(x, y)) |value| { + if (value == ofType) { + return true; + } + } + return false; + } + pub fn set(self: *Self, x: i64, y: i64, value: Value) !void { const c = try self.ensureColumn(x); try c.set(y, value); diff --git a/src/game_scene.zig b/src/game_scene.zig index 2c3506a..f28e309 100644 --- a/src/game_scene.zig +++ b/src/game_scene.zig @@ -50,11 +50,7 @@ pub const GameScene = struct { const renderer = ctx.renderer; const viewport = renderer.viewport; - const center = viewport.center(); - _ = center; const bounds = viewport.bounds; - const scale = viewport.scale; - _ = scale; const background = renderer.textures.get("background_jungle").?; const backgroundDisplacementFactor = -0.01; @@ -66,30 +62,46 @@ pub const GameScene = struct { const tileBounds = self.game.tilesInView(); + const tiles = self.game.level.tiles; + const collectables = self.game.level.collectables; + var x = tileBounds.min.x; while (x < tileBounds.max.x) : (x += 1) { const randomDirtOffset = self.game.randomTileOffset(x, 99, 3); self.game.drawSpriteFrame("tiles_dirt_32", 0 + randomDirtOffset, x, 19); self.game.drawSpriteFrame("tiles_dirt_32", 3 + randomDirtOffset, x, 20); - if (x < 0) continue; - - const tiles = self.game.level.tiles.ensureColumn(x) catch continue; - const collectables = self.game.level.collectables.ensureColumn(x) catch continue; var y = tileBounds.min.y; - while (y < tileBounds.max.y) : (y += 1) { - if (tiles.get(y)) |tile| { + while (y <= tileBounds.max.y) : (y += 1) { + if (tiles.get(x, y)) |tile| { switch (tile) { game.Level.Tile.Grass => { - const randomOffset = self.game.randomTileOffset(x, y, 2); - self.game.drawSpriteFrame("tiles_grass_32", 1 + randomOffset, x, y - 1); - self.game.drawSpriteFrame("tiles_grass_32", 5 + randomOffset, x, y); + const ordinals = tiles.getOrdinals(x, y, game.Level.Tile.Grass); + var offset: usize = 17; + switch (ordinals.count()) { + 1 => { + if (ordinals.right) offset = 0; + if (ordinals.left) offset = 3; + }, + 2 => { + if (ordinals.right and ordinals.left) offset = 1 + self.game.randomTileOffset(x, y, 2); + if (ordinals.top and ordinals.bottom) offset = 12; + if (ordinals.right and ordinals.bottom) offset = 4; + if (ordinals.left and ordinals.bottom) offset = 5; + }, + 3 => { + if (!ordinals.left) offset = 6; + if (!ordinals.right) offset = 7; + }, + else => {}, + } + self.game.drawSpriteFrame("tiles_grass_32", offset, x, y - 1); }, // else => {}, } } - if (collectables.get(y)) |collectable| { + if (collectables.get(x, y)) |collectable| { switch (collectable) { game.Level.Collectable.Star => { const distanceToPlayer = engine.Point.init(x, y).float().distance(self.game.playerPosition); diff --git a/src/main.zig b/src/main.zig index 384f0ad..eec7b83 100644 --- a/src/main.zig +++ b/src/main.zig @@ -50,7 +50,7 @@ pub fn main() !void { try renderer.sprites.addFromTextures(renderer.textures, "character_lion_48", 48, 48); try renderer.sprites.addFromTextures(renderer.textures, "item_star_32", 32, 32); try renderer.sprites.addFromTextures(renderer.textures, "tiles_dirt_32", 32, 32); - try renderer.sprites.addFromTextures(renderer.textures, "tiles_grass_32", 32, 32); + try renderer.sprites.addFromTextures(renderer.textures, "tiles_grass_32", 32, 64); allegro.convertMemoryBitmaps();