diff --git a/resources/graphics/Cards/card_sunflower.png b/resources/graphics/Cards/card_sunflower.png index 4aea97b..200a3d8 100644 Binary files a/resources/graphics/Cards/card_sunflower.png and b/resources/graphics/Cards/card_sunflower.png differ diff --git a/source/component/menubar.py b/source/component/menubar.py index 3a573ee..d445817 100644 --- a/source/component/menubar.py +++ b/source/component/menubar.py @@ -4,6 +4,12 @@ import pygame as pg from .. import tool from .. import constants as c +PANEL_Y_START = 87 +PANEL_X_START = 22 +PANEL_Y_INTERNAL = 74 +PANEL_X_INTERNAL = 53 +CARD_LIST_NUM = 8 + card_name_list = [c.CARD_SUNFLOWER, c.CARD_PEASHOOTER, c.CARD_SNOWPEASHOOTER, c.CARD_WALLNUT, c.CARD_CHERRYBOMB, c.CARD_THREEPEASHOOTER, c.CARD_REPEATERPEA, c.CARD_CHOMPER, c.CARD_PUFFMUSHROOM, c.CARD_POTATOMINE, c.CARD_SQUASH] @@ -12,11 +18,26 @@ plant_name_list = [c.SUNFLOWER, c.PEASHOOTER, c.SNOWPEASHOOTER, c.WALLNUT, c.PUFFMUSHROOM, c.POTATOMINE, c.SQUASH] plant_sun_list = [50, 100, 175, 50, 150, 325, 200, 150, 0, 25, 50] plant_frozen_time_list = [0, 5000, 5000, 10000, 5000, 5000, 5000, 5000, 8000, 8000, 8000] -card_list = [0, 1, 3, 4, 7, 8, 9, 10] +all_card_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + +def getSunValueImage(sun_value): + font = pg.font.SysFont(None, 22) + width = 32 + msg_image = font.render(str(sun_value), True, c.NAVYBLUE, c.LIGHTYELLOW) + msg_rect = msg_image.get_rect() + msg_w = msg_rect.width + + image = pg.Surface([width, 17]) + x = width - msg_w + + image.fill(c.LIGHTYELLOW) + image.blit(msg_image, (x, 0), (0, 0, msg_rect.w, msg_rect.h)) + image.set_colorkey(c.BLACK) + return image class Card(): - def __init__(self, x, y, name_index): - self.loadFrame(card_name_list[name_index]) + def __init__(self, x, y, name_index, scale=0.78): + self.loadFrame(card_name_list[name_index], scale) self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y @@ -25,13 +46,14 @@ class Card(): self.sun_cost = plant_sun_list[name_index] self.frozen_time = plant_frozen_time_list[name_index] self.frozen_timer = -self.frozen_time + self.select = True - def loadFrame(self, name): + def loadFrame(self, name, scale): frame = tool.GFX[name] rect = frame.get_rect() width, height = rect.w, rect.h - self.image = tool.get_image(frame, 0, 0, width, height, c.BLACK, 0.78) + self.image = tool.get_image(frame, 0, 0, width, height, c.BLACK, scale) def checkMouseClick(self, mouse_pos): x, y = mouse_pos @@ -45,6 +67,16 @@ class Card(): return True return False + def canSelect(self): + return self.select + + def setSelect(self, can_select): + self.select = can_select + if can_select: + self.image.set_alpha(255) + else: + self.image.set_alpha(128) + def setFrozenTime(self, current_time): self.frozen_timer = current_time @@ -68,7 +100,6 @@ class MenuBar(): self.sun_value = sun_value self.card_offset_x = 32 self.setupCards(card_list) - self.font = pg.font.SysFont(None, 20) def loadFrame(self, name): frame = tool.GFX[name] @@ -135,21 +166,9 @@ class MenuBar(): break def drawSunValue(self): - width = 32 - msg_image = self.font.render(str(self.sun_value), True, c.NAVYBLUE, c.LIGHTYELLOW) - msg_rect = msg_image.get_rect() - msg_w = msg_rect.width - - image = pg.Surface([width, 17]) - x = width - msg_w - - image.fill(c.LIGHTYELLOW) - image.blit(msg_image, (x, 0), (0, 0, msg_rect.w, msg_rect.h)) - image.set_colorkey(c.BLACK) - - self.value_image = image + self.value_image = getSunValueImage(self.sun_value) self.value_rect = self.value_image.get_rect() - self.value_rect.x = 18 + self.value_rect.x = 21 self.value_rect.y = self.rect.bottom - 21 self.image.blit(self.value_image, self.value_rect) @@ -158,4 +177,111 @@ class MenuBar(): self.drawSunValue() surface.blit(self.image, self.rect) for card in self.card_list: - card.draw(surface) \ No newline at end of file + card.draw(surface) + +class Panel(): + def __init__(self, card_list, sun_value): + self.loadImages(sun_value) + self.selected_cards = [] + self.selected_num = 0 + self.setupCards(card_list) + + def loadFrame(self, name): + frame = tool.GFX[name] + rect = frame.get_rect() + frame_rect = (rect.x, rect.y, rect.w, rect.h) + + return tool.get_image(tool.GFX[name], *frame_rect, c.WHITE, 1) + + def loadImages(self, sun_value): + self.menu_image = self.loadFrame(c.MENUBAR_BACKGROUND) + self.menu_rect = self.menu_image.get_rect() + self.menu_rect.x = 0 + self.menu_rect.y = 0 + + self.panel_image = self.loadFrame(c.PANEL_BACKGROUND) + self.panel_rect = self.panel_image.get_rect() + self.panel_rect.x = 0 + self.panel_rect.y = PANEL_Y_START + + + self.value_image = getSunValueImage(sun_value) + self.value_rect = self.value_image.get_rect() + self.value_rect.x = 21 + self.value_rect.y = self.menu_rect.bottom - 21 + + self.button_image = self.loadFrame(c.START_BUTTON) + self.button_rect = self.button_image.get_rect() + self.button_rect.x = 155 + self.button_rect.y = 547 + + def setupCards(self, card_list): + self.card_list = [] + x = PANEL_X_START - PANEL_X_INTERNAL + y = PANEL_Y_START + 43 - PANEL_Y_INTERNAL + for i, index in enumerate(card_list): + if i % 8 == 0: + x = PANEL_X_START - PANEL_X_INTERNAL + y += PANEL_Y_INTERNAL + x += PANEL_X_INTERNAL + self.card_list.append(Card(x, y, index, 0.75)) + + def checkCardClick(self, mouse_pos): + delete_card = None + for card in self.selected_cards: + if delete_card: # when delete a card, move right cards to left + card.rect.x -= 55 + elif card.checkMouseClick(mouse_pos): + self.deleteCard(card.name_index) + delete_card = card + + if delete_card: + self.selected_cards.remove(delete_card) + self.selected_num -= 1 + + if self.selected_num == CARD_LIST_NUM: + return + + for card in self.card_list: + if card.checkMouseClick(mouse_pos): + if card.canSelect(): + self.addCard(card) + break + + def addCard(self, card): + card.setSelect(False) + y = 8 + x = 78 + self.selected_num * 55 + self.selected_cards.append(Card(x, y, card.name_index)) + self.selected_num += 1 + + def deleteCard(self, index): + self.card_list[index].setSelect(True) + + def checkStartButtonClick(self, mouse_pos): + if self.selected_num < CARD_LIST_NUM: + return False + + x, y = mouse_pos + if (x >= self.button_rect.x and x <= self.button_rect.right and + y >= self.button_rect.y and y <= self.button_rect.bottom): + return True + return False + + def getSelectedCards(self): + card_index_list = [] + for card in self.selected_cards: + card_index_list.append(card.name_index) + return card_index_list + + def draw(self, surface): + self.menu_image.blit(self.value_image, self.value_rect) + surface.blit(self.menu_image, self.menu_rect) + surface.blit(self.panel_image, self.panel_rect) + for card in self.card_list: + card.draw(surface) + for card in self.selected_cards: + card.draw(surface) + + if self.selected_num == CARD_LIST_NUM: + surface.blit(self.button_image, self.button_rect) \ No newline at end of file diff --git a/source/constants.py b/source/constants.py index 850dab7..b55b9a6 100644 --- a/source/constants.py +++ b/source/constants.py @@ -57,6 +57,8 @@ MAP_OFFSET_Y = 100 #MENUBAR MENUBAR_BACKGROUND = 'ChooserBackground' +PANEL_BACKGROUND = 'PanelBackground' +START_BUTTON = 'StartButton' #PLANT INFO PLANT_IMAGE_RECT = 'plant_image_rect' @@ -140,3 +142,6 @@ DIGEST = 'digest' WALK = 'walk' DIE = 'die' +#LEVEL STATE +CHOOSE = 'choose' +PLAY = 'play' diff --git a/source/state/level.py b/source/state/level.py index 855484c..0e67dc7 100644 --- a/source/state/level.py +++ b/source/state/level.py @@ -19,21 +19,10 @@ class Level(tool.State): self.map = map.Map(c.GRID_X_LEN, self.map_y_len) self.loadMap() - - self.menubar = menubar.MenuBar(menubar.card_list, self.map_data[c.INIT_SUN_NAME]) - self.drag_plant = False - self.hint_image = None - self.hint_plant = False - - self.produce_sun = True - self.sun_timer = current_time - - self.removeMouseImage() + self.state = c.CHOOSE + self.initChoose() self.setupBackground() - self.setupGroups() - self.setupZombies() - self.setupCars() - + def loadMap(self): map_file = 'level_' + str(self.game_info[c.LEVEL_NUM]) + '.json' file_path = os.path.join('source', 'data', 'map', map_file) @@ -80,7 +69,37 @@ class Level(tool.State): def update(self, surface, current_time, mouse_pos, mouse_click): self.current_time = self.game_info[c.CURRENT_TIME] = current_time - + if self.state == c.CHOOSE: + self.choose(mouse_pos, mouse_click) + elif self.state == c.PLAY: + self.play(mouse_pos, mouse_click) + + self.draw(surface) + + def initChoose(self): + self.panel = menubar.Panel(menubar.all_card_list, self.map_data[c.INIT_SUN_NAME]) + + def choose(self, mouse_pos, mouse_click): + if mouse_pos and mouse_click[0]: + self.panel.checkCardClick(mouse_pos) + if self.panel.checkStartButtonClick(mouse_pos): + self.state = c.PLAY + self.initPlay(self.panel.getSelectedCards()) + + def initPlay(self, card_list): + self.menubar = menubar.MenuBar(card_list, self.map_data[c.INIT_SUN_NAME]) + self.drag_plant = False + self.hint_image = None + self.hint_plant = False + self.produce_sun = True + self.sun_timer = self.current_time + + self.removeMouseImage() + self.setupGroups() + self.setupZombies() + self.setupCars() + + def play(self, mouse_pos, mouse_click): if self.zombie_start_time == 0: self.zombie_start_time = self.current_time elif len(self.zombie_list) > 0: @@ -132,8 +151,7 @@ class Level(tool.State): self.checkPlants() self.checkCarCollisions() self.checkGameState() - self.draw(surface) - + def createZombie(self, name, map_y): x, y = self.map.getMapGridPos(0, map_y) if name == c.NORMAL_ZOMBIE: @@ -370,15 +388,18 @@ class Level(tool.State): def draw(self, surface): self.level.blit(self.background, self.viewport, self.viewport) surface.blit(self.level, (0,0), self.viewport) - self.menubar.draw(surface) - for i in range(self.map_y_len): - self.plant_groups[i].draw(surface) - self.zombie_groups[i].draw(surface) - self.bullet_groups[i].draw(surface) - for car in self.cars: - car.draw(surface) - self.head_group.draw(surface) - self.sun_group.draw(surface) + if self.state == c.CHOOSE: + self.panel.draw(surface) + elif self.state == c.PLAY: + self.menubar.draw(surface) + for i in range(self.map_y_len): + self.plant_groups[i].draw(surface) + self.zombie_groups[i].draw(surface) + self.bullet_groups[i].draw(surface) + for car in self.cars: + car.draw(surface) + self.head_group.draw(surface) + self.sun_group.draw(surface) - if self.drag_plant: - self.drawMouseShow(surface) \ No newline at end of file + if self.drag_plant: + self.drawMouseShow(surface) \ No newline at end of file