Skip to content

Commit

Permalink
Stop gophers at ledges
Browse files Browse the repository at this point in the history
  • Loading branch information
fabioarnold committed Feb 14, 2023
1 parent c598263 commit e70bfb2
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 51 deletions.
21 changes: 3 additions & 18 deletions ProcessAssetsStep.zig
Original file line number Diff line number Diff line change
Expand Up @@ -138,28 +138,13 @@ fn make(step: *std.build.Step) !void {
const template = object.template orelse continue;
if (std.mem.endsWith(u8, template, "zero.tj")) {
try writer.writeAll("Entity{.class = .player,");
try writer.print(".box = Box{{ .x = {}, .y = {}, .w = {}, .h = {} }},}},", .{
object.x + 8,
object.y - 24,
16,
24,
});
try writer.print(".box = Box{{ .x = {}, .y = {}, .w = {}, .h = {} }},}},", .{ object.x + 8, object.y - 24, 16, 24 });
} else if (std.mem.endsWith(u8, template, "gopher.tj")) {
try writer.writeAll("Entity{.class = .gopher,");
try writer.print(".box = Box{{ .x = {}, .y = {}, .w = {}, .h = {} }},}},", .{
object.x + 8,
object.y - 24,
16,
24,
});
try writer.print(".box = Box{{ .x = {}, .y = {}, .w = {}, .h = {} }},}},", .{ object.x + 4, object.y - 24, 16, 24 });
} else if (std.mem.endsWith(u8, template, "spike.tj")) {
try writer.writeAll("Entity{.class = .spike,");
try writer.print(".box = Box{{ .x = {}, .y = {}, .w = {}, .h = {} }},}},", .{
object.x,
object.y - 24,
16,
24,
});
try writer.print(".box = Box{{ .x = {}, .y = {}, .w = {}, .h = {} }},}},", .{ object.x, object.y - 24, 16, 24 });
}
}
try writer.writeAll("},\n");
Expand Down
12 changes: 9 additions & 3 deletions maps/stages/needleman/room0.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,14 @@
{
"id":5,
"template":"..\/..\/objects\/gopher.tj",
"x":304,
"y":192
"x":368,
"y":144
},
{
"id":6,
"template":"..\/..\/objects\/gopher.tj",
"x":576,
"y":144
}],
"opacity":1,
"type":"objectgroup",
Expand All @@ -58,7 +64,7 @@
"y":0
}],
"nextlayerid":3,
"nextobjectid":6,
"nextobjectid":7,
"orientation":"orthogonal",
"renderorder":"right-down",
"tiledversion":"1.9.2",
Expand Down
2 changes: 1 addition & 1 deletion src/Box.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub fn toRect2(self: Box) Rect2 {
};
}

pub fn overlap(self: Box, other: Box) bool {
pub fn overlaps(self: Box, other: Box) bool {
return self.x < other.x + other.w and self.x + self.w > other.x and self.y < other.y + other.h and self.y + self.h > other.y;
}

Expand Down
41 changes: 24 additions & 17 deletions src/Enemy.zig
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const std = @import("std");
const GameData = @import("main.zig").GameData;
const Box = @import("Box.zig");
const Attrib = @import("Tile.zig").Attrib;
const Room = @import("Room.zig");
Expand All @@ -21,11 +22,11 @@ pub const Type = enum {
pub var gopher_sprite: Renderer.Texture = undefined;

active: bool = false,
@"type": Type = undefined,
type: Type = undefined,
box: Box = undefined,
state: u8 = 0,
frame: u8 = 0,
counter: u32 = 0,
counter: i32 = 0,
flip_x: bool = false,

pub fn load() void {
Expand All @@ -34,7 +35,7 @@ pub fn load() void {

pub fn activate(self: *Self, @"type": Type, box: Box) void {
self.active = true;
self.@"type" = @"type";
self.type = @"type";
self.box = box;
switch (@"type") {
.gopher => {},
Expand All @@ -44,14 +45,14 @@ pub fn activate(self: *Self, @"type": Type, box: Box) void {
self.counter = 0;
}

pub fn tick(self: *Self, room: Room, attribs: []const Attrib) void {
switch (self.@"type") {
.gopher => tickGopher(self, room, attribs),
pub fn tick(self: *Self, r: std.rand.Random, game: *GameData, attribs: []const Attrib) void {
switch (self.type) {
.gopher => tickGopher(self, r, game, attribs),
}
}

pub fn draw(self: Self) void {
switch (self.@"type") {
switch (self.type) {
.gopher => drawGopher(self),
}
}
Expand All @@ -61,37 +62,43 @@ const GopherState = enum(u8) {
walk = 1,
};

fn tickGopher(self: *Self, room: Room, attribs: []const Attrib) void {
var state = @ptrCast(*GopherState, &self.state);
fn tickGopher(self: *Self, r: std.rand.Random, game: *GameData, attribs: []const Attrib) void {
const room = game.getCurrentRoom();
const state = @ptrCast(*GopherState, &self.state);
switch (state.*) {
.idle => {
self.frame = 0;
self.flip_x = self.counter & 16 != 0;
if (self.counter >= 128) {
self.counter = 0;
if (self.counter <= 0) {
self.counter = r.intRangeLessThan(i32, 100, 500);
state.* = .walk;
}
},
.walk => {
self.frame = if (self.counter & 8 != 0) 1 else 2;
const amount: i32 = if (self.flip_x) - 1 else 1;
if (room.clipX(attribs, self.box, amount) != amount) {
const amount: i32 = if (self.flip_x) -1 else 1;
const sense_x = self.box.x + @divTrunc(self.box.w + amount * self.box.w, 2);
if (room.getTileAttribAtPixel(attribs, sense_x, self.box.y + self.box.h) != .solid or room.clipX(attribs, self.box, amount) != amount) {
self.flip_x = !self.flip_x;
} else {
self.box.x += amount;
}
if (self.counter >= 128) {
self.counter = 0;
if (self.counter <= 0) {
self.counter = r.intRangeLessThan(i32, 100, 200);
state.* = .idle;
}
},
}
self.counter += 1;
self.counter -= 1;

if (self.box.overlaps(game.player.box)) {
game.killPlayer();
}
}

fn drawGopher(self: Self) void {
var src_rect = Rect2.init(@intToFloat(f32, self.frame * 24), 0, 24, 24);
var dst_rect = Rect2.init(@intToFloat(f32, self.box.x) - 8, @intToFloat(f32, self.box.y), src_rect.w, src_rect.h);
var dst_rect = Rect2.init(@intToFloat(f32, self.box.x) - 4, @intToFloat(f32, self.box.y), src_rect.w, src_rect.h);
if (self.flip_x) {
src_rect.x += src_rect.w;
src_rect.w = -src_rect.w;
Expand Down
2 changes: 1 addition & 1 deletion src/Room.zig
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub fn overlap(self: Room, attribs: []const Tile.Attrib, mover: Box) bool {
const attrib = attribs[tile_index];
if (attrib == .solid) {
const solid = Box{ .x = x * Tile.size, .y = y * Tile.size, .w = Tile.size, .h = Tile.size };
if (box.overlap(solid)) return true;
if (box.overlaps(solid)) return true;
}
}
}
Expand Down
26 changes: 16 additions & 10 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ const text_w = screen_width / 8;
const text_h = screen_height / 8;
var text_buffer: [text_w * text_h]u8 = undefined;

var prng = std.rand.DefaultPrng.init(0);

const GameState = enum {
title,
start,
Expand All @@ -65,7 +67,7 @@ const door_duration = 16;
var room_transition: RoomTransition = .none;
var mode_frame: i32 = 0;

const GameData = struct {
pub const GameData = struct {
state: GameState = .title,
counter: u8 = 0, // number of frames to wait in a state
title_any_key_pressed: bool = false,
Expand Down Expand Up @@ -93,7 +95,7 @@ const GameData = struct {
self.prev_input = std.mem.zeroes(Player.Input);
self.cur_room_index = 0;
self.prev_room_index = 0;
const room = cur_stage.rooms[self.cur_room_index];
const room = self.getCurrentRoom();
uploadRoomTexture(&cur_room_tex, room);
self.scrollr.x = room.bounds.x;
self.scrollr.y = room.bounds.y;
Expand Down Expand Up @@ -143,7 +145,11 @@ const GameData = struct {
self.* = std.json.parse(GameData, &ts, .{
.ignore_unknown_fields = true,
}) catch return;
uploadRoomTexture(&cur_room_tex, cur_stage.rooms[self.cur_room_index]); // FIXME
uploadRoomTexture(&cur_room_tex, self.getCurrentRoom()); // FIXME
}

pub fn getCurrentRoom(self: GameData) Room {
return cur_stage.rooms[self.cur_room_index];
}

fn tickTitle(self: *GameData) void {
Expand Down Expand Up @@ -241,7 +247,7 @@ const GameData = struct {
}
}

fn killPlayer(self: *GameData) void {
pub fn killPlayer(self: *GameData) void {
if (!self.player.no_clip) {
self.state = .gameover;
self.counter = 0;
Expand All @@ -263,7 +269,7 @@ const GameData = struct {
updatePlayer(&self.player);

for (self.enemies) |*enemy| {
if (enemy.active) enemy.tick(cur_stage.rooms[self.cur_room_index], cur_stage.attribs);
if (enemy.active) enemy.tick(prng.random(), self, cur_stage.attribs);
}

if (findNextRoom(cur_stage.rooms, self.cur_room_index, self.player.box)) |next_room_index| {
Expand All @@ -273,7 +279,7 @@ const GameData = struct {
}

const cur_room = cur_stage.rooms[self.cur_room_index];
if (!cur_room.bounds.overlap(self.player.box)) {
if (!cur_room.bounds.overlaps(self.player.box)) {
if (self.player.box.y > cur_room.bounds.y + cur_room.bounds.h) {
self.killPlayer();
return;
Expand All @@ -288,7 +294,7 @@ const GameData = struct {
.w = Tile.size,
.h = 4 * Tile.size,
};
if (self.player.box.overlap(door_box)) {
if (self.player.box.overlaps(door_box)) {
door_box.x -= 1;
if (findNextRoom(cur_stage.rooms, self.cur_room_index, door_box)) |next_room_index| {
setNextRoom(next_room_index);
Expand All @@ -306,7 +312,7 @@ const GameData = struct {
.w = Tile.size,
.h = 4 * Tile.size,
};
if (self.player.box.overlap(door_box)) {
if (self.player.box.overlaps(door_box)) {
door_box.x += 1;
if (findNextRoom(cur_stage.rooms, self.cur_room_index, door_box)) |next_room_index| {
setNextRoom(next_room_index);
Expand All @@ -319,7 +325,7 @@ const GameData = struct {
// check spikes
for (cur_room.entities) |entity| {
if (entity.class == .spike) {
if (self.player.box.overlap(entity.box)) {
if (self.player.box.overlaps(entity.box)) {
self.killPlayer();
}
}
Expand Down Expand Up @@ -431,7 +437,7 @@ fn findNextRoom(rooms: []const Room, skip_room_index: u8, box: Box) ?u8 {
var room_index: u8 = 0;
while (room_index < rooms.len) : (room_index += 1) {
if (room_index == skip_room_index) continue;
if (rooms[room_index].bounds.overlap(box)) {
if (rooms[room_index].bounds.overlaps(box)) {
return room_index;
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/stages/needleman.zig
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ pub const needleman = Stage{
},
Entity{
.class = .gopher,
.box = Box{ .x = 312, .y = 168, .w = 16, .h = 24 },
.box = Box{ .x = 372, .y = 120, .w = 16, .h = 24 },
},
Entity{
.class = .gopher,
.box = Box{ .x = 580, .y = 120, .w = 16, .h = 24 },
},
},
},
Expand Down

0 comments on commit e70bfb2

Please sign in to comment.