mirror of
https://github.com/The-Memory-Managers/cpu-vs-ai.git
synced 2025-09-03 21:48:12 +00:00
Changes
- Separated screen rendering logic into separate structs, which are switched on when rendering/updating - Added font loading logic - Began work on tower mechanics
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
.zig-cache/
|
.zig-cache/
|
||||||
zig-out/
|
zig-out/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
commsg.txt
|
||||||
|
177
src/main.zig
177
src/main.zig
@@ -41,7 +41,46 @@ pub fn main() anyerror!void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Cpu = struct {};
|
const BugKind = enum {
|
||||||
|
nullptr_deref,
|
||||||
|
stack_overflow,
|
||||||
|
infinite_loop,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Condition = union(enum) {
|
||||||
|
always,
|
||||||
|
memory_leak: f32, // Health percentage, ram<0.25 or ram<0.5 (randomized)
|
||||||
|
bug: BugKind, // Against this specific enemy type
|
||||||
|
idle: f32, // Idle time in seconds, 1s-2s (randomized)
|
||||||
|
};
|
||||||
|
|
||||||
|
const Instruction = struct {
|
||||||
|
condition: Condition,
|
||||||
|
opcode: Opcode,
|
||||||
|
|
||||||
|
const Opcode = union(enum) {
|
||||||
|
sleep: f32, // Slows enemies (multiplier of enemy speed, 0.5-0.9 randomized)
|
||||||
|
prefetch: f32, // Deals more damage (multiplier of cache size, 1.5-2 randomized)
|
||||||
|
overclock: f32, // Faster firerate (multiplier of clock speed, 1.1-1.5 randomized)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const Cpu = struct {
|
||||||
|
clock_speed: f32 = 1, // Fire rate, every how many seconds to fire
|
||||||
|
cache_size: f32 = 1, // Cache size, damage dealt
|
||||||
|
debugs: u32 = 0, // How many bugs were killed
|
||||||
|
instructions: []Instruction, // modifiers
|
||||||
|
|
||||||
|
fn cores(self: Cpu) u32 {
|
||||||
|
return switch (self.debugs) {
|
||||||
|
0...10 => 1,
|
||||||
|
10...25 => 2,
|
||||||
|
25...50 => 3,
|
||||||
|
50...100 => 4,
|
||||||
|
else => 5,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const Cell = union(enum) {
|
const Cell = union(enum) {
|
||||||
none,
|
none,
|
||||||
@@ -95,25 +134,42 @@ const Wave = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const TextureKind = enum {
|
||||||
|
socket,
|
||||||
|
lane,
|
||||||
|
};
|
||||||
|
|
||||||
const Game = struct {
|
const Game = struct {
|
||||||
global_arena: std.heap.ArenaAllocator,
|
global_arena: std.heap.ArenaAllocator,
|
||||||
frame_arena: std.heap.ArenaAllocator,
|
frame_arena: std.heap.ArenaAllocator,
|
||||||
|
|
||||||
texture_map: std.AutoHashMap(Cell, rl.Texture2D),
|
texture_map: std.AutoHashMap(TextureKind, rl.Texture2D),
|
||||||
|
|
||||||
|
font_title: rl.Font,
|
||||||
|
font_normal: rl.Font,
|
||||||
|
|
||||||
camera: rl.Camera2D,
|
camera: rl.Camera2D,
|
||||||
wave: Wave,
|
wave: Wave,
|
||||||
|
|
||||||
|
screen_state: union(enum) {
|
||||||
|
main: ScreenMainMenu,
|
||||||
|
battle: ScreenBattle,
|
||||||
|
},
|
||||||
|
|
||||||
fn init() Game {
|
fn init() Game {
|
||||||
var global_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
var global_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
const ga = global_arena.allocator();
|
const ga = global_arena.allocator();
|
||||||
var texture_map = std.AutoHashMap(Cell, rl.Texture2D).init(ga);
|
var texture_map = std.AutoHashMap(TextureKind, rl.Texture2D).init(ga);
|
||||||
|
|
||||||
const lane = rl.loadTexture("assets/socket.png") catch unreachable;
|
const lane = rl.loadTexture("assets/img/socket.png") catch unreachable;
|
||||||
const socket = rl.loadTexture("assets/lane.png") catch unreachable;
|
|
||||||
|
const socket = rl.loadTexture("assets/img/lane.png") catch unreachable;
|
||||||
texture_map.put(.socket, lane) catch unreachable;
|
texture_map.put(.socket, lane) catch unreachable;
|
||||||
texture_map.put(.lane, socket) catch unreachable;
|
texture_map.put(.lane, socket) catch unreachable;
|
||||||
|
|
||||||
|
const font_title = rl.loadFont("assets/font/DepartureMonoNerdFontMono-Regular.otf") catch unreachable;
|
||||||
|
const font_normal = rl.loadFont("assets/font/GohuFont14NerdFontMono-Regular.ttf") catch unreachable;
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.camera = .{
|
.camera = .{
|
||||||
.target = .{ .x = 128, .y = 128 },
|
.target = .{ .x = 128, .y = 128 },
|
||||||
@@ -128,6 +184,11 @@ const Game = struct {
|
|||||||
.frame_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator),
|
.frame_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator),
|
||||||
.wave = .init(),
|
.wave = .init(),
|
||||||
.texture_map = texture_map,
|
.texture_map = texture_map,
|
||||||
|
.font_title = font_title,
|
||||||
|
.font_normal = font_normal,
|
||||||
|
.screen_state = .{
|
||||||
|
.main = .{},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,9 +209,57 @@ const Game = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render(self: *Game) void {
|
fn render(self: *Game) void {
|
||||||
const a = self.frame_arena.allocator();
|
switch (self.screen_state) {
|
||||||
const map = self.wave.map;
|
.main => self.renderMain(),
|
||||||
const camera = self.camera;
|
.wave => self.renderWave(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn updateCamera(self: *Game) void {
|
||||||
|
screenWidth = rl.getScreenWidth();
|
||||||
|
screenHeight = rl.getScreenHeight();
|
||||||
|
|
||||||
|
self.camera.offset = .{
|
||||||
|
.x = @as(f32, @floatFromInt(screenWidth)) / 2,
|
||||||
|
.y = @as(f32, @floatFromInt(screenHeight)) / 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.camera.target = .{
|
||||||
|
.x = world_width / 2.0,
|
||||||
|
.y = world_height / 2.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Take the average between the ratios
|
||||||
|
// This avoids "cheating" by changing the ratio to an extreme value
|
||||||
|
// in order to see more terrain in a certain axis
|
||||||
|
const width_ratio = @as(f32, @floatFromInt(screenWidth)) / world_width;
|
||||||
|
const height_ratio = @as(f32, @floatFromInt(screenHeight)) / world_height;
|
||||||
|
self.camera.zoom = (width_ratio + height_ratio) / 2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const ScreenMainMenu = struct {
|
||||||
|
fn update(self: *ScreenMainMenu, game: *Game) void {
|
||||||
|
_ = self;
|
||||||
|
_ = game;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(self: *ScreenMainMenu, game: *Game) void {
|
||||||
|
_ = self;
|
||||||
|
_ = game;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const ScreenBattle = struct {
|
||||||
|
fn update(self: *ScreenBattle, game: *Game) void {
|
||||||
|
_ = self;
|
||||||
|
_ = game;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(self: *ScreenBattle, game: *Game) void {
|
||||||
|
const a = game.frame_arena.allocator();
|
||||||
|
const map = game.wave.map;
|
||||||
|
const camera = game.camera;
|
||||||
|
|
||||||
rl.beginDrawing();
|
rl.beginDrawing();
|
||||||
defer rl.endDrawing();
|
defer rl.endDrawing();
|
||||||
@@ -163,7 +272,7 @@ const Game = struct {
|
|||||||
|
|
||||||
for (0..map.len) |y| {
|
for (0..map.len) |y| {
|
||||||
for (0..map[0].len) |x| {
|
for (0..map[0].len) |x| {
|
||||||
drawCell(self, x, y);
|
self.drawCell(game, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,50 +302,42 @@ const Game = struct {
|
|||||||
,
|
,
|
||||||
.{ rl.getFPS(), screenWidth, screenHeight, world_width, world_height, cell_size },
|
.{ rl.getFPS(), screenWidth, screenHeight, world_width, world_height, cell_size },
|
||||||
) catch return;
|
) catch return;
|
||||||
|
|
||||||
rl.drawText(debug_info, 20, 20, font_size, .black);
|
rl.drawText(debug_info, 20, 20, font_size, .black);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn updateCamera(self: *Game) void {
|
fn drawCell(self: *ScreenBattle, game: *Game, x: usize, y: usize) void {
|
||||||
screenWidth = rl.getScreenWidth();
|
_ = self;
|
||||||
screenHeight = rl.getScreenHeight();
|
|
||||||
|
|
||||||
self.camera.offset = .{
|
switch (game.wave.map[y][x]) {
|
||||||
.x = @as(f32, @floatFromInt(screenWidth)) / 2,
|
|
||||||
.y = @as(f32, @floatFromInt(screenHeight)) / 2,
|
|
||||||
};
|
|
||||||
self.camera.target = .{
|
|
||||||
.x = world_width / 2.0,
|
|
||||||
.y = world_height / 2.0,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Take the average between the ratios
|
|
||||||
// This avoids "cheating" by changing the ratio to an extreme value
|
|
||||||
// in order to see more terrain in a certain axis
|
|
||||||
const width_ratio = @as(f32, @floatFromInt(screenWidth)) / world_width;
|
|
||||||
const height_ratio = @as(f32, @floatFromInt(screenHeight)) / world_height;
|
|
||||||
self.camera.zoom = (width_ratio + height_ratio) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn drawCell(self: *Game, x: usize, y: usize) void {
|
|
||||||
switch (self.wave.map[y][x]) {
|
|
||||||
.none => return,
|
.none => return,
|
||||||
.socket => {
|
.socket => {
|
||||||
const texture = self.texture_map.get(.socket).?;
|
const texture = game.texture_map.get(.socket).?;
|
||||||
rl.drawTexture(texture, @intCast(x * cell_size), @intCast(y * cell_size), rl.Color.white);
|
rl.drawTexture(texture, @intCast(x * cell_size), @intCast(y * cell_size), rl.Color.white);
|
||||||
},
|
},
|
||||||
.lane => {
|
.lane => {
|
||||||
const texture = self.texture_map.get(.lane).?;
|
const texture = game.texture_map.get(.lane).?;
|
||||||
|
|
||||||
const lane_left = self.wave.get(x - 1, y).isLaneConnected();
|
const lane_left = game.wave.get(x - 1, y).isLaneConnected();
|
||||||
const lane_right = self.wave.get(x + 1, y).isLaneConnected();
|
const lane_right = game.wave.get(x + 1, y).isLaneConnected();
|
||||||
const lane_top = self.wave.get(x, y - 1).isLaneConnected();
|
const lane_top = game.wave.get(x, y - 1).isLaneConnected();
|
||||||
const lane_bottom = self.wave.get(x, y + 1).isLaneConnected();
|
const lane_bottom = game.wave.get(x, y + 1).isLaneConnected();
|
||||||
|
|
||||||
var offset: f32 = undefined;
|
var offset: f32 = undefined;
|
||||||
|
// Choose the correct sprite
|
||||||
if (lane_top and lane_left) {
|
if (lane_top and lane_left) {
|
||||||
offset = 3;
|
offset = 3;
|
||||||
|
} else if (lane_top and lane_right) {
|
||||||
|
offset = 2;
|
||||||
|
} else if (lane_bottom and lane_left) {
|
||||||
|
offset = 5;
|
||||||
|
} else if (lane_bottom and lane_right) {
|
||||||
|
offset = 4;
|
||||||
|
} else if (lane_left or lane_right) {
|
||||||
|
offset = 0;
|
||||||
|
} else if (lane_top or lane_bottom) {
|
||||||
|
offset = 1;
|
||||||
}
|
}
|
||||||
// TODO(kyren): do the rest
|
|
||||||
|
|
||||||
rl.drawTextureRec(
|
rl.drawTextureRec(
|
||||||
texture,
|
texture,
|
||||||
|
Reference in New Issue
Block a user