Ignore:
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • nagslang/enemies.py

    r229 r235  
    99from nagslang.mutators import FLIP_H
    1010from nagslang.resources import resources
     11
     12
     13def get_editable_enemies():
     14    classes = []
     15    for cls_name, cls in globals().iteritems():
     16        if isinstance(cls, type) and issubclass(cls, Enemy):
     17            if hasattr(cls, 'requires'):
     18                classes.append((cls_name, cls))
     19    return classes
    1120
    1221
     
    3342    def attack(self):
    3443        raise NotImplementedError
     44
     45    @classmethod
     46    def requires(cls):
     47        return [("name", "string"), ("position", "coordinates")]
    3548
    3649
     
    113126        self.set_direction(x_step, y_step)
    114127        super(PatrollingAlien, self).animate()
     128
     129    @classmethod
     130    def requires(cls):
     131        return [("name", "string"), ("position", "coordinates"),
     132                ("end_position", "coordinates")]
  • nagslang/engine.py

    r180 r238  
    88from nagslang.screens.area import AreaScreen
    99from nagslang.events import ScreenChange
     10from nagslang.world import World
    1011
    1112
     
    1617        self._fps = constants.FPS
    1718        self._dt = 1. / self._fps
    18         self._world = None  # TODO: create the world
     19        self._world = World()
    1920        self._current_screen = None
    2021        self._screens = {
  • nagslang/game_object.py

    r229 r235  
    99from nagslang.resources import resources
    1010from nagslang.events import DoorEvent
     11
     12
     13def get_editable_game_objects():
     14    classes = []
     15    for cls_name, cls in globals().iteritems():
     16        if isinstance(cls, type) and hasattr(cls, 'requires'):
     17            classes.append((cls_name, cls))
     18    return classes
    1119
    1220
     
    137145        return True
    138146
     147    @classmethod
     148    def requires(cls):
     149        """Hints for the level editor"""
     150        return [("name", "string")]
     151
    139152
    140153class FloorSwitch(GameObject):
     
    155168        )
    156169
     170    @classmethod
     171    def requires(cls):
     172        return [("name", "string"), ("position", "coordinates")]
     173
    157174
    158175class Note(GameObject):
     
    169186            render.TextOverlay(message),
    170187        )
     188
     189    @classmethod
     190    def requires(cls):
     191        return [("name", "string"), ("position", "coordinates"),
     192                ("message", "text")]
    171193
    172194
     
    187209            puzzle.StateProxyPuzzler(state_source),
    188210        )
     211
     212    @classmethod
     213    def requires(cls):
     214        return [("name", "string"), ("position", "coordinates"),
     215                ("state_source", "puzzler")]
    189216
    190217
     
    201228        )
    202229
     230    @classmethod
     231    def requires(cls):
     232        return [("name", "string"), ("position", "coordinates"),
     233                ("state_source", "puzzler")]
     234
    203235
    204236class Door(GameObject):
     
    226258        if self.puzzler.get_state():
    227259            DoorEvent.post(self.destination, self.dest_pos)
     260
     261    @classmethod
     262    def requires(cls):
     263        return [("name", "string"), ("position", "coordinates"),
     264                ("destination", "level name"), ("dest_pos", "coordinate"),
     265                ("key_state", "puzzler")]
    228266
    229267
     
    250288            return False
    251289        return True
     290
     291    @classmethod
     292    def requires(cls):
     293        return [("name", "string"), ("end1", "coordinates"),
     294                ("end2", "coordinates"), ("key_state", "puzzler")]
  • nagslang/puzzle.py

    r201 r235  
    11from nagslang.constants import COLLISION_TYPE_PLAYER
     2
     3
     4def get_editable_puzzlers():
     5    classes = []
     6    for cls_name, cls in globals().iteritems():
     7        if isinstance(cls, type) and hasattr(cls, 'requires'):
     8            classes.append((cls_name, cls))
     9    return classes
    210
    311
     
    3038        raise NotImplementedError()
    3139
     40    @classmethod
     41    def requires(cls):
     42        """Tell the level editor the arguments we require
     43
     44           Format is a list of name: type hint tuples"""
     45        return [("name", "string")]
     46
    3247
    3348class YesPuzzler(Puzzler):
     
    5873        return False
    5974
     75    @classmethod
     76    def requires(cls):
     77        return [("name", "string"), ("collision_types", "list of ints")]
     78
    6079
    6180class StateProxyPuzzler(Puzzler):
     
    6584    def get_state(self):
    6685        return self.glue.get_state_of(self._state_source)
     86
     87    @classmethod
     88    def requires(cls):
     89        return [("name", "string"), ("sources", "list of names")]
    6790
    6891
     
    7699                return False
    77100        return True
     101
     102    @classmethod
     103    def requires(cls):
     104        return [("name", "string"), ("sources", "list of names")]
  • nagslang/screens/area.py

    r243 r244  
    127127            if ev.key == pygame.locals.K_c:
    128128                self.protagonist.toggle_form()
     129                self.world.transformations += 1
    129130        elif DoorEvent.matches(ev):
    130131            self.protagonist.set_position(ev.dest_pos)
     
    132133                # Go to anther screen
    133134                self._disable_render = True
     135                self.world.rooms += 1
    134136                ScreenChange.post(ev.destination, self.protagonist)
    135137                return
  • nagslang/screens/menu.py

    r226 r238  
    55from nagslang.screens.base import Screen
    66from nagslang.events import QuitEvent, ScreenChange
    7 from nagslang.widgets.text import TextWidget
     7from nagslang.widgets.text import TextWidget, MultiLineWidget
    88
    99
     
    2424            TextWidget((40, 70), 'Restore saved game'),
    2525            TextWidget((40, 90), 'Quit'),
     26            MultiLineWidget((60, 120), self.world.get_formatted_stats()),
    2627            self.cursor,
    2728        ]
  • nagslang/widgets/text.py

    r196 r237  
     1from nagslang.constants import FONT, FONT_SIZE
     2from nagslang.widgets.base import Widget
    13import pygame
    24
    3 from nagslang.constants import FONT, FONT_SIZE
    4 from nagslang.widgets.base import Widget
    55from nagslang.utils import convert_colour
    66from nagslang.resources import resources
     
    3232
    3333
     34class MultiLineWidget(TextWidget):
     35
     36    def prepare(self):
     37        self.font = resources.get_font(self.fontname, self.fontsize)
     38        surfaces = []
     39        height = 0
     40        width = 0
     41        for line in self.text.split('\n'):
     42            surface = self.font.render(line, True, self.colour)
     43            width = max(width, surface.get_rect().width)
     44            height += surface.get_rect().height
     45            surfaces.append(surface)
     46        self.surface = pygame.surface.Surface((width, height))
     47        self.surface.fill(pygame.Color('white'))
     48        y = 0
     49        for surface in surfaces:
     50            self.surface.blit(surface, (0, y))
     51            y += surface.get_rect().height
     52
     53
    3454class LabelWidget(TextWidget):
    3555    def __init__(self, *args, **kwargs):
  • tools/area_editor.py

    r225 r236  
    3232from nagslang.constants import SCREEN
    3333from nagslang.level import Level, POLY_COLORS, LINE_COLOR
    34 from nagslang.enemies import Enemy
    35 
     34from nagslang.enemies import Enemy, get_editable_enemies
     35from nagslang.game_object import get_editable_game_objects
     36from nagslang.puzzle import get_editable_puzzlers
    3637
    3738# layout constants
     
    378379        row.rect = pygame.rect.Rect(0, 450, 700, 50)
    379380        edit_box.add(row)
     381        edit_box.get_selection = lambda: table.get_selection()
    380382        return edit_box
    381383
     
    383385        edit_box = self._make_edit_dialog(self.level._game_objects)
    384386        res = edit_box.present()
     387        choice = edit_box.get_selection()
     388        if choice is None:
     389            return
    385390        if res == 'OK':
    386391            # Edit object stuff goes here
     
    392397        edit_box = self._make_edit_dialog(self.level._enemies)
    393398        res = edit_box.present()
     399        choice = edit_box.get_selection()
     400        if choice is None:
     401            return
    394402        if res == 'OK':
    395403            # Edit object stuff goes here
    396404            pass
    397405        elif res == 'Delete':
     406            pass
     407
     408    def _make_choice_dialog(self, classes):
     409        # Dialog to hold the editor
     410        data = []
     411        for cls_name, cls in classes:
     412            data.append({"classname": cls_name, "class": cls})
     413        edit_box = Dialog()
     414        edit_box.rect = pygame.rect.Rect(0, 0, 700, 500)
     415        table = ObjectTable(data)
     416        edit_box.add(table)
     417        buttons = []
     418        for text in ['OK', 'Cancel']:
     419            but = Button(text, action=lambda x=text: edit_box.dismiss(x))
     420            buttons.append(but)
     421        row = Row(buttons)
     422        row.rect = pygame.rect.Rect(0, 450, 700, 50)
     423        edit_box.add(row)
     424        edit_box.get_selection = lambda: table.get_selection()
     425        return edit_box
     426
     427    def add_game_object(self):
     428        classes = get_editable_game_objects()
     429        choose = self._make_choice_dialog(classes)
     430        res = choose.present()
     431        choice = choose.get_selection()
     432        if res == 'OK' and choice is not None:
     433            pass
     434
     435    def add_enemy(self):
     436        classes = get_editable_enemies()
     437        choose = self._make_choice_dialog(classes)
     438        res = choose.present()
     439        choice = choose.get_selection()
     440        if res == 'OK' and choice is not None:
     441            pass
     442
     443    def add_puzzler(self):
     444        classes = get_editable_puzzlers()
     445        choose = self._make_choice_dialog(classes)
     446        res = choose.present()
     447        choice = choose.get_selection()
     448        if res == 'OK' and choice is not None:
    398449            pass
    399450
     
    466517        y += MENU_BUTTON_HEIGHT + MENU_PAD
    467518
    468         save_but = Button('Save Level', action=self.save)
    469         save_but.rect = BUTTON_RECT.copy()
    470         save_but.rect.move_ip(MENU_LEFT, y)
    471         widgets.append(save_but)
    472         y += MENU_BUTTON_HEIGHT + MENU_PAD
    473 
    474519        close_poly_but = Button('Close Polygon',
    475520                                action=self.level_widget.close_poly)
     
    498543        y += label.rect.height + MENU_PAD
    499544
     545        y += MENU_PAD
    500546        switch_but = Button('Switch to Objects', action=self.switch_to_objects)
    501547        switch_but.rect = BUTTON_RECT.copy()
     
    504550        y += switch_but.rect.height + MENU_PAD
    505551
     552        save_but = Button('Save Level', action=self.save)
     553        save_but.rect = BUTTON_RECT.copy()
     554        save_but.rect.move_ip(MENU_LEFT, y)
     555        widgets.append(save_but)
     556        y += MENU_BUTTON_HEIGHT + MENU_PAD
     557
     558        y += MENU_PAD
    506559        quit_but = Button('Quit', action=self.quit)
    507560        quit_but.rect = BUTTON_RECT.copy()
     
    531584        y += MENU_BUTTON_HEIGHT + MENU_PAD
    532585
    533         save_but = Button('Save Level', action=self.save)
    534         save_but.rect = BUTTON_RECT.copy()
    535         save_but.rect.move_ip(MENU_LEFT, y)
    536         widgets.append(save_but)
    537         y += MENU_BUTTON_HEIGHT + MENU_PAD
    538 
     586        add_obj_but = Button('Add Game Object',
     587                             action=self.level_widget.add_game_object)
     588        add_obj_but.rect = BUTTON_RECT.copy()
     589        add_obj_but.rect.move_ip(MENU_LEFT, y)
     590        widgets.append(add_obj_but)
     591        y += MENU_BUTTON_HEIGHT + MENU_PAD
     592
     593        add_puzzle_but = Button('Add Puzzler',
     594                                action=self.level_widget.add_puzzler)
     595        add_puzzle_but.rect = BUTTON_RECT.copy()
     596        add_puzzle_but.rect.move_ip(MENU_LEFT, y)
     597        widgets.append(add_puzzle_but)
     598        y += MENU_BUTTON_HEIGHT + MENU_PAD
     599
     600        add_enemy_but = Button('Add Enemy',
     601                               action=self.level_widget.add_enemy)
     602        add_enemy_but.rect = BUTTON_RECT.copy()
     603        add_enemy_but.rect.move_ip(MENU_LEFT, y)
     604        widgets.append(add_enemy_but)
     605        y += MENU_BUTTON_HEIGHT + MENU_PAD
     606
     607        y += MENU_PAD
    539608        switch_but = Button('Switch to Drawing', action=self.switch_to_draw)
    540609        switch_but.rect = BUTTON_RECT.copy()
     
    543612        y += switch_but.rect.height + MENU_PAD
    544613
     614        save_but = Button('Save Level', action=self.save)
     615        save_but.rect = BUTTON_RECT.copy()
     616        save_but.rect.move_ip(MENU_LEFT, y)
     617        widgets.append(save_but)
     618        y += MENU_BUTTON_HEIGHT + MENU_PAD
     619
     620        y += MENU_PAD
    545621        quit_but = Button('Quit', action=self.quit)
    546622        quit_but.rect = BUTTON_RECT.copy()
Note: See TracChangeset for help on using the changeset viewer.