Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | Add initial prototype with https://ansimuz.itch.io/warped-city assets |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | lisp-game-jam-2020 |
Files: | files | file ages | folders |
SHA3-256: |
a6620266bc459d6cbc28594d903b74d5 |
User & Date: | chewbranca 2020-04-13 20:06:40 |
2020-04-16
| ||
05:39 | Add Warper City atlas loader and initial animations check-in: 02b8ba3fe4 user: chewbranca tags: lisp-game-jam-2020 | |
2020-04-13
| ||
20:06 | Add initial prototype with https://ansimuz.itch.io/warped-city assets check-in: a6620266bc user: chewbranca tags: lisp-game-jam-2020 | |
2020-04-11
| ||
22:49 | Finish part1 and fix jumping check-in: d243b75468 user: chewbranca tags: lisp-game-jam-2020 | |
Added src/fahombo/assets/warped_city/atlas/atlas.json.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 |
{"frames": [ { "filename": "antenna", "frame": {"x":612,"y":133,"w":21,"h":95}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":1,"w":21,"h":95}, "sourceSize": {"w":22,"h":96}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "back-jump-1", "frame": {"x":575,"y":2,"w":24,"h":27}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":24,"y":40,"w":24,"h":27}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "back-jump-2", "frame": {"x":374,"y":55,"w":35,"h":42}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":15,"y":25,"w":35,"h":42}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "back-jump-3", "frame": {"x":168,"y":55,"w":35,"h":38}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":15,"y":20,"w":35,"h":38}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "back-jump-4", "frame": {"x":773,"y":55,"w":44,"h":40}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":12,"y":16,"w":44,"h":40}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "back-jump-5", "frame": {"x":411,"y":55,"w":31,"h":47}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":17,"y":18,"w":31,"h":47}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "back-jump-6", "frame": {"x":1124,"y":2,"w":28,"h":39}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":24,"y":28,"w":28,"h":39}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "back-jump-7", "frame": {"x":858,"y":2,"w":35,"h":27}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":19,"y":40,"w":35,"h":27}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "back-jump-preview", "frame": {"x":601,"y":2,"w":24,"h":27}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":24,"y":40,"w":24,"h":27}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-big-1", "frame": {"x":635,"y":133,"w":35,"h":92}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":35,"h":92}, "sourceSize": {"w":35,"h":92}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-big-2", "frame": {"x":672,"y":133,"w":35,"h":92}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":35,"h":92}, "sourceSize": {"w":35,"h":92}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-big-3", "frame": {"x":746,"y":133,"w":35,"h":92}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":35,"h":92}, "sourceSize": {"w":35,"h":92}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-big-4", "frame": {"x":783,"y":133,"w":35,"h":92}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":35,"h":92}, "sourceSize": {"w":35,"h":92}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-big-preview", "frame": {"x":709,"y":133,"w":35,"h":92}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":35,"h":92}, "sourceSize": {"w":35,"h":92}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-coke-1", "frame": {"x":382,"y":133,"w":27,"h":78}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":27,"h":78}, "sourceSize": {"w":27,"h":78}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-coke-2", "frame": {"x":440,"y":133,"w":27,"h":78}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":27,"h":78}, "sourceSize": {"w":27,"h":78}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-coke-3", "frame": {"x":411,"y":133,"w":27,"h":78}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":27,"h":78}, "sourceSize": {"w":27,"h":78}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-coke-preview", "frame": {"x":469,"y":133,"w":27,"h":78}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":27,"h":78}, "sourceSize": {"w":27,"h":78}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-neon-1", "frame": {"x":1215,"y":2,"w":19,"h":48}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":19,"h":48}, "sourceSize": {"w":19,"h":48}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-neon-2", "frame": {"x":1194,"y":2,"w":19,"h":48}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":19,"h":48}, "sourceSize": {"w":19,"h":48}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-neon-3", "frame": {"x":1103,"y":2,"w":19,"h":48}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":19,"h":48}, "sourceSize": {"w":19,"h":48}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-neon-4", "frame": {"x":1236,"y":2,"w":19,"h":48}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":19,"h":48}, "sourceSize": {"w":19,"h":48}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-neon-preview", "frame": {"x":1278,"y":2,"w":19,"h":48}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":19,"h":48}, "sourceSize": {"w":19,"h":48}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-scroll-1", "frame": {"x":678,"y":2,"w":13,"h":47}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":13,"h":47}, "sourceSize": {"w":13,"h":47}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-scroll-2", "frame": {"x":663,"y":2,"w":13,"h":47}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":13,"h":47}, "sourceSize": {"w":13,"h":47}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-scroll-3", "frame": {"x":693,"y":2,"w":13,"h":47}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":13,"h":47}, "sourceSize": {"w":13,"h":47}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-scroll-4", "frame": {"x":723,"y":2,"w":13,"h":47}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":13,"h":47}, "sourceSize": {"w":13,"h":47}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-scroll-preview", "frame": {"x":708,"y":2,"w":13,"h":47}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":13,"h":47}, "sourceSize": {"w":13,"h":47}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-side-1", "frame": {"x":1323,"y":55,"w":19,"h":76}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":19,"h":76}, "sourceSize": {"w":19,"h":76}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-side-2", "frame": {"x":1302,"y":55,"w":19,"h":76}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":19,"h":76}, "sourceSize": {"w":19,"h":76}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-side-3", "frame": {"x":1281,"y":55,"w":19,"h":76}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":19,"h":76}, "sourceSize": {"w":19,"h":76}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-side-4", "frame": {"x":1365,"y":55,"w":19,"h":76}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":19,"h":76}, "sourceSize": {"w":19,"h":76}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-side-preview", "frame": {"x":1344,"y":55,"w":19,"h":76}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":19,"h":76}, "sourceSize": {"w":19,"h":76}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-sushi-1", "frame": {"x":499,"y":2,"w":36,"h":13}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":36,"h":13}, "sourceSize": {"w":36,"h":13}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-sushi-2", "frame": {"x":423,"y":2,"w":36,"h":13}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":36,"h":13}, "sourceSize": {"w":36,"h":13}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-sushi-3", "frame": {"x":461,"y":2,"w":36,"h":13}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":36,"h":13}, "sourceSize": {"w":36,"h":13}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "banner-sushi-preview", "frame": {"x":537,"y":2,"w":36,"h":13}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":36,"h":13}, "sourceSize": {"w":36,"h":13}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "climb-1", "frame": {"x":63,"y":55,"w":15,"h":55}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":30,"y":10,"w":15,"h":55}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "climb-2", "frame": {"x":969,"y":2,"w":15,"h":49}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":30,"y":16,"w":15,"h":49}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "climb-3", "frame": {"x":627,"y":2,"w":16,"h":40}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":30,"y":19,"w":16,"h":40}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "climb-4", "frame": {"x":46,"y":55,"w":15,"h":55}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":31,"y":10,"w":15,"h":55}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "climb-5", "frame": {"x":952,"y":2,"w":15,"h":49}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":31,"y":16,"w":15,"h":49}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "climb-6", "frame": {"x":645,"y":2,"w":16,"h":40}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":30,"y":19,"w":16,"h":40}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "climb-preview", "frame": {"x":102,"y":55,"w":15,"h":55}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":30,"y":10,"w":15,"h":55}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "control-box-1", "frame": {"x":764,"y":2,"w":32,"h":30}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":32,"h":30}, "sourceSize": {"w":32,"h":30}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "control-box-2", "frame": {"x":216,"y":2,"w":16,"h":27}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":0,"y":0,"w":16,"h":27}, "sourceSize": {"w":17,"h":27}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "control-box-3", "frame": {"x":982,"y":55,"w":62,"h":30}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":62,"h":30}, "sourceSize": {"w":62,"h":30}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "crouch", "frame": {"x":1022,"y":2,"w":33,"h":33}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":21,"y":34,"w":33,"h":33}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "drone-1", "frame": {"x":546,"y":55,"w":34,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":13,"y":4,"w":34,"h":48}, "sourceSize": {"w":55,"h":52}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "drone-2", "frame": {"x":343,"y":55,"w":29,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":11,"y":4,"w":29,"h":48}, "sourceSize": {"w":55,"h":52}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "drone-3", "frame": {"x":444,"y":55,"w":31,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":12,"y":3,"w":31,"h":48}, "sourceSize": {"w":55,"h":52}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "drone-4", "frame": {"x":312,"y":55,"w":29,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":15,"y":4,"w":29,"h":48}, "sourceSize": {"w":55,"h":52}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "drone_preview", "frame": {"x":510,"y":55,"w":34,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":13,"y":4,"w":34,"h":48}, "sourceSize": {"w":55,"h":52}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "enemy-explosion-1", "frame": {"x":825,"y":2,"w":31,"h":31}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":12,"y":13,"w":31,"h":31}, "sourceSize": {"w":55,"h":52}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "enemy-explosion-2", "frame": {"x":582,"y":55,"w":42,"h":40}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":5,"y":9,"w":42,"h":40}, "sourceSize": {"w":55,"h":52}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "enemy-explosion-3", "frame": {"x":1231,"y":55,"w":48,"h":46}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":2,"y":4,"w":48,"h":46}, "sourceSize": {"w":55,"h":52}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "enemy-explosion-4", "frame": {"x":273,"y":133,"w":52,"h":50}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":2,"w":52,"h":50}, "sourceSize": {"w":55,"h":52}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "enemy-explosion-5", "frame": {"x":555,"y":133,"w":55,"h":52}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":55,"h":52}, "sourceSize": {"w":55,"h":52}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "enemy-explosion-6", "frame": {"x":498,"y":133,"w":55,"h":52}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":55,"h":52}, "sourceSize": {"w":55,"h":52}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "enemy-explosion-preview", "frame": {"x":662,"y":55,"w":34,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":13,"y":4,"w":34,"h":48}, "sourceSize": {"w":55,"h":52}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "hurt", "frame": {"x":141,"y":55,"w":25,"h":47}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":21,"y":20,"w":25,"h":47}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "idle-1", "frame": {"x":1057,"y":2,"w":21,"h":46}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":28,"y":21,"w":21,"h":46}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "idle-2", "frame": {"x":24,"y":55,"w":20,"h":50}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":28,"y":17,"w":20,"h":50}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "idle-3", "frame": {"x":119,"y":55,"w":20,"h":51}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":28,"y":16,"w":20,"h":51}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "idle-4", "frame": {"x":80,"y":55,"w":20,"h":50}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":28,"y":17,"w":20,"h":50}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "idle-peview", "frame": {"x":1080,"y":2,"w":21,"h":46}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":28,"y":21,"w":21,"h":46}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "jump-1", "frame": {"x":626,"y":55,"w":34,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":22,"y":14,"w":34,"h":48}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "jump-2", "frame": {"x":269,"y":55,"w":41,"h":35}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":15,"y":15,"w":41,"h":35}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "jump-3", "frame": {"x":1342,"y":2,"w":37,"h":32}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":21,"y":18,"w":37,"h":32}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "jump-4", "frame": {"x":233,"y":55,"w":34,"h":40}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":23,"y":16,"w":34,"h":40}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "jump-preview", "frame": {"x":2,"y":55,"w":20,"h":50}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":28,"y":17,"w":20,"h":50}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "monitor-face-1", "frame": {"x":193,"y":2,"w":21,"h":18}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":21,"h":18}, "sourceSize": {"w":21,"h":18}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "monitor-face-2", "frame": {"x":101,"y":2,"w":21,"h":18}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":21,"h":18}, "sourceSize": {"w":21,"h":18}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "monitor-face-3", "frame": {"x":124,"y":2,"w":21,"h":18}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":21,"h":18}, "sourceSize": {"w":21,"h":18}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "monitor-face-4", "frame": {"x":147,"y":2,"w":21,"h":18}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":21,"h":18}, "sourceSize": {"w":21,"h":18}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "monitorface_preview", "frame": {"x":170,"y":2,"w":21,"h":18}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":21,"h":18}, "sourceSize": {"w":21,"h":18}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-1", "frame": {"x":1046,"y":55,"w":41,"h":51}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":10,"y":16,"w":41,"h":51}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-2", "frame": {"x":1138,"y":55,"w":47,"h":46}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":7,"y":18,"w":47,"h":46}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-3", "frame": {"x":735,"y":55,"w":36,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":16,"y":19,"w":36,"h":48}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-4", "frame": {"x":205,"y":55,"w":26,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":26,"y":19,"w":26,"h":48}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-5", "frame": {"x":1187,"y":55,"w":42,"h":51}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":10,"y":16,"w":42,"h":51}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-6", "frame": {"x":1089,"y":55,"w":47,"h":46}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":7,"y":18,"w":47,"h":46}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-7", "frame": {"x":698,"y":55,"w":35,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":16,"y":19,"w":35,"h":48}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-8", "frame": {"x":477,"y":55,"w":31,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":21,"y":19,"w":31,"h":48}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-preview", "frame": {"x":939,"y":55,"w":41,"h":51}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":10,"y":16,"w":41,"h":51}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-shoot-1", "frame": {"x":162,"y":133,"w":51,"h":51}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":10,"y":16,"w":51,"h":51}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-shoot-2", "frame": {"x":52,"y":133,"w":55,"h":46}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":7,"y":18,"w":55,"h":46}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-shoot-3", "frame": {"x":1386,"y":55,"w":47,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":16,"y":19,"w":47,"h":48}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-shoot-4", "frame": {"x":819,"y":55,"w":37,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":26,"y":19,"w":37,"h":48}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-shoot-5", "frame": {"x":327,"y":133,"w":53,"h":51}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":10,"y":16,"w":53,"h":51}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-shoot-6", "frame": {"x":215,"y":133,"w":56,"h":46}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":7,"y":18,"w":56,"h":46}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-shoot-7", "frame": {"x":2,"y":133,"w":48,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":16,"y":19,"w":48,"h":48}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-shoot-8", "frame": {"x":895,"y":55,"w":42,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":21,"y":19,"w":42,"h":48}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "run-shoot-preview", "frame": {"x":109,"y":133,"w":51,"h":51}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":10,"y":16,"w":51,"h":51}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "shoot", "frame": {"x":858,"y":55,"w":35,"h":51}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":20,"y":16,"w":35,"h":51}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "shot-1", "frame": {"x":41,"y":2,"w":12,"h":5}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":3,"w":12,"h":5}, "sourceSize": {"w":15,"h":11}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "shot-2", "frame": {"x":2,"y":2,"w":10,"h":7}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":2,"w":10,"h":7}, "sourceSize": {"w":15,"h":11}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "shot-3", "frame": {"x":14,"y":2,"w":11,"h":6}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":3,"w":11,"h":6}, "sourceSize": {"w":15,"h":11}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "shot-hit-1", "frame": {"x":55,"y":2,"w":9,"h":9}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":1,"w":9,"h":9}, "sourceSize": {"w":15,"h":11}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "shot-hit-2", "frame": {"x":66,"y":2,"w":9,"h":9}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":1,"w":9,"h":9}, "sourceSize": {"w":15,"h":11}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "shot-hit-3", "frame": {"x":88,"y":2,"w":11,"h":11}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":2,"y":0,"w":11,"h":11}, "sourceSize": {"w":15,"h":11}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "shot-hit-preview", "frame": {"x":77,"y":2,"w":9,"h":9}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":3,"y":1,"w":9,"h":9}, "sourceSize": {"w":15,"h":11}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "shot-preview", "frame": {"x":27,"y":2,"w":12,"h":5}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":1,"y":3,"w":12,"h":5}, "sourceSize": {"w":15,"h":11}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "turret-1", "frame": {"x":315,"y":2,"w":25,"h":23}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":25,"h":23}, "sourceSize": {"w":25,"h":23}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "turret-2", "frame": {"x":342,"y":2,"w":25,"h":23}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":25,"h":23}, "sourceSize": {"w":25,"h":23}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "turret-3", "frame": {"x":261,"y":2,"w":25,"h":23}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":25,"h":23}, "sourceSize": {"w":25,"h":23}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "turret-4", "frame": {"x":234,"y":2,"w":25,"h":23}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":25,"h":23}, "sourceSize": {"w":25,"h":23}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "turret-5", "frame": {"x":288,"y":2,"w":25,"h":23}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":25,"h":23}, "sourceSize": {"w":25,"h":23}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "turret-6", "frame": {"x":396,"y":2,"w":25,"h":23}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":25,"h":23}, "sourceSize": {"w":25,"h":23}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "turret-preview", "frame": {"x":369,"y":2,"w":25,"h":23}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":25,"h":23}, "sourceSize": {"w":25,"h":23}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "v-police", "frame": {"x":1013,"y":133,"w":163,"h":60}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":163,"h":60}, "sourceSize": {"w":163,"h":60}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "v-red", "frame": {"x":915,"y":133,"w":96,"h":61}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":96,"h":61}, "sourceSize": {"w":96,"h":61}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "v-truck", "frame": {"x":1178,"y":133,"w":257,"h":104}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":257,"h":104}, "sourceSize": {"w":257,"h":104}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "v-yellow", "frame": {"x":820,"y":133,"w":93,"h":60}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":93,"h":60}, "sourceSize": {"w":93,"h":60}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-1", "frame": {"x":1320,"y":2,"w":20,"h":49}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":28,"y":18,"w":20,"h":49}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-10", "frame": {"x":1257,"y":2,"w":19,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":26,"y":19,"w":19,"h":48}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-11", "frame": {"x":986,"y":2,"w":16,"h":49}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":27,"y":18,"w":16,"h":49}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-12", "frame": {"x":738,"y":2,"w":11,"h":50}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":30,"y":17,"w":11,"h":50}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-13", "frame": {"x":895,"y":2,"w":11,"h":51}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":30,"y":16,"w":11,"h":51}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-14", "frame": {"x":937,"y":2,"w":13,"h":51}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":29,"y":16,"w":13,"h":51}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-15", "frame": {"x":921,"y":2,"w":14,"h":50}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":28,"y":17,"w":14,"h":50}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-16", "frame": {"x":1381,"y":2,"w":19,"h":50}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":27,"y":17,"w":19,"h":50}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-2", "frame": {"x":1154,"y":2,"w":19,"h":48}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":26,"y":19,"w":19,"h":48}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-3", "frame": {"x":1004,"y":2,"w":16,"h":49}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":27,"y":18,"w":16,"h":49}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-4", "frame": {"x":751,"y":2,"w":11,"h":50}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":30,"y":17,"w":11,"h":50}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-5", "frame": {"x":908,"y":2,"w":11,"h":51}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":30,"y":16,"w":11,"h":51}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-6", "frame": {"x":798,"y":2,"w":11,"h":51}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":30,"y":16,"w":11,"h":51}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-7", "frame": {"x":811,"y":2,"w":12,"h":50}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":30,"y":17,"w":12,"h":50}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-8", "frame": {"x":1175,"y":2,"w":17,"h":50}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":29,"y":17,"w":17,"h":50}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-9", "frame": {"x":1299,"y":2,"w":19,"h":49}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":29,"y":18,"w":19,"h":49}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }, { "filename": "walk-preview", "frame": {"x":1402,"y":2,"w":20,"h":49}, "rotated": false, "trimmed": true, "spriteSourceSize": {"x":28,"y":18,"w":20,"h":49}, "sourceSize": {"w":71,"h":67}, "pivot": {"x":0.5,"y":0.5} }], "meta": { "app": "http://www.codeandweb.com/texturepacker", "version": "1.0", "image": "atlas.png", "format": "RGBA8888", "size": {"w":1437,"h":239}, "scale": "1", "smartupdate": "$TexturePacker:SmartUpdate:133d307a83f4c0480bfd6bd8d553a8ee:a09b2f18f63aa97ec00a8aa0c1bb7edd:cbce6b53f0f49e0bf15173c25c41f876$" } } |
Added src/fahombo/assets/warped_city/atlas/atlas.png.
cannot compute difference between binary files
Added src/fahombo/assets/warped_city/atlas/atlas.tps.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 |
<?xml version="1.0" encoding="UTF-8"?> <data version="1.0"> <struct type="Settings"> <key>fileFormatVersion</key> <int>3</int> <key>texturePackerVersion</key> <string>3.5.2</string> <key>fileName</key> <string>/Users/luiszuno/Documents/GameDev/Phaser/artpacks/2019/warped-city/assets/atlas/atlas.tps</string> <key>autoSDSettings</key> <array> <struct type="AutoSDSettings"> <key>scale</key> <double>1</double> <key>extension</key> <string></string> <key>spriteFilter</key> <string></string> <key>acceptFractionalValues</key> <false/> <key>maxTextureSize</key> <QSize> <key>width</key> <int>-1</int> <key>height</key> <int>-1</int> </QSize> </struct> </array> <key>allowRotation</key> <true/> <key>premultiplyAlpha</key> <false/> <key>shapeDebug</key> <false/> <key>dpi</key> <uint>72</uint> <key>dataFormat</key> <string>json-array</string> <key>textureFileName</key> <filename>atlas.png</filename> <key>flipPVR</key> <false/> <key>pvrCompressionQuality</key> <enum type="SettingsBase::PvrCompressionQuality">PVR_QUALITY_NORMAL</enum> <key>mipMapMinSize</key> <uint>32768</uint> <key>etc1CompressionQuality</key> <enum type="SettingsBase::Etc1CompressionQuality">ETC1_QUALITY_LOW_PERCEPTUAL</enum> <key>dxtCompressionMode</key> <enum type="SettingsBase::DxtCompressionMode">DXT_PERCEPTUAL</enum> <key>jxrColorFormat</key> <enum type="SettingsBase::JpegXrColorMode">JXR_YUV444</enum> <key>jxrTrimFlexBits</key> <uint>0</uint> <key>jxrCompressionLevel</key> <uint>0</uint> <key>ditherType</key> <enum type="SettingsBase::DitherType">NearestNeighbour</enum> <key>backgroundColor</key> <uint>0</uint> <key>libGdx</key> <struct type="LibGDX"> <key>filtering</key> <struct type="LibGDXFiltering"> <key>x</key> <enum type="LibGDXFiltering::Filtering">Linear</enum> <key>y</key> <enum type="LibGDXFiltering::Filtering">Linear</enum> </struct> </struct> <key>shapePadding</key> <uint>2</uint> <key>jpgQuality</key> <uint>80</uint> <key>pngOptimizationLevel</key> <uint>0</uint> <key>webpQualityLevel</key> <uint>101</uint> <key>textureSubPath</key> <string></string> <key>textureFormat</key> <enum type="SettingsBase::TextureFormat">png</enum> <key>borderPadding</key> <uint>2</uint> <key>maxTextureSize</key> <QSize> <key>width</key> <int>2048</int> <key>height</key> <int>2048</int> </QSize> <key>fixedTextureSize</key> <QSize> <key>width</key> <int>-1</int> <key>height</key> <int>-1</int> </QSize> <key>reduceBorderArtifacts</key> <false/> <key>algorithmSettings</key> <struct type="AlgorithmSettings"> <key>algorithm</key> <enum type="AlgorithmSettings::AlgorithmId">Basic</enum> <key>freeSizeMode</key> <enum type="AlgorithmSettings::AlgorithmFreeSizeMode">Best</enum> <key>sizeConstraints</key> <enum type="AlgorithmSettings::SizeConstraints">AnySize</enum> <key>forceSquared</key> <false/> <key>forceWordAligned</key> <false/> <key>maxRects</key> <struct type="AlgorithmMaxRectsSettings"> <key>heuristic</key> <enum type="AlgorithmMaxRectsSettings::Heuristic">Best</enum> </struct> <key>basic</key> <struct type="AlgorithmBasicSettings"> <key>sortBy</key> <enum type="AlgorithmBasicSettings::SortBy">Best</enum> <key>order</key> <enum type="AlgorithmBasicSettings::Order">Ascending</enum> </struct> </struct> <key>andEngine</key> <struct type="AndEngine"> <key>minFilter</key> <enum type="AndEngine::MinFilter">Linear</enum> <key>packageName</key> <string>Texture</string> <key>wrap</key> <struct type="AndEngineWrap"> <key>s</key> <enum type="AndEngineWrap::Wrap">Clamp</enum> <key>t</key> <enum type="AndEngineWrap::Wrap">Clamp</enum> </struct> <key>magFilter</key> <enum type="AndEngine::MagFilter">MagLinear</enum> </struct> <key>dataFileNames</key> <map type="GFileNameMap"> <key>data</key> <struct type="DataFile"> <key>name</key> <filename>atlas.json</filename> </struct> </map> <key>multiPack</key> <false/> <key>forceIdenticalLayout</key> <false/> <key>outputFormat</key> <enum type="SettingsBase::OutputFormat">RGBA8888</enum> <key>contentProtection</key> <struct type="ContentProtection"> <key>key</key> <string></string> </struct> <key>autoAliasEnabled</key> <false/> <key>trimSpriteNames</key> <true/> <key>prependSmartFolderName</key> <false/> <key>cleanTransparentPixels</key> <true/> <key>globalSpriteSettings</key> <struct type="SpriteSettings"> <key>scale</key> <double>1</double> <key>scaleMode</key> <enum type="ScaleMode">Smooth</enum> <key>innerPadding</key> <uint>0</uint> <key>extrude</key> <uint>0</uint> <key>trimThreshold</key> <uint>1</uint> <key>trimMode</key> <enum type="SpriteSettings::TrimMode">Trim</enum> <key>heuristicMask</key> <false/> <key>pivotPoint</key> <enum type="SpriteSettings::PivotPoint">Center</enum> </struct> <key>fileList</key> <array> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/player/back-jump</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/player/climb</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/player/crouch</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/player/hurt</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/player/idle</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/player/jump</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/player/run</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/player/shoot</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/player/walk</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/vehicles</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/ENVIRONMENT/props/antenna.png</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/ENVIRONMENT/props/control-box-1.png</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/ENVIRONMENT/props/control-box-2.png</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/ENVIRONMENT/props/control-box-3.png</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/ENVIRONMENT/props/banner-big</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/ENVIRONMENT/props/banner-coke</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/ENVIRONMENT/props/banner-neon</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/ENVIRONMENT/props/banner-scroll</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/ENVIRONMENT/props/banner-side</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/ENVIRONMENT/props/banner-sushi</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/ENVIRONMENT/props/monitorface</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/misc/drone</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/misc/enemy-explosion</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/misc/shot</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/misc/shot-hit</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/misc/turret</filename> <filename>../../../../../../../ansimuz resources/ART PACKS/2019/warped city/warped city files/SPRITES/player/run-shoot</filename> </array> <key>ignoreFileList</key> <array/> <key>replaceList</key> <array/> <key>ignoredWarnings</key> <array/> <key>commonDivisorX</key> <uint>1</uint> <key>commonDivisorY</key> <uint>1</uint> </struct> </data> |
Added src/fahombo/assets/warped_city/environment/bg-1.png.
cannot compute difference between binary files
Added src/fahombo/assets/warped_city/environment/bg-2.png.
cannot compute difference between binary files
Added src/fahombo/assets/warped_city/environment/bg-3.png.
cannot compute difference between binary files
Added src/fahombo/assets/warped_city/environment/tileset.png.
cannot compute difference between binary files
Added src/fahombo/assets/warped_city/maps/map.json.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
{ "backgroundcolor":"#0000ff", "height":28, "infinite":false, "layers":[ { "data":[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], "height":28, "name":"Collisions Layer", "opacity":1, "type":"tilelayer", "visible":true, "width":120, "x":0, "y":0 }, { "data":[0, 26, 76, 77, 78, 29, 29, 76, 77, 78, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 39, 40, 41, 37, 159, 160, 161, 37, 279, 280, 281, 37, 39, 40, 41, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 76, 77, 78, 245, 29, 76, 77, 78, 80, 0, 50, 100, 101, 102, 29, 29, 100, 101, 102, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 63, 64, 65, 61, 183, 184, 185, 61, 303, 304, 305, 61, 63, 64, 65, 67, 68, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 100, 101, 102, 269, 29, 100, 101, 102, 56, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 83, 87, 88, 89, 85, 207, 208, 209, 85, 327, 328, 329, 61, 87, 88, 89, 91, 92, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 0, 26, 28, 29, 30, 245, 163, 28, 29, 30, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 107, 111, 112, 113, 109, 231, 232, 233, 85, 351, 352, 353, 61, 111, 112, 113, 115, 116, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 225, 224, 224, 224, 0, 0, 0, 224, 224, 224, 225, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 28, 29, 30, 228, 229, 28, 29, 30, 32, 0, 50, 52, 53, 54, 269, 187, 52, 53, 54, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 52, 53, 54, 252, 253, 52, 53, 54, 32, 0, 74, 76, 77, 78, 245, 29, 76, 77, 78, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 39, 40, 41, 37, 159, 160, 161, 37, 39, 40, 41, 37, 279, 280, 281, 43, 44, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 29, 29, 29, 29, 165, 147, 29, 228, 229, 43, 44, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 76, 77, 78, 167, 29, 76, 77, 78, 56, 0, 26, 100, 101, 102, 269, 29, 100, 101, 102, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 63, 64, 65, 61, 183, 184, 185, 61, 63, 64, 65, 61, 303, 304, 305, 67, 68, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 189, 189, 29, 29, 29, 147, 29, 252, 253, 67, 68, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 100, 101, 102, 191, 29, 100, 101, 102, 80, 0, 50, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 83, 87, 88, 89, 109, 207, 208, 209, 85, 87, 88, 89, 61, 327, 328, 329, 91, 92, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 83, 165, 189, 29, 29, 29, 147, 29, 29, 29, 91, 92, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 273, 272, 272, 272, 272, 272, 272, 272, 272, 272, 0, 74, 28, 29, 30, 228, 229, 28, 29, 30, 32, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 107, 111, 112, 113, 85, 231, 232, 233, 85, 111, 112, 113, 61, 351, 352, 353, 115, 116, 0, 0, 0, 0, 224, 224, 225, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 107, 29, 29, 29, 29, 29, 147, 29, 29, 29, 115, 116, 0, 0, 0, 0, 224, 224, 225, 224, 224, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 50, 28, 29, 30, 167, 245, 28, 29, 30, 56, 0, 26, 52, 53, 54, 252, 253, 52, 53, 54, 32, 0, 0, 0, 0, 0, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 147, 272, 272, 272, 272, 272, 274, 0, 0, 271, 272, 272, 272, 272, 272, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 83, 155, 156, 157, 29, 29, 147, 29, 189, 165, 67, 68, 0, 0, 0, 271, 272, 272, 272, 272, 272, 274, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 50, 52, 53, 54, 191, 245, 52, 53, 54, 56, 0, 50, 76, 77, 78, 29, 29, 76, 77, 78, 56, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 279, 280, 281, 37, 159, 160, 161, 37, 39, 40, 41, 147, 159, 160, 161, 43, 44, 0, 0, 0, 0, 26, 245, 167, 29, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 107, 179, 180, 181, 29, 29, 147, 29, 189, 189, 91, 92, 0, 0, 0, 0, 26, 245, 167, 29, 56, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 26, 76, 77, 78, 167, 245, 76, 77, 78, 32, 0, 74, 100, 101, 102, 29, 29, 100, 101, 102, 80, 0, 0, 0, 224, 224, 225, 224, 224, 224, 224, 224, 224, 224, 0, 0, 0, 0, 58, 59, 303, 304, 305, 61, 183, 184, 185, 61, 63, 64, 65, 147, 183, 184, 185, 67, 68, 0, 0, 0, 0, 50, 245, 191, 29, 32, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 147, 272, 272, 272, 272, 272, 274, 0, 0, 0, 50, 245, 191, 29, 32, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 50, 100, 101, 102, 191, 269, 100, 101, 102, 56, 271, 273, 272, 272, 272, 147, 272, 272, 272, 272, 272, 274, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 82, 83, 327, 328, 329, 85, 207, 208, 209, 85, 87, 88, 89, 147, 207, 208, 209, 91, 92, 0, 0, 0, 0, 74, 245, 167, 29, 56, 0, 0, 0, 0, 0, 34, 35, 228, 229, 29, 37, 29, 228, 229, 37, 228, 229, 29, 147, 167, 29, 29, 43, 44, 0, 0, 0, 0, 74, 245, 167, 29, 56, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 50, 28, 29, 30, 147, 245, 28, 29, 30, 56, 0, 0, 0, 26, 228, 229, 245, 149, 29, 163, 228, 229, 32, 0, 0, 0, 0, 106, 107, 351, 352, 353, 85, 231, 232, 233, 85, 111, 112, 113, 147, 231, 232, 233, 115, 116, 0, 0, 0, 0, 26, 245, 191, 29, 56, 0, 0, 0, 0, 0, 58, 59, 252, 253, 29, 61, 29, 252, 253, 61, 252, 253, 29, 147, 191, 29, 29, 67, 68, 0, 0, 0, 0, 26, 245, 191, 29, 56, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 26, 28, 29, 30, 245, 163, 28, 29, 30, 32, 0, 50, 52, 53, 54, 147, 245, 52, 53, 54, 56, 0, 0, 0, 50, 252, 253, 245, 173, 29, 187, 252, 253, 56, 0, 0, 0, 271, 272, 272, 272, 272, 272, 61, 46, 46, 46, 46, 46, 46, 46, 147, 272, 272, 272, 272, 272, 274, 0, 0, 0, 50, 245, 167, 29, 56, 0, 0, 0, 0, 0, 82, 83, 165, 165, 29, 109, 29, 189, 189, 61, 189, 189, 29, 147, 167, 29, 189, 91, 92, 0, 0, 0, 0, 50, 245, 167, 29, 56, 0, 0, 0, 0, 224, 224, 225, 224, 224, 0, 0, 0, 0, 224, 224, 225, 224, 224, 0, 0, 0, 50, 52, 53, 54, 269, 187, 52, 53, 54, 56, 0, 26, 76, 77, 78, 147, 245, 76, 77, 78, 32, 0, 0, 0, 74, 29, 29, 245, 173, 29, 29, 29, 167, 80, 0, 0, 0, 0, 34, 35, 39, 40, 41, 61, 228, 229, 29, 29, 29, 228, 229, 147, 39, 40, 41, 43, 44, 0, 0, 0, 0, 74, 245, 191, 29, 80, 0, 0, 0, 0, 0, 106, 107, 189, 189, 29, 61, 29, 189, 165, 61, 189, 189, 29, 147, 191, 29, 29, 115, 116, 0, 0, 0, 0, 74, 245, 191, 29, 80, 0, 0, 0, 271, 272, 272, 272, 272, 272, 274, 0, 0, 271, 272, 272, 272, 272, 272, 274, 0, 0, 74, 76, 77, 78, 245, 29, 76, 77, 78, 80, 0, 50, 100, 101, 102, 147, 269, 100, 101, 102, 56, 0, 0, 0, 26, 163, 29, 245, 173, 29, 29, 29, 191, 32, 0, 0, 0, 0, 58, 59, 63, 64, 65, 61, 252, 253, 29, 29, 29, 252, 253, 147, 63, 64, 65, 67, 68, 0, 0, 0, 0, 26, 228, 229, 29, 56, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 147, 46, 46, 46, 46, 46, 0, 0, 0, 0, 26, 228, 229, 29, 56, 0, 0, 0, 0, 26, 245, 167, 29, 56, 0, 0, 0, 0, 26, 245, 167, 29, 56, 0, 0, 0, 26, 100, 101, 102, 269, 29, 100, 101, 102, 56, 0, 46, 46, 46, 46, 147, 46, 46, 46, 46, 46, 0, 0, 0, 50, 187, 29, 245, 173, 155, 156, 157, 29, 56, 0, 0, 0, 0, 82, 83, 87, 88, 89, 85, 165, 29, 155, 156, 157, 29, 29, 147, 87, 88, 89, 91, 92, 0, 0, 0, 0, 50, 252, 253, 29, 56, 0, 0, 0, 0, 0, 34, 35, 279, 280, 281, 37, 159, 160, 161, 37, 39, 40, 41, 147, 159, 160, 161, 43, 44, 0, 0, 0, 0, 50, 252, 253, 29, 56, 0, 0, 0, 0, 50, 245, 191, 29, 32, 0, 0, 0, 0, 50, 245, 191, 29, 32, 0, 0, 0, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 0, 26, 28, 29, 30, 147, 29, 28, 29, 30, 32, 0, 0, 0, 74, 29, 189, 189, 173, 179, 180, 181, 29, 80, 0, 0, 0, 0, 106, 107, 111, 112, 113, 109, 189, 29, 179, 180, 181, 29, 29, 171, 111, 112, 113, 115, 116, 0, 0, 0, 0, 74, 29, 167, 29, 80, 0, 0, 0, 0, 0, 58, 59, 303, 304, 305, 61, 183, 184, 185, 61, 63, 64, 65, 147, 183, 184, 185, 67, 68, 0, 0, 0, 0, 74, 29, 167, 29, 80, 0, 0, 0, 0, 74, 245, 167, 29, 56, 0, 0, 0, 0, 74, 245, 167, 29, 56, 0, 0, 0, 74, 28, 29, 30, 228, 229, 28, 29, 30, 32, 0, 50, 52, 53, 54, 147, 29, 52, 53, 54, 56, 0, 0, 0, 26, 29, 163, 163, 173, 228, 229, 167, 29, 32, 0, 0, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 26, 29, 191, 29, 56, 0, 0, 0, 0, 0, 82, 83, 327, 328, 329, 85, 207, 208, 209, 85, 87, 88, 89, 147, 207, 208, 209, 91, 92, 0, 0, 0, 0, 26, 29, 191, 29, 56, 0, 0, 0, 0, 26, 245, 191, 29, 56, 0, 0, 0, 0, 26, 245, 191, 29, 56, 0, 0, 0, 26, 52, 53, 54, 252, 253, 52, 53, 54, 32, 0, 74, 76, 77, 78, 147, 163, 76, 77, 78, 80, 0, 0, 0, 50, 29, 187, 187, 197, 252, 253, 191, 29, 56, 0, 0, 0, 0, 34, 35, 159, 160, 161, 37, 159, 160, 161, 37, 279, 280, 281, 37, 39, 40, 41, 43, 44, 0, 0, 0, 0, 50, 29, 167, 29, 56, 0, 0, 0, 0, 0, 106, 107, 351, 352, 353, 85, 231, 232, 233, 85, 111, 112, 113, 171, 231, 232, 233, 115, 116, 0, 0, 0, 0, 50, 29, 167, 29, 56, 0, 0, 0, 0, 50, 245, 167, 29, 56, 0, 0, 0, 0, 50, 245, 167, 29, 56, 0, 0, 0, 50, 76, 77, 78, 29, 167, 76, 77, 78, 56, 0, 26, 100, 101, 102, 171, 187, 100, 101, 102, 56, 0, 0, 0, 74, 29, 245, 245, 29, 173, 29, 167, 29, 80, 0, 0, 0, 0, 58, 59, 183, 184, 185, 61, 183, 184, 185, 61, 303, 304, 305, 109, 63, 64, 65, 67, 68, 0, 0, 0, 0, 74, 29, 191, 29, 56, 0, 0, 0, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 74, 29, 191, 29, 56, 0, 0, 0, 0, 74, 245, 191, 29, 80, 0, 0, 0, 0, 74, 245, 191, 29, 80, 0, 0, 0, 74, 100, 101, 102, 29, 191, 100, 101, 102, 80, 0, 50, 272, 272, 272, 272, 272, 272, 272, 147, 272, 274, 0, 0, 26, 29, 245, 245, 29, 173, 29, 191, 29, 32, 0, 0, 0, 0, 82, 83, 207, 208, 209, 85, 207, 208, 209, 85, 327, 328, 329, 61, 87, 88, 89, 91, 92, 0, 0, 0, 0, 26, 29, 167, 29, 56, 0, 0, 0, 0, 0, 34, 35, 39, 40, 41, 61, 159, 160, 161, 61, 159, 160, 161, 37, 39, 40, 41, 43, 44, 0, 0, 0, 0, 26, 29, 167, 29, 56, 0, 0, 0, 0, 26, 228, 229, 29, 56, 0, 0, 0, 0, 26, 228, 229, 29, 56, 0, 0, 0, 273, 272, 272, 272, 272, 272, 272, 272, 272, 272, 0, 74, 28, 29, 30, 228, 229, 28, 29, 147, 32, 0, 0, 0, 50, 29, 245, 245, 29, 173, 189, 189, 189, 56, 0, 0, 0, 0, 106, 107, 231, 232, 233, 85, 231, 232, 233, 85, 351, 352, 353, 61, 111, 112, 113, 115, 116, 0, 0, 0, 0, 50, 29, 191, 29, 56, 0, 0, 0, 0, 0, 58, 59, 63, 64, 65, 61, 183, 184, 185, 61, 183, 184, 185, 61, 63, 64, 65, 67, 68, 0, 0, 0, 0, 50, 29, 191, 29, 56, 0, 0, 0, 0, 50, 252, 253, 29, 56, 0, 0, 0, 0, 50, 252, 253, 29, 56, 0, 0, 0, 50, 28, 29, 30, 29, 245, 28, 29, 30, 56, 0, 26, 52, 53, 54, 252, 253, 52, 53, 147, 32, 0, 0, 0, 74, 29, 245, 245, 29, 173, 189, 189, 189, 80, 0, 0, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 74, 29, 167, 29, 56, 0, 0, 0, 0, 0, 82, 83, 87, 88, 89, 85, 207, 208, 209, 61, 207, 208, 209, 109, 87, 88, 89, 91, 92, 0, 0, 0, 0, 74, 29, 167, 29, 56, 0, 0, 0, 0, 74, 29, 167, 29, 80, 0, 0, 0, 0, 74, 29, 167, 29, 80, 0, 0, 0, 50, 52, 53, 54, 29, 245, 52, 53, 54, 56, 0, 50, 76, 77, 78, 29, 29, 76, 77, 147, 56, 0, 0, 0, 26, 29, 197, 245, 29, 173, 29, 29, 29, 32, 0, 0, 0, 0, 34, 35, 39, 40, 41, 37, 159, 160, 161, 37, 39, 40, 41, 37, 39, 40, 41, 43, 44, 0, 0, 0, 0, 50, 29, 191, 29, 56, 0, 0, 0, 0, 0, 106, 107, 111, 112, 113, 109, 231, 232, 233, 61, 231, 232, 233, 61, 111, 112, 113, 115, 116, 0, 0, 0, 0, 50, 29, 191, 29, 56, 0, 0, 0, 0, 26, 29, 191, 29, 56, 0, 0, 0, 0, 26, 29, 191, 29, 56, 0, 0, 0, 26, 76, 77, 78, 29, 245, 76, 77, 78, 32, 0, 74, 100, 101, 102, 29, 29, 100, 101, 171, 80, 0, 0, 0, 50, 155, 156, 157, 29, 173, 29, 228, 229, 56, 0, 0, 0, 0, 58, 59, 63, 64, 65, 61, 183, 184, 185, 61, 63, 64, 65, 61, 63, 64, 65, 67, 68, 0, 0, 0, 0, 50, 155, 156, 157, 80, 0, 0, 0, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 50, 155, 156, 157, 80, 0, 0, 0, 0, 50, 29, 167, 29, 56, 0, 0, 0, 0, 50, 29, 167, 29, 56, 0, 0, 0, 50, 100, 101, 102, 29, 269, 100, 101, 102, 56, 271, 273, 273, 273, 273, 273, 272, 272, 272, 272, 272, 274, 0, 0, 74, 179, 180, 181, 29, 173, 29, 252, 253, 80, 0, 0, 0, 0, 82, 83, 87, 88, 89, 85, 207, 208, 209, 85, 87, 88, 89, 61, 87, 88, 89, 91, 92, 0, 0, 0, 0, 50, 179, 180, 181, 56, 0, 0, 0, 0, 0, 34, 35, 159, 160, 161, 37, 159, 160, 161, 37, 279, 280, 281, 37, 39, 40, 41, 43, 44, 0, 0, 0, 0, 50, 179, 180, 181, 56, 0, 0, 0, 0, 74, 29, 191, 29, 56, 0, 0, 0, 0, 74, 29, 191, 29, 56, 0, 0, 0, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272], "height":28, "name":"Main Layer", "opacity":1, "type":"tilelayer", "visible":true, "width":120, "x":0, "y":0 }, { "draworder":"topdown", "name":"Object Layer", "objects":[ { "gid":5, "height":16, "id":12, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":294.666666666667, "y":382.333333333333 }, { "gid":6, "height":16, "id":13, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":240.333333333333, "y":300 }, { "gid":7, "height":16, "id":14, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":19.6666666666666, "y":142.666666666667 }, { "gid":8, "height":16, "id":17, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":166, "y":415.666666666667 }, { "gid":9, "height":16, "id":19, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":161, "y":247.333333333333 }, { "gid":11, "height":16, "id":21, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":32.6666666666667, "y":417.666666666667 }, { "gid":11, "height":16, "id":22, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":30.3333333333333, "y":285 }, { "gid":10, "height":16, "id":23, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":248.333333333333, "y":425 }, { "gid":6, "height":16, "id":29, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":737.333333333333, "y":299.333333333333 }, { "gid":5, "height":16, "id":30, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":442, "y":44.6666666666667 }, { "gid":9, "height":16, "id":31, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":811.333333333333, "y":203.333333333333 }, { "gid":10, "height":16, "id":32, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":730, "y":174 }, { "gid":5, "height":16, "id":33, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":1264, "y":313.333333333333 }, { "gid":5, "height":16, "id":34, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":1480.66666666667, "y":291.333333333333 }, { "gid":6, "height":16, "id":35, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":1062.66666666667, "y":90.6666666666667 }, { "gid":10, "height":16, "id":36, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":1646, "y":268 }, { "gid":11, "height":16, "id":37, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":1039.33333333333, "y":264 }, { "gid":11, "height":16, "id":38, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":1370, "y":222.666666666667 }, { "gid":11, "height":16, "id":39, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":1129.33333333333, "y":264 }, { "gid":9, "height":16, "id":40, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":741.333333333333, "y":390.666666666667 }, { "gid":9, "height":16, "id":41, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":323.333333333333, "y":298.666666666667 }, { "gid":11, "height":16, "id":42, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":1798.66666666667, "y":318 }, { "gid":11, "height":16, "id":43, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":1869.33333333333, "y":104.666666666667 }, { "gid":9, "height":16, "id":44, "name":"", "rotation":0, "type":"", "visible":true, "width":16, "x":1908, "y":186.666666666667 }], "opacity":1, "type":"objectgroup", "visible":true, "x":0, "y":0 }], "nextobjectid":45, "orientation":"orthogonal", "renderorder":"right-down", "tiledversion":"1.1.4", "tileheight":16, "tilesets":[ { "columns":24, "firstgid":1, "image":"..\/environment\/tileset.png", "imageheight":256, "imagewidth":384, "margin":0, "name":"tileset", "spacing":0, "tilecount":384, "tileheight":16, "tilewidth":16 }], "tilewidth":16, "type":"map", "version":1, "width":120 } |
Added src/fahombo/assets/warped_city/public-license.txt.
> > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Artwork created by Luis Zuno @ansimuz License for Everyone. Public domain and free to use on whatever you want, personal or commercial. Credit is not required but appreciated. Feeling Grateful? You can support my work at https://www.patreon.com/ansimuz Get more Free Assetslike these at: http://www.pixelgameart.org Additional credits Demo Music by Pascal Belisle pacethemusician@hotmail.com https://soundcloud.com/pascalbelisle |
Changes to src/fahombo/conf.lua.
1 2 3 4 5 6 7 8 9 10 |
love.conf = function(t) t.gammacorrect = true t.title, t.identity = "Fahombo", "fahombo" t.modules.joystick = false t.modules.physics = false t.window.width = 1024 t.window.height = 768 t.window.vsync = false t.version = "11.3" end |
| | |
1 2 3 4 5 6 7 8 9 10 |
love.conf = function(t) t.gammacorrect = true t.title, t.identity = "Fahombo", "fahombo" t.modules.joystick = false t.modules.physics = false t.window.width = 768 t.window.height = 448 t.window.vsync = false t.version = "11.3" end |
Added src/fahombo/lib/bump.lua.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 |
local bump = { _VERSION = 'bump v3.1.7', _URL = 'https://github.com/kikito/bump.lua', _DESCRIPTION = 'A collision detection library for Lua', _LICENSE = [[ MIT LICENSE Copyright (c) 2014 Enrique García Cota Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]] } ------------------------------------------ -- Auxiliary functions ------------------------------------------ local DELTA = 1e-10 -- floating-point margin of error local abs, floor, ceil, min, max = math.abs, math.floor, math.ceil, math.min, math.max local function sign(x) if x > 0 then return 1 end if x == 0 then return 0 end return -1 end local function nearest(x, a, b) if abs(a - x) < abs(b - x) then return a else return b end end local function assertType(desiredType, value, name) if type(value) ~= desiredType then error(name .. ' must be a ' .. desiredType .. ', but was ' .. tostring(value) .. '(a ' .. type(value) .. ')') end end local function assertIsPositiveNumber(value, name) if type(value) ~= 'number' or value <= 0 then error(name .. ' must be a positive integer, but was ' .. tostring(value) .. '(' .. type(value) .. ')') end end local function assertIsRect(x,y,w,h) assertType('number', x, 'x') assertType('number', y, 'y') assertIsPositiveNumber(w, 'w') assertIsPositiveNumber(h, 'h') end local defaultFilter = function() return 'slide' end ------------------------------------------ -- Rectangle functions ------------------------------------------ local function rect_getNearestCorner(x,y,w,h, px, py) return nearest(px, x, x+w), nearest(py, y, y+h) end -- This is a generalized implementation of the liang-barsky algorithm, which also returns -- the normals of the sides where the segment intersects. -- Returns nil if the segment never touches the rect -- Notice that normals are only guaranteed to be accurate when initially ti1, ti2 == -math.huge, math.huge local function rect_getSegmentIntersectionIndices(x,y,w,h, x1,y1,x2,y2, ti1,ti2) ti1, ti2 = ti1 or 0, ti2 or 1 local dx, dy = x2-x1, y2-y1 local nx, ny local nx1, ny1, nx2, ny2 = 0,0,0,0 local p, q, r for side = 1,4 do if side == 1 then nx,ny,p,q = -1, 0, -dx, x1 - x -- left elseif side == 2 then nx,ny,p,q = 1, 0, dx, x + w - x1 -- right elseif side == 3 then nx,ny,p,q = 0, -1, -dy, y1 - y -- top else nx,ny,p,q = 0, 1, dy, y + h - y1 -- bottom end if p == 0 then if q <= 0 then return nil end else r = q / p if p < 0 then if r > ti2 then return nil elseif r > ti1 then ti1,nx1,ny1 = r,nx,ny end else -- p > 0 if r < ti1 then return nil elseif r < ti2 then ti2,nx2,ny2 = r,nx,ny end end end end return ti1,ti2, nx1,ny1, nx2,ny2 end -- Calculates the minkowsky difference between 2 rects, which is another rect local function rect_getDiff(x1,y1,w1,h1, x2,y2,w2,h2) return x2 - x1 - w1, y2 - y1 - h1, w1 + w2, h1 + h2 end local function rect_containsPoint(x,y,w,h, px,py) return px - x > DELTA and py - y > DELTA and x + w - px > DELTA and y + h - py > DELTA end local function rect_isIntersecting(x1,y1,w1,h1, x2,y2,w2,h2) return x1 < x2+w2 and x2 < x1+w1 and y1 < y2+h2 and y2 < y1+h1 end local function rect_getSquareDistance(x1,y1,w1,h1, x2,y2,w2,h2) local dx = x1 - x2 + (w1 - w2)/2 local dy = y1 - y2 + (h1 - h2)/2 return dx*dx + dy*dy end local function rect_detectCollision(x1,y1,w1,h1, x2,y2,w2,h2, goalX, goalY) goalX = goalX or x1 goalY = goalY or y1 local dx, dy = goalX - x1, goalY - y1 local x,y,w,h = rect_getDiff(x1,y1,w1,h1, x2,y2,w2,h2) local overlaps, ti, nx, ny if rect_containsPoint(x,y,w,h, 0,0) then -- item was intersecting other local px, py = rect_getNearestCorner(x,y,w,h, 0, 0) local wi, hi = min(w1, abs(px)), min(h1, abs(py)) -- area of intersection ti = -wi * hi -- ti is the negative area of intersection overlaps = true else local ti1,ti2,nx1,ny1 = rect_getSegmentIntersectionIndices(x,y,w,h, 0,0,dx,dy, -math.huge, math.huge) -- item tunnels into other if ti1 and ti1 < 1 and (abs(ti1 - ti2) >= DELTA) -- special case for rect going through another rect's corner and (0 < ti1 + DELTA or 0 == ti1 and ti2 > 0) then ti, nx, ny = ti1, nx1, ny1 overlaps = false end end if not ti then return end local tx, ty if overlaps then if dx == 0 and dy == 0 then -- intersecting and not moving - use minimum displacement vector local px, py = rect_getNearestCorner(x,y,w,h, 0,0) if abs(px) < abs(py) then py = 0 else px = 0 end nx, ny = sign(px), sign(py) tx, ty = x1 + px, y1 + py else -- intersecting and moving - move in the opposite direction local ti1, _ ti1,_,nx,ny = rect_getSegmentIntersectionIndices(x,y,w,h, 0,0,dx,dy, -math.huge, 1) if not ti1 then return end tx, ty = x1 + dx * ti1, y1 + dy * ti1 end else -- tunnel tx, ty = x1 + dx * ti, y1 + dy * ti end return { overlaps = overlaps, ti = ti, move = {x = dx, y = dy}, normal = {x = nx, y = ny}, touch = {x = tx, y = ty}, itemRect = {x = x1, y = y1, w = w1, h = h1}, otherRect = {x = x2, y = y2, w = w2, h = h2} } end ------------------------------------------ -- Grid functions ------------------------------------------ local function grid_toWorld(cellSize, cx, cy) return (cx - 1)*cellSize, (cy-1)*cellSize end local function grid_toCell(cellSize, x, y) return floor(x / cellSize) + 1, floor(y / cellSize) + 1 end -- grid_traverse* functions are based on "A Fast Voxel Traversal Algorithm for Ray Tracing", -- by John Amanides and Andrew Woo - http://www.cse.yorku.ca/~amana/research/grid.pdf -- It has been modified to include both cells when the ray "touches a grid corner", -- and with a different exit condition local function grid_traverse_initStep(cellSize, ct, t1, t2) local v = t2 - t1 if v > 0 then return 1, cellSize / v, ((ct + v) * cellSize - t1) / v elseif v < 0 then return -1, -cellSize / v, ((ct + v - 1) * cellSize - t1) / v else return 0, math.huge, math.huge end end local function grid_traverse(cellSize, x1,y1,x2,y2, f) local cx1,cy1 = grid_toCell(cellSize, x1,y1) local cx2,cy2 = grid_toCell(cellSize, x2,y2) local stepX, dx, tx = grid_traverse_initStep(cellSize, cx1, x1, x2) local stepY, dy, ty = grid_traverse_initStep(cellSize, cy1, y1, y2) local cx,cy = cx1,cy1 f(cx, cy) -- The default implementation had an infinite loop problem when -- approaching the last cell in some occassions. We finish iterating -- when we are *next* to the last cell while abs(cx - cx2) + abs(cy - cy2) > 1 do if tx < ty then tx, cx = tx + dx, cx + stepX f(cx, cy) else -- Addition: include both cells when going through corners if tx == ty then f(cx + stepX, cy) end ty, cy = ty + dy, cy + stepY f(cx, cy) end end -- If we have not arrived to the last cell, use it if cx ~= cx2 or cy ~= cy2 then f(cx2, cy2) end end local function grid_toCellRect(cellSize, x,y,w,h) local cx,cy = grid_toCell(cellSize, x, y) local cr,cb = ceil((x+w) / cellSize), ceil((y+h) / cellSize) return cx, cy, cr - cx + 1, cb - cy + 1 end ------------------------------------------ -- Responses ------------------------------------------ local touch = function(world, col, x,y,w,h, goalX, goalY, filter) return col.touch.x, col.touch.y, {}, 0 end local cross = function(world, col, x,y,w,h, goalX, goalY, filter) local cols, len = world:project(col.item, x,y,w,h, goalX, goalY, filter) return goalX, goalY, cols, len end local slide = function(world, col, x,y,w,h, goalX, goalY, filter) goalX = goalX or x goalY = goalY or y local tch, move = col.touch, col.move if move.x ~= 0 or move.y ~= 0 then if col.normal.x ~= 0 then goalX = tch.x else goalY = tch.y end end col.slide = {x = goalX, y = goalY} x,y = tch.x, tch.y local cols, len = world:project(col.item, x,y,w,h, goalX, goalY, filter) return goalX, goalY, cols, len end local bounce = function(world, col, x,y,w,h, goalX, goalY, filter) goalX = goalX or x goalY = goalY or y local tch, move = col.touch, col.move local tx, ty = tch.x, tch.y local bx, by = tx, ty if move.x ~= 0 or move.y ~= 0 then local bnx, bny = goalX - tx, goalY - ty if col.normal.x == 0 then bny = -bny else bnx = -bnx end bx, by = tx + bnx, ty + bny end col.bounce = {x = bx, y = by} x,y = tch.x, tch.y goalX, goalY = bx, by local cols, len = world:project(col.item, x,y,w,h, goalX, goalY, filter) return goalX, goalY, cols, len end ------------------------------------------ -- World ------------------------------------------ local World = {} local World_mt = {__index = World} -- Private functions and methods local function sortByWeight(a,b) return a.weight < b.weight end local function sortByTiAndDistance(a,b) if a.ti == b.ti then local ir, ar, br = a.itemRect, a.otherRect, b.otherRect local ad = rect_getSquareDistance(ir.x,ir.y,ir.w,ir.h, ar.x,ar.y,ar.w,ar.h) local bd = rect_getSquareDistance(ir.x,ir.y,ir.w,ir.h, br.x,br.y,br.w,br.h) return ad < bd end return a.ti < b.ti end local function addItemToCell(self, item, cx, cy) self.rows[cy] = self.rows[cy] or setmetatable({}, {__mode = 'v'}) local row = self.rows[cy] row[cx] = row[cx] or {itemCount = 0, x = cx, y = cy, items = setmetatable({}, {__mode = 'k'})} local cell = row[cx] self.nonEmptyCells[cell] = true if not cell.items[item] then cell.items[item] = true cell.itemCount = cell.itemCount + 1 end end local function removeItemFromCell(self, item, cx, cy) local row = self.rows[cy] if not row or not row[cx] or not row[cx].items[item] then return false end local cell = row[cx] cell.items[item] = nil cell.itemCount = cell.itemCount - 1 if cell.itemCount == 0 then self.nonEmptyCells[cell] = nil end return true end local function getDictItemsInCellRect(self, cl,ct,cw,ch) local items_dict = {} for cy=ct,ct+ch-1 do local row = self.rows[cy] if row then for cx=cl,cl+cw-1 do local cell = row[cx] if cell and cell.itemCount > 0 then -- no cell.itemCount > 1 because tunneling for item,_ in pairs(cell.items) do items_dict[item] = true end end end end end return items_dict end local function getCellsTouchedBySegment(self, x1,y1,x2,y2) local cells, cellsLen, visited = {}, 0, {} grid_traverse(self.cellSize, x1,y1,x2,y2, function(cx, cy) local row = self.rows[cy] if not row then return end local cell = row[cx] if not cell or visited[cell] then return end visited[cell] = true cellsLen = cellsLen + 1 cells[cellsLen] = cell end) return cells, cellsLen end local function getInfoAboutItemsTouchedBySegment(self, x1,y1, x2,y2, filter) local cells, len = getCellsTouchedBySegment(self, x1,y1,x2,y2) local cell, rect, l,t,w,h, ti1,ti2, tii0,tii1 local visited, itemInfo, itemInfoLen = {},{},0 for i=1,len do cell = cells[i] for item in pairs(cell.items) do if not visited[item] then visited[item] = true if (not filter or filter(item)) then rect = self.rects[item] l,t,w,h = rect.x,rect.y,rect.w,rect.h ti1,ti2 = rect_getSegmentIntersectionIndices(l,t,w,h, x1,y1, x2,y2, 0, 1) if ti1 and ((0 < ti1 and ti1 < 1) or (0 < ti2 and ti2 < 1)) then -- the sorting is according to the t of an infinite line, not the segment tii0,tii1 = rect_getSegmentIntersectionIndices(l,t,w,h, x1,y1, x2,y2, -math.huge, math.huge) itemInfoLen = itemInfoLen + 1 itemInfo[itemInfoLen] = {item = item, ti1 = ti1, ti2 = ti2, weight = min(tii0,tii1)} end end end end end table.sort(itemInfo, sortByWeight) return itemInfo, itemInfoLen end local function getResponseByName(self, name) local response = self.responses[name] if not response then error(('Unknown collision type: %s (%s)'):format(name, type(name))) end return response end -- Misc Public Methods function World:addResponse(name, response) self.responses[name] = response end function World:project(item, x,y,w,h, goalX, goalY, filter) assertIsRect(x,y,w,h) goalX = goalX or x goalY = goalY or y filter = filter or defaultFilter local collisions, len = {}, 0 local visited = {} if item ~= nil then visited[item] = true end -- This could probably be done with less cells using a polygon raster over the cells instead of a -- bounding rect of the whole movement. Conditional to building a queryPolygon method local tl, tt = min(goalX, x), min(goalY, y) local tr, tb = max(goalX + w, x+w), max(goalY + h, y+h) local tw, th = tr-tl, tb-tt local cl,ct,cw,ch = grid_toCellRect(self.cellSize, tl,tt,tw,th) local dictItemsInCellRect = getDictItemsInCellRect(self, cl,ct,cw,ch) for other,_ in pairs(dictItemsInCellRect) do if not visited[other] then visited[other] = true local responseName = filter(item, other) if responseName then local ox,oy,ow,oh = self:getRect(other) local col = rect_detectCollision(x,y,w,h, ox,oy,ow,oh, goalX, goalY) if col then col.other = other col.item = item col.type = responseName len = len + 1 collisions[len] = col end end end end table.sort(collisions, sortByTiAndDistance) return collisions, len end function World:countCells() local count = 0 for _,row in pairs(self.rows) do for _,_ in pairs(row) do count = count + 1 end end return count end function World:hasItem(item) return not not self.rects[item] end function World:getItems() local items, len = {}, 0 for item,_ in pairs(self.rects) do len = len + 1 items[len] = item end return items, len end function World:countItems() local len = 0 for _ in pairs(self.rects) do len = len + 1 end return len end function World:getRect(item) local rect = self.rects[item] if not rect then error('Item ' .. tostring(item) .. ' must be added to the world before getting its rect. Use world:add(item, x,y,w,h) to add it first.') end return rect.x, rect.y, rect.w, rect.h end function World:toWorld(cx, cy) return grid_toWorld(self.cellSize, cx, cy) end function World:toCell(x,y) return grid_toCell(self.cellSize, x, y) end --- Query methods function World:queryRect(x,y,w,h, filter) assertIsRect(x,y,w,h) local cl,ct,cw,ch = grid_toCellRect(self.cellSize, x,y,w,h) local dictItemsInCellRect = getDictItemsInCellRect(self, cl,ct,cw,ch) local items, len = {}, 0 local rect for item,_ in pairs(dictItemsInCellRect) do rect = self.rects[item] if (not filter or filter(item)) and rect_isIntersecting(x,y,w,h, rect.x, rect.y, rect.w, rect.h) then len = len + 1 items[len] = item end end return items, len end function World:queryPoint(x,y, filter) local cx,cy = self:toCell(x,y) local dictItemsInCellRect = getDictItemsInCellRect(self, cx,cy,1,1) local items, len = {}, 0 local rect for item,_ in pairs(dictItemsInCellRect) do rect = self.rects[item] if (not filter or filter(item)) and rect_containsPoint(rect.x, rect.y, rect.w, rect.h, x, y) then len = len + 1 items[len] = item end end return items, len end function World:querySegment(x1, y1, x2, y2, filter) local itemInfo, len = getInfoAboutItemsTouchedBySegment(self, x1, y1, x2, y2, filter) local items = {} for i=1, len do items[i] = itemInfo[i].item end return items, len end function World:querySegmentWithCoords(x1, y1, x2, y2, filter) local itemInfo, len = getInfoAboutItemsTouchedBySegment(self, x1, y1, x2, y2, filter) local dx, dy = x2-x1, y2-y1 local info, ti1, ti2 for i=1, len do info = itemInfo[i] ti1 = info.ti1 ti2 = info.ti2 info.weight = nil info.x1 = x1 + dx * ti1 info.y1 = y1 + dy * ti1 info.x2 = x1 + dx * ti2 info.y2 = y1 + dy * ti2 end return itemInfo, len end --- Main methods function World:add(item, x,y,w,h) local rect = self.rects[item] if rect then error('Item ' .. tostring(item) .. ' added to the world twice.') end assertIsRect(x,y,w,h) self.rects[item] = {x=x,y=y,w=w,h=h} local cl,ct,cw,ch = grid_toCellRect(self.cellSize, x,y,w,h) for cy = ct, ct+ch-1 do for cx = cl, cl+cw-1 do addItemToCell(self, item, cx, cy) end end return item end function World:remove(item) local x,y,w,h = self:getRect(item) self.rects[item] = nil local cl,ct,cw,ch = grid_toCellRect(self.cellSize, x,y,w,h) for cy = ct, ct+ch-1 do for cx = cl, cl+cw-1 do removeItemFromCell(self, item, cx, cy) end end end function World:update(item, x2,y2,w2,h2) local x1,y1,w1,h1 = self:getRect(item) w2,h2 = w2 or w1, h2 or h1 assertIsRect(x2,y2,w2,h2) if x1 ~= x2 or y1 ~= y2 or w1 ~= w2 or h1 ~= h2 then local cellSize = self.cellSize local cl1,ct1,cw1,ch1 = grid_toCellRect(cellSize, x1,y1,w1,h1) local cl2,ct2,cw2,ch2 = grid_toCellRect(cellSize, x2,y2,w2,h2) if cl1 ~= cl2 or ct1 ~= ct2 or cw1 ~= cw2 or ch1 ~= ch2 then local cr1, cb1 = cl1+cw1-1, ct1+ch1-1 local cr2, cb2 = cl2+cw2-1, ct2+ch2-1 local cyOut for cy = ct1, cb1 do cyOut = cy < ct2 or cy > cb2 for cx = cl1, cr1 do if cyOut or cx < cl2 or cx > cr2 then removeItemFromCell(self, item, cx, cy) end end end for cy = ct2, cb2 do cyOut = cy < ct1 or cy > cb1 for cx = cl2, cr2 do if cyOut or cx < cl1 or cx > cr1 then addItemToCell(self, item, cx, cy) end end end end local rect = self.rects[item] rect.x, rect.y, rect.w, rect.h = x2,y2,w2,h2 end end function World:move(item, goalX, goalY, filter) local actualX, actualY, cols, len = self:check(item, goalX, goalY, filter) self:update(item, actualX, actualY) return actualX, actualY, cols, len end function World:check(item, goalX, goalY, filter) filter = filter or defaultFilter local visited = {[item] = true} local visitedFilter = function(itm, other) if visited[other] then return false end return filter(itm, other) end local cols, len = {}, 0 local x,y,w,h = self:getRect(item) local projected_cols, projected_len = self:project(item, x,y,w,h, goalX,goalY, visitedFilter) while projected_len > 0 do local col = projected_cols[1] len = len + 1 cols[len] = col visited[col.other] = true local response = getResponseByName(self, col.type) goalX, goalY, projected_cols, projected_len = response( self, col, x, y, w, h, goalX, goalY, visitedFilter ) end return goalX, goalY, cols, len end -- Public library functions bump.newWorld = function(cellSize) cellSize = cellSize or 64 assertIsPositiveNumber(cellSize, 'cellSize') local world = setmetatable({ cellSize = cellSize, rects = {}, rows = {}, nonEmptyCells = {}, responses = {} }, World_mt) world:addResponse('touch', touch) world:addResponse('cross', cross) world:addResponse('slide', slide) world:addResponse('bounce', bounce) return world end bump.rect = { getNearestCorner = rect_getNearestCorner, getSegmentIntersectionIndices = rect_getSegmentIntersectionIndices, getDiff = rect_getDiff, containsPoint = rect_containsPoint, isIntersecting = rect_isIntersecting, getSquareDistance = rect_getSquareDistance, detectCollision = rect_detectCollision } bump.responses = { touch = touch, cross = cross, slide = slide, bounce = bounce } return bump |
Added src/fahombo/lib/sti/graphics.lua.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 |
local lg = _G.love.graphics local graphics = { isCreated = lg and true or false } function graphics.newSpriteBatch(...) if graphics.isCreated then return lg.newSpriteBatch(...) end end function graphics.newCanvas(...) if graphics.isCreated then return lg.newCanvas(...) end end function graphics.newImage(...) if graphics.isCreated then return lg.newImage(...) end end function graphics.newQuad(...) if graphics.isCreated then return lg.newQuad(...) end end function graphics.getCanvas(...) if graphics.isCreated then return lg.getCanvas(...) end end function graphics.setCanvas(...) if graphics.isCreated then return lg.setCanvas(...) end end function graphics.clear(...) if graphics.isCreated then return lg.clear(...) end end function graphics.push(...) if graphics.isCreated then return lg.push(...) end end function graphics.origin(...) if graphics.isCreated then return lg.origin(...) end end function graphics.scale(...) if graphics.isCreated then return lg.scale(...) end end function graphics.translate(...) if graphics.isCreated then return lg.translate(...) end end function graphics.pop(...) if graphics.isCreated then return lg.pop(...) end end function graphics.draw(...) if graphics.isCreated then return lg.draw(...) end end function graphics.rectangle(...) if graphics.isCreated then return lg.rectangle(...) end end function graphics.getColor(...) if graphics.isCreated then return lg.getColor(...) end end function graphics.setColor(...) if graphics.isCreated then return lg.setColor(...) end end function graphics.line(...) if graphics.isCreated then return lg.line(...) end end function graphics.polygon(...) if graphics.isCreated then return lg.polygon(...) end end function graphics.points(...) if graphics.isCreated then return lg.points(...) end end function graphics.getWidth() if graphics.isCreated then return lg.getWidth() end return 0 end function graphics.getHeight() if graphics.isCreated then return lg.getHeight() end return 0 end return graphics |
Added src/fahombo/lib/sti/init.lua.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 |
--- Simple and fast Tiled map loader and renderer. -- @module sti -- @author Landon Manning -- @copyright 2019 -- @license MIT/X11 local STI = { _LICENSE = "MIT/X11", _URL = "https://github.com/karai17/Simple-Tiled-Implementation", _VERSION = "1.2.3.0", _DESCRIPTION = "Simple Tiled Implementation is a Tiled Map Editor library designed for the *awesome* LÖVE framework.", cache = {} } STI.__index = STI local love = _G.love local cwd = (...):gsub('%.init$', '') .. "." local utils = require(cwd .. "utils") local ceil = math.ceil local floor = math.floor local lg = require(cwd .. "graphics") local Map = {} Map.__index = Map local function new(map, plugins, ox, oy) local dir = "" if type(map) == "table" then map = setmetatable(map, Map) else -- Check for valid map type local ext = map:sub(-4, -1) assert(ext == ".lua", string.format( "Invalid file type: %s. File must be of type: lua.", ext )) -- Get directory of map dir = map:reverse():find("[/\\]") or "" if dir ~= "" then dir = map:sub(1, 1 + (#map - dir)) end -- Load map map = setmetatable(assert(love.filesystem.load(map))(), Map) end map:init(dir, plugins, ox, oy) return map end --- Instance a new map. -- @param map Path to the map file or the map table itself -- @param plugins A list of plugins to load -- @param ox Offset of map on the X axis (in pixels) -- @param oy Offset of map on the Y axis (in pixels) -- @return table The loaded Map function STI.__call(_, map, plugins, ox, oy) return new(map, plugins, ox, oy) end --- Flush image cache. function STI:flush() self.cache = {} end --- Map object --- Instance a new map -- @param path Path to the map file -- @param plugins A list of plugins to load -- @param ox Offset of map on the X axis (in pixels) -- @param oy Offset of map on the Y axis (in pixels) function Map:init(path, plugins, ox, oy) if type(plugins) == "table" then self:loadPlugins(plugins) end self:resize() self.objects = {} self.tiles = {} self.tileInstances = {} self.drawRange = { sx = 1, sy = 1, ex = self.width, ey = self.height, } self.offsetx = ox or 0 self.offsety = oy or 0 self.freeBatchSprites = {} setmetatable(self.freeBatchSprites, { __mode = 'k' }) -- Set tiles, images local gid = 1 for i, tileset in ipairs(self.tilesets) do assert(tileset.image, "STI does not support Tile Collections.\nYou need to create a Texture Atlas.") -- Cache images if lg.isCreated then local formatted_path = utils.format_path(path .. tileset.image) if not STI.cache[formatted_path] then utils.fix_transparent_color(tileset, formatted_path) utils.cache_image(STI, formatted_path, tileset.image) else tileset.image = STI.cache[formatted_path] end end gid = self:setTiles(i, tileset, gid) end local layers = {} for _, layer in ipairs(self.layers) do self:groupAppendToList(layers, layer) end self.layers = layers -- Set layers for _, layer in ipairs(self.layers) do self:setLayer(layer, path) end end --- Layers from the group are added to the list -- @param layers List of layers -- @param layer Layer data function Map:groupAppendToList(layers, layer) if layer.type == "group" then for _, groupLayer in pairs(layer.layers) do groupLayer.name = layer.name .. "." .. groupLayer.name groupLayer.visible = layer.visible groupLayer.opacity = layer.opacity * groupLayer.opacity groupLayer.offsetx = layer.offsetx + groupLayer.offsetx groupLayer.offsety = layer.offsety + groupLayer.offsety for key, property in pairs(layer.properties) do if groupLayer.properties[key] == nil then groupLayer.properties[key] = property end end self:groupAppendToList(layers, groupLayer) end else table.insert(layers, layer) end end --- Load plugins -- @param plugins A list of plugins to load function Map:loadPlugins(plugins) for _, plugin in ipairs(plugins) do local pluginModulePath = cwd .. 'plugins.' .. plugin local ok, pluginModule = pcall(require, pluginModulePath) if ok then for k, func in pairs(pluginModule) do if not self[k] then self[k] = func end end end end end --- Create Tiles -- @param index Index of the Tileset -- @param tileset Tileset data -- @param gid First Global ID in Tileset -- @return number Next Tileset's first Global ID function Map:setTiles(index, tileset, gid) local quad = lg.newQuad local imageW = tileset.imagewidth local imageH = tileset.imageheight local tileW = tileset.tilewidth local tileH = tileset.tileheight local margin = tileset.margin local spacing = tileset.spacing local w = utils.get_tiles(imageW, tileW, margin, spacing) local h = utils.get_tiles(imageH, tileH, margin, spacing) for y = 1, h do for x = 1, w do local id = gid - tileset.firstgid local quadX = (x - 1) * tileW + margin + (x - 1) * spacing local quadY = (y - 1) * tileH + margin + (y - 1) * spacing local type = "" local properties, terrain, animation, objectGroup for _, tile in pairs(tileset.tiles) do if tile.id == id then properties = tile.properties animation = tile.animation objectGroup = tile.objectGroup type = tile.type if tile.terrain then terrain = {} for i = 1, #tile.terrain do terrain[i] = tileset.terrains[tile.terrain[i] + 1] end end end end local tile = { id = id, gid = gid, tileset = index, type = type, quad = quad( quadX, quadY, tileW, tileH, imageW, imageH ), properties = properties or {}, terrain = terrain, animation = animation, objectGroup = objectGroup, frame = 1, time = 0, width = tileW, height = tileH, sx = 1, sy = 1, r = 0, offset = tileset.tileoffset, } self.tiles[gid] = tile gid = gid + 1 end end return gid end --- Create Layers -- @param layer Layer data -- @param path (Optional) Path to an Image Layer's image function Map:setLayer(layer, path) if layer.encoding then if layer.encoding == "base64" then assert(require "ffi", "Compressed maps require LuaJIT FFI.\nPlease Switch your interperator to LuaJIT or your Tile Layer Format to \"CSV\".") local fd = love.data.decode("string", "base64", layer.data) if not layer.compression then layer.data = utils.get_decompressed_data(fd) else assert(love.data.decompress, "zlib and gzip compression require LOVE 11.0+.\nPlease set your Tile Layer Format to \"Base64 (uncompressed)\" or \"CSV\".") if layer.compression == "zlib" then local data = love.data.decompress("string", "zlib", fd) layer.data = utils.get_decompressed_data(data) end if layer.compression == "gzip" then local data = love.data.decompress("string", "gzip", fd) layer.data = utils.get_decompressed_data(data) end end end end layer.x = (layer.x or 0) + layer.offsetx + self.offsetx layer.y = (layer.y or 0) + layer.offsety + self.offsety layer.update = function() end if layer.type == "tilelayer" then self:setTileData(layer) self:setSpriteBatches(layer) layer.draw = function() self:drawTileLayer(layer) end elseif layer.type == "objectgroup" then self:setObjectData(layer) self:setObjectCoordinates(layer) self:setObjectSpriteBatches(layer) layer.draw = function() self:drawObjectLayer(layer) end elseif layer.type == "imagelayer" then layer.draw = function() self:drawImageLayer(layer) end if layer.image ~= "" then local formatted_path = utils.format_path(path .. layer.image) if not STI.cache[formatted_path] then utils.cache_image(STI, formatted_path) end layer.image = STI.cache[formatted_path] layer.width = layer.image:getWidth() layer.height = layer.image:getHeight() end end self.layers[layer.name] = layer end --- Add Tiles to Tile Layer -- @param layer The Tile Layer function Map:setTileData(layer) if layer.chunks then for _, chunk in ipairs(layer.chunks) do self:setTileData(chunk) end return end local i = 1 local map = {} for y = 1, layer.height do map[y] = {} for x = 1, layer.width do local gid = layer.data[i] -- NOTE: Empty tiles have a GID of 0 if gid > 0 then map[y][x] = self.tiles[gid] or self:setFlippedGID(gid) end i = i + 1 end end layer.data = map end --- Add Objects to Layer -- @param layer The Object Layer function Map:setObjectData(layer) for _, object in ipairs(layer.objects) do object.layer = layer self.objects[object.id] = object end end --- Correct position and orientation of Objects in an Object Layer -- @param layer The Object Layer function Map:setObjectCoordinates(layer) for _, object in ipairs(layer.objects) do local x = layer.x + object.x local y = layer.y + object.y local w = object.width local h = object.height local cos = math.cos(math.rad(object.rotation)) local sin = math.sin(math.rad(object.rotation)) if object.shape == "rectangle" and not object.gid then object.rectangle = {} local vertices = { { x=x, y=y }, { x=x + w, y=y }, { x=x + w, y=y + h }, { x=x, y=y + h }, } for _, vertex in ipairs(vertices) do vertex.x, vertex.y = utils.rotate_vertex(self, vertex, x, y, cos, sin) table.insert(object.rectangle, { x = vertex.x, y = vertex.y }) end elseif object.shape == "ellipse" then object.ellipse = {} local vertices = utils.convert_ellipse_to_polygon(x, y, w, h) for _, vertex in ipairs(vertices) do vertex.x, vertex.y = utils.rotate_vertex(self, vertex, x, y, cos, sin) table.insert(object.ellipse, { x = vertex.x, y = vertex.y }) end elseif object.shape == "polygon" then for _, vertex in ipairs(object.polygon) do vertex.x = vertex.x + x vertex.y = vertex.y + y vertex.x, vertex.y = utils.rotate_vertex(self, vertex, x, y, cos, sin) end elseif object.shape == "polyline" then for _, vertex in ipairs(object.polyline) do vertex.x = vertex.x + x vertex.y = vertex.y + y vertex.x, vertex.y = utils.rotate_vertex(self, vertex, x, y, cos, sin) end end end end --- Convert tile location to tile instance location -- @param layer Tile layer -- @param tile Tile -- @param x Tile location on X axis (in tiles) -- @param y Tile location on Y axis (in tiles) -- @return number Tile instance location on X axis (in pixels) -- @return number Tile instance location on Y axis (in pixels) function Map:getLayerTilePosition(layer, tile, x, y) local tileW = self.tilewidth local tileH = self.tileheight local tileX, tileY if self.orientation == "orthogonal" then local tileset = self.tilesets[tile.tileset] tileX = (x - 1) * tileW + tile.offset.x tileY = (y - 0) * tileH + tile.offset.y - tileset.tileheight tileX, tileY = utils.compensate(tile, tileX, tileY, tileW, tileH) elseif self.orientation == "isometric" then tileX = (x - y) * (tileW / 2) + tile.offset.x + layer.width * tileW / 2 - self.tilewidth / 2 tileY = (x + y - 2) * (tileH / 2) + tile.offset.y else local sideLen = self.hexsidelength or 0 if self.staggeraxis == "y" then if self.staggerindex == "odd" then if y % 2 == 0 then tileX = (x - 1) * tileW + tileW / 2 + tile.offset.x else tileX = (x - 1) * tileW + tile.offset.x end else if y % 2 == 0 then tileX = (x - 1) * tileW + tile.offset.x else tileX = (x - 1) * tileW + tileW / 2 + tile.offset.x end end local rowH = tileH - (tileH - sideLen) / 2 tileY = (y - 1) * rowH + tile.offset.y else if self.staggerindex == "odd" then if x % 2 == 0 then tileY = (y - 1) * tileH + tileH / 2 + tile.offset.y else tileY = (y - 1) * tileH + tile.offset.y end else if x % 2 == 0 then tileY = (y - 1) * tileH + tile.offset.y else tileY = (y - 1) * tileH + tileH / 2 + tile.offset.y end end local colW = tileW - (tileW - sideLen) / 2 tileX = (x - 1) * colW + tile.offset.x end end return tileX, tileY end --- Place new tile instance -- @param layer Tile layer -- @param chunk Layer chunk -- @param tile Tile -- @param number Tile location on X axis (in tiles) -- @param number Tile location on Y axis (in tiles) function Map:addNewLayerTile(layer, chunk, tile, x, y) local tileset = tile.tileset local image = self.tilesets[tile.tileset].image local batches local size if chunk then batches = chunk.batches size = chunk.width * chunk.height else batches = layer.batches size = layer.width * layer.height end batches[tileset] = batches[tileset] or lg.newSpriteBatch(image, size) local batch = batches[tileset] local tileX, tileY = self:getLayerTilePosition(layer, tile, x, y) local instance = { layer = layer, chunk = chunk, gid = tile.gid, x = tileX, y = tileY, r = tile.r, oy = 0 } -- NOTE: STI can run headless so it is not guaranteed that a batch exists. if batch then instance.batch = batch instance.id = batch:add(tile.quad, tileX, tileY, tile.r, tile.sx, tile.sy) end self.tileInstances[tile.gid] = self.tileInstances[tile.gid] or {} table.insert(self.tileInstances[tile.gid], instance) end function Map:set_batches(layer, chunk) if chunk then chunk.batches = {} else layer.batches = {} end if self.orientation == "orthogonal" or self.orientation == "isometric" then local offsetX = chunk and chunk.x or 0 local offsetY = chunk and chunk.y or 0 local startX = 1 local startY = 1 local endX = chunk and chunk.width or layer.width local endY = chunk and chunk.height or layer.height local incrementX = 1 local incrementY = 1 -- Determine order to add tiles to sprite batch -- Defaults to right-down if self.renderorder == "right-up" then startY, endY, incrementY = endY, startY, -1 elseif self.renderorder == "left-down" then startX, endX, incrementX = endX, startX, -1 elseif self.renderorder == "left-up" then startX, endX, incrementX = endX, startX, -1 startY, endY, incrementY = endY, startY, -1 end for y = startY, endY, incrementY do for x = startX, endX, incrementX do -- NOTE: Cannot short circuit this since it is valid for tile to be assigned nil local tile if chunk then tile = chunk.data[y][x] else tile = layer.data[y][x] end if tile then self:addNewLayerTile(layer, chunk, tile, x + offsetX, y + offsetY) end end end else if self.staggeraxis == "y" then for y = 1, (chunk and chunk.height or layer.height) do for x = 1, (chunk and chunk.width or layer.width) do -- NOTE: Cannot short circuit this since it is valid for tile to be assigned nil local tile if chunk then tile = chunk.data[y][x] else tile = layer.data[y][x] end if tile then self:addNewLayerTile(layer, chunk, tile, x, y) end end end else local i = 0 local _x if self.staggerindex == "odd" then _x = 1 else _x = 2 end while i < (chunk and chunk.width * chunk.height or layer.width * layer.height) do for _y = 1, (chunk and chunk.height or layer.height) + 0.5, 0.5 do local y = floor(_y) for x = _x, (chunk and chunk.width or layer.width), 2 do i = i + 1 -- NOTE: Cannot short circuit this since it is valid for tile to be assigned nil local tile if chunk then tile = chunk.data[y][x] else tile = layer.data[y][x] end if tile then self:addNewLayerTile(layer, chunk, tile, x, y) end end if _x == 1 then _x = 2 else _x = 1 end end end end end end --- Batch Tiles in Tile Layer for improved draw speed -- @param layer The Tile Layer function Map:setSpriteBatches(layer) if layer.chunks then for _, chunk in ipairs(layer.chunks) do self:set_batches(layer, chunk) end return end self:set_batches(layer) end --- Batch Tiles in Object Layer for improved draw speed -- @param layer The Object Layer function Map:setObjectSpriteBatches(layer) local newBatch = lg.newSpriteBatch local batches = {} if layer.draworder == "topdown" then table.sort(layer.objects, function(a, b) return a.y + a.height < b.y + b.height end) end for _, object in ipairs(layer.objects) do if object.gid then local tile = self.tiles[object.gid] or self:setFlippedGID(object.gid) local tileset = tile.tileset local image = self.tilesets[tileset].image batches[tileset] = batches[tileset] or newBatch(image) local sx = object.width / tile.width local sy = object.height / tile.height -- Tiled rotates around bottom left corner, where love2D rotates around top left corner local ox = 0 local oy = tile.height local batch = batches[tileset] local tileX = object.x + tile.offset.x local tileY = object.y + tile.offset.y local tileR = math.rad(object.rotation) -- Compensation for scale/rotation shift if tile.sx == -1 then tileX = tileX + object.width if tileR ~= 0 then tileX = tileX - object.width ox = ox + tile.width end end if tile.sy == -1 then tileY = tileY - object.height if tileR ~= 0 then tileY = tileY + object.width oy = oy - tile.width end end local instance = { id = batch:add(tile.quad, tileX, tileY, tileR, tile.sx * sx, tile.sy * sy, ox, oy), batch = batch, layer = layer, gid = tile.gid, x = tileX, y = tileY - oy, r = tileR, oy = oy } self.tileInstances[tile.gid] = self.tileInstances[tile.gid] or {} table.insert(self.tileInstances[tile.gid], instance) end end layer.batches = batches end --- Create a Custom Layer to place userdata in (such as player sprites) -- @param name Name of Custom Layer -- @param index Draw order within Layer stack -- @return table Custom Layer function Map:addCustomLayer(name, index) index = index or #self.layers + 1 local layer = { type = "customlayer", name = name, visible = true, opacity = 1, properties = {}, } function layer.draw() end function layer.update() end table.insert(self.layers, index, layer) self.layers[name] = self.layers[index] return layer end --- Convert another Layer into a Custom Layer -- @param index Index or name of Layer to convert -- @return table Custom Layer function Map:convertToCustomLayer(index) local layer = assert(self.layers[index], "Layer not found: " .. index) layer.type = "customlayer" layer.x = nil layer.y = nil layer.width = nil layer.height = nil layer.encoding = nil layer.data = nil layer.chunks = nil layer.objects = nil layer.image = nil function layer.draw() end function layer.update() end return layer end --- Remove a Layer from the Layer stack -- @param index Index or name of Layer to remove function Map:removeLayer(index) local layer = assert(self.layers[index], "Layer not found: " .. index) if type(index) == "string" then for i, l in ipairs(self.layers) do if l.name == index then table.remove(self.layers, i) self.layers[index] = nil break end end else local name = self.layers[index].name table.remove(self.layers, index) self.layers[name] = nil end -- Remove layer batches if layer.batches then for _, batch in pairs(layer.batches) do self.freeBatchSprites[batch] = nil end end -- Remove chunk batches if layer.chunks then for _, chunk in ipairs(layer.chunks) do for _, batch in pairs(chunk.batches) do self.freeBatchSprites[batch] = nil end end end -- Remove tile instances if layer.type == "tilelayer" then for _, tiles in pairs(self.tileInstances) do for i = #tiles, 1, -1 do local tile = tiles[i] if tile.layer == layer then table.remove(tiles, i) end end end end -- Remove objects if layer.objects then for i, object in pairs(self.objects) do if object.layer == layer then self.objects[i] = nil end end end end --- Animate Tiles and update every Layer -- @param dt Delta Time function Map:update(dt) for _, tile in pairs(self.tiles) do local update = false if tile.animation then tile.time = tile.time + dt * 1000 while tile.time > tonumber(tile.animation[tile.frame].duration) do update = true tile.time = tile.time - tonumber(tile.animation[tile.frame].duration) tile.frame = tile.frame + 1 if tile.frame > #tile.animation then tile.frame = 1 end end if update and self.tileInstances[tile.gid] then for _, j in pairs(self.tileInstances[tile.gid]) do local t = self.tiles[tonumber(tile.animation[tile.frame].tileid) + self.tilesets[tile.tileset].firstgid] j.batch:set(j.id, t.quad, j.x, j.y, j.r, tile.sx, tile.sy, 0, j.oy) end end end end for _, layer in ipairs(self.layers) do layer:update(dt) end end --- Draw every Layer -- @param tx Translate on X -- @param ty Translate on Y -- @param sx Scale on X -- @param sy Scale on Y function Map:draw(tx, ty, sx, sy) local current_canvas = lg.getCanvas() lg.setCanvas(self.canvas) lg.clear() -- Scale map to 1.0 to draw onto canvas, this fixes tearing issues -- Map is translated to correct position so the right section is drawn lg.push() lg.origin() lg.translate(math.floor(tx or 0), math.floor(ty or 0)) for _, layer in ipairs(self.layers) do if layer.visible and layer.opacity > 0 then self:drawLayer(layer) end end lg.pop() -- Draw canvas at 0,0; this fixes scissoring issues -- Map is scaled to correct scale so the right section is shown lg.push() lg.origin() lg.scale(sx or 1, sy or sx or 1) lg.setCanvas(current_canvas) lg.draw(self.canvas) lg.pop() end --- Draw an individual Layer -- @param layer The Layer to draw function Map.drawLayer(_, layer) local r,g,b,a = lg.getColor() lg.setColor(r, g, b, a * layer.opacity) layer:draw() lg.setColor(r,g,b,a) end --- Default draw function for Tile Layers -- @param layer The Tile Layer to draw function Map:drawTileLayer(layer) if type(layer) == "string" or type(layer) == "number" then layer = self.layers[layer] end assert(layer.type == "tilelayer", "Invalid layer type: " .. layer.type .. ". Layer must be of type: tilelayer") -- NOTE: This does not take into account any sort of draw range clipping and will always draw every chunk if layer.chunks then for _, chunk in ipairs(layer.chunks) do for _, batch in pairs(chunk.batches) do lg.draw(batch, 0, 0) end end return end for _, batch in pairs(layer.batches) do lg.draw(batch, floor(layer.x), floor(layer.y)) end end --- Default draw function for Object Layers -- @param layer The Object Layer to draw function Map:drawObjectLayer(layer) if type(layer) == "string" or type(layer) == "number" then layer = self.layers[layer] end assert(layer.type == "objectgroup", "Invalid layer type: " .. layer.type .. ". Layer must be of type: objectgroup") local line = { 160, 160, 160, 255 * layer.opacity } local fill = { 160, 160, 160, 255 * layer.opacity * 0.5 } local r,g,b,a = lg.getColor() local reset = { r, g, b, a * layer.opacity } local function sortVertices(obj) local vertex = {} for _, v in ipairs(obj) do table.insert(vertex, v.x) table.insert(vertex, v.y) end return vertex end local function drawShape(obj, shape) local vertex = sortVertices(obj) if shape == "polyline" then lg.setColor(line) lg.line(vertex) return elseif shape == "polygon" then lg.setColor(fill) if not love.math.isConvex(vertex) then local triangles = love.math.triangulate(vertex) for _, triangle in ipairs(triangles) do lg.polygon("fill", triangle) end else lg.polygon("fill", vertex) end else lg.setColor(fill) lg.polygon("fill", vertex) end lg.setColor(line) lg.polygon("line", vertex) end for _, object in ipairs(layer.objects) do if object.shape == "rectangle" and not object.gid then drawShape(object.rectangle, "rectangle") elseif object.shape == "ellipse" then drawShape(object.ellipse, "ellipse") elseif object.shape == "polygon" then drawShape(object.polygon, "polygon") elseif object.shape == "polyline" then drawShape(object.polyline, "polyline") elseif object.shape == "point" then lg.points(object.x, object.y) end end lg.setColor(reset) for _, batch in pairs(layer.batches) do lg.draw(batch, 0, 0) end lg.setColor(r,g,b,a) end --- Default draw function for Image Layers -- @param layer The Image Layer to draw function Map:drawImageLayer(layer) if type(layer) == "string" or type(layer) == "number" then layer = self.layers[layer] end assert(layer.type == "imagelayer", "Invalid layer type: " .. layer.type .. ". Layer must be of type: imagelayer") if layer.image ~= "" then lg.draw(layer.image, layer.x, layer.y) end end --- Resize the drawable area of the Map -- @param w The new width of the drawable area (in pixels) -- @param h The new Height of the drawable area (in pixels) function Map:resize(w, h) if lg.isCreated then w = w or lg.getWidth() h = h or lg.getHeight() self.canvas = lg.newCanvas(w, h) self.canvas:setFilter("nearest", "nearest") end end --- Create flipped or rotated Tiles based on bitop flags -- @param gid The flagged Global ID -- @return table Flipped Tile function Map:setFlippedGID(gid) local bit31 = 2147483648 local bit30 = 1073741824 local bit29 = 536870912 local flipX = false local flipY = false local flipD = false local realgid = gid if realgid >= bit31 then realgid = realgid - bit31 flipX = not flipX end if realgid >= bit30 then realgid = realgid - bit30 flipY = not flipY end if realgid >= bit29 then realgid = realgid - bit29 flipD = not flipD end local tile = self.tiles[realgid] local data = { id = tile.id, gid = gid, tileset = tile.tileset, frame = tile.frame, time = tile.time, width = tile.width, height = tile.height, offset = tile.offset, quad = tile.quad, properties = tile.properties, terrain = tile.terrain, animation = tile.animation, sx = tile.sx, sy = tile.sy, r = tile.r, } if flipX then if flipY and flipD then data.r = math.rad(-90) data.sy = -1 elseif flipY then data.sx = -1 data.sy = -1 elseif flipD then data.r = math.rad(90) else data.sx = -1 end elseif flipY then if flipD then data.r = math.rad(-90) else data.sy = -1 end elseif flipD then data.r = math.rad(90) data.sy = -1 end self.tiles[gid] = data return self.tiles[gid] end --- Get custom properties from Layer -- @param layer The Layer -- @return table List of properties function Map:getLayerProperties(layer) local l = self.layers[layer] if not l then return {} end return l.properties end --- Get custom properties from Tile -- @param layer The Layer that the Tile belongs to -- @param x The X axis location of the Tile (in tiles) -- @param y The Y axis location of the Tile (in tiles) -- @return table List of properties function Map:getTileProperties(layer, x, y) local tile = self.layers[layer].data[y][x] if not tile then return {} end return tile.properties end --- Get custom properties from Object -- @param layer The Layer that the Object belongs to -- @param object The index or name of the Object -- @return table List of properties function Map:getObjectProperties(layer, object) local o = self.layers[layer].objects if type(object) == "number" then o = o[object] else for _, v in ipairs(o) do if v.name == object then o = v break end end end if not o then return {} end return o.properties end --- Change a tile in a layer to another tile -- @param layer The Layer that the Tile belongs to -- @param x The X axis location of the Tile (in tiles) -- @param y The Y axis location of the Tile (in tiles) -- @param gid The gid of the new tile function Map:setLayerTile(layer, x, y, gid) layer = self.layers[layer] layer.data[y] = layer.data[y] or {} local tile = layer.data[y][x] local instance if tile then local tileX, tileY = self:getLayerTilePosition(layer, tile, x, y) for _, inst in pairs(self.tileInstances[tile.gid]) do if inst.x == tileX and inst.y == tileY then instance = inst break end end end if tile == self.tiles[gid] then return end tile = self.tiles[gid] if instance then self:swapTile(instance, tile) else self:addNewLayerTile(layer, tile, x, y) end layer.data[y][x] = tile end --- Swap a tile in a spritebatch -- @param instance The current Instance object we want to replace -- @param tile The Tile object we want to use -- @return none function Map:swapTile(instance, tile) -- Update sprite batch if instance.batch then if tile then instance.batch:set( instance.id, tile.quad, instance.x, instance.y, tile.r, tile.sx, tile.sy ) else instance.batch:set( instance.id, instance.x, instance.y, 0, 0) self.freeBatchSprites[instance.batch] = self.freeBatchSprites[instance.batch] or {} table.insert(self.freeBatchSprites[instance.batch], instance) end end -- Remove old tile instance for i, ins in ipairs(self.tileInstances[instance.gid]) do if ins.batch == instance.batch and ins.id == instance.id then table.remove(self.tileInstances[instance.gid], i) break end end -- Add new tile instance if tile then self.tileInstances[tile.gid] = self.tileInstances[tile.gid] or {} local freeBatchSprites = self.freeBatchSprites[instance.batch] local newInstance if freeBatchSprites and #freeBatchSprites > 0 then newInstance = freeBatchSprites[#freeBatchSprites] freeBatchSprites[#freeBatchSprites] = nil else newInstance = {} end newInstance.layer = instance.layer newInstance.batch = instance.batch newInstance.id = instance.id newInstance.gid = tile.gid or 0 newInstance.x = instance.x newInstance.y = instance.y newInstance.r = tile.r or 0 newInstance.oy = tile.r ~= 0 and tile.height or 0 table.insert(self.tileInstances[tile.gid], newInstance) end end --- Convert tile location to pixel location -- @param x The X axis location of the point (in tiles) -- @param y The Y axis location of the point (in tiles) -- @return number The X axis location of the point (in pixels) -- @return number The Y axis location of the point (in pixels) function Map:convertTileToPixel(x,y) if self.orientation == "orthogonal" then local tileW = self.tilewidth local tileH = self.tileheight return x * tileW, y * tileH elseif self.orientation == "isometric" then local mapH = self.height local tileW = self.tilewidth local tileH = self.tileheight local offsetX = mapH * tileW / 2 return (x - y) * tileW / 2 + offsetX, (x + y) * tileH / 2 elseif self.orientation == "staggered" or self.orientation == "hexagonal" then local tileW = self.tilewidth local tileH = self.tileheight local sideLen = self.hexsidelength or 0 if self.staggeraxis == "x" then return x * tileW, ceil(y) * (tileH + sideLen) + (ceil(y) % 2 == 0 and tileH or 0) else return ceil(x) * (tileW + sideLen) + (ceil(x) % 2 == 0 and tileW or 0), y * tileH end end end --- Convert pixel location to tile location -- @param x The X axis location of the point (in pixels) -- @param y The Y axis location of the point (in pixels) -- @return number The X axis location of the point (in tiles) -- @return number The Y axis location of the point (in tiles) function Map:convertPixelToTile(x, y) if self.orientation == "orthogonal" then local tileW = self.tilewidth local tileH = self.tileheight return x / tileW, y / tileH elseif self.orientation == "isometric" then local mapH = self.height local tileW = self.tilewidth local tileH = self.tileheight local offsetX = mapH * tileW / 2 return y / tileH + (x - offsetX) / tileW, y / tileH - (x - offsetX) / tileW elseif self.orientation == "staggered" then local staggerX = self.staggeraxis == "x" local even = self.staggerindex == "even" local function topLeft(x, y) if staggerX then if ceil(x) % 2 == 1 and even then return x - 1, y else return x - 1, y - 1 end else if ceil(y) % 2 == 1 and even then return x, y - 1 else return x - 1, y - 1 end end end local function topRight(x, y) if staggerX then if ceil(x) % 2 == 1 and even then return x + 1, y else return x + 1, y - 1 end else if ceil(y) % 2 == 1 and even then return x + 1, y - 1 else return x, y - 1 end end end local function bottomLeft(x, y) if staggerX then if ceil(x) % 2 == 1 and even then return x - 1, y + 1 else return x - 1, y end else if ceil(y) % 2 == 1 and even then return x, y + 1 else return x - 1, y + 1 end end end local function bottomRight(x, y) if staggerX then if ceil(x) % 2 == 1 and even then return x + 1, y + 1 else return x + 1, y end else if ceil(y) % 2 == 1 and even then return x + 1, y + 1 else return x, y + 1 end end end local tileW = self.tilewidth local tileH = self.tileheight if staggerX then x = x - (even and tileW / 2 or 0) else y = y - (even and tileH / 2 or 0) end local halfH = tileH / 2 local ratio = tileH / tileW local referenceX = ceil(x / tileW) local referenceY = ceil(y / tileH) local relativeX = x - referenceX * tileW local relativeY = y - referenceY * tileH if (halfH - relativeX * ratio > relativeY) then return topLeft(referenceX, referenceY) elseif (-halfH + relativeX * ratio > relativeY) then return topRight(referenceX, referenceY) elseif (halfH + relativeX * ratio < relativeY) then return bottomLeft(referenceX, referenceY) elseif (halfH * 3 - relativeX * ratio < relativeY) then return bottomRight(referenceX, referenceY) end return referenceX, referenceY elseif self.orientation == "hexagonal" then local staggerX = self.staggeraxis == "x" local even = self.staggerindex == "even" local tileW = self.tilewidth local tileH = self.tileheight local sideLenX = 0 local sideLenY = 0 local colW = tileW / 2 local rowH = tileH / 2 if staggerX then sideLenX = self.hexsidelength x = x - (even and tileW or (tileW - sideLenX) / 2) colW = colW - (colW - sideLenX / 2) / 2 else sideLenY = self.hexsidelength y = y - (even and tileH or (tileH - sideLenY) / 2) rowH = rowH - (rowH - sideLenY / 2) / 2 end local referenceX = ceil(x) / (colW * 2) local referenceY = ceil(y) / (rowH * 2) -- If in staggered line, then shift reference by 0.5 of other axes if staggerX then if (floor(referenceX) % 2 == 0) == even then referenceY = referenceY - 0.5 end else if (floor(referenceY) % 2 == 0) == even then referenceX = referenceX - 0.5 end end local relativeX = x - referenceX * colW * 2 local relativeY = y - referenceY * rowH * 2 local centers if staggerX then local left = sideLenX / 2 local centerX = left + colW local centerY = tileH / 2 centers = { { x = left, y = centerY }, { x = centerX, y = centerY - rowH }, { x = centerX, y = centerY + rowH }, { x = centerX + colW, y = centerY }, } else local top = sideLenY / 2 local centerX = tileW / 2 local centerY = top + rowH centers = { { x = centerX, y = top }, { x = centerX - colW, y = centerY }, { x = centerX + colW, y = centerY }, { x = centerX, y = centerY + rowH } } end local nearest = 0 local minDist = math.huge local function len2(ax, ay) return ax * ax + ay * ay end for i = 1, 4 do local dc = len2(centers[i].x - relativeX, centers[i].y - relativeY) if dc < minDist then minDist = dc nearest = i end end local offsetsStaggerX = { { x = 1, y = 1 }, { x = 2, y = 0 }, { x = 2, y = 1 }, { x = 3, y = 1 }, } local offsetsStaggerY = { { x = 1, y = 1 }, { x = 0, y = 2 }, { x = 1, y = 2 }, { x = 1, y = 3 }, } local offsets = staggerX and offsetsStaggerX or offsetsStaggerY return referenceX + offsets[nearest].x, referenceY + offsets[nearest].y end end --- A list of individual layers indexed both by draw order and name -- @table Map.layers -- @see TileLayer -- @see ObjectLayer -- @see ImageLayer -- @see CustomLayer --- A list of individual tiles indexed by Global ID -- @table Map.tiles -- @see Tile -- @see Map.tileInstances --- A list of tile instances indexed by Global ID -- @table Map.tileInstances -- @see TileInstance -- @see Tile -- @see Map.tiles --- A list of no-longer-used batch sprites, indexed by batch --@table Map.freeBatchSprites --- A list of individual objects indexed by Global ID -- @table Map.objects -- @see Object --- @table TileLayer -- @field name The name of the layer -- @field x Position on the X axis (in pixels) -- @field y Position on the Y axis (in pixels) -- @field width Width of layer (in tiles) -- @field height Height of layer (in tiles) -- @field visible Toggle if layer is visible or hidden -- @field opacity Opacity of layer -- @field properties Custom properties -- @field data A tileWo dimensional table filled with individual tiles indexed by [y][x] (in tiles) -- @field update Update function -- @field draw Draw function -- @see Map.layers -- @see Tile --- @table ObjectLayer -- @field name The name of the layer -- @field x Position on the X axis (in pixels) -- @field y Position on the Y axis (in pixels) -- @field visible Toggle if layer is visible or hidden -- @field opacity Opacity of layer -- @field properties Custom properties -- @field objects List of objects indexed by draw order -- @field update Update function -- @field draw Draw function -- @see Map.layers -- @see Object --- @table ImageLayer -- @field name The name of the layer -- @field x Position on the X axis (in pixels) -- @field y Position on the Y axis (in pixels) -- @field visible Toggle if layer is visible or hidden -- @field opacity Opacity of layer -- @field properties Custom properties -- @field image Image to be drawn -- @field update Update function -- @field draw Draw function -- @see Map.layers --- Custom Layers are used to place userdata such as sprites within the draw order of the map. -- @table CustomLayer -- @field name The name of the layer -- @field x Position on the X axis (in pixels) -- @field y Position on the Y axis (in pixels) -- @field visible Toggle if layer is visible or hidden -- @field opacity Opacity of layer -- @field properties Custom properties -- @field update Update function -- @field draw Draw function -- @see Map.layers -- @usage -- -- Create a Custom Layer -- local spriteLayer = map:addCustomLayer("Sprite Layer", 3) -- -- -- Add data to Custom Layer -- spriteLayer.sprites = { -- player = { -- image = lg.newImage("assets/sprites/player.png"), -- x = 64, -- y = 64, -- r = 0, -- } -- } -- -- -- Update callback for Custom Layer -- function spriteLayer:update(dt) -- for _, sprite in pairs(self.sprites) do -- sprite.r = sprite.r + math.rad(90 * dt) -- end -- end -- -- -- Draw callback for Custom Layer -- function spriteLayer:draw() -- for _, sprite in pairs(self.sprites) do -- local x = math.floor(sprite.x) -- local y = math.floor(sprite.y) -- local r = sprite.r -- lg.draw(sprite.image, x, y, r) -- end -- end --- @table Tile -- @field id Local ID within Tileset -- @field gid Global ID -- @field tileset Tileset ID -- @field quad Quad object -- @field properties Custom properties -- @field terrain Terrain data -- @field animation Animation data -- @field frame Current animation frame -- @field time Time spent on current animation frame -- @field width Width of tile -- @field height Height of tile -- @field sx Scale value on the X axis -- @field sy Scale value on the Y axis -- @field r Rotation of tile (in radians) -- @field offset Offset drawing position -- @field offset.x Offset value on the X axis -- @field offset.y Offset value on the Y axis -- @see Map.tiles --- @table TileInstance -- @field batch Spritebatch the Tile Instance belongs to -- @field id ID within the spritebatch -- @field gid Global ID -- @field x Position on the X axis (in pixels) -- @field y Position on the Y axis (in pixels) -- @see Map.tileInstances -- @see Tile --- @table Object -- @field id Global ID -- @field name Name of object (non-unique) -- @field shape Shape of object -- @field x Position of object on X axis (in pixels) -- @field y Position of object on Y axis (in pixels) -- @field width Width of object (in pixels) -- @field height Heigh tof object (in pixels) -- @field rotation Rotation of object (in radians) -- @field visible Toggle if object is visible or hidden -- @field properties Custom properties -- @field ellipse List of verticies of specific shape -- @field rectangle List of verticies of specific shape -- @field polygon List of verticies of specific shape -- @field polyline List of verticies of specific shape -- @see Map.objects return setmetatable({}, STI) |
Added src/fahombo/lib/sti/plugins/box2d.lua.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
--- Box2D plugin for STI -- @module box2d -- @author Landon Manning -- @copyright 2019 -- @license MIT/X11 local love = _G.love local utils = require((...):gsub('plugins.box2d', 'utils')) local lg = require((...):gsub('plugins.box2d', 'graphics')) return { box2d_LICENSE = "MIT/X11", box2d_URL = "https://github.com/karai17/Simple-Tiled-Implementation", box2d_VERSION = "2.3.2.7", box2d_DESCRIPTION = "Box2D hooks for STI.", --- Initialize Box2D physics world. -- @param world The Box2D world to add objects to. box2d_init = function(map, world) assert(love.physics, "To use the Box2D plugin, please enable the love.physics module.") local body = love.physics.newBody(world, map.offsetx, map.offsety) local collision = { body = body, } local function addObjectToWorld(objshape, vertices, userdata, object) local shape if objshape == "polyline" then if #vertices == 4 then shape = love.physics.newEdgeShape(unpack(vertices)) else shape = love.physics.newChainShape(false, unpack(vertices)) end else shape = love.physics.newPolygonShape(unpack(vertices)) end local currentBody = body if userdata.properties.dynamic == true then currentBody = love.physics.newBody(world, map.offsetx, map.offsety, 'dynamic') end local fixture = love.physics.newFixture(currentBody, shape) fixture:setUserData(userdata) -- Set some custom properties from userdata (or use default set by box2d) fixture:setFriction(userdata.properties.friction or 0.2) fixture:setRestitution(userdata.properties.restitution or 0.0) fixture:setSensor(userdata.properties.sensor or false) fixture:setFilterData( userdata.properties.categories or 1, userdata.properties.mask or 65535, userdata.properties.group or 0 ) local obj = { object = object, body = currentBody, shape = shape, fixture = fixture, } table.insert(collision, obj) end local function getPolygonVertices(object) local vertices = {} for _, vertex in ipairs(object.polygon) do table.insert(vertices, vertex.x) table.insert(vertices, vertex.y) end return vertices end local function calculateObjectPosition(object, tile) local o = { shape = object.shape, x = (object.dx or object.x) + map.offsetx, y = (object.dy or object.y) + map.offsety, w = object.width, h = object.height, polygon = object.polygon or object.polyline or object.ellipse or object.rectangle } local userdata = { object = o, properties = object.properties } o.r = object.rotation or 0 if o.shape == "rectangle" then local cos = math.cos(math.rad(o.r)) local sin = math.sin(math.rad(o.r)) local oy = 0 if object.gid then local tileset = map.tilesets[map.tiles[object.gid].tileset] local lid = object.gid - tileset.firstgid local t = {} -- This fixes a height issue o.y = o.y + map.tiles[object.gid].offset.y oy = o.h for _, tt in ipairs(tileset.tiles) do if tt.id == lid then t = tt break end end if t.objectGroup then for _, obj in ipairs(t.objectGroup.objects) do -- Every object in the tile calculateObjectPosition(obj, object) end return else o.w = map.tiles[object.gid].width o.h = map.tiles[object.gid].height end end o.polygon = { { x=o.x+0, y=o.y+0 }, { x=o.x+o.w, y=o.y+0 }, { x=o.x+o.w, y=o.y+o.h }, { x=o.x+0, y=o.y+o.h } } for _, vertex in ipairs(o.polygon) do vertex.x, vertex.y = utils.rotate_vertex(map, vertex, o.x, o.y, cos, sin, oy) end local vertices = getPolygonVertices(o) addObjectToWorld(o.shape, vertices, userdata, tile or object) elseif o.shape == "ellipse" then if not o.polygon then o.polygon = utils.convert_ellipse_to_polygon(o.x, o.y, o.w, o.h) end local vertices = getPolygonVertices(o) local triangles = love.math.triangulate(vertices) for _, triangle in ipairs(triangles) do addObjectToWorld(o.shape, triangle, userdata, tile or object) end elseif o.shape == "polygon" then -- Recalculate collision polygons inside tiles if tile then local cos = math.cos(math.rad(o.r)) local sin = math.sin(math.rad(o.r)) for _, vertex in ipairs(o.polygon) do vertex.x = vertex.x + o.x vertex.y = vertex.y + o.y vertex.x, vertex.y = utils.rotate_vertex(map, vertex, o.x, o.y, cos, sin) end end local vertices = getPolygonVertices(o) local triangles = love.math.triangulate(vertices) for _, triangle in ipairs(triangles) do addObjectToWorld(o.shape, triangle, userdata, tile or object) end elseif o.shape == "polyline" then local vertices = getPolygonVertices(o) addObjectToWorld(o.shape, vertices, userdata, tile or object) end end for _, tile in pairs(map.tiles) do if map.tileInstances[tile.gid] then for _, instance in ipairs(map.tileInstances[tile.gid]) do -- Every object in every instance of a tile if tile.objectGroup then for _, object in ipairs(tile.objectGroup.objects) do if object.properties.collidable == true then object = utils.deepCopy(object) object.dx = instance.x + object.x object.dy = instance.y + object.y calculateObjectPosition(object, instance) end end end -- Every instance of a tile if tile.properties.collidable == true then local object = { shape = "rectangle", x = instance.x, y = instance.y, width = map.tilewidth, height = map.tileheight, properties = tile.properties } calculateObjectPosition(object, instance) end end end end for _, layer in ipairs(map.layers) do -- Entire layer if layer.properties.collidable == true then if layer.type == "tilelayer" then for gid, tiles in pairs(map.tileInstances) do local tile = map.tiles[gid] local tileset = map.tilesets[tile.tileset] for _, instance in ipairs(tiles) do if instance.layer == layer then local object = { shape = "rectangle", x = instance.x, y = instance.y, width = tileset.tilewidth, height = tileset.tileheight, properties = tile.properties } calculateObjectPosition(object, instance) end end end elseif layer.type == "objectgroup" then for _, object in ipairs(layer.objects) do calculateObjectPosition(object) end elseif layer.type == "imagelayer" then local object = { shape = "rectangle", x = layer.x or 0, y = layer.y or 0, width = layer.width, height = layer.height, properties = layer.properties } calculateObjectPosition(object) end end -- Individual objects if layer.type == "objectgroup" then for _, object in ipairs(layer.objects) do if object.properties.collidable == true then calculateObjectPosition(object) end end end end map.box2d_collision = collision end, --- Remove Box2D fixtures and shapes from world. -- @param index The index or name of the layer being removed box2d_removeLayer = function(map, index) local layer = assert(map.layers[index], "Layer not found: " .. index) local collision = map.box2d_collision -- Remove collision objects for i = #collision, 1, -1 do local obj = collision[i] if obj.object.layer == layer then obj.fixture:destroy() table.remove(collision, i) end end end, --- Draw Box2D physics world. -- @param tx Translate on X -- @param ty Translate on Y -- @param sx Scale on X -- @param sy Scale on Y box2d_draw = function(map, tx, ty, sx, sy) local collision = map.box2d_collision lg.push() lg.scale(sx or 1, sy or sx or 1) lg.translate(math.floor(tx or 0), math.floor(ty or 0)) for _, obj in ipairs(collision) do local points = {obj.body:getWorldPoints(obj.shape:getPoints())} local shape_type = obj.shape:getType() if shape_type == "edge" or shape_type == "chain" then love.graphics.line(points) elseif shape_type == "polygon" then love.graphics.polygon("line", points) else error("sti box2d plugin does not support "..shape_type.." shapes") end end lg.pop() end } --- Custom Properties in Tiled are used to tell this plugin what to do. -- @table Properties -- @field collidable set to true, can be used on any Layer, Tile, or Object -- @field sensor set to true, can be used on any Tile or Object that is also collidable -- @field dynamic set to true, can be used on any Tile or Object -- @field friction can be used to define the friction of any Object -- @field restitution can be used to define the restitution of any Object -- @field categories can be used to set the filter Category of any Object -- @field mask can be used to set the filter Mask of any Object -- @field group can be used to set the filter Group of any Object |
Added src/fahombo/lib/sti/plugins/bump.lua.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 |
--- Bump.lua plugin for STI -- @module bump.lua -- @author David Serrano (BobbyJones|FrenchFryLord) -- @copyright 2019 -- @license MIT/X11 local lg = require((...):gsub('plugins.bump', 'graphics')) return { bump_LICENSE = "MIT/X11", bump_URL = "https://github.com/karai17/Simple-Tiled-Implementation", bump_VERSION = "3.1.7.0", bump_DESCRIPTION = "Bump hooks for STI.", --- Adds each collidable tile to the Bump world. -- @param world The Bump world to add objects to. -- @return collidables table containing the handles to the objects in the Bump world. bump_init = function(map, world) local collidables = {} for _, tileset in ipairs(map.tilesets) do for _, tile in ipairs(tileset.tiles) do local gid = tileset.firstgid + tile.id if map.tileInstances[gid] then for _, instance in ipairs(map.tileInstances[gid]) do -- Every object in every instance of a tile if tile.objectGroup then for _, object in ipairs(tile.objectGroup.objects) do if object.properties.collidable == true then local t = { name = object.name, type = object.type, x = instance.x + map.offsetx + object.x, y = instance.y + map.offsety + object.y, width = object.width, height = object.height, layer = instance.layer, properties = object.properties } world:add(t, t.x, t.y, t.width, t.height) table.insert(collidables, t) end end end -- Every instance of a tile if tile.properties and tile.properties.collidable == true then local t = { x = instance.x + map.offsetx, y = instance.y + map.offsety, width = map.tilewidth, height = map.tileheight, layer = instance.layer, properties = tile.properties } world:add(t, t.x, t.y, t.width, t.height) table.insert(collidables, t) end end end end end for _, layer in ipairs(map.layers) do -- Entire layer if layer.properties.collidable == true then if layer.type == "tilelayer" then for y, tiles in ipairs(layer.data) do for x, tile in pairs(tiles) do if tile.objectGroup then for _, object in ipairs(tile.objectGroup.objects) do if object.properties.collidable == true then local t = { name = object.name, type = object.type, x = ((x-1) * map.tilewidth + tile.offset.x + map.offsetx) + object.x, y = ((y-1) * map.tileheight + tile.offset.y + map.offsety) + object.y, width = object.width, height = object.height, layer = layer, properties = object.properties } world:add(t, t.x, t.y, t.width, t.height) table.insert(collidables, t) end end end local t = { x = (x-1) * map.tilewidth + tile.offset.x + map.offsetx, y = (y-1) * map.tileheight + tile.offset.y + map.offsety, width = tile.width, height = tile.height, layer = layer, properties = tile.properties } world:add(t, t.x, t.y, t.width, t.height) table.insert(collidables, t) end end elseif layer.type == "imagelayer" then world:add(layer, layer.x, layer.y, layer.width, layer.height) table.insert(collidables, layer) end end -- individual collidable objects in a layer that is not "collidable" -- or whole collidable objects layer if layer.type == "objectgroup" then for _, obj in ipairs(layer.objects) do if layer.properties.collidable == true or obj.properties.collidable == true then if obj.shape == "rectangle" then local t = { name = obj.name, type = obj.type, x = obj.x + map.offsetx, y = obj.y + map.offsety, width = obj.width, height = obj.height, layer = layer, properties = obj.properties } if obj.gid then t.y = t.y - obj.height end world:add(t, t.x, t.y, t.width, t.height) table.insert(collidables, t) end -- TODO implement other object shapes? end end end end map.bump_collidables = collidables end, --- Remove layer -- @param index to layer to be removed -- @param world bump world the holds the tiles -- @param tx Translate on X -- @param ty Translate on Y -- @param sx Scale on X -- @param sy Scale on Y bump_removeLayer = function(map, index, world) local layer = assert(map.layers[index], "Layer not found: " .. index) local collidables = map.bump_collidables -- Remove collision objects for i = #collidables, 1, -1 do local obj = collidables[i] if obj.layer == layer and ( layer.properties.collidable == true or obj.properties.collidable == true ) then world:remove(obj) table.remove(collidables, i) end end end, --- Draw bump collisions world. -- @param world bump world holding the tiles geometry -- @param tx Translate on X -- @param ty Translate on Y -- @param sx Scale on X -- @param sy Scale on Y bump_draw = function(map, world, tx, ty, sx, sy) lg.push() lg.scale(sx or 1, sy or sx or 1) lg.translate(math.floor(tx or 0), math.floor(ty or 0)) for _, collidable in pairs(map.bump_collidables) do lg.rectangle("line", world:getRect(collidable)) end lg.pop() end } --- Custom Properties in Tiled are used to tell this plugin what to do. -- @table Properties -- @field collidable set to true, can be used on any Layer, Tile, or Object |
Added src/fahombo/lib/sti/utils.lua.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 |
-- Some utility functions that shouldn't be exposed. local utils = {} -- https://github.com/stevedonovan/Penlight/blob/master/lua/pl/path.lua#L286 function utils.format_path(path) local np_gen1,np_gen2 = '[^SEP]+SEP%.%.SEP?','SEP+%.?SEP' local np_pat1, np_pat2 = np_gen1:gsub('SEP','/'), np_gen2:gsub('SEP','/') local k repeat -- /./ -> / path,k = path:gsub(np_pat2,'/',1) until k == 0 repeat -- A/../ -> (empty) path,k = path:gsub(np_pat1,'',1) until k == 0 if path == '' then path = '.' end return path end -- Compensation for scale/rotation shift function utils.compensate(tile, tileX, tileY, tileW, tileH) local compx = 0 local compy = 0 if tile.sx < 0 then compx = tileW end if tile.sy < 0 then compy = tileH end if tile.r > 0 then tileX = tileX + tileH - compy tileY = tileY + tileH + compx - tileW elseif tile.r < 0 then tileX = tileX + compy tileY = tileY - compx + tileH else tileX = tileX + compx tileY = tileY + compy end return tileX, tileY end -- Cache images in main STI module function utils.cache_image(sti, path, image) image = image or love.graphics.newImage(path) image:setFilter("nearest", "nearest") sti.cache[path] = image end -- We just don't know. function utils.get_tiles(imageW, tileW, margin, spacing) imageW = imageW - margin local n = 0 while imageW >= tileW do imageW = imageW - tileW if n ~= 0 then imageW = imageW - spacing end if imageW >= 0 then n = n + 1 end end return n end -- Decompress tile layer data function utils.get_decompressed_data(data) local ffi = require "ffi" local d = {} local decoded = ffi.cast("uint32_t*", data) for i = 0, data:len() / ffi.sizeof("uint32_t") do table.insert(d, tonumber(decoded[i])) end return d end -- Convert a Tiled ellipse object to a LOVE polygon function utils.convert_ellipse_to_polygon(x, y, w, h, max_segments) local ceil = math.ceil local cos = math.cos local sin = math.sin local function calc_segments(segments) local function vdist(a, b) local c = { x = a.x - b.x, y = a.y - b.y, } return c.x * c.x + c.y * c.y end segments = segments or 64 local vertices = {} local v = { 1, 2, ceil(segments/4-1), ceil(segments/4) } local m if love and love.physics then m = love.physics.getMeter() else m = 32 end for _, i in ipairs(v) do local angle = (i / segments) * math.pi * 2 local px = x + w / 2 + cos(angle) * w / 2 local py = y + h / 2 + sin(angle) * h / 2 table.insert(vertices, { x = px / m, y = py / m }) end local dist1 = vdist(vertices[1], vertices[2]) local dist2 = vdist(vertices[3], vertices[4]) -- Box2D threshold if dist1 < 0.0025 or dist2 < 0.0025 then return calc_segments(segments-2) end return segments end local segments = calc_segments(max_segments) local vertices = {} table.insert(vertices, { x = x + w / 2, y = y + h / 2 }) for i = 0, segments do local angle = (i / segments) * math.pi * 2 local px = x + w / 2 + cos(angle) * w / 2 local py = y + h / 2 + sin(angle) * h / 2 table.insert(vertices, { x = px, y = py }) end return vertices end function utils.rotate_vertex(map, vertex, x, y, cos, sin, oy) if map.orientation == "isometric" then x, y = utils.convert_isometric_to_screen(map, x, y) vertex.x, vertex.y = utils.convert_isometric_to_screen(map, vertex.x, vertex.y) end vertex.x = vertex.x - x vertex.y = vertex.y - y return x + cos * vertex.x - sin * vertex.y, y + sin * vertex.x + cos * vertex.y - (oy or 0) end --- Project isometric position to cartesian position function utils.convert_isometric_to_screen(map, x, y) local mapW = map.width local tileW = map.tilewidth local tileH = map.tileheight local tileX = x / tileH local tileY = y / tileH local offsetX = mapW * tileW / 2 return (tileX - tileY) * tileW / 2 + offsetX, (tileX + tileY) * tileH / 2 end function utils.hex_to_color(hex) if hex:sub(1, 1) == "#" then hex = hex:sub(2) end return { r = tonumber(hex:sub(1, 2), 16) / 255, g = tonumber(hex:sub(3, 4), 16) / 255, b = tonumber(hex:sub(5, 6), 16) / 255 } end function utils.pixel_function(_, _, r, g, b, a) local mask = utils._TC if r == mask.r and g == mask.g and b == mask.b then return r, g, b, 0 end return r, g, b, a end function utils.fix_transparent_color(tileset, path) local image_data = love.image.newImageData(path) tileset.image = love.graphics.newImage(image_data) if tileset.transparentcolor then utils._TC = utils.hex_to_color(tileset.transparentcolor) image_data:mapPixel(utils.pixel_function) tileset.image = love.graphics.newImage(image_data) end end function utils.deepCopy(t) local copy = {} for k,v in pairs(t) do if type(v) == "table" then v = utils.deepCopy(v) end copy[k] = v end return copy end return utils |
Added src/fahombo/map.lua.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 |
-- based on assets/warped_city/maps/map.json return { version = "1.2", luaversion = "5.1", tiledversion = "1.3.3", orientation = "orthogonal", renderorder = "right-down", width = 120, height = 28, tilewidth = 16, tileheight = 16, nextlayerid = 4, nextobjectid = 45, backgroundcolor = { 0, 0, 255 }, properties = {}, tilesets = { { name = "tileset", firstgid = 1, tilewidth = 16, tileheight = 16, spacing = 0, margin = 0, columns = 24, image = "assets/warped_city/environment/tileset.png", imagewidth = 384, imageheight = 256, tileoffset = { x = 0, y = 0 }, grid = { orientation = "orthogonal", width = 16, height = 16 }, properties = {}, terrains = {}, tilecount = 384, tiles = {} } }, layers = { { type = "tilelayer", id = 1, name = "Collisions Layer", x = 0, y = 0, width = 120, height = 28, visible = true, opacity = 1, offsetx = 0, offsety = 0, properties = {}, encoding = "lua", data = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 } }, { type = "tilelayer", id = 2, name = "Main Layer", x = 0, y = 0, width = 120, height = 28, visible = true, opacity = 1, offsetx = 0, offsety = 0, properties = {}, encoding = "lua", data = { 0, 26, 76, 77, 78, 29, 29, 76, 77, 78, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 39, 40, 41, 37, 159, 160, 161, 37, 279, 280, 281, 37, 39, 40, 41, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 76, 77, 78, 245, 29, 76, 77, 78, 80, 0, 50, 100, 101, 102, 29, 29, 100, 101, 102, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 63, 64, 65, 61, 183, 184, 185, 61, 303, 304, 305, 61, 63, 64, 65, 67, 68, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 100, 101, 102, 269, 29, 100, 101, 102, 56, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 83, 87, 88, 89, 85, 207, 208, 209, 85, 327, 328, 329, 61, 87, 88, 89, 91, 92, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 0, 26, 28, 29, 30, 245, 163, 28, 29, 30, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 107, 111, 112, 113, 109, 231, 232, 233, 85, 351, 352, 353, 61, 111, 112, 113, 115, 116, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 225, 224, 224, 224, 0, 0, 0, 224, 224, 224, 225, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 28, 29, 30, 228, 229, 28, 29, 30, 32, 0, 50, 52, 53, 54, 269, 187, 52, 53, 54, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 52, 53, 54, 252, 253, 52, 53, 54, 32, 0, 74, 76, 77, 78, 245, 29, 76, 77, 78, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 39, 40, 41, 37, 159, 160, 161, 37, 39, 40, 41, 37, 279, 280, 281, 43, 44, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 29, 29, 29, 29, 165, 147, 29, 228, 229, 43, 44, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 76, 77, 78, 167, 29, 76, 77, 78, 56, 0, 26, 100, 101, 102, 269, 29, 100, 101, 102, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 63, 64, 65, 61, 183, 184, 185, 61, 63, 64, 65, 61, 303, 304, 305, 67, 68, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 189, 189, 29, 29, 29, 147, 29, 252, 253, 67, 68, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 100, 101, 102, 191, 29, 100, 101, 102, 80, 0, 50, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 83, 87, 88, 89, 109, 207, 208, 209, 85, 87, 88, 89, 61, 327, 328, 329, 91, 92, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 83, 165, 189, 29, 29, 29, 147, 29, 29, 29, 91, 92, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 273, 272, 272, 272, 272, 272, 272, 272, 272, 272, 0, 74, 28, 29, 30, 228, 229, 28, 29, 30, 32, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 107, 111, 112, 113, 85, 231, 232, 233, 85, 111, 112, 113, 61, 351, 352, 353, 115, 116, 0, 0, 0, 0, 224, 224, 225, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 107, 29, 29, 29, 29, 29, 147, 29, 29, 29, 115, 116, 0, 0, 0, 0, 224, 224, 225, 224, 224, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 50, 28, 29, 30, 167, 245, 28, 29, 30, 56, 0, 26, 52, 53, 54, 252, 253, 52, 53, 54, 32, 0, 0, 0, 0, 0, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 147, 272, 272, 272, 272, 272, 274, 0, 0, 271, 272, 272, 272, 272, 272, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 83, 155, 156, 157, 29, 29, 147, 29, 189, 165, 67, 68, 0, 0, 0, 271, 272, 272, 272, 272, 272, 274, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 50, 52, 53, 54, 191, 245, 52, 53, 54, 56, 0, 50, 76, 77, 78, 29, 29, 76, 77, 78, 56, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 279, 280, 281, 37, 159, 160, 161, 37, 39, 40, 41, 147, 159, 160, 161, 43, 44, 0, 0, 0, 0, 26, 245, 167, 29, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 107, 179, 180, 181, 29, 29, 147, 29, 189, 189, 91, 92, 0, 0, 0, 0, 26, 245, 167, 29, 56, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 26, 76, 77, 78, 167, 245, 76, 77, 78, 32, 0, 74, 100, 101, 102, 29, 29, 100, 101, 102, 80, 0, 0, 0, 224, 224, 225, 224, 224, 224, 224, 224, 224, 224, 0, 0, 0, 0, 58, 59, 303, 304, 305, 61, 183, 184, 185, 61, 63, 64, 65, 147, 183, 184, 185, 67, 68, 0, 0, 0, 0, 50, 245, 191, 29, 32, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 147, 272, 272, 272, 272, 272, 274, 0, 0, 0, 50, 245, 191, 29, 32, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 50, 100, 101, 102, 191, 269, 100, 101, 102, 56, 271, 273, 272, 272, 272, 147, 272, 272, 272, 272, 272, 274, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 82, 83, 327, 328, 329, 85, 207, 208, 209, 85, 87, 88, 89, 147, 207, 208, 209, 91, 92, 0, 0, 0, 0, 74, 245, 167, 29, 56, 0, 0, 0, 0, 0, 34, 35, 228, 229, 29, 37, 29, 228, 229, 37, 228, 229, 29, 147, 167, 29, 29, 43, 44, 0, 0, 0, 0, 74, 245, 167, 29, 56, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 50, 28, 29, 30, 147, 245, 28, 29, 30, 56, 0, 0, 0, 26, 228, 229, 245, 149, 29, 163, 228, 229, 32, 0, 0, 0, 0, 106, 107, 351, 352, 353, 85, 231, 232, 233, 85, 111, 112, 113, 147, 231, 232, 233, 115, 116, 0, 0, 0, 0, 26, 245, 191, 29, 56, 0, 0, 0, 0, 0, 58, 59, 252, 253, 29, 61, 29, 252, 253, 61, 252, 253, 29, 147, 191, 29, 29, 67, 68, 0, 0, 0, 0, 26, 245, 191, 29, 56, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 0, 0, 26, 28, 29, 30, 245, 163, 28, 29, 30, 32, 0, 50, 52, 53, 54, 147, 245, 52, 53, 54, 56, 0, 0, 0, 50, 252, 253, 245, 173, 29, 187, 252, 253, 56, 0, 0, 0, 271, 272, 272, 272, 272, 272, 61, 46, 46, 46, 46, 46, 46, 46, 147, 272, 272, 272, 272, 272, 274, 0, 0, 0, 50, 245, 167, 29, 56, 0, 0, 0, 0, 0, 82, 83, 165, 165, 29, 109, 29, 189, 189, 61, 189, 189, 29, 147, 167, 29, 189, 91, 92, 0, 0, 0, 0, 50, 245, 167, 29, 56, 0, 0, 0, 0, 224, 224, 225, 224, 224, 0, 0, 0, 0, 224, 224, 225, 224, 224, 0, 0, 0, 50, 52, 53, 54, 269, 187, 52, 53, 54, 56, 0, 26, 76, 77, 78, 147, 245, 76, 77, 78, 32, 0, 0, 0, 74, 29, 29, 245, 173, 29, 29, 29, 167, 80, 0, 0, 0, 0, 34, 35, 39, 40, 41, 61, 228, 229, 29, 29, 29, 228, 229, 147, 39, 40, 41, 43, 44, 0, 0, 0, 0, 74, 245, 191, 29, 80, 0, 0, 0, 0, 0, 106, 107, 189, 189, 29, 61, 29, 189, 165, 61, 189, 189, 29, 147, 191, 29, 29, 115, 116, 0, 0, 0, 0, 74, 245, 191, 29, 80, 0, 0, 0, 271, 272, 272, 272, 272, 272, 274, 0, 0, 271, 272, 272, 272, 272, 272, 274, 0, 0, 74, 76, 77, 78, 245, 29, 76, 77, 78, 80, 0, 50, 100, 101, 102, 147, 269, 100, 101, 102, 56, 0, 0, 0, 26, 163, 29, 245, 173, 29, 29, 29, 191, 32, 0, 0, 0, 0, 58, 59, 63, 64, 65, 61, 252, 253, 29, 29, 29, 252, 253, 147, 63, 64, 65, 67, 68, 0, 0, 0, 0, 26, 228, 229, 29, 56, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 147, 46, 46, 46, 46, 46, 0, 0, 0, 0, 26, 228, 229, 29, 56, 0, 0, 0, 0, 26, 245, 167, 29, 56, 0, 0, 0, 0, 26, 245, 167, 29, 56, 0, 0, 0, 26, 100, 101, 102, 269, 29, 100, 101, 102, 56, 0, 46, 46, 46, 46, 147, 46, 46, 46, 46, 46, 0, 0, 0, 50, 187, 29, 245, 173, 155, 156, 157, 29, 56, 0, 0, 0, 0, 82, 83, 87, 88, 89, 85, 165, 29, 155, 156, 157, 29, 29, 147, 87, 88, 89, 91, 92, 0, 0, 0, 0, 50, 252, 253, 29, 56, 0, 0, 0, 0, 0, 34, 35, 279, 280, 281, 37, 159, 160, 161, 37, 39, 40, 41, 147, 159, 160, 161, 43, 44, 0, 0, 0, 0, 50, 252, 253, 29, 56, 0, 0, 0, 0, 50, 245, 191, 29, 32, 0, 0, 0, 0, 50, 245, 191, 29, 32, 0, 0, 0, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 0, 26, 28, 29, 30, 147, 29, 28, 29, 30, 32, 0, 0, 0, 74, 29, 189, 189, 173, 179, 180, 181, 29, 80, 0, 0, 0, 0, 106, 107, 111, 112, 113, 109, 189, 29, 179, 180, 181, 29, 29, 171, 111, 112, 113, 115, 116, 0, 0, 0, 0, 74, 29, 167, 29, 80, 0, 0, 0, 0, 0, 58, 59, 303, 304, 305, 61, 183, 184, 185, 61, 63, 64, 65, 147, 183, 184, 185, 67, 68, 0, 0, 0, 0, 74, 29, 167, 29, 80, 0, 0, 0, 0, 74, 245, 167, 29, 56, 0, 0, 0, 0, 74, 245, 167, 29, 56, 0, 0, 0, 74, 28, 29, 30, 228, 229, 28, 29, 30, 32, 0, 50, 52, 53, 54, 147, 29, 52, 53, 54, 56, 0, 0, 0, 26, 29, 163, 163, 173, 228, 229, 167, 29, 32, 0, 0, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 26, 29, 191, 29, 56, 0, 0, 0, 0, 0, 82, 83, 327, 328, 329, 85, 207, 208, 209, 85, 87, 88, 89, 147, 207, 208, 209, 91, 92, 0, 0, 0, 0, 26, 29, 191, 29, 56, 0, 0, 0, 0, 26, 245, 191, 29, 56, 0, 0, 0, 0, 26, 245, 191, 29, 56, 0, 0, 0, 26, 52, 53, 54, 252, 253, 52, 53, 54, 32, 0, 74, 76, 77, 78, 147, 163, 76, 77, 78, 80, 0, 0, 0, 50, 29, 187, 187, 197, 252, 253, 191, 29, 56, 0, 0, 0, 0, 34, 35, 159, 160, 161, 37, 159, 160, 161, 37, 279, 280, 281, 37, 39, 40, 41, 43, 44, 0, 0, 0, 0, 50, 29, 167, 29, 56, 0, 0, 0, 0, 0, 106, 107, 351, 352, 353, 85, 231, 232, 233, 85, 111, 112, 113, 171, 231, 232, 233, 115, 116, 0, 0, 0, 0, 50, 29, 167, 29, 56, 0, 0, 0, 0, 50, 245, 167, 29, 56, 0, 0, 0, 0, 50, 245, 167, 29, 56, 0, 0, 0, 50, 76, 77, 78, 29, 167, 76, 77, 78, 56, 0, 26, 100, 101, 102, 171, 187, 100, 101, 102, 56, 0, 0, 0, 74, 29, 245, 245, 29, 173, 29, 167, 29, 80, 0, 0, 0, 0, 58, 59, 183, 184, 185, 61, 183, 184, 185, 61, 303, 304, 305, 109, 63, 64, 65, 67, 68, 0, 0, 0, 0, 74, 29, 191, 29, 56, 0, 0, 0, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 74, 29, 191, 29, 56, 0, 0, 0, 0, 74, 245, 191, 29, 80, 0, 0, 0, 0, 74, 245, 191, 29, 80, 0, 0, 0, 74, 100, 101, 102, 29, 191, 100, 101, 102, 80, 0, 50, 272, 272, 272, 272, 272, 272, 272, 147, 272, 274, 0, 0, 26, 29, 245, 245, 29, 173, 29, 191, 29, 32, 0, 0, 0, 0, 82, 83, 207, 208, 209, 85, 207, 208, 209, 85, 327, 328, 329, 61, 87, 88, 89, 91, 92, 0, 0, 0, 0, 26, 29, 167, 29, 56, 0, 0, 0, 0, 0, 34, 35, 39, 40, 41, 61, 159, 160, 161, 61, 159, 160, 161, 37, 39, 40, 41, 43, 44, 0, 0, 0, 0, 26, 29, 167, 29, 56, 0, 0, 0, 0, 26, 228, 229, 29, 56, 0, 0, 0, 0, 26, 228, 229, 29, 56, 0, 0, 0, 273, 272, 272, 272, 272, 272, 272, 272, 272, 272, 0, 74, 28, 29, 30, 228, 229, 28, 29, 147, 32, 0, 0, 0, 50, 29, 245, 245, 29, 173, 189, 189, 189, 56, 0, 0, 0, 0, 106, 107, 231, 232, 233, 85, 231, 232, 233, 85, 351, 352, 353, 61, 111, 112, 113, 115, 116, 0, 0, 0, 0, 50, 29, 191, 29, 56, 0, 0, 0, 0, 0, 58, 59, 63, 64, 65, 61, 183, 184, 185, 61, 183, 184, 185, 61, 63, 64, 65, 67, 68, 0, 0, 0, 0, 50, 29, 191, 29, 56, 0, 0, 0, 0, 50, 252, 253, 29, 56, 0, 0, 0, 0, 50, 252, 253, 29, 56, 0, 0, 0, 50, 28, 29, 30, 29, 245, 28, 29, 30, 56, 0, 26, 52, 53, 54, 252, 253, 52, 53, 147, 32, 0, 0, 0, 74, 29, 245, 245, 29, 173, 189, 189, 189, 80, 0, 0, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 74, 29, 167, 29, 56, 0, 0, 0, 0, 0, 82, 83, 87, 88, 89, 85, 207, 208, 209, 61, 207, 208, 209, 109, 87, 88, 89, 91, 92, 0, 0, 0, 0, 74, 29, 167, 29, 56, 0, 0, 0, 0, 74, 29, 167, 29, 80, 0, 0, 0, 0, 74, 29, 167, 29, 80, 0, 0, 0, 50, 52, 53, 54, 29, 245, 52, 53, 54, 56, 0, 50, 76, 77, 78, 29, 29, 76, 77, 147, 56, 0, 0, 0, 26, 29, 197, 245, 29, 173, 29, 29, 29, 32, 0, 0, 0, 0, 34, 35, 39, 40, 41, 37, 159, 160, 161, 37, 39, 40, 41, 37, 39, 40, 41, 43, 44, 0, 0, 0, 0, 50, 29, 191, 29, 56, 0, 0, 0, 0, 0, 106, 107, 111, 112, 113, 109, 231, 232, 233, 61, 231, 232, 233, 61, 111, 112, 113, 115, 116, 0, 0, 0, 0, 50, 29, 191, 29, 56, 0, 0, 0, 0, 26, 29, 191, 29, 56, 0, 0, 0, 0, 26, 29, 191, 29, 56, 0, 0, 0, 26, 76, 77, 78, 29, 245, 76, 77, 78, 32, 0, 74, 100, 101, 102, 29, 29, 100, 101, 171, 80, 0, 0, 0, 50, 155, 156, 157, 29, 173, 29, 228, 229, 56, 0, 0, 0, 0, 58, 59, 63, 64, 65, 61, 183, 184, 185, 61, 63, 64, 65, 61, 63, 64, 65, 67, 68, 0, 0, 0, 0, 50, 155, 156, 157, 80, 0, 0, 0, 0, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 0, 0, 0, 50, 155, 156, 157, 80, 0, 0, 0, 0, 50, 29, 167, 29, 56, 0, 0, 0, 0, 50, 29, 167, 29, 56, 0, 0, 0, 50, 100, 101, 102, 29, 269, 100, 101, 102, 56, 271, 273, 273, 273, 273, 273, 272, 272, 272, 272, 272, 274, 0, 0, 74, 179, 180, 181, 29, 173, 29, 252, 253, 80, 0, 0, 0, 0, 82, 83, 87, 88, 89, 85, 207, 208, 209, 85, 87, 88, 89, 61, 87, 88, 89, 91, 92, 0, 0, 0, 0, 50, 179, 180, 181, 56, 0, 0, 0, 0, 0, 34, 35, 159, 160, 161, 37, 159, 160, 161, 37, 279, 280, 281, 37, 39, 40, 41, 43, 44, 0, 0, 0, 0, 50, 179, 180, 181, 56, 0, 0, 0, 0, 74, 29, 191, 29, 56, 0, 0, 0, 0, 74, 29, 191, 29, 56, 0, 0, 0, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272 } }, { type = "objectgroup", id = 3, name = "Object Layer", visible = true, opacity = 1, offsetx = 0, offsety = 0, draworder = "topdown", properties = {}, objects = { { id = 12, name = "", type = "", shape = "rectangle", x = 294.667, y = 382.333, width = 16, height = 16, rotation = 0, gid = 5, visible = true, properties = {} }, { id = 13, name = "", type = "", shape = "rectangle", x = 240.333, y = 300, width = 16, height = 16, rotation = 0, gid = 6, visible = true, properties = {} }, { id = 14, name = "", type = "", shape = "rectangle", x = 19.6667, y = 142.667, width = 16, height = 16, rotation = 0, gid = 7, visible = true, properties = {} }, { id = 17, name = "", type = "", shape = "rectangle", x = 166, y = 415.667, width = 16, height = 16, rotation = 0, gid = 8, visible = true, properties = {} }, { id = 19, name = "", type = "", shape = "rectangle", x = 161, y = 247.333, width = 16, height = 16, rotation = 0, gid = 9, visible = true, properties = {} }, { id = 21, name = "", type = "", shape = "rectangle", x = 32.6667, y = 417.667, width = 16, height = 16, rotation = 0, gid = 11, visible = true, properties = {} }, { id = 22, name = "", type = "", shape = "rectangle", x = 30.3333, y = 285, width = 16, height = 16, rotation = 0, gid = 11, visible = true, properties = {} }, { id = 23, name = "", type = "", shape = "rectangle", x = 248.333, y = 425, width = 16, height = 16, rotation = 0, gid = 10, visible = true, properties = {} }, { id = 29, name = "", type = "", shape = "rectangle", x = 737.333, y = 299.333, width = 16, height = 16, rotation = 0, gid = 6, visible = true, properties = {} }, { id = 30, name = "", type = "", shape = "rectangle", x = 442, y = 44.6667, width = 16, height = 16, rotation = 0, gid = 5, visible = true, properties = {} }, { id = 31, name = "", type = "", shape = "rectangle", x = 811.333, y = 203.333, width = 16, height = 16, rotation = 0, gid = 9, visible = true, properties = {} }, { id = 32, name = "", type = "", shape = "rectangle", x = 730, y = 174, width = 16, height = 16, rotation = 0, gid = 10, visible = true, properties = {} }, { id = 33, name = "", type = "", shape = "rectangle", x = 1264, y = 313.333, width = 16, height = 16, rotation = 0, gid = 5, visible = true, properties = {} }, { id = 34, name = "", type = "", shape = "rectangle", x = 1480.67, y = 291.333, width = 16, height = 16, rotation = 0, gid = 5, visible = true, properties = {} }, { id = 35, name = "", type = "", shape = "rectangle", x = 1062.67, y = 90.6667, width = 16, height = 16, rotation = 0, gid = 6, visible = true, properties = {} }, { id = 36, name = "", type = "", shape = "rectangle", x = 1646, y = 268, width = 16, height = 16, rotation = 0, gid = 10, visible = true, properties = {} }, { id = 37, name = "", type = "", shape = "rectangle", x = 1039.33, y = 264, width = 16, height = 16, rotation = 0, gid = 11, visible = true, properties = {} }, { id = 38, name = "", type = "", shape = "rectangle", x = 1370, y = 222.667, width = 16, height = 16, rotation = 0, gid = 11, visible = true, properties = {} }, { id = 39, name = "", type = "", shape = "rectangle", x = 1129.33, y = 264, width = 16, height = 16, rotation = 0, gid = 11, visible = true, properties = {} }, { id = 40, name = "", type = "", shape = "rectangle", x = 741.333, y = 390.667, width = 16, height = 16, rotation = 0, gid = 9, visible = true, properties = {} }, { id = 41, name = "", type = "", shape = "rectangle", x = 323.333, y = 298.667, width = 16, height = 16, rotation = 0, gid = 9, visible = true, properties = {} }, { id = 42, name = "", type = "", shape = "rectangle", x = 1798.67, y = 318, width = 16, height = 16, rotation = 0, gid = 11, visible = true, properties = {} }, { id = 43, name = "", type = "", shape = "rectangle", x = 1869.33, y = 104.667, width = 16, height = 16, rotation = 0, gid = 11, visible = true, properties = {} }, { id = 44, name = "", type = "", shape = "rectangle", x = 1908, y = 186.667, width = 16, height = 16, rotation = 0, gid = 9, visible = true, properties = {} } } } } } |
Changes to src/fahombo/mode-intro.fnl.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
(var counter 0)
(var time 0)
(local dev-mode? true)
;;(local play-game :play)
(local play-game :play-osms-part1)
{:draw (fn draw [message]
(love.graphics.print (: "This window should close in %0.2f seconds"
:format (- 3 time)) 32 16))
:update (fn update [dt set-mode]
(if (< counter 65535)
(set counter (+ counter 1))
(set counter 0))
(set time (+ time dt))
(when (or (> time 3) dev-mode?)
(set-mode play-game)))
:keypressed (fn keypressed [key set-mode]
(love.event.quit))}
|
| | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
(var counter 0)
(var time 0)
(local dev-mode? true)
(local play-game :play)
;;(local play-game :play-osms-part1)
{:draw (fn draw [message]
(love.graphics.print (: "This window should close in %0.2f seconds"
:format (- 3 time)) 32 16))
:update (fn update [dt set-mode]
(if (< counter 65535)
(set counter (+ counter 1))
(set counter 0))
(set time (+ time dt))
(when (or (> time 3) dev-mode?)
(set-mode play-game)))
:keypressed (fn keypressed [key set-mode]
(love.event.quit))}
|
Added src/fahombo/play.fnl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 |
;; This is a Fennel implementation of http://www.osmstudios.com/tutorials/love2d-platformer-tutorial-part-1-the-basics (local sti (require "lib.sti")) (local bump (require "lib.bump")) (local game-width 384) (local game-height 224) (local bg-1 (love.graphics.newImage "assets/warped_city/environment/bg-1.png")) (local bg-2 (love.graphics.newImage "assets/warped_city/environment/bg-2.png")) (local bg-3 (love.graphics.newImage "assets/warped_city/environment/bg-3.png")) (local player-img (love.graphics.newImage "assets/osmstudios_character_block.png")) (local player { :x 16 :y 16 ;; The first set of values are for our rudimentary physics system :xVelocity 0 ;; current velocity on x, y axes :yVelocity 0 :acc 50 ;; the acceleration of our player :maxSpeed 600 ;; the top speed :friction 20 ;; slow our player down - we could toggle this situationally to create icy or slick platforms :gravity 80 ;; we will accelerate towards the bottom ;; These are values applying specifically to jumping :isJumping false ;; are we in the process of jumping? :isGrounded false ;; are we on the ground? :hasReachedMax false ;; is this as high as we can go? :jumpAcc 500 ;; how fast do we accelerate towards the top :jumpMaxSpeed 9.5 ;; our speed limit while jumping ;; Here are some incidental storage areas :img player-img}) ;; store the sprite we'll be drawing (local map (sti "map.lua" ["bump"])) ;; TODO: add lint wrapper (local world (bump.newWorld 16)) (local ground-0 {}) (local ground-1 {}) (: map :bump_init world) (: world :add player player.x player.y (: player.img :getWidth) (: player.img :getHeight)) ;;(: world :add ground-0 20 360 640 16) ; blog version (: world :add ground-0 120 360 640 16) ; github version (: world :add ground-1 0 448 640 32) (set player.filter (fn [item other] (let [(x y w h) (: world :getRect other) (px py pw ph) (: world :getRect item) player-bottom (+ py ph) other-bottom (+ y h)] (if (<= player-bottom y) :slide)))) (fn update [dt set-mode] (let [goal-x (+ player.x player.xVelocity) goal-y (+ player.y player.yVelocity) (x y cols) (: world :move player goal-x goal-y player.filter)] (set player.x (lume.clamp x 5 1000)) (set player.y y) (each [i col (ipairs cols)] (if (> col.touch.y goal-y) (do (set player.hasReachedMax true) (set player.isGrounded false)) (< col.normal.y 0) (do (set player.hasReachedMax false) (set player.isGrounded true))))) ;; apply friction (let [df (- 1 (math.min 1 (* dt player.friction)))] (set player.xVelocity (* player.xVelocity df)) (set player.yVelocity (* player.yVelocity df))) ;; apply gravity (set player.yVelocity (+ player.yVelocity (* player.gravity dt))) ;; handle horizontal movement (if (and (love.keyboard.isDown "left" "a") (> player.xVelocity (- player.maxSpeed))) (set player.xVelocity (- player.xVelocity (* player.acc dt))) (and (love.keyboard.isDown "right" "d") (< player.xVelocity player.maxSpeed)) (set player.xVelocity (+ player.xVelocity (* player.acc dt)))) ;; jump up jump up and get down (if (love.keyboard.isDown "up" "w") (do (if (and (< (- player.yVelocity) player.jumpMaxSpeed) (not player.hasReachedMax)) (do ;; (log "{%s} Setting player velocity{%s} to {%s} using a={%s}" dt player.yVelocity (- player.yVelocity (* player.jumpAcc dt)) player.jumpAcc) (set player.yVelocity (- player.yVelocity (* player.jumpAcc dt)))) ;; (log "Approaching terminal velocity %s ----> %s" (math.abs player.yVelocity) player.jumpMaxSpeed) (> (math.abs player.yVelocity) player.jumpMaxSpeed) (set player.hasReachedMax true)) (set player.isGrounded false)))) (fn keypressed [key set-mode]) (fn draw [map world player] (let [w (love.graphics.getWidth) h (love.graphics.getHeight) iw (: bg-1 :getWidth) ih (: bg-1 :getHeight) sw (/ w iw) sh (/ h ih)] (love.graphics.draw bg-1 0 0 0 sw sh) (love.graphics.draw bg-2 0 0 0 sw sh) (love.graphics.draw bg-3 0 0 0 sw sh)) (: map :draw) (love.graphics.draw player.img player.x player.y) (let [(x0 y0 w0 h0) (: world :getRect ground-0) (x1 y1 w1 h1) (: world :getRect ground-1)] (love.graphics.rectangle "fill" x0 y0 w0 h0) (love.graphics.rectangle "fill" x1 y1 w1 h1))) {:draw (partial draw map world player) :update update :keypressed keypressed} |