-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathgameworld.py
More file actions
281 lines (233 loc) · 11.8 KB
/
gameworld.py
File metadata and controls
281 lines (233 loc) · 11.8 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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
""" This file contains the classes for creating a model of the game state and generating the view of the game. """
import pygame
import random
import actors
from banner import Banner
from flag import Flag
from education_screen import *
from level_generation import *
import copy
import math
class Cell(object):
""" This is an object for each grid cell """
def __init__(self, cell_coord, grid_coord):
"""Initialize the cell object.
cell_coord: Tuple of coordinate in pixels
grid_coord: TUple of coordinate in cells"""
self.cell_coord = cell_coord # coordinates of upper left corner of cell in pixels, tuple
self.label = grid_coord # coordinates of cell in terms of position in grid, tuple
self.occupied = False
self.type = "nothing"
class Model(object):
""" Class that holds the state of the entire game """
def __init__(self, cell_size = (40, 40), grid_size = (46, 20)):
"""Initialize the model.
cell_size: Tuple of the dimension of each cell in pixels
grid_size: Tuple of the dimensions of the grid in cells"""
self.cell_size = cell_size
self.grid_size = grid_size
self.screen_size = (self.cell_size[0]*self.grid_size[0],
self.cell_size[1]*self.grid_size[1]+160)
self.endgame = False
self.obstacles = []
self.cleared_obstacles = []
self.make_grid()
self.choose_flag()
self.make_colors()
self.make_player()
self.generate_level()
self.make_darkness()
self.make_banner()
def make_grid(self):
"""Instantiate grid cells for game map.
Creates a dictionary with keys that are cell
coordinates with values that are cell objects"""
self.grid_cells = {}
cell_size = (self.cell_size) # cell size in pixels
for i in range(self.grid_size[0]): # for the x cells
for j in range(self.grid_size[1]): # for the y cells
cell_coord = (i*self.cell_size[0], j*self.cell_size[1]+160)
self.grid_cells[(i,j)] = Cell(cell_coord, (i, j))
def choose_flag(self):
"""Randomly choose which flag to play the game with."""
self.flag = Flag({
1:"ace",
2:"alt-lesbian",
3:"bi",
4:"intersex",
5:"l-lesbian",
6:"nb",
7:"pan",
8:"poc",
9:"pride",
10:"trans",
11:"gqueer"
}[random.randint(1, 10)])
def make_colors(self):
"""Instantiate Color objects for each color in the chosen flag and place in random cells """
self.color_objs = []
for color in self.flag.colors:
x_cell = random.randint(0, self.grid_size[0]-1)
y_cell = random.randint(0, self.grid_size[1]-1)
cell_coord = self.grid_cells[(x_cell,y_cell)].cell_coord
grid_coord = self.grid_cells[(x_cell,y_cell)].label
self.color_objs.append(actors.Color(color, self.cell_size, cell_coord, grid_coord, self.grid_cells[grid_coord]))
self.grid_cells[(x_cell,y_cell)].occupied = True
self.grid_cells[(x_cell,y_cell)].type = 'color'
def generate_level(self):
""" Generates playable level """
#gets position of player for play path
player_pos = self.player.get_draw_position()
player_grid_pos = (math.floor((player_pos[0]-40)/self.cell_size[0]), math.floor((player_pos[1] - 160)/self.cell_size[1]))
player_cell = self.grid_cells[(player_grid_pos)]
#initializes order of goals for random playable path
path_order_colors = self.color_objs
random.shuffle(path_order_colors)
path_order = [color.cell_in for color in path_order_colors]
path_order.insert(0,player_cell)
#generates path, places obstacles accordingly
self.path = []
ind = 0
for i in list(range(len(path_order)-1)):
#for i in range(2):
zigzag_path = get_zigzag_path(self.grid_cells, path_order[ind], path_order[ind+1], 3)
self.place_obstacles(zigzag_path, ind)
if not ind == 0:
for cell in zigzag_path:
cell.type == 'none'
self.path.extend(zigzag_path)
ind += 1
def place_obstacles(self, path, ind):
""" Generate obstacles in the grid
path = list of Cell objects that comprise a path through the grid
ind = number path that is currently being generated """
obstacle_types = self.flag.colors[:ind+1]
for i in range(round(350/(len(self.flag.colors)))): # always place 350 obstacles
x_cell = random.randint(0, self.grid_size[0]-1)
y_cell = random.randint(0, self.grid_size[1]-1)
while self.grid_cells[(x_cell, y_cell)].occupied: # re-randomize cells if chosen ones are occupied
x_cell = random.randint(0, self.grid_size[0]-1)
y_cell = random.randint(0, self.grid_size[1]-1)
coord = self.grid_cells[(x_cell,y_cell)].cell_coord
type = random.choice(obstacle_types) # randomly chooses this obstacle's type
obstacle = actors.Obstacle((self.cell_size),coord,type)
obstacle.make_groups(obstacle, self.obstacles) # add obstacle to group based on what the obstacle's type is
self.grid_cells[(x_cell,y_cell)].occupied = True
self.grid_cells[(x_cell,y_cell)].type = 'obstacle'
def erase_obstacles(self, key = pygame.K_SPACE):
""" Removes obstacles from self.model.obstacles while spacebar is held """
if pygame.key.get_pressed()[key] == 1:
for color in self.player.collided_with: # iterates through list of colors that have been collided with
for group in self.obstacles: # iterates through all groups of obstacles
if group.type == color.color: # finds group that corresponds to color that was just touched
self.obstacles.remove(group)
self.cleared_obstacles.append(group)
else:
for group in self.cleared_obstacles:
self.cleared_obstacles.remove(group)
self.obstacles.append(group)
def make_player(self):
""" Instantiate Player object """
self.player = actors.Player((400, 400), self.screen_size,
self.obstacles, self.color_objs)
for i in range(14, 16): # range of x_coord cells where the player spawns
for j in range(10,12): # range of y_coord cells where player spawns
self.grid_cells[(i,j)].occupied = True # marks cells as occupied so that nothing else spawns there
def make_darkness(self):
""" Instantiate Darkness object """
self.darkness = actors.Darkness(self.player, (self.cell_size[0]*self.grid_size[0], self.cell_size[1]*self.grid_size[0]))
def make_banner(self):
""" Instatiate Banner object """
colors = self.flag.colors
screen_size = self.screen_size
self.banner = Banner(self.flag.name, screen_size)
self.banner.scale_text(40) # we want the text to be 40 pixels tall
self.banner.scale_logo(100) # and we want the logo to be 100 pixels tall
self.banner.center_text()
def make_endscreen(self):
""" Instantiate Endscreen object """
self.endscreen = EndScreen(self.flag.name, (1920, 1080))
class View():
"""
Instantiates model and draws the state of every object on the game screen
"""
def __init__(self, screen_size, image, model):
"""Initialize model and make game screen
screen_size = size of the game window in pixels
model = game model objects"""
self.model = model
self.screen = pygame.display.set_mode(screen_size, pygame.FULLSCREEN) # sets screen dimensions
self.fullscreen = True
self.image = image.convert() # convert makes the image smaller
pygame.display.set_caption('Window Viewer') # sets window caption
def draw_player(self):
"""Draw the player at its draw position"""
self.model.player.update_position()
self.screen.blit(self.model.player.image, self.model.player.get_draw_position()) # places image of player_actor
def draw_colors(self):
"""Draw the flag colors onto the display"""
flag_image = pygame.transform.scale(pygame.image.load('./images/flag_piece_mask.png'), (40,40))
for piece in self.model.color_objs:
if piece.exists:
self.screen.blit(piece.image, piece.position)
self.screen.blit(flag_image, piece.position)
def draw_sparkles(self):
""" draw sparkles to indicate position of flag colors """
sparkles_image = pygame.transform.scale(pygame.image.load('./images/sparkles.png'), (40,40))
for piece in self.model.color_objs:
if piece.exists:
self.screen.blit(sparkles_image, piece.position)
def draw_obstacles(self):
"""
Draw the obstacles on the display
Ideally the group.draw(self.screen) function would draw both the colored square and the obstacle.png overlay
"""
for group in self.model.obstacles: # places image of obstacle for each obstacle created in Model
for obstacle in group:
color = obstacle.type
rectangle = pygame.Rect(obstacle.position, self.model.cell_size)
pygame.draw.rect(self.screen, color, rectangle) # drawns foundation square of the obstacle's color
group.draw(self.screen) # overlays the shaded "spike"
self.model.erase_obstacles() # runs method that allows player to erase colored obstacles by holding spacebar
def draw_flag(self):
"""Draw the flag onto the display"""
if self.model.flag.colors_up:
for image in self.model.flag.colors_up:
self.screen.blit(image, self.model.flag.position)
def draw_darkness(self):
"""Draw the darkness on the display"""
self.model.darkness.rotate()
self.screen.blit(self.model.darkness.image, self.model.darkness.draw_position()) # places image of player_actor
def draw_endscreen(self):
"""Draw the endscreen on the display"""
# draw the current page in the book
self.screen.blit(self.model.endscreen.book.pages[self.model.endscreen.book.current_page].image, (0, 0))
def draw_path(self):
"""Draw a created path"""
#colors = [(255, 255, 255), (255, 0, 0), ( 0, 255, 0), ( 0, 0, 255), (255, 255, 0)]
for step in self.model.path:
pygame.draw.rect(self.screen, (255, 255, 255),
[step.cell_coord[0], step.cell_coord[1],self.model.cell_size[0],
self.model.cell_size[1]])
def draw_banner(self):
"""Draw banner at top of screen"""
banner = self.model.banner
box = pygame.Rect(0, 0, banner.size[0], banner.size[1])
pygame.draw.rect(self.screen, (0,0,0), box) # draws black rectangle as background for banner contents
self.screen.blit(banner.text, (banner.x_pos,banner.y_pos)) # blits text that says the level's flag
self.screen.blit(banner.logo, (10,10)) # blits image of FlagQuest logo
def update(self):
"""Update the draw positons of player, color_actors, obstacles, grid, and the flag"""
self.screen.blit(self.image, (0, 0)) # sets background
if self.model.endgame == False:
# self.draw_path()
self.draw_player()
self.draw_colors()
self.draw_obstacles()
self.draw_darkness()
self.draw_sparkles()
self.draw_banner()
self.draw_flag()
else: # if it is the end, just draw the endscreen
self.draw_endscreen()
pygame.display.update()