Added collision detection (with tiles).
This commit is contained in:
parent
219eebbfb6
commit
ced8a1994f
@ -14,8 +14,8 @@ x
|
||||
x x
|
||||
x x
|
||||
xxxxxxxxxx x
|
||||
x SSSS x
|
||||
x SSSSS x
|
||||
x x
|
||||
x S S S x
|
||||
x P S S S S x
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
@ -9,6 +9,8 @@ const Renderer = @import("renderer.zig").Renderer;
|
||||
pub const Context = struct {
|
||||
const DefaultDisplayWidth = 960;
|
||||
const DefaultDisplayHeight = 540;
|
||||
// const DefaultDisplayWidth = 480;
|
||||
// const DefaultDisplayHeight = 270;
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
palette: Palette = undefined,
|
||||
|
@ -6,7 +6,7 @@ pub const PointF = struct {
|
||||
x: f32,
|
||||
y: f32,
|
||||
|
||||
pub const Zero = Point{ .x = 0, .y = 0 };
|
||||
pub const Zero = PointF{ .x = 0, .y = 0 };
|
||||
|
||||
pub fn init(x: f32, y: f32) PointF {
|
||||
return PointF{ .x = x, .y = y };
|
||||
|
@ -23,7 +23,7 @@ pub const Game = struct {
|
||||
playerIdleAnimation: Animation,
|
||||
playerWalkingAnimation: Animation,
|
||||
playerDirection: Direction,
|
||||
isPlayerWalking: bool,
|
||||
playerVelocity: engine.PointF,
|
||||
|
||||
starAnimation: Animation,
|
||||
|
||||
@ -40,7 +40,7 @@ pub const Game = struct {
|
||||
.playerIdleAnimation = Animation.initPartialLoop(renderer.sprites.get("character_lion_48").?, 0.25, 0, 4),
|
||||
.playerWalkingAnimation = Animation.initPartialLoop(renderer.sprites.get("character_lion_48").?, 0.125, 4, 8),
|
||||
.playerDirection = Direction.Right,
|
||||
.isPlayerWalking = false,
|
||||
.playerVelocity = engine.PointF.Zero,
|
||||
.starAnimation = Animation.init(renderer.sprites.get("item_star_32").?, 0.15),
|
||||
.renderer = renderer,
|
||||
.randomTile = TileMap(usize).init(allocator),
|
||||
@ -79,14 +79,49 @@ pub const Game = struct {
|
||||
renderer.textures.get("opaque").?.drawTintedScaled(allegro.mapRgba(127, 127, 127, 127), topLeftScreen.x, topLeftScreen.y, tileSizeScreen, tileSizeScreen);
|
||||
}
|
||||
|
||||
pub fn moveCharacter(self: *Game, distance: f32) void {
|
||||
self.playerPosition.x += distance;
|
||||
self.isPlayerWalking = true;
|
||||
self.playerDirection = if (distance > 0) Direction.Right else Direction.Left;
|
||||
pub fn movePlayer(self: *Game, dt: f32) void {
|
||||
const to = self.playerPosition.add(self.playerVelocity.multiply(dt));
|
||||
self.playerPosition = to;
|
||||
if (self.playerVelocity.y > 0 and self.playerIsOnTile()) {
|
||||
self.playerPosition.y = std.math.floor(self.playerPosition.y);
|
||||
self.playerVelocity.y = 0;
|
||||
} else if (self.playerVelocity.y < 0 and self.playerIsUnderTile()) {
|
||||
self.playerPosition.y = std.math.ceil(self.playerPosition.y);
|
||||
self.playerVelocity.y = -self.playerVelocity.y;
|
||||
}
|
||||
if (self.playerVelocity.x != 0) {
|
||||
const playerTileTop = @floatToInt(i64, std.math.floor(self.playerPosition.y));
|
||||
const playerTileBottom = @floatToInt(i64, std.math.floor(self.playerPosition.y + 0.99));
|
||||
if (self.playerVelocity.x < 0) {
|
||||
const playerTileLeft = @floatToInt(i64, std.math.ceil(self.playerPosition.x)) - 1;
|
||||
if (self.level.tiles.get(playerTileLeft, playerTileTop) != null or self.level.tiles.get(playerTileLeft, playerTileBottom) != null) {
|
||||
self.playerPosition.x = std.math.ceil(self.playerPosition.x);
|
||||
self.playerVelocity.x = 0;
|
||||
}
|
||||
}
|
||||
// const playerTileRight = @floatToInt(i64, std.math.floor(self.playerPosition.x)) + 1;
|
||||
}
|
||||
self.playerDirection = if (self.playerVelocity.x == 0) self.playerDirection else if (self.playerVelocity.x > 0) Direction.Right else Direction.Left;
|
||||
|
||||
self.boundsInTiles = Game.calculateBoundsInTiles(self.playerPosition);
|
||||
}
|
||||
|
||||
pub fn playerIsOnTile(self: Game) bool {
|
||||
const playerTileHeight = @floatToInt(i64, std.math.floor(self.playerPosition.y)) + 1;
|
||||
const playerTileLeft = @floatToInt(i64, std.math.floor(self.playerPosition.x + 0.5));
|
||||
const playerTileRight = @floatToInt(i64, std.math.ceil(self.playerPosition.x - 0.5));
|
||||
|
||||
return self.level.tiles.get(playerTileLeft, playerTileHeight) != null or self.level.tiles.get(playerTileRight, playerTileHeight) != null;
|
||||
}
|
||||
|
||||
pub fn playerIsUnderTile(self: Game) bool {
|
||||
const playerTileHeight = @floatToInt(i64, std.math.ceil(self.playerPosition.y)) - 1;
|
||||
const playerTileLeft = @floatToInt(i64, std.math.floor(self.playerPosition.x + 0.5));
|
||||
const playerTileRight = @floatToInt(i64, std.math.ceil(self.playerPosition.x - 0.5));
|
||||
|
||||
return self.level.tiles.get(playerTileLeft, playerTileHeight) != null or self.level.tiles.get(playerTileRight, playerTileHeight) != null;
|
||||
}
|
||||
|
||||
pub fn randomTileOffset(self: *Game, x: i64, y: i64, maxOffset: usize) usize {
|
||||
if (self.randomTile.get(x, y)) |offset| {
|
||||
return offset;
|
||||
@ -134,7 +169,8 @@ pub const Game = struct {
|
||||
}
|
||||
|
||||
pub fn tick(self: *Game, t: f32, dt: f32) void {
|
||||
_ = t;
|
||||
_ = self;
|
||||
_ = dt;
|
||||
self.playerAnimation.tick(t);
|
||||
}
|
||||
};
|
||||
|
@ -26,21 +26,40 @@ pub const GameScene = struct {
|
||||
}
|
||||
|
||||
pub fn tick(self: *GameScene, ctx: *Context, t: f32, dt: f32) void {
|
||||
const speed: f32 = 6; // tiles/s
|
||||
const horizontalWalkAcceleration: f32 = 13;
|
||||
const gravity: f32 = 71;
|
||||
const jumpVelocity: f32 = -26;
|
||||
const maxFallVelocity: f32 = 23;
|
||||
const maxHorizontalWalkVelocity: f32 = 7; // tiles/s
|
||||
|
||||
if (ctx.keys.isKeyPressed(allegro.c.ALLEGRO_KEY_LEFT)) {
|
||||
self.game.moveCharacter(-speed * dt);
|
||||
self.game.playerWalkingAnimation.tick(t);
|
||||
self.game.playerVelocity.x = std.math.max(-maxHorizontalWalkVelocity, self.game.playerVelocity.x - horizontalWalkAcceleration);
|
||||
} else if (ctx.keys.isKeyPressed(allegro.c.ALLEGRO_KEY_RIGHT)) {
|
||||
self.game.moveCharacter(speed * dt);
|
||||
self.game.playerWalkingAnimation.tick(t);
|
||||
self.game.playerVelocity.x = std.math.min(maxHorizontalWalkVelocity, self.game.playerVelocity.x + horizontalWalkAcceleration);
|
||||
} else {
|
||||
if (self.game.isPlayerWalking) {
|
||||
self.game.playerWalkingAnimation.reset();
|
||||
if (std.math.fabs(self.game.playerVelocity.x) > 0.2) {
|
||||
self.game.playerVelocity.x = self.game.playerVelocity.x - std.math.sign(self.game.playerVelocity.x) * horizontalWalkAcceleration * dt;
|
||||
} else {
|
||||
self.game.playerVelocity.x = 0;
|
||||
}
|
||||
self.game.isPlayerWalking = false;
|
||||
self.game.playerIdleAnimation.tick(t);
|
||||
}
|
||||
|
||||
if (self.game.playerVelocity.y == 0 and ctx.keys.isKeyPressed(allegro.c.ALLEGRO_KEY_SPACE)) {
|
||||
self.game.playerVelocity.y = jumpVelocity;
|
||||
} else if (!self.game.playerIsOnTile()) {
|
||||
self.game.playerVelocity.y = std.math.min(maxFallVelocity, self.game.playerVelocity.y + gravity * dt);
|
||||
}
|
||||
|
||||
// self.game.playerVelocity.y = std.math.min(maxFallVelocity, self.game.playerVelocity.y + self.game.playerAcceleration.y * dt);
|
||||
if (self.game.playerVelocity.x != 0 and self.game.playerVelocity.y == 0) {
|
||||
self.game.playerWalkingAnimation.tick(t);
|
||||
self.game.playerIdleAnimation.reset();
|
||||
} else if (self.game.playerVelocity.x == 0) {
|
||||
self.game.playerIdleAnimation.tick(t);
|
||||
self.game.playerWalkingAnimation.reset();
|
||||
}
|
||||
self.game.movePlayer(dt);
|
||||
|
||||
self.game.starAnimation.tick(t);
|
||||
}
|
||||
|
||||
@ -113,14 +132,14 @@ pub const GameScene = struct {
|
||||
}
|
||||
|
||||
const playerDirectionFrameOffset: usize = if (self.game.playerDirection == game.Game.Direction.Left) 0 else 8;
|
||||
if (self.game.isPlayerWalking) {
|
||||
if (self.game.playerVelocity.x != 0 and self.game.playerVelocity.y == 0) {
|
||||
self.game.drawSpriteFrameP("character_lion_48", self.game.playerWalkingAnimation.current + playerDirectionFrameOffset, self.game.playerPosition.add(engine.PointF.init(-0.25, -0.25)));
|
||||
} else {
|
||||
self.game.drawSpriteFrameP("character_lion_48", self.game.playerIdleAnimation.current + playerDirectionFrameOffset, self.game.playerPosition.add(engine.PointF.init(-0.25, -0.25)));
|
||||
}
|
||||
|
||||
if (ctx.showDebug) {
|
||||
ctx.renderer.printTextV("debug", ctx.palette.background.text, 0.01, 0.1, Renderer.TextAlignment.Left, "Character: ({d}, {d})", .{ self.game.playerPosition.x, self.game.playerPosition.y });
|
||||
ctx.renderer.printTextV("debug", ctx.palette.background.text, 0.01, 0.1, Renderer.TextAlignment.Left, "Character: ({d:.2}, {d:.2})", .{ self.game.playerPosition.x, self.game.playerPosition.y });
|
||||
ctx.renderer.printTextV("debug", ctx.palette.background.text, 0.01, 0.15, Renderer.TextAlignment.Left, "Tiles: ({d}, {d}) -> ({d}, {d})", .{ tileBounds.min.x, tileBounds.min.y, tileBounds.max.x, tileBounds.max.y });
|
||||
// self.game.debugHighlightTile(self.game.playerPosition);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user