diff options
| author | tslil clingman <> | 2021-09-01 12:59:50 -0400 |
|---|---|---|
| committer | tslil clingman <> | 2021-09-01 12:59:50 -0400 |
| commit | 6a2d132873ce7b40405a3dc000a12539fffd969b (patch) | |
| tree | 3b730360b348900fbc937bd44b89c293c39ca00c /src/main.zig | |
Init
Diffstat (limited to 'src/main.zig')
| -rwxr-xr-x | src/main.zig | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/src/main.zig b/src/main.zig new file mode 100755 index 0000000..2b5f7f2 --- /dev/null +++ b/src/main.zig @@ -0,0 +1,157 @@ +const sf = struct { + pub usingnamespace @import("sfml"); + pub usingnamespace graphics; + pub usingnamespace window; +}; + +const isKeyPressed = sf.window.keyboard.isKeyPressed; + +const std = @import("std"); +usingnamespace @import("raycast.zig"); +usingnamespace @import("renderConstants.zig"); +usingnamespace @import("map.zig"); + +const screenWidth = 1280; +const screenHeight = 960; + +fn renderWall( + window: sf.graphics.RenderWindow, + sprite: sf.graphics.Sprite, + col: i32, // which column + top: f32, // top of wall + height: f32, // how tall + texfrac: f32, // how far along the texture + texture: u8, // which texture index +) !void { + const hFact = screenWidth / planeWidth; + const vFact = screenHeight / planeHeight; + const xpos = @intToFloat(f32, col) * hFact; + const length = height * vFact; + const starty = (screenHeight + vFact * planeHeight) / 2 - top * vFact; + const tind = @as(c_int, texture) * @floatToInt(c_int, 1 + wallTextureDim); + + sprite.setPosition(.{ .x = xpos, .y = starty }); + sprite.setScale(.{ .x = hFact, .y = length / wallTextureDim }); + sprite.setTextureRect(.{ .top = 0, .left = tind + @floatToInt(c_int, texfrac * wallTextureDim), .width = 1, .height = wallTextureDim }); + window.draw(sprite, null); +} + +pub fn main() !void { + const PI = std.math.pi; + + // Setup player and map + //-------------------------------------------------------------------------- + + var player = Player.new(15.75, 1.5, // pos + PI / 2.0, // ang + @intToFloat(f32, planeWidth), @intToFloat(f32, planeHeight)); + + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + + var map = try Map.new(32, 32, &gpa.allocator); + defer map.deinit(); + + var y: u32 = 0; + while (y < 32) : (y += 1) { + map.cells.items[y * 32 + 00] = Cell{ .height = MAX_HEIGHT }; + map.cells.items[y * 32 + 31] = Cell{ .height = MAX_HEIGHT }; + map.cells.items[31 * 32 + y] = Cell{ .height = MAX_HEIGHT }; + map.cells.items[00 * 32 + y] = Cell{ .height = MAX_HEIGHT }; + } + + map.cells.items[y * 15 + 15] = Cell{ .height = MAX_HEIGHT, .wall_texture = 1 }; + map.cells.items[y * 15 + 14] = Cell{ .height = MAX_HEIGHT / 1.5, .wall_texture = 1 }; + + // Initialise SFML + //-------------------------------------------------------------------------- + + var window = try sf.RenderWindow.create(.{ .x = screenWidth, .y = screenHeight }, 32, "zirc", sf.window.Style.none); + defer window.destroy(); + + window.setFramerateLimit(30); + + var backRect = try sf.RectangleShape.create(.{ .x = screenWidth, .y = screenHeight / 2 }); + defer backRect.destroy(); + + backRect.setPosition(.{ .x = 0, .y = screenHeight / 2 }); + backRect.setFillColor(sf.Color.fromRGB(50, 50, 50)); + + // Load the background skybox, really `skycylinder', and assign it to a + // sprite -- it's set to repeating so that it goes on forever. We need to + // scale the sprite so that drawing 1/4 of backTextureWidth fills the screen + // horizontally, and drawing backTextureHeight fills half of the screen + // vertically. + var backTexture = try sf.Texture.createFromFile("back.png"); + defer backTexture.destroy(); + + backTexture.setSmooth(false); // looks worse => better! + backTexture.setRepeated(true); + + var backSprite = try sf.Sprite.createFromTexture(backTexture); + defer backSprite.destroy(); + + backSprite.setScale(.{ .x = 4.0 * @intToFloat(f32, screenWidth) / backTextureWidth, .y = @intToFloat(f32, screenHeight) / (2 * backTextureHeight) }); + + // Load brick texture! + var wallTexture = try sf.Texture.createFromFile("walls.png"); + defer wallTexture.destroy(); + wallTexture.setSmooth(false); // looks worse => better! + + var wallSprite = try sf.Sprite.createFromTexture(wallTexture); + defer wallSprite.destroy(); + + // Start your engines! + //-------------------------------------------------------------------------- + + while (window.isOpen()) { + while (window.pollEvent()) |event| { + if (event == .closed) window.close(); + } + + if (isKeyPressed(.Escape)) window.close(); + + const rotation = 2.0 * PI / 100.0; + if (isKeyPressed(.R)) player.ang += rotation; + if (isKeyPressed(.T)) player.ang -= rotation; + + player.acc_x = 0; + player.acc_y = 0; + const acc_mag = 50; + if (isKeyPressed(.Right)) { + player.acc_x += std.math.cos(player.ang - PI / 2.0) * acc_mag; + player.acc_y += std.math.sin(player.ang - PI / 2.0) * acc_mag; + } + if (isKeyPressed(.Left)) { + player.acc_x -= std.math.cos(player.ang - PI / 2.0) * acc_mag; + player.acc_y -= std.math.sin(player.ang - PI / 2.0) * acc_mag; + } + if (isKeyPressed(.Up) or isKeyPressed(.F)) { + player.acc_x += std.math.cos(player.ang) * acc_mag; + player.acc_y += std.math.sin(player.ang) * acc_mag; + } + if (isKeyPressed(.Down) or isKeyPressed(.S)) { + player.acc_x -= std.math.cos(player.ang) * acc_mag; + player.acc_y -= std.math.sin(player.ang) * acc_mag; + } + + window.clear(sf.Color.fromRGB(100, 100, 100)); + + const back_scroll = @floatToInt(i32, -backTextureWidth * player.ang / (2 * PI)); + backSprite.setTextureRect(sf.IntRect{ + .left = back_scroll, // fix location of texture in the sky + .top = 0, + // scaling ensures that the next two paint it across the width of + // the screen, and for half the height of the screen + .width = backTextureWidth / 4.0, // 1/4 of texture per screen + .height = backTextureHeight, // full height of texture visible + }); + window.draw(backSprite, null); + + try player.renderMapUsing(window, wallSprite, map, renderWall); + + window.display(); + + player.tick(); + } +} |
