-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcamera.rb
More file actions
156 lines (130 loc) · 5.02 KB
/
camera.rb
File metadata and controls
156 lines (130 loc) · 5.02 KB
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
class Camera
attr_reader :position, :target, :horizontal_angle, :vertical_angle
def initialize(parent_window)
@parent_window = parent_window
@position = Vector3D.new(2.0, 2.5, 5.0)
@target = Vector3D.new(0.0, 0.0, 0.0)
@up = Vector3D.new(0.0, 1.0, 0.0)
@ratio, @fovy, @far, @near = @parent_window.width.to_f / @parent_window.height.to_f, 60.0, 1000.0, 0.01
@horizontal_angle = 0.0
@vertical_angle = 0.0
@distance = 3.0
@speed = 0.08
@angle_speed = 1.9
@collision_box = Box2D.new(Vector3D.new(@position.x - 0.5, @position.y, @position.z - 0.5), 1.0, 1.0)
@parent_window.mouse_x, @parent_window.mouse_y = @parent_window.width / 2, @parent_window.height / 2
@last_mouse_x, @last_mouse_y = @parent_window.mouse_x, @parent_window.mouse_y
@mouse_sensitivity = 0.1
@on_ground = false
@gravity = -0.0075
@velocity_y = 0.0
adjust_target
end
def update
speed = @speed
old_x, old_z = @position.x, @position.z
handle_jump
# diagonal speed
if @parent_window.button_down?(Gosu::KbW) or @parent_window.button_down?(Gosu::KbS)
if @parent_window.button_down?(Gosu::KbA) or @parent_window.button_down?(Gosu::KbD)
speed *= 0.7
end
end
if @parent_window.button_down?(Gosu::KbW)
@position.x += speed * Math::cos(@horizontal_angle * Math::PI / 180.0)
@position.z += speed * Math::sin(@horizontal_angle * Math::PI / 180.0)
elsif @parent_window.button_down?(Gosu::KbS)
@position.x -= speed * Math::cos(@horizontal_angle * Math::PI / 180.0)
@position.z -= speed * Math::sin(@horizontal_angle * Math::PI / 180.0)
end
if @parent_window.button_down?(Gosu::KbA)
@position.x += speed * Math::cos((@horizontal_angle - 90.0) * Math::PI / 180.0)
@position.z += speed * Math::sin((@horizontal_angle - 90.0) * Math::PI / 180.0)
elsif @parent_window.button_down?(Gosu::KbD)
@position.x -= speed * Math::cos((@horizontal_angle - 90.0) * Math::PI / 180.0)
@position.z -= speed * Math::sin((@horizontal_angle - 90.0) * Math::PI / 180.0)
end
# ANGLE
if @parent_window.button_down?(Gosu::KbUp)
@vertical_angle += @angle_speed
elsif @parent_window.button_down?(Gosu::KbDown)
@vertical_angle -= @angle_speed
end
if @parent_window.button_down?(Gosu::KbLeft)
@horizontal_angle -= @angle_speed
elsif @parent_window.button_down?(Gosu::KbRight)
@horizontal_angle += @angle_speed
end
# ANGLE WITH MOUSE
if @parent_window.mouse_x != @last_mouse_x
@horizontal_angle += (@parent_window.mouse_x - @last_mouse_x) * @mouse_sensitivity
@parent_window.mouse_x = @parent_window.width / 2
@last_mouse_x = @parent_window.mouse_x
end
if @parent_window.mouse_y != @last_mouse_y
@vertical_angle -= (@parent_window.mouse_y - @last_mouse_y) * @mouse_sensitivity
@parent_window.mouse_y = @parent_window.height / 2
@last_mouse_y = @parent_window.mouse_y
end
@vertical_angle = -90.0 if @vertical_angle < -90.0
@vertical_angle = 90.0 if @vertical_angle > 90.0
# collision check
@collision_box.origin.x = @position.x - 0.5
@collision_box.origin.z = @position.z - 0.5
if @parent_window.map.block?(@collision_box)
if !@parent_window.map.block?(Box2D.new(Vector3D.new(@position.x - 0.5, @position.y, old_z - 0.5), 1.0, 1.0))
@position.z = old_z
elsif !@parent_window.map.block?(Box2D.new(Vector3D.new(old_x - 0.5, @position.y, @position.z - 0.5), 1.0, 1.0))
@position.x = old_x
else # neither x or z are allowed
@position.x = old_x
@position.z = old_z
end
end
adjust_target
end
def adjust_target
@target.x = @position.x + @distance * Math::cos(@horizontal_angle * Math::PI / 180.0)
@target.y = @position.y + @distance * Math::sin(@vertical_angle * Math::PI / 180.0)
@target.z = @position.z + @distance * Math::sin(@horizontal_angle * Math::PI / 180.0)
end
def look
glEnable(GL_DEPTH_TEST)
glEnable(GL_TEXTURE_2D)
#~ glClearColor(0.0, 1.0, 0.0, 0.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glEnable(GL_ALPHA_TEST)
glAlphaFunc(GL_GREATER, 0)
glMatrixMode(GL_PROJECTION)
glLoadIdentity
gluPerspective(@fovy, @ratio, @near, @far)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity
gluLookAt(@position.x, @position.y, @position.z, @target.x, @target.y, @target.z, @up.x, @up.y, @up.z)
end
def handle_jump
if @parent_window.button_down? Gosu::KbSpace
apply_force
else
reset_velocity
end
@velocity_y += @gravity
@position.y += @velocity_y
if @position.y < 2.5
@position.y = 2.5
@velocity_y = 0.0
@on_ground = true
end
end
def apply_force
if @on_ground
@velocity_y = 0.15
@on_ground = false
end
end
def reset_velocity
if @velocity_y > 0.08
@velocity_y = 0.08
end
end
end