-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmap_editor.py
152 lines (132 loc) · 4.94 KB
/
map_editor.py
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
import pygame
import json
# You can install pygame lib with `pip install pygame`
class Bunch:
def __init__(self, **kwds):
self.__dict__.update(kwds)
class Level:
def __init__(self, path=None):
self.points = []
self.walls = []
if path is not None:
with open(path, 'r') as f:
obj = json.load(f)
for point in obj["points"]:
self.points.append( (point["xy"][0],point["xy"][1]) )
# Define some colors
BLACK = ( 0, 0, 0)
WHITE = (255,255,255)
level = Level("data/level_test.json")
state = Bunch(
grid_size=20,
disable_grid_snapping=False,
camera_shift=(-30,-30),
moving_camera_from=None,
moving_camera_before=None,
moving_camera=False,
point_size=4,
dragging_point_id=None
)
def handle_event(event, state, level):
global done
global screen
global size
if event.type == pygame.QUIT:
done = True
if event.type == pygame.VIDEORESIZE:
old_surface_saved = screen
size = (event.w, event.h)
screen = pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE)
screen.blit(old_surface_saved, (0,0))
del old_surface_saved
elif event.type == pygame.KEYDOWN:
if (event.key == pygame.K_LCTRL or event.key == pygame.K_RCTRL):
state.disable_grid_snapping = True
if (event.key == pygame.K_LALT):
state.moving_camera = True
elif event.type == pygame.KEYUP:
if (event.key == pygame.K_LCTRL or event.key == pygame.K_RCTRL):
state.disable_grid_snapping = False
if (event.key == pygame.K_LALT):
state.moving_camera = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if state.moving_camera:
state.moving_camera_from = event.pos
state.moving_camera_before = state.camera_shift
else:
for i, point in enumerate(level.points):
pos = to_view(event.pos)
if (pos[0]-point[0])**2+(pos[1]-point[1])**2<state.point_size**2+1:
state.dragging_point_id = i
break
else: # this is for-else expression, not if-else
level.points.append(snap_to_grid(to_view(event.pos)))
state.dragging_point_id = len(level.points)-1
elif event.button == 3:
for point in level.points:
pos = to_view(event.pos)
if (pos[0]-point[0])**2+(pos[1]-point[1])**2<state.point_size**2+1:
level.points.remove(point)
elif event.type == pygame.MOUSEMOTION:
pos = to_view(event.pos)
if state.dragging_point_id is not None:
level.points[state.dragging_point_id] = snap_to_grid(pos)
if state.moving_camera_from is not None:
state.camera_shift = (
state.moving_camera_before[0]-event.pos[0]+state.moving_camera_from[0],
state.moving_camera_before[1]-event.pos[1]+state.moving_camera_from[1]
)
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
state.dragging_point_id = None
state.moving_camera_from = None
def to_view(pos, rev=False):
global state
if not rev:
return (pos[0]+state.camera_shift[0],
pos[1]+state.camera_shift[1])
else:
return (pos[0]-state.camera_shift[0],
pos[1]-state.camera_shift[1])
def snap_to_grid(pt):
if state.grid_size > 0 and not state.disable_grid_snapping:
gr = state.grid_size
return ((pt[0]+gr//2)//gr*gr,
(pt[1]+gr//2)//gr*gr)
else:
return pt
pygame.init()
# Set the width and height of the screen [width, height]
size = (700, 500)
screen = pygame.display.set_mode(size, pygame.RESIZABLE)
pygame.display.set_caption("NERTEX 2D Level Editor")
done = False
clock = pygame.time.Clock()
# -------- Main Program Loop -----------
while not done:
# --- Main event loop
for event in pygame.event.get():
handle_event(event, state, level)
# --- Game logic should go here
# --- Screen-clearing code goes here
screen.fill(BLACK)
# --- Drawing code should go here
if state.grid_size > 0:
i = -state.camera_shift[0]%state.grid_size
while i <= size[0]:
j = -state.camera_shift[1]%state.grid_size
while j <= size[1]:
pygame.draw.circle(screen, (100,100,100), (i,j), state.point_size-2)
j += state.grid_size
i += state.grid_size
for i, point in enumerate(level.points):
if i == state.dragging_point_id:
col = (255,255,0)
else:
col = WHITE
pygame.draw.circle(screen, col, to_view(point,True), state.point_size)
pygame.display.flip() # swap buffers
clock.tick(60) # Limit to 60 frames per second
# Close the window and quit.
pygame.quit()