2 / 2 / 1
Регистрация: 12.02.2018
Сообщений: 48
1

Как реализовать коллизию?

06.08.2018, 05:41. Показов 2978. Ответов 1
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здесь есть класс моего игрока player. Смотрите в функцию collide.
Можете её содержимое вообще удалить и перенаписать.
Результат моей попытки сделать коллизию тут: game.zip
Движение: A, D, SPACE, SHIFT
Телепорт: ЛКМ
А вот и сам код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
enum PLAYER_CONTROL
{
    WALK_RIGHT,
    WALK_LEFT,
    RUN_RIGHT,
    RUN_LEFT,
    START_JUMP,
    HOLD_JUMP,
    END_JUMP
};
class player
{
public:
    //parameters
    world environment = world();
    float ground_friction = 0.03f;
    float air_friction = 0.01f;
    float ground_control_force = 0.1f;
    float air_control_force = 0.05f;
    int jump_max_time = 18;
    float jump_velocity = 0.4f;
    float gravity = -0.035f;
    float walk_speed = 0.25f;
    float run_speed = 0.35f;
    float fall_vel = -1.2f;
    vector<vec2f> poly = { vec2f(-0.4f, -1.7f), vec2f(-0.8f, -1.1f), vec2f(-0.8f, 1.1f), vec2f(-0.4f, 1.7f), vec2f(0.4f, 1.7f), vec2f(0.8f, 1.1f), vec2f(0.8f, -1.1f), vec2f(0.4f, -1.7f) };
 
    //currents
    vec2f pos = vec2f();
    vec2f vel = vec2f();
    float *friction = &ground_friction;
    float *control_force = &ground_control_force;
    int jump_timer = 0;
    bool on_ground = true;
 
    player()
    {
 
    };
    void collide()
    {
        bool collides_with_ground = false;
        for (int i = 0; i != environment.blocks.size(); i++)
        {
            bool intersect = false;
            for (int j = 0; j != poly.size(); j++)
            {
                if (environment.blocks[i][0] + 0.5f >= pos.x + poly[j].x && environment.blocks[i][0] - 0.5f <= pos.x + poly[j].x
                 && environment.blocks[i][1] + 0.5f >= pos.y + poly[j].y && environment.blocks[i][1] - 0.5f <= pos.y + poly[j].y)
                {
                    intersect = true;
                }
            }
            if (intersect)
            {
                if (pos.y >= environment.blocks[i][1])
                {
                    float max_y = 0;
                    for (int i = 0; i != poly.size(); i++)
                    {
                        max_y = max(max_y, poly[i].y);
                    }
                    pos.sety(environment.blocks[i][1] + 0.5f + max_y);
                    collides_with_ground = true;
                }
                else if (pos.y <= environment.blocks[i][1])
                {
                    float min_y = 0;
                    for (int i = 0; i != poly.size(); i++)
                    {
                        min_y = max(min_y, poly[i].y);
                    }
                    pos.sety(environment.blocks[i][1] - 0.5f + min_y);
                    vel.sety(0);
                }
            }
        }
        on_ground = collides_with_ground;
    };
    void move()
    {
        pos.addxy(vel.x, vel.y);
    }
    void physics()
    {
        friction = on_ground ? &ground_friction : &air_friction;
        control_force = on_ground ? &ground_control_force : &air_control_force;
        if (on_ground)
        {
            vel.sety(0);
        }
        else if (fall_vel < vel.y)
        { 
            vel.sety(max(vel.y + gravity, fall_vel));
        }
        vel.addx(abs(vel.x) > *friction ? (-(vel.x / abs(vel.x)) * *friction) : -vel.x);
    }
    void control(PLAYER_CONTROL KEY)
    {
        switch (KEY)
        {
        case WALK_RIGHT:
            if (vel.x < walk_speed) { vel.addx(0.6f * *control_force); }
            break;
        case WALK_LEFT:
            if (vel.x > -walk_speed) { vel.addx(-0.6f * *control_force); }
            break;
        case RUN_RIGHT:
            if (vel.x < run_speed) { vel.addx(0.6f * *control_force); }
            break;
        case RUN_LEFT:
            if (vel.x > -run_speed) { vel.addx(-0.6f * *control_force); }
            break;
        case START_JUMP:
            if (on_ground) { jump_timer = 0; }
            break;
        case HOLD_JUMP:
            if (jump_timer < jump_max_time)
            {
                jump_timer++;
                vel.sety(jump_velocity);
            }
            else
            {
                jump_timer = jump_max_time;
            }
            break;
        case END_JUMP:
            jump_timer = jump_max_time;
            break;
        }
    };
};
А вот, в каком порядке функции игрока исполняются в игровом таймере:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
if (keyPressed(KEY_D) && !keyPressed(KEY_A))
{
    if (keyPressed(KEY_SHIFT))
    {
        actor.control(RUN_RIGHT);
    }
    else
    {
        actor.control(WALK_RIGHT);
    }
}
if (keyPressed(KEY_A) && !keyPressed(KEY_D))
{
    if (keyPressed(KEY_SHIFT))
    {
        actor.control(RUN_LEFT);
    }
    else
    {
        actor.control(WALK_LEFT);
        }
}
if (keyDown(KEY_SPACE) || keyDown(KEY_W)) { actor.control(START_JUMP); }
if (keyPressed(KEY_SPACE) || keyPressed(KEY_W)) { actor.control(HOLD_JUMP); }
if (keyUp(KEY_SPACE) || keyUp(KEY_W)) { actor.control(END_JUMP); }
if (keyDown(KEY_F)) { glutSetWindowTitle(randWord().c_str()); }
actor.move();
actor.collide();
actor.physics();
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.08.2018, 05:41
Ответы с готовыми решениями:

Как сделать плавную коллизию?
Привет. Есть коллизия. Камера сталкивается с окружностью. Когда координаты камеры приближаются к...

Как сделать коллизию(столкновение) в игре?
Написал игру сделал карту , карта сделана с помощь двумерного массива Вопрос в том, как сделать...

Как сделать коллизию подгруженым 3ds моделям?
Доброго времени суток! Я смотрю вот уроки по OpenGL, дошел до...

Как создать универсальную коллизию для спрайтов в pascal(wingraph)
procedure ris(st:string;var p:pointer); var f:file; sz:longint; begin ...

1
2 / 2 / 1
Регистрация: 12.02.2018
Сообщений: 48
06.08.2018, 05:47  [ТС] 2
Ах... Забыл про класс мира:
C++
1
2
3
4
5
6
7
8
9
class world
{
public:
    vector<array<int, 2>> blocks { { -2, 0 }, { -1, 0 }, { 0, 0 }, { 1, 0 },{ 2, 0 }, { -1, 7 },{ 1, 7 } };
    world()
    {
 
    }
};
0
06.08.2018, 05:47
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.08.2018, 05:47
Помогаю со студенческими работами здесь

Определить коллизию прямоугольников
Ребят зашел в тупик(. Моя задача такова: у меня есть 2 прямоугольника. Надо определить их коллизию...

Имитировать коллизию в Cisco Packet Tracker
У меня не получается сделать так: соединяю два компа, прописываю IP-адреса: 192.168.1.1 и...

Как правильно реализовать доступ во внутреннюю (корпоративную) сеть из внешней и реализовать аутентификацию
Доброго времени суток. Вобщем суть вопроса... есть настроенный в корпоративной среде Sql Server...

Как реализовать видео как фон и оконный эффект? (Такой как по ссылке ниже)
Добрый день. Подскажите пожалуйста, как реализовать видео как фон и оконный эффект? Такой как...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru