Compare commits

...

194 Commits

Author SHA1 Message Date
Florian Rival
e79a328748 Bump newIDE version 2018-02-25 23:24:20 +01:00
Florian Rival
2083ee1029 Update hosted GDJS root for previews in browser with S3 in newIDE 2018-02-25 23:24:10 +01:00
Florian Rival
3e982cdd87 Add link to roadmap in newIDE readme 2018-02-25 22:58:06 +01:00
Florian Rival
883527b289 Fix tests 2018-02-25 22:38:46 +01:00
Florian Rival
a4d84efdd5 Add support for editing properties of resources in ResourcePropertiesEditor in newIDE 2018-02-25 22:35:17 +01:00
Florian Rival
e46c8493bc Refactor Resource to use gd::PropertyDescriptor for custom properties 2018-02-25 22:17:04 +01:00
Florian Rival
4c443b09cf Update zombie-laser example for newIDE 2018-02-25 18:57:14 +01:00
Florian Rival
98bc2236f4 Merge pull request #445 from Lizard-13/raycast-1
Add Raycast condition
2018-02-25 18:08:43 +01:00
Florian Rival
5199299639 Add analytics when a user choose a new subscription plan 2018-02-25 17:45:49 +01:00
Florian Rival
3268d1db25 Merge pull request #451 from 4ian/feature/profile-in-context
Preview over wifi, GDevelop splash and minor improvements
2018-02-25 17:36:34 +01:00
Florian Rival
741770924b Remove useless package & update subscription descriptions 2018-02-25 17:34:55 +01:00
Florian Rival
49aa9469bb Add SubscriptionChecker when trying to deactivate GDevelop splash in ProjectPropertiesDialog 2018-02-25 17:19:24 +01:00
Florian Rival
7cbe34436c Improve design of SubscriptionDialog and SubscriptionCheckDialog 2018-02-25 16:40:48 +01:00
Lizard-13
122f7ecf3e Fix date functions (#450) 2018-02-25 14:13:23 +01:00
Florian Rival
d79bdd9554 Add SubscriptionChecker to ask users to get a subscription if needed 2018-02-24 20:34:59 +01:00
Lizard-13
3e331cb2e8 Fix event description string (#448) 2018-02-24 19:02:15 +01:00
Florian Rival
361fb6aeab Move UserProfile into a single object provided by a Provider (using react-create-context)
Can be updated later to use the new React Context API once it's ready
SubscriptionCheckDialog is still a Work-In-Progress.
2018-02-24 16:23:45 +01:00
Florian Rival
b4a76895ee [WIP] Display dialog asking for a subscription when starting network preview
TODO: Refactor to store user profile in a context/store to avoid de-synchronisation
between components using UserProfileContainer.
2018-02-24 14:31:08 +01:00
Florian Rival
b2251e1a12 Fix external layout previews for web-app 2018-02-23 15:55:19 +01:00
Florian Rival
1c1860370a Prevent pinch-to-zoom on exported games/preview and set black address bar 2018-02-23 15:24:35 +01:00
Florian Rival
1a190b2a44 Add Network Preview (Preview over wifi) to newIDE with live reload 2018-02-23 12:41:18 +01:00
Florian Rival
b1e0f72416 Add local server in Electron app (to serve previews over wifi) 2018-02-20 08:31:13 +01:00
Florian Rival
2c4ae7573e Add LoadingScreen in project properties to allow to show/hide splash at startup 2018-02-18 23:02:26 +01:00
Florian Rival
04ff1f2726 Add GDevelop Splashscreen at game startup 2018-02-18 21:55:42 +01:00
Florian Rival
eaa5200f95 Fix warning 2018-02-18 17:00:05 +01:00
Florian Rival
53c749b79e Update some links in newIDE to the new GDevelop website (gdevelop-app.com) 2018-02-18 16:30:39 +01:00
Lizard-13
eb96ee8497 Fix @static hint 2018-02-17 17:56:07 -03:00
Lizard-13
458444ee7b Implement collinear case 2018-02-17 16:02:13 -03:00
Lizard-13
c8eb13f18f Minor fixes
Removed circle code, unused includes and debug lines.
Improved extension strings.
Added reference link.
Updated "Laser and zombies.gdg" example
2018-02-17 16:01:11 -03:00
Lizard-13
a224b93edc Remove circle from test game 2018-02-17 16:01:00 -03:00
Lizard-13
f077ca6723 Commented out circle raycasting and added icons 2018-02-17 16:00:52 -03:00
Lizard-13
6bbfa1d4a1 Implement C++ version
And little fixes on the JS version
2018-02-17 16:00:32 -03:00
Lizard-13
3c3dc6ef6e Implement raycast JS version and test game 2018-02-17 16:00:18 -03:00
Lizard-13
5c101dbcda Engine condition set up
Neither tested nor compiled yet
2018-02-17 15:56:50 -03:00
Florian Rival
701b78361a Add support for disabled events in EventsSheet in newIDE 2018-02-17 16:34:42 +01:00
Florian Rival
07f26027f6 Bump newIDE version 2018-02-15 22:56:13 +01:00
Florian Rival
09cf13d6e2 Add confirm before close dialog to newIDE 2018-02-15 22:50:08 +01:00
Florian Rival
42f91565fa Merge pull request #443 from 4ian/feature/cordova-icons
Add support for icons when exporting to Android/iOS
2018-02-13 19:51:04 +01:00
Florian Rival
ac6c146808 Fix ImageThumbnail error when onContextMenu is not specified 2018-02-13 19:50:21 +01:00
Florian Rival
59ad23f8ac Allow to customize game orientation (for when exported with Cordova) 2018-02-11 23:44:00 +01:00
Florian Rival
769c6fe3d5 Move ResourcesLoader in its own folder + refactor methods 2018-02-11 23:17:44 +01:00
Florian Rival
07b92911ab Add message on web-app about non support of automatic icons creation 2018-02-11 22:03:30 +01:00
Florian Rival
eb57bcfc87 Add iOS icons support for Cordova + fix image caching 2018-02-11 21:52:40 +01:00
Florian Rival
7addeba73a Add support for Android icons in Cordova export 2018-02-11 21:14:18 +01:00
Florian Rival
263902b45a Avoid caching in ImagePreview and ImageThumbnail 2018-02-11 18:14:47 +01:00
Florian Rival
d283f759fe Add PlatformSpecificAssets to Project 2018-02-10 18:36:02 +01:00
Florian Rival
fabd028a63 Update VSCode C++ properties for Intellisense 2018-02-10 18:35:05 +01:00
Florian Rival
2b18272c41 Merge branch 'master' of github.com:4ian/GD 2018-02-07 00:02:25 +01:00
Florian Rival
a1fb39da3d Fix scene unloading re-creating a RuntimeSceneRenderer leading to issues with Cocos2d-JS renderer 2018-02-05 23:12:51 +01:00
Florian Rival
09602fdf9e Merge pull request #441 from ronnystandtke/patch-1
Update gdevelop.desktop
2018-02-04 17:03:22 +01:00
ronnystandtke
d574ef17ba Update gdevelop.desktop
added German L10n
2018-02-04 17:00:34 +01:00
Florian Rival
0e3f70627b Bump newIDE version 2018-02-03 19:32:52 +01:00
Florian Rival
a814a07105 Fix ResourcesEditor selection 2018-02-03 19:24:47 +01:00
Florian Rival
c49af90a9c Add program opening count to Keen.io analytics 2018-02-03 19:09:33 +01:00
Florian Rival
24afa155c8 Improve Keen.io analytics events by adding user profile information 2018-02-03 18:30:09 +01:00
Florian Rival
9e5a431516 Only run Fullstory on newIDE web-app 2018-02-03 17:53:57 +01:00
Florian Rival
182a94285c Unregister service worker (it is not ready yet) 2018-02-03 13:05:22 +01:00
Florian Rival
442c2c8dd9 Merge pull request #439 from 4ian/feature/resources-editor
Resources editor for newIDE
2018-02-03 12:57:22 +01:00
Florian Rival
f8fd0dd353 Add a preview in ResourcesEditor 2018-02-03 12:55:30 +01:00
Florian Rival
faad9e23ac Add ResourcesEditor with ResourcePropertiesEditor and Toolbar 2018-01-30 23:12:31 +01:00
Florian Rival
d2af0da1b1 Added tools method to ResourcesManager and finish working version of ResourcesList 2018-01-30 21:56:40 +01:00
Florian Rival
c65e5c3e49 [WIP] Add ResourcesEditor based on a generic SortableVirtualizedItemList
TODO:
* Use SortableVirtualizedItemList for ObjectsList and ObjectsGroupsList
* Add missing features (sorting, delete, thumbnail for images, properties edition) to ResourcesEditor
2018-01-30 00:58:21 +01:00
Florian Rival
24a8dfc5f0 Add SemiControlledTextField to be able to type freely in PropertiesEditor 2018-01-28 18:45:44 +01:00
Florian Rival
9c6790ac37 Update default gravity in PhysicsBehavior 2018-01-27 23:50:49 +01:00
Florian Rival
18ef7460ba Bump newIDE version 2018-01-27 19:34:36 +01:00
Florian Rival
63cd0e76c3 Fix warning 2018-01-27 19:34:27 +01:00
Florian Rival
bdbf7fd9fc Add support for editing BehaviorSharedData in newIDE
TODO:
* Support for cancelling modifications made on it in ScenePropertiesDialog
2018-01-27 19:13:27 +01:00
Florian Rival
6bbedbd8f9 Fix BehaviorSharedData not created by newIDE + fix warnings 2018-01-27 17:00:44 +01:00
Florian Rival
648bd1ff2e Show warning if game name or package name is empty when exporting in newIDE 2018-01-24 23:31:02 +01:00
Florian Rival
d4288caedb Fix .env file loading with electron-app and bump newIDE version 2018-01-23 00:15:13 +01:00
Florian Rival
0a35bc3272 Bump newIDE version 2018-01-22 23:35:55 +01:00
Florian Rival
d8b737a31f Fix LocalS3Export always reusing the same folder leading to useless files in exported game 2018-01-22 23:35:32 +01:00
Florian Rival
cfd2655f6c Bump newIDE version 2018-01-22 23:29:21 +01:00
Florian Rival
1896241b9d Move AWS S3 credentials to an .env file for games deployment on GDevelop hosting 2018-01-22 23:25:42 +01:00
Florian Rival
0ed22a6ee1 Fix upload to GDevelop hosting of exported games with large files 2018-01-22 22:52:44 +01:00
Florian Rival
2bfcb99c3e Add analytics when a signup is done 2018-01-22 00:20:32 +01:00
Florian Rival
815f8a520a Bump newIDE version 2018-01-21 22:11:59 +01:00
Florian Rival
f115b6607f Add PhysicsBehavior support to newIDE, with an example 2018-01-21 22:11:24 +01:00
Florian Rival
c876f67502 Add pathfinding example to newIDE web-app 2018-01-20 21:25:25 +01:00
Florian Rival
27674f272c Bump newIDE version 2018-01-20 19:21:13 +01:00
Florian Rival
02879507e3 Fix tests (outdated snapshots after adding Pathfinding to newIDE) 2018-01-20 19:19:38 +01:00
Florian Rival
0a7629878f Fix Sepia layer effect (broken since Pixi v4 update) 2018-01-20 19:00:22 +01:00
Florian Rival
b0368232d0 Add Parallax example to newIDE 2018-01-20 17:19:45 +01:00
Florian Rival
a32bf3db98 Add Pathfinding and Zombie Laser examples to newIDE 2018-01-20 17:02:47 +01:00
Florian Rival
64cbbb20d3 Expose PathfindingBehavior when building with Emscripten 2018-01-20 16:53:12 +01:00
Florian Rival
dd4fbecc98 Update some GDevelop services API to use api.gdevelop-app.com 2018-01-20 16:28:27 +01:00
Florian Rival
807a75a265 Update productName for newIDE 2018-01-19 00:24:07 +01:00
Florian Rival
6e1b44ea56 Bump newIDE version 2018-01-18 23:31:41 +01:00
Florian Rival
d870a54f58 Fix error when handling download-progress of an update 2018-01-18 23:31:00 +01:00
Florian Rival
9f464a3f23 Bump newIDE version 2018-01-18 23:12:37 +01:00
Florian Rival
ed4e84d665 Add Export icon in newIDE main toolbar & fix profile refreshing after getting a new subscription 2018-01-18 23:12:08 +01:00
Florian Rival
1e4ab96233 Bump newIDE version 2018-01-18 00:04:27 +01:00
Florian Rival
380c034ff5 Merge pull request #433 from 4ian/feature/online-cordova-export
Packaging for Android with GDevelop online build service + various improvements
2018-01-18 00:02:51 +01:00
Florian Rival
7c9abe432d Fix AboutDialog story in storybook and use retro default avatars 2018-01-18 00:02:05 +01:00
Florian Rival
2ca853c22c Add HelpButton in ProfileDialog and disabled icon field in ProjectPropertiesDialog 2018-01-17 23:55:40 +01:00
Florian Rival
b23d55612a Add display of user Gravatar in ProfileDetails 2018-01-17 22:36:51 +01:00
Florian Rival
b261faacfc Freeze GDCore/libGD.js and newIDE version to 4.0.96 (don't read it from Git tags) 2018-01-17 00:21:07 +01:00
Florian Rival
9984b32876 Add link to help page specific to each exporters 2018-01-16 23:42:46 +01:00
Florian Rival
d63ba75430 Change wording in CreateProfile 2018-01-16 23:33:44 +01:00
Florian Rival
2db903ed94 Fix profile refreshing after login/account creation 2018-01-16 22:00:45 +01:00
Florian Rival
3f9bc4d335 Fix upload and Android export for large files 2018-01-16 21:25:36 +01:00
Florian Rival
3df95d0e21 Switch authentification to use Firebase 2018-01-14 17:59:09 +01:00
Florian Rival
f445695f6a Add auto-update support to GDevelop 5 2018-01-13 17:17:48 +01:00
Florian Rival
6f3163d7bd Rework ExportDialog to have a list of exporters to choose from 2018-01-13 14:54:10 +01:00
Florian Rival
5421eae23d Add buttons to switch between exporters of the same kind 2018-01-11 00:04:31 +01:00
Florian Rival
a0e82ee22f Add button to download logs in LocalOnlineCordovaExport 2018-01-10 23:25:18 +01:00
Florian Rival
1fbf822769 Move GDevelop hosting API configuration to GDevelopServices/ApiConfigs.js 2018-01-09 23:52:44 +01:00
Florian Rival
6b0f037722 Add a comment about working with Auth0 during development 2018-01-09 23:52:44 +01:00
Florian Rival
ae231d2fe6 Update packageName of fixtures/example games 2018-01-09 23:52:44 +01:00
Florian Rival
2e95899da7 Ensure user is asked for authenticating again if needed 2018-01-09 23:52:44 +01:00
Florian Rival
3f45b38dfc [WIP] Make SubscriptionDialog working with GDevelop Services and Stripe
TODO: Properly handle the refresh of ProfileDialog
2018-01-09 23:52:44 +01:00
Florian Rival
daf4d36348 [WIP] Add SubscriptionDialog 2018-01-09 23:52:44 +01:00
Florian Rival
477cd16f23 Add storybook stories for Profile components 2018-01-09 23:52:44 +01:00
Florian Rival
83eded0056 [WIP] Improve LocalOnlineCordovaExport progress handling 2018-01-09 23:52:44 +01:00
Florian Rival
338de9c149 [WIP] Add LimitDisplayer and display subscriptions limits in LocalOnlineCordovaExport 2018-01-09 23:52:44 +01:00
Florian Rival
6d99d4e661 [WIP] Add happy path for LocalOnlineCordovaExport 2018-01-09 23:52:44 +01:00
Florian Rival
4e5a8060c8 [WIP] Add Archiver to create zip files for LocalOnlineCordovaExport 2018-01-09 23:52:44 +01:00
Florian Rival
eb938e39ff [WIP] Add LocalOnlineCordovaExport (with no real calls to the build service for now) 2018-01-09 23:52:44 +01:00
Florian Rival
cff8604a5f Fix flow error/incompatibility in auth0-lock's node_modules 2018-01-09 23:52:44 +01:00
Florian Rival
2afa54bcd2 [WIP] Add SubscriptionDetails, ProfileDetails and UsagesDetails in ProfileDialog 2018-01-09 23:52:44 +01:00
Florian Rival
4da6025b6f Move configuration of BrowserS3PreviewLauncher in ApiConfigs 2018-01-09 23:52:44 +01:00
Florian Rival
c4f64444e7 [WIP] Add a Profile in newIDE with login/logout based on Auth0 2018-01-09 23:52:44 +01:00
Florian Rival
b0205b296f Merge pull request #432 from 4ian/fix/various
Various improvements for GDJS (memory + libs update)
2018-01-09 23:48:15 +01:00
Florian Rival
e0c8b3cc81 Add comment about RuntimScene.unloadScene and memory management 2018-01-09 23:47:47 +01:00
Florian Rival
80ca92336e Fix filters and refactor Text style update for Pixi v4 2018-01-09 23:03:26 +01:00
Florian Rival
6c0681e4ca Merge branch 'mem' of https://github.com/dos1/GD into dos1-mem 2018-01-07 20:06:18 +01:00
Sebastian Krzyszkowiak
26e8503dc8 GDJS: HowlerSoundManager: use XMLHttpRequest to preload
Howler decodes the whole file, which causes massive memory spike
on load when the project contains lots of longer music files.
We could use HTML5 audio to avoid decoding, but then the load event
actually means "preloaded enough to start playing without buffering".

We don't need to decode here, putting the file into browser cache
should be enough, so let's just download the file with XHR.
2018-01-06 02:09:01 +01:00
Sebastian Krzyszkowiak
c1ce78efde GDJS: howler-sound-manager: use .unload() method when destroying to free the resources used by sounds 2018-01-06 02:08:54 +01:00
Sebastian Krzyszkowiak
2f52c2f062 GDJS: store global volume value in HowlerSoundManager to avoid rounding errors (#430) 2018-01-05 16:59:16 +01:00
Sebastian Krzyszkowiak
24d11a2446 GDJS: update howler.js to 2.0.7 2018-01-04 23:44:57 +01:00
Sebastian Krzyszkowiak
e1d4ae5bbd GDJS: update Pixi to 4.6.2 2018-01-04 23:44:32 +01:00
Sebastian Krzyszkowiak
dcfe346f54 GDJS: RuntimeScene: clean up more variables on unload, so they can be garbage collected 2018-01-04 23:44:13 +01:00
Florian Rival
3906db9efe Make UserUUID generation security/exception errors-proof 2017-12-26 16:47:00 +01:00
Florian Rival
ba5244d95d Bump newIDE version 2017-12-26 16:46:32 +01:00
Florian Rival
52db730870 Add ErrorBounday for handling editor crash and EmptyEventsPlaceholder for empty events sheets 2017-12-26 14:47:46 +01:00
Florian Rival
82d2278ebd Bump newIDE version 2017-12-25 23:55:48 +01:00
Florian Rival
30d08ac72d Add button linking to help about creating new themes in newIDE 2017-12-25 17:48:38 +01:00
Florian Rival
6f1e71c8e5 Update README about creating themes for newIDE 2017-12-25 17:41:00 +01:00
Florian Rival
385be9b5f5 Make EventsSheet color scheme customizable and add Monokai inspired dark color scheme 2017-12-25 17:33:25 +01:00
Florian Rival
25cb041d78 Improve DarkTheme to fix Raised buttons readability 2017-12-25 14:58:36 +01:00
Florian Rival
18fa9cd659 Merge pull request #429 from 4ian/feature/upgrade-mui-react
Upgrade to React 16 and Material-UI 0.20
2017-12-24 17:33:58 +01:00
Florian Rival
ce760541c5 Upgrade to React 16.2 2017-12-24 16:51:04 +01:00
Florian Rival
db51b652f0 Remove useless refs created warnings with React 16 2017-12-24 15:05:46 +01:00
Florian Rival
4222d98aa9 Update instructions parameters color scheme 2017-12-24 15:05:20 +01:00
Florian Rival
484f1e5dcb Fix typing 2017-12-24 14:30:43 +01:00
Florian Rival
7304b94a77 Fix warnings/React issues with refs in EventsSheet 2017-12-24 14:07:20 +01:00
Florian Rival
ee5ec7df72 Fix InstancePropertiesEditor not refreshed when an instance is deleted/moved 2017-12-24 12:49:20 +01:00
Florian Rival
9a1e4bdf7c Update react-i18next dependency of newIDE 2017-12-24 12:40:26 +01:00
Florian Rival
a43cca7629 Update react-dnd dependency of newIDE 2017-12-24 12:31:08 +01:00
Florian Rival
0cdabab2ec Update react-color dependency of newIDE 2017-12-24 12:24:49 +01:00
Florian Rival
28b968ea99 Update newIDE to React 15.6.2 2017-12-24 12:21:32 +01:00
Florian Rival
5160033092 Upgrade storybook and remove useless newIDE dependencies 2017-12-24 12:00:41 +01:00
Florian Rival
ce086c07b9 Upgrade material-ui to v0.20 and upgrade other dependencies 2017-12-24 11:49:40 +01:00
Florian Rival
bf9348488d Merge pull request #428 from 4ian/feature/themable-newIDE
Add a Dark theme to newIDE
2017-12-23 23:18:38 +01:00
Florian Rival
70b3e0701b Fix StartPage tests 2017-12-23 23:14:44 +01:00
Florian Rival
dc3d890937 Add comment explaining how to create a new theme 2017-12-23 23:14:02 +01:00
Florian Rival
f68be32e2d Update logo in newIDE StartPage and tweak colors 2017-12-23 23:11:10 +01:00
Florian Rival
3758e7af03 Fix editors not opening in SceneEditor in newIDE 2017-12-23 22:40:50 +01:00
Florian Rival
5ab1858349 [WIP] Refactor EventsSheet to make it partially themable 2017-12-23 21:50:12 +01:00
Florian Rival
54353bcb24 [WIP] Add PreferencesDialog and make the whole newIDE interface themable 2017-12-23 21:06:55 +01:00
Florian Rival
de7640558d Fix Clock Skew related errors while uploading to S3 from certain computers 2017-12-23 13:52:33 +01:00
Florian Rival
2e17b16516 Make newIDE context menus dynamic (greyed-out items if not applicable, checkbox for grid) 2017-12-23 13:51:36 +01:00
Sebastian Krzyszkowiak
345f9f1786 Run CopyRuntimeToGD.sh with bash explicitly (#427)
The script contains bashisms which fail on systems where sh is
symlinked to dash instead of bash.
2017-12-22 11:12:02 +01:00
Florian Rival
8c9214ce5e Bump newIDE version 2017-12-20 22:44:49 +01:00
Florian Rival
fc9cc8046d Merge pull request #426 from 4ian/feature/newide-js-code-event
Add support for Javascript Code Event in newIDE
2017-12-20 22:33:12 +01:00
Florian Rival
e592bb855d Add support for objects parameter in JsCodeEvent in newIDE 2017-12-20 22:30:53 +01:00
Florian Rival
f8407264da Add basic support for JsCodeEvent in newIDE 2017-12-19 21:16:27 +01:00
Florian Rival
202fe2b69a Add FpsLimiter to limit framerate on InstancesEditor of newIDE, to avoid killing CPU/battery 2017-12-18 00:05:31 +01:00
Florian Rival
d14a93f9d0 Remove ok button in MainFrame Snackbar 2017-12-17 19:37:13 +01:00
Florian Rival
1d1ccdbf06 Fix unmounting and related focus issue of editors in newIDE 2017-12-17 16:16:29 +01:00
Florian Rival
92fd647316 Add button to open external events or layout events from a LinkEvent in newIDE 2017-12-16 18:09:30 +01:00
Florian Rival
d8ca506200 Add flow typing to MainFrame 2017-12-16 17:18:09 +01:00
Florian Rival
928d6eda98 Update VSCode settings 2017-12-16 16:53:53 +01:00
Florian Rival
d5e6755694 Move all providers from MainFrame to a dedicated component 2017-12-16 16:53:37 +01:00
Florian Rival
a1431126ec Merge pull request #424 from 4ian/feature/clipboard-project-manager
Clipboard support for ProjectManager in newIDE
2017-12-16 16:17:14 +01:00
Florian Rival
13c8caeb8c Increase flow coverage 2017-12-16 16:12:10 +01:00
Florian Rival
b2b5ee0e19 Add a TODO about style refactoring 2017-12-16 14:28:32 +01:00
Florian Rival
ff74ecd7c9 Run prettier on newIDE codebase 2017-12-16 14:26:05 +01:00
Florian Rival
0ac3e79156 Fix flow typing in newIDE and update flow to latest version 2017-12-16 14:24:25 +01:00
Florian Rival
3a69936e2e Add copy/cut/paste support for External Layouts and Events in newIDE 2017-12-16 14:02:40 +01:00
Florian Rival
e738d5dd5f Add copy/cut/paste support for Layout in newIDE 2017-12-16 00:14:18 +01:00
Florian Rival
ed8ee21c04 Reduce GroupEvent height 2017-12-15 23:22:47 +01:00
Florian Rival
87220a941a Bump newIDE version 2017-12-15 23:19:23 +01:00
Florian Rival
4425d13c7a Rename objectWithScope to objectWithContext 2017-12-13 00:19:31 +01:00
Florian Rival
b818e5f493 Add support for copy/cut/paste objects 2017-12-12 23:57:37 +01:00
Lizard-13
403563ba32 Support keyboard top row numbers in HTML5 games (#422) 2017-12-11 14:29:14 +01:00
Florian Rival
156ca68116 Make newIDE save project as formatted JSON 2017-12-10 23:03:16 +01:00
Florian Rival
de3677a6c3 Add AnimationPreview in SpriteEditor 2017-12-10 23:02:51 +01:00
Florian Rival
3b76dfe9f4 Fix LocalCordovaExport storybook and increase expression selector height 2017-12-09 20:08:23 +01:00
Florian Rival
6e38ee6d16 Move newIDE test files next to the test source files (no __tests__ folder) 2017-12-09 18:05:59 +01:00
Florian Rival
454657b00f Add link to Tank Shooter beginner tutorial in newIDE 2017-12-09 17:47:54 +01:00
Florian Rival
aad0c4e909 Fix newIDE yarn.lock 2017-12-09 17:27:53 +01:00
Florian Rival
d106ee9ac1 Merge pull request #421 from 4ian/feature/newide-expressions-autocomplete
Expression field with list of available functions for newIDE
2017-12-09 17:16:41 +01:00
Lizard-13
495900c083 Add point inside object condition (#418)
* Add point inside object condition

* Update names and comments
2017-12-04 09:25:56 +01:00
395 changed files with 34303 additions and 7014 deletions

View File

@@ -10,28 +10,31 @@
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"${workspaceRoot}/ExtLibs/SFML/include",
"/usr/local/lib/wx/include/osx_cocoa-unicode-3.0",
"/usr/local/include/wx-3.0",
"/usr/include/machine",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1",
"/usr/local/include",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/8.0.0/include",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
"/usr/include"
"/usr/include",
"/usr/local/lib/wx/include/osx_cocoa-unicode-3.0",
"/usr/local/include/wx-3.0",
"${workspaceRoot}"
],
"defines": [
"GD_IDE_ONLY",
"__WXMAC__",
"__WXOSX__",
"__WXOSX_COCOA__",
"GD_CORE_API=\" \"",
"GD_CORE_API=\/* Macro used to export classes on Windows, please ignore *\/",
"GD_API=\/* Macro used to export classes on Windows, please ignore *\/",
"GD_EXTENSION_API=\/* Macro used to export classes on Windows, please ignore *\/",
"WXUSINGDLL"
],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1",
"/usr/local/include",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/8.0.0/include",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
"/usr/include",
"${workspaceRoot}"
@@ -39,7 +42,6 @@
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"intelliSenseMode": "clang-x64",
"macFrameworkPath": [
"/System/Library/Frameworks",
"/Library/Frameworks"
@@ -49,10 +51,27 @@
"name": "Linux",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/IDE",
"${workspaceRoot}/GDCpp",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"${workspaceRoot}/ExtLibs/SFML/include",
"/usr/include",
"/usr/local/include"
"/usr/local/include",
"${workspaceRoot}"
],
"defines": [],
"defines": [
"GD_IDE_ONLY",
"__WXMAC__",
"__WXOSX__",
"__WXOSX_COCOA__",
"GD_CORE_API=\/* Macro used to export classes on Windows, please ignore *\/",
"GD_API=\/* Macro used to export classes on Windows, please ignore *\/",
"GD_EXTENSION_API=\/* Macro used to export classes on Windows, please ignore *\/",
"WXUSINGDLL"
],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/usr/include",
@@ -61,19 +80,34 @@
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"intelliSenseMode": "clang-x64"
}
},
{
"name": "Win32",
"includePath": [
"${workspaceRoot}",
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include"
"${workspaceRoot}/IDE",
"${workspaceRoot}/GDCpp",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"${workspaceRoot}/ExtLibs/SFML/include",
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include",
"${workspaceRoot}"
],
"defines": [
"_DEBUG",
"UNICODE"
"UNICODE",
"GD_IDE_ONLY",
"__WXMAC__",
"__WXOSX__",
"__WXOSX_COCOA__",
"GD_CORE_API=\/* Macro used to export classes on Windows, please ignore *\/",
"GD_API=\/* Macro used to export classes on Windows, please ignore *\/",
"GD_EXTENSION_API=\/* Macro used to export classes on Windows, please ignore *\/",
"WXUSINGDLL"
],
"intelliSenseMode": "msvc-x64",
"browse": {
"path": [
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*",
@@ -81,9 +115,8 @@
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"intelliSenseMode": "msvc-x64"
}
}
],
"version": 3
}
}

11
.vscode/settings.json vendored
View File

@@ -62,7 +62,16 @@
"__tuple": "cpp",
"hash_map": "cpp",
"hash_set": "cpp",
"system_error": "cpp"
"system_error": "cpp",
"__nullptr": "cpp",
"__functional_base": "cpp",
"__functional_base_03": "cpp",
"chrono": "cpp",
"ratio": "cpp",
"atomic": "cpp",
"locale": "cpp",
"string_view": "cpp",
"__string": "cpp"
},
"files.exclude": {
"Binaries/*build*": true,

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -2,7 +2,9 @@
Version=1.0
Name=GDevelop
GenericName=Game creator IDE
GenericName[de]=Entwicklungsumgebung für Spiele
Comment=HTML5 and native game development software
Comment[de]=Entwicklungsumgebung für native und HTML5-Spiele
Exec=sh -c "gdevelop %F"
MimeType=application/x-gdevelop-project;
Icon=GDevelop

View File

@@ -337,7 +337,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(gd::Plat
extension.AddCondition("GlobalVolume",
_("Global volume"),
_("Test the global sound level. The volume is between 0 and 100."),
_("The global game volume is _PARAM2_ to _PARAM1_"),
_("The global game volume is _PARAM1__PARAM2_"),
_("Audio"),
"res/conditions/volume24.png",
"res/conditions/volume.png")

View File

@@ -621,6 +621,18 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(gd:
.AddParameter("objectList", _("Objects"))
.MarkAsSimple();
obj.AddCondition("CollisionPoint",
_("Point inside object"),
_("Test if a point is inside the object collision masks."),
_("_PARAM1_;_PARAM2_ is inside _PARAM0_"),
_("Collision"),
"res/conditions/collisionPoint24.png",
"res/conditions/collisionPoint.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("X position of the point"))
.AddParameter("expression", _("Y position of the point"))
.MarkAsSimple();
obj.AddExpression("X", _("X position"), _("X position of the object"), _("Position"), "res/actions/position.png")
.AddParameter("object", _("Object"));
@@ -848,6 +860,23 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(gd:
.AddCodeOnlyParameter("conditionInverted", "")
.MarkAsAdvanced();
extension.AddCondition("Raycast",
_("Raycast"),
_("Sends a ray from the given source position and angle, intersecting the closest object.\nThe instersected object will become the only one taken into account.\nIf the condition is inverted, the object to be intersected will be the farthest one within the ray radius."),
_("Raycast _PARAM0_ from _PARAM1_;_PARAM2_, and save the result in _PARAM5_, _PARAM6_"),
_("Collision"),
"res/conditions/raycast24.png",
"res/conditions/raycast.png")
.AddParameter("objectList", _("Objects to test against the ray"))
.AddParameter("expression", _("Ray source X position"))
.AddParameter("expression", _("Ray source Y position"))
.AddParameter("expression", _("Ray angle (in degrees)"))
.AddParameter("expression", _("Ray maximum distance (in pixels)"))
.AddParameter("scenevar", _("Variable where to store the X position of the intersection"))
.AddParameter("scenevar", _("Variable where to store the Y position of the intersection"))
.AddCodeOnlyParameter("conditionInverted", "")
.MarkAsAdvanced();
extension.AddExpression("Count", _("Number of objects"), _("Count the number of the specified objects currently picked"), _("Objects"), "res/conditions/nbObjet.png")
.AddParameter("objectList", _("Object"));
#endif

View File

@@ -52,6 +52,7 @@
#include "GDCore/Tools/Log.h"
#include "GDCore/IDE/Dialogs/DndResourcesEditor.h"
#include "GDCore/IDE/wxTools/TreeItemStringData.h"
#include "GDCore/IDE/Dialogs/PropertyDescriptor.h"
#ifdef __WXGTK__
#include <gtk/gtk.h>
@@ -635,7 +636,7 @@ void ResourcesEditor::OnresourcesTreeSelectionChanged( wxTreeEvent& event )
void ResourcesEditor::UpdatePropertyGrid()
{
std::vector<gd::String> commonProperties; ///< The name of the properties to be displayed
std::map<gd::String, gd::PropertyDescriptor> commonProperties; ///< The name of the properties to be displayed
bool aFolderIsSelected = false;
//First construct the list of common properties
@@ -646,18 +647,29 @@ void ResourcesEditor::UpdatePropertyGrid()
gd::TreeItemStringData * data = dynamic_cast<gd::TreeItemStringData*>(resourcesTree->GetItemData(selection[i]));
if ( data && data->GetString() == "Image")
{
std::vector<gd::String> properties = project.GetResourcesManager().GetResource(data->GetSecondString()).GetAllProperties(project);
const std::map<gd::String, gd::PropertyDescriptor> & properties =
project.GetResourcesManager().GetResource(data->GetSecondString()).GetProperties(project);
if ( i == 0 )
commonProperties = properties;
else
{
//Keep only properties that are common to all the selected resources
for (std::size_t j = 0;j<commonProperties.size();)
// TODO: This could be factored with helpers like ObjectsPropgridHelper
//Merge custom properties
for(std::map<gd::String, gd::PropertyDescriptor>::const_iterator it = properties.begin();
it != properties.end();++it)
{
if ( find(properties.begin(), properties.end(), commonProperties[j]) == properties.end() )
commonProperties.erase(commonProperties.begin()+j);
else
++j;
if ( commonProperties.find(it->first) == commonProperties.end() ) continue;
if ( commonProperties[it->first].GetValue() != it->second.GetValue() )
commonProperties[it->first].SetValue(_("(Multiples values)"));
}
//Also erase properties which are not in common.
for(std::map<gd::String, gd::PropertyDescriptor>::iterator it = commonProperties.begin();
it != commonProperties.end();)
{
if ( properties.find(it->first) == properties.end() )
commonProperties.erase(it++);
else ++it;
}
}
}
@@ -721,32 +733,11 @@ void ResourcesEditor::UpdatePropertyGrid()
//Other properties
if ( !commonProperties.empty() ) propertyGrid->Append( new wxPropertyCategory(_("Other properties")) );
for (std::size_t j = 0;j<commonProperties.size();++j)
for(auto & propertyIterator: commonProperties)
{
wxPGProperty * property = propertyGrid->Append( new wxStringProperty("", commonProperties[j], "") );
wxString commonValue;
for (std::size_t i = 0;i<selection.size();++i)
{
gd::TreeItemStringData * data = dynamic_cast<gd::TreeItemStringData*>(resourcesTree->GetItemData(selection[i]));
if ( data && data->GetString() == "Image")
{
//It is assumed that the description and the user friendly name
//are the same for all the properties with the same name.
gd::String propertyUserFriendlyName;
gd::String propertyDescription;
project.GetResourcesManager().GetResource(data->GetSecondString()).GetPropertyInformation(project, commonProperties[j], propertyUserFriendlyName, propertyDescription);
propertyGrid->SetPropertyLabel(property, propertyUserFriendlyName);
propertyGrid->SetPropertyHelpString(property, propertyDescription);
//Values can be different though
gd::String propertyValue = project.GetResourcesManager().GetResource(data->GetSecondString()).GetProperty(project, commonProperties[j]);
if ( i == 0 ) commonValue = propertyValue;
else if ( commonValue != propertyValue ) commonValue = _("(Multiple values)");
}
}
propertyGrid->SetPropertyValue(property, commonValue);
// TODO: For now, all other properties are assumed to be booleans.
auto & propertyName = propertyIterator.first;
propertyGrid->Append(new wxBoolProperty(propertyName, propertyName, propertyIterator.second.GetValue() == "true"));
}
}
}
@@ -782,7 +773,7 @@ void ResourcesEditor::OnPropertyChanged(wxPropertyGridEvent& event)
RenameInTree(resourcesTree->GetRootItem(), renamedItemOldName, propertyNewValue, "Image");
}
else
project.GetResourcesManager().GetResource(data->GetSecondString()).ChangeProperty(project, propertyName, propertyNewValue);
project.GetResourcesManager().GetResource(data->GetSecondString()).UpdateProperty(propertyName, propertyNewValue, project);
for ( std::size_t j = 0; j < project.GetUsedPlatforms().size();++j)
project.GetUsedPlatforms()[j]->GetChangesNotifier().OnResourceModified(project, data->GetSecondString());
@@ -945,7 +936,7 @@ void ResourcesEditor::Refresh()
gd::ResourceFolder & folder = project.GetResourcesManager().GetFolder(folders[i]);
wxTreeItemId folderItem = resourcesTree->AppendItem( resourcesTree->GetRootItem(), folders[i], -1, -1, new gd::TreeItemStringData("Folder", folders[i] ));
std::vector<gd::String> resources = folder.GetAllResourcesList();
std::vector<gd::String> resources = folder.GetAllResourceNames();
for (std::size_t j=0;j<resources.size();++j)
{
gd::Resource & resource = folder.GetResource(resources[j]);
@@ -959,7 +950,7 @@ void ResourcesEditor::Refresh()
//All images
allImagesItem = resourcesTree->AppendItem( resourcesTree->GetRootItem(), _("All images"), -1,-1, new gd::TreeItemStringData("BaseFolder", "" ));
std::vector<gd::String> resources = project.GetResourcesManager().GetAllResourcesList();
std::vector<gd::String> resources = project.GetResourcesManager().GetAllResourceNames();
for ( std::size_t i = 0;i <resources.size();i++ )
{
gd::Resource & resource = project.GetResourcesManager().GetResource(resources[i]);

View File

@@ -143,13 +143,13 @@ void InstructionSentenceFormatter::LoadTypesFormattingFromConfig()
{
//Load default configuration
typesFormatting.clear();
typesFormatting["expression"].SetColor(99, 0, 0).SetBold();
typesFormatting["object"].SetColor(19, 81, 0).SetBold();
typesFormatting["behavior"].SetColor(19, 81, 0).SetBold();
typesFormatting["operator"].SetColor(64, 81, 79).SetBold();
typesFormatting["objectvar"].SetColor(44, 69, 99).SetBold();
typesFormatting["scenevar"].SetColor(44, 69, 99).SetBold();
typesFormatting["globalvar"].SetColor(44, 69, 99).SetBold();
typesFormatting["expression"].SetColor(27, 143, 1).SetBold();
typesFormatting["object"].SetColor(182, 97, 10).SetBold();
typesFormatting["behavior"].SetColor(119, 119, 119).SetBold();
typesFormatting["operator"].SetColor(55, 131, 211).SetBold();
typesFormatting["objectvar"].SetColor(131, 55, 162).SetBold();
typesFormatting["scenevar"].SetColor(131, 55, 162).SetBold();
typesFormatting["globalvar"].SetColor(131, 55, 162).SetBold();
//Load any existing custom configuration
#if !defined(GD_NO_WX_GUI)

View File

@@ -51,7 +51,7 @@ void ArbitraryResourceWorker::ExposeResources(gd::ResourcesManager * resourcesMa
resourcesManagers.push_back(resourcesManager);
std::vector<gd::String> resources = resourcesManager->GetAllResourcesList();
std::vector<gd::String> resources = resourcesManager->GetAllResourceNames();
for ( std::size_t i = 0;i < resources.size() ;i++ )
{
if ( resourcesManager->GetResource(resources[i]).UseFile() )

View File

@@ -45,7 +45,7 @@ std::vector<gd::String> ProjectResourcesAdder::GetAllUselessImages(gd::Project &
std::set<gd::String> & usedImages = inventorizer.GetAllUsedImages();
//Search all images resources not used
std::vector<gd::String> resources = project.GetResourcesManager().GetAllResourcesList();
std::vector<gd::String> resources = project.GetResourcesManager().GetAllResourceNames();
for (std::size_t i = 0;i < resources.size();i++)
{
if (project.GetResourcesManager().GetResource(resources[i]).GetKind() != "image")

View File

@@ -45,7 +45,7 @@ bool ProjectResourcesCopier::CopyAllResourcesTo(gd::Project & originalProject, A
#endif
auto projectDirectory = fs.DirNameFrom(originalProject.GetProjectFile());
std::cout << "Copying all ressources from " << projectDirectory << " to " << destinationDirectory;
std::cout << "Copying all ressources from " << projectDirectory << " to " << destinationDirectory << "..." << std::endl;
//Get the resources to be copied
gd::ResourcesMergingHelper resourcesMergingHelper(fs);

View File

@@ -68,7 +68,7 @@ public:
* Usage example:
\code
std::map<gd::String, gd::PropertyDescriptor> properties;
properties[ToString(_("Initial speed"))].SetValue("5");
properties[_("Initial speed")].SetValue(gd::String::From(initialSpeed));
return properties;
\endcode

View File

@@ -5,6 +5,10 @@
*/
#include "GDCore/Project/BehaviorsSharedData.h"
#if defined(GD_IDE_ONLY)
#include <map>
#include "GDCore/IDE/Dialogs/PropertyDescriptor.h"
#endif
namespace gd
{
@@ -13,4 +17,12 @@ BehaviorsSharedData::~BehaviorsSharedData()
{
};
#if defined(GD_IDE_ONLY)
std::map<gd::String, gd::PropertyDescriptor> BehaviorsSharedData::GetProperties(gd::Project & project) const
{
std::map<gd::String, gd::PropertyDescriptor> nothing;
return nothing;
}
#endif
}

View File

@@ -8,9 +8,13 @@
#define BEHAVIORSSHAREDDATA_H
#include <memory>
#include <map>
#include "GDCore/String.h"
class BehaviorsRuntimeSharedData;
namespace gd { class SerializerElement; }
namespace gd { class PropertyDescriptor; }
namespace gd { class Project; }
namespace gd { class Layout; }
namespace gd
{
@@ -52,6 +56,31 @@ public:
virtual void SetTypeName(const gd::String & type_) { type = type_; };
#if defined(GD_IDE_ONLY)
/**
* \brief Called when the IDE wants to know about the properties of the shared data.
*
* Usage example:
\code
std::map<gd::String, gd::PropertyDescriptor> properties;
properties[_("Initial speed")].SetValue(gd::String::From(initialSpeed));
return properties;
\endcode
*
* \return a std::map with properties names as key.
* \see gd::PropertyDescriptor
*/
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(gd::Project & project) const;
/**
* \brief Called when the IDE wants to update a property of the shared data
*
* \return false if the new value cannot be set
* \see gd::InitialInstance
*/
virtual bool UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project) {return false;};
/**
* \brief Serialize behaviors shared data.
*/

View File

@@ -141,7 +141,7 @@ void ImageManager::LoadPermanentImages()
//so as not to unload images that could be still present.
std::map < gd::String, std::shared_ptr<SFMLTextureWrapper> > newPermanentlyLoadedImages;
std::vector<gd::String> resources = resourcesManager->GetAllResourcesList();
std::vector<gd::String> resources = resourcesManager->GetAllResourceNames();
for ( std::size_t i = 0;i <resources.size();i++ )
{
try

View File

@@ -29,6 +29,7 @@ namespace gd
{
gd::Layer Layout::badLayer;
gd::BehaviorsSharedData Layout::badBehaviorSharedData;
Layout::Layout(const Layout & other)
{
@@ -74,6 +75,53 @@ void Layout::SetName(const gd::String & name_)
mangledName = gd::SceneNameMangler::GetMangledSceneName(name);
};
bool Layout::HasBehaviorSharedData(const gd::String & behaviorName)
{
return behaviorsInitialSharedDatas.find(behaviorName) != behaviorsInitialSharedDatas.end();
}
std::vector <gd::String> Layout::GetAllBehaviorSharedDataNames() const
{
std::vector < gd::String > allNames;
for (auto & it : behaviorsInitialSharedDatas)
allNames.push_back(it.first);
return allNames;
}
const gd::BehaviorsSharedData & Layout::GetBehaviorSharedData(const gd::String & behaviorName) const
{
auto it = behaviorsInitialSharedDatas.find(behaviorName);
if (it != behaviorsInitialSharedDatas.end())
return *it->second;
return badBehaviorSharedData;
}
gd::BehaviorsSharedData & Layout::GetBehaviorSharedData(const gd::String & behaviorName)
{
auto it = behaviorsInitialSharedDatas.find(behaviorName);
if (it != behaviorsInitialSharedDatas.end())
return *it->second;
return badBehaviorSharedData;
}
std::shared_ptr<gd::BehaviorsSharedData> Layout::GetBehaviorSharedDataSmartPtr(const gd::String & behaviorName)
{
auto it = behaviorsInitialSharedDatas.find(behaviorName);
if (it != behaviorsInitialSharedDatas.end())
return it->second;
return std::shared_ptr<gd::BehaviorsSharedData>();
}
const std::map < gd::String, std::shared_ptr<gd::BehaviorsSharedData> > & Layout::GetAllBehaviorSharedData() const
{
return behaviorsInitialSharedDatas;
}
gd::Layer & Layout::GetLayer(const gd::String & name)
{
std::vector<gd::Layer>::iterator layer = find_if(initialLayers.begin(), initialLayers.end(), bind2nd(gd::LayerHasName(), name));
@@ -83,6 +131,7 @@ gd::Layer & Layout::GetLayer(const gd::String & name)
return badLayer;
}
const gd::Layer & Layout::GetLayer(const gd::String & name) const
{
std::vector<gd::Layer>::const_iterator layer = find_if(initialLayers.begin(), initialLayers.end(), bind2nd(gd::LayerHasName(), name));
@@ -92,14 +141,17 @@ const gd::Layer & Layout::GetLayer(const gd::String & name) const
return badLayer;
}
gd::Layer & Layout::GetLayer(std::size_t index)
{
return initialLayers[index];
}
const gd::Layer & Layout::GetLayer (std::size_t index) const
{
return initialLayers[index];
}
std::size_t Layout::GetLayersCount() const
{
return initialLayers.size();

View File

@@ -172,37 +172,37 @@ public:
/** \name Layout layers management
* Members functions related to layout layers management.
* TODO: This should be moved to a separate class
* TODO: This could be moved to a separate class
*/
///@{
/**
* Must return true if the layer called "name" exists.
* \brief Return true if the layer called "name" exists.
*/
bool HasLayerNamed(const gd::String & name) const;
/**
* Must return a reference to the layer called "name".
* \brief Return a reference to the layer called "name".
*/
Layer & GetLayer(const gd::String & name);
/**
* Must return a reference to the layer called "name".
* \brief Return a reference to the layer called "name".
*/
const Layer & GetLayer(const gd::String & name) const;
/**
* Must return a reference to the layer at position "index" in the layers list
* \brief Return a reference to the layer at position "index" in the layers list
*/
Layer & GetLayer(std::size_t index);
/**
* Must return a reference to the layer at position "index" in the layers list
* \brief Return a reference to the layer at position "index" in the layers list
*/
const Layer & GetLayer (std::size_t index) const;
const Layer & GetLayer(std::size_t index) const;
/**
* Must return the position of the layer called "name" in the layers list
* \brief Return the position of the layer called "name" in the layers list
*/
std::size_t GetLayerPosition(const gd::String & name) const;
@@ -253,15 +253,45 @@ public:
///@}
/**
* Make sure that the scene had an instance of shared data for
* This ensures that the scene had an instance of shared data for
* every behavior of every object that can be used on the scene
* ( i.e. the objects of the scene and the global objects )
* (i.e. the objects of the scene and the global objects)
*
* Must be called when a behavior have been added/deleted
* or when a scene have been added to a project.
*/
void UpdateBehaviorsSharedData(gd::Project & project);
/**
* \brief Get the names of all shared data stored for behaviors
*/
std::vector <gd::String> GetAllBehaviorSharedDataNames() const;
/**
* \brief Check if shared data are stored for a behavior
*/
bool HasBehaviorSharedData(const gd::String & behaviorName);
/**
* \brief Get the shared data stored for a behavior
*/
const gd::BehaviorsSharedData & GetBehaviorSharedData(const gd::String & behaviorName) const;
/**
* \brief Get the shared data stored for a behavior
*/
gd::BehaviorsSharedData & GetBehaviorSharedData(const gd::String & behaviorName);
/**
* \brief Get a map of all shared data stored for behaviors
*/
const std::map < gd::String, std::shared_ptr<gd::BehaviorsSharedData> > & GetAllBehaviorSharedData() const;
/**
* \brief Get the (smart pointer to the) shared data stored for a behavior.
*/
std::shared_ptr<gd::BehaviorsSharedData> GetBehaviorSharedDataSmartPtr(const gd::String & behaviorName);
#if defined(GD_IDE_ONLY)
/**
* Return the settings associated to the layout.
@@ -357,9 +387,6 @@ public:
void UnserializeFrom(gd::Project & project, const SerializerElement & element);
///@}
//TODO: Send this to private part.
std::map < gd::String, std::shared_ptr<gd::BehaviorsSharedData> > behaviorsInitialSharedDatas; ///< Initial shared datas of behaviors
//TODO: GD C++ Platform specific code below
#if defined(GD_IDE_ONLY)
/** \name Events compilation and bitcode management
@@ -442,6 +469,7 @@ private:
gd::InitialInstancesContainer initialInstances; ///< Initial instances
std::vector < gd::Layer > initialLayers; ///< Initial layers
ObjectGroupsContainer objectGroups; ///< Objects groups
std::map < gd::String, std::shared_ptr<gd::BehaviorsSharedData> > behaviorsInitialSharedDatas; ///< Initial shared datas of behaviors
bool stopSoundsOnStartup; ///< True to make the scene stop all sounds at startup.
bool standardSortMethod; ///< True to sort objects using standard sort.
float oglFOV; ///< OpenGL Field Of View value
@@ -449,6 +477,7 @@ private:
float oglZFar; ///< OpenGL Far Z position
bool disableInputWhenNotFocused; /// If set to true, the input must be disabled when the window do not have the focus.
static gd::Layer badLayer; ///< Null object, returned when GetLayer can not find an appropriate layer.
static gd::BehaviorsSharedData badBehaviorSharedData; ///< Null object, returned when GetBehaviorSharedData can not find the specified behavior shared data.
#if defined(GD_IDE_ONLY)
EventsList events; ///< Scene events
gd::LayoutEditorCanvasOptions associatedSettings;

View File

@@ -0,0 +1,21 @@
/*
* GDevelop Core
* Copyright 2008-2018 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
* This project is released under the MIT License.
*/
#include "LoadingScreen.h"
#include "GDCore/Serialization/SerializerElement.h"
namespace gd {
void LoadingScreen::SerializeTo(SerializerElement& element) const
{
element.SetAttribute("showGDevelopSplash", showGDevelopSplash);
}
void LoadingScreen::UnserializeFrom(const SerializerElement& element)
{
showGDevelopSplash = element.GetBoolAttribute("showGDevelopSplash", true);
}
}

View File

@@ -0,0 +1,57 @@
/*
* GDevelop Core
* Copyright 2008-2018 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
* This project is released under the MIT License.
*/
#ifndef GDCORE_LOADINGSCREEN_H
#define GDCORE_LOADINGSCREEN_H
#include "GDCore/String.h"
namespace gd {
class SerializerElement;
}
namespace gd {
/**
* \brief Describe the content and set up of the loading screen
*
* \see gd::LoadingScreen
*
* \ingroup PlatformDefinition
*/
class GD_CORE_API LoadingScreen {
public:
LoadingScreen(){};
virtual ~LoadingScreen(){};
/**
* \brief Set if the GDevelop splash should be shown while loading assets.
*/
void ShowGDevelopSplash(bool show) { showGDevelopSplash = show; };
/**
* \brief Return true if the GDevelop splash should be shown while loading assets.
*/
bool IsGDevelopSplashShown() const { return showGDevelopSplash; };
/** \name Saving and loading
*/
///@{
/**
* \brief Serialize objects groups container.
*/
void SerializeTo(SerializerElement& element) const;
/**
* \brief Unserialize the objects groups container.
*/
void UnserializeFrom(const SerializerElement& element);
///@}
private:
bool showGDevelopSplash;
};
}
#endif // GDCORE_LOADINGSCREEN_H

View File

@@ -0,0 +1,58 @@
/*
* GDevelop Core
* Copyright 2008-2018 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
* This project is released under the MIT License.
*/
#include "PlatformSpecificAssets.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
namespace gd {
gd::String PlatformSpecificAssets::badStr;
bool PlatformSpecificAssets::Has(const gd::String& platform, const gd::String& name) const
{
return assets.find(platform + "-" + name) != assets.end();
}
const gd::String& PlatformSpecificAssets::Get(const gd::String& platform, const gd::String& name) const
{
const auto & it = assets.find(platform + "-" + name);
return it != assets.end() ? it->second : badStr;
}
void PlatformSpecificAssets::Remove(const gd::String& platform, const gd::String& name)
{
assets.erase(platform + "-" + name);
}
void PlatformSpecificAssets::Set(const gd::String& platform, const gd::String& name, const gd::String& resourceName)
{
assets[platform + "-" + name] = resourceName;
}
void PlatformSpecificAssets::SerializeTo(SerializerElement& element) const
{
for (auto& it : assets) {
element.AddChild(it.first).SetValue(it.second);
}
}
void PlatformSpecificAssets::UnserializeFrom(const SerializerElement& element)
{
assets.clear();
for (auto& child : element.GetAllChildren()) {
assets[child.first] = child.second->GetValue().GetString();
}
}
void PlatformSpecificAssets::ExposeResources(gd::ArbitraryResourceWorker & worker)
{
for (auto& it : assets) {
worker.ExposeImage(it.second);
}
}
}

View File

@@ -0,0 +1,76 @@
/*
* GDevelop Core
* Copyright 2008-2018 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
* This project is released under the MIT License.
*/
#ifndef GDCORE_PLATFORMASSETS_H
#define GDCORE_PLATFORMASSETS_H
#include "GDCore/String.h"
#include <map>
namespace gd {
class SerializerElement;
}
namespace gd {
class ArbitraryResourceWorker;
}
namespace gd {
/**
* \brief Store the icons, splashscreens or reference to any other asset
* that can be needed when exporting the game.
*
* \see gd::Project
*
* \ingroup PlatformDefinition
*/
class GD_CORE_API PlatformSpecificAssets {
public:
PlatformSpecificAssets(){};
virtual ~PlatformSpecificAssets(){};
/**
* \brief Return true if the specified asset exists.
*/
bool Has(const gd::String& platform, const gd::String& name) const;
/**
* \brief Get the specified asset resource name.
*/
const gd::String& Get(const gd::String& platform, const gd::String& name) const;
/**
* \brief Remove the specified asset.
*/
void Remove(const gd::String& platform, const gd::String& name);
/**
* \brief Remove the specified asset.
*/
void Set(const gd::String& platform, const gd::String& name, const gd::String& resourceName);
void ExposeResources(gd::ArbitraryResourceWorker & worker);
/** \name Saving and loading
*/
///@{
/**
* \brief Serialize objects groups container.
*/
void SerializeTo(SerializerElement& element) const;
/**
* \brief Unserialize the objects groups container.
*/
void UnserializeFrom(const SerializerElement& element);
///@}
private:
std::map<gd::String, gd::String> assets;
static gd::String badStr;
};
}
#endif // GDCORE_PLATFORMASSETS_H

View File

@@ -61,6 +61,7 @@ Project::Project() :
#if defined(GD_IDE_ONLY)
name(_("Project")),
packageName("com.example.gamename"),
orientation("landscape"),
folderProject(false),
#endif
windowWidth(800),
@@ -531,9 +532,12 @@ void Project::UnserializeFrom(const SerializerElement & element)
#if defined(GD_IDE_ONLY)
SetAuthor(propElement.GetChild("author", 0, "Auteur").GetValue().GetString());
SetPackageName(propElement.GetStringAttribute("packageName"));
SetOrientation(propElement.GetStringAttribute("orientation", "default"));
SetFolderProject(propElement.GetBoolAttribute("folderProject"));
SetProjectFile(propElement.GetStringAttribute("projectFile"));
SetLastCompilationDirectory(propElement.GetChild("latestCompilationDirectory", 0, "LatestCompilationDirectory").GetValue().GetString());
platformSpecificAssets.UnserializeFrom(propElement.GetChild("platformSpecificAssets"));
loadingScreen.UnserializeFrom(propElement.GetChild("loadingScreen"));
winExecutableFilename = propElement.GetStringAttribute("winExecutableFilename");
winExecutableIconFile = propElement.GetStringAttribute("winExecutableIconFile");
linuxExecutableFilename = propElement.GetStringAttribute("linuxExecutableFilename");
@@ -743,6 +747,9 @@ void Project::SerializeTo(SerializerElement & element) const
propElement.SetAttribute("projectFile", gameFile);
propElement.SetAttribute("folderProject", folderProject);
propElement.SetAttribute("packageName", packageName);
propElement.SetAttribute("orientation", orientation);
platformSpecificAssets.SerializeTo(propElement.AddChild("platformSpecificAssets"));
loadingScreen.SerializeTo(propElement.AddChild("loadingScreen"));
propElement.SetAttribute("winExecutableFilename", winExecutableFilename);
propElement.SetAttribute("winExecutableIconFile", winExecutableIconFile);
propElement.SetAttribute("linuxExecutableFilename", linuxExecutableFilename);
@@ -815,6 +822,7 @@ void Project::ExposeResources(gd::ArbitraryResourceWorker & worker)
{
//Add project resources
worker.ExposeResources(&GetResourcesManager());
platformSpecificAssets.ExposeResources(worker);
#if !defined(GD_NO_WX_GUI)
gd::SafeYield::Do();
#endif
@@ -1019,8 +1027,11 @@ void Project::Init(const gd::Project & game)
#if defined(GD_IDE_ONLY)
author = game.author;
packageName = game.packageName;
orientation = game.orientation;
folderProject = game.folderProject;
latestCompilationDirectory = game.latestCompilationDirectory;
platformSpecificAssets = game.platformSpecificAssets;
loadingScreen = game.loadingScreen;
objectGroups = game.objectGroups;
GDMajorVersion = game.GDMajorVersion;

View File

@@ -16,6 +16,8 @@ class TiXmlElement;
#include "GDCore/Project/ChangesNotifier.h"
#include "GDCore/Project/VariablesContainer.h"
#include "GDCore/Project/ResourcesManager.h"
#include "GDCore/Project/PlatformSpecificAssets.h"
#include "GDCore/Project/LoadingScreen.h"
#include "GDCore/Project/ObjectGroupsContainer.h"
namespace gd { class Platform; }
namespace gd { class Layout; }
@@ -85,6 +87,18 @@ public:
*/
const gd::String & GetPackageName() const { return packageName; }
/**
* \brief Change the project orientation (in particular when exported with Cordova).
* This has no effect on desktop and web browsers.
* \param orientation The orientation to use ("default", "landscape", "portrait").
*/
void SetOrientation(const gd::String & orientation_) { orientation = orientation_; };
/**
* \brief Get project orientation ("default", "landscape", "portrait").
*/
const gd::String & GetOrientation() const { return orientation; }
/**
* Called when project file has changed.
*/
@@ -118,6 +132,26 @@ public:
* \see gd::Project::SetLastCompilationDirectory
*/
const gd::String & GetLastCompilationDirectory() const {return latestCompilationDirectory;}
/**
* \brief Return a reference to platform assets of the project (icons, splashscreen...).
*/
gd::PlatformSpecificAssets & GetPlatformSpecificAssets() { return platformSpecificAssets; }
/**
* \brief Return a reference to platform assets of the project (icons, splashscreen...).
*/
const gd::PlatformSpecificAssets & GetPlatformSpecificAssets() const { return platformSpecificAssets; }
/**
* \brief Return a reference to loading screen setup for the project
*/
gd::LoadingScreen & GetLoadingScreen() { return loadingScreen; }
/**
* \brief Return a reference to loading screen setup for the project
*/
const gd::LoadingScreen & GetLoadingScreen() const { return loadingScreen; }
#endif
/**
@@ -737,10 +771,13 @@ private:
gd::ObjectGroupsContainer objectGroups; ///< Global objects groups
gd::String author; ///< Game author name
gd::String packageName; ///< Game package name
gd::String orientation; ///< Lock game orientation (on mobile devices). "default", "landscape" or "portrait".
bool folderProject; ///< True if folder project, false if single file project.
gd::String gameFile; ///< File of the game
gd::String latestCompilationDirectory; ///< File of the game
gd::Platform* currentPlatform; ///< The platform being used to edit the project.
gd::PlatformSpecificAssets platformSpecificAssets;
gd::LoadingScreen loadingScreen;
std::vector < std::unique_ptr<gd::ExternalEvents> > externalEvents; ///< List of all externals events
mutable unsigned int GDMajorVersion; ///< The GD major version used the last time the project was saved.
mutable unsigned int GDMinorVersion; ///< The GD minor version used the last time the project was saved.

View File

@@ -5,6 +5,7 @@
*/
#include <iostream>
#include <map>
#if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI)
#include "GDCore/IDE/wxTools/CommonBitmapProvider.h"
#include <wx/filedlg.h>
@@ -20,6 +21,7 @@
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/Tools/Log.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/IDE/Dialogs/PropertyDescriptor.h"
namespace gd
{
@@ -105,7 +107,7 @@ bool ResourcesManager::HasResource(const gd::String & name) const
return false;
}
std::vector<gd::String> ResourcesManager::GetAllResourcesList()
std::vector<gd::String> ResourcesManager::GetAllResourceNames()
{
std::vector<gd::String> allResources;
for (std::size_t i = 0;i<resources.size();++i)
@@ -114,8 +116,30 @@ std::vector<gd::String> ResourcesManager::GetAllResourcesList()
return allResources;
}
#if defined(GD_IDE_ONLY)
std::map<gd::String, gd::PropertyDescriptor> Resource::GetProperties(gd::Project & project) const
{
std::map<gd::String, gd::PropertyDescriptor> nothing;
return nothing;
}
std::map<gd::String, gd::PropertyDescriptor> ImageResource::GetProperties(gd::Project & project) const
{
std::map<gd::String, gd::PropertyDescriptor> properties;
properties[_("Smooth the image")].SetValue(smooth ? "true" : "false").SetType("Boolean");
properties[_("Always loaded in memory")].SetValue(alwaysLoaded ? "true" : "false").SetType("Boolean");
return properties;
}
bool ImageResource::UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project)
{
if (name == _("Smooth the image")) smooth = value == "1";
else if (name == _("Always loaded in memory")) alwaysLoaded = value == "1";
return true;
}
bool ResourcesManager::AddResource(const gd::Resource & resource)
{
if ( HasResource(resource.GetName()) ) return false;
@@ -146,7 +170,7 @@ bool ResourcesManager::AddResource(const gd::String & name, const gd::String & f
return true;
}
std::vector<gd::String> ResourceFolder::GetAllResourcesList()
std::vector<gd::String> ResourceFolder::GetAllResourceNames()
{
std::vector<gd::String> allResources;
for (std::size_t i = 0;i<resources.size();++i)
@@ -155,61 +179,6 @@ std::vector<gd::String> ResourceFolder::GetAllResourcesList()
return allResources;
}
bool ImageResource::EditProperty(gd::Project & project, const gd::String & property)
{
return false;
}
bool ImageResource::ChangeProperty(gd::Project & project, const gd::String & property, const gd::String & newValue)
{
if ( property == "smooth" )
smooth = (newValue == _("Yes"));
else if ( property == "alwaysLoaded" )
alwaysLoaded = (newValue == _("Yes"));
return true;
}
void ImageResource::GetPropertyInformation(gd::Project & project, const gd::String & property, gd::String & userFriendlyName, gd::String & description) const
{
if ( property == "smooth" )
{
userFriendlyName = _("Smooth the image");
description = _("Set this to \"Yes\" to set a smooth filter on the image");
}
else if ( property == "alwaysLoaded" )
{
userFriendlyName = _("Always loaded in memory");
description = _("Set this to \"Yes\" to let the image always loaded in memory.\nUseful when the image is used by actions.");
}
}
gd::String ImageResource::GetProperty(gd::Project & project, const gd::String & property)
{
if ( property == "smooth" )
{
return smooth ? _("Yes") : _("No");
}
else if ( property == "alwaysLoaded" )
{
return alwaysLoaded ? _("Yes") : _("No");
}
return "";
}
/**
* Return a vector containing the name of all the properties of the resource
*/
std::vector<gd::String> ImageResource::GetAllProperties(gd::Project & project) const
{
std::vector<gd::String> allProperties;
allProperties.push_back("smooth");
allProperties.push_back("alwaysLoaded");
return allProperties;
}
#if !defined(GD_NO_WX_GUI)
void ImageResource::RenderPreview(wxPaintDC & dc, wxPanel & previewPanel, gd::Project & project)
{
@@ -351,6 +320,25 @@ bool ResourcesManager::MoveResourceDownInList(const gd::String & name)
return gd::MoveResourceDownInList(resources, name);
}
std::size_t ResourcesManager::GetResourcePosition(const gd::String & name) const
{
for (std::size_t i = 0;i<resources.size();++i)
{
if (resources[i]->GetName() == name) return i;
}
return gd::String::npos;
}
void ResourcesManager::MoveResource(std::size_t oldIndex, std::size_t newIndex)
{
if ( oldIndex >= resources.size() || newIndex >= resources.size() )
return;
auto resource = resources[oldIndex];
resources.erase(resources.begin() + oldIndex);
resources.insert(resources.begin() + newIndex, resource);
}
bool ResourcesManager::MoveFolderUpInList(const gd::String & name)
{
for (std::size_t i =1;i<folders.size();++i)

View File

@@ -6,11 +6,12 @@
#ifndef GDCORE_RESOURCESMANAGER_H
#define GDCORE_RESOURCESMANAGER_H
#include <memory>
#include "GDCore/String.h"
#include <vector>
#include "GDCore/String.h"
namespace gd { class Project; }
namespace gd { class ResourceFolder; }
namespace gd { class SerializerElement; }
namespace gd { class PropertyDescriptor; }
class wxPaintDC;
class wxPanel;
@@ -83,37 +84,6 @@ public:
*/
gd::String GetAbsoluteFile(const gd::Project & game) const;
/**
* \brief Called when a property must be edited (i.e: it was double clicked in a property grid)
*
* \return true if the resource was changed
*/
virtual bool EditProperty(gd::Project & project, const gd::String & property) { return true; };
/**
* \brief Called when a property must be changed (i.e: its value was changed in a property grid)
*
* \return true if the resource was changed
*/
virtual bool ChangeProperty(gd::Project & project, const gd::String & property, const gd::String & newValue) { return true; };
/**
* \brief Must return a description of the main property provided by the resource (example : "Image file")
*/
virtual void GetPropertyInformation(gd::Project & project, const gd::String & property, gd::String & userFriendlyName, gd::String & description) const { return; };
/**
* \brief Called when a property must be changed ( i.e: its value was changed in the property grid )
*
* \return the value of the property
*/
virtual gd::String GetProperty(gd::Project & project, const gd::String & property) { return ""; };
/**
* \brief Return a description of the main property provided by the resource ( Example : "Image file" )
*/
virtual std::vector<gd::String> GetAllProperties(gd::Project & project) const { std::vector<gd::String> noProperties; return noProperties; };
#if !defined(GD_NO_WX_GUI)
/**
* \brief Called when the resource must be rendered in a preview panel.
@@ -121,6 +91,36 @@ public:
virtual void RenderPreview(wxPaintDC & dc, wxPanel & previewPanel, gd::Project & game) {};
#endif
#if defined(GD_IDE_ONLY)
/** \name Resources properties
* Reading and updating resources properties
*/
///@{
/**
* \brief Called when the IDE wants to know about the custom properties of the resource.
*
* Usage example:
\code
std::map<gd::String, gd::PropertyDescriptor> properties;
properties[ToString(_("Text"))].SetValue("Hello world!");
return properties;
\endcode
*
* \return a std::map with properties names as key.
* \see gd::PropertyDescriptor
*/
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(gd::Project & project) const;
/**
* \brief Called when the IDE wants to update a custom property of the resource
*
* \return false if the new value cannot be set
*/
virtual bool UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project) {return false;};
///@}
#endif
/**
* \brief Serialize the object
*/
@@ -150,69 +150,41 @@ class GD_CORE_API ImageResource : public Resource
public:
ImageResource() : Resource(), smooth(true), alwaysLoaded(false) { SetKind("image"); };
virtual ~ImageResource() {};
virtual ImageResource* Clone() const { return new ImageResource(*this);}
virtual ImageResource* Clone() const override { return new ImageResource(*this);}
/**
* Return the file used by the resource.
*/
virtual const gd::String & GetFile() const {return file;};
virtual const gd::String & GetFile() const override {return file;};
/**
* Change the file of the resource.
*/
virtual void SetFile(const gd::String & newFile);
virtual void SetFile(const gd::String & newFile) override;
#if defined(GD_IDE_ONLY)
virtual bool UseFile() { return true; }
virtual bool UseFile() override { return true; }
#if !defined(GD_NO_WX_GUI)
/**
* Called when the resource must be rendered in a preview panel.
*/
virtual void RenderPreview(wxPaintDC & dc, wxPanel & previewPanel, gd::Project & game);
virtual void RenderPreview(wxPaintDC & dc, wxPanel & previewPanel, gd::Project & game) override;
#endif
/**
* Called when a property must be edited ( i.e: it was double clicked )
*
* \return true if the resource was changed
*/
virtual bool EditProperty(gd::Project & project, const gd::String & property);
/**
* Called when a property must be changed ( i.e: its value was changed in the property grid )
*
* \return true if the resource was changed
*/
virtual bool ChangeProperty(gd::Project & project, const gd::String & property, const gd::String & newValue);
/**
* Called when a property must be changed ( i.e: its value was changed in the property grid )
*
* \return the value of the property
*/
virtual gd::String GetProperty(gd::Project & project, const gd::String & property);
/**
* Return a description of the main property provided by the resource ( Example : "Image file" )
*/
virtual void GetPropertyInformation(gd::Project & project, const gd::String & property, gd::String & userFriendlyName, gd::String & description) const;
/**
* Return a vector containing the name of all the properties of the resource
*/
virtual std::vector<gd::String> GetAllProperties(gd::Project & project) const;
std::map<gd::String, gd::PropertyDescriptor> GetProperties(gd::Project & project) const override;
bool UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project) override;
/**
* \brief Serialize the object
*/
void SerializeTo(SerializerElement & element) const;
void SerializeTo(SerializerElement & element) const override;
#endif
/**
* \brief Unserialize the objectt.
*/
void UnserializeFrom(const SerializerElement & element);
void UnserializeFrom(const SerializerElement & element) override;
/**
* \brief Return true if the image should be smoothed.
@@ -242,17 +214,17 @@ class GD_CORE_API AudioResource : public Resource
public:
AudioResource() : Resource() { SetKind("audio"); };
virtual ~AudioResource() {};
virtual AudioResource* Clone() const { return new AudioResource(*this);}
virtual AudioResource* Clone() const override { return new AudioResource(*this);}
virtual const gd::String & GetFile() const {return file;};
virtual void SetFile(const gd::String & newFile);
virtual const gd::String & GetFile() const override {return file;};
virtual void SetFile(const gd::String & newFile) override;
#if defined(GD_IDE_ONLY)
virtual bool UseFile() { return true; }
void SerializeTo(SerializerElement & element) const;
virtual bool UseFile() override { return true; }
void SerializeTo(SerializerElement & element) const override;
#endif
void UnserializeFrom(const SerializerElement & element);
void UnserializeFrom(const SerializerElement & element) override;
private:
gd::String file;
@@ -293,9 +265,9 @@ public:
std::shared_ptr<Resource> CreateResource(const gd::String & kind);
/**
* \brief Get a list containing the name of all of the resources.
* \brief Get a list containing the names of all resources.
*/
std::vector<gd::String> GetAllResourcesList();
std::vector<gd::String> GetAllResourceNames();
#if defined(GD_IDE_ONLY)
/**
@@ -324,6 +296,11 @@ public:
*/
void RenameResource(const gd::String & oldName, const gd::String & newName);
/**
* \brief Return the position of the layer called "name" in the layers list
*/
std::size_t GetResourcePosition(const gd::String & name) const;
/**
* \brief Move a resource up in the list
*/
@@ -334,6 +311,11 @@ public:
*/
bool MoveResourceDownInList(const gd::String & name);
/**
* Change the position of the specified resource.
*/
void MoveResource(std::size_t oldIndex, std::size_t newIndex);
/**
* \brief Return true if the folder exists.
*/
@@ -445,7 +427,7 @@ public:
/**
* Get a list containing the name of all of the resources.
*/
virtual std::vector<gd::String> GetAllResourcesList();
virtual std::vector<gd::String> GetAllResourceNames();
/**
* Move a resource up in the list

View File

@@ -84,7 +84,7 @@ TEST_CASE( "Resources", "[common][resources]" ) {
gd::ProjectResourcesAdder::RemoveAllUselessImages(project);
std::vector<gd::String> remainingResources =
project.GetResourcesManager().GetAllResourcesList();
project.GetResourcesManager().GetAllResourceNames();
REQUIRE(remainingResources.size() == 2);
REQUIRE(remainingResources[0] == "res1");
REQUIRE(remainingResources[1] == "res4");

View File

@@ -21,7 +21,7 @@ class GD_EXTENSION_API AdMobObject : public gd::Object
public:
AdMobObject(gd::String name_);
virtual ~AdMobObject() {};
virtual std::unique_ptr<gd::Object> Clone() const { return gd::make_unique<AdMobObject>(*this); }
virtual std::unique_ptr<gd::Object> Clone() const override { return gd::make_unique<AdMobObject>(*this); }
#if !defined(GD_NO_WX_GUI)
void DrawInitialInstance(gd::InitialInstance & instance, sf::RenderTarget & renderTarget, gd::Project & project, gd::Layout & layout) override;

View File

@@ -10,7 +10,7 @@ include(CMakeUtils.txt) #Functions to factor common tasks done in CMakeLists.txt
#Add all the CMakeLists:
ADD_SUBDIRECTORY(AdMobObject)
ADD_SUBDIRECTORY(AnchorBehavior)
IF (NOT EMSCRIPTEN) #Only add some extensions when compiling with emscripten.
IF (NOT EMSCRIPTEN)
ADD_SUBDIRECTORY(AdvancedXML)
ADD_SUBDIRECTORY(AES)
ADD_SUBDIRECTORY(Box3DObject)
@@ -35,9 +35,9 @@ ENDIF()
ADD_SUBDIRECTORY(PanelSpriteObject)
IF (NOT EMSCRIPTEN)
ADD_SUBDIRECTORY(PathBehavior)
ADD_SUBDIRECTORY(PathfindingBehavior)
ADD_SUBDIRECTORY(PhysicsBehavior)
ENDIF()
ADD_SUBDIRECTORY(PathfindingBehavior)
ADD_SUBDIRECTORY(PhysicsBehavior)
ADD_SUBDIRECTORY(PlatformBehavior)
ADD_SUBDIRECTORY(PrimitiveDrawing)
ADD_SUBDIRECTORY(Shopify)

View File

@@ -7,8 +7,6 @@ This project is released under the MIT License.
#if defined(GD_IDE_ONLY)
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include <iostream>
void DeclarePanelSpriteObjectExtension(gd::PlatformExtension & extension);

View File

@@ -322,13 +322,13 @@ PathBehaviorEditor::PathBehaviorEditor(wxWindow* parent, gd::Project & game_, gd
followAngleCheck->SetValue(behavior.FollowAngle());
//Setup shared datas
if ( !scene || scene->behaviorsInitialSharedDatas.find(behavior.GetName()) == scene->behaviorsInitialSharedDatas.end())
if (!scene || !scene->HasBehaviorSharedData(behavior.GetName()))
{
gd::LogError(_("Unable to access to shared datas."));
return;
}
sharedDatas = std::dynamic_pointer_cast<ScenePathDatas>(scene->behaviorsInitialSharedDatas[behavior.GetName()]);
sharedDatas = std::dynamic_pointer_cast<ScenePathDatas>(scene->GetBehaviorSharedDataSmartPtr(behavior.GetName()));
if ( sharedDatas == std::shared_ptr<ScenePathDatas>() )
{

File diff suppressed because it is too large Load Diff

View File

@@ -8,26 +8,21 @@ This project is released under the MIT License.
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include <iostream>
void DeclarePathfindingBehaviorExtension(gd::PlatformExtension & extension);
/**
* \brief This class declares information about the JS extension.
*/
class JsExtension : public gd::PlatformExtension
class PathfindingBehaviorJsExtension : public gd::PlatformExtension
{
public:
/**
* \brief Constructor of an extension declares everything the extension contains: objects, actions, conditions and expressions.
*/
JsExtension()
PathfindingBehaviorJsExtension()
{
SetExtensionInformation("PathfindingBehavior",
_("Pathfinding behavior"),
_("Compute paths for objects avoiding obstacles."),
"Florian Rival",
"Open source (MIT License)");
CloneExtension("GDevelop C++ platform", "PathfindingBehavior");
DeclarePathfindingBehaviorExtension(*this);
GetBehaviorMetadata("PathfindingBehavior::PathfindingBehavior")
.SetIncludeFile("Extensions/PathfindingBehavior/pathfindingruntimebehavior.js")
@@ -103,14 +98,21 @@ public:
}
StripUnimplementedInstructionsAndExpressions();
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
};
};
#if defined(EMSCRIPTEN)
extern "C" gd::PlatformExtension * CreateGDJSPathfindingBehaviorExtension() {
return new PathfindingBehaviorJsExtension;
}
#else
/**
* Used by GDevelop to create the extension class
* -- Do not need to be modified. --
*/
extern "C" gd::PlatformExtension * GD_EXTENSION_API CreateGDJSExtension() {
return new JsExtension;
return new PathfindingBehaviorJsExtension;
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -6,29 +6,23 @@ This project is released under the MIT License.
*/
#if defined(GD_IDE_ONLY)
#include "GDCore/Extensions/PlatformExtension.h"
#include <iostream>
#include "GDCore/Tools/Localization.h"
void DeclarePhysicsBehaviorExtension(gd::PlatformExtension & extension);
/**
* \brief This class declares information about the JS extension.
*/
class JsExtension : public gd::PlatformExtension
class PhysicsBehaviorJsExtension : public gd::PlatformExtension
{
public:
/**
* \brief Constructor of an extension declares everything the extension contains: objects, actions, conditions and expressions.
*/
JsExtension()
PhysicsBehaviorJsExtension()
{
SetExtensionInformation("PhysicsBehavior",
_("Physics behavior"),
_("Behavior allowing to move objects as if they were subject to the laws of physics."),
"Florian Rival",
"Open source (MIT License)");
CloneExtension("GDevelop C++ platform", "PhysicsBehavior");
DeclarePhysicsBehaviorExtension(*this);
GetBehaviorMetadata("PhysicsBehavior::PhysicsBehavior")
.SetIncludeFile("Extensions/PhysicsBehavior/box2djs/box2d.js")
@@ -145,14 +139,21 @@ public:
*/
StripUnimplementedInstructionsAndExpressions();
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
};
};
#if defined(EMSCRIPTEN)
extern "C" gd::PlatformExtension * CreateGDJSPhysicsBehaviorExtension() {
return new PhysicsBehaviorJsExtension;
}
#else
/**
* Used by GDevelop to create the extension class
* -- Do not need to be modified. --
*/
extern "C" gd::PlatformExtension * GD_EXTENSION_API CreateGDJSExtension() {
return new JsExtension;
return new PhysicsBehaviorJsExtension;
}
#endif
#endif

View File

@@ -7,6 +7,7 @@ This project is released under the MIT License.
#include "PhysicsBehavior.h"
#include <string>
#include "GDCore/Tools/Localization.h"
#include "Box2D/Box2D.h"
#include "Triangulation/triangulate.h"
#include "GDCpp/Runtime/RuntimeScene.h"
@@ -17,6 +18,10 @@ This project is released under the MIT License.
#include "GDCpp/Runtime/Project/Project.h"
#include "GDCpp/Runtime/Project/Layout.h"
#include "RuntimeScenePhysicsDatas.h"
#if defined(GD_IDE_ONLY)
#include <map>
#include "GDCore/IDE/Dialogs/PropertyDescriptor.h"
#endif
#undef GetObject
@@ -100,10 +105,6 @@ void PhysicsBehavior::DoStepPostEvents(RuntimeScene & scene)
float newHeight = object->GetHeight();
if ( (int)objectOldWidth != (int)newWidth || (int)objectOldHeight != (int)newHeight )
{
/*std::cout << "Changed:" << (int)objectOldWidth << "!=" << (int)newWidth << std::endl;
std::cout << "Changed:" << (int)objectOldHeight << "!=" << (int)newHeight << std::endl;
std::cout << "( Object name:" << object->GetName() << std::endl;*/
double oldAngularVelocity = body->GetAngularVelocity();
b2Vec2 oldVelocity = body->GetLinearVelocity();
@@ -700,6 +701,76 @@ void PhysicsBehavior::UnserializeFrom(const gd::SerializerElement & element)
SetPolygonCoords(PhysicsBehavior::GetCoordsVectorFromString(coordsStr, '/', ';'));
}
#if defined(GD_IDE_ONLY)
std::map<gd::String, gd::PropertyDescriptor> PhysicsBehavior::GetProperties(gd::Project & project) const
{
std::map<gd::String, gd::PropertyDescriptor> properties;
gd::String shapeTypeStr = _("Box (rectangle)");
if (shapeType == Box) shapeTypeStr = _("Box (rectangle)");
else if (shapeType == Circle) shapeTypeStr = _("Circle");
else if (shapeType == CustomPolygon) shapeTypeStr = _("Custom polygon");
properties[_("Shape")]
.SetValue(shapeTypeStr)
.SetType("Choice")
.AddExtraInfo(_("Box (rectangle)"))
.AddExtraInfo(_("Circle"));
properties[_("Dynamic object")].SetValue(dynamic ? "true" : "false").SetType("Boolean");
properties[_("Fixed rotation")].SetValue(fixedRotation ? "true" : "false").SetType("Boolean");
properties[_("Consider as bullet (better collision handling)")].SetValue(isBullet ? "true" : "false").SetType("Boolean");
properties[_("Mass density")].SetValue(gd::String::From(massDensity));
properties[_("Friction")].SetValue(gd::String::From(averageFriction));
properties[_("Restitution (elasticity)")].SetValue(gd::String::From(averageRestitution));
properties[_("Linear Damping")].SetValue(gd::String::From(linearDamping));
properties[_("Angular Damping")].SetValue(gd::String::From(angularDamping));
properties[_("PLEASE_ALSO_SHOW_EDIT_BUTTON_THANKS")].SetValue("");
return properties;
}
bool PhysicsBehavior::UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project)
{
if (name == _("Shape"))
{
if (value == _("Box (rectangle)"))
shapeType = Box;
else if (value == _("Circle"))
shapeType = Circle;
else if (value == _("Custom polygon"))
shapeType = CustomPolygon;
}
if ( name == _("Dynamic object") ) {
dynamic = (value != "0");
}
if ( name == _("Fixed rotation") ) {
fixedRotation = (value != "0");
}
if ( name == _("Consider as bullet (better collision handling)") ) {
isBullet = (value != "0");
}
if ( name == _("Mass density") ) {
massDensity = value.To<float>();
}
if ( name == _("Friction") ) {
averageFriction = value.To<float>();
}
if ( name == _("Restitution (elasticity)") ) {
averageRestitution = value.To<float>();
}
if ( name == _("Linear Damping") ) {
if ( value.To<float>() < 0 ) return false;
linearDamping = value.To<float>();
}
if ( name == _("Angular Damping") ) {
if ( value.To<float>() < 0 ) return false;
angularDamping = value.To<float>();
}
return true;
}
#endif
gd::String PhysicsBehavior::GetStringFromCoordsVector(const std::vector<sf::Vector2f> &vec, char32_t coordsSep, char32_t composantSep)
{

View File

@@ -56,6 +56,9 @@ public:
* Called when user wants to edit the behavior.
*/
virtual void EditBehavior( wxWindow* parent, gd::Project & project_, gd::Layout * layout_, gd::MainFrameWrapper & mainFrameWrapper_ );
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(gd::Project & project) const;
virtual bool UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project);
#endif
/**

View File

@@ -241,13 +241,13 @@ scene(scene_)
}
//Setup shared datas
if ( !scene || scene->behaviorsInitialSharedDatas.find(behavior.GetName()) == scene->behaviorsInitialSharedDatas.end())
if (!scene || !scene->HasBehaviorSharedData(behavior.GetName()))
{
gd::LogError(_("Unable to access to shared datas."));
return;
}
sharedDatas = std::dynamic_pointer_cast<ScenePhysicsDatas>(scene->behaviorsInitialSharedDatas[behavior.GetName()]);
sharedDatas = std::dynamic_pointer_cast<ScenePhysicsDatas>(scene->GetBehaviorSharedDataSmartPtr(behavior.GetName()));
if ( sharedDatas == std::shared_ptr<ScenePhysicsDatas>() )
{

View File

@@ -6,9 +6,46 @@ This project is released under the MIT License.
*/
#include "ScenePhysicsDatas.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/Serialization/SerializerElement.h"
#if defined(GD_IDE_ONLY)
#include <map>
#include "GDCore/String.h"
#include "GDCore/CommonTools.h"
#include "GDCore/Project/Project.h"
#include "GDCore/IDE/Dialogs/PropertyDescriptor.h"
#endif
#if defined(GD_IDE_ONLY)
std::map<gd::String, gd::PropertyDescriptor> ScenePhysicsDatas::GetProperties(gd::Project & project) const
{
std::map<gd::String, gd::PropertyDescriptor> properties;
properties[_("Gravity on X axis (in m/s²)")].SetValue(gd::String::From(gravityX));
properties[_("Gravity on Y axis (in m/s²)")].SetValue(gd::String::From(gravityY));
properties[_("X Scale: number of pixels for 1 meter")].SetValue(gd::String::From(scaleX));
properties[_("Y Scale: number of pixels for 1 meter")].SetValue(gd::String::From(scaleY));
return properties;
}
bool ScenePhysicsDatas::UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project)
{
if (name == _("Gravity on X axis (in m/s²)")) {
gravityX = value.To<float>();
}
if (name == _("Gravity on Y axis (in m/s²)")) {
gravityY = value.To<float>();
}
if (name == _("X scale: number of pixels for 1 meter")) {
scaleX = value.To<float>();
}
if (name == _("Y scale: number of pixels for 1 meter")) {
scaleY = value.To<float>();
}
return true;
}
void ScenePhysicsDatas::SerializeTo(gd::SerializerElement & element) const
{
element.SetAttribute("gravityX", gravityX);

View File

@@ -17,7 +17,7 @@ This project is released under the MIT License.
class ScenePhysicsDatas : public gd::BehaviorsSharedData
{
public:
ScenePhysicsDatas() : BehaviorsSharedData(), gravityX(0), gravityY(0), scaleX(100), scaleY(100)
ScenePhysicsDatas() : BehaviorsSharedData(), gravityX(0), gravityY(9), scaleX(100), scaleY(100)
{
};
virtual ~ScenePhysicsDatas() {};
@@ -34,6 +34,8 @@ public:
}
#if defined(GD_IDE_ONLY)
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(gd::Project & project) const;
virtual bool UpdateProperty(const gd::String & name, const gd::String & value, gd::Project & project);
virtual void SerializeTo(gd::SerializerElement & element) const;
#endif

View File

@@ -29,13 +29,21 @@ gdjs.TextRuntimeObjectPixiRenderer.prototype.ensureUpToDate = function() {
gdjs.TextRuntimeObjectPixiRenderer.prototype.updateStyle = function() {
var fontName = "\"gdjs_font_" + this._object._fontName + "\"";
var style = { align:"left" };
style.font = "";
if ( this._object._italic ) style.font += "italic ";
if ( this._object._bold ) style.font += "bold ";
style.font += this._object._characterSize + "px " + fontName;
style.fill = "rgb("+this._object._color[0]+","+this._object._color[1]+","+this._object._color[2]+")";
this._text.style = style;
var style = this._text.style;
style.fontStyle = this._object._italic ? 'italic' : 'normal';
style.fontWeight = this._object._bold ? 'bold' : 'normal';
style.fontSize = this._object._characterSize;
style.fontFamily = fontName;
style.fill = gdjs.rgbToHexNumber(
this._object._color[0],
this._object._color[1],
this._object._color[2]
);
// Manually ask the PIXI object to re-render as we changed a style property
// see http://www.html5gamedevs.com/topic/16924-change-text-style-post-render/
this._text.dirty = true;
};
gdjs.TextRuntimeObjectPixiRenderer.prototype.updatePosition = function() {

View File

@@ -69,6 +69,7 @@ BaseObjectExtension::BaseObjectExtension()
objectActions["Rebondir"].SetFunctionName("SeparateObjectsWithForces").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
objectActions["Ecarter"].SetFunctionName("SeparateObjectsWithoutForces").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
objectActions["SeparateFromObjects"].SetFunctionName("SeparateFromObjects").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
objectConditions["CollisionPoint"].SetFunctionName("IsCollidingWithPoint");
objectExpressions["X"].SetFunctionName("GetX");
@@ -105,6 +106,7 @@ BaseObjectExtension::BaseObjectExtension()
GetAllConditions()["NbObjet"].SetFunctionName("PickedObjectsCount").SetManipulatedType("number").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
GetAllConditions()["CollisionNP"].SetFunctionName("HitBoxesCollision").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
GetAllConditions()["EstTourne"].SetFunctionName("ObjectsTurnedToward").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
GetAllConditions()["Raycast"].SetFunctionName("RaycastObject").SetIncludeFile("GDCpp/Extensions/Builtin/RuntimeSceneTools.h");
GetAllExpressions()["Count"].SetFunctionName("PickedObjectsCount").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
#endif

View File

@@ -22,6 +22,9 @@
#include "GDCpp/Runtime/CommonTools.h"
#include "GDCpp/Runtime/Project/Variable.h"
#include "GDCpp/Extensions/CppPlatform.h"
#include "GDCpp/Runtime/PolygonCollision.h"
#include "GDCpp/Runtime/Polygon2d.h"
#include <iostream>
gd::String GD_API GetSceneName(RuntimeScene & scene)
{
@@ -208,6 +211,48 @@ bool GD_API PickNearestObject(std::map <gd::String, std::vector<RuntimeObject*>
return true;
}
bool GD_API RaycastObject(std::map <gd::String, std::vector<RuntimeObject*> *> pickedObjectLists, float x, float y, float angle, float dist, gd::Variable & varX, gd::Variable & varY, bool inverted)
{
RuntimeObject * matchObject = NULL;
float testSqDist = inverted ? 0 : dist*dist;
float resultX = 0.0f;
float resultY = 0.0f;
for (auto it = pickedObjectLists.begin(); it != pickedObjectLists.end(); ++it)
{
if ( it->second == NULL ) continue;
auto list = *it->second;
for (std::size_t i = 0; i < list.size(); ++i)
{
RaycastResult result = list[i]->RaycastTest(x, y, angle, dist, !inverted);
if( result.collision ) {
if ( !inverted && (result.closeSqDist <= testSqDist) ) {
testSqDist = result.closeSqDist;
matchObject = list[i];
resultX = result.closePoint.x;
resultY = result.closePoint.y;
}
else if ( inverted && (result.farSqDist >= testSqDist) ) {
testSqDist = result.farSqDist;
matchObject = list[i];
resultX = result.farPoint.x;
resultY = result.farPoint.y;
}
}
}
}
if ( !matchObject )
return false;
PickOnly(pickedObjectLists, matchObject);
varX.SetValue(resultX);
varY.SetValue(resultY);
return true;
}
bool GD_API SceneVariableExists(RuntimeScene & scene, const gd::String & variable)
{
return scene.GetVariables().Has(variable);

View File

@@ -94,6 +94,11 @@ bool GD_API PickRandomObject(RuntimeScene & scene, std::map <gd::String, std::ve
*/
bool GD_API PickNearestObject(std::map <gd::String, std::vector<RuntimeObject*> *> pickedObjectLists, double x, double y, bool inverted);
/**
* Only used internally by GD events generated code.
*/
bool GD_API RaycastObject(std::map <gd::String, std::vector<RuntimeObject*> *> pickedObjectLists, float x, float y, float angle, float dist, gd::Variable & varX, gd::Variable & varY, bool inverted);
/**
* Only used internally by GD events generated code.
*/

View File

@@ -7,6 +7,7 @@
#include "GDCpp/Runtime/Polygon2d.h"
#include <cmath>
#include <cfloat>
#include <algorithm>
namespace
{
@@ -30,6 +31,13 @@ float dotProduct(const sf::Vector2f a, const sf::Vector2f b)
return dp;
}
float crossProduct(const sf::Vector2f a, const sf::Vector2f b)
{
float cp = a.x*b.y - a.y*b.x;
return cp;
}
void project(const sf::Vector2f axis, const Polygon2d & p, float& min, float& max)
{
float dp = dotProduct(axis, p.vertices[0]);
@@ -128,3 +136,109 @@ CollisionResult GD_API PolygonCollisionTest(Polygon2d & p1, Polygon2d & p2)
return result;
}
RaycastResult GD_API PolygonRaycastTest(Polygon2d & poly, float startX, float startY, float endX, float endY)
{
RaycastResult result;
result.collision = false;
if ( poly.vertices.size() < 2 )
{
return result;
}
poly.ComputeEdges();
sf::Vector2f p, q, r, s;
float minSqDist = FLT_MAX;
// Ray segment: p + t*r, with p = start and r = end - start
p.x = startX;
p.y = startY;
r.x = endX - startX;
r.y = endY - startY;
for( int i=0; i<poly.edges.size(); i++ )
{
// Edge segment: q + u*s
q = poly.vertices[i];
s = poly.edges[i];
sf::Vector2f deltaQP = q - p;
float crossRS = crossProduct(r, s);
float t = crossProduct(deltaQP, s) / crossRS;
float u = crossProduct(deltaQP, r) / crossRS;
// Collinear
if ( abs(crossRS) <= 0.0001 && abs(crossProduct(deltaQP, r)) <= 0.0001 )
{
// Project the ray and the edge to work on floats, keeping linearity through t
sf::Vector2f axis(r.x, r.y);
normalise(axis);
float rayA = 0.0f;
float rayB = dotProduct(axis, r);
float edgeA = dotProduct(axis, deltaQP);
float edgeB = dotProduct(axis, deltaQP + s);
// Get overlapping range
float minOverlap = std::max(std::min(rayA, rayB), std::min(edgeA, edgeB));
float maxOverlap = std::min(std::max(rayA, rayB), std::max(edgeA, edgeB));
if( minOverlap > maxOverlap ){
return result;
}
result.collision = true;
// Zero distance ray
if( rayB == 0.0f ){
result.closePoint = p;
result.closeSqDist = 0.0f;
result.farPoint = p;
result.farSqDist = 0.0f;
}
float t1 = minOverlap / abs(rayB);
float t2 = maxOverlap / abs(rayB);
result.closePoint = p + t1*r;
result.closeSqDist = t1*t1*(r.x*r.x + r.y*r.y);
result.farPoint = p + t2*r;
result.farSqDist = t2*t2*(r.x*r.x + r.y*r.y);
return result;
}
else if ( crossRS != 0 && 0<=t && t<=1 && 0<=u && u<=1 )
{
sf::Vector2f point = p + t*r;
float sqDist = (point.x-startX)*(point.x-startX) + (point.y-startY)*(point.y-startY);
if ( sqDist < minSqDist )
{
if ( !result.collision ){
result.farPoint = point;
result.farSqDist = sqDist;
}
minSqDist = sqDist;
result.closePoint = point;
result.closeSqDist = sqDist;
result.collision = true;
}
else
{
result.farPoint = point;
result.farSqDist = sqDist;
}
}
}
return result;
}
bool GD_API IsPointInsidePolygon(Polygon2d & poly, float x, float y)
{
bool inside = false;
sf::Vector2f vi, vj;
for (std::size_t i = 0, j = poly.vertices.size()-1; i < poly.vertices.size(); j = i++)
{
vi = poly.vertices[i];
vj = poly.vertices[j];
if ( ((vi.y>y) != (vj.y>y)) && (x < (vj.x-vi.x) * (y-vi.y) / (vj.y-vi.y) + vi.x) )
inside = !inside;
}
return inside;
}

View File

@@ -19,6 +19,15 @@ struct CollisionResult
sf::Vector2f move_axis;
};
struct RaycastResult
{
bool collision;
sf::Vector2f closePoint;
float closeSqDist;
sf::Vector2f farPoint;
float farSqDist;
};
/**
* Do a collision test between the two polygons.
* \warning Polygons must convexes.
@@ -33,5 +42,27 @@ struct CollisionResult
*/
CollisionResult GD_API PolygonCollisionTest(Polygon2d & p1, Polygon2d & p2);
/**
* Do a raycast test.
* \warning Polygon must be convex.
* For some theory check "Find the Intersection Point of Two Line Segments" (https://www.codeproject.com/Tips/862988/Find-the-Intersection-Point-of-Two-Line-Segments)
*
* \return A raycast result with the contact points and distances
*
* \ingroup GameEngine
*/
RaycastResult GD_API PolygonRaycastTest(Polygon2d & poly, float startX, float startY, float endX, float endY);
/**
* Check if a point is inside a polygon.
*
* Uses PNPOLY by W. Randolph Franklin (https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html)
*
* \return true if the point is inside the polygon
*
* \ingroup GameEngine
*/
bool GD_API IsPointInsidePolygon(Polygon2d & poly, float x, float y);
#endif // POLYGONCOLLISION_H

View File

@@ -4,6 +4,7 @@
* This project is released under the MIT License.
*/
#include <cstring>
#include <cmath>
#include "GDCore/Tools/Localization.h"
#include "GDCpp/Extensions/Builtin/MathematicalTools.h"
#include "GDCpp/Runtime/RuntimeObject.h"
@@ -379,6 +380,54 @@ bool RuntimeObject::IsCollidingWith(RuntimeObject * obj2)
return false;
}
bool RuntimeObject::IsCollidingWithPoint(float pointX, float pointY){
vector<Polygon2d> hitBoxes = GetHitBoxes();
for (std::size_t i = 0; i < hitBoxes.size(); ++i)
{
if ( IsPointInsidePolygon(hitBoxes[i], pointX, pointY) )
return true;
}
return false;
}
RaycastResult RuntimeObject::RaycastTest(float x, float y, float angle, float dist, bool closest){
float objW = GetWidth();
float objH = GetHeight();
float diffX = GetDrawableX()+GetCenterX() - x;
float diffY = GetDrawableY()+GetCenterY() - y;
float boundingRadius = sqrt(objW*objW + objH*objH)/2.0;
RaycastResult result;
result.collision = false;
if ( sqrt(diffX*diffX + diffY*diffY) > boundingRadius + dist )
return result;
float endX = x + dist*cos(angle*3.14159/180.0);
float endY = y + dist*sin(angle*3.14159/180.0);
float testSqDist = closest ? dist*dist : 0.0f;
vector<Polygon2d> hitboxes = GetHitBoxes();
for (std::size_t i = 0; i < hitboxes.size(); ++i)
{
RaycastResult res = PolygonRaycastTest(hitboxes[i], x, y, endX, endY);
if ( res.collision ) {
if ( closest && (res.closeSqDist < testSqDist) ) {
testSqDist = res.closeSqDist;
result = res;
}
else if ( !closest && (res.farSqDist > testSqDist) && (res.farSqDist <= dist*dist) ) {
testSqDist = res.farSqDist;
result = res;
}
}
}
return result;
}
void RuntimeObject::SeparateObjectsWithoutForces( std::map <gd::String, std::vector<RuntimeObject*> *> pickedObjectLists)
{
vector<RuntimeObject*> objects2;

View File

@@ -20,6 +20,7 @@ namespace gd { class InitialInstance; }
namespace gd { class Object; }
namespace sf { class RenderTarget; }
class Polygon2d;
class RaycastResult;
class RuntimeScene;
/**
@@ -223,6 +224,25 @@ public:
*/
bool IsCollidingWith(RuntimeObject * other);
/**
* \brief Check if a point is inside the object collision hitboxes.
* \param pointX The point x coordinate.
* \param pointY The point y coordinate.
* \return true if the point is inside the object collision hitboxes.
*/
bool IsCollidingWithPoint(float pointX, float pointY);
/**
* \brief Check if a ray intersect any object hitbox.
* \param x The raycast source X
* \param y The raycast source Y
* \param angle The raycast angle
* \param dist The raycast max distance
* \param closest Get the closest or farthest collision mask result?
* \return A raycast result with the contact points and distances
*/
RaycastResult RaycastTest(float x, float y, float angle, float dist, bool closest);
/**
* \brief Check collision with each object of the list using their hitboxes, and move the object
* according to the sum of the move vector returned by each collision test.

View File

@@ -450,7 +450,7 @@ bool RuntimeScene::LoadFromSceneAndCustomInstances( const gd::Layout & scene, co
//Behaviors shared data
std::cout << ".";
behaviorsSharedDatas.LoadFrom(scene.behaviorsInitialSharedDatas);
behaviorsSharedDatas.LoadFrom(scene.GetAllBehaviorSharedData());
std::cout << ".";
//Extensions specific initialization

View File

@@ -103,7 +103,7 @@ ELSE()
ELSE()
add_custom_target(GDJS_Runtime
ALL
COMMAND sh "CopyRuntimeToGD.sh" ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME}/JsPlatform/Runtime
COMMAND bash "CopyRuntimeToGD.sh" ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME}/JsPlatform/Runtime
WORKING_DIRECTORY ${GD_base_dir}/GDJS/scripts)
ENDIF()
ENDIF()

View File

@@ -71,6 +71,7 @@ BaseObjectExtension::BaseObjectExtension()
objectConditions["ObjectVariableChildExists"].SetFunctionName("variableChildExists").SetIncludeFile("runtimeobject.js");
objectActions["ObjectVariableRemoveChild"].SetFunctionName("variableRemoveChild").SetIncludeFile("runtimeobject.js");
objectActions["ObjectVariableClearChildren"].SetFunctionName("variableClearChildren").SetIncludeFile("runtimeobject.js");
objectConditions["CollisionPoint"].SetFunctionName("isCollidingWithPoint").SetIncludeFile("runtimeobject.js");
objectExpressions["X"].SetFunctionName("getX");
objectExpressions["Y"].SetFunctionName("getY");
@@ -100,6 +101,7 @@ BaseObjectExtension::BaseObjectExtension()
GetAllConditions()["CollisionNP"]
.AddCodeOnlyParameter("currentScene", "") //We need an extra parameter pointing to the scene.
.SetFunctionName("gdjs.evtTools.object.hitBoxesCollisionTest");
GetAllConditions()["Raycast"].SetFunctionName("gdjs.evtTools.object.raycastObject");
GetAllConditions()["Distance"].SetFunctionName("gdjs.evtTools.object.distanceTest");
GetAllConditions()["SeDirige"].SetFunctionName("gdjs.evtTools.object.movesTowardTest");
GetAllConditions()["EstTourne"].SetFunctionName("gdjs.evtTools.object.turnedTowardTest");

View File

@@ -137,6 +137,8 @@ gd::PlatformExtension * CreateGDJSInventoryExtension();
gd::PlatformExtension * CreateGDJSLinkedObjectsExtension();
gd::PlatformExtension * CreateGDJSSystemInfoExtension();
gd::PlatformExtension * CreateGDJSShopifyExtension();
gd::PlatformExtension * CreateGDJSPathfindingBehaviorExtension();
gd::PlatformExtension * CreateGDJSPhysicsBehaviorExtension();
}
#endif
@@ -183,6 +185,8 @@ JsPlatform::JsPlatform() :
AddExtension(std::shared_ptr<gd::PlatformExtension>(CreateGDJSLinkedObjectsExtension())); std::cout.flush();
AddExtension(std::shared_ptr<gd::PlatformExtension>(CreateGDJSSystemInfoExtension())); std::cout.flush();
AddExtension(std::shared_ptr<gd::PlatformExtension>(CreateGDJSShopifyExtension())); std::cout.flush();
AddExtension(std::shared_ptr<gd::PlatformExtension>(CreateGDJSPathfindingBehaviorExtension())); std::cout.flush();
AddExtension(std::shared_ptr<gd::PlatformExtension>(CreateGDJSPhysicsBehaviorExtension())); std::cout.flush();
#endif
std::cout << "done." << std::endl;
};

View File

@@ -97,8 +97,9 @@ bool Exporter::ExportWholePixiProject(gd::Project & project, gd::String exportDi
bool minify, bool exportForCordova)
{
ExporterHelper helper(fs, gdjsRoot, codeOutputDir);
gd::Project exportedProject = project;
auto exportProject = [this, &project, &minify,
auto exportProject = [this, &exportedProject, &minify,
&exportForCordova, &helper](gd::String exportDir)
{
wxProgressDialog * progressDialogPtr = NULL;
@@ -111,8 +112,6 @@ bool Exporter::ExportWholePixiProject(gd::Project & project, gd::String exportDi
fs.MkDir(exportDir);
std::vector<gd::String> includesFiles;
gd::Project exportedProject = project;
//Export the resources (before generating events as some resources filenames may be updated)
helper.ExportResources(fs, exportedProject, exportDir, progressDialogPtr);
@@ -168,11 +167,12 @@ bool Exporter::ExportWholePixiProject(gd::Project & project, gd::String exportDi
{
//Prepare the export directory
fs.MkDir(exportDir);
if (!helper.ExportCordovaConfigFile(project, exportDir))
return false;
if (!exportProject(exportDir + "/www"))
return false;
if (!helper.ExportCordovaConfigFile(exportedProject, exportDir))
return false;
} else {
if (!exportProject(exportDir))
return false;

View File

@@ -58,9 +58,10 @@ static void GenerateFontsDeclaration(gd::AbstractFileSystem & fs, const gd::Stri
css += urlPrefix + relativeFile;
css +="') format('truetype'); }";
// Use the font for a dummy text to trigger immediate load of the font at game startup
html += "<div style=\"font-family: 'gdjs_font_";
html += relativeFile;
html += "';\">.</div>";
html += "'; color: black;\">.</div>";
}
}
@@ -79,6 +80,9 @@ bool ExporterHelper::ExportLayoutForPixiPreview(gd::Project & project, gd::Layou
gd::Project exportedProject = project;
// Always disable the splash for preview
exportedProject.GetLoadingScreen().ShowGDevelopSplash(false);
//Export resources (*before* generating events as some resources filenames may be updated)
ExportResources(fs, exportedProject, exportDir);
//Generate events code
@@ -156,10 +160,42 @@ bool ExporterHelper::ExportPixiIndexFile(gd::String source, gd::String exportDir
bool ExporterHelper::ExportCordovaConfigFile(const gd::Project & project, gd::String exportDir)
{
auto & platformSpecificAssets = project.GetPlatformSpecificAssets();
auto & resourceManager = project.GetResourcesManager();
auto getIconFilename = [&resourceManager, &platformSpecificAssets](const gd::String & platform, const gd::String & name) {
const gd::String & file = resourceManager.GetResource(platformSpecificAssets.Get(platform, name)).GetFile();
return file.empty() ? "" : "www/" + file;
};
gd::String str = fs.ReadFile(gdjsRoot + "/Runtime/Cordova/config.xml")
.FindAndReplace("GDJS_PROJECTNAME", project.GetName())
.FindAndReplace("GDJS_PACKAGENAME", project.GetPackageName())
.FindAndReplace("GDJS_ORIENTATION", "default");
.FindAndReplace("GDJS_ORIENTATION", project.GetOrientation())
// Android icons
.FindAndReplace("GDJS_ICON_ANDROID_36", getIconFilename("android", "icon-36"))
.FindAndReplace("GDJS_ICON_ANDROID_48", getIconFilename("android", "icon-48"))
.FindAndReplace("GDJS_ICON_ANDROID_72", getIconFilename("android", "icon-72"))
.FindAndReplace("GDJS_ICON_ANDROID_96", getIconFilename("android", "icon-96"))
.FindAndReplace("GDJS_ICON_ANDROID_144", getIconFilename("android", "icon-144"))
.FindAndReplace("GDJS_ICON_ANDROID_192", getIconFilename("android", "icon-192"))
// iOS icons
.FindAndReplace("GDJS_ICON_IOS_180", getIconFilename("ios", "icon-180"))
.FindAndReplace("GDJS_ICON_IOS_60", getIconFilename("ios", "icon-60"))
.FindAndReplace("GDJS_ICON_IOS_120", getIconFilename("ios", "icon-120"))
.FindAndReplace("GDJS_ICON_IOS_76", getIconFilename("ios", "icon-76"))
.FindAndReplace("GDJS_ICON_IOS_152", getIconFilename("ios", "icon-152"))
.FindAndReplace("GDJS_ICON_IOS_40", getIconFilename("ios", "icon-40"))
.FindAndReplace("GDJS_ICON_IOS_80", getIconFilename("ios", "icon-80"))
.FindAndReplace("GDJS_ICON_IOS_57", getIconFilename("ios", "icon-57"))
.FindAndReplace("GDJS_ICON_IOS_114", getIconFilename("ios", "icon-114"))
.FindAndReplace("GDJS_ICON_IOS_72", getIconFilename("ios", "icon-72"))
.FindAndReplace("GDJS_ICON_IOS_144", getIconFilename("ios", "icon-144"))
.FindAndReplace("GDJS_ICON_IOS_167", getIconFilename("ios", "icon-167"))
.FindAndReplace("GDJS_ICON_IOS_29", getIconFilename("ios", "icon-29"))
.FindAndReplace("GDJS_ICON_IOS_58", getIconFilename("ios", "icon-58"))
.FindAndReplace("GDJS_ICON_IOS_50", getIconFilename("ios", "icon-50"))
.FindAndReplace("GDJS_ICON_IOS_100", getIconFilename("ios", "icon-100"))
;
if (!fs.WriteToFile(exportDir + "/config.xml", str))
{
@@ -196,14 +232,14 @@ bool ExporterHelper::ExportCocos2dFiles(const gd::Project & project, gd::String
std::vector<gd::String> noIncludesInThisFile;
if (!CompleteIndexFile(str, customCss, customHtml, exportDir, noIncludesInThisFile, ""))
{
lastError = "Unable to complete Cocos2d index.html file.";
lastError = "Unable to complete Cocos2d-JS index.html file.";
return false;
}
//Write the index.html file
if (!fs.WriteToFile(exportDir + "/index.html", str))
{
lastError = "Unable to write Cocos2d index.html file.";
lastError = "Unable to write Cocos2d-JS index.html file.";
return false;
}
}
@@ -229,7 +265,7 @@ bool ExporterHelper::ExportCocos2dFiles(const gd::Project & project, gd::String
if (!fs.WriteToFile(exportDir + "/project.json", str))
{
lastError = "Unable to write Cocos2d project.json file.";
lastError = "Unable to write Cocos2d-JS project.json file.";
return false;
}
}
@@ -337,6 +373,7 @@ bool ExporterHelper::ExportEventsCode(gd::Project & project, gd::String outputDi
//First, do not forget common includes (they must be included before events generated code files).
InsertUnique(includesFiles, "libs/jshashtable.js");
InsertUnique(includesFiles, "gd.js");
InsertUnique(includesFiles, "gd-splash-image.js");
InsertUnique(includesFiles, "libs/hshg.js");
InsertUnique(includesFiles, "libs/rbush.js");
InsertUnique(includesFiles, "inputmanager.js");

View File

@@ -12,10 +12,47 @@
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
<icon src="GDJS_ICON_ANDROID_36" density="ldpi" />
<icon src="GDJS_ICON_ANDROID_48" density="mdpi" />
<icon src="GDJS_ICON_ANDROID_72" density="hdpi" />
<icon src="GDJS_ICON_ANDROID_96" density="xhdpi" />
<icon src="GDJS_ICON_ANDROID_144" density="xxhdpi" />
<icon src="GDJS_ICON_ANDROID_192" density="xxxhdpi" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
<!-- iOS 8.0+ -->
<!-- iPhone 6 Plus -->
<icon src="GDJS_ICON_IOS_180" width="180" height="180" />
<!-- iOS 7.0+ -->
<!-- iPhone / iPod Touch -->
<icon src="GDJS_ICON_IOS_60" width="60" height="60" />
<icon src="GDJS_ICON_IOS_120" width="120" height="120" />
<!-- iPad -->
<icon src="GDJS_ICON_IOS_76" width="76" height="76" />
<icon src="GDJS_ICON_IOS_152" width="152" height="152" />
<!-- Spotlight Icon -->
<icon src="GDJS_ICON_IOS_40" width="40" height="40" />
<icon src="GDJS_ICON_IOS_80" width="80" height="80" />
<!-- iOS 6.1 -->
<!-- iPhone / iPod Touch -->
<icon src="GDJS_ICON_IOS_57" width="57" height="57" />
<icon src="GDJS_ICON_IOS_114" width="114" height="114" />
<!-- iPad -->
<icon src="GDJS_ICON_IOS_72" width="72" height="72" />
<icon src="GDJS_ICON_IOS_144" width="144" height="144" />
<!-- iPad Pro -->
<icon src="GDJS_ICON_IOS_167" width="167" height="167" />
<!-- iPhone Spotlight and Settings Icon -->
<icon src="GDJS_ICON_IOS_29" width="29" height="29" />
<icon src="GDJS_ICON_IOS_58" width="58" height="58" />
<!-- iPad Spotlight and Settings Icon -->
<icon src="GDJS_ICON_IOS_50" width="50" height="50" />
<icon src="GDJS_ICON_IOS_100" width="100" height="100" />
<!-- iPad Pro -->
<icon src="GDJS_ICON_IOS_167" width="167" height="167" />
</platform>
<preference name="orientation" value="GDJS_ORIENTATION" />
<preference name="BackgroundColor" value="0xff000000"/>
</widget>

View File

@@ -4,7 +4,7 @@
* This project is released under the MIT License.
*/
gdjs.LoadingScreenCocosRenderer = function(runtimeGamePixiRenderer)
gdjs.LoadingScreenCocosRenderer = function(runtimeGamePixiRenderer, loadingScreenSetup)
{
}
@@ -13,3 +13,7 @@ gdjs.LoadingScreenRenderer = gdjs.LoadingScreenCocosRenderer; //Register the cla
gdjs.LoadingScreenCocosRenderer.prototype.render = function(percent) {
console.log("Loading " + percent + "%");
};
gdjs.LoadingScreenCocosRenderer.prototype.unload = function() {
// Nothing to do
};

View File

@@ -100,6 +100,17 @@ gdjs.evtTools.input.keysNameToCode = {
"x": 88,
"y": 89,
"z": 90,
"Num0": 48,
"Num1": 49,
"Num2": 50,
"Num3": 51,
"Num4": 52,
"Num5": 53,
"Num6": 54,
"Num7": 55,
"Num8": 56,
"Num9": 57,
"Numpad0": 96,
"Numpad1": 97,

View File

@@ -316,6 +316,47 @@ gdjs.evtTools.object.pickNearestObject = function(objectsLists, x, y, inverted)
return true;
};
gdjs.evtTools.object.raycastObject = function(objectsLists, x, y, angle, dist, varX, varY, inverted) {
var matchObject = null;
var testSqDist = inverted ? 0 : dist*dist;
var resultX = 0;
var resultY = 0;
var lists = gdjs.staticArray(gdjs.evtTools.object.raycastObject);
objectsLists.values(lists);
for (var i = 0; i < lists.length; i++) {
var list = lists[i];
for (var j = 0; j < list.length; j++) {
var object = list[j];
var result = object.raycastTest(x, y, angle, dist, !inverted);
if( result.collision ) {
if ( !inverted && (result.closeSqDist <= testSqDist) ) {
testSqDist = result.closeSqDist;
matchObject = object;
resultX = result.closeX;
resultY = result.closeY;
}
else if ( inverted && (result.farSqDist >= testSqDist) ) {
testSqDist = result.farSqDist;
matchObject = object;
resultX = result.farX;
resultY = result.farY;
}
}
}
}
if ( !matchObject )
return false;
gdjs.evtTools.object.pickOnly(objectsLists, matchObject);
varX.setNumber(resultX);
varY.setNumber(resultY);
return true;
};
/**
* Do the work of creating a new object
* @private

View File

@@ -108,13 +108,13 @@ gdjs.evtTools.runtimeScene.getTime = function(runtimeScene, what) {
else if ( what === "sec" )
return now.getSeconds();
else if ( what === "mday" )
return now.getdate();
return now.getDate();
else if ( what === "mon" )
return now.getMonth();
else if ( what === "year" )
return now.getFullYear() - 1900; //Conform to the C way of returning years.
else if ( what === "wday" )
return now.getday();
return now.getDay();
else if ( what === "yday" ) {
var start = new Date(now.getFullYear(), 0, 0);
var diff = now - start;

File diff suppressed because one or more lines are too long

View File

@@ -17,7 +17,7 @@ var gdjs = gdjs || {
};
/**
* Convert a rgb color value to a hex value.
* Convert a rgb color value to a hex string.
* @note No "#" or "0x" are added.
* @static
*/
@@ -25,6 +25,14 @@ gdjs.rgbToHex = function(r, g, b) {
return "" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
};
/**
* Convert a rgb color value to a hex value.
* @static
*/
gdjs.rgbToHexNumber = function(r, g, b) {
return (r << 16) + (g << 8) + b;
}
/**
* Get a random integer between 0 and max.
* @method random

View File

@@ -75,6 +75,8 @@ gdjs.HowlerSoundManager = function(resources)
this._resources = resources;
this._availableResources = {}; //Map storing "audio" resources for faster access.
this._globalVolume = 100;
this._sounds = {};
this._musics = {};
this._freeSounds = []; //Sounds without an assigned channel.
@@ -121,7 +123,7 @@ gdjs.HowlerSoundManager = function(resources)
sound.play();
}
}
that._pausedSounds = [];
that._pausedSounds.length = 0;
that._paused = false;
}, false);
});
@@ -203,7 +205,7 @@ gdjs.HowlerSoundManager.prototype.playSound = function(soundName, loop, volume,
gdjs.HowlerSoundManager.prototype.playSoundOnChannel = function(soundName, channel, loop, volume, pitch) {
var oldSound = this._sounds[channel];
if (oldSound) {
oldSound.stop();
oldSound.unload();
}
var soundFile = this._getFileFromSoundName(soundName);
@@ -244,7 +246,7 @@ gdjs.HowlerSoundManager.prototype.playMusic = function(soundName, loop, volume,
gdjs.HowlerSoundManager.prototype.playMusicOnChannel = function(soundName, channel, loop, volume, pitch) {
var oldMusic = this._musics[channel];
if (oldMusic) {
oldMusic.stop();
oldMusic.unload();
}
var soundFile = this._getFileFromSoundName(soundName);
@@ -268,41 +270,43 @@ gdjs.HowlerSoundManager.prototype.getMusicOnChannel = function(channel) {
};
gdjs.HowlerSoundManager.prototype.setGlobalVolume = function(volume) {
Howler.volume(volume/100);
this._globalVolume = volume;
if (this._globalVolume > 100) this._globalVolume = 100;
if (this._globalVolume < 0) this._globalVolume = 0;
Howler.volume(this._globalVolume/100);
};
gdjs.HowlerSoundManager.prototype.getGlobalVolume = function() {
return Howler.volume()*100;
return this._globalVolume;
};
gdjs.HowlerSoundManager.prototype.clearAll = function() {
for (var i = 0;i<this._freeSounds.length;++i) {
if (this._freeSounds[i]) this._freeSounds[i].stop();
if (this._freeSounds[i]) this._freeSounds[i].unload();
}
for (var i = 0;i<this._freeMusics.length;++i) {
if (this._freeMusics[i]) this._freeMusics[i].stop();
if (this._freeMusics[i]) this._freeMusics[i].unload();
}
this._freeSounds.length = 0;
this._freeMusics.length = 0;
for (var p in this._sounds) {
if (this._sounds.hasOwnProperty(p) && this._sounds[p]) {
this._sounds[p].stop();
this._sounds[p].unload();
delete this._sounds[p];
}
}
for (var p in this._musics) {
if (this._musics.hasOwnProperty(p) && this._musics[p]) {
this._musics[p].stop();
this._musics[p].unload();
delete this._musics[p];
}
}
this._pausedSounds = [];
this._pausedSounds.length = 0;
}
gdjs.HowlerSoundManager.prototype.preloadAudio = function(onProgress, onComplete, resources) {
resources = resources || this._resources;
var files = [];
for(var i = 0, len = resources.length;i<len;++i) {
var res = resources[i];
@@ -319,10 +323,8 @@ gdjs.HowlerSoundManager.prototype.preloadAudio = function(onProgress, onComplete
var loaded = 0;
function onLoad(audioFile) {
console.log("loaded" + audioFile);
loaded++;
if (loaded === files.length) {
console.log("All audio loaded");
return onComplete();
}
@@ -332,13 +334,12 @@ gdjs.HowlerSoundManager.prototype.preloadAudio = function(onProgress, onComplete
var that = this;
for(var i = 0;i<files.length;++i) {
(function(audioFile) {
console.log("Loading" + audioFile)
var sound = new Howl({
src: [audioFile], //TODO: ogg, mp3...
preload: true,
onload: onLoad.bind(that, audioFile),
onloaderror: onLoad.bind(that, audioFile)
});
var sound = new XMLHttpRequest();
sound.addEventListener('load', onLoad.bind(that, audioFile));
sound.addEventListener('error', onLoad.bind(that, audioFile));
sound.addEventListener('abort', onLoad.bind(that, audioFile));
sound.open('GET', audioFile);
sound.send();
})(files[i]);
}
}

File diff suppressed because one or more lines are too long

View File

@@ -2,6 +2,13 @@
<html>
<head>
<meta charset="UTF-8"/>
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="theme-color" content="#000000" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<style>
body {
margin: 0;

View File

@@ -1,6 +1,7 @@
gdjs.LayerPixiRenderer = function(layer, runtimeSceneRenderer)
{
this._pixiContainer = new PIXI.Container();
this._filters = {};
this._layer = layer;
runtimeSceneRenderer.getPIXIContainer().addChild(this._pixiContainer);

View File

@@ -1,16 +1,70 @@
gdjs.LoadingScreenPixiRenderer = function(runtimeGamePixiRenderer)
{
this._pixiRenderer = runtimeGamePixiRenderer.getPIXIRenderer();
this._loadingScreen = new PIXI.Container();
this._text = new PIXI.Text(" ", {font: "bold 60px Arial", fill: "#FFFFFF", align: "center"});
this._loadingScreen.addChild(this._text);
this._text.position.y = this._pixiRenderer.height/2;
}
gdjs.LoadingScreenPixiRenderer = function(runtimeGamePixiRenderer, loadingScreenSetup) {
this._pixiRenderer = runtimeGamePixiRenderer.getPIXIRenderer();
this._loadingScreen = new PIXI.Container();
this._progressText = new PIXI.Text(' ', {
font: '30px Arial',
fill: '#FFFFFF',
align: 'center',
});
this._loadingScreen.addChild(this._progressText);
if (loadingScreenSetup && loadingScreenSetup.showGDevelopSplash) {
this._madeWithText = new PIXI.Text('Made with', {
font: '30px Arial',
fill: '#FFFFFF',
align: 'center',
});
this._madeWithText.position.y = this._pixiRenderer.height / 2 - 130;
this._websiteText = new PIXI.Text('gdevelop-app.com', {
font: '30px Arial',
fill: '#FFFFFF',
align: 'center',
});
this._websiteText.position.y = this._pixiRenderer.height / 2 + 100;
this._splashImage = new PIXI.Sprite.fromImage(gdjs.splashImage);
this._splashImage.position.x = this._pixiRenderer.width / 2;
this._splashImage.position.y = this._pixiRenderer.height / 2;
this._splashImage.anchor.x = 0.5;
this._splashImage.anchor.y = 0.5;
this._splashImage.scale.x = this._pixiRenderer.width / 800;
this._splashImage.scale.y = this._pixiRenderer.width / 800;
this._loadingScreen.addChild(this._splashImage);
this._loadingScreen.addChild(this._madeWithText);
this._loadingScreen.addChild(this._websiteText);
}
};
gdjs.LoadingScreenRenderer = gdjs.LoadingScreenPixiRenderer; //Register the class to let the engine use it.
gdjs.LoadingScreenPixiRenderer.prototype.render = function(percent) {
this._text.text = percent + "%";
this._text.position.x = this._pixiRenderer.width/2 - this._text.width/2;
this._pixiRenderer.render(this._loadingScreen);
var screenBorder = 10;
if (this._madeWithText) {
this._madeWithText.position.x =
this._pixiRenderer.width / 2 - this._madeWithText.width / 2;
this._madeWithText.position.y =
this._pixiRenderer.height / 2 -
this._splashImage.height / 2 -
this._madeWithText.height -
20;
}
if (this._websiteText) {
this._websiteText.position.x =
this._pixiRenderer.width - this._websiteText.width - screenBorder;
this._websiteText.position.y =
this._pixiRenderer.height - this._websiteText.height - screenBorder;
}
this._progressText.text = percent + '%';
this._progressText.position.x = screenBorder;
this._progressText.position.y =
this._pixiRenderer.height - this._progressText.height - screenBorder;
this._pixiRenderer.render(this._loadingScreen);
};
gdjs.LoadingScreenPixiRenderer.prototype.unload = function() {
// Nothing to do
};

View File

@@ -22,13 +22,13 @@ gdjs.NightPixiFilter = function() {
opacity: { type: '1f', value: 1 }
};
PIXI.AbstractFilter.call(this,
PIXI.Filter.call(this,
vertexShader,
fragmentShader,
uniforms
);
}
gdjs.NightPixiFilter.prototype = Object.create(PIXI.AbstractFilter.prototype);
gdjs.NightPixiFilter.prototype = Object.create(PIXI.Filter.prototype);
gdjs.NightPixiFilter.prototype.constructor = gdjs.NightPixiFilter;
gdjs.LightNightPixiFilter = function() {
@@ -51,13 +51,13 @@ gdjs.LightNightPixiFilter = function() {
opacity: { type: '1f', value: 1 }
};
PIXI.AbstractFilter.call(this,
PIXI.Filter.call(this,
vertexShader,
fragmentShader,
uniforms
);
}
gdjs.LightNightPixiFilter.prototype = Object.create(PIXI.AbstractFilter.prototype);
gdjs.LightNightPixiFilter.prototype = Object.create(PIXI.Filter.prototype);
gdjs.LightNightPixiFilter.prototype.constructor = gdjs.LightNightPixiFilter;
gdjs.PixiFiltersTools._filters = {
@@ -70,7 +70,7 @@ gdjs.PixiFiltersTools._filters = {
if (parameterName !== 'intensity' &&
parameterName !== 'opacity') return;
filter.uniforms[parameterName].value = value;
filter.uniforms[parameterName] = value;
},
},
LightNight: {
@@ -81,17 +81,19 @@ gdjs.PixiFiltersTools._filters = {
updateParameter: function(filter, parameterName, value) {
if (parameterName !== 'opacity') return;
filter.uniforms.opacity.value = value;
filter.uniforms.opacity = value;
},
},
Sepia: {
makeFilter: function() {
return new PIXI.filters.SepiaFilter();
var colorMatrix = new PIXI.filters.ColorMatrixFilter();
colorMatrix.sepia();
return colorMatrix;
},
updateParameter: function(filter, parameterName, value) {
if (parameterName !== 'opacity') return;
filter.sepia = value;
filter.alpha = value;
},
},
};

File diff suppressed because one or more lines are too long

View File

@@ -219,6 +219,146 @@ gdjs.Polygon.collisionTest._statics = {
}
};
/**
* Do a raycast test.<br>
* Please note that the polygon must be <b>convex</b>!
* For some theory, check <a href="https://www.codeproject.com/Tips/862988/Find-the-Intersection-Point-of-Two-Line-Segments">Find the Intersection Point of Two Line Segments</a>
*
* @method raycastTest
* @static
* @param poly {Polygon} The polygon to test
* @param startX {Number} The raycast start point X
* @param startY {Number} The raycast start point Y
* @param endX {Number} The raycast end point X
* @param endY {Number} The raycast end point Y
* @return A raycast result with the contact points and distances
*/
gdjs.Polygon.raycastTest = function(poly, startX, startY, endX, endY)
{
var result = gdjs.Polygon.raycastTest._statics.result;
result.collision = false;
if ( poly.vertices.length < 2 )
{
return result;
}
poly.computeEdges();
var p = gdjs.Polygon.raycastTest._statics.p;
var q = gdjs.Polygon.raycastTest._statics.q;
var r = gdjs.Polygon.raycastTest._statics.r;
var s = gdjs.Polygon.raycastTest._statics.s;
var minSqDist = Number.MAX_VALUE;
// Ray segment: p + t*r, with p = start and r = end - start
p[0] = startX;
p[1] = startY;
r[0] = endX - startX;
r[1] = endY - startY;
for(var i=0; i<poly.edges.length; i++)
{
// Edge segment: q + u*s
q[0] = poly.vertices[i][0];
q[1] = poly.vertices[i][1];
s[0] = poly.edges[i][0];
s[1] = poly.edges[i][1];
var deltaQP = gdjs.Polygon.raycastTest._statics.deltaQP;
deltaQP[0] = q[0] - p[0];
deltaQP[1] = q[1] - p[1];
var crossRS = gdjs.Polygon.crossProduct(r, s);
var t = gdjs.Polygon.crossProduct(deltaQP, s) / crossRS;
var u = gdjs.Polygon.crossProduct(deltaQP, r) / crossRS;
// Collinear
if ( Math.abs(crossRS) <= 0.0001 && Math.abs(gdjs.Polygon.crossProduct(deltaQP, r)) <= 0.0001 )
{
// Project the ray and the edge to work on floats, keeping linearity through t
var axis = gdjs.Polygon.raycastTest._statics.axis;
axis[0] = r[0];
axis[1] = r[1];
gdjs.Polygon.normalise(axis);
var rayA = 0;
var rayB = gdjs.Polygon.dotProduct(axis, r);
var edgeA = gdjs.Polygon.dotProduct(axis, deltaQP);
var edgeB = gdjs.Polygon.dotProduct(axis, [deltaQP[0] + s[0], deltaQP[1] + s[1]]);
// Get overlapping range
var minOverlap = Math.max(Math.min(rayA, rayB), Math.min(edgeA, edgeB));
var maxOverlap = Math.min(Math.max(rayA, rayB), Math.max(edgeA, edgeB));
if( minOverlap > maxOverlap ){
return result;
}
result.collision = true;
// Zero distance ray
if( rayB === 0 ){
result.closeX = startX;
result.closeY = startY;
result.closeSqDist = 0;
result.farX = startX;
result.farY = startY;
result.farSqDist = 0;
}
var t1 = minOverlap / Math.abs(rayB);
var t2 = maxOverlap / Math.abs(rayB);
result.closeX = startX + t1*r[0];
result.closeY = startY + t1*r[1];
result.closeSqDist = t1*t1*(r[0]*r[0] + r[1]*r[1]);
result.farX = startX + t2*r[0];
result.farY = startY + t2*r[1];
result.farSqDist = t2*t2*(r[0]*r[0] + r[1]*r[1]);
return result;
}
// One point intersection
else if ( crossRS !== 0 && 0<=t && t<=1 && 0<=u && u<=1 )
{
var x = p[0] + t*r[0];
var y = p[1] + t*r[1];
var sqDist = (x-startX)*(x-startX) + (y-startY)*(y-startY);
if ( sqDist < minSqDist )
{
if ( !result.collision ){
result.farX = x;
result.farY = y;
result.farSqDist = sqDist;
}
minSqDist = sqDist;
result.closeX = x;
result.closeY = y;
result.closeSqDist = sqDist;
result.collision = true;
}
else
{
result.farX = x;
result.farY = y;
result.farSqDist = sqDist;
}
}
}
return result;
};
gdjs.Polygon.raycastTest._statics = {
p: [0,0],
q: [0,0],
r: [0,0],
s: [0,0],
deltaQP: [0,0],
axis: [0,0],
result: {
collision: false,
closeX: 0,
closeY: 0,
closeSqDist: 0,
farX: 0,
farY: 0,
farSqDist: 0
}
}
//Tools functions :
gdjs.Polygon.normalise = function(v)
{
@@ -237,6 +377,13 @@ gdjs.Polygon.dotProduct = function(a, b)
return dp;
}
gdjs.Polygon.crossProduct = function(a, b)
{
var cp = a[0]*b[1] - a[1]*b[0];
return cp;
}
gdjs.Polygon.project = function(axis, p, result)
{
var dp = gdjs.Polygon.dotProduct(axis, p.vertices[0]);
@@ -258,3 +405,29 @@ gdjs.Polygon.distance = function(minA, maxA, minB, maxB)
if (minA < minB) return minB - maxA;
else return minA - maxB;
}
/**
* Check if a point is inside a polygon.
*
* Uses <a href="https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html">PNPOLY</a> by W. Randolph Franklin.
*
* @method isPointInside
* @static
* @param poly {Polygon} The polygon to test
* @param x {Number} The point x coordinate
* @param y {Number} The point y coordinate
* @return {Boolean} true if the point is inside the polygon
*/
gdjs.Polygon.isPointInside = function(poly, x, y)
{
var inside = false;
var vi, vj;
for (var i = 0, j = poly.vertices.length-1; i < poly.vertices.length; j = i++) {
vi = poly.vertices[i];
vj = poly.vertices[j];
if ( ((vi[1]>y) != (vj[1]>y)) && (x < (vj[0]-vi[0]) * (y-vi[1]) / (vj[1]-vi[1]) + vi[0]) )
inside = !inside;
}
return inside;
};

View File

@@ -13,38 +13,44 @@
* @param data The object (usually stored in data.json) containing the full project data
* @param spec Optional object for specifiying additional options: {forceFullscreen: ...}
*/
gdjs.RuntimeGame = function(data, spec)
{
spec = spec || {};
gdjs.RuntimeGame = function(data, spec) {
spec = spec || {};
this._variables = new gdjs.VariablesContainer(data.variables);
this._data = data;
this._imageManager = new gdjs.ImageManager(data.resources ? data.resources.resources : undefined);
this._soundManager = new gdjs.SoundManager(data.resources ? data.resources.resources : undefined);
this._minFPS = data ? parseInt(data.properties.minFPS, 10) : 15;
this._variables = new gdjs.VariablesContainer(data.variables);
this._data = data;
this._imageManager = new gdjs.ImageManager(
data.resources ? data.resources.resources : undefined
);
this._soundManager = new gdjs.SoundManager(
data.resources ? data.resources.resources : undefined
);
this._minFPS = data ? parseInt(data.properties.minFPS, 10) : 15;
this._defaultWidth = data.properties.windowWidth; //Default size for scenes cameras
this._defaultHeight = data.properties.windowHeight;
this._originalWidth = data.properties.windowWidth; //Original size of the game, won't be changed.
this._originalHeight = data.properties.windowHeight;
this._renderer = new gdjs.RuntimeGameRenderer(this,
this._defaultWidth, this._defaultHeight,
spec.forceFullscreen || false);
this._defaultWidth = data.properties.windowWidth; //Default size for scenes cameras
this._defaultHeight = data.properties.windowHeight;
this._originalWidth = data.properties.windowWidth; //Original size of the game, won't be changed.
this._originalHeight = data.properties.windowHeight;
this._renderer = new gdjs.RuntimeGameRenderer(
this,
this._defaultWidth,
this._defaultHeight,
spec.forceFullscreen || false
);
//Game loop management (see startGameLoop method)
this._sceneStack = new gdjs.SceneStack(this);
this._notifySceneForResize = false; //When set to true, the current scene is notified that canvas size changed.
//Game loop management (see startGameLoop method)
this._sceneStack = new gdjs.SceneStack(this);
this._notifySceneForResize = false; //When set to true, the current scene is notified that canvas size changed.
//Inputs :
this._inputManager = new gdjs.InputManager();
//Inputs :
this._inputManager = new gdjs.InputManager();
//Allow to specify an external layout to insert in the first scene:
this._injectExternalLayout = spec.injectExternalLayout || "";
//Allow to specify an external layout to insert in the first scene:
this._injectExternalLayout = spec.injectExternalLayout || '';
};
gdjs.RuntimeGame.prototype.getRenderer = function() {
return this._renderer;
}
return this._renderer;
};
/**
* Get the variables of the RuntimeGame.
@@ -52,7 +58,7 @@ gdjs.RuntimeGame.prototype.getRenderer = function() {
* @return a variablesContainer object.
*/
gdjs.RuntimeGame.prototype.getVariables = function() {
return this._variables;
return this._variables;
};
/**
@@ -61,7 +67,7 @@ gdjs.RuntimeGame.prototype.getVariables = function() {
* @return {gdjs.SoundManager} The sound manager.
*/
gdjs.RuntimeGame.prototype.getSoundManager = function() {
return this._soundManager;
return this._soundManager;
};
/**
@@ -70,7 +76,7 @@ gdjs.RuntimeGame.prototype.getSoundManager = function() {
* @return {gdjs.ImageManager} The image manager.
*/
gdjs.RuntimeGame.prototype.getImageManager = function() {
return this._imageManager;
return this._imageManager;
};
/**
@@ -79,7 +85,7 @@ gdjs.RuntimeGame.prototype.getImageManager = function() {
* @return The input manager owned by the game
*/
gdjs.RuntimeGame.prototype.getInputManager = function() {
return this._inputManager;
return this._inputManager;
};
/**
@@ -88,7 +94,7 @@ gdjs.RuntimeGame.prototype.getInputManager = function() {
* @return The object associated to the game.
*/
gdjs.RuntimeGame.prototype.getGameData = function() {
return this._data;
return this._data;
};
/**
@@ -99,20 +105,20 @@ gdjs.RuntimeGame.prototype.getGameData = function() {
* @return The data associated to the scene.
*/
gdjs.RuntimeGame.prototype.getSceneData = function(sceneName) {
var scene = undefined;
for(var i = 0, len = this._data.layouts.length;i<len;++i) {
var sceneData = this._data.layouts[i];
var scene = undefined;
for (var i = 0, len = this._data.layouts.length; i < len; ++i) {
var sceneData = this._data.layouts[i];
if ( sceneName === undefined || sceneData.name === sceneName ) {
scene = sceneData;
break;
}
}
if (sceneName === undefined || sceneData.name === sceneName) {
scene = sceneData;
break;
}
}
if ( scene === undefined )
console.warn("The game has no scene called \""+sceneName+"\"");
if (scene === undefined)
console.warn('The game has no scene called "' + sceneName + '"');
return scene;
return scene;
};
/**
@@ -123,17 +129,17 @@ gdjs.RuntimeGame.prototype.getSceneData = function(sceneName) {
* @return true if the scene exists. If sceneName is undefined, true if the game has a scene.
*/
gdjs.RuntimeGame.prototype.hasScene = function(sceneName) {
var isTrue = false;
for(var i = 0, len = this._data.layouts.length;i<len;++i) {
var sceneData = this._data.layouts[i];
var isTrue = false;
for (var i = 0, len = this._data.layouts.length; i < len; ++i) {
var sceneData = this._data.layouts[i];
if ( sceneName === undefined || sceneData.name == sceneName ) {
isTrue = true;
break;
}
}
if (sceneName === undefined || sceneData.name == sceneName) {
isTrue = true;
break;
}
}
return isTrue;
return isTrue;
};
/**
@@ -144,17 +150,17 @@ gdjs.RuntimeGame.prototype.hasScene = function(sceneName) {
* @return The data associated to the external layout or null if not found.
*/
gdjs.RuntimeGame.prototype.getExternalLayoutData = function(name) {
var externalLayout = null;
for(var i = 0, len = this._data.externalLayouts.length;i<len;++i) {
var layoutData = this._data.externalLayouts[i];
var externalLayout = null;
for (var i = 0, len = this._data.externalLayouts.length; i < len; ++i) {
var layoutData = this._data.externalLayouts[i];
if ( layoutData.name === name ) {
externalLayout = layoutData;
break;
}
if (layoutData.name === name) {
externalLayout = layoutData;
break;
}
}
return externalLayout;
return externalLayout;
};
/**
@@ -163,7 +169,7 @@ gdjs.RuntimeGame.prototype.getExternalLayoutData = function(name) {
* @return The data associated to the global objects.
*/
gdjs.RuntimeGame.prototype.getInitialObjectsData = function() {
return this._data.objects || [];
return this._data.objects || [];
};
/**
@@ -173,7 +179,7 @@ gdjs.RuntimeGame.prototype.getInitialObjectsData = function() {
* @method getOriginalWidth
*/
gdjs.RuntimeGame.prototype.getOriginalWidth = function() {
return this._originalWidth;
return this._originalWidth;
};
/**
@@ -183,7 +189,7 @@ gdjs.RuntimeGame.prototype.getOriginalWidth = function() {
* @method getOriginalHeight
*/
gdjs.RuntimeGame.prototype.getOriginalHeight = function() {
return this._originalHeight;
return this._originalHeight;
};
/**
@@ -192,7 +198,7 @@ gdjs.RuntimeGame.prototype.getOriginalHeight = function() {
* @method getDefaultWidth
*/
gdjs.RuntimeGame.prototype.getDefaultWidth = function() {
return this._defaultWidth;
return this._defaultWidth;
};
/**
@@ -201,7 +207,7 @@ gdjs.RuntimeGame.prototype.getDefaultWidth = function() {
* @method getDefaultHeight
*/
gdjs.RuntimeGame.prototype.getDefaultHeight = function() {
return this._defaultHeight;
return this._defaultHeight;
};
/**
@@ -211,7 +217,7 @@ gdjs.RuntimeGame.prototype.getDefaultHeight = function() {
* @param width {Number} The new default width
*/
gdjs.RuntimeGame.prototype.setDefaultWidth = function(width) {
this._defaultWidth = width;
this._defaultWidth = width;
};
/**
@@ -221,7 +227,7 @@ gdjs.RuntimeGame.prototype.setDefaultWidth = function(width) {
* @param height {Number} The new default height
*/
gdjs.RuntimeGame.prototype.setDefaultHeight = function(height) {
this._defaultHeight = height;
this._defaultHeight = height;
};
/**
@@ -230,7 +236,7 @@ gdjs.RuntimeGame.prototype.setDefaultHeight = function(height) {
* @method getMinimalFramerate
*/
gdjs.RuntimeGame.prototype.getMinimalFramerate = function() {
return this._minFPS;
return this._minFPS;
};
/**
@@ -238,60 +244,73 @@ gdjs.RuntimeGame.prototype.getMinimalFramerate = function() {
* @method loadAllAssets
*/
gdjs.RuntimeGame.prototype.loadAllAssets = function(callback) {
var loadingScreen = new gdjs.LoadingScreenRenderer(this.getRenderer());
var allAssetsTotal = this._data.resources.resources.length;
var loadingScreen = new gdjs.LoadingScreenRenderer(
this.getRenderer(),
this._data.properties.loadingScreen
);
var allAssetsTotal = this._data.resources.resources.length;
var that = this;
this._imageManager.loadTextures(function (count, total) {
loadingScreen.render(Math.floor(count / allAssetsTotal * 100));
}, function() {
that._soundManager.preloadAudio(function (count, total) {
loadingScreen.render(Math.floor((allAssetsTotal - total + count)
/ allAssetsTotal * 100));
}, function() {
callback();
});
});
var that = this;
this._imageManager.loadTextures(
function(count, total) {
loadingScreen.render(Math.floor(count / allAssetsTotal * 100));
},
function() {
that._soundManager.preloadAudio(
function(count, total) {
loadingScreen.render(
Math.floor((allAssetsTotal - total + count) / allAssetsTotal * 100)
);
},
function() {
loadingScreen.unload();
callback();
}
);
}
);
};
gdjs.RuntimeGame.prototype.startGameLoop = function() {
if ( !this.hasScene() ) {
console.log("The game has no scene.");
return;
if (!this.hasScene()) {
console.log('The game has no scene.');
return;
}
//Load the first scene
var firstSceneName = gdjs.projectData.firstLayout;
this._sceneStack.push(
this.hasScene(firstSceneName) ? firstSceneName : this.getSceneData().name,
this._injectExternalLayout
);
//Uncomment to profile the first x frames of the game.
// var x = 500;
// var startTime = Date.now();
// console.profile("Stepping for " + x + " frames")
// for(var i = 0; i < x; ++i) {
// this._sceneStack.step(16);
// }
// console.profileEnd();
// var time = Date.now() - startTime;
// console.log("Took", time, "ms");
// return;
//The standard game loop
var that = this;
this._renderer.startGameLoop(function(elapsedTime) {
//Manage resize events.
if (that._notifySceneForResize) {
that._sceneStack.onRendererResized();
that._notifySceneForResize = false;
}
//Load the first scene
var firstSceneName = gdjs.projectData.firstLayout;
this._sceneStack.push(this.hasScene(firstSceneName) ? firstSceneName : this.getSceneData().name,
this._injectExternalLayout);
//Render and step the scene.
if (that._sceneStack.step(elapsedTime)) {
that.getInputManager().onFrameEnded();
return true;
}
//Uncomment to profile the first x frames of the game.
// var x = 500;
// var startTime = Date.now();
// console.profile("Stepping for " + x + " frames")
// for(var i = 0; i < x; ++i) {
// this._sceneStack.step(16);
// }
// console.profileEnd();
// var time = Date.now() - startTime;
// console.log("Took", time, "ms");
// return;
//The standard game loop
var that = this;
this._renderer.startGameLoop(function(elapsedTime) {
//Manage resize events.
if (that._notifySceneForResize) {
that._sceneStack.onRendererResized();
that._notifySceneForResize = false;
}
//Render and step the scene.
if (that._sceneStack.step(elapsedTime)) {
that.getInputManager().onFrameEnded();
return true;
}
return false;
});
return false;
});
};

View File

@@ -1151,12 +1151,47 @@ gdjs.RuntimeObject.collisionTest = function(obj1, obj2) {
};
/**
* Check the distance between two objects.
* @method distanceTest
* @static
* @method raycastTest
* @param x {Number} The raycast source X
* @param y {Number} The raycast source Y
* @param angle {Number} The raycast angle
* @param dist {Number} The raycast max distance
* @param closest {Boolean} Get the closest or farthest collision mask result?
* @return A raycast result with the contact points and distances
*/
gdjs.RuntimeObject.distanceTest = function(obj1, obj2, distance) {
return obj1.getSqDistanceToObject(obj2) <= distance;
gdjs.RuntimeObject.prototype.raycastTest = function(x, y, angle, dist, closest) {
var objW = this.getWidth();
var objH = this.getHeight();
var diffX = this.getDrawableX()+this.getCenterX() - x;
var diffY = this.getDrawableY()+this.getCenterY() - y;
var boundingRadius = Math.sqrt(objW*objW + objH*objH)/2.0;
var result = gdjs.Polygon.raycastTest._statics.result;
result.collision = false;
if ( Math.sqrt(diffX*diffX + diffY*diffY) > boundingRadius + dist )
return result;
var endX = x + dist*Math.cos(angle*Math.PI/180.0);
var endY = y + dist*Math.sin(angle*Math.PI/180.0);
var testSqDist = closest ? dist*dist : 0;
var hitBoxes = this.getHitBoxes();
for (var i=0; i<hitBoxes.length; i++) {
var res = gdjs.Polygon.raycastTest(hitBoxes[i], x, y, endX, endY);
if ( res.collision ) {
if ( closest && (res.closeSqDist < testSqDist) ) {
testSqDist = res.closeSqDist;
result = res;
}
else if ( !closest && (res.farSqDist > testSqDist) && (res.farSqDist <= dist*dist) ) {
testSqDist = res.farSqDist;
result = res;
}
}
}
return result;
};
/**
@@ -1174,6 +1209,15 @@ gdjs.RuntimeObject.prototype.insideObject = function(x, y) {
&& this.getDrawableY() + this.getHeight() >= y;
}
/**
* Check the distance between two objects.
* @method distanceTest
* @static
*/
gdjs.RuntimeObject.distanceTest = function(obj1, obj2, distance) {
return obj1.getSqDistanceToObject(obj2) <= distance;
};
/**
* Return true if the cursor, or any touch, is on the object.
*
@@ -1202,6 +1246,23 @@ gdjs.RuntimeObject.prototype.cursorOnObject = function(runtimeScene) {
return false;
};
/**
* \brief Check if a point is inside the object collision hitboxes.
* @method isCollidingWithPoint
* @param pointX The point x coordinate.
* @param pointY The point y coordinate.
* @return true if the point is inside the object collision hitboxes.
*/
gdjs.RuntimeObject.prototype.isCollidingWithPoint = function(pointX, pointY) {
var hitBoxes = this.getHitBoxes();
for(var i = 0; i < this.hitBoxes.length; ++i) {
if ( gdjs.Polygon.isPointInside(hitBoxes[i], pointX, pointY) )
return true;
}
return false;
}
/**
* Get the identifier associated to an object name :<br>

View File

@@ -146,6 +146,27 @@ gdjs.RuntimeScene.prototype.unloadScene = function() {
for(var i = 0;i < gdjs.callbacksRuntimeSceneUnloaded.length;++i) {
gdjs.callbacksRuntimeSceneUnloaded[i](this);
}
// It should not be necessary to reset these variables, but this help
// ensuring that all memory related to the RuntimeScene is released immediately.
this._layers = new Hashtable();
this._variables = new gdjs.VariablesContainer();
this._initialBehaviorSharedData = new Hashtable();
this._objects = new Hashtable();
this._instances = new Hashtable();
this._instancesCache = new Hashtable();
this._initialObjectsData = null;
this._eventsFunction = null;
this._objectsCtor = new Hashtable();
this._allInstancesList = [];
this._instancesRemoved = [];
this._lastId = 0;
this._eventsContext = null;
this._isLoaded = false;
this.onCanvasResized();
};
/**

View File

@@ -1,3 +1,4 @@
#!/bin/bash
#Get the destination, or copy by default to release directory
DESTINATION=../../Binaries/Output/Release_Linux/JsPlatform/Runtime/
if [ "$(uname)" == "Darwin" ]; then
@@ -14,4 +15,4 @@ mkdir -p "$DESTINATION"
cp -R ../Runtime/* "$DESTINATION"
rsync -r -u --include=*.js --include=*/ --exclude=* ../../Extensions/ "$DESTINATION"/Extensions/
echo "✅ Copied GDJS and extensions runtime files (*.js) to '$DESTINATION'."
echo "✅ Copied GDJS and extensions runtime files (*.js) to '$DESTINATION'."

View File

@@ -0,0 +1,606 @@
<?xml version="1.0" encoding="UTF-8" ?>
<project firstLayout="">
<gdVersion build="96" major="4" minor="0" revision="140" />
<properties folderProject="false" linuxExecutableFilename="" macExecutableFilename="" packageName="com.example.gamename" projectFile="C:\Users\Maciel\Programacion\gits\GD\GDJS\tests\games\Raycast.gdg" useExternalSourceFiles="false" winExecutableFilename="" winExecutableIconFile="">
<name>Project</name>
<author></author>
<windowWidth>800</windowWidth>
<windowHeight>600</windowHeight>
<latestCompilationDirectory></latestCompilationDirectory>
<maxFPS>60</maxFPS>
<minFPS>10</minFPS>
<verticalSync>false</verticalSync>
<extensions>
<extension name="BuiltinObject" />
<extension name="BuiltinAudio" />
<extension name="BuiltinVariables" />
<extension name="BuiltinTime" />
<extension name="BuiltinMouse" />
<extension name="BuiltinKeyboard" />
<extension name="BuiltinJoystick" />
<extension name="BuiltinCamera" />
<extension name="BuiltinWindow" />
<extension name="BuiltinFile" />
<extension name="BuiltinNetwork" />
<extension name="BuiltinScene" />
<extension name="BuiltinAdvanced" />
<extension name="Sprite" />
<extension name="BuiltinCommonInstructions" />
<extension name="BuiltinCommonConversions" />
<extension name="BuiltinStringInstructions" />
<extension name="BuiltinMathematicalTools" />
<extension name="BuiltinExternalLayouts" />
<extension name="PrimitiveDrawing" />
</extensions>
<platforms>
<platform name="GDevelop JS platform" />
<platform name="GDevelop C++ platform" />
</platforms>
<currentPlatform>GDevelop JS platform</currentPlatform>
</properties>
<resources>
<resources>
<resource alwaysLoaded="false" file="Grass.png" kind="image" name="Grass.png" smoothed="true" userAdded="true" />
<resource alwaysLoaded="false" file="spship2.png" kind="image" name="spship2.png" smoothed="true" userAdded="false" />
<resource alwaysLoaded="false" file="Shape1.png" kind="image" name="Shape1.png" smoothed="true" userAdded="false" />
<resource alwaysLoaded="false" file="Pea-Happy.png" kind="image" name="Pea-Happy.png" smoothed="true" userAdded="false" />
</resources>
<resourceFolders />
</resources>
<objects />
<objectsGroups />
<variables />
<layouts>
<layout b="30" disableInputWhenNotFocused="true" mangledName="Scene" name="Scene" oglFOV="90.000000" oglZFar="500.000000" oglZNear="1.000000" r="30" standardSortMethod="false" stopSoundsOnStartup="true" title="" v="30">
<uiSettings grid="false" gridB="80" gridG="80" gridHeight="70" gridOffsetX="0" gridOffsetY="20" gridR="80" gridWidth="70" snap="true" windowMask="false" zoomFactor="0.754867" />
<objectsGroups>
<group name="Colliders">
<objects>
<object name="Quad" />
<object name="Line" />
<object name="Triangle" />
<object name="Polygon" />
</objects>
</group>
</objectsGroups>
<variables />
<instances>
<instance angle="0.000000" customSize="true" height="64.000000" layer="" locked="false" name="Player" width="64.000000" x="400.000000" y="300.000000" zOrder="2">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="160.000000" layer="" locked="false" name="Quad" width="160.000000" x="511.653046" y="426.899933" zOrder="1">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="642.864868" y="20.479473" zOrder="1">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="340.216797" y="524.969666" zOrder="1">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="52.560143" y="106.766174" zOrder="1">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="202.182587" y="29.507092" zOrder="1">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="550.417358" y="268.102661" zOrder="1">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="259.622040" y="466.785736" zOrder="1">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="640.945984" y="188.205658" zOrder="1">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="80.000000" layer="" locked="false" name="Quad" width="80.000000" x="330.563049" y="69.781281" zOrder="1">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="13.854311" y="547.935608" zOrder="1">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="4.000000" layer="" locked="false" name="Line" width="200.000000" x="42.436562" y="348.760468" zOrder="4">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="2.000000" layer="" locked="false" name="Line" width="64.000000" x="22.880741" y="14.281113" zOrder="4">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="2.000000" layer="" locked="false" name="Line" width="64.000000" x="694.834351" y="81.030281" zOrder="4">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="2.000000" layer="" locked="false" name="Line" width="64.000000" x="321.407257" y="436.969086" zOrder="4">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="false" height="0.000000" layer="" locked="false" name="Drawer" width="0.000000" x="467.504181" y="221.897949" zOrder="5">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="40.000000" layer="" locked="false" name="Quad" width="40.000000" x="687.335632" y="495.352386" zOrder="1">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="2.000000" layer="" locked="false" name="Line" width="64.000000" x="231.507050" y="134.513855" zOrder="4">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="60.000000" layer="" locked="false" name="Triangle" width="60.000000" x="432.457794" y="17.137005" zOrder="3">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="60.000000" layer="" locked="false" name="Triangle" width="60.000000" x="119.492599" y="63.272141" zOrder="3">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="60.000000" layer="" locked="false" name="Triangle" width="60.000000" x="625.232666" y="333.912476" zOrder="3">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="60.000000" layer="" locked="false" name="Triangle" width="60.000000" x="476.822723" y="355.556915" zOrder="3">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="60.000000" layer="" locked="false" name="Triangle" width="60.000000" x="404.859680" y="522.776550" zOrder="3">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="80.000000" layer="" locked="false" name="Polygon" width="100.000000" x="19.355259" y="383.442963" zOrder="4">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="50.000000" layer="" locked="false" name="Polygon" width="100.000000" x="723.214783" y="536.209045" zOrder="4">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
<instance angle="0.000000" customSize="true" height="140.000000" layer="" locked="false" name="Polygon" width="60.000000" x="517.953369" y="37.765617" zOrder="4">
<numberProperties />
<stringProperties />
<initialVariables />
</instance>
</instances>
<objects>
<object name="Player" type="Sprite" updateIfNotVisible="true">
<variables />
<behaviors />
<animations>
<animation name="" useMultipleDirections="false">
<directions>
<direction looping="false" timeBetweenFrames="1.000000">
<sprites>
<sprite hasCustomCollisionMask="false" image="Pea-Happy.png">
<points />
<originPoint name="origine" x="18.000000" y="18.000000" />
<centerPoint automatic="true" name="centre" x="18.500000" y="18.500000" />
<customCollisionMask>
<polygon>
<vertice x="0.000000" y="0.000000" />
<vertice x="37.000000" y="0.000000" />
<vertice x="37.000000" y="37.000000" />
<vertice x="0.000000" y="37.000000" />
</polygon>
</customCollisionMask>
</sprite>
</sprites>
</direction>
</directions>
</animation>
</animations>
</object>
<object name="Quad" type="Sprite" updateIfNotVisible="true">
<variables />
<behaviors />
<animations>
<animation name="" useMultipleDirections="false">
<directions>
<direction looping="false" timeBetweenFrames="1.000000">
<sprites>
<sprite hasCustomCollisionMask="false" image="Grass.png">
<points />
<originPoint name="origine" x="0.000000" y="0.000000" />
<centerPoint automatic="true" name="centre" x="35.000000" y="35.000000" />
<customCollisionMask>
<polygon>
<vertice x="0.000000" y="0.000000" />
<vertice x="70.000000" y="0.000000" />
<vertice x="70.000000" y="70.000000" />
<vertice x="0.000000" y="70.000000" />
</polygon>
</customCollisionMask>
</sprite>
</sprites>
</direction>
</directions>
</animation>
</animations>
</object>
<object name="Line" type="Sprite" updateIfNotVisible="false">
<variables />
<behaviors />
<animations>
<animation name="" useMultipleDirections="false">
<directions>
<direction looping="false" timeBetweenFrames="1.000000">
<sprites>
<sprite hasCustomCollisionMask="true" image="Pea-Happy.png">
<points />
<originPoint name="origine" x="0.000000" y="0.000000" />
<centerPoint automatic="true" name="centre" x="18.500000" y="18.500000" />
<customCollisionMask>
<polygon>
<vertice x="0.000000" y="18.000000" />
<vertice x="36.000000" y="18.000000" />
</polygon>
</customCollisionMask>
</sprite>
</sprites>
</direction>
</directions>
</animation>
</animations>
</object>
<object name="Drawer" type="PrimitiveDrawing::Drawer">
<variables />
<behaviors />
<fillOpacity>255</fillOpacity>
<outlineSize>0</outlineSize>
<outlineOpacity>0</outlineOpacity>
<fillColor b="255" g="255" r="255" />
<outlineColor b="255" g="34" r="250" />
<absoluteCoordinates>true</absoluteCoordinates>
</object>
<object name="Triangle" type="Sprite" updateIfNotVisible="false">
<variables />
<behaviors />
<animations>
<animation name="" useMultipleDirections="false">
<directions>
<direction looping="false" timeBetweenFrames="1.000000">
<sprites>
<sprite hasCustomCollisionMask="true" image="spship2.png">
<points />
<originPoint name="origine" x="0.000000" y="0.000000" />
<centerPoint automatic="true" name="centre" x="41.500000" y="41.500000" />
<customCollisionMask>
<polygon>
<vertice x="0.000000" y="0.000000" />
<vertice x="83.000000" y="42.000000" />
<vertice x="0.000000" y="83.000000" />
</polygon>
</customCollisionMask>
</sprite>
</sprites>
</direction>
</directions>
</animation>
</animations>
</object>
<object name="Polygon" type="Sprite" updateIfNotVisible="false">
<variables />
<behaviors />
<animations>
<animation name="" useMultipleDirections="false">
<directions>
<direction looping="false" timeBetweenFrames="1.000000">
<sprites>
<sprite hasCustomCollisionMask="true" image="Shape1.png">
<points />
<originPoint name="origine" x="0.000000" y="0.000000" />
<centerPoint automatic="true" name="centre" x="89.000000" y="64.500000" />
<customCollisionMask>
<polygon>
<vertice x="0.000000" y="47.000000" />
<vertice x="77.000000" y="0.000000" />
<vertice x="175.000000" y="11.000000" />
<vertice x="178.000000" y="56.000000" />
<vertice x="160.000000" y="96.000000" />
<vertice x="104.000000" y="129.000000" />
<vertice x="7.000000" y="103.000000" />
</polygon>
</customCollisionMask>
</sprite>
</sprites>
</direction>
</directions>
</animation>
</animations>
</object>
</objects>
<events>
<event disabled="false" folded="false">
<type>BuiltinCommonInstructions::Standard</type>
<conditions>
<instruction>
<type inverted="false" value="DepartScene" />
<parameters>
<parameter></parameter>
</parameters>
<subInstructions />
</instruction>
</conditions>
<actions />
<events>
<event disabled="false" folded="false">
<type>BuiltinCommonInstructions::Repeat</type>
<repeatExpression>300</repeatExpression>
<conditions />
<actions>
<instruction>
<type inverted="false" value="Create" />
<parameters>
<parameter></parameter>
<parameter>Polygon</parameter>
<parameter>Random(200)</parameter>
<parameter>Random(200)</parameter>
<parameter></parameter>
</parameters>
<subInstructions />
</instruction>
<instruction>
<type inverted="false" value="Create" />
<parameters>
<parameter></parameter>
<parameter>Line</parameter>
<parameter>500 + Random(300)</parameter>
<parameter>400 + Random(200)</parameter>
<parameter></parameter>
</parameters>
<subInstructions />
</instruction>
<instruction>
<type inverted="false" value="ChangeScaleHeight" />
<parameters>
<parameter>Line</parameter>
<parameter>=</parameter>
<parameter>0.1</parameter>
</parameters>
<subInstructions />
</instruction>
</actions>
<events />
</event>
</events>
</event>
<event disabled="false" folded="false">
<type>BuiltinCommonInstructions::Standard</type>
<conditions />
<actions>
<instruction>
<type inverted="false" value="ChangeColor" />
<parameters>
<parameter>Colliders</parameter>
<parameter>&quot;255;255;255&quot;</parameter>
</parameters>
<subInstructions />
</instruction>
<instruction>
<type inverted="false" value="PrimitiveDrawing::FillColor" />
<parameters>
<parameter>Drawer</parameter>
<parameter>&quot;200;200;250&quot;</parameter>
</parameters>
<subInstructions />
</instruction>
<instruction>
<type inverted="false" value="PrimitiveDrawing::FillOpacity" />
<parameters>
<parameter>Drawer</parameter>
<parameter>=</parameter>
<parameter>50</parameter>
</parameters>
<subInstructions />
</instruction>
<instruction>
<type inverted="false" value="PrimitiveDrawing::Circle" />
<parameters>
<parameter>Drawer</parameter>
<parameter>Player.X()</parameter>
<parameter>Player.Y()</parameter>
<parameter>400</parameter>
</parameters>
<subInstructions />
</instruction>
</actions>
<events />
</event>
<event disabled="false" folded="false">
<type>BuiltinCommonInstructions::Standard</type>
<conditions>
<instruction>
<type inverted="true" value="Raycast" />
<parameters>
<parameter>Colliders</parameter>
<parameter>Player.X()</parameter>
<parameter>Player.Y()</parameter>
<parameter>ToDeg(atan2(MouseY(&quot;&quot;,0)-Player.Y(), MouseX(&quot;&quot;,0)-Player.X()))</parameter>
<parameter>400</parameter>
<parameter>x</parameter>
<parameter>y</parameter>
<parameter></parameter>
</parameters>
<subInstructions />
</instruction>
</conditions>
<actions>
<instruction>
<type inverted="false" value="SetAngle" />
<parameters>
<parameter>Colliders</parameter>
<parameter>+</parameter>
<parameter>10 * TimeDelta()</parameter>
</parameters>
<subInstructions />
</instruction>
<instruction>
<type inverted="false" value="PrimitiveDrawing::FillColor" />
<parameters>
<parameter>Drawer</parameter>
<parameter>&quot;255;0;0&quot;</parameter>
</parameters>
<subInstructions />
</instruction>
<instruction>
<type inverted="false" value="PrimitiveDrawing::FillOpacity" />
<parameters>
<parameter>Drawer</parameter>
<parameter>=</parameter>
<parameter>100</parameter>
</parameters>
<subInstructions />
</instruction>
<instruction>
<type inverted="false" value="PrimitiveDrawing::Line" />
<parameters>
<parameter>Drawer</parameter>
<parameter>Player.X()</parameter>
<parameter>Player.Y()</parameter>
<parameter>Variable(x)</parameter>
<parameter>Variable(y)</parameter>
<parameter>1</parameter>
</parameters>
<subInstructions />
</instruction>
<instruction>
<type inverted="false" value="PrimitiveDrawing::Circle" />
<parameters>
<parameter>Drawer</parameter>
<parameter>Variable(x)</parameter>
<parameter>Variable(y)</parameter>
<parameter>3</parameter>
</parameters>
<subInstructions />
</instruction>
</actions>
<events />
</event>
<event disabled="false" folded="false">
<type>BuiltinCommonInstructions::Standard</type>
<conditions>
<instruction>
<type inverted="false" value="Raycast" />
<parameters>
<parameter>Colliders</parameter>
<parameter>Player.X()</parameter>
<parameter>Player.Y()</parameter>
<parameter>ToDeg(atan2(MouseY(&quot;&quot;,0)-Player.Y(), MouseX(&quot;&quot;,0)-Player.X()))</parameter>
<parameter>400</parameter>
<parameter>x</parameter>
<parameter>y</parameter>
<parameter></parameter>
</parameters>
<subInstructions />
</instruction>
</conditions>
<actions>
<instruction>
<type inverted="false" value="ChangeColor" />
<parameters>
<parameter>Colliders</parameter>
<parameter>&quot;50;100;50&quot;</parameter>
</parameters>
<subInstructions />
</instruction>
<instruction>
<type inverted="false" value="PrimitiveDrawing::FillColor" />
<parameters>
<parameter>Drawer</parameter>
<parameter>&quot;0;255;0&quot;</parameter>
</parameters>
<subInstructions />
</instruction>
<instruction>
<type inverted="false" value="PrimitiveDrawing::FillOpacity" />
<parameters>
<parameter>Drawer</parameter>
<parameter>=</parameter>
<parameter>100</parameter>
</parameters>
<subInstructions />
</instruction>
<instruction>
<type inverted="false" value="PrimitiveDrawing::Line" />
<parameters>
<parameter>Drawer</parameter>
<parameter>Player.X()</parameter>
<parameter>Player.Y()</parameter>
<parameter>Variable(x)</parameter>
<parameter>Variable(y)</parameter>
<parameter>1</parameter>
</parameters>
<subInstructions />
</instruction>
<instruction>
<type inverted="false" value="PrimitiveDrawing::Circle" />
<parameters>
<parameter>Drawer</parameter>
<parameter>Variable(x)</parameter>
<parameter>Variable(y)</parameter>
<parameter>2</parameter>
</parameters>
<subInstructions />
</instruction>
</actions>
<events />
</event>
</events>
<layers>
<layer name="" visibility="true">
<cameras>
<camera defaultSize="true" defaultViewport="true" height="0.000000" viewportBottom="1.000000" viewportLeft="0.000000" viewportRight="1.000000" viewportTop="0.000000" width="0.000000" />
</cameras>
<effects />
</layer>
<layer name="Debug" visibility="true">
<cameras>
<camera defaultSize="true" defaultViewport="true" height="0.000000" viewportBottom="1.000000" viewportLeft="0.000000" viewportRight="1.000000" viewportTop="0.000000" width="0.000000" />
</cameras>
<effects />
</layer>
</layers>
<behaviorsSharedData />
</layout>
</layouts>
<externalEvents />
<externalLayouts />
<externalSourceFiles>
<sourceFile filename="C:\Users\Maciel\AppData\Local\Temp/GDTemporaries/GD0x67750b8SourceFile.cpp" gdManaged="true" language="C++" />
<sourceFile filename="C:\Users\Maciel\AppData\Local\Temp/GDTemporaries/GD0x6830850SourceFile.cpp" gdManaged="true" language="C++" />
</externalSourceFiles>
</project>

BIN
GDJS/tests/games/Shape1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,114 +0,0 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<Project>
<GDVersion Major="3" Minor="0" Build="11297" Revision="57008" />
<Info winExecutableFilename="" winExecutableIconFile="" linuxExecutableFilename="" macExecutableFilename="" useExternalSourceFiles="false">
<Nom value="Projet" />
<Auteur value="" />
<Extensions>
<Extension name="BuiltinObject" />
<Extension name="BuiltinAudio" />
<Extension name="BuiltinVariables" />
<Extension name="BuiltinTime" />
<Extension name="BuiltinMouse" />
<Extension name="BuiltinKeyboard" />
<Extension name="BuiltinJoystick" />
<Extension name="BuiltinCamera" />
<Extension name="BuiltinWindow" />
<Extension name="BuiltinFile" />
<Extension name="BuiltinNetwork" />
<Extension name="BuiltinScene" />
<Extension name="BuiltinAdvanced" />
<Extension name="Sprite" />
<Extension name="BuiltinCommonInstructions" />
<Extension name="BuiltinCommonConversions" />
<Extension name="BuiltinStringInstructions" />
<Extension name="BuiltinMathematicalTools" />
<Extension name="BuiltinExternalLayouts" />
<Extension name="TextObject" />
</Extensions>
<Platforms current="GDevelop JS platform">
<Platform name="GDevelop JS platform" />
<Platform name="GDevelop C++ platform" />
</Platforms>
<WindowW value="800" />
<WindowH value="600" />
<Portable />
<LatestCompilationDirectory value="" />
<FPSmax value="60" />
<FPSmin value="10" />
<verticalSync value="false" />
</Info>
<Resources>
<Resources />
<ResourceFolders />
</Resources>
<Objects />
<ObjectGroups />
<Variables />
<Scenes firstScene="">
<Scene nom="Nouvelle sc<73>ne" mangledName="Nouvelle_32sc__4524ne" r="209.000000" v="209.000000" b="209.000000" titre="" oglFOV="90.000000" oglZNear="1.000000" oglZFar="500.000000" standardSortMethod="true" stopSoundsOnStartup="true" disableInputWhenNotFocused="true">
<UISettings gridWidth="32.000000" grid="false" snap="true" gridHeight="32.000000" gridR="158.000000" gridG="180.000000" gridB="255.000000" zoomFactor="1.000000" windowMask="true" associatedLayout="" />
<GroupesObjets />
<Objets>
<Objet nom="NouvelObjet" type="TextObject::Text" smoothed="true" bold="false" italic="false" underlined="false">
<Variables />
<String value="Heeello" />
<Font value="BOD_CB.TTF" />
<CharacterSize value="50" />
<Color r="255" g="128" b="0" />
</Objet>
</Objets>
<Layers>
<Layer Name="" Visibility="true">
<Camera DefaultSize="true" Width="0.000000" Height="0.000000" DefaultViewport="true" ViewportLeft="0.000000" ViewportTop="0.000000" ViewportRight="1.000000" ViewportBottom="1.000000" />
</Layer>
</Layers>
<Variables />
<BehaviorsSharedDatas />
<Positions>
<Objet nom="NouvelObjet" x="297.000000" y="245.000000" plan="1" layer="" angle="0.000000" personalizedSize="false" width="0.000000" height="0.000000" locked="false">
<floatInfos />
<stringInfos />
<InitialVariables />
</Objet>
</Positions>
<Events>
<Event disabled="false" folded="false">
<Type value="BuiltinCommonInstructions::Standard" />
<Conditions />
<Actions>
<Action>
<Type value="MettreXY" />
<Parametre value="NouvelObjet" />
<Parametre value="=" />
<Parametre value="300" />
<Parametre value="=" />
<Parametre value="300" />
</Action>
<Action>
<Type value="TextObject::Angle" />
<Parametre value="NouvelObjet" />
<Parametre value="+" />
<Parametre value="1" />
</Action>
<Action>
<Type value="TextObject::Opacity" />
<Parametre value="NouvelObjet" />
<Parametre value="=" />
<Parametre value="128+cos(TimeFromStart())*128" />
</Action>
<Action>
<Type value="TextObject::Size" />
<Parametre value="NouvelObjet" />
<Parametre value="=" />
<Parametre value="30+cos(TimeFromStart())*30" />
</Action>
</Actions>
</Event>
</Events>
</Scene>
</Scenes>
<ExternalEvents />
<ExternalLayouts />
<ExternalSourceFiles />
</Project>

View File

@@ -0,0 +1 @@
{"firstLayout": "","gdVersion": {"build": 96,"major": 4,"minor": 0,"revision": 89},"properties": {"folderProject": false,"linuxExecutableFilename": "","macExecutableFilename": "","packageName": "","projectFile": "/Users/florian/Projects/F/GD/GDJS/tests/games/Text.json","useExternalSourceFiles": false,"winExecutableFilename": "","winExecutableIconFile": "","name": "Projet","author": "","windowWidth": 800,"windowHeight": 600,"latestCompilationDirectory": "","maxFPS": 60,"minFPS": 10,"verticalSync": false,"extensions": [{"name": "BuiltinObject"},{"name": "BuiltinAudio"},{"name": "BuiltinVariables"},{"name": "BuiltinTime"},{"name": "BuiltinMouse"},{"name": "BuiltinKeyboard"},{"name": "BuiltinJoystick"},{"name": "BuiltinCamera"},{"name": "BuiltinWindow"},{"name": "BuiltinFile"},{"name": "BuiltinNetwork"},{"name": "BuiltinScene"},{"name": "BuiltinAdvanced"},{"name": "Sprite"},{"name": "BuiltinCommonInstructions"},{"name": "BuiltinCommonConversions"},{"name": "BuiltinStringInstructions"},{"name": "BuiltinMathematicalTools"},{"name": "BuiltinExternalLayouts"},{"name": "TextObject"}],"platforms": [{"name": "GDevelop JS platform"},{"name": "GDevelop C++ platform"}],"currentPlatform": "GDevelop C++ platform"},"resources": {"resources": [],"resourceFolders": []},"objects": [],"objectsGroups": [],"variables": [],"layouts": [{"b": 209,"disableInputWhenNotFocused": true,"mangledName": "Nouvelle_32sc_232ne","name": "Nouvelle scène","oglFOV": 90,"oglZFar": 500,"oglZNear": 1,"r": 209,"standardSortMethod": true,"stopSoundsOnStartup": true,"title": "","v": 209,"uiSettings": {"grid": false,"gridB": 255,"gridG": 180,"gridHeight": 32,"gridOffsetX": 0,"gridOffsetY": 0,"gridR": 158,"gridWidth": 32,"snap": true,"windowMask": true,"zoomFactor": 1},"objectsGroups": [],"variables": [],"instances": [{"angle": 0,"customSize": false,"height": 0,"layer": "","locked": false,"name": "NouvelObjet","width": 0,"x": 297,"y": 245,"zOrder": 1,"numberProperties": [],"stringProperties": [],"initialVariables": []}],"objects": [{"bold": false,"italic": false,"name": "NouvelObjet","smoothed": true,"type": "TextObject::Text","underlined": false,"variables": [],"behaviors": [],"string": "Heeello","font": "BOD_CB.TTF","characterSize": 50,"color": {"b": 0,"g": 128,"r": 255}}],"events": [{"disabled": false,"folded": false,"type": "BuiltinCommonInstructions::Standard","conditions": [],"actions": [{"type": {"inverted": false,"value": "MettreXY"},"parameters": ["NouvelObjet","=","300","=","300"],"subInstructions": []},{"type": {"inverted": false,"value": "TextObject::Angle"},"parameters": ["NouvelObjet","+","1"],"subInstructions": []},{"type": {"inverted": false,"value": "TextObject::Opacity"},"parameters": ["NouvelObjet","=","128+cos(TimeFromStart())*128"],"subInstructions": []},{"type": {"inverted": false,"value": "TextObject::Size"},"parameters": ["NouvelObjet","=","30+cos(TimeFromStart())*30"],"subInstructions": []}],"events": []}],"layers": [{"name": "","visibility": true,"cameras": [{"defaultSize": true,"defaultViewport": true,"height": 0,"viewportBottom": 1,"viewportLeft": 0,"viewportRight": 1,"viewportTop": 0,"width": 0}],"effects": []}],"behaviorsSharedData": []}],"externalEvents": [],"externalLayouts": [],"externalSourceFiles": []}

View File

@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 2.6)
cmake_policy(SET CMP0015 NEW)
project(GDVersion)
set(GD_VERSION_STR "4.0.96")
if(FULL_VERSION_NUMBER)
set(GENERATE_VERSION_SCRIPT ${PROJECT_SOURCE_DIR}/GenerateVersionFull.cmake)
@@ -11,5 +12,5 @@ endif()
add_custom_target(GDVersion
ALL
COMMAND ${CMAKE_COMMAND} -P ${GENERATE_VERSION_SCRIPT} ${PROJECT_SOURCE_DIR}/../Core/GDCore/Tools/
COMMAND ${CMAKE_COMMAND} -P ${GENERATE_VERSION_SCRIPT} ${PROJECT_SOURCE_DIR}/../Core/GDCore/Tools/ ${GD_VERSION_STR}
)

View File

@@ -1,13 +1,19 @@
find_package(Git)
if(GIT_FOUND)
EXECUTE_PROCESS(
COMMAND ${GIT_EXECUTABLE} describe --tags
OUTPUT_VARIABLE GD_VERSION_STR
RESULT_VARIABLE GIT_DESCRIBE_RESULT
ERROR_VARIABLE GIT_DESCRIBE_ERROR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# Retrieving GDevelop version from Git tags is disabled as GDevelop 5
# is being developed and we still want the old IDE version to stay at 4.
# The old IDE has the same version number as GDCore/libGD.js
# Hence, version of GDevelop 4 is manually specified in CMakeLists.txt
# EXECUTE_PROCESS(
# COMMAND ${GIT_EXECUTABLE} describe --tags
# OUTPUT_VARIABLE GD_VERSION_STR
# RESULT_VARIABLE GIT_DESCRIBE_RESULT
# ERROR_VARIABLE GIT_DESCRIBE_ERROR
# OUTPUT_STRIP_TRAILING_WHITESPACE
# )
set(GD_VERSION_STR ${CMAKE_ARGV4})
set(VERSIONPRIV_PATH "${CMAKE_ARGV3}/VersionPriv.h")
set(ORIGINAL_CONTENT " ")

View File

@@ -3,13 +3,19 @@ find_package(Git)
message(WARNING "You're not using the full version number. It's not suitable for public releases and builds!")
if(GIT_FOUND)
EXECUTE_PROCESS(
COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=0 # Only get the lastest tag's name
OUTPUT_VARIABLE GD_VERSION_STR
RESULT_VARIABLE GIT_DESCRIBE_RESULT
ERROR_VARIABLE GIT_DESCRIBE_ERROR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# Retrieving GDevelop version from Git tags is disabled as GDevelop 5
# is being developed and we still want the old IDE version to stay at 4.
# The old IDE has the same version number as GDCore/libGD.js
# Hence, version of GDevelop 4 is manually specified in CMakeLists.txt
# EXECUTE_PROCESS(
# COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=0 # Only get the lastest tag's name
# OUTPUT_VARIABLE GD_VERSION_STR
# RESULT_VARIABLE GIT_DESCRIBE_RESULT
# ERROR_VARIABLE GIT_DESCRIBE_ERROR
# OUTPUT_STRIP_TRAILING_WHITESPACE
# )
set(GD_VERSION_STR ${CMAKE_ARGV4})
set(VERSIONPRIV_PATH "${CMAKE_ARGV3}/VersionPriv.h")
set(ORIGINAL_CONTENT " ")

View File

@@ -61,18 +61,29 @@ cd newIDE/app
yarn test #or npm run test
```
### Theming
It's possible to create new themes for the UI. See [this file](https://github.com/4ian/GD/blob/master/newIDE/app/src/UI/Theme/index.js) to declare a new theme. You can take a look at the [default theme](https://github.com/4ian/GD/blob/master/newIDE/app/src/UI/Theme/DefaultTheme/index.js), including the [styling of the Events Sheets](https://github.com/4ian/GD/blob/master/newIDE/app/src/UI/Theme/DefaultTheme/EventsSheet.css).
## Building and deploying the standalone app
### Desktop version
First, update version number which is read in `newIDE/electron-app/app/package.json`.
```bash
cd newIDE/electron-app
yarn build #or npm run build
```
This will build and package the Electron app for Windows, macOS and Linux (according to your OS).
The output are stored inside `newIDE/electron-app/dist` and copied to `Binaries/Output/Release_XXX`.
Version number is read from `newIDE/electron-app/app/package.json`.
This will build and package the Electron app for Windows, macOS and Linux (according to your OS). The output are stored inside `newIDE/electron-app/dist`.
To build artifacts for all platforms and publish to a draft GitHub release:
```
GH_TOKEN=xxx yarn build --mac --win --linux tar.gz --publish always
```
### Webapp version
@@ -86,7 +97,6 @@ yarn deploy #or npm run deploy
This new editor is still in development and is missing some features:
- [ ] Support for translations (See an [example of a component that can be translated](https://github.com/4ian/GD/blob/master/newIDE/app/src/MainFrame/Toolbar.js#L44))
- [ ] [Autocompletion of expressions and parameters in Events editor](https://trello.com/c/mAROBTR8/46-expression-editor-auto-complete-for-the-new-ide).
- [ ] [Collision mask editor](https://trello.com/c/2Kzwj61r/47-collision-masks-editors-for-sprite-objects-in-the-new-ide)
- [ ] Support for native games
- [ ] More [documentation](http://wiki.compilgames.net/doku.php/gdevelop5/start) about how to package for iOS/Android with Cordova/PhoneGap Build or Cocos2d-JS.
@@ -98,6 +108,8 @@ This new editor is still in development and is missing some features:
You can contribute by picking anything here or anything that you think is missing or could be improved in GD5! If you don't know how to start, it's a good idea to play a bit with the editor and see if there is something that is unavailable and that you can add or fix.
See also [the roadmap for ideas and features planned](https://trello.com/b/qf0lM7k8/gdevelop-roadmap).
## Additional help
This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app). Check out their documentation for common tasks or help about using it.

View File

@@ -1,4 +1,4 @@
# Rename this file as .env.local and complete the following values.
# Copy this file as ".env.local" and complete the following values.
# If values are not completed, some features will be unavailable.
REACT_APP_PREVIEW_S3_ACCESS_KEY_ID=

View File

@@ -1,5 +1,7 @@
[ignore]
<PROJECT_ROOT>/resources/.*
<PROJECT_ROOT>/node_modules/auth0-lock/node_modules/fbjs/flow/include/PromiseMap.js
<PROJECT_ROOT>/node_modules/protobufjs/src/bower.json
[include]

View File

@@ -5,6 +5,7 @@ node_modules
# testing
coverage
flow-coverage
# production
build
@@ -23,3 +24,4 @@ public/res
public/CppPlatform
public/JsPlatform
resources/GDJS

24
newIDE/app/flow-typed/libGD.js vendored Normal file
View File

@@ -0,0 +1,24 @@
// @flow
//TODO: These types could be generated from GDevelop.js instead of being
//manually written here.
type EmscriptenObject = Object & {
ptr: Number
};
declare type gdProject = EmscriptenObject;
declare type gdLayout = EmscriptenObject;
declare type gdExternalLayout = EmscriptenObject;
declare type gdExternalEvents = EmscriptenObject;
declare type gdSerializerElement = EmscriptenObject;
declare type gdInitialInstance = EmscriptenObject;
declare type gdBaseEvent = EmscriptenObject;
declare type gdResource = EmscriptenObject;
declare type gdObject = EmscriptenObject;
declare type gdInstruction = EmscriptenObject;
declare type gdInstructionMetadata = EmscriptenObject;
declare type gdInstructionsList = EmscriptenObject;
//Represents all objects that have serializeTo and unserializeFrom methods.
declare type gdSerializable = EmscriptenObject;

View File

@@ -0,0 +1,94 @@
// flow-typed signature: 6c6a5771bbdffe188d60637063b5f9a4
// flow-typed version: 6533cd10ce/react-i18next_v6.x.x/flow_>=v0.53.x
declare module "react-i18next" {
declare type TFunction = (key?: ?string, data?: ?Object) => string;
declare type Locales = string | Array<string>;
declare type TranslatorProps = {
t: TFunction,
i18nLoadedAt: Date,
i18n: Object
};
declare type Translator<OP, P> = (
component: React$ComponentType<P>
) => Class<React$Component<OP, *>>;
declare type TranslateOptions = $Shape<{
wait: boolean,
nsMode: "default" | "fallback",
bindi18n: false | string,
bindStore: false | string,
withRef: boolean,
translateFuncName: string,
i18n: Object
}>;
declare function translate<OP, P>(
locales?: Locales,
options?: TranslateOptions
): Translator<OP, P>;
declare type I18nProps = {
i18n?: Object,
ns?: string | Array<string>,
children: (t: TFunction, { i18n: Object, t: TFunction }) => React$Node,
initialI18nStore?: Object,
initialLanguage?: string
};
declare var I18n: React$ComponentType<I18nProps>;
declare type InterpolateProps = {
className?: string,
dangerouslySetInnerHTMLPartElement?: string,
i18n?: Object,
i18nKey?: string,
options?: Object,
parent?: string,
style?: Object,
t?: TFunction,
useDangerouslySetInnerHTML?: boolean
};
declare var Interpolate: React$ComponentType<InterpolateProps>;
declare type TransProps = {
count?: number,
parent?: string,
i18n?: Object,
i18nKey?: string,
t?: TFunction
};
declare var Trans: React$ComponentType<TransProps>;
declare type ProviderProps = { i18n: Object, children: React$Element<*> };
declare var I18nextProvider: React$ComponentType<ProviderProps>;
declare type NamespacesProps = {
components: Array<React$ComponentType<*>>,
i18n: { loadNamespaces: Function }
};
declare function loadNamespaces(props: NamespacesProps): Promise<void>;
declare var reactI18nextModule: {
type: "3rdParty",
init: (instance: Object) => void
};
declare var defaultOptions: {
wait: false,
withRef: false,
bindI18n: "languageChanged loaded",
bindStore: "added removed",
translateFuncName: "t",
nsMode: "default"
};
declare function setDefaults(options: TranslateOptions): void;
declare function getDefaults(): TranslateOptions;
declare function getI18n(): Object;
declare function setI18n(instance: Object): void;
}

View File

@@ -5,62 +5,75 @@
"license": "MIT",
"homepage": ".",
"devDependencies": {
"flow-bin": "^0.58.0",
"flow-bin": "^0.61.0",
"flow-coverage-report": "^0.4.0",
"follow-redirects": "^1.2.3",
"prettier": "1.7.0",
"react-scripts": "1.0.6",
"react-scripts": "1.0.17",
"shelljs": "^0.7.7"
},
"dependencies": {
"@storybook/react": "3.2.14",
"@storybook/react": "3.2.19",
"aws-sdk": "^2.100.0",
"axios": "^0.16.1",
"classnames": "^2.2.5",
"cursores": "^1.0.1",
"element-closest": "^2.0.2",
"blueimp-md5": "^2.10.0",
"classnames": "2.2.5",
"create-react-context": "^0.1.6",
"date-fns": "^1.29.0",
"element-closest": "2.0.2",
"firebase": "^4.8.2",
"flat": "2.0.1",
"fontfaceobserver": "^2.0.13",
"fontfaceobserver": "2.0.13",
"i18next": "^10.0.3",
"keen-tracking": "1.1.3",
"lodash": "4.17.4",
"material-ui": "0.18.3",
"material-ui-search-bar": "0.4.0",
"material-ui": "0.20",
"material-ui-search-bar": "0.4.1",
"pixi-simple-gesture": "0.2.2",
"pixi.js": "3.0.11",
"prop-types": "^15.5.10",
"raven-js": "^3.19.1",
"react": "15.4.2",
"react-addons-css-transition-group": "15.4.2",
"react-addons-perf": "15.4.2",
"react-color": "2.11.7",
"react-dnd": "2.3.0",
"react-dnd-html5-backend": "2.3.0",
"react-dom": "15.4.2",
"react-i18next": "^6.0.6",
"react-measure": "1.4.6",
"react": "^16.2.0",
"react-color": "2.13.8",
"react-dnd": "2.5.4",
"react-dnd-html5-backend": "2.5.4",
"react-dom": "^16.2.0",
"react-error-boundary": "^1.2.0",
"react-i18next": "6.2.0",
"react-measure": "1.4.7",
"react-mosaic-component": "1.0.3",
"react-sortable-hoc": "^0.6.3",
"react-sortable-tree": "^0.1.21",
"react-tap-event-plugin": "2.0.1",
"react-test-renderer": "15.4.2",
"react-virtualized": "9.3.0",
"slugs": "^0.1.3",
"react-sortable-hoc": "0.6.8",
"react-sortable-tree": "1.5.3",
"react-test-renderer": "16.2.0",
"react-virtualized": "9.14.1",
"slugs": "0.1.3",
"source-map-explorer": "^1.4.0",
"wait-promise": "^0.4.1"
"wait-promise": "0.4.1"
},
"scripts": {
"postinstall": "npm run import-resources",
"import-resources": "cd scripts && node import-libGD.js && node import-res-folder.js && node import-GDJS-Runtime.js",
"start": "npm run import-resources && react-scripts start",
"build": "npm run import-resources && react-scripts build",
"postinstall": "npm run import-resources",
"format": "prettier --write \"src/**/*.js\"",
"test": "react-scripts test --env=jsdom",
"flow": "flow",
"analyze-source-map": "source-map-explorer build/static/js/main.*",
"storybook": "start-storybook -p 9009 -s public",
"build-storybook": "build-storybook -s public"
"analyze-test-coverage": "react-scripts test --env=jsdom --coverage",
"analyze-flow-coverage": "flow-coverage-report",
"analyze-source-map": "source-map-explorer build/static/js/main.*"
},
"eslintConfig": {
"extends": "react-app"
},
"flow-coverage-report": {
"includeGlob": [
"src/**/*.js"
],
"type": [
"text",
"html",
"json"
]
}
}

View File

@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>GDevelop 5</title>
@@ -25,24 +25,9 @@
<meta name="theme-color" content="#4ab0e4">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<!-- Fullstory user analytics -->
<script>
window['_fs_debug'] = false;
window['_fs_host'] = 'fullstory.com';
window['_fs_org'] = '8DWZ1';
window['_fs_namespace'] = 'FS';
(function(m,n,e,t,l,o,g,y){
if (e in m) {if(m.console && m.console.log) { m.console.log('FullStory namespace conflict. Please set window["_fs_namespace"].');} return;}
g=m[e]=function(a,b){g.q?g.q.push([a,b]):g._api(a,b);};g.q=[];
o=n.createElement(t);o.async=1;o.src='https://'+_fs_host+'/s/fs.js';
y=n.getElementsByTagName(t)[0];y.parentNode.insertBefore(o,y);
g.identify=function(i,v){g(l,{uid:i});if(v)g(l,v)};g.setUserVars=function(v){g(l,v)};
g.identifyAccount=function(i,v){o='account';v=v||{};v.acctId=i;g(o,v)};
g.clearUserCookie=function(c,d,i){if(!c || document.cookie.match('fs_uid=[`;`]*`[`;`]*`[`;`]*`')){
d=n.domain;while(1){n.cookie='fs_uid=;domain='+d+
';path=/;expires='+new Date(0).toUTCString();i=d.indexOf('.');if(i<0)break;d=d.slice(i+1)}}};
})(window,document,window['_fs_namespace'],'script','user');
</script>
<!-- Stripe.com Checkout -->
<script src="https://checkout.stripe.com/checkout.js"></script>
</head>
<body>
<!-- Root div used for React `App` component rendering-->

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,760 @@
{
"firstLayout": "",
"gdVersion": {
"build": 96,
"major": 4,
"minor": 0,
"revision": 0
},
"properties": {
"folderProject": false,
"linuxExecutableFilename": "",
"macExecutableFilename": "",
"packageName": "",
"projectFile": "/Users/florian/Desktop/parallax/parallax.json",
"useExternalSourceFiles": false,
"winExecutableFilename": "",
"winExecutableIconFile": "",
"name": "Project",
"author": "",
"windowWidth": 600,
"windowHeight": 400,
"latestCompilationDirectory": "",
"maxFPS": 60,
"minFPS": 10,
"verticalSync": false,
"extensions": [
{
"name": "BuiltinObject"
},
{
"name": "BuiltinAudio"
},
{
"name": "BuiltinVariables"
},
{
"name": "BuiltinTime"
},
{
"name": "BuiltinMouse"
},
{
"name": "BuiltinKeyboard"
},
{
"name": "BuiltinJoystick"
},
{
"name": "BuiltinCamera"
},
{
"name": "BuiltinWindow"
},
{
"name": "BuiltinFile"
},
{
"name": "BuiltinNetwork"
},
{
"name": "BuiltinScene"
},
{
"name": "BuiltinAdvanced"
},
{
"name": "Sprite"
},
{
"name": "BuiltinCommonInstructions"
},
{
"name": "BuiltinCommonConversions"
},
{
"name": "BuiltinStringInstructions"
},
{
"name": "BuiltinMathematicalTools"
},
{
"name": "BuiltinExternalLayouts"
}
],
"platforms": [
{
"name": "GDevelop JS platform"
}
],
"currentPlatform": "GDevelop JS platform"
},
"resources": {
"resources": [
{
"alwaysLoaded": false,
"file": "Vegetation_(middle_layer).png",
"kind": "image",
"name": "Vegetation_(middle_layer).png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "Ground_(front_layer).png",
"kind": "image",
"name": "Ground_(front_layer).png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "Sky_back_layer.png",
"kind": "image",
"name": "Sky_back_layer.png",
"smoothed": true,
"userAdded": true
},
{
"alwaysLoaded": false,
"file": "Elisa_standing.png",
"kind": "image",
"name": "Elisa_standing.png",
"smoothed": true,
"userAdded": true
}
],
"resourceFolders": []
},
"objects": [],
"objectsGroups": [],
"variables": [],
"layouts": [
{
"b": 209,
"disableInputWhenNotFocused": true,
"mangledName": "New_32scene",
"name": "New scene",
"oglFOV": 90,
"oglZFar": 500,
"oglZNear": 1,
"r": 209,
"standardSortMethod": true,
"stopSoundsOnStartup": true,
"title": "",
"v": 209,
"uiSettings": {
"grid": true,
"gridB": 255,
"gridG": 180,
"gridHeight": 32,
"gridOffsetX": 0,
"gridOffsetY": 0,
"gridR": 158,
"gridWidth": 32,
"snap": true,
"windowMask": false,
"zoomFactor": 1
},
"objectsGroups": [],
"variables": [],
"instances": [
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "",
"locked": false,
"name": "ObjectToFollow",
"width": 0,
"x": -128,
"y": 320,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
},
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "Layer4",
"locked": false,
"name": "Background",
"width": 0,
"x": -640,
"y": -32,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
},
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "Layer3",
"locked": false,
"name": "Background",
"width": 0,
"x": -640,
"y": -32,
"zOrder": 1,
"numberProperties": [
{
"name": "animation",
"value": 1
}
],
"stringProperties": [],
"initialVariables": []
},
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "Layer2",
"locked": false,
"name": "Background",
"width": 0,
"x": -608,
"y": -32,
"zOrder": 1,
"numberProperties": [
{
"name": "animation",
"value": 2
}
],
"stringProperties": [],
"initialVariables": []
},
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "Layer3",
"locked": false,
"name": "Background",
"width": 0,
"x": 0,
"y": -32,
"zOrder": 1,
"numberProperties": [
{
"name": "animation",
"value": 1
}
],
"stringProperties": [],
"initialVariables": []
},
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "Layer2",
"locked": false,
"name": "Background",
"width": 0,
"x": 0,
"y": -32,
"zOrder": 1,
"numberProperties": [
{
"name": "animation",
"value": 2
}
],
"stringProperties": [],
"initialVariables": []
},
{
"angle": 0,
"customSize": false,
"height": 0,
"layer": "Layer4",
"locked": false,
"name": "Background",
"width": 0,
"x": 0,
"y": -32,
"zOrder": 1,
"numberProperties": [],
"stringProperties": [],
"initialVariables": []
}
],
"objects": [
{
"name": "Background",
"type": "Sprite",
"updateIfNotVisible": true,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 1,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "Sky_back_layer.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": [
[
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
}
]
]
}
]
}
]
},
{
"name": "",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 1,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "Vegetation_(middle_layer).png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": [
[
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
}
]
]
}
]
}
]
},
{
"name": "",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 1,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "Ground_(front_layer).png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": [
[
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
}
]
]
}
]
}
]
}
]
},
{
"name": "ObjectToFollow",
"type": "Sprite",
"updateIfNotVisible": true,
"variables": [],
"behaviors": [],
"animations": [
{
"name": "",
"useMultipleDirections": false,
"directions": [
{
"looping": false,
"timeBetweenFrames": 1,
"sprites": [
{
"hasCustomCollisionMask": false,
"image": "Elisa_standing.png",
"points": [],
"originPoint": {
"name": "origine",
"x": 0,
"y": 0
},
"centerPoint": {
"automatic": true,
"name": "centre",
"x": 0,
"y": 0
},
"customCollisionMask": [
[
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
},
{
"x": 0,
"y": 0
}
]
]
}
]
}
]
}
]
}
],
"events": [
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Comment",
"color": {
"b": 109,
"g": 230,
"r": 255,
"textB": 0,
"textG": 0,
"textR": 0
},
"comment": "The character can just be moved left and right - in a real game you can use the Platformer character behavior.",
"comment2": ""
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "KeyPressed"
},
"parameters": [
"",
"Left"
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "AddForceXY"
},
"parameters": [
"ObjectToFollow",
"-200",
"0",
"0"
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [
{
"type": {
"inverted": false,
"value": "KeyPressed"
},
"parameters": [
"",
"Right"
],
"subInstructions": []
}
],
"actions": [
{
"type": {
"inverted": false,
"value": "AddForceXY"
},
"parameters": [
"ObjectToFollow",
"200",
"0",
"0"
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "MoveObjects"
},
"parameters": [
""
],
"subInstructions": []
}
],
"events": []
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Comment",
"color": {
"b": 109,
"g": 230,
"r": 255,
"textB": 0,
"textG": 0,
"textR": 0
},
"comment": "Parallax is achieved by setting the position of the camera to the position of the player, multiplied by a factor (between 0 and 1).\nA small factor makes the layer appears far.\nA factor close to 1 makes the layer appears like if it was near the player.",
"comment2": ""
},
{
"disabled": false,
"folded": false,
"type": "BuiltinCommonInstructions::Standard",
"conditions": [],
"actions": [
{
"type": {
"inverted": false,
"value": "CameraX"
},
"parameters": [
"",
"=",
"ObjectToFollow.X()",
"",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "CameraX"
},
"parameters": [
"",
"=",
"ObjectToFollow.X()*0.75",
"\"Layer2\"",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "CameraX"
},
"parameters": [
"",
"=",
"ObjectToFollow.X()*0.50",
"\"Layer3\"",
""
],
"subInstructions": []
},
{
"type": {
"inverted": false,
"value": "CameraX"
},
"parameters": [
"",
"=",
"ObjectToFollow.X()*0.25",
"\"Layer4\"",
""
],
"subInstructions": []
}
],
"events": []
}
],
"layers": [
{
"name": "Layer4",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
},
{
"name": "Layer3",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
},
{
"name": "Layer2",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
},
{
"name": "",
"visibility": true,
"cameras": [
{
"defaultSize": true,
"defaultViewport": true,
"height": 0,
"viewportBottom": 1,
"viewportLeft": 0,
"viewportRight": 1,
"viewportTop": 0,
"width": 0
}
],
"effects": []
}
],
"behaviorsSharedData": []
}
],
"externalEvents": [],
"externalLayouts": [],
"externalSourceFiles": []
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Some files were not shown because too many files have changed in this diff Show More