rapid-router 5.4.1__py2.py3-none-any.whl → 7.6.8__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- example_project/rapid_router_test_settings.py +164 -0
- example_project/settings.py +152 -0
- example_project/urls.py +15 -0
- example_project/{example_project/wsgi.py → wsgi.py} +2 -1
- game/__init__.py +1 -1
- game/admin.py +43 -4
- game/app_settings.py +3 -7
- game/character.py +26 -18
- game/decor.py +172 -97
- game/end_to_end_tests/base_game_test.py +44 -33
- game/end_to_end_tests/editor_page.py +17 -2
- game/end_to_end_tests/game_page.py +127 -45
- game/end_to_end_tests/selenium_test_case.py +1 -20
- game/end_to_end_tests/test_cow_crashes.py +3 -5
- game/end_to_end_tests/test_language_dropdown.py +14 -0
- game/end_to_end_tests/test_level_editor.py +290 -0
- game/end_to_end_tests/test_level_failures.py +1 -1
- game/end_to_end_tests/test_level_selection.py +79 -0
- game/end_to_end_tests/test_play_through.py +240 -102
- game/end_to_end_tests/test_python_levels.py +44 -13
- game/end_to_end_tests/test_saving_workspace.py +22 -0
- game/forms.py +9 -2
- game/level_management.py +38 -29
- game/messages.py +1218 -203
- game/migrations/0001_squashed_0025_levels_ordering_pt1.py +19 -1
- game/migrations/0026_levels_pt2.py +13 -2
- game/migrations/0032_cannot_turn_left_level.py +13 -2
- game/migrations/0033_recursion_level.py +13 -2
- game/migrations/0034_joes_level.py +13 -2
- game/migrations/0035_disable_route_score_level_70.py +0 -2
- game/migrations/0036_level_score_73.py +0 -2
- game/migrations/0037_level_score_79.py +0 -2
- game/migrations/0038_level_score_40.py +0 -1
- game/migrations/0042_level_score_73.py +0 -2
- game/migrations/0048_add_cow_field_and_blocks.py +0 -2
- game/migrations/0049_level_score_34.py +0 -2
- game/migrations/0050_level_score_40.py +0 -2
- game/migrations/0051_level_score_49.py +0 -1
- game/migrations/0076_level_locked_for_class.py +19 -0
- game/migrations/0077_alter_level_next_level.py +52 -0
- game/migrations/0078_add_block_types.py +23 -0
- game/migrations/0079_populate_block_type_add_cow_blocks.py +60 -0
- game/migrations/0080_level_disable_algorithm_score.py +18 -0
- game/migrations/0081_first_12_levels_no_algo_score.py +29 -0
- game/migrations/0082_level_43_solution.py +16 -0
- game/migrations/0083_add_cows_to_existing_levels.py +195 -0
- game/migrations/0084_alter_block_block_type.py +18 -0
- game/migrations/0085_add_new_blocks.py +53 -0
- game/migrations/0086_loop_levels.py +482 -0
- game/migrations/0087_workspace_python_view_enabled.py +18 -0
- game/migrations/0088_rename_episodes.py +35 -0
- game/migrations/0089_episodes_in_development.py +30 -0
- game/migrations/0090_add_missing_model_solutions.py +144 -0
- game/migrations/0091_disable_algo_score_if_no_model_solution.py +46 -0
- game/migrations/0092_disable_algo_score_in_custom_levels.py +28 -0
- game/migrations/0093_alter_level_character_name.py +18 -0
- game/migrations/0094_add_hint_lesson_subtitle_to_levels.py +28 -0
- game/migrations/0095_level_commands.py +18 -0
- game/migrations/0096_alter_level_commands.py +18 -0
- game/migrations/0097_add_python_den_levels.py +1515 -0
- game/migrations/0098_add_episode_link_fields.py +44 -0
- game/migrations/0099_python_episodes_links.py +103 -0
- game/migrations/0100_reorder_python_levels.py +179 -0
- game/migrations/0101_rename_episodes.py +45 -0
- game/migrations/0102_reoder_episodes_13_14.py +136 -0
- game/migrations/0103_level_1015_solution.py +26 -0
- game/migrations/0104_remove_level_direct_drive.py +17 -0
- game/migrations/0105_delete_invalid_attempts.py +18 -0
- game/migrations/0106_fields_to_snake_case.py +48 -0
- game/migrations/0107_rename_worksheet_link_episode_student_worksheet_link.py +18 -0
- game/migrations/0108_episode_indy_worksheet_link.py +18 -0
- game/migrations/0109_create_episodes_23_and_24.py +99 -0
- game/migrations/0110_remove_episode_indy_worksheet_link_and_more.py +100 -0
- game/migrations/0111_create_worksheets.py +149 -0
- game/migrations/0112_worksheet_locked_classes.py +21 -0
- game/migrations/0113_level_needs_approval.py +18 -0
- game/migrations/0114_default_and_non_student_levels_no_approval.py +31 -0
- game/migrations/0115_level_level__default_does_not_need_approval.py +22 -0
- game/migrations/0116_update_worksheet_video_links.py +68 -0
- game/migrations/0117_update_solutions_to_if_else.py +61 -0
- game/models.py +157 -16
- game/permissions.py +34 -19
- game/python_den_urls.py +26 -0
- game/random_road.py +43 -127
- game/serializers.py +12 -17
- game/static/django_reverse_js/js/reverse.js +171 -0
- game/static/game/css/LilitaOne-Regular.ttf +0 -0
- game/static/game/css/backgrounds.css +14 -10
- game/static/game/css/dataTables.custom.css +4 -2
- game/static/game/css/dataTables.jqueryui.css +561 -320
- game/static/game/css/editor.css +47 -0
- game/static/game/css/game.css +43 -49
- game/static/game/css/game_screen.css +116 -53
- game/static/game/css/jquery.dataTables.css +455 -251
- game/static/game/css/level_editor.css +10 -1
- game/static/game/css/level_selection.css +32 -3
- game/static/game/css/level_share.css +6 -5
- game/static/game/css/skulpt/codemirror.css +1 -0
- game/static/game/image/Python_Den_hero_student.png +0 -0
- game/static/game/image/Python_levels_page.svg +1954 -0
- game/static/game/image/characters/front_view/Electric_van.svg +448 -0
- game/static/game/image/characters/top_view/Electric_van.svg +448 -0
- game/static/game/image/characters/top_view/Sleigh.svg +436 -0
- game/static/game/image/decor/city/solar_panel.svg +1200 -0
- game/static/game/image/decor/farm/solar_panel.svg +86 -0
- game/static/game/image/decor/grass/solar_panel.svg +86 -0
- game/static/game/image/decor/snow/barn.svg +1788 -0
- game/static/game/image/decor/snow/cfc.svg +1050 -147
- game/static/game/image/decor/snow/crops.svg +7370 -0
- game/static/game/image/decor/snow/hospital.svg +1220 -0
- game/static/game/image/decor/snow/house1.svg +971 -0
- game/static/game/image/decor/snow/house2.svg +1574 -0
- game/static/game/image/decor/snow/school.svg +1071 -0
- game/static/game/image/decor/snow/shop.svg +3211 -0
- game/static/game/image/decor/snow/solar_panel.svg +173 -0
- game/static/game/image/electric_van.svg +448 -0
- game/static/game/image/icons/add_house.svg +26 -0
- game/static/game/image/icons/delete_house.svg +26 -0
- game/static/game/image/icons/description.svg +1 -0
- game/static/game/image/icons/hint.svg +1 -0
- game/static/game/image/icons/if_else.svg +3 -0
- game/static/game/image/icons/python.svg +1 -1
- game/static/game/image/if_else_example.png +0 -0
- game/static/game/image/pigeon.svg +684 -0
- game/static/game/image/python_den_header.svg +19 -0
- game/static/game/js/animation.js +84 -28
- game/static/game/js/blockly/msg/js/bg.js +52 -1
- game/static/game/js/blockly/msg/js/ca.js +52 -1
- game/static/game/js/blockly/msg/js/en-gb.js +52 -1
- game/static/game/js/blockly/msg/js/en.js +52 -1
- game/static/game/js/blockly/msg/js/es.js +52 -1
- game/static/game/js/blockly/msg/js/fr.js +52 -1
- game/static/game/js/blockly/msg/js/hi.js +52 -1
- game/static/game/js/blockly/msg/js/it.js +52 -1
- game/static/game/js/blockly/msg/js/pl.js +52 -1
- game/static/game/js/blockly/msg/js/pt-br.js +52 -1
- game/static/game/js/blockly/msg/js/ru.js +52 -1
- game/static/game/js/blockly/msg/js/ur.js +52 -1
- game/static/game/js/blocklyCompiler.js +550 -392
- game/static/game/js/blocklyControl.js +335 -302
- game/static/game/js/blocklyCustomBlocks.js +691 -458
- game/static/game/js/blocklyCustomisations.js +3 -1
- game/static/game/js/button.js +12 -0
- game/static/game/js/cow.js +15 -130
- game/static/game/js/drawing.js +313 -201
- game/static/game/js/editor.js +23 -0
- game/static/game/js/game.js +148 -139
- game/static/game/js/jquery.dataTables.min.js +3 -159
- game/static/game/js/level_editor.js +823 -448
- game/static/game/js/level_moderation.js +33 -2
- game/static/game/js/level_selection.js +62 -25
- game/static/game/js/loadLanguages.js +21 -0
- game/static/game/js/map.js +106 -36
- game/static/game/js/model.js +55 -107
- game/static/game/js/pathFinder.js +73 -72
- game/static/game/js/program.js +184 -193
- game/static/game/js/pythonControl.js +14 -1
- game/static/game/js/scoreboard.js +0 -37
- game/static/game/js/scoreboardSharedLevels.js +48 -0
- game/static/game/js/sharing.js +22 -10
- game/static/game/js/skulpt/codemirror.js +5 -4
- game/static/game/js/skulpt/skulpt-stdlib.js +1 -1
- game/static/game/js/sound.js +52 -5
- game/static/game/js/van.js +0 -7
- game/static/game/raphael_image/characters/top_view/Electric_van.svg +448 -0
- game/static/game/raphael_image/characters/top_view/Sleigh.svg +436 -0
- game/static/game/raphael_image/decor/city/solar_panel.svg +1200 -0
- game/static/game/raphael_image/decor/farm/solar_panel.svg +86 -0
- game/static/game/raphael_image/decor/grass/solar_panel.svg +86 -0
- game/static/game/raphael_image/decor/snow/barn.svg +1788 -0
- game/static/game/raphael_image/decor/snow/cfc.svg +1050 -147
- game/static/game/raphael_image/decor/snow/crops.svg +7370 -0
- game/static/game/raphael_image/decor/snow/hospital.svg +1220 -0
- game/static/game/raphael_image/decor/snow/house1.svg +971 -0
- game/static/game/raphael_image/decor/snow/house2.svg +1574 -0
- game/static/game/raphael_image/decor/snow/school.svg +1071 -0
- game/static/game/raphael_image/decor/snow/shop.svg +3211 -0
- game/static/game/raphael_image/decor/snow/solar_panel.svg +173 -0
- game/static/game/raphael_image/pigeon.svg +685 -0
- game/static/game/raphael_image/sleigh_wreckage.svg +430 -0
- game/static/game/sass/game.scss +22 -6
- game/static/game/sound/clown_horn.mp3 +0 -0
- game/static/game/sound/clown_horn.ogg +0 -0
- game/static/game/sound/electric_van_starting.mp3 +0 -0
- game/static/game/sound/electric_van_starting.ogg +0 -0
- game/static/game/sound/pigeon.mp3 +0 -0
- game/static/game/sound/pigeon.ogg +0 -0
- game/static/game/sound/sleigh_bells.mp3 +0 -0
- game/static/game/sound/sleigh_bells.ogg +0 -0
- game/static/game/sound/sleigh_crash.mp3 +0 -0
- game/static/game/sound/sleigh_crash.ogg +0 -0
- game/templates/game/base.html +35 -15
- game/templates/game/basenonav.html +23 -17
- game/templates/game/game.html +236 -111
- game/templates/game/level_editor.html +353 -275
- game/templates/game/level_moderation.html +19 -6
- game/templates/game/level_selection.html +75 -62
- game/templates/game/python_den_level_selection.html +291 -0
- game/templates/game/python_den_worksheet.html +101 -0
- game/templates/game/scoreboard.html +88 -65
- game/tests/test_level_editor.py +210 -35
- game/tests/test_level_moderation.py +6 -20
- game/tests/test_level_selection.py +332 -11
- game/tests/test_python_den_worksheet.py +85 -0
- game/tests/test_scoreboard.py +258 -66
- game/tests/utils/level.py +43 -3
- game/tests/utils/teacher.py +2 -2
- game/theme.py +21 -21
- game/urls.py +125 -78
- game/views/language_code_conversions.py +90 -0
- game/views/level.py +201 -63
- game/views/level_editor.py +109 -48
- game/views/level_moderation.py +29 -6
- game/views/level_selection.py +179 -56
- game/views/level_solutions.py +600 -106
- game/views/scoreboard.py +181 -66
- game/views/worksheet.py +25 -0
- rapid_router-7.6.8.dist-info/METADATA +174 -0
- {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/RECORD +222 -242
- {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/WHEEL +1 -1
- rapid_router-7.6.8.dist-info/licenses/LICENSE.md +3 -0
- example_project/example_project/__init__.py +0 -1
- example_project/example_project/settings.py +0 -54
- example_project/example_project/urls.py +0 -16
- example_project/manage.py +0 -10
- game/autoconfig.py +0 -59
- game/csp_config.py +0 -23
- game/locale/ar_SA/LC_MESSAGES/django.mo +0 -0
- game/locale/ar_SA/LC_MESSAGES/django.po +0 -405
- game/locale/ar_SA/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ar_SA/LC_MESSAGES/djangojs.po +0 -743
- game/locale/bg_BG/LC_MESSAGES/django.mo +0 -0
- game/locale/bg_BG/LC_MESSAGES/django.po +0 -405
- game/locale/bg_BG/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/bg_BG/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ca_ES/LC_MESSAGES/django.mo +0 -0
- game/locale/ca_ES/LC_MESSAGES/django.po +0 -405
- game/locale/ca_ES/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ca_ES/LC_MESSAGES/djangojs.po +0 -740
- game/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- game/locale/cs_CZ/LC_MESSAGES/django.po +0 -405
- game/locale/cs_CZ/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/cs_CZ/LC_MESSAGES/djangojs.po +0 -741
- game/locale/cy_GB/LC_MESSAGES/django.mo +0 -0
- game/locale/cy_GB/LC_MESSAGES/django.po +0 -405
- game/locale/cy_GB/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/cy_GB/LC_MESSAGES/djangojs.po +0 -743
- game/locale/de_DE/LC_MESSAGES/django.mo +0 -0
- game/locale/de_DE/LC_MESSAGES/django.po +0 -405
- game/locale/de_DE/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/de_DE/LC_MESSAGES/djangojs.po +0 -739
- game/locale/el_GR/LC_MESSAGES/django.mo +0 -0
- game/locale/el_GR/LC_MESSAGES/django.po +0 -405
- game/locale/el_GR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/el_GR/LC_MESSAGES/djangojs.po +0 -739
- game/locale/en_GB/LC_MESSAGES/django.mo +0 -0
- game/locale/en_GB/LC_MESSAGES/django.po +0 -405
- game/locale/en_GB/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/en_GB/LC_MESSAGES/djangojs.po +0 -739
- game/locale/es_ES/LC_MESSAGES/django.mo +0 -0
- game/locale/es_ES/LC_MESSAGES/django.po +0 -405
- game/locale/es_ES/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/es_ES/LC_MESSAGES/djangojs.po +0 -739
- game/locale/fi_FI/LC_MESSAGES/django.mo +0 -0
- game/locale/fi_FI/LC_MESSAGES/django.po +0 -405
- game/locale/fi_FI/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/fi_FI/LC_MESSAGES/djangojs.po +0 -739
- game/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
- game/locale/fr_FR/LC_MESSAGES/django.po +0 -405
- game/locale/fr_FR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/fr_FR/LC_MESSAGES/djangojs.po +0 -739
- game/locale/gu_IN/LC_MESSAGES/django.mo +0 -0
- game/locale/gu_IN/LC_MESSAGES/django.po +0 -405
- game/locale/gu_IN/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/gu_IN/LC_MESSAGES/djangojs.po +0 -739
- game/locale/hi_IN/LC_MESSAGES/django.mo +0 -0
- game/locale/hi_IN/LC_MESSAGES/django.po +0 -405
- game/locale/hi_IN/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/hi_IN/LC_MESSAGES/djangojs.po +0 -739
- game/locale/id_ID/LC_MESSAGES/django.mo +0 -0
- game/locale/id_ID/LC_MESSAGES/django.po +0 -405
- game/locale/id_ID/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/id_ID/LC_MESSAGES/djangojs.po +0 -738
- game/locale/it_IT/LC_MESSAGES/django.mo +0 -0
- game/locale/it_IT/LC_MESSAGES/django.po +0 -405
- game/locale/it_IT/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/it_IT/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ja_JP/LC_MESSAGES/django.mo +0 -0
- game/locale/ja_JP/LC_MESSAGES/django.po +0 -405
- game/locale/ja_JP/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ja_JP/LC_MESSAGES/djangojs.po +0 -738
- game/locale/lol_US/LC_MESSAGES/django.mo +0 -0
- game/locale/lol_US/LC_MESSAGES/django.po +0 -405
- game/locale/lol_US/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/lol_US/LC_MESSAGES/djangojs.po +0 -739
- game/locale/nb_NO/LC_MESSAGES/django.mo +0 -0
- game/locale/nb_NO/LC_MESSAGES/django.po +0 -405
- game/locale/nb_NO/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/nb_NO/LC_MESSAGES/djangojs.po +0 -739
- game/locale/nl_NL/LC_MESSAGES/django.mo +0 -0
- game/locale/nl_NL/LC_MESSAGES/django.po +0 -405
- game/locale/nl_NL/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/nl_NL/LC_MESSAGES/djangojs.po +0 -739
- game/locale/pl_PL/LC_MESSAGES/django.mo +0 -0
- game/locale/pl_PL/LC_MESSAGES/django.po +0 -405
- game/locale/pl_PL/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/pl_PL/LC_MESSAGES/djangojs.po +0 -741
- game/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- game/locale/pt_BR/LC_MESSAGES/django.po +0 -405
- game/locale/pt_BR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/pt_BR/LC_MESSAGES/djangojs.po +0 -739
- game/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- game/locale/pt_PT/LC_MESSAGES/django.po +0 -405
- game/locale/pt_PT/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/pt_PT/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ro_RO/LC_MESSAGES/django.mo +0 -0
- game/locale/ro_RO/LC_MESSAGES/django.po +0 -405
- game/locale/ro_RO/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ro_RO/LC_MESSAGES/djangojs.po +0 -740
- game/locale/ru_RU/LC_MESSAGES/django.mo +0 -0
- game/locale/ru_RU/LC_MESSAGES/django.po +0 -405
- game/locale/ru_RU/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ru_RU/LC_MESSAGES/djangojs.po +0 -741
- game/locale/sv_SE/LC_MESSAGES/django.mo +0 -0
- game/locale/sv_SE/LC_MESSAGES/django.po +0 -405
- game/locale/sv_SE/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/sv_SE/LC_MESSAGES/djangojs.po +0 -739
- game/locale/tl_PH/LC_MESSAGES/django.mo +0 -0
- game/locale/tl_PH/LC_MESSAGES/django.po +0 -405
- game/locale/tl_PH/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/tl_PH/LC_MESSAGES/djangojs.po +0 -739
- game/locale/tlh_AA/LC_MESSAGES/django.mo +0 -0
- game/locale/tlh_AA/LC_MESSAGES/django.po +0 -405
- game/locale/tlh_AA/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/tlh_AA/LC_MESSAGES/djangojs.po +0 -739
- game/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
- game/locale/tr_TR/LC_MESSAGES/django.po +0 -405
- game/locale/tr_TR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/tr_TR/LC_MESSAGES/djangojs.po +0 -740
- game/locale/ur_IN/LC_MESSAGES/django.mo +0 -0
- game/locale/ur_IN/LC_MESSAGES/django.po +0 -405
- game/locale/ur_IN/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ur_IN/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ur_PK/LC_MESSAGES/django.mo +0 -0
- game/locale/ur_PK/LC_MESSAGES/django.po +0 -405
- game/locale/ur_PK/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ur_PK/LC_MESSAGES/djangojs.po +0 -739
- game/static/game/image/actions/go.svg +0 -18
- game/static/game/image/icons/destination.svg +0 -9
- game/static/game/js/pqselect.min.js +0 -9
- game/static/game/js/widget-scroller.js +0 -906
- rapid_router-5.4.1.dist-info/LICENSE.md +0 -577
- rapid_router-5.4.1.dist-info/METADATA +0 -24
- {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/top_level.txt +0 -0
game/static/game/js/drawing.js
CHANGED
|
@@ -2,67 +2,65 @@
|
|
|
2
2
|
|
|
3
3
|
var ocargo = ocargo || {}
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
let GRID_WIDTH = 10
|
|
6
|
+
let GRID_HEIGHT = 8
|
|
7
7
|
var GRID_SPACE_SIZE = 100
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
let PAPER_WIDTH = GRID_SPACE_SIZE * GRID_WIDTH
|
|
9
|
+
let PAPER_HEIGHT = GRID_SPACE_SIZE * GRID_HEIGHT
|
|
10
|
+
let PAPER_PADDING = 30
|
|
11
|
+
let EXTENDED_PAPER_WIDTH = PAPER_WIDTH + 2 * PAPER_PADDING
|
|
12
|
+
let EXTENDED_PAPER_HEIGHT = PAPER_WIDTH + 2 * PAPER_PADDING
|
|
13
|
+
let SEMI_EXTENDED_PAPER_HEIGHT = PAPER_HEIGHT + 2 * PAPER_PADDING
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
let DEFAULT_CHARACTER_WIDTH = 40
|
|
16
|
+
let DEFAULT_CHARACTER_HEIGHT = 20
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
let COW_WIDTH = 80
|
|
19
|
+
let COW_HEIGHT = 80
|
|
20
|
+
const TRAFFIC_LIGHT_WIDTH = 30
|
|
21
|
+
const TRAFFIC_LIGHT_HEIGHT = 80
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
let zoom = 15
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
var currentWidth = PAPER_WIDTH
|
|
28
|
-
var currentHeight = PAPER_HEIGHT
|
|
29
|
-
var currentStartX = 0
|
|
30
|
-
var currentStartY = 0
|
|
25
|
+
let currentWidth = PAPER_WIDTH
|
|
26
|
+
let currentHeight = PAPER_HEIGHT
|
|
27
|
+
let currentStartX = 0
|
|
28
|
+
let currentStartY = 0
|
|
31
29
|
|
|
32
30
|
ocargo.Drawing = function (startingPosition) {
|
|
33
31
|
/*************/
|
|
34
32
|
/* Constants */
|
|
35
33
|
/*************/
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
let characterWidth =
|
|
38
36
|
typeof CHARACTER_WIDTH !== 'undefined'
|
|
39
37
|
? CHARACTER_WIDTH
|
|
40
38
|
: DEFAULT_CHARACTER_WIDTH
|
|
41
|
-
|
|
39
|
+
let characterHeight =
|
|
42
40
|
typeof CHARACTER_HEIGHT !== 'undefined'
|
|
43
41
|
? CHARACTER_HEIGHT
|
|
44
42
|
: DEFAULT_CHARACTER_HEIGHT
|
|
45
43
|
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
let TRAFFIC_LIGHT_WIDTH = 60
|
|
45
|
+
let TRAFFIC_LIGHT_HEIGHT = 22
|
|
48
46
|
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
let INITIAL_CFC_OFFSET_X = -105
|
|
48
|
+
let INITIAL_CFC_OFFSET_Y = -7
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
let DESTINATION_NOT_VISITED_COLOUR = 'red'
|
|
51
|
+
let DESTINATION_VISITED_COLOUR = 'green'
|
|
54
52
|
|
|
55
53
|
/*********/
|
|
56
54
|
/* State */
|
|
57
55
|
/*********/
|
|
58
56
|
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
let paper = new Raphael('paper', EXTENDED_PAPER_WIDTH, EXTENDED_PAPER_HEIGHT)
|
|
58
|
+
let roadImages = []
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
let lightImages = {}
|
|
61
|
+
let destinationImages = {}
|
|
64
62
|
|
|
65
|
-
|
|
63
|
+
let character
|
|
66
64
|
|
|
67
65
|
if (!ocargo.Drawing.inLevelEditor()) {
|
|
68
66
|
character = new ocargo.Character(
|
|
@@ -79,8 +77,8 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
79
77
|
paper.setViewBox(
|
|
80
78
|
currentStartX,
|
|
81
79
|
currentStartY,
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
1060,
|
|
81
|
+
1000
|
|
84
82
|
)
|
|
85
83
|
|
|
86
84
|
/**
|
|
@@ -98,7 +96,8 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
98
96
|
|
|
99
97
|
currentStartX = newX
|
|
100
98
|
currentStartY = newY
|
|
101
|
-
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
102
101
|
let newX = currentStartX + zoom
|
|
103
102
|
let newY = currentStartY + zoom
|
|
104
103
|
|
|
@@ -122,14 +121,14 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
122
121
|
/**
|
|
123
122
|
* Map moving
|
|
124
123
|
*/
|
|
125
|
-
|
|
124
|
+
let currentMousePos = { x: -1, y: -1 }
|
|
126
125
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
let isMouseDown = false
|
|
127
|
+
let prevX = 0
|
|
128
|
+
let prevY = 0
|
|
130
129
|
|
|
131
130
|
this.enablePanning = function () {
|
|
132
|
-
|
|
131
|
+
let $paper = $('#paper')
|
|
133
132
|
|
|
134
133
|
$paper.mousedown(function (event) {
|
|
135
134
|
isMouseDown = true
|
|
@@ -146,8 +145,8 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
146
145
|
currentMousePos.y = event.pageY
|
|
147
146
|
|
|
148
147
|
if (isMouseDown) {
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
let deltaX = prevX - currentMousePos.x
|
|
149
|
+
let deltaY = prevY - currentMousePos.y
|
|
151
150
|
currentStartX = currentStartX + deltaX
|
|
152
151
|
currentStartY = currentStartY + deltaY
|
|
153
152
|
paper.setViewBox(
|
|
@@ -170,11 +169,11 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
170
169
|
// Used by level editor to preload road tiles to prevent jittery drawing
|
|
171
170
|
|
|
172
171
|
this.preloadRoadTiles = function () {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
172
|
+
let tiles = ['dead_end', 'crossroads', 'straight', 't_junction', 'turn']
|
|
173
|
+
let tileImages = []
|
|
174
|
+
let path = ocargo.Drawing.raphaelImageDir + 'road_tiles/'
|
|
176
175
|
|
|
177
|
-
for (
|
|
176
|
+
for (let i = 0; i < tiles.length; i++) {
|
|
178
177
|
tileImages.push(
|
|
179
178
|
paper.image(
|
|
180
179
|
path + 'road/' + tiles[i] + '.svg',
|
|
@@ -195,13 +194,13 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
195
194
|
)
|
|
196
195
|
}
|
|
197
196
|
|
|
198
|
-
for (
|
|
197
|
+
for (let i = 0; i < tileImages.length; i++) {
|
|
199
198
|
tileImages[i].remove()
|
|
200
199
|
}
|
|
201
200
|
}
|
|
202
201
|
|
|
203
202
|
function calculateCFCInitialPosition (startNode) {
|
|
204
|
-
|
|
203
|
+
let coord = ocargo.Drawing.translate(startNode.coordinate)
|
|
205
204
|
return {
|
|
206
205
|
x: coord.x * GRID_SPACE_SIZE + INITIAL_CFC_OFFSET_X + PAPER_PADDING,
|
|
207
206
|
y: coord.y * GRID_SPACE_SIZE + INITIAL_CFC_OFFSET_Y + PAPER_PADDING
|
|
@@ -209,8 +208,8 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
209
208
|
}
|
|
210
209
|
|
|
211
210
|
function calculateInitialRotation (previousNode, startNode) {
|
|
212
|
-
|
|
213
|
-
|
|
211
|
+
let nodeAngleRadians = ocargo.calculateNodeAngle(previousNode, startNode)
|
|
212
|
+
let nodeAngleDegrees = nodeAngleRadians * (180 / Math.PI)
|
|
214
213
|
return -nodeAngleDegrees // Calculation is counterclockwise, transformations are clockwise
|
|
215
214
|
}
|
|
216
215
|
|
|
@@ -273,8 +272,8 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
273
272
|
// Returns the direction of the middle branch
|
|
274
273
|
// E.g. T-shaped junction will be described as 'down'
|
|
275
274
|
function tJunctionOrientation (middle, node1, node2, node3) {
|
|
276
|
-
|
|
277
|
-
|
|
275
|
+
let res1 = getRoadLetters(node1, middle, node2)
|
|
276
|
+
let res2 = getRoadLetters(node2, middle, node3)
|
|
278
277
|
|
|
279
278
|
if (res1 === 'H' && res2 === 'DR') {
|
|
280
279
|
return 'down'
|
|
@@ -291,11 +290,11 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
291
290
|
/***************/
|
|
292
291
|
|
|
293
292
|
this.renderDestinations = function (destinations) {
|
|
294
|
-
for (
|
|
295
|
-
|
|
296
|
-
|
|
293
|
+
for (let i = 0; i < destinations.length; i++) {
|
|
294
|
+
let destination = destinations[i].node
|
|
295
|
+
let variation = getDestinationPosition(destination)
|
|
297
296
|
|
|
298
|
-
|
|
297
|
+
let destinationRect = paper
|
|
299
298
|
.rect(
|
|
300
299
|
destination.coordinate.x * GRID_SPACE_SIZE + PAPER_PADDING,
|
|
301
300
|
PAPER_HEIGHT -
|
|
@@ -307,7 +306,7 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
307
306
|
)
|
|
308
307
|
.attr({ stroke: DESTINATION_NOT_VISITED_COLOUR })
|
|
309
308
|
|
|
310
|
-
|
|
309
|
+
let destinationHouse = paper
|
|
311
310
|
.image(
|
|
312
311
|
ocargo.Drawing.raphaelImageDir + HOUSE_URL,
|
|
313
312
|
destination.coordinate.x * GRID_SPACE_SIZE +
|
|
@@ -330,12 +329,12 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
330
329
|
|
|
331
330
|
//find a side of the road
|
|
332
331
|
function getDestinationPosition (destination) {
|
|
333
|
-
|
|
332
|
+
let roadLetters = []
|
|
334
333
|
|
|
335
334
|
//might be best to just use the coordinates rather than get road letters and then convert back to directions
|
|
336
335
|
if (destination.connectedNodes.length === 1) {
|
|
337
|
-
|
|
338
|
-
|
|
336
|
+
let previousNode = destination.connectedNodes[0]
|
|
337
|
+
let nextNode = {}
|
|
339
338
|
nextNode.coordinate = new ocargo.Coordinate(
|
|
340
339
|
destination.coordinate.x +
|
|
341
340
|
(destination.coordinate.x - previousNode.coordinate.x),
|
|
@@ -350,9 +349,9 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
350
349
|
)
|
|
351
350
|
)
|
|
352
351
|
} else {
|
|
353
|
-
for (
|
|
354
|
-
|
|
355
|
-
for (
|
|
352
|
+
for (let i = 0; i < destination.connectedNodes.length; i++) {
|
|
353
|
+
let previousNode = destination.connectedNodes[i]
|
|
354
|
+
for (let j = i + 1; j < destination.connectedNodes.length; j++) {
|
|
356
355
|
roadLetters.push(
|
|
357
356
|
getRoadLetters(
|
|
358
357
|
previousNode.coordinate,
|
|
@@ -363,13 +362,13 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
363
362
|
}
|
|
364
363
|
}
|
|
365
364
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
365
|
+
let left = true
|
|
366
|
+
let right = true
|
|
367
|
+
let up = true
|
|
368
|
+
let down = true
|
|
370
369
|
|
|
371
370
|
//variation specifies x,y,rotation
|
|
372
|
-
|
|
371
|
+
let variation = [25, 25, 90]
|
|
373
372
|
|
|
374
373
|
// Set "default" variations of the house position
|
|
375
374
|
// based on straight roads and turns
|
|
@@ -427,19 +426,19 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
427
426
|
}
|
|
428
427
|
|
|
429
428
|
this.renderOrigin = function (position) {
|
|
430
|
-
|
|
431
|
-
|
|
429
|
+
let initialPosition = calculateCFCInitialPosition(position.currentNode)
|
|
430
|
+
let cfc = paper.image(
|
|
432
431
|
ocargo.Drawing.raphaelImageDir + CFC_URL,
|
|
433
432
|
initialPosition.x,
|
|
434
433
|
initialPosition.y,
|
|
435
434
|
100,
|
|
436
435
|
107
|
|
437
436
|
)
|
|
438
|
-
|
|
437
|
+
let rotation = calculateInitialRotation(
|
|
439
438
|
position.previousNode,
|
|
440
439
|
position.currentNode
|
|
441
440
|
)
|
|
442
|
-
|
|
441
|
+
let transformation = ocargo.Drawing.rotationTransformationAroundCentreOfGridSpace(
|
|
443
442
|
rotation,
|
|
444
443
|
position.currentNode.coordinate.x,
|
|
445
444
|
position.currentNode.coordinate.y
|
|
@@ -449,21 +448,21 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
449
448
|
}
|
|
450
449
|
|
|
451
450
|
this.renderRoad = function (nodes) {
|
|
452
|
-
for (
|
|
453
|
-
|
|
451
|
+
for (let i = 0; i < roadImages.length; i++) {
|
|
452
|
+
let image = roadImages[i]
|
|
454
453
|
if (image) {
|
|
455
454
|
image.remove()
|
|
456
455
|
}
|
|
457
456
|
}
|
|
458
457
|
|
|
459
|
-
|
|
458
|
+
let path = ocargo.Drawing.raphaelImageDir + 'road_tiles/'
|
|
460
459
|
|
|
461
|
-
path += CHARACTER_NAME === 'Van' ? 'road/' : 'path/'
|
|
460
|
+
path += (CHARACTER_NAME === 'Van' || CHARACTER_NAME === "Electric van") ? 'road/' : 'path/'
|
|
462
461
|
|
|
463
462
|
roadImages = []
|
|
464
|
-
for (
|
|
465
|
-
|
|
466
|
-
|
|
463
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
464
|
+
let node = nodes[i]
|
|
465
|
+
let roadImage
|
|
467
466
|
switch (node.connectedNodes.length) {
|
|
468
467
|
case 1:
|
|
469
468
|
roadImage = drawDeadEndRoad(node, path)
|
|
@@ -493,24 +492,24 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
493
492
|
}
|
|
494
493
|
|
|
495
494
|
function drawDeadEndRoad (node, path) {
|
|
496
|
-
|
|
495
|
+
let previousNode = node.connectedNodes[0]
|
|
497
496
|
|
|
498
|
-
|
|
497
|
+
let nextNode = {}
|
|
499
498
|
nextNode.coordinate = new ocargo.Coordinate(
|
|
500
499
|
node.coordinate.x + (node.coordinate.x - previousNode.coordinate.x),
|
|
501
500
|
node.coordinate.y + (node.coordinate.y - previousNode.coordinate.y)
|
|
502
501
|
)
|
|
503
502
|
|
|
504
|
-
|
|
503
|
+
let roadLetters = getRoadLetters(
|
|
505
504
|
previousNode.coordinate,
|
|
506
505
|
node.coordinate,
|
|
507
506
|
nextNode.coordinate
|
|
508
507
|
)
|
|
509
508
|
|
|
510
|
-
|
|
511
|
-
|
|
509
|
+
let prevFlipped = ocargo.Drawing.translate(previousNode.coordinate)
|
|
510
|
+
let flipped = ocargo.Drawing.translate(node.coordinate)
|
|
512
511
|
|
|
513
|
-
|
|
512
|
+
let road = paper.image(
|
|
514
513
|
path + 'dead_end.svg',
|
|
515
514
|
flipped.x * GRID_SPACE_SIZE + PAPER_PADDING,
|
|
516
515
|
flipped.y * GRID_SPACE_SIZE + PAPER_PADDING,
|
|
@@ -542,18 +541,18 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
542
541
|
}
|
|
543
542
|
|
|
544
543
|
function drawSingleRoadSegment (previousNode, node, nextNode, path) {
|
|
545
|
-
|
|
544
|
+
let roadLetters = getRoadLetters(
|
|
546
545
|
previousNode.coordinate,
|
|
547
546
|
node.coordinate,
|
|
548
547
|
nextNode.coordinate
|
|
549
548
|
)
|
|
550
549
|
|
|
551
|
-
|
|
552
|
-
|
|
550
|
+
let flipped = ocargo.Drawing.translate(node.coordinate)
|
|
551
|
+
let roadSrc =
|
|
553
552
|
path +
|
|
554
553
|
(roadLetters === 'H' || roadLetters === 'V' ? 'straight' : 'turn') +
|
|
555
554
|
'.svg'
|
|
556
|
-
|
|
555
|
+
let road = paper.image(
|
|
557
556
|
roadSrc,
|
|
558
557
|
flipped.x * GRID_SPACE_SIZE + PAPER_PADDING,
|
|
559
558
|
flipped.y * GRID_SPACE_SIZE + PAPER_PADDING,
|
|
@@ -587,24 +586,24 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
587
586
|
}
|
|
588
587
|
|
|
589
588
|
function drawTJunction (node, path) {
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
589
|
+
let node1 = node.connectedNodes[0]
|
|
590
|
+
let node2 = node.connectedNodes[1]
|
|
591
|
+
let node3 = node.connectedNodes[2]
|
|
593
592
|
|
|
594
|
-
|
|
593
|
+
let flipped = ocargo.Drawing.translate(node.coordinate)
|
|
595
594
|
|
|
596
|
-
|
|
595
|
+
let letters12 = getRoadLetters(
|
|
597
596
|
node1.coordinate,
|
|
598
597
|
node.coordinate,
|
|
599
598
|
node3.coordinate
|
|
600
599
|
)
|
|
601
|
-
|
|
600
|
+
let letters13 = getRoadLetters(
|
|
602
601
|
node1.coordinate,
|
|
603
602
|
node.coordinate,
|
|
604
603
|
node2.coordinate
|
|
605
604
|
)
|
|
606
605
|
|
|
607
|
-
|
|
606
|
+
let rotation = 0
|
|
608
607
|
if (
|
|
609
608
|
(letters12 === 'V' && (letters13 === 'UL' || letters13 === 'DL')) ||
|
|
610
609
|
(letters12 === 'UL' && (letters13 === 'DL' || letters13 === 'V')) ||
|
|
@@ -631,7 +630,7 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
631
630
|
rotation = 270
|
|
632
631
|
}
|
|
633
632
|
|
|
634
|
-
|
|
633
|
+
let road = paper.image(
|
|
635
634
|
path + 't_junction.svg',
|
|
636
635
|
flipped.x * GRID_SPACE_SIZE + PAPER_PADDING,
|
|
637
636
|
flipped.y * GRID_SPACE_SIZE + PAPER_PADDING,
|
|
@@ -648,7 +647,7 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
648
647
|
}
|
|
649
648
|
|
|
650
649
|
function drawCrossRoads (node, path) {
|
|
651
|
-
|
|
650
|
+
let flipped = ocargo.Drawing.translate(node.coordinate)
|
|
652
651
|
|
|
653
652
|
return paper.image(
|
|
654
653
|
path + 'crossroads.svg',
|
|
@@ -670,13 +669,14 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
670
669
|
}
|
|
671
670
|
|
|
672
671
|
this.renderDecor = function (decors) {
|
|
673
|
-
for (
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
672
|
+
for (let i = 0; i < decors.length; i++) {
|
|
673
|
+
let decor = decors[i]
|
|
674
|
+
let decorUrl = new Date().getMonth() === 11 ? decor.xmas_url : decor.url
|
|
675
|
+
let src = ocargo.Drawing.raphaelImageDir + decorUrl
|
|
676
|
+
let x = decor.x + PAPER_PADDING
|
|
677
|
+
let y = PAPER_HEIGHT - decor.y - decor.height + PAPER_PADDING
|
|
678
|
+
let width = decor.width
|
|
679
|
+
let height = decor.height
|
|
680
680
|
paper.image(src, x, y, width, height)
|
|
681
681
|
}
|
|
682
682
|
}
|
|
@@ -691,26 +691,26 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
691
691
|
image
|
|
692
692
|
) {
|
|
693
693
|
// get position based on nodes
|
|
694
|
-
|
|
695
|
-
|
|
694
|
+
let x = (controlledCoordinate.x + sourceCoordinate.x) / 2.0
|
|
695
|
+
let y = (controlledCoordinate.y + sourceCoordinate.y) / 2.0
|
|
696
696
|
|
|
697
697
|
// get rotation based on nodes (should face source)
|
|
698
|
-
|
|
699
|
-
|
|
698
|
+
let angle = sourceCoordinate.angleTo(controlledCoordinate) * (180 / Math.PI)
|
|
699
|
+
let rotation = 90 - angle
|
|
700
700
|
|
|
701
701
|
// draw red and green lights, keep reference to both
|
|
702
|
-
|
|
703
|
-
|
|
702
|
+
let drawX = x * GRID_SPACE_SIZE + TRAFFIC_LIGHT_HEIGHT + PAPER_PADDING
|
|
703
|
+
let drawY =
|
|
704
704
|
PAPER_HEIGHT - y * GRID_SPACE_SIZE - TRAFFIC_LIGHT_WIDTH + PAPER_PADDING
|
|
705
705
|
|
|
706
706
|
image.transform('t' + drawX + ',' + drawY + ' r' + rotation + 's-1,1')
|
|
707
707
|
}
|
|
708
708
|
|
|
709
709
|
this.renderTrafficLights = function (trafficLights) {
|
|
710
|
-
for (
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
710
|
+
for (let i = 0; i < trafficLights.length; i++) {
|
|
711
|
+
let trafficLight = trafficLights[i]
|
|
712
|
+
let sourceCoordinate = trafficLight.sourceNode.coordinate
|
|
713
|
+
let controlledCoordinate = trafficLight.controlledNode.coordinate
|
|
714
714
|
|
|
715
715
|
trafficLight.greenLightEl = this.createTrafficLightImage(
|
|
716
716
|
ocargo.Drawing.raphaelImageDir + 'trafficLight_green.svg'
|
|
@@ -747,23 +747,26 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
747
747
|
}
|
|
748
748
|
|
|
749
749
|
this.determineCowOrientation = function (coordinate, node) {
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
750
|
+
let x = coordinate.x
|
|
751
|
+
let y = coordinate.y
|
|
752
|
+
|
|
753
|
+
let xOffset = 0
|
|
754
|
+
let yOffset = 0
|
|
755
|
+
let rotation = 0
|
|
756
|
+
if (node == null) {
|
|
757
|
+
// the cow is outside of road
|
|
758
|
+
rotation = 0
|
|
759
|
+
}
|
|
760
|
+
else if (node.connectedNodes.length === 1) {
|
|
758
761
|
// Deadends
|
|
759
|
-
|
|
760
|
-
|
|
762
|
+
let previousNode = node.connectedNodes[0]
|
|
763
|
+
let nextNode = {}
|
|
761
764
|
nextNode.coordinate = new ocargo.Coordinate(
|
|
762
765
|
node.coordinate.x + (node.coordinate.x - previousNode.coordinate.x),
|
|
763
766
|
node.coordinate.y + (node.coordinate.y - previousNode.coordinate.y)
|
|
764
767
|
)
|
|
765
768
|
|
|
766
|
-
|
|
769
|
+
let roadLetters = getRoadLetters(
|
|
767
770
|
previousNode.coordinate,
|
|
768
771
|
node.coordinate,
|
|
769
772
|
nextNode.coordinate
|
|
@@ -774,10 +777,10 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
774
777
|
}
|
|
775
778
|
} else if (node.connectedNodes.length === 2) {
|
|
776
779
|
// Turns
|
|
777
|
-
|
|
778
|
-
|
|
780
|
+
let previousNode = node.connectedNodes[0]
|
|
781
|
+
let nextNode = node.connectedNodes[1]
|
|
779
782
|
|
|
780
|
-
|
|
783
|
+
let roadLetters = getRoadLetters(
|
|
781
784
|
previousNode.coordinate,
|
|
782
785
|
node.coordinate,
|
|
783
786
|
nextNode.coordinate
|
|
@@ -804,10 +807,10 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
804
807
|
}
|
|
805
808
|
} else if (node.connectedNodes.length === 3) {
|
|
806
809
|
// T-junctions
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
810
|
+
let previousNode = node.connectedNodes[0]
|
|
811
|
+
let nextNode = node.connectedNodes[1]
|
|
812
|
+
let nextNextNode = node.connectedNodes[2]
|
|
813
|
+
let res = tJunctionOrientation(
|
|
811
814
|
node.coordinate,
|
|
812
815
|
previousNode.coordinate,
|
|
813
816
|
nextNode.coordinate,
|
|
@@ -823,9 +826,9 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
823
826
|
}
|
|
824
827
|
}
|
|
825
828
|
|
|
826
|
-
|
|
829
|
+
let drawX =
|
|
827
830
|
(x + 0.5) * GRID_SPACE_SIZE - COW_WIDTH / 2 + xOffset + PAPER_PADDING
|
|
828
|
-
|
|
831
|
+
let drawY =
|
|
829
832
|
PAPER_HEIGHT -
|
|
830
833
|
(y + 0.5) * GRID_SPACE_SIZE -
|
|
831
834
|
COW_HEIGHT / 2 +
|
|
@@ -846,21 +849,21 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
846
849
|
}
|
|
847
850
|
|
|
848
851
|
this.setCowImagePosition = function (coordinate, image, node) {
|
|
849
|
-
|
|
852
|
+
let res = this.determineCowOrientation(coordinate, node)
|
|
850
853
|
|
|
851
854
|
image.transform('t' + res.drawX + ',' + res.drawY + 'r' + res.rotation)
|
|
852
855
|
}
|
|
853
856
|
|
|
854
857
|
this.renderCow = function (id, coordinate, node, animationLength, type) {
|
|
855
|
-
|
|
856
|
-
|
|
858
|
+
let res = this.determineCowOrientation(coordinate, node)
|
|
859
|
+
let image = paper.image(
|
|
857
860
|
ocargo.Drawing.raphaelImageDir + ocargo.Drawing.cowUrl(type),
|
|
858
861
|
res.drawX,
|
|
859
862
|
res.drawY,
|
|
860
863
|
COW_WIDTH,
|
|
861
864
|
COW_HEIGHT
|
|
862
865
|
)
|
|
863
|
-
|
|
866
|
+
let rot = 'r' + res.rotation
|
|
864
867
|
image.transform(rot + 's0.1')
|
|
865
868
|
image.animate({ transform: rot + 's1' }, animationLength, 'linear')
|
|
866
869
|
|
|
@@ -871,14 +874,16 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
871
874
|
}
|
|
872
875
|
|
|
873
876
|
this.removeCow = function (cow, animationLength) {
|
|
874
|
-
cow
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
877
|
+
if (cow){
|
|
878
|
+
cow.image.animate(
|
|
879
|
+
{ transform: 's0.01' },
|
|
880
|
+
animationLength,
|
|
881
|
+
'linear',
|
|
882
|
+
function () {
|
|
883
|
+
cow.image.remove()
|
|
884
|
+
}
|
|
885
|
+
)
|
|
886
|
+
}
|
|
882
887
|
}
|
|
883
888
|
|
|
884
889
|
this.renderCharacter = function () {
|
|
@@ -886,12 +891,12 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
886
891
|
}
|
|
887
892
|
|
|
888
893
|
this.createGrid = function () {
|
|
889
|
-
|
|
890
|
-
for (
|
|
891
|
-
|
|
892
|
-
for (
|
|
893
|
-
|
|
894
|
-
|
|
894
|
+
let grid = []
|
|
895
|
+
for (let i = 0; i < GRID_WIDTH; i++) {
|
|
896
|
+
let row = []
|
|
897
|
+
for (let j = 0; j < GRID_HEIGHT; j++) {
|
|
898
|
+
let x = i * GRID_SPACE_SIZE + PAPER_PADDING
|
|
899
|
+
let y = j * GRID_SPACE_SIZE + PAPER_PADDING
|
|
895
900
|
|
|
896
901
|
row.push(paper.rect(x, y, GRID_SPACE_SIZE, GRID_SPACE_SIZE))
|
|
897
902
|
}
|
|
@@ -901,11 +906,11 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
901
906
|
}
|
|
902
907
|
|
|
903
908
|
this.renderGrid = function (grid, currentTheme) {
|
|
904
|
-
for (
|
|
905
|
-
for (
|
|
909
|
+
for (let i = 0; i < GRID_WIDTH; i++) {
|
|
910
|
+
for (let j = 0; j < GRID_HEIGHT; j++) {
|
|
906
911
|
grid[i][j].attr({
|
|
907
912
|
stroke: currentTheme.border,
|
|
908
|
-
fill: currentTheme.background,
|
|
913
|
+
fill: new Date().getMonth() === 11 ? THEMES.snow.background : currentTheme.background,
|
|
909
914
|
'fill-opacity': 1
|
|
910
915
|
})
|
|
911
916
|
}
|
|
@@ -948,8 +953,8 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
948
953
|
}
|
|
949
954
|
|
|
950
955
|
this.transitionDestination = function (destinationID, visited, duration) {
|
|
951
|
-
|
|
952
|
-
|
|
956
|
+
let destinationRect = destinationImages[destinationID].rect
|
|
957
|
+
let colour = visited
|
|
953
958
|
? DESTINATION_VISITED_COLOUR
|
|
954
959
|
: DESTINATION_NOT_VISITED_COLOUR
|
|
955
960
|
|
|
@@ -977,7 +982,7 @@ ocargo.Drawing = function (startingPosition) {
|
|
|
977
982
|
}
|
|
978
983
|
|
|
979
984
|
this.wait = function (duration, callback) {
|
|
980
|
-
character.wait(duration, callback)
|
|
985
|
+
character.wait(duration, callback);
|
|
981
986
|
}
|
|
982
987
|
|
|
983
988
|
this.deliver = function (destinationId, duration) {
|
|
@@ -1014,6 +1019,14 @@ ocargo.Drawing.translate = function (coordinate) {
|
|
|
1014
1019
|
return new ocargo.Coordinate(coordinate.x, GRID_HEIGHT - 1 - coordinate.y)
|
|
1015
1020
|
}
|
|
1016
1021
|
|
|
1022
|
+
// A Function used to stop the iframe video
|
|
1023
|
+
function stopVideo() {
|
|
1024
|
+
// // https://gist.github.com/cferdinandi/9044694
|
|
1025
|
+
const video = document.getElementsByTagName("video");
|
|
1026
|
+
const videoSrc = video[0].src;
|
|
1027
|
+
video[0].src = videoSrc;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1017
1030
|
/*
|
|
1018
1031
|
This is the function that starts the pop-up.
|
|
1019
1032
|
Buttons should be passed in separately to the function instead of concatenating
|
|
@@ -1029,38 +1042,147 @@ ocargo.Drawing.startPopup = function (
|
|
|
1029
1042
|
title,
|
|
1030
1043
|
subtitle,
|
|
1031
1044
|
message,
|
|
1032
|
-
|
|
1045
|
+
showMascot,
|
|
1033
1046
|
buttons
|
|
1034
1047
|
) {
|
|
1035
1048
|
$('#myModal-title').html(title)
|
|
1036
1049
|
$('#myModal-lead').html(subtitle)
|
|
1037
1050
|
$('#myModal-mainText').html(message)
|
|
1038
1051
|
|
|
1039
|
-
$('#modal-mascot')
|
|
1040
|
-
$('#modal-mascot--brain')
|
|
1052
|
+
const mascot = $('#modal-mascot')
|
|
1053
|
+
const brain = $('#modal-mascot--brain')
|
|
1054
|
+
|
|
1055
|
+
mascot.hide()
|
|
1056
|
+
brain.hide()
|
|
1041
1057
|
|
|
1042
|
-
if (
|
|
1058
|
+
if (showMascot) {
|
|
1043
1059
|
if (EPISODE === 9) {
|
|
1044
|
-
|
|
1060
|
+
brain.show()
|
|
1045
1061
|
}
|
|
1046
1062
|
else {
|
|
1047
|
-
|
|
1063
|
+
mascot.show()
|
|
1048
1064
|
}
|
|
1049
1065
|
}
|
|
1050
1066
|
|
|
1051
|
-
|
|
1067
|
+
const video = $("video")
|
|
1068
|
+
if (video) {
|
|
1069
|
+
mascot.hide()
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// create a wrapper for the buttons that will be appended
|
|
1073
|
+
let buttonDiv = $("<div>").addClass("modal-buttons")
|
|
1074
|
+
|
|
1075
|
+
const icons = [
|
|
1076
|
+
$("<span>").addClass("iconify icon").attr("data-icon", "mdi:chevron-left"),
|
|
1077
|
+
"NOT USED",
|
|
1078
|
+
$("<span>").addClass("iconify icon").attr("data-icon", "mdi:chevron-right"),
|
|
1079
|
+
]
|
|
1080
|
+
|
|
1081
|
+
// buttons are passed as html string..
|
|
1082
|
+
// hence this terribleness
|
|
1083
|
+
// check if we pass an array of buttons or just one button
|
|
1084
|
+
if (Array.isArray(buttons)) {
|
|
1085
|
+
const links = [
|
|
1086
|
+
PREV_LEVEL_URL,
|
|
1087
|
+
"",
|
|
1088
|
+
NEXT_LEVEL_URL,
|
|
1089
|
+
]
|
|
1090
|
+
|
|
1091
|
+
const regexID = /id=\"*\w+_\w+\"/
|
|
1092
|
+
|
|
1093
|
+
// Close the video on pressing the top right close button
|
|
1094
|
+
$("#close-modal").click(function () {
|
|
1095
|
+
stopVideo();
|
|
1096
|
+
});
|
|
1097
|
+
|
|
1098
|
+
for (let i = 0; i < buttons.length; i++) {
|
|
1099
|
+
// get id with regex by stripping the html content
|
|
1100
|
+
let currentID = buttons[i].match(regexID)[0].slice(3).replaceAll('"', '')
|
|
1101
|
+
|
|
1102
|
+
let currentButton = $(buttons[i])
|
|
1103
|
+
let classToBeAdded = currentID === "play_button" ? "navigation_button_portal long_button rapid-router-welcome" : "navigation_button_portal_secondary long_button rapid-router-welcome button--icon"
|
|
1104
|
+
|
|
1105
|
+
currentButton.removeClass().addClass(classToBeAdded)
|
|
1106
|
+
if (currentID !== "play_button") {
|
|
1107
|
+
// adding links to buttons
|
|
1108
|
+
currentButton.append(icons[i])
|
|
1109
|
+
let currentLink = links[i] === "" ? "" : `window.location.replace('${links[i]}')`
|
|
1110
|
+
if (!(currentID === "next_button" && NEXT_LEVEL_URL === "/pythonden/")) {
|
|
1111
|
+
currentButton.attr("onclick", currentLink);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
// Close the video on the play button
|
|
1116
|
+
currentButton.click(function () {
|
|
1117
|
+
stopVideo();
|
|
1118
|
+
});
|
|
1119
|
+
|
|
1120
|
+
// first level shouldn't have prev_button
|
|
1121
|
+
// and last level shouldn't have next_button
|
|
1122
|
+
if (currentButton.attr("onclick")) buttonDiv.append(currentButton)
|
|
1123
|
+
}
|
|
1124
|
+
// append the whole div to the popup
|
|
1125
|
+
$("#modal-buttons").html(buttonDiv)
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
else if (buttons) {
|
|
1052
1129
|
$('#modal-buttons').html(buttons)
|
|
1130
|
+
|
|
1131
|
+
let tryAgainButton = $("#try_again_button")
|
|
1132
|
+
tryAgainButton.removeClass().addClass("navigation_button_portal long_button rapid-router-welcome")
|
|
1133
|
+
buttonDiv.append(tryAgainButton)
|
|
1134
|
+
|
|
1135
|
+
let editButton = $("#edit_button")
|
|
1136
|
+
editButton.removeClass().addClass("navigation_button_portal long_button rapid-router-welcome")
|
|
1137
|
+
buttonDiv.append(editButton)
|
|
1138
|
+
|
|
1139
|
+
let yesButton = $("#yes_button")
|
|
1140
|
+
yesButton.removeClass().addClass("navigation_button_portal long_button rapid-router-welcome")
|
|
1141
|
+
buttonDiv.append(yesButton)
|
|
1142
|
+
|
|
1143
|
+
let noButton = $("#no_button")
|
|
1144
|
+
noButton.removeClass().addClass("navigation_button_portal long_button rapid-router-welcome")
|
|
1145
|
+
buttonDiv.append(noButton)
|
|
1146
|
+
|
|
1147
|
+
let nextLevelButton = $("#next_level_button")
|
|
1148
|
+
nextLevelButton.removeClass().addClass("navigation_button_portal_secondary long_button rapid-router-welcome button--icon")
|
|
1149
|
+
nextLevelButton.append(icons[2])
|
|
1150
|
+
buttonDiv.append(nextLevelButton)
|
|
1151
|
+
|
|
1152
|
+
let playButton = $("#play_button")
|
|
1153
|
+
playButton.removeClass().addClass("navigation_button_portal_secondary long_button rapid-router-welcome button--icon")
|
|
1154
|
+
playButton.append(icons[2])
|
|
1155
|
+
buttonDiv.append(playButton)
|
|
1156
|
+
|
|
1157
|
+
let hintPopupButton = $("#hintPopupBtn")
|
|
1158
|
+
hintPopupButton.removeClass().addClass("navigation_button_portal long_button")
|
|
1159
|
+
buttonDiv.append(hintPopupButton)
|
|
1160
|
+
|
|
1161
|
+
$("#modal-buttons").html(buttonDiv)
|
|
1053
1162
|
} else {
|
|
1054
1163
|
$('#modal-buttons').html(
|
|
1055
1164
|
ocargo.button.dismissButtonHtml('close_button', gettext('Close'))
|
|
1056
1165
|
)
|
|
1166
|
+
|
|
1167
|
+
let closeButton = $("#close_button")
|
|
1168
|
+
closeButton.removeClass().addClass("navigation_button_portal long_button rapid-router-welcome")
|
|
1169
|
+
buttonDiv.append(closeButton)
|
|
1170
|
+
$("#modal-buttons").html(buttonDiv)
|
|
1057
1171
|
}
|
|
1058
1172
|
// Show popup
|
|
1059
|
-
$("#myModal").show
|
|
1060
|
-
$("#ocargo-modal").show
|
|
1061
|
-
|
|
1173
|
+
$("#myModal").addClass("show");
|
|
1174
|
+
$("#ocargo-modal").addClass("show");
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
var hideModal = function() {
|
|
1178
|
+
$("#myModal").removeClass("show");
|
|
1179
|
+
$("#ocargo-modal").removeClass("show");
|
|
1062
1180
|
}
|
|
1063
1181
|
|
|
1182
|
+
$("#close-modal").on('click', function() {
|
|
1183
|
+
hideModal();
|
|
1184
|
+
})
|
|
1185
|
+
|
|
1064
1186
|
// This is the function that starts the pop-up with a yes and a no button
|
|
1065
1187
|
ocargo.Drawing.startYesNoPopup = function (
|
|
1066
1188
|
title,
|
|
@@ -1068,31 +1190,15 @@ ocargo.Drawing.startYesNoPopup = function (
|
|
|
1068
1190
|
message,
|
|
1069
1191
|
yesFunction,
|
|
1070
1192
|
noFunction,
|
|
1071
|
-
|
|
1193
|
+
showMascot
|
|
1072
1194
|
) {
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
ocargo.
|
|
1076
|
-
$('#modal-yesBtn').click(yesFunction)
|
|
1077
|
-
$('#modal-noBtn').click(noFunction)
|
|
1078
|
-
}
|
|
1195
|
+
let buttons = '';
|
|
1196
|
+
buttons += ocargo.button.dismissButtonHtml("yes_button", "Yes");
|
|
1197
|
+
buttons += ocargo.button.dismissButtonHtml("no_button", "No");
|
|
1079
1198
|
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
subtitle,
|
|
1084
|
-
message,
|
|
1085
|
-
optionAFunction,
|
|
1086
|
-
optionBFunction,
|
|
1087
|
-
optionAText,
|
|
1088
|
-
optionBText,
|
|
1089
|
-
mascot
|
|
1090
|
-
) {
|
|
1091
|
-
var buttonHtml =
|
|
1092
|
-
'<button id="modal-optionABtn" class="navigation_button long_button">' + optionAText + '</button> <button id="modal-optionBBtn" class="navigation_button long_button">' + optionBText + '</button>'
|
|
1093
|
-
ocargo.Drawing.startPopup(title, subtitle, message, mascot, buttonHtml)
|
|
1094
|
-
$('#modal-optionABtn').click(optionAFunction)
|
|
1095
|
-
$('#modal-optionBBtn').click(optionBFunction)
|
|
1199
|
+
ocargo.Drawing.startPopup(title, subtitle, message, showMascot, buttons)
|
|
1200
|
+
$('#yes_button').click(yesFunction)
|
|
1201
|
+
$('#no_button').click(noFunction)
|
|
1096
1202
|
}
|
|
1097
1203
|
|
|
1098
1204
|
// This is the function that starts the pop-up when there is no internet connection while playing the game
|
|
@@ -1107,7 +1213,7 @@ ocargo.Drawing.startInternetDownPopup = function () {
|
|
|
1107
1213
|
}
|
|
1108
1214
|
|
|
1109
1215
|
ocargo.Drawing.isMobile = function () {
|
|
1110
|
-
|
|
1216
|
+
let mobileDetect = new MobileDetect(window.navigator.userAgent)
|
|
1111
1217
|
return !!mobileDetect.mobile()
|
|
1112
1218
|
}
|
|
1113
1219
|
|
|
@@ -1116,8 +1222,8 @@ ocargo.Drawing.isChrome = function () {
|
|
|
1116
1222
|
}
|
|
1117
1223
|
|
|
1118
1224
|
ocargo.Drawing.renderCoins = function (coins) {
|
|
1119
|
-
|
|
1120
|
-
|
|
1225
|
+
let html = '<div>'
|
|
1226
|
+
let i
|
|
1121
1227
|
for (i = 0; i < coins.whole; i++) {
|
|
1122
1228
|
html +=
|
|
1123
1229
|
"<img src='" +
|
|
@@ -1141,11 +1247,14 @@ ocargo.Drawing.renderCoins = function (coins) {
|
|
|
1141
1247
|
}
|
|
1142
1248
|
|
|
1143
1249
|
ocargo.Drawing.cowUrl = function (type) {
|
|
1250
|
+
ocargo.Drawing.animalType = type;
|
|
1144
1251
|
switch (type) {
|
|
1145
1252
|
case ocargo.Cow.WHITE:
|
|
1146
1253
|
return ocargo.Drawing.whiteCowUrl
|
|
1147
1254
|
case ocargo.Cow.BROWN:
|
|
1148
1255
|
return ocargo.Drawing.brownCowUrl
|
|
1256
|
+
case ocargo.Cow.PIGEON:
|
|
1257
|
+
return ocargo.Drawing.pigeonUrl
|
|
1149
1258
|
default:
|
|
1150
1259
|
return ocargo.Drawing.whiteCowUrl
|
|
1151
1260
|
}
|
|
@@ -1156,7 +1265,7 @@ ocargo.Drawing.createAbsoluteRotationTransformation = function (
|
|
|
1156
1265
|
rotationPointX,
|
|
1157
1266
|
rotationPointY
|
|
1158
1267
|
) {
|
|
1159
|
-
|
|
1268
|
+
let transformation = '... R' + degrees
|
|
1160
1269
|
if (rotationPointX !== undefined && rotationPointY !== undefined) {
|
|
1161
1270
|
transformation += ',' + rotationPointX
|
|
1162
1271
|
transformation += ',' + rotationPointY
|
|
@@ -1169,10 +1278,10 @@ ocargo.Drawing.rotationTransformationAroundCentreOfGridSpace = function (
|
|
|
1169
1278
|
x,
|
|
1170
1279
|
y
|
|
1171
1280
|
) {
|
|
1172
|
-
|
|
1173
|
-
|
|
1281
|
+
let rotationPointX = (x + 1 / 2) * GRID_SPACE_SIZE + PAPER_PADDING
|
|
1282
|
+
let rotationPointY =
|
|
1174
1283
|
(GRID_HEIGHT - (y + 1 / 2)) * GRID_SPACE_SIZE + PAPER_PADDING //flipping y
|
|
1175
|
-
|
|
1284
|
+
let result = ocargo.Drawing.createAbsoluteRotationTransformation(
|
|
1176
1285
|
degrees,
|
|
1177
1286
|
rotationPointX,
|
|
1178
1287
|
rotationPointY
|
|
@@ -1189,6 +1298,9 @@ ocargo.Drawing.TOP_VIEW = 'top_view'
|
|
|
1189
1298
|
|
|
1190
1299
|
ocargo.Drawing.whiteCowUrl = 'Clarice.svg'
|
|
1191
1300
|
ocargo.Drawing.brownCowUrl = 'Clarice_Jersey.svg'
|
|
1301
|
+
ocargo.Drawing.pigeonUrl = 'pigeon.svg'
|
|
1192
1302
|
|
|
1193
1303
|
ocargo.Drawing.imageDir = '/static/game/image/'
|
|
1194
1304
|
ocargo.Drawing.raphaelImageDir = '/static/game/raphael_image/'
|
|
1305
|
+
|
|
1306
|
+
ocargo.Drawing.animalType = 'WHITE'
|