-
-
Notifications
You must be signed in to change notification settings - Fork 188
Change Log
Read about the future of p5play in the q5play announcement! 🔮
Over the past 3 years, I've done a lot of work to improve p5play. 💫
Below is a summary of the version history, highlighting key updates and features introduced in each release. 📣
- Improved sprite animation rendering performance.
- Changed
animation
function parameters for consistency with q5.js/p5.jsimage
. - Deprecated
ani.rotation
setting.
- Added robust group editing functions, including
group.splice
. - Renamed
sprite.remove()
tosprite.delete()
for clarity. - Introduced
group.delete()
andgroup.deleteAll()
.
- Added warnings for incompatible p5.js versions.
- Upgraded planck.js to v1.4.2.
- Added support for p5.js v2 (not recommended until this issue is resolved).
- Fixed issues with
p5.disableFriendlyErrors
. - Deprecated
sprite.collider
in favor ofsprite.physicsType
.
- Added support for the new frame cycle functions
update
anddrawFrame
to p5.js. - Implemented workarounds for p5.js draw support bugs.
- Updated bundled planck.js to v1.3.0.
- Improved error handling for unsupported p5.js v2 usage.
- Revised frame cycle logic.
- Removed deprecated properties/functions and undocumented
sprite.addImg
. - See frame cycle revision log.
- Bug fixes for reported issues, including issue #327.
- Added server-side image loading support.
- WebGPU fallback for sketches.
- Merged community PRs and improved debug visuals.
- See server-side demo.
- Initial support for q5-webgpu.
- Improved group animation dimension inheritance.
- Use emojis as images for sprites.
- More bug fixes for p5.js compatibility.
- Improved animation scaling and image sizing (details).
- Fixed memory leak and revised sprite direction logic.
- Added
sprite.gravityScale
. - Improved collider type transitions.
- Added support for p5.js WebGL mode (canvas example).
- Added
world.rayCast
andsprite.distanceTo
. - Improved controller input handling.
- HDR color space support with q5.js.
- New
sprite.opacity
property. - Finalized input/touch functions.
- See HDR Web Design Guide and input devices documentation.
- Improved tile-based movement.
- Fixed text caching for latest p5.js versions.
- See canvas fullscreen preset docs.
- Refactored contact handling system for better performance and memory efficiency.
- Improved compatibility with p5.js v1.8.0.
- Major internal refactoring.
- Improved Sprite constructor and collider/shape handling.
- Fixed group contact issues.
- Re-implemented contact handling for better performance.
- Fixed mobile touch and group removal behaviors.
- Introduced fast rotated text rendering via caching.
- Fixed text/image alignment.
- Improved input handling.
- See VSCode autocompletion FAQ.
- Try the p5play-vscode extension!
- Added VSCode auto-complete support.
- Improved group and input device typings.
- Fixed animation inheritance.
- Bug fixes for planck.js compatibility.
- Improved joint offset handling.
- Breaking change to
applyForce
function. - Added
bearing
property andattractTo
function. - Upgraded planck.js for performance.
- See advanced movement docs.
- Removed deprecated functions.
- Fixed critical mass calculation bug.
- Improved Netcode class for future multiplayer support.
- Details in Physical Attributes docs.
- Finalized joint implementations.
- Improved sensor drawing logic.
- Fixed collider/rotation issues.
- See joints learn page.
- Performance improvements for collision/overlap handling.
- Added "pixelated" canvas preset.
- Improved group animation inheritance.
- See SpriteArt color palette example.
- Added
pixelPerfect
sprite property. - Improved camera and group collision handling.
- Introduced loading screen.
- Try the ghost ability example and see the made with p5play image.
- Critical bug fixes for p5.js instance mode.
- Added q5.js beta support.
- Improved sprite/group update/draw control.
- See advanced topics on update/draw control.
- Improved documentation.
- Improved input state handling.
- Improved collider/animation management.
- See input devices docs.
- Fixed polygon/chain rotation origin.
- Improved sprite scale logic.
- Added movement sequencing examples.
- Try the hourglass demo and movement sequencing example.
- Changed
move
function parameter order. - Improved rotate functions.
- Fixed animation/image handling.
- See sprite scale example and sprite rotate/animation docs.
- Added new movement functions.
- Improved group property setters.
- Enhanced polygon/chain sprite creation.
- See group property setters docs, sprite movement docs, and polygon sprite example.
- Updated input system naming conventions.
- Improved collision/overlap event handling.
- Fixed critical bugs.
- See collision docs and overlap docs.
- Major release with ES6 class support.
- Improved sprite/group creation.
- Enhanced compatibility.
- Improved Sprite constructor.
- Revised Asteroids example.
- Demonstrated Sprite extension.
- Added
Group.cull
method. - Improved quadtree and tunneling fixes.
- Introduced ES6 class structure.
Fixed bug with ani.cutFrames
.
This is (probably) the last significant update to p5play. 🌜
Version 4 (q5play) is coming! 🌞
Drawing sprites with animations is now faster. 🚀
This is technically a breaking change, but this functionality was never used in the p5play Learn pages or examples. For 99% of existing projects this will just provide a nice speed boost since it eliminates the need for two push
/pop
matrix cycles for every sprite with animation.
The animation
function now accepts the same four first inputs as image
: the x, y, width, and height to display the frame at. Previously this function accepted rotation and scaling. ani.rotation
setting was also removed.
Users should rotate animations with the q5.js/p5.js rotate
function or by adding an animation to a sprite and setting sprite.rotation
.
Fully implemented group.splice
and all other group editing functions in a robust way.
https://p5play.org/docs/Group.html#splice
Renamed sprite.remove()
to sprite.delete()
to avoid confusion with group.remove(sprite)
which removes sprites from the group but not the world (physics simulation). Also added group.delete()
and group.deleteAll()
.
https://p5play.org/learn/group.html?page=5
To retain backwards compatibility group.removeAll()
is a deprecated alias for group.deleteAll
. In q5play (v4), as a breaking change, removeAll
will provide a convenient way to remove all sprites from a group but not delete them from the world.
For quality control, p5play will now warn against using p5play with some versions of p5.js.
Upgraded planck.js to v1.4.2
p5.disableFriendlyErrors = true
not being respected by p5. I filed an issue report:
https://github.com/processing/p5.js/issues/7819
Override incorrect _setupDone flag in p5.js v1.11.
p5play v3.30: Added support for p5.js v2 but using it with p5play is still not recommended. https://github.com/processing/p5.js-compatibility/issues/25
"Red Remover" is now working again! https://game.thegamebox.ca/red_remover
sprite.collider
is now a deprecated alias for sprite.physicsType
/sprite.physics
. This is because it defines how the sprite's physics body behaves, including its sensors, not just its collider.
https://p5play.org/learn/sprite.html?page=1
New frame cycle functions update
and drawFrame
can now be used instead of draw
when p5play is used with p5.js.
My attempt at a better workaround for the bug in p5 broke draw
support when p5play was used with p5.
Added a workaround for a bug in p5.js that prevents sketches from using update
and drawFrame
instead of draw
https://github.com/processing/p5.js/issues/7781
Added console error when p5play is used with p5.js v2, which doesn't support p5play (yet).
Updated p5play's licenses.
https://q5js.substack.com/publish/posts/detail/162003781
p5play.renderStats
now just shows sprite count and FPS stats.
Updated the bundled planck.min.js
to planck v1.3.0
The sprite.addImg
function has been deprecated so long, it didn't even have documentation to mark it as such. It was removed in this update. This is to avoid confusion with sprite.image
because sprite.addImg
actually added a single frame animation.
Users need to explicitly add a single frame animation using sprite.addAni
or set an image using sprite.image
.
Revised p5play's frame cycle (aka "game loop"):
https://github.com/quinton-ashley/p5play/wiki/Developer-Log#frame-cycle-revision--december-19-2024
Also several deprecated properties and functions marked for removal were removed. This is to prepare for development on version 4.
Fix for https://github.com/quinton-ashley/p5play/issues/327
Added support for server side synchronous image loading. p5play can now run server side with q5
, skia-canvas
, and jsdom
npm packages. Check out the demo:
https://github.com/quinton-ashley/p5play-render-demo
Merged PRs from @codingMASTER398 and @Dukemz 🎉
Added support for sketches written for q5 WebGPU that fall back to the Canvas2D renderer if WebGPU is not available in the user's browser.
Fixed friendly angle rounding, angular slop was not properly calculated.
Fixed #337
When sprite.debug
is true sensors now display as bright yellow with 50% transparency, so that lime green colliders drawn directly under a sensor can still be seen.
Fixed a regression introduced in v3.22.13 that messed up animation scaling. I recommend that npm users upgrade to this version ASAP!
When used with q5.js v2.9 and above, p5play will use q5's default image scale system. p5play will also use the image's defaultWidth
and defaultHeight
to determine the size of group sprites when a group has an image or animation but the user didn't specifying what width and height the sprites should be like in this example.
https://p5play.org/learn/animation.html?page=3
Initial support for q5-webgpu! https://q5js.org
Made a proper fix for group.width
and group.height
not being inherited by group animations if no other dimensions are specified.
p5.js v1.10.0 finally has the fix I helped Dave make for deltaTime
, 5 months after I suggested it. Better late than never I guess, but it took so long I forgot to remove the warning I made to p5play user's about p5's inaccurate delaTime
, until now.
Reimplemented the Emoji Image function so that it simply uses a p5 or q5 graphics object to make the image. It's a bit faster than the previous implementation that used createTextImage
.
Removed the text image cache system from p5play.js because it was admittedly a hacky solution to p5's slow text rendering and I don't want to maintain a separate version of this code I originally wrote for q5. I've improved the system in q5.js, so anyone that wants to use text image caching going forward needs to use q5.js instead of p5.js.
For q5's WebGPU renderer I'm working on a more robust system for displaying high quality text with much better performance compared to p5.js WebGL mode. Stay tuned! https://github.com/q5js/q5.js/wiki/Developer-Log#research-on-realtime-text-rendering-in-webgpu--september-22-2024
Fixed #332 a regression introduced in v3.22.15
Optimized EmojiImage
code.
Updated applyForce
params and documentation. Thanks to @sifhg!
Fixed regression in v3.22.8, use of new Canvas(200, 200, "pixelated")
properly makes the canvas fullscreen.
If no input params are given to fill
, stroke
, and background
, p5play.js no longer throws an error, the error should be thrown from q5 or p5.
Fixed major issue with v3.22.8 that caused p5play to crash when used with p5.js. I forgot to test with p5, not just with q5.
sprite.move
now works with negative direction angles.
Fixed #323
Setting group.image
to an arrow function works now.
sprite.image
and group.image
have to determine if the input string is a file path or emoji. My test to determine that was not so sophisticated, just checking if the length of the string were less than 4. But some emojis have a really long unicode char lengths:
"👋🏻".length; // => Expected 1, got 4. "👨👩👧👧".length; // => Expected 1, got 11. "🤽🏿♀️".length; // => Expected 1, got 7. credits: https://github.com/jericirenej/emoji-string-length
Now p5play just checks if the string includes a ".", then it's an image file.
group.image
works now! What an oversight haha.
No images? 🫥 No problem! 😄 You can use any emoji as the image for your sprite. The size of the emoji image will be based on the sprite's size. Great for quick prototyping! 🧪 https://p5play.org/learn/sprite.html?page=2
sprite.image = '🏀';
Also implemented #322. The setter of sprite.image
no longer creates a single frame animation behind the scenes, it just stores the image. Some pretty common questions on the discord server were how to offset an image from the center of the sprite and how to scale it. I figured these features should be introduced sooner on Sprite page 2.
Deprecated sprite.addImage
, group.addImage
, and similar functions because it's unclear that p5play is making single frame animations inside these functions which are actually just aliased to sprite.addAni
anyway.
Implemented #321 spirte.canvasPos
requested by a user on discord (can't find them!)
Fixed #320
Also the memory leak fix from v3.21.7 has been confirmed to work!
Fixed a memory leak introduced in v3.18.5 that brought fps to a crawl on some devices after a few minutes of use!
Breaking change to the getter for sprite.direction
. When a sprite stopped moving it used to get the sprite's rotation. I realized after talking to some users on discord that this behavior is too confusing and doesn't make sense in many situations. Now a sprite's direction and rotation are completely separate. A sprite's direction setting persists, even if it stops moving. To retain old behavior simply set sprite.direction = sprite.rotation
.
Turtle
sprites have direction tied to rotation and the examples that use the turtles now explain this.
Fix for sound not activating on first touch on iOS devices, needed to call userStartAudio
in ontouchstart
.
Added sprite.gravityScale
Removed ".png" extension check which doesn't work if image names have "?" params.
When a sprite with a collider type of "d", "s", or "k" is changed to "none", or vice versa, the sprite will maintain its current position, speed, rotation, and rotation speed.
If you want to have the sprite lose it's speed or rotationSpeed after the collider type change, simply set them to zero manually.
https://aijs.io/editor?user=quinton-ashley&project=colliderEditing_demo
It just wouldn't be a new minor release bump if I didn't forget to manually update the version number at the top of the file lol.
Fixed bug that caused new Sprite()
with no input params to crash inside preload
.
contros.swap
should also update contro
in p5.js if contros[0]
is changed.
More sophisticated feature detection for Contro
object's hasAnalogTriggers
property
The way I had implemented contro
did not work properly with p5. Fixed it real quick!
Added world.meterSize
.
Fixed camera support with p5's webgl mode.
Upgraded the controllers
array, now aliased to contros
(with an "s") instead of contro
.
contro
will still attempt to get input from the first controller but if it doesn't exist, it'll get a mock controller. The mock controller object can be used for testing or even TAS purposes.
I also publicly exposed Contro
as a public class in case users want to make additional mock controllers. Added getter hasAnalogTriggers
to controller objects.
Added contros.onConnect
, contros.onDisconnect
, contros.swap
, and contros.remove
functions.
Fixed some mistakes that had broken the camera for canvas 2d mode.
I still need to implement proper support for the camera in p5's webgl mode.
p5 webgl mode support is ready for beta testing!
new Canvas(400, 400, 'webgl');
p5play canvas presets can still be used but must be specified before the mode param:
new Canvas(400, 400, 'fullscreen', 'webgl');
Also fixed a q5.js bug with sprite.strokeWeight = 0
, which should just make chain colliders not be drawn.
Added world.rayCast
and world.rayCastAll
functions.
https://p5play.org/docs/World.html#rayCast
Demo: https://aijs.io/editor?user=quinton-ashley&project=p5play_world_rayCast_demo
Added world.physicsTime
and world.realTime
Added sprite.distanceTo
https://p5play.org/docs/Sprite.html#distanceTo
Thanks to @codingMASTER398 for his help and PR #314 !
Fixed bug with frameRate
function override.
Fixed bug that caused sprite.mass
setter to crash due to changes in v3.20.1. Oof my bad, I didn't consider it.
Also sprite.resetMass
will now only reset the sprite's mass, not its center of mass.
The renderStats
function is now deprecated in favor of setting a boolean property p5play.renderStats
. This makes it easier to render stats, no need to run renderStats
every frame, its much better to just be able to toggle it on and off, which can simply be done in the console. renderStats
didn't actually draw the stats anyways, it just set a flag for p5play to draw them after the user's draw loop and all sprites were drawn.
Fixed #312. In p5play my goal was always to have the sprite's center (position), center of mass, and center of rotation all be the same point. So to ensure this is true, addCollider
will not change the sprite's center of mass. Users can then use a separate function for that: resetCenterOfMass
Also I tweaked sprite.rotate
so that it will not snap to the angle amount prematurely. It also will slow the sprite on the last frame of rotation if the remaining angular distance is not divisible by the rotation speed. This prevents the sprite from having to rotationally teleport too far, ideally a negligible amount or not at all, when set to the exact destination angle. The v3.20.0 implmentation broke my hourglass demo, now it's working great!
Fixed renderStats
crashing if not used on frame 1.
Fixes #310
sprite.life
is now based on world.timeScale
instead of frameCount
. Fixes #308
Fixed renderStats
not working with p5.js and made the rect bigger to fit the additional line of text that shows the display frame rate.
Also when sprite.debug
is true, sensors will be drawn with bright yellow to differentiate them from colliders which are bright green.
Implemented world.timeScale
which can be used to control the physics simulation.
https://p5play.org/learn/world.html?page=1
Fixed #307 rotateTo
is now straightforward, just rotate the sprite to whatever angle at whatever speed you give it. rotateMinTo
will rotate the sprite the minimum angular distance to the destination angle, using the given rotation speed as an absolute speed, flipping the direction of rotation as needed.
No longer shows the "made with p5play" on replit.dev pages.
Properly implemented rotationSpeed
. In planck angularVelocity is specified in angles per second. Therefore to properly set rotationSpeed
the user's angle value must be multiplied by 60 (fps) then divided by 57.2958 to convert to radians. Previously this function didn't do any calculation and the results were visually similar when used with the default degree mode. I'm not sure how I didn't catch this, but no one else ever reported the issue either. Glad it's fixed now!
p5play now calls mousePressed
on first touches, as it should.
Various tweaks were made to make p5play not throw errors if window
or document
are not defined node.js.
A template for using p5play in a node.js server with q5, canvas, and jsdom packages will be published soon!
Documented p5play's touches
array!
https://p5play.org/learn/input.html?page=5
Fixed #298
Implemented #258 kb.visible = true
only works if done inside the p5/q5 touchStarted
function.
Fixed this but only with p5.js #296
Forgot to add the fix to #270 into the new release. Re-added...
Fixed bug with touches not ending. A variable name was wrong in one place.
Fixed crash with "pixelated" preset when using p5play with p5.js. I forgot one line of code ah. Thanks to @ coding on Discord for reporting the error.
The future is here: p5play v3.19 now supports HDR color space when used with q5.js! ✨ https://github.com/quinton-ashley/q5.js https://github.com/quinton-ashley/q5.js/issues/24
Thusly, p5play.org has been upgraded to display vibrant colors and images on HDR devices. 👀 https://p5play.org
Check out my "HDR Web Design Guide" for more info on how to use HDR in your own projects. 🤝 https://quinton-ashley.github.io/hdr-web-design-guide/
New feature: sprite.opacity
which changes the opacity of the sprite, whether it's drawn using shapes or images.
Keep this a secret for now, but I also added p5play style input functions pressing
and dragging
for touch objects in the touches
array. I will announce this feature on Discord after I write documentation for it. 😅
https://p5play.org/learn/input_devices.html?page=5
Upgraded p5play's license from the GPLv3 to the AGPLv3. See LICENSING.md for more info.
The fullscreen and pixelated (no scalar) canvas presets are now programmed to decide to scale width or height to 100% by comparing the aspect ratio of the canvas to the aspect ratio of the window.
if (c.w / c.h > window.innerWidth / window.innerHeight) style += 'width: 100%!important; height: auto!important;';
else style += 'height: 100%!important; width: auto!important;';
Fixed #281
I added a new feature to make it easier to make tile based games. When using sprite.move
with a sprite that has a tileSize
(not equal to 1), and an input distance that's divisible by 0.5, and an input direction name or cardinal direction angle, then the distance the sprite moves will be rounded up to the nearest half tile.
Also improved the canvas "fullscreen" preset and wrote documentation for it. https://p5play.org/learn/canvas.html?page=0
Reverted some incorrect changes to move
and moveTo
. For better performance, I tried making it so that if a sprite is moved in a cardinal direction, the calculations for one axis of movement would be skipped, but these functions still need to override that axis of movement. In the docs it says inputting direction in these functions should be equivalent to changing the sprite.direction
property, like this:
sprite.move(1, 'left');
// is equivalent to
sprite.direction = 'left';
sprite.move(1);
For non-imperative movement, applyForce
can be used.
Fixed sprite.moveTo
function errors introduced in v3.17.
Changed the implementation of the sleep
function, when run without arguments it now resolve it's promise after the next world step is complete, instead of using requestAnimationFrame
. Pretty much the same result in normal use cases but it could allow users to run world.step
separate from the canvas display rate and have functions like move
and moveTo
still work. Previously they were tied to the frame rate too.
Upgraded p5play's rotated text caching system to work exclusively with p5.js v1.9.0 (latest) and any future releases.
This is because p5.js' devs made some breaking changes to p5.Graphics.get
which makes the current implementation of text caching in p5play incompatible with older versions of p5.js.
Fixes for text caching bugs with p5.js v1.8.0.
Bug fix. When setting a sprite's collider type to 'none' with the property setter, for sprites with no overlap sensors, after destroying the body I needed to also set this.body = null
.
Support for negative sprite.scale
(which mirrors the sprite).
Support use of sprite.moveTo
with null values for x or y destination. Will only ensure move along one axis, used internally by move
if a cardinal direction is used.
Took out the deprecation warning for group.collides(sprite)
cause even though its implementation is a bit messier than sprite.collides(group)
I think the former can read better for users in some scenarios, especially if only the first input param to the callback needs to be used. For example:
arrows.collides(shield, (arrow) => arrow.remove());
Added warning if animation is cloned before it's loaded:
The animation named "${this.name}" must be loaded before it can be properly copied. Sprites need their own copy of a group's animation. Try loading the animation in the preload function and creating new group sprites in the setup function.
Fixed a little mistake in the internal helper function group._ensureCollide
. I had set hasOverlaps
to true for reflexive group collisions, sprites in the same group. Which broke the example on Tile page 1.
Also only if a sprite has a tileSize
greater than 1 will it's movement with the sprite.move
function be rounded to the nearest half tileSize if direction names are used.
https://p5play.org/learn/tiles.html?page=1
Last month p5.js v1.8.0 added support for pixelDensity in p5.Graphic and p5.Image, so I had to edit p5play's textCache code to be compatible with the changes. Thanks to @ Mike on Discord for noticing this issue!
Discord user @ zeebeejeebee pointed out that this use case was previously supported new Sprite(x, y, colliderType)
but I had forgot that was a valid use. Just added it back!
Also I better documented all the different ways the Sprite constructor can be used.
Earlier I upgraded the setter for sprite.collider
so that it would not destroy the sprite's body and instead use the new planck function body.setType
, which is a much more efficient way to do it, but this change had a lot of unintended consequences. In the process of fixing the issues I refactored the Sprite constructor, which was a total mess! There was lots of duplicate code in the Sprite constructor and sprite.addCollider
which I consolidated and organized better.
Additional fix for reflexive group contact handling so it can work when called after the group's sprites are created.
groupA.overlaps(groupA)
Fixed issue where only setting group.width
and not group.height
would make new GroupSprites be circles, when they should be boxes.
Updated the setter for sprite.shape
which no longer destroy's the sprite's physics body, it removes the sprite's fixtures, then creates new ones based on the desired shape. The sprite's mass is now recalculated if the sprite's shape changes, this was in the documentation but by mistake had not actually been implemented.
Fixed issue changing a "none" collider with a "circle" shape to any non-"none" collider type.
SpriteAnimation set frame now throws an error if the user tries to set a frame value that's too high (or low).
Breaking change to a previously undocumented feature, world.offset
which is now called world.origin
because it doesn't behave the same as sprite.offset
, it just sets where the origin (0, 0) of the world is on the canvas, effectively translating every sprite. Also the physics world doesn't have a size, so it was misleading to have world.hw
and world.hh
(half-width and half-height) properties, those are now properties of the p5 canvas
.
The new contact handling system did have one issue I hadn't tested for.
Just fixed reflexive group contact handling, where a contact handler is set between members of a group.
groupA.overlaps(groupA, cb);
Used in Fruit 2048: https://arissazh.github.io/final-project/
This update contains mostly internal changes (refactoring 🧼). I rewrote a big part of p5play's contact handling system... again. 🐳 But I think I've finally cracked it with the perfect mix of good performance, memory efficiency, and much more readable code.
Also, it's now possible to set a group contact (collision or overlap) handler and then additional contact handler between group members. I don't know how useful this feature will actually be but it is what users would expect. I achieved this new capability by doing another overhaul of how contact relationships, collisions and overlaps, are implemented internally.
I added a ton of contact handling Jest tests to the Sprite.test.js and Group.test.js files to try to ensure this implementation is correct. 🤞🏻
Fix for #275
Fixed group to group overlap checks.
If a sprite is added to a group that was previously removed with group.remove()
, users will get this warning.
"Adding a sprite to a group that was removed. Use group.removeAll()
to remove all of a group's sprites without removing the group itself. Restoring the group in p5play's memory."
This provides backwards compatibility with previous version of p5play where group.remove
and group.removeAll
were exactly the same.
Fixed #270 problem with instance mode cause I acidentally used touches
instead of this.touches
in __ontouchstart
I also added _ontouchmove
to make dragging sprites work.
Fixed sprite to group contact callback input params being ordered wrong only if group sprites were added to the group after the contact was set.
Includes bug fixes for all known issues!
Fixes #262, #265, #266, #267, #269, #270, #271, #272, #273, #274
I pretty much re-implemented how p5play handles contacts (collisions and overlaps) for better performance, which is why this update took 2 months to finish. 😅
sprite.mouse
now functions properly on mobile touchscreen devices.
Another important change is that setting a sprite's collider type to "none" does not remove its overlap sensors. Any projects that took advantage of that erroneous behavior can additionally use the sprite.removeSensors()
function.
Also I did a lot of little updates to p5play.org. The homepage videos play automatically on mobile now, I made them play based on whether they're observed, not based on the mouse hover position.
Fix for rotated text images with centered text alignment.
I also noticed text image caching fixes rotation jitter.
pixelPerfect
implementation should check the dimensions (width and height) of a sprite's current animation frame, not the dimensions of its collider when calculating the pixel perfect position for images with odd side lengths. For example, an image with a width of 5 should have its x position rounded to the nearest integer + 0.5 so that the image can be displayed pixel perfectly.
Proper fix for #256
I didn't consider that if group sprites with no colliders are set to overlap on a group level, at the time addDefaultSensors
is called sprite._angle
would not exist. I switched the order of those lines in the Sprite constructor to make it work. I also never considered that the sprite needs to maintain its velocity vector as well, so I added that too.
Properly fixed #261 createTextImage
now returns a p5.Image
with correct sizing.
Also fixed p5play.palettes
not being assigned the default color palette.
Fixed mouse.dragging
. Also now sprite.mouse.hovering
and sprite.mouse.pressing
are strictly true only if the mouse is currently pressing on the sprite, so if the sprite moves they'll be false. sprite.mouse.dragging
is still suitably sticky, even if the mouse stops hovering directly over the sprite during the drag, it'll still drag.
Better fix for #256
p5.js actually sets textLeading
to be 1.25x textSize
by default, so I needed to adjust the position of text images to accommodate that. Also upgraded q5 to have the same behavior.
I also added the version number to the top of the file, haha I always forget.
Added not just a 2x or 5x, but a ridiculous 90x performance increase for rendering rotated text! All thanks to the new text image cache system. This feature is enabled by default, simply use the text
function as you normally would and p5play handles the rest behind the scenes.
Why does VSCode autocompletion only work inside the p5.js setup function? https://github.com/quinton-ashley/p5play/wiki/FAQ#why-does-vscode-auto-completion-only-work-inside-the-p5js-setup-function
Also fixed issues #253 and #256
Added group.velocity
alias for group.vel
.
Fixed a small mistake made in v3.13.0, group sprites should inherit group.speed
.
Sprites made with the GroupSprite
constructor new group.Sprite()
now have auto-completion! Same with Subgroup
groups.
Added types for input devices so that they can get auto-completions in VSCode too! #254
I also added contro.leftTrigger
and contro.rightTrigger
getters, thanks to discord user @ Metamere
Fixed #255
Removed all private (underscored) properties and methods from p5play.d.ts.
BIG update! Auto-complete in VSCode is here!
To add auto-completion to an existing project use npm or bun to install @types/p5 and p5play and add this jsconfig.json
file to your project folder:
{
"compilerOptions": {
"target": "ESNext"
},
"include": ["*.js", "**/*.js", "node_modules/@types/p5/global.d.ts", "node_modules/p5play/p5play.d.ts"]
}
Optionally, you can use the new p5play-vscode extension to create a new p5play project that will have auto-complete enabled. Huge thanks to @ Yog for his research and work on the extension.
This update to p5play adds a p5play.d.ts file to the p5play npm package.
This update also includes:
- fix for sprites not inheriting the name of an animation from a group animation (including when used with the Tiles constructor)
The dimensions of a sprite that's created from a group with defined dimensions can now be overridden in the sprite's constructor, as users would expect.
let g = new Group();
g.d = 20;
// inherits diameter of 20
new g.Sprite(60, 60);
// overrides with diameter of 40
new g.Sprite(10, 10, 40);
planck.js bug 263 was fixed, p5play now uses v1 beta16
Workaround fix for an error found in v1 beta15 of planck. https://github.com/piqnt/planck.js/issues/263
The offsetA
and offsetB
properties of DistanceJoint
and HingeJoint
were not properly implemented. @ Raj noticed that changing the offsets would change the positions of the attached sprites, which is not desirable! Also, sprite rotation is now accounted for when drawing joints with offset attachment points. I had previously announced that joints were finalized but the problem was that I tested joints with sprites that were too small for me to see the problems with changing the joint's offsets. Now they are good!
Added mouse.visible
, a boolean property for easily hiding the mouse, and mouse.cursor
which can be used to change the mouse's style. Will make a documentation page demoing this.
kb
letter key properties are now available in upper case, in addition to lower case. When using functions like kb.pressing()
the key name can be case insensitive, but special keys now uses camelCase
property names instead of PascalCase
.
Keyboard letter input will not be case sensitive.
See the updated learn page: https://p5play.org/learn/input_devices.html?page=1
Fixed kb
input detection for letter keys when users are pressing shift.
For other keys like "enter" and "arrowUp", kb
properties now use camelCase instead of PascalCase which is typical for JS properties, though the input functions, like kb.pressing
are still not case sensitive for these keys. I also added a few aliases such as "option" for "alt", "command" and "windows" for "meta", "ctrl" for "control", etc.
Also updated planck to v1.0 beta15
Fixed pixelPerfect
and upgraded planck.js to v1 beta 13.
Fixed param check for applyForce
and applyForceScaled
.
Also fixed renderStats
sprite count when sprites are drawn manually in the p5.js draw loop.
Upgraded planck.js to v1.0 beta10 which features huge performance improvements! Huge thanks to the lead developer of planck, Ali Shakiba!
Check out the updated page on "Advanced Movement"!
https://p5play.org/learn/sprite.html?page=15
This release included a breaking change to the applyForce
function, as recommended by @ Raj Raizada. It no longer scales the applied force to the sprite's mass. I also created the bearing
property and attractTo
function.
Made renderStats
render above all other content drawn on the canvas no matter where it's placed in the p5.js draw
function, just cause that's how everyone would want to use it and then they don't have to fuss with manually drawing sprites before renderStats
.
Google Analytics will only load its script once per page now, no matter how many instances of p5play are on a page.
Added Google Analytics tracking so I can see how the library is being used. 🕵️♂️
Updated the EULA: "You consent to p5play using Google Analytics to track how the p5play library is used."
Also the Tiles
constructor will now ignore an initial new line character in its first parameter input string. This is so users can use backticks like this:
new Tiles(
`
ggg
sssgg
sssssgg
`,
100,
100
);
Instead of having to use it like this for the tile sprites to appear at the specified position.
new Tiles(
`ggg
sssgg
sssssgg
`,
100,
100
);
Changing camera.zoom
recalculates the camera's visible boundaries, as it should.
Fixed issue with sprites not being visible if their collider was set to none and they had overlap sensors.
The default camera
position (centered) is now set when the canvas is created, instead of in frame 1 of pre draw. This is a better way and also enables p5play to be compatible with p5.SceneManager.
Fixed problem with canvas.resize
not working with p5.js
Implemented resizeCanvas
and canvas.resize
https://p5play.org/learn/canvas.html?page=2
Fixed bug (regression) that caused inter-group collisions/overlaps to trigger their callback function twice.
I've made some important bug fixes in v3.9 so I thought it'd be good to do another minor version bump to v3.10. 🎆
Also in this update, I took out a lot of deprecated functions I had added warnings to months ago. I removed the Netcode
class as well, since it will only be useful for multiplayer games in the future and doesn't need to be part of the base p5play.js file. It will be included in p5play-pro.js as part of my upcoming release of p5play Pro features. p5play.min.js is now only 86kb.
Additionally, I fixed a critical bug 🐛 that was found by discord user rajraizada ! Big thanks to him!
If you always set a sprite's dimensions using the Sprite
constructor or using group inheritance, you don't have to worry about the ramifications of this bug fix. This bug fix had no negative affects on any p5play.org examples.
TLDR: The default mass of a sprite is now the same whether its dimensions are set in the Sprite
constructor or defined after the sprite gets created. Check out the updated "Physical Attributes" Learn page for a concise explanation of sprite.mass
.
Here's an in-depth explanation of what the problem was.
In p5play v3 all Sprite
constructor parameters are optional. This flexibility primarily exists to make p5play easier to learn for beginners, since after learning how to use the constructor most people would prefer using it to create sprites faster. But my intention was to make setting the sprite's position and dimensions later equivalent to setting them in the constructor. I've always promised that in the documentation.
However, Raj noticed that when setting a sprite's width and height after it was created without dimension parameters, the sprite's mass didn't change from the default 50x50 box collider sprite mass. That was not good, a big oversight!
Yet, when a sprite's dimensions change after they've already been defined by the user, the mass of the sprite should not change. This is because p5play doesn't make the assumption that any additional matter is theoretically being added to the sprite as its dimension changes. That's because in the real world, stretching or squishing an object doesn't change its mass.
function setup() {
new Canvas(400, 400);
spriteA = new Sprite();
log(spriteA.mass); // logs the default sprite's 50x50 box collider mass of ~3.461
spriteA.w = 20;
spriteA.h = 100;
log(spriteA.mass); // mass changes when the sprite's size is initially defined
spriteA.h = 200;
log(spriteA.mass); // mass doesn't change because the size of the sprite was already set
spriteB = new Sprite(100, 200, 20, 100);
log(spriteB.mass); // nearly the same as spriteA
spriteB.h = 200;
log(spriteB.mass); // mass doesn't change because the size of the sprite was already set
}
function draw() {
background(255);
}
Skip drawing sensors unless sprite.debug
is true.
Finalized implementing RopeJoint
! Will make a Learn page for it soon.
Changing a sprite's collider type will remove all the joints attached to that collider. A console warning appears if users try to change the collider of a sprite that has joints. The sprite's collider type should be set before any joints are added to it or removing joints should be done explicitly with sprite.joints.removeAll()
Fixed issue with sprites with none colliders having rotation
set to NaN
Finalized the implementation of GlueJoint, DistanceJoint, WheelJoint, HingeJoint, and SliderJoint!
p5play's new Canvas
no longer applies styles to all canvases, just in the .p5Canvas
class. Also pixelated preset styling is now only applied to a canvas using its individual id.
Fix for a regression introduced by v3.8.37 two weeks ago. The algorithm in the Sprite
constructor can now accurately search for animations if a sprite inherits from multiple groups that have animations with the same names. I forgot how important the order of the sprite.groups
array is because the function that finds animations needs to start with the lowest subgroup that the sprite is part of and then end with searching for the animation in the allSprites
group.
Quick fix for #249 but I will implement a better fix that'll be available in v3.9
I realized the spriteArt page didn't have a color table or any kind of illustration of the default color palette. Whoops!
I decided to update the default color palette in p5play so it now has a color for each letter of the alphabet! (even the letters that don't really have a color commonly associated with them) Then I improved the Learn reference page for the spriteArt function by adding a sketch that illustrates what color each letter represents.
The custom color palette section is now last and I give a brief intro level explanation of what a JavaScript Object is.
https://p5play.org/learn/sprite.html?page=3
Actually fixed joint.springiness
lol
The contro.released
function now properly detects when game controller buttons are released. Thanks to Discord user @Tezumie for reporting that issue.
When sprites are added to a group using group.push
or its alias group.add
, the sprite will now inherit the group's collision and overlap relationships with other sprites and groups. New group sprites will also inherit any previously set relations as well. Thanks to Discord user @Day for reporting that issue.
Several issues with q5.js compatibility were also fixed recently.
Sensors are now sorted to be in the back of the sprite's fixture list when added. This ensures that physics attribute getters only get values from the sprite's most recently added collider, unless it had its colliders removed.
Fixed a pretty major oversight in regards to the contact system, which was demonstrated to me by Discord user @Day. In previous versions, for example colliding
checks would not return a truthy frame value on the first frame of collision, when collides
returns true. Also when sprites collide and stop colliding on the same exact frame, usually due to colliding with other sprites on that frame, collides
wouldn't return true like it should. Now it all works just like the input system (ex. presses, pressing, pressed), as described in the docs!
Fixed a bug with group collisions not calling their callbacks if it also had contacts with another group, such as allSprites.
Bug fixes and fixes for my previous bug fixes... whoops! v3.9 is coming soon.
RevoluteJoint was renamed to HingeJoint
. Added SliderJoint
(wrapper for PrismaticJoint). Renamed maxTorque and torque to maxPower
and power
.
GlueJoint, DistanceJoint, WheelJoint, and RevoluteJoint classes have been added to p5play! The implementation of these joints and an additional joint will be finalized in v3.9.
Implemented proper mouse dragging detection. Also if a sprite is above multiple sprites that are overlapping, the mouse is only considered to be hovering over the sprite on the highest layer.
Fixed sprite.moveTowards
not reseting velocity to zero if the sprite is so close to the target position that it shouldn't move.
Move and rotate functions no longer throw an error if given null arguments, the sprite simply won't move. Enabling this usage will give users more flexibility. I think it'll be especially beneficial for testing multiplayer games in the future.
I've added a new global variable, netcode
, which is an instance of the p5play Netcode
class. It contains utility functions like spriteToBinary
and binaryToSprite
that will enable online multiplayer. I am not finished with it yet, but I'm publishing the code in case anyone has feedback or wants to collaborate with me on it!
Fixed move
and moveTo
not working properly if tileSize
was not 1.
The move
, moveTo
, rotate
, and rotateTo
sprite functions all return a Promise that resolves to true when the movement is finished.
But, if the sprite's movement is interrupted by a new movement or a collision that significantly changes the sprite's trajectory, the promise will resolve to false.
I also fixed a bug that caused sprite.offset
to not be maintained when changing the sprite's collider type.
Added cavas.w
/canvas.width
and canvas.h
/canvas.height
which you should use instead of the p5.js instance width
and height
variables, which are not specific enough and can lead to confusion. I changed all the p5play docs to use canvas.w
and canvas.h
.
Replaced sprite.offsetCenter
with a sprite.offset
object that has x and y properties. It can be changed for a whole group of sprites using group.offset
. Added support for other group object props like mirror and scale.
I added a offsetCenter
function that enables users to offset the center of a sprite. Also the rotateTo
and rotateTowards
functions can now use angles, as suggested by @ busch! I updated the examples:
https://p5play.org/learn/sprite.html?page=7
These functions can still accept position objects with x and y coordinates. However, if you want to provide position coordinates as numbers, then speed must be specified in the function as well.
Sensors can be added to a sprite with a collider type of "none". I also added a new function addSensor
which adds overlap sensors to a sprite. I added removeColliders
and removeSensors
but these functions completely remove colliders/sensors so in most cases it's better to use collision functions like collides
to disable, without entirely removing, overlap sensors, and vice versa, use overlap functions like overlaps
to disable colliders.
Bug fix for group collisions and overlaps. Sprites could not begin contact with a group on the same frame as ending contact with another sprite in the same group.
User's can now set the camera's position in the p5.js setup function.
In previous versions there was no way to disable an overlap between sprites/groups, without changing the sprite's collider type. A student of @Bobby S. suggested that overlaps could be disabled by explicitly checking for a collision and vice versa. Now why hadn't I thought of that!? 🧠 🧐
Check out the new "ghost ability" example! 👻 https://p5play.org/learn/sprite.html?page=6
I added a new "made with p5play" intro loading screen, similar to Unity's. But don't worry, it won't show up when you're developing with p5play in VSCode or any popular online code editor. I wanted to keep the loading screen simple but at least making it more interesting and professional looking than p5.js' basic "...loading" text.
What better way to unveil this new feature than with two of my favorite projects that were made with p5play: @Axiom's "Squirrel" art and @Nitmay's "Red Remover" game!
https://quinton-ashley.github.io/Squirrel/Code/index.html https://thegamebox.ca/redremover.html
I added a new sprite property called pixelPerfect for displaying sprites at integer coordinates, while retaining the precise position of the sprite's collider. Useful for pixel art games! 👾
Bug fix. Adding an image/animation to a sprite that has no specified dimensions should change it's dimensions.
Bug fix for when a sprite's dimensions are not defined in the constructor, then the user would expect the mass to change after they define the sprite's dimensions.
Performance improvements!
Collision and overlap handling in p5play (not talking about the physics solver here) is now faster. Behind the scenes of functions like overlaps
I was using JS Map. Each sprite and group had a map, and these maps used, as keys, the sprites/groups that the sprite/group overlapped with. But, I found out that getting and setting object properties that use integers as keys is nearly twice as fast! So now each sprite and group have unique ids for use in these objects.
Also now when a sprite gets removed that was previously colliding or overlapping with another sprite, it will still trigger collided
and overlapped
callbacks if it has any.
Fixed culling bug and the last p5play compatibility issue with q5.js! (at least as far as I've tested)
Major bug fixes for testing group collisions. Also group.push (and its alias group.add) can now accept multiple sprites and returns the new length of the group just like Array.push does. Thanks to @calebfoss for reporting these problems!
Fixed rotateTo
bug that caused sprites to spin infinitely. q5.js is now used on every page of p5play.org!
Fixed bug with sprite.scale not working. I'll add tests for this so it doesn't happen again.
Bug fixes. When a sprite's collider is switched to 'none' it now retains its current position and vector, as expected.
I updated the sprite movement page to include the new angleTo
function. Inspired by @ Andy Shaw#1876's issue report of performance problems with using moveTo
every frame.
https://p5play.org/learn/sprite.html?page=2
Also sprite.anis
and group.anis
objects now function like groups do for sprites, they can enact soft and dynamic inheritance on the animations they contain. Example reference page coming soon!
sprite.debug = true
now shows the outline of the sprite's collider over the sprite's image/animation. Suggested by @ Lil Bobbity Scribbler#3858 !
Added the ability to define a scale for a canvas with the "pixelated" preset.
new Canvas(256, 240, 'pixelated x2');
Also entering keyboard input functions now autocorrect number keys inputted as JS Numbers by converting them to a string.
kb.pressing(5);
Added the version number to the top of the file.
@everyone v3.6 includes some critical bug fixes for p5play when used in p5.js instance mode, that were introduced in recent versions of v3.5. I also added beta support for q5.js, a small and fast alternative to p5.js. https://github.com/quinton-ashley/q5.js
In addition, I've made some important changes, to features that were mostly undocumented, which give users a greater degree of control over the drawing, physics stepping, and updating of sprites. 🔃
Before, if any sprite was drawn manually in the p5.js draw loop with sprite.draw()
, then every other sprite will not automatically be drawn and must also be drawn manually. That's probably not what most people would expect. Also there was no way to update animations without also progressing time in the physics world. 🌐
To see how I fixed these problems, check out this new page in the advanced topics section: https://p5play.org/learn/advanced.html?page=3
I also made some structural/naming improvements to help users known what functions rely on the physics world and which ones do not.
getSpriteAt
is now world.getSpriteAt
getSpritesAt
is now world.getSpritesAt
updateSprites
is now world.step
and allSprites.update
p5play.autoDrawSprites
is now a property of groups and sprites called autoDraw
p5play.autoUpdateSprites
is now a property of groups and sprites called autoUpdate
world.autoResetAnimation
is now a property of groups and sprites called resetAnimationsOnChange
world.palettes
is now p5play.palettes
Fixed #237 and the Turtle class not being able to make a Sprite
"p5.play" is now called "p5play"!
Fixed a bug that prevented users being unable to set sprite.ani
to a SpriteAnimation object. For example:
sprite.ani = loadAni('splat00.png', 7);
The best way is still to use sprite.addAni
though:
sprite.addAni('splat00.png', 7);
Added an experimental function sprite.addCollider
which adds a collider (fixture) to the sprite's physics body.
It accepts parameters in a similar format to the Sprite constructor except the first two parameters are x and y offsets, the distance the new collider should be from the sprite's (x, y) position.
One limitation of the current implementation is that the collider type can't be changed without losing every collider added to the sprite besides the first. This will be fixed in a future release.
I improved the contro
interface for getting input from game controllers, adding support for the GuliKit KingKong 2 Pro Controller. I also fixed a vertex mode polygon positioning bug.
Setting sprite.img
or sprite.image
still changes the image into a single frame animation that the sprite uses. But getting sprite.img
or sprite.image
now returns whatever the sprite is displaying, equivalent to sprite.ani.frameImage
.
I noticed some of my students changing the collider of sprites to static and then trying to assign the sprite a new position or size, which isn't how static colliders are intended to be used. 🙈 This caused really crazy errors when other physics bodies interact with a static collider that's had its size changed. But... instead of throwing an error if users try to do this, I just fixed the problem by forcing planck to update a static colliders size when it gets changed! So now the following code is totally fine. 😎
sprite = new Sprite();
sprite.collider = 'static';
sprite.w = 100;
Improved user error reports for collide and overlap functions
Fixed an bug with setting a circle sprite's collider type after its creation which would cause the sprite to be a box
Added sprite.stroke
and sprite.strokeWeight
Simplified and added more documentation for getting the state of an input from an input device. https://p5play.org/learn/input_devices.html
Also the inputDevice.pressing
function now returns the amount of frames the user has been pressing the input. Any non-zero number is considered truthy in JS so the function can still be used in if
statements just like before. This change brings the function inline with user expectations from the other "-ing" functions like sprite.colliding
and sprite.overlapping
.
Fixed a bug that prevented sprite.text = 0
from displaying the text "0" on the sprite.
Improved documentation
Using the SpriteAnimation
constructor is now equivalent to using loadAnimation
. I also fixed inheritance order for animations, if say you had a default animation for the allSprites
group and a default for the sprite's immediate parent group, then the sprite would inherent the default animation from it's parent group.
A sprite with no collider ("none") can now be set to have a "dynamic", "kinematic", or "static" collider.
One of my students convinced me that it was a bad decision I made in v3.3.9 (8 days ago) to detach a sprite's scale from the scale of its animations (making it only scale the sprite's collider).
The problem is that if a sprite has a lot of animations, then it's very tedious to go through and scale all of them individually. 😭 I think they're right. If you need to scale a sprite's animation individually you still can, but now it will have a multiplier effect on top of the sprite's scale. I think that makes a lot more sense intuitively. 🧠
Here is the finalized example of using sprite.scale: https://editor.p5js.org/quinton-ashley/sketches/rQZNY7-n6
Fixed changing the collider type of circle sprite, a regression in 3.4.0 made it turn in to a box. If moveTo
or moveTowards
is used with the mouse
object, the sprite or group will not move until the player performs a mouse input or hovers on the canvas.
Fixed origin calculation for non-convex polygon shaped chain colliders. Such as the hourglass in this example: https://p5play.org/demos/?file=hourglass.js
I made this page to demonstrate movement sequencing via the power of async/await! 🐢 https://p5play.org/learn/sprite.html?page=8
When working on that page, I noticed a problem with polygon/chain sprite rotations: their (x,y) position changed slightly while the sprite was being rotated! OOF.. 😟 TLDR: I fixed it. 🥳
Turns out planck uses the triangle centroid (vertex averaging) method of determining the center of any polygon physics body, meanwhile I was just taking the total width and height and dividing it in half to get the center. So when rotated, a polygon physics body's center would no longer match up with its center in p5.play. Fast forward a whole day of coding later: problem solved! These changes have no effect on sprites with box, circle, and non-polygon shaped chain sprites.
image/ani related bug fixes
Fixed sprite.scale
which, if used more than once, used to not work how one might expect.
sprite.scale = 2; // scale the sprite 2x its original size
sprite.scale = 2; // expectation: should do nothing
In previous versions, if sprite.scale
was set to 2 more than once it would double the size of the sprite! This is inconsistent behavior, given how the p5.js scale
function works and how animation.scale
works. Sprite collider scale values are now always multiples of the original scale the sprite was at, not its current size.
Also HAS SCIENCE GONE TOO FAR?! 👨🔬 I made it so sprite.scale
and sprite.ani.scale
could be used as a number (the average of the x and y scale components) and also as an object with x and y parameters! 🧪
Check out this example: https://editor.p5js.org/quinton-ashley/sketches/rQZNY7-n6
In this update I also added the ability for a sprite's size to be defined by the size of the first image or animation added to it, just like how the Sprite constructor is able to do so if the image/ani is defined in the constructor.
// image/ani in constructor
let ball = new Sprite(ballAnimation);
// image/ani added outside the constructor
let ball = new Sprite();
ball.ani = ballAnimation;
The v3.3.5 update introduces a preset option called "pixelated" 👾 for the createCanvas function and new Canvas constructor.
// (width, height, preset)
new Canvas(256, 240, 'pixelated');
Making a retro 8-bit or 16-bit style game with p5.js used to be pretty difficult. That's because by default p5.js runs at high resolutions and low res sketches are displayed at a very small size on modern displays. But now, just by using the "pixelated" preset, p5.js will render chunky pixel goodness! 🕹️
How does it work? It scales the canvas to fullscreen while maintaining the aspect ratio of the dimensions given to it. It sets the CSS canvas property "image-rendering" to "pixelated". It also sets the p5.js pixelDensity to 1 and enables noSmooth.
This is the first preset I've made but in the future I will also make a "mobile" preset for mobile touch screen devices that will create on screen buttons that interface with the contro object in p5.play. 📲
In other news, I've also reverted all the template code links from the jsDelivr CDN back to the p5play.org library location. Students using the CDN links reported problems with p5.play due to their cached library file being outdated. I found out using the CDN links can cache the file on a user's computer for up to seven days! 😲 I'd prefer for users to be able to use the latest features without delay.
Fixed the sprite.scale
setter, if used in p5.js draw and set to the same value it would constantly remove the sprite's collider and add it back at the same scale, now if set to the same scale amount it does nothing, as expected.
- The p5.js
keyIsDown
function had already been deprecated in p5.play v3 for a long time. @Caleb Foss (they/them)#6472 pointed out that it's unexpected for p5.play to override this function with the non-equivalent kb.pressing function, which only accepts key names and not key codes. So as of this update any use of the p5.jskeyIsDown
function will result in this error:
Error: The p5.js keyIsDown function is outdated and can't be used in p5.play. Trust me, you'll see that the p5.play kb.pressing function is much better. It uses key name strings that are easier to write and easier to read! https://p5play.org/learn/input_devices.html The p5.js keyIsDown function relies on key codes and custom constants for key codes, which are not only hard to remember but were also deprecated in the JavaScript language standards over six years ago and shouldn't be used in new projects. More info: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
- changing a sprite's collider property with a single letter now works properly in both the Sprite constructor and the collider setter
- I fixed a bug caught by @axiom.split . Scaling a sprite's current animation can now be done by setting sprite.ani.scale.x and sprite.ani.scale.y. Each of a sprite's animations can now potentially have their own (x, y) scale.
There is one breaking change in this release. The sprite.move
function's parameter order is now (distance, direction, speed). I promise not to make any more breaking changes like this to existing functions!
I made this change due to feedback from my students. One of my goals with p5.play is to not have many functions that absolutely require more than one parameter. I realized that if I made distance the first parameter in the move
function then users could set direction and speed separately.
// single parameter usage
sprite.direction = 'up';
sprite.speed = 5;
sprite.move(50);
// multi-param usage
// (distance, direction, speed)
sprite.move(50, 'up', 5);
Pretty nice huh? The rotate
function works similarly.
// single param
sprite.rotationSpeed = 2;
sprite.rotate(90);
// multi-param
// (rotationAmount, speed)
sprite.rotate(90, 2);
If no direction is given the sprite will move 'forward', in the direction of it's current angle of rotation, (like in Turtle programming 🐢 ).
turtle.rotate(90);
turtle.move(50);
The old move
function parameter order (direction, speed) can still be used if the direction is a direction name (ex. "up"). The default distance is 1. This is nice for tile based games.
pawn.move('up');
This update also improves the rotate
, rotateTo
, rotateTowards
functions. :kirbyRotate: These functions required a lot of complicated math which makes them valuable additions to p5.play. Check out the new learn page: https://p5play.org/learn/sprite.html?page=7
Thanks to @Gabriel Caldas#6327 suggestion, setting the sprite.img
or sprite.image
property to a p5.js Image can now add that image to the sprite. group.img
and group.image
work for groups too.
- added a reference page for the sprite rotation methods
rotate
,rotateTo
,rotateTowards
https://p5play.org/learn/sprite.html?page=7 - fixed the hourglass demo, now it doesn't lose a grain of sand! https://p5play.org/demos/?file=hourglass.js
- fixed #230 and #231
- fixed bug in the previous version (v3.2.20) that caused new Sprite not working in the p5.js preload function.
textSize()
doesn't exist until the canvas is created, I didn't know that!
Bug fixes!
There are now three distinct movement functions: move
(in a direction, at a fixed speed, across a distance), moveTo
(to a position, at a fixed speed), and moveTowards
(towards a position, at a percentage of the distance to that point). Check them out here: https://p5play.org/learn/sprite.html?page=2
Any arrow function added to a group will be used as a property setter that will be evaluated when a new sprite from that group is created. https://p5play.org/learn/group.html?page=1 This will work for custom properties now, not just the p5.play sprite properties! To add a function to a Group use the function
keyword.
Also the moveTowards
function can now accept any object with (x,y) properties.
enemies = new Group();
enemies.health = () => random(50, 70);
enemies.attack = function () {
enemies.moveTowards(player);
};
I added a new mode to the Sprite constructor for making regular polygons!
// ( x, y, sideLength, polygonName)
new Sprite(250, 100, 80, 'pentagon');
See the updated reference page for more info: http://p5play.org/learn/sprite.html?page=8
p5.play is now available on Open Processing! Follow me (Quinton Ashley) if you'd like to see what I'll be making with p5.play and I'll follow you back. https://openprocessing.org/user/350295?o=6&view=sketches
I've updated how chain and polygon sprites can be created using the Sprite constructor. There are now three different modes: vertex, distance, and line! For more info see the updated reference page: https://p5play.org/learn/sprite.html?page=7
I also added auto-correcting to user input functions so case insensitive input strings can be used. In previous versions the following boolean condition would always return false, regardless of if the Enter key or left mouse button was pressed. Now It just works!
kb.presses('enter') || mouse.presses('LEFT');
Fixed a bug in the p5.play loadImage
function that caused the p5.js internal preloadCount
(the count of images, JSON, and other data being loaded in the preload function) to go down by two instead of one when using the addAni
function, which would cause p5.js to run the setup function before other preload content had finished loading.
- replaced the sprite and group property
shapeColor
(deprecated) withcolor
because it's also used for chains colliders which have lines and not shapes - changed
colliding
andoverlapping
to return frame counts of how long the collision or overlap has occurred (which are truthy values in JS so they can still be treated like booleans in if statements) - updated the website to have separate pages for collision and overlap function explanations
https://p5play.org/learn/sprite.html?page=5 https://p5play.org/learn/sprite.html?page=6
CRITICAL fixes for the collided
and overlapped
functions which were not working correctly. Also I fixed the input held
function so that it only returns true if the user releases an input after it was held for 12 frames or longer.
This update contains changes to the input system. I'm sorry to make these changes after p5.play v3's release but I think it's important p5.play uses the same verb conjugations for all timing related functions.
I was inspired to make these changes because I'm adding a new paradigm for custom collide and overlap event handling that won't require the use of callback functions and can be used in if
statements. This feature has been highly requested by my students!
In technical terms, single frame initiative timing functions will use present simple tense naming. Continuous timing functions will use present continuous tense naming. Single frame cessation timing functions will use past simple tense naming. For example collides
, colliding
, and collided
. This will allow users greater control over customizing collision and overlap event response!
presses
will return true on the first frame the user presses an input. holds
will return true when the users holds an input for 12 frames (by default). The mouse functions for detecting hovering will be changed to hovers
, hovering
, and hovered
.
Here is an example of the new collides
function in action. The "old way" will still work too.
// old way
player.collide(block, () => {
block.remove();
});
// new way
if (player.collides(block)) {
block.remove();
}
collides
returns true on the first frame a sprite collides with a target sprite, colliding
returns true while a sprite collides with a target, and collided
returns true on the frame when contact between the sprite and target ends. overlaps
, overlapping
, and overlapped
functions will be available too.
- creating sprites with the Sprite constructor
new Sprite(x, y, w, h)
is equivalent to usingcreateSprite
so extending Sprite can work properly - revised the Asteroids example to include winning and losing mechanics
- added a different version of the Asteroids game that demonstrates how Sprite can be extended
- added a new method Group.cull
- the primary use case for Group.cull is the easy removal of offscreen sprites
- I also added an culling example to the p5.play site
- Quadtree fix when removing sprites #124
- tunneling fix with dev logs for demo purposes #214
- use createSprite(x, y, r) with three parameters to easily create a placeholder circle
- new feature, you can add animations to groups, sprites can use the animations added to a group it belongs to
- cameraPop, cameraPush bug fix #218
Big update to p5.play which now uses ES6 JavaScript classes!
- instanceof works on instances of these classes
- fully backwards compatible with version 1