当前位置: 首页 > news >正文

0445-Bomb-实现进入下一关

环境

  • Time 2024-03-14
  • Zig 0.12.0-dev.3152+90c1a2c41
  • WSL-Ubuntu 22.04.3 LTS
  • raylib 5.0

前言

说明

参考资料:

  1. 《游戏开发:世嘉新人培训教材》
  2. 图片素材:https://www.ituring.com.cn/book/1742

目标

如果游戏关卡完成,显示提示信息,等待两秒后跳转下一关。

play.zig

加入了进入下一关的调试代码。

const std = @import("std");
const engine = @import("engine.zig");
const map = @import("map.zig");pub fn init(allocator: std.mem.Allocator, level: usize, box: engine.Texture) ?Play {const m = map.Map.init(allocator, level) catch |err| {std.log.err("init stage error: {}", .{err});return null;} orelse return null;return .{ .map = m, .box = box };
}pub const Play = struct {map: map.Map,box: engine.Texture,pub fn update(_: *Play) ?@import("popup.zig").PopupType {if (engine.isPressed(engine.Key.x)) return .over;if (engine.isPressed(engine.Key.c)) return .clear;return null;}pub fn draw(self: Play) void {for (0..self.map.height) |y| {for (0..self.map.width) |x| {const item = self.map.data[y * self.map.width + x];if (item != map.MapItem.WALL) {self.drawCell(x, y, if (item.hasGoal()) .GOAL else .SPACE);}if (item != .SPACE) self.drawCell(x, y, item);}}}fn drawCell(play: Play, x: usize, y: usize, item: map.MapItem) void {var source = engine.Rectangle{ .width = 32, .height = 32 };source.x = item.toImageIndex() * source.width;const position = .{ .x = x * source.width, .y = y * source.height };play.box.drawRectangle(source, position);}pub fn deinit(self: Play) void {self.map.deinit();}
};

popup.zig

抽取了 TimePopup 来实现定时显示弹出消息的功能,clear 和 over 使用了这个。

const std = @import("std");
const engine = @import("engine.zig");
const map = @import("map.zig");pub const MenuType = enum { quit, title, select, reset, next };
pub const PopupType = enum { loading, menu, clear, over };pub const Popup = union(PopupType) {loading: Loading,menu: Menu,clear: TimePopup,over: 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 init() Popup {return .{ .loading = Loading.init() };
}pub fn initWithType(popupType: PopupType) Popup {return switch (popupType) {.clear => .{ .clear = TimePopup.init("clear.png", .next) },.menu => .{ .menu = Menu.init() },.loading => .{ .loading = Loading.init() },.over => .{ .over = TimePopup.init("over.png", .title) },};
}const TimePopup = struct {texture: engine.Texture,time: usize,target: MenuType,fn init(name: []const u8, target: MenuType) TimePopup {return TimePopup{.texture = engine.Texture.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.texture.draw();}fn deinit(self: TimePopup) void {self.texture.deinit();}
};const Loading = struct {texture: engine.Texture,time: usize,fn init() Loading {return Loading{.texture = engine.Texture.init("loading.dds"),.time = engine.time(),};}fn update(self: Loading) ?MenuType {return if (engine.time() - self.time > 1000) return .quit else null;}fn draw(self: Loading) void {self.texture.draw();}fn deinit(self: Loading) void {self.texture.deinit();}
};const Menu = struct {texture: engine.Texture,fn init() Menu {return Menu{ .texture = engine.Texture.init("menu.dds") };}fn update(_: Menu) ?MenuType {const char = engine.getPressed();return switch (char) {'1' => .reset,'2' => .select,'3' => .title,'4' => .quit,else => null,};}fn draw(self: Menu) void {self.texture.draw();}fn deinit(self: Menu) void {self.texture.deinit();}
};

stage.zig

抽取了新建 Popup 的功能到 popup.zig 模块。

const std = @import("std");
const popup = @import("popup.zig");
const play = @import("play.zig");const Texture = @import("engine.zig").Texture;
pub const SequenceType = enum { title, select, stage };
pub const SequenceData = union(SequenceType) {title: void,select: void,stage: usize,
};pub fn init(allocator: std.mem.Allocator, level: usize, box: Texture) ?Stage {const current = play.init(allocator, level, box) orelse return null;return Stage{ .level = level, .current = current, .popup = popup.init() };
}pub const Stage = struct {level: usize,current: play.Play,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,.select => return .select,.reset => return .{ .stage = self.level },.next => return .{ .stage = self.level + 1 },.quit => self.popup = null,}}const popupType = self.current.update() orelse return null;self.popup = popup.initWithType(popupType);return null;}pub fn draw(self: Stage) void {self.current.draw();if (self.popup) |option| option.draw();}pub fn deinit(self: Stage) void {if (self.popup) |option| option.deinit();self.current.deinit();}
};

效果

bomb

总结

实现炸弹人的下一关功能。

附录

http://www.jsqmd.com/news/1397905/

相关文章:

  • IDEA图形化Git操作指南:Merge Request模式下的高效协作与冲突解决
  • 面向编程代理的开源视频编辑器:API化视频处理与自动化集成指南
  • 全局快捷键突然失灵?3步完成热键冲突检测,揪出偷走按键的进程
  • 下班后的《绝区零》,终于不用再“上班“了
  • AI基准测试内测指南:从环境准备到高效反馈的全流程实践
  • 游戏刚启动就闪退?MelonLoader启动失败从排查到修复的完整自救手册
  • C语言内存初始化:静态数组与malloc动态内存管理详解
  • 一条命令搞定 M3U8 视频下载:N_m3u8DL-RE 完整上手手册
  • 2026解析圆度圆柱仪哪个厂家好 精密测量设备选型全指南 - 起跑123
  • 覆铜板如何决定PCB高速信号完整性(SI)性能?
  • AI生成柯基图片的多模型协同工作流与优化技巧
  • 杜绝称重猫腻!广州合规黄金回收门店计量标准公示 - 资讯早知道
  • 人形机器人微表情解码系统(下)
  • 一站式 IDEA API 调试插件实战:Cool Request 快速上手指南
  • 蛋白质结构预测批量处理实战:用 ColabFold 一次搞定上百条序列
  • LLM工程实践:为何应追求结构化输出而非拟人化表达
  • 一次 SSH 连接排障全记录:为什么一根网线能折腾一下午
  • Windows 下 Touch Bar 只剩音量键?三步安装 DFRDisplayKm 驱动,解锁 MacBook Pro 的完整交互
  • Windows系统下通过Cygwin64编译安装LibRadtran辐射传输计算工具
  • Windows系统文件svsvc.dll丢失找不到问题解决
  • 高空线缆难辨识?输电线路航空标志球提前化解飞行器撞线风险
  • Unity引擎VR大场景开发与优化实战
  • 华为OD机试真题 新系统 2026-08-05 C++ 实现【最长不连续子串】
  • GraphvizOnline 完整上手指南:一个浏览器页面,把 DOT 文本变成专业图表
  • 抖音批量下载从入门到精通:douyin-downloader 完整实战手册
  • Diablo Edit2:暗黑破坏神2终极存档编辑器完整指南,从改属性到打造符文之语
  • 动态规划与数学建模在《幻兽帕鲁》育种优化中的应用
  • 网盘直链下载助手终极指南:三步告别限速,快速获取8大网盘真实下载链接
  • JPEXS Free Flash Decompiler 从入门到精通:SWF 反编译实战完全指南
  • Windows Defender恢复终极指南:3种方案重建完整系统安全防线(附自检清单)