0459-Bomb-实现敌人移动

环境

  • Time 2024-03-22
  • 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

目标

之前的敌人都是静止的,增加敌人的 AI 移动逻辑。

ai.zig

新增了一个线程来处理敌人的移动。

const std = @import("std");
const engine = @import("../engine.zig");
const World = @import("world.zig").World;
const Player = @import("player.zig").Player;

var thread: std.Thread = undefined;
var running: bool = true;
pub fn init(world: World) void {
    thread = std.Thread.spawn(.{}, control, .{world}) catch unreachable;
}

const enemySpeed = 500;

fn control(world: World) void {
    while (running) {
        for (world.players) |*enemy| {
            if (enemy.type == .enemy) controlEnemy(world, enemy);
        }
        std.time.sleep(std.time.ns_per_ms * 10);
    }
}

fn controlEnemy(world: World, enemy: *Player) void {
    const direction = enemy.direction orelse return;

    if (direction == .north) {
        var e = enemy.*;
        e.y -|= enemySpeed;
        if (world.isCollisionY(e, e.getCell().x, e.getCell().y -| 1)) {
            enemy.direction = @enumFromInt(engine.random(4));
        } else {
            enemy.y -|= enemySpeed;
        }
    }

    if (direction == .south) {
        var e = enemy.*;
        e.y -|= enemySpeed;
        if (world.isCollisionY(e, e.getCell().x, e.getCell().y + 1)) {
            enemy.direction = @enumFromInt(engine.random(4));
        } else {
            enemy.y += enemySpeed;
        }
    }

    if (direction == .west) {
        var e = enemy.*;
        e.x -|= enemySpeed;
        if (world.isCollisionY(e, e.getCell().x -| 1, e.getCell().y)) {
            enemy.direction = @enumFromInt(engine.random(4));
        } else {
            enemy.x -|= enemySpeed;
        }
    }

    if (direction == .east) {
        var e = enemy.*;
        e.x += enemySpeed;
        if (world.isCollisionY(e, e.getCell().x + 1, e.getCell().y)) {
            enemy.direction = @enumFromInt(engine.random(4));
        } else {
            enemy.x += enemySpeed;
        }
    }
}

pub fn deinit() void {
    running = false;
    thread.join();
}

player.zig

新增了移动的方向。

pub const Player = struct {
    x: usize,
    y: usize,
    bombNumber: usize = 0,
    maxBombNumber: usize = 1,
    maxBombLength: usize = 1,
    direction: ?core.Direction,
    type: core.MapType,

    pub fn genEnemy(x: usize, y: usize) Player {
        const rand = engine.random(4);
        return init(x, y, .enemy, @enumFromInt(rand));
    }

    pub fn genPlayer(x: usize, y: usize) Player {
        return init(x, y, .player1, null);
    }

    fn init(x: usize, y: usize, t: core.MapType, d: ?core.Direction) Player {
        return Player{
            .x = x * core.getMapUnit() * speedUnit,
            .y = y * core.getMapUnit() * speedUnit,
            .type = t,
            .direction = d,
        };
    }

    pub fn getCell(self: Player) engine.Vector {
        const unit = core.getMapUnit();
        return .{
            .x = (self.x / speedUnit + (unit / 2)) / unit,
            .y = (self.y / speedUnit + (unit / 2)) / unit,
        };
    }

    pub fn draw(self: Player) void {
        const x = self.x / speedUnit;
        core.drawXY(self.type, x, self.y / speedUnit);
    }

    pub fn toCollisionRec(self: Player) engine.Rectangle {
        return engine.Rectangle{
            .x = self.x / speedUnit + 5,
            .y = self.y / speedUnit + 5,
            .width = core.getMapUnit() - 10,
            .height = core.getMapUnit() - 7,
        };
    }
};

效果

bomb

总结

实现了敌人的移动。

附录

posted @ 2026-08-16 08:58  jiangbo4444  阅读(10)  评论(0)    收藏  举报