0464-Bomb-实现通关界面
环境
- Time 2024-03-23
- Zig 0.12.0-dev.3152+90c1a2c41
- WSL-Ubuntu 22.04.3 LTS
- raylib 5.0
前言
说明
参考资料:
- 《游戏开发:世嘉新人培训教材》
- 图片素材:https://www.ituring.com.cn/book/1742
目标
如果达到了最大地图,则显示通关界面。
popup.zig
const std = @import("std");
const engine = @import("engine.zig");
const map = @import("map.zig");
pub const MenuType = enum { quit, title, reset, next };
pub const PopupType = enum { clear, over, ending };
pub const Popup = union(PopupType) {
clear: TimePopup,
over: TimePopup,
ending: TimePopup,
pub fn update(self: *Popup) ?MenuType {
return switch (self.*) {
inline else => |*case| case.update(),
};
}
pub fn draw(self: Popup) void {
switch (self) {
inline else => |sequence| sequence.draw(),
}
}
pub fn deinit(self: Popup) void {
switch (self) {
inline else => |sequence| sequence.deinit(),
}
}
};
pub fn initWithType(popupType: PopupType) Popup {
return switch (popupType) {
.clear => .{ .clear = TimePopup.init("clear.png", .next) },
.over => .{ .over = TimePopup.init("over.png", .title) },
.ending => .{ .ending = TimePopup.init("ending.png", .title) },
};
}
const TimePopup = struct {
image: engine.Image,
time: usize,
target: MenuType,
fn init(name: []const u8, target: MenuType) TimePopup {
return TimePopup{
.image = engine.Image.init(name),
.time = engine.time(),
.target = target,
};
}
fn update(self: TimePopup) ?MenuType {
return if (engine.time() - self.time > 2000) self.target else null;
}
fn draw(self: TimePopup) void {
self.image.draw();
}
fn deinit(self: TimePopup) void {
self.image.deinit();
}
};
stage.zig
const std = @import("std");
const popup = @import("popup.zig");
const play = @import("play.zig");
pub const SequenceType = enum { title, mode, stage };
pub const SequenceData = union(SequenceType) {
title: void,
mode: bool,
stage: usize,
};
pub fn init(mode: bool, level: usize) ?Stage {
const gameplay = play.Gameplay.init(mode, level) orelse return null;
return Stage{ .level = level, .gameplay = gameplay };
}
const maxLevel = 3;
pub const Stage = struct {
level: usize,
gameplay: play.Gameplay,
popup: ?popup.Popup = null,
pub fn update(self: *Stage) ?SequenceData {
if (self.popup) |*option| {
const menu = option.update() orelse return null;
defer option.deinit();
switch (menu) {
.title => return .title,
.reset => return .{ .stage = self.level },
.next => return .{ .stage = self.level + 1 },
.quit => self.popup = null,
}
}
const popupType = self.gameplay.update() orelse return null;
if (popupType == .clear and self.level + 1 == maxLevel)
self.popup = popup.initWithType(.ending)
else
self.popup = popup.initWithType(popupType);
return null;
}
pub fn draw(self: Stage) void {
self.gameplay.draw();
if (self.popup) |option| option.draw();
}
pub fn deinit(self: *Stage) void {
if (self.popup) |option| option.deinit();
self.gameplay.deinit();
}
};
效果

总结
实现显示通关界面。

浙公网安备 33010602011771号