Initial implementation of one way platforms
parent
d799830ad9
commit
8ad6d20fbd
|
@ -20,6 +20,9 @@ pub const Pos = struct {
|
|||
pub fn initVel(pos: Vec2f, vel: Vec2f) @This() {
|
||||
return @This(){ .pos = pos, .last = pos - vel };
|
||||
}
|
||||
pub fn getDirection(pos: Pos) Vec2f {
|
||||
return pos.pos - pos.last;
|
||||
}
|
||||
};
|
||||
pub const Control = struct {
|
||||
controller: enum { player },
|
||||
|
@ -39,6 +42,7 @@ pub const Kinematic = struct {
|
|||
col: AABB,
|
||||
move: Vec2f = Vec2f{ 0, 0 },
|
||||
lastCol: Vec2f = Vec2f{ 0, 0 },
|
||||
pass_start: ?usize = null,
|
||||
|
||||
pub fn inAir(this: @This()) bool {
|
||||
return approxEqAbs(f32, this.lastCol[1], 0, 0.01);
|
||||
|
|
32
src/game.zig
32
src/game.zig
|
@ -328,7 +328,7 @@ pub fn update(time: usize) !State {
|
|||
velocityProcess(1, &player.pos);
|
||||
physicsProcess(1, &player.pos, &player.physics);
|
||||
try manipulationProcess(&player.pos, &player.control);
|
||||
controlProcess(1, &player.pos, &player.control, &player.physics, &player.kinematic);
|
||||
controlProcess(time, &player.pos, &player.control, &player.physics, &player.kinematic);
|
||||
try kinematicProcess(1, &player.pos, &player.kinematic);
|
||||
controlAnimProcess(1, &player.sprite, &player.controlAnim, &player.control);
|
||||
try particles.update();
|
||||
|
@ -727,12 +727,18 @@ fn controlAnimProcess(_: f32, sprite: *Sprite, anim: *ControlAnim, control: *Con
|
|||
|
||||
const approxEqAbs = std.math.approxEqAbs;
|
||||
|
||||
fn controlProcess(_: f32, pos: *Pos, control: *Control, physics: *Physics, kinematic: *Kinematic) void {
|
||||
fn controlProcess(time: usize, pos: *Pos, control: *Control, physics: *Physics, kinematic: *Kinematic) void {
|
||||
var delta = Vec2f{ 0, 0 };
|
||||
if (kinematic.pass_start) |pass_start| {
|
||||
if (time - pass_start > 10) {
|
||||
kinematic.pass_start = null;
|
||||
}
|
||||
}
|
||||
if (approxEqAbs(f32, kinematic.move[1], 0, 0.01) and kinematic.lastCol[1] > 0) {
|
||||
if (input.btnp(.one, .one)) delta[1] -= 23;
|
||||
if (input.btn(.one, .left)) delta[0] -= 1;
|
||||
if (input.btn(.one, .right)) delta[0] += 1;
|
||||
if (input.btn(.one, .down)) kinematic.pass_start = time;
|
||||
if (delta[0] != 0 or delta[1] != 0) {
|
||||
control.state = .walk;
|
||||
} else {
|
||||
|
@ -759,9 +765,15 @@ fn controlProcess(_: f32, pos: *Pos, control: *Control, physics: *Physics, kinem
|
|||
}
|
||||
|
||||
fn kinematicProcess(_: f32, pos: *Pos, kinematic: *Kinematic) !void {
|
||||
const is_passing = kinematic.pass_start != null;
|
||||
var next = pos.last;
|
||||
next[0] = pos.pos[0];
|
||||
var hcol = map.collide(kinematic.col.addv(next));
|
||||
var hcol = map.collide(.{
|
||||
.rect = kinematic.col.addv(next),
|
||||
.last = pos.last,
|
||||
.next = next,
|
||||
.is_passing = is_passing,
|
||||
});
|
||||
if (hcol.len > 0) {
|
||||
kinematic.lastCol[0] = next[0] - pos.last[0];
|
||||
next[0] = pos.last[0];
|
||||
|
@ -770,7 +782,12 @@ fn kinematicProcess(_: f32, pos: *Pos, kinematic: *Kinematic) !void {
|
|||
}
|
||||
|
||||
next[1] = pos.pos[1];
|
||||
var vcol = map.collide(kinematic.col.addv(next));
|
||||
var vcol = map.collide(.{
|
||||
.rect = kinematic.col.addv(next),
|
||||
.last = pos.last,
|
||||
.next = next,
|
||||
.is_passing = is_passing,
|
||||
});
|
||||
if (vcol.len > 0) {
|
||||
kinematic.lastCol[1] = next[1] - pos.last[1];
|
||||
next[1] = pos.last[1];
|
||||
|
@ -779,7 +796,12 @@ fn kinematicProcess(_: f32, pos: *Pos, kinematic: *Kinematic) !void {
|
|||
}
|
||||
|
||||
var colPosAbs = next + kinematic.lastCol;
|
||||
var lastCol = map.collide(kinematic.col.addv(colPosAbs));
|
||||
var lastCol = map.collide(.{
|
||||
.rect = kinematic.col.addv(colPosAbs),
|
||||
.last = pos.last,
|
||||
.next = next,
|
||||
.is_passing = is_passing,
|
||||
});
|
||||
if (lastCol.len == 0) {
|
||||
kinematic.lastCol = Vec2f{ 0, 0 };
|
||||
}
|
||||
|
|
80
src/map.zig
80
src/map.zig
|
@ -107,6 +107,55 @@ fn getTile(this: @This(), x: i32, y: i32) ?u8 {
|
|||
return this.tiles[@intCast(u32, i)];
|
||||
}
|
||||
|
||||
pub const BodyInfo = struct {
|
||||
/// Rectangle
|
||||
rect: util.AABB,
|
||||
/// Last position
|
||||
last: Vec2f,
|
||||
/// Next position
|
||||
next: Vec2f,
|
||||
/// Pass through one way platforms
|
||||
is_passing: bool = false,
|
||||
};
|
||||
|
||||
pub fn collide(this: @This(), body: BodyInfo) CollisionInfo {
|
||||
const top_left = body.rect.pos / tile_sizef;
|
||||
const bot_right = (body.rect.pos + body.rect.size) / tile_sizef;
|
||||
var collisions = CollisionInfo.init();
|
||||
|
||||
var i: isize = @floatToInt(i32, top_left[0]);
|
||||
while (i <= @floatToInt(i32, bot_right[0])) : (i += 1) {
|
||||
var a: isize = @floatToInt(i32, top_left[1]);
|
||||
while (a <= @floatToInt(i32, bot_right[1])) : (a += 1) {
|
||||
|
||||
const tile = this.getTile(i, a) orelse continue;
|
||||
const tilex = @intToFloat(f32, i * tile_width);
|
||||
const tiley = @intToFloat(f32, a * tile_height);
|
||||
const bottom = @floatToInt(i32, bot_right[1]);
|
||||
|
||||
if (isOneWay(tile)) {
|
||||
// const last = @floatToInt(i32, body.last[1]);
|
||||
// const next = @floatToInt(i32, body.next[1]);
|
||||
// w4.tracef("%d, %d, %d", last, next, a * tile_height);
|
||||
if (!body.is_passing and a == bottom and body.last[1] <= body.next[1]) {
|
||||
collisions.append(util.AABB{
|
||||
.pos = Vec2f{tilex, tiley},
|
||||
.size = tile_sizef,
|
||||
});
|
||||
}
|
||||
} else if (isSolid(tile)) {
|
||||
collisions.append(util.AABB{
|
||||
.pos = Vec2f{tilex, tiley},
|
||||
.size = tile_sizef,
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return collisions;
|
||||
}
|
||||
|
||||
pub const CollisionInfo = struct {
|
||||
len: usize,
|
||||
items: [9]util.AABB,
|
||||
|
@ -125,35 +174,12 @@ pub const CollisionInfo = struct {
|
|||
}
|
||||
};
|
||||
|
||||
pub fn collide(this: @This(), rect: util.AABB) CollisionInfo {
|
||||
const top_left = rect.pos / tile_sizef;
|
||||
const bot_right = (rect.pos + rect.size) / tile_sizef;
|
||||
var collisions = CollisionInfo.init();
|
||||
|
||||
var i: isize = @floatToInt(i32, top_left[0]);
|
||||
while (i <= @floatToInt(i32, bot_right[0])) : (i += 1) {
|
||||
var a: isize = @floatToInt(i32, top_left[1]);
|
||||
while (a <= @floatToInt(i32, bot_right[1])) : (a += 1) {
|
||||
if (this.isSolid(Cell{ i, a })) {
|
||||
collisions.append(util.AABB{
|
||||
.pos = Vec2f{
|
||||
@intToFloat(f32, i * tile_width),
|
||||
@intToFloat(f32, a * tile_height),
|
||||
},
|
||||
.size = tile_sizef,
|
||||
});
|
||||
}
|
||||
}
|
||||
pub fn isSolid(tile: u8) bool {
|
||||
return tile >= 2;
|
||||
}
|
||||
|
||||
return collisions;
|
||||
}
|
||||
|
||||
pub fn isSolid(this: @This(), cell: Cell) bool {
|
||||
if (this.get_cell(cell)) |tile| {
|
||||
return tile != 0 and tile != 1;
|
||||
}
|
||||
return true;
|
||||
pub fn isOneWay(tile: u8) bool {
|
||||
return tile >= 34 and tile <= 36;
|
||||
}
|
||||
|
||||
// Debug functions
|
||||
|
|
Loading…
Reference in New Issue