-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheditor.rb
137 lines (127 loc) · 3.79 KB
/
editor.rb
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
require 'gosu'
require_relative 'block'
require_relative 'zorder'
require_relative 'slidingblock'
require_relative 'invisibleblock'
require_relative 'enemy'
require_relative 'bullet'
require_relative 'movingenemy'
require_relative 'prizebottom'
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
class EditorWindow < Gosu::Window
# Public: get coordinates of the grid square containing specified point.
#
# x, y - coordintes of the point
#
# Returns array of square center's coordinates ([x, y])
def adjust_block_coordinates(x, y)
new_x = x - x % 1.u + 1.u / 2
new_y = y - y % 1.u + 1.u / 2
[new_x, new_y]
end
# Public: get one block of current type at the specified coordinates.
#
# x, y - coordinates, adjusted to grid automatically.
#
# Returns block of current type at the specified position.
def get_current_block(x, y)
case @block_type
when :ordinary
Block.new(adjust_block_coordinates(x,y).to_vec2d)
when :sliding_horizontally
SlidingBlock.new(adjust_block_coordinates(x, y).to_vec2d,
:horizontal)
when :sliding_vertically
SlidingBlock.new(adjust_block_coordinates(x, y).to_vec2d,
:vertical)
when :moving_enemy
MovingEnemy.new(adjust_block_coordinates(x, y).to_vec2d)
when :prize
PrizeBottom.new(adjust_block_coordinates(x,y).to_vec2d)
end
end
# Public: write level to the file.
#
# Returns nothing.
def save_level
File.open(@file_name, 'w') do |file|
@blocks_array.each do |block|
new_block = Block.new block.relative_position
puts new_block.to_s
end
end
end
def initialize
super(SCREEN_WIDTH, SCREEN_HEIGHT, false, 16)
@blocks_array = Array.new
@x_viewport = @y_viewport = 0
@block_type = :ordinary
@block_types = [:ordinary, :sliding_horizontally, :sliding_vertically, :moving_enemy, :prize]
@file_name = "level.lvl"
if File.exists?(@file_name)
File.open(@file_name) do |file|
@blocks_array += Marshal::load(file)
end
end
end
def needs_cursor?
true
end
def update
unless button_down? Gosu::MsLeft
@block_under_mouse = get_current_block(mouse_x - @x_viewport,
mouse_y - @y_viewport)
else
@block_under_mouse = nil
end
if button_down? Gosu::KbLeft
@x_viewport += 10
end
if button_down? Gosu::KbRight
@x_viewport -= 10
end
if button_down? Gosu::KbUp
@y_viewport += 10
end
if button_down? Gosu::KbDown
@y_viewport -= 10
end
@blocks_array.each do |block|
block.update unless block.moving
end
end
def draw
@blocks_array.each do |block|
block.draw(self,
[@x_viewport, @y_viewport].to_vec2d)
end
if @block_under_mouse
@block_under_mouse.draw(self, [@x_viewport,@y_viewport].to_vec2d)
end
end
def button_down(id)
case id
when Gosu::KbEnter, Gosu::KbReturn # Save level
File.open(@file_name, 'w') do |file|
puts "Saving"
file.puts Marshal::dump(@blocks_array)
end
when Gosu::KbTab # Switch block type
@block_type = @block_types.rotate![0]
when Gosu::MsLeft # Add new block
@blocks_array << get_current_block(mouse_x - @x_viewport,
mouse_y - @y_viewport)
puts "new block added"
when Gosu::MsRight # Delete block
@blocks_array.each_index do |index|
if @blocks_array[index].contains_point(mouse_x - @x_viewport, mouse_y - @y_viewport)
puts "block deleted, #{@blocks_array[index].relative_position.x}, #{@blocks_array[index].relative_position.y}"
@blocks_array.delete_at index
end
end
end
end
end
window = EditorWindow.new
window.show