⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gamefunc.java

📁 Jake2是一个Java 3D游戏引擎.
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 1997-2001 Id Software, Inc. *  * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. *  * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. *  * See the GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307, USA. *   */// Created on 18.11.2003 by RST.// $Id: GameFunc.java,v 1.9 2006/01/21 21:53:32 salomo Exp $package jake2.game;import jake2.Defines;import jake2.Globals;import jake2.util.Lib;import jake2.util.Math3D;public class GameFunc {    static void Move_Calc(edict_t ent, float[] dest, EntThinkAdapter func) {        Math3D.VectorClear(ent.velocity);        Math3D.VectorSubtract(dest, ent.s.origin, ent.moveinfo.dir);        ent.moveinfo.remaining_distance = Math3D                .VectorNormalize(ent.moveinfo.dir);        ent.moveinfo.endfunc = func;        if (ent.moveinfo.speed == ent.moveinfo.accel                && ent.moveinfo.speed == ent.moveinfo.decel) {            if (GameBase.level.current_entity == ((ent.flags & Defines.FL_TEAMSLAVE) != 0 ? ent.teammaster                    : ent)) {                Move_Begin.think(ent);            } else {                ent.nextthink = GameBase.level.time + Defines.FRAMETIME;                ent.think = Move_Begin;            }        } else {            // accelerative            ent.moveinfo.current_speed = 0;            ent.think = Think_AccelMove;            ent.nextthink = GameBase.level.time + Defines.FRAMETIME;        }    }    static void AngleMove_Calc(edict_t ent, EntThinkAdapter func) {        Math3D.VectorClear(ent.avelocity);        ent.moveinfo.endfunc = func;        if (GameBase.level.current_entity == ((ent.flags & Defines.FL_TEAMSLAVE) != 0 ? ent.teammaster                : ent)) {            AngleMove_Begin.think(ent);        } else {            ent.nextthink = GameBase.level.time + Defines.FRAMETIME;            ent.think = AngleMove_Begin;        }    }    /**     * Think_AccelMove     *      * The team has completed a frame of movement, so change the speed for the     * next frame.     */    static float AccelerationDistance(float target, float rate) {        return target * ((target / rate) + 1) / 2;    };    static void plat_CalcAcceleratedMove(moveinfo_t moveinfo) {        float accel_dist;        float decel_dist;        moveinfo.move_speed = moveinfo.speed;        if (moveinfo.remaining_distance < moveinfo.accel) {            moveinfo.current_speed = moveinfo.remaining_distance;            return;        }        accel_dist = AccelerationDistance(moveinfo.speed, moveinfo.accel);        decel_dist = AccelerationDistance(moveinfo.speed, moveinfo.decel);        if ((moveinfo.remaining_distance - accel_dist - decel_dist) < 0) {            float f;            f = (moveinfo.accel + moveinfo.decel)                    / (moveinfo.accel * moveinfo.decel);            moveinfo.move_speed = (float) ((-2 + Math.sqrt(4 - 4 * f                    * (-2 * moveinfo.remaining_distance))) / (2 * f));            decel_dist = AccelerationDistance(moveinfo.move_speed,                    moveinfo.decel);        }        moveinfo.decel_distance = decel_dist;    };    static void plat_Accelerate(moveinfo_t moveinfo) {        // are we decelerating?        if (moveinfo.remaining_distance <= moveinfo.decel_distance) {            if (moveinfo.remaining_distance < moveinfo.decel_distance) {                if (moveinfo.next_speed != 0) {                    moveinfo.current_speed = moveinfo.next_speed;                    moveinfo.next_speed = 0;                    return;                }                if (moveinfo.current_speed > moveinfo.decel)                    moveinfo.current_speed -= moveinfo.decel;            }            return;        }        // are we at full speed and need to start decelerating during this move?        if (moveinfo.current_speed == moveinfo.move_speed)            if ((moveinfo.remaining_distance - moveinfo.current_speed) < moveinfo.decel_distance) {                float p1_distance;                float p2_distance;                float distance;                p1_distance = moveinfo.remaining_distance                        - moveinfo.decel_distance;                p2_distance = moveinfo.move_speed                        * (1.0f - (p1_distance / moveinfo.move_speed));                distance = p1_distance + p2_distance;                moveinfo.current_speed = moveinfo.move_speed;                moveinfo.next_speed = moveinfo.move_speed - moveinfo.decel                        * (p2_distance / distance);                return;            }        // are we accelerating?        if (moveinfo.current_speed < moveinfo.speed) {            float old_speed;            float p1_distance;            float p1_speed;            float p2_distance;            float distance;            old_speed = moveinfo.current_speed;            // figure simple acceleration up to move_speed            moveinfo.current_speed += moveinfo.accel;            if (moveinfo.current_speed > moveinfo.speed)                moveinfo.current_speed = moveinfo.speed;            // are we accelerating throughout this entire move?            if ((moveinfo.remaining_distance - moveinfo.current_speed) >= moveinfo.decel_distance)                return;            // during this move we will accelrate from current_speed to            // move_speed            // and cross over the decel_distance; figure the average speed for            // the            // entire move            p1_distance = moveinfo.remaining_distance - moveinfo.decel_distance;            p1_speed = (old_speed + moveinfo.move_speed) / 2.0f;            p2_distance = moveinfo.move_speed                    * (1.0f - (p1_distance / p1_speed));            distance = p1_distance + p2_distance;            moveinfo.current_speed = (p1_speed * (p1_distance / distance))                    + (moveinfo.move_speed * (p2_distance / distance));            moveinfo.next_speed = moveinfo.move_speed - moveinfo.decel                    * (p2_distance / distance);            return;        }        // we are at constant velocity (move_speed)        return;    };    static void plat_go_up(edict_t ent) {        if (0 == (ent.flags & Defines.FL_TEAMSLAVE)) {            if (ent.moveinfo.sound_start != 0)                GameBase.gi.sound(ent, Defines.CHAN_NO_PHS_ADD                        + Defines.CHAN_VOICE, ent.moveinfo.sound_start, 1,                        Defines.ATTN_STATIC, 0);            ent.s.sound = ent.moveinfo.sound_middle;        }        ent.moveinfo.state = STATE_UP;        Move_Calc(ent, ent.moveinfo.start_origin, plat_hit_top);    }    static void plat_spawn_inside_trigger(edict_t ent) {        edict_t trigger;        float[] tmin = { 0, 0, 0 }, tmax = { 0, 0, 0 };        //        //	   middle trigger        //	        trigger = GameUtil.G_Spawn();        trigger.touch = Touch_Plat_Center;        trigger.movetype = Defines.MOVETYPE_NONE;        trigger.solid = Defines.SOLID_TRIGGER;        trigger.enemy = ent;        tmin[0] = ent.mins[0] + 25;        tmin[1] = ent.mins[1] + 25;        tmin[2] = ent.mins[2];        tmax[0] = ent.maxs[0] - 25;        tmax[1] = ent.maxs[1] - 25;        tmax[2] = ent.maxs[2] + 8;        tmin[2] = tmax[2] - (ent.pos1[2] - ent.pos2[2] + GameBase.st.lip);        if ((ent.spawnflags & PLAT_LOW_TRIGGER) != 0)            tmax[2] = tmin[2] + 8;        if (tmax[0] - tmin[0] <= 0) {            tmin[0] = (ent.mins[0] + ent.maxs[0]) * 0.5f;            tmax[0] = tmin[0] + 1;        }        if (tmax[1] - tmin[1] <= 0) {            tmin[1] = (ent.mins[1] + ent.maxs[1]) * 0.5f;            tmax[1] = tmin[1] + 1;        }        Math3D.VectorCopy(tmin, trigger.mins);        Math3D.VectorCopy(tmax, trigger.maxs);        GameBase.gi.linkentity(trigger);    }    /**     * QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER speed default 150     *      * Plats are always drawn in the extended position, so they will light     * correctly.     *      * If the plat is the target of another trigger or button, it will start out     * disabled in the extended position until it is trigger, when it will lower     * and become a normal plat.     *      * "speed" overrides default 200. "accel" overrides default 500 "lip"     * overrides default 8 pixel lip     *      * If the "height" key is set, that will determine the amount the plat     * moves, instead of being implicitly determoveinfoned by the model's     * height.     *      * Set "sounds" to one of the following: 1) base fast 2) chain slow     */    static void SP_func_plat(edict_t ent) {        Math3D.VectorClear(ent.s.angles);        ent.solid = Defines.SOLID_BSP;        ent.movetype = Defines.MOVETYPE_PUSH;        GameBase.gi.setmodel(ent, ent.model);        ent.blocked = plat_blocked;        if (0 == ent.speed)            ent.speed = 20;        else            ent.speed *= 0.1;        if (ent.accel == 0)            ent.accel = 5;        else            ent.accel *= 0.1;        if (ent.decel == 0)            ent.decel = 5;        else            ent.decel *= 0.1;        if (ent.dmg == 0)            ent.dmg = 2;        if (GameBase.st.lip == 0)            GameBase.st.lip = 8;        // pos1 is the top position, pos2 is the bottom        Math3D.VectorCopy(ent.s.origin, ent.pos1);        Math3D.VectorCopy(ent.s.origin, ent.pos2);        if (GameBase.st.height != 0)            ent.pos2[2] -= GameBase.st.height;        else            ent.pos2[2] -= (ent.maxs[2] - ent.mins[2]) - GameBase.st.lip;        ent.use = Use_Plat;        plat_spawn_inside_trigger(ent); // the "start moving" trigger        if (ent.targetname != null) {            ent.moveinfo.state = STATE_UP;        } else {            Math3D.VectorCopy(ent.pos2, ent.s.origin);            GameBase.gi.linkentity(ent);            ent.moveinfo.state = STATE_BOTTOM;        }        ent.moveinfo.speed = ent.speed;        ent.moveinfo.accel = ent.accel;        ent.moveinfo.decel = ent.decel;        ent.moveinfo.wait = ent.wait;        Math3D.VectorCopy(ent.pos1, ent.moveinfo.start_origin);        Math3D.VectorCopy(ent.s.angles, ent.moveinfo.start_angles);        Math3D.VectorCopy(ent.pos2, ent.moveinfo.end_origin);        Math3D.VectorCopy(ent.s.angles, ent.moveinfo.end_angles);        ent.moveinfo.sound_start = GameBase.gi.soundindex("plats/pt1_strt.wav");        ent.moveinfo.sound_middle = GameBase.gi.soundindex("plats/pt1_mid.wav");        ent.moveinfo.sound_end = GameBase.gi.soundindex("plats/pt1_end.wav");    }    /**     * DOORS     *      * spawn a trigger surrounding the entire team unless it is already targeted     * by another.     *      */    /**     * QUAKED func_door (0 .5 .8) ? START_OPEN x CRUSHER NOMONSTER ANIMATED     * TOGGLE ANIMATED_FAST TOGGLE wait in both the start and end states for a     * trigger event. START_OPEN the door to moves to its destination when     * spawned, and operate in reverse. It is used to temporarily or permanently     * close off an area when triggered (not useful for touch or takedamage     * doors). NOMONSTER monsters will not trigger this door     *      * "message" is printed when the door is touched if it is a trigger door and     * it hasn't been fired yet "angle" determines the opening direction     * "targetname" if set, no touch field will be spawned and a remote button     * or trigger field activates the door. "health" if set, door must be shot     * open "speed" movement speed (100 default) "wait" wait before returning (3     * default, -1 = never return) "lip" lip remaining at end of move (8     * default) "dmg" damage to inflict when blocked (2 default) "sounds" 1)     * silent 2) light 3) medium 4) heavy     */    static void door_use_areaportals(edict_t self, boolean open) {        edict_t t = null;        if (self.target == null)            return;        EdictIterator edit = null;        while ((edit = GameBase                .G_Find(edit, GameBase.findByTarget, self.target)) != null) {            t = edit.o;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -