source: trunk/orbital/snake.h @ 1372

Last change on this file since 1372 was 1372, checked in by sam, 11 years ago

orbital: better snake initialisation.

File size: 4.3 KB
Line 
1//
2// Orbital
3//
4// Copyright: (c) 2012 Various People
5//
6
7/* FIXME: this file is pure crap; it's only a test. */
8
9#if !defined __SNAKE_H__
10#define __SNAKE_H__
11
12class Snake : public WorldEntity
13{
14public:
15    Snake(int nodes)
16      : m_steer(0.f),
17        m_ready(false)
18    {
19        m_head.SendCommand("sc1,1,1,1,afcb10,10,10,1,sc.9,.6,.1,1,afcb30,3,3,.8,fl");
20        m_head.SendCommand("sc1,1,1,1,afcb.4,.4,12,.4,tz3,tx8,mx,fl");
21        m_head.SendCommand("sc1,1,1,1,afcb.4,.4,12,.4,tz3,tx12,mx,fl");
22        m_head.SendCommand("sc.4,.6,.8,.6,afcb5,8,8,1,ty3,tz3,fl");
23
24        m_body.SendCommand("sc1,1,1,1,afcb6,6,12,1,sc.9,.6,.1,1,afcb3,20,3,.8,afcb20,3,3,.8,fl");
25        m_body.SendCommand("sc1,1,1,1,afcb.4,.4,7,.4,ty8,my,fl");
26        m_body.SendCommand("sc1,1,1,1,afcb.4,.4,7,.4,tx8,mx,fl");
27
28        m_tail.SendCommand("sc1,1,1,1,afcb6,6,10,1,tz-1,fl");
29        m_tail.SendCommand("sc.9,.6,.1,1,afcb3,15,3,.8,ty8,fl");
30        m_tail.SendCommand("sc1,1,1,1,afcb.4,.4,8,.4,tz-1,ty8,fl");
31        m_tail.SendCommand("sc1,1,1,1,afcb.4,.4,8,.4,tz-1,ty12,fl");
32        m_tail.SendCommand("sc.9,.6,.1,1,afcb15,3,3,.8,tx8,fl");
33        m_tail.SendCommand("sc1,1,1,1,afcb.4,.4,8,.4,tz-1,tx8,fl");
34        m_tail.SendCommand("sc1,1,1,1,afcb.4,.4,8,.4,tz-1,tx12,fl");
35
36        m_position = vec3(RandF(0.f, 100.f), 20.f, RandF(150.f, 250.f));
37        m_rotation = quat::rotate(RandF(30.f, 70.f), 0.f, 1.f, 0.f);;
38
39        /* The last node is actually the tail */
40        for (int i = 0; i < nodes; i++)
41            m_nodes.Push(m_rotation.transform(vec3(-12.f, 0.f, 0.f)), 0.f);
42        m_nodes.Push(vec3(0.f, 0.f, 0.f), 45.f);
43    }
44
45    ~Snake()
46    {
47    }
48
49    char const *GetName() { return "<snake>"; }
50
51protected:
52    virtual void TickGame(float seconds)
53    {
54        WorldEntity::TickGame(seconds);
55
56        m_steer += 2.f * seconds;
57
58        /* Destruction test */
59        if (m_nodes.Count() >= 3 && m_steer > 30
60             && (int)m_steer / 6 != (int)(m_steer - 2.f * seconds) / 6)
61        {
62            int todelete = (int)RandF(m_nodes.Count() - 2);
63            m_nodes[todelete + 1].m1 += m_nodes[todelete].m1;
64            m_nodes.Remove(todelete);
65            m_nodes[todelete + 1].m1 += m_nodes[todelete].m1;
66            m_nodes.Remove(todelete);
67        }
68
69        float test = sinf(m_steer) * 100.f + 30.f;
70        m_rotation *= quat::rotate(seconds * test, vec3(0, 1, 0));
71
72        m_velocity = 60.f * m_rotation.transform(vec3(0, 0, 1));
73        vec3 deltapos = seconds * m_velocity;
74        m_position += deltapos;
75
76        for (int i = 0; i < m_nodes.Count(); i++)
77        {
78            /* The current node is dragged by the previous one */
79            vec3 new_delta = m_nodes[i].m1 - deltapos;
80            float new_distance = length(new_delta);
81            if (new_distance > 12.f)
82            {
83                new_delta /= new_distance;
84                new_distance = std::max(12.f, new_distance - seconds * 80.f);
85                new_delta *= new_distance;
86            }
87            deltapos = new_delta + deltapos - m_nodes[i].m1;
88            m_nodes[i].m1 = new_delta;
89
90            /* If the current node is not the tail, rotate */
91            if (i != m_nodes.Count() - 1)
92                m_nodes[i].m2 += seconds * ((i & 1) ? 200.f : -200.f);
93        }
94    }
95
96    virtual void TickDraw(float seconds)
97    {
98        WorldEntity::TickDraw(seconds);
99
100        if (!m_ready)
101        {
102            m_head.SendCommand("irb");
103            m_body.SendCommand("irb");
104            m_tail.SendCommand("irb");
105            m_ready = true;
106        }
107
108        vec3 pos = m_position;
109        quat rot = m_rotation;
110        float y_angle = 0.f;
111        mat4 model = mat4::translate(pos) * mat4(rot);
112        m_head.Render(model);
113
114        for (int i = 0; i < m_nodes.Count(); i++)
115        {
116            pos += m_nodes[i].m1;
117            y_angle = (180.f / M_PI) * atan2(m_nodes[i].m1.x, m_nodes[i].m1.z);
118            rot = quat::rotate(y_angle, 0.f, 1.f, 0.f)
119                * quat::rotate(m_nodes[i].m2, 0.f, 0.f, 1.f);
120            model = mat4::translate(pos) * mat4(rot);
121            if (i != m_nodes.Count() - 1)
122                m_body.Render(model);
123            else
124                m_tail.Render(model);
125        }
126    }
127
128private:
129    Mesh m_head, m_body, m_tail;
130    float m_steer;
131    /* List of nodes (position, self-rotation angle) */
132    Array<vec3, float> m_nodes;
133    bool m_ready;
134};
135
136#endif /* __SNAKE_H__ */
137
Note: See TracBrowser for help on using the repository browser.