function enemy_move_and_collide() { x_spd_kb = lerp(x_spd_kb, 0, 0.2); if abs(x_spd_kb) < 1 x_spd_kb = 0; y_spd_kb = lerp(y_spd_kb, 0, 0.2); if abs(y_spd_kb) < 1 y_spd_kb = 0; var _y_spd_total = (y_spd + y_spd_kb) * global.time_scale; var _x_spd_total = (x_spd + x_spd_kb) * global.time_scale; if place_meeting(x, y + _y_spd_total, oParentSolid) && apply_collision { while !place_meeting(x, y + sign(_y_spd_total), oParentSolid) y += sign(_y_spd_total); _y_spd_total = 0; y_spd = 0; y_spd_kb = 0; } y += _y_spd_total; if place_meeting(x + _x_spd_total, y, oParentSolid) && apply_collision { while !place_meeting(x + sign(_x_spd_total), y, oParentSolid) x += sign(_x_spd_total); _x_spd_total = 0; x_spd = 0; x_spd_kb = 0; } x += _x_spd_total; } function enemy_check_hazard() { var _hazard = instance_place(x, y, oParentHazard); if _hazard == noone exit; hp -= _hazard.damage; if hp <= 0 { is_dead = true; enemy_death(); } } function enemy_check_hitstun() { if hitstun_timer > 0 { hitstun_timer -= global.time_scale; x_spd = 0; y_spd = 0; if global.developer_mode image_blend = c_orange; } else { image_index += animation_spd; enemy_ai(); image_blend = c_white; } } function enemy_death() { //death_pe(); 没有_info传参,不要去注释!! if !is_undefined(death_callback) death_callback(); else { var _corpse = icd(oEnemyCorpse, x, y, 50); _corpse.sprite_index = corpse_sprite; if corpse_doll { _corpse.x_spd = x_spd_kb; _corpse.y_spd = -max(abs(y_spd_kb), abs(x_spd_kb)); _corpse.apply_gravity = true; } instance_destroy(); } } /// @desc 优雅地以该实例为原点,给定宽高、偏移与持续时间为参数,生成敌人middle/left碰撞箱(多用于横向攻击) /// @param {real} _x 碰撞箱宽度 /// @param {real} _y 碰撞箱高度 /// @param {real} _x_offset 碰撞箱与该实例在x轴上的偏移量,默认为0 /// @param {real} _y_offset 碰撞箱与该实例在y轴上的偏移量,默认为0 /// @param {real} _duration 碰撞箱持续时间,默认为0,即无限 function enemy_create_hitboxML(_x, _y, _x_offset = 0, _y_offset = 0, _duration = 0) { var _hb = icd(oEnemyHitbox, x + _x_offset, y + _y_offset); _hb.owner = id; _hb.sprite_index = sEnemyHitboxML; _hb.x_offset = _x_offset; _hb.y_offset = _y_offset; var _base = 2; _hb.image_xscale = _x / _base * facing_x; _hb.image_yscale = _y / _base; /* oEnemyHitbox的基础大小为2*2 因为gml的1*1sprite无法将重心放在middle/center 此处定义后续用于缩放 */ if _duration != 0 { _hb.hitbox_type = "BLADE"; _hb.duration = _duration; } return _hb; } /// @desc 优雅地以该实例为原点,给定宽高为参数,生成敌人middle/center碰撞箱(多用于空中本体,射弹等) /// @param {real} _x 碰撞箱宽度 /// @param {real} _y 碰撞箱高度 function enemy_create_hitboxMC(_x, _y) { var _hb = icd(oEnemyHitbox, x, y); _hb.owner = id; _hb.sprite_index = sEnemyHitboxMC; var _base = 2; _hb.image_xscale = _x / _base; _hb.image_yscale = _y / _base; return _hb; } /// @desc 优雅地以该实例为原点,给定宽高、偏移与持续时间为参数,生成敌人bottom/center碰撞箱(多用于地面本体、纵向攻击等) /// @param {real} _x 碰撞箱宽度 /// @param {real} _y 碰撞箱高度 /// @param {real} _x_offset 碰撞箱与该实例在x轴上的偏移量,默认为0 /// @param {real} _y_offset 碰撞箱与该实例在y轴上的偏移量,默认为0 /// @param {real} _duration 碰撞箱持续时间,默认为0,即无限 function enemy_create_hitboxBC(_x, _y, _x_offset = 0, _y_offset = 0, _duration = 0) { var _hb = icd(oEnemyHitbox, x + _x_offset, y + _y_offset); _hb.owner = id; _hb.sprite_index = sEnemyHitboxBC; _hb.x_offset = _x_offset; _hb.y_offset = _y_offset; var _base = 2; _hb.image_xscale = _x / _base; _hb.image_yscale = _y / _base; if _duration != 0 { _hb.hitbox_type = "BLADE"; _hb.duration = _duration; } return _hb; } function weighted_pick(_weights) { var _total = 0; for (var i = 0; i < array_length(_weights); i++) _total += _weights[i]; var _roll = irandom(_total - 1); var _acc = 0; for (var i = 0; i < array_length(_weights); i++) { _acc += _weights[i]; if _roll < _acc return i; } }