New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor MultiWay #876
Refactor MultiWay #876
Conversation
ee79d89
to
f6980ea
Compare
b587623
to
5cee553
Compare
@starwed would you kindly take a look at this, if you have time/motivation? would like to hear your opinion |
Sure, I have some work to do this afternoon, but should be able to look at it either later today or tomorrow. |
f83a898
to
6914790
Compare
Alrighty, I have adapted the code a bit. The A possible future issue is that
|
Regarding netplay: It's probably not worth worrying about netplay with Multiway specifically. As soon as you want more control over how an entity moves (whether it's tweaking the physics, having contextual controls, or syncing with a server) you're going to have to write your own code for that stuff. Something like Multiway can't possibly meet every use case -- its main reason for existence is to help someone just starting with Crafty. I'd agree that a component or system that makes it easy to connect input to internal game state would be super usefull! Like you say, we can perhaps convert to a better model in a future PR. |
PR in general: I don't see any specific problems jumping out, but it's a big enough set of changes I'll want to make up a small demo and play around with the upgraded components. |
this.trigger('Moved', {x: oldX, y: newY}); | ||
movedEvent.x = oldX; | ||
movedEvent.y = newY; | ||
this.trigger('Moved', movedEvent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this will matter too much, but the way we've recommended handling collisions is to listen to the "Moved" event, test for collisions, and then move back to the old position if necessary.
The catch here is that this will cause a second "Moved" event to trigger on the entity before the first has returned, and both of them use the same _movedEvent
object. As long as the collision check is the only thing listening to Moved, no big deal, but it might cause some unexpected behavior if someone has multiple event handlers for "Moved".
I think this would be pretty rare, so I'm ok solving this particular issue down the road. But maybe add a comment about it?
Thanks for taking a look at it. We should discuss 3 more things before proceeding. Move Event
How could a second move event be triggered before the first one has returned? if (this._movement.x !== 0) {
this.x += this._movement.x;
this.trigger('Moved', {
x: this.x - this._movement.x,
y: this.y
});
}
if (this._movement.y !== 0) {
this.y += this._movement.y;
this.trigger('Moved', {
x: this.x,
y: this.y - this._movement.y
});
} In order to preserve the old semantics I refactored it to this. However, the event is triggered in the 1st block with the new var movedEvent = this.__movedEvent;
if (this._dx !== 0) {
this.x = newX;
movedEvent.x = oldX;
movedEvent.y = newY;
this.trigger('Moved', movedEvent);
}
if (this._dy !== 0) {
this.y = newY;
movedEvent.x = newX;
movedEvent.y = oldY;
this.trigger('Moved', movedEvent);
} Originally I had this. This makes the most sense to me, even if the var movedEvent = this.__movedEvent;
if (this._dx !== 0 || this._dy !== 0) {
this.x = newX;
this.y = newY;
movedEvent.x = oldX;
movedEvent.y = oldY;
this.trigger('Moved', movedEvent);
} There's even another alternative which circumvents setting var movedEvent = this.__movedEvent;
var chandedX = this._dx !== 0,
changedY = this._dy !== 0;
if (changedX || changedY) {
if (changedX)
this.x = newX;
if (changedY)
this.y = newY;
movedEvent.x = oldX;
movedEvent.y = oldY;
this.trigger('Moved', movedEvent);
} Which approach would you recommend? MoveSpeed IssueIf you use the same speed arguments, from before the Overly cautious event objectsInstead of creating a new object when triggering Specifically the var oldDirection = this.__oldDirection;
var _vx = this._vx, dvx = _vx >> 31 | -_vx >>> 31, // Math.sign(this._vx)
_vy = this._vy, dvy = _vy >> 31 | -_vy >>> 31; // Math.sign(this._vy)
if (oldDirection.x !== dvx || oldDirection.y !== dvy) {
var directionEvent = this.__directionEvent;
directionEvent.x = oldDirection.x = dvx;
directionEvent.y = oldDirection.y = dvy;
this.trigger('NewDirection', directionEvent);
} This could be simplified to the following. However, if user changes properties of the event object, the var directionEvent = this.__directionEvent;
var _vx = this._vx, dvx = _vx >> 31 | -_vx >>> 31, // Math.sign(this._vx)
_vy = this._vy, dvy = _vy >> 31 | -_vy >>> 31; // Math.sign(this._vy)
if (directionEvent.x !== dvx || directionEvent.y !== dvy) {
directionEvent.x = dvx;
directionEvent.y = dvy;
this.trigger('NewDirection', directionEvent);
} What is better here? Favor safety over computational performance every frame? |
I mocked up a simple test, and Multiway seems to work fine to me! I didn't notice any problems with our front-page pong demo either.
Ah true, I was thinking of the separate "Move" event which occurs when you assign new coordinates. So long as code responding to the "Moved" event doesn't trigger "Moved" itself, it's ok.
It totally does! :)
If this is a big pain, it's ok to break backwards compatibility here. It looks to me like the next released version of Crafty will have several breaking changes already, so now it a good time to make painful (but needed) breaks with the past. Was there anything more you wanted to do before this is merged? |
Use Motion component in MultiWay to move entities.
6914790
to
56bc0d9
Compare
Thanks for the pointers, I have updated var movedEvent = this.__movedEvent;
if (this._dx !== 0) {
this.x = newX;
movedEvent.axis = 'x';
movedEvent.oldValue = oldX;
this.trigger('Moved', movedEvent);
}
if (this._dy !== 0) {
this.y = newY;
movedEvent.axis = 'y';
movedEvent.oldValue = oldY;
this.trigger('Moved', movedEvent);
} It makes more sense to me. Is it ok to break backward compatibility here ( |
No objections thus far to the |
Overview
This is the continuation of #708 in order to incorporate the new
Motion
component into the library.This PR focuses on changing
Multiway
to work withMotion
.Details of this PR
The current solution prevents keys for the same direction to move the player twice as fast. However, for more complex scenarios, additional modifications will need to be done (see linked PR/issue)
NewDirection
event toMotion
component, make it trigger beforeEnterFrame
motion tickalso add
NewRevolution
toAngularMotion
component analoguelyNewDirection
andNewRevolution
eventsChanges from user point-of-view
NewDirection
event changed significantly:direction = {x: Math.sign(vx), y: Math.sign(vy)}
-1
,0
or1
Issues
ifresolved, see commentMultiway
is added, while a key is pressed, the component will not function properly (unfortunately as described in Logic separation of components #578 we can not assume access to the keyboard state on the server)I may have a fix for this, but need to test
Multiway
, the speed of movement should be approximately close when using the samespeed
argument before and after this change__convertPixelsToMeters
should multiply by50
, instead of100
, but thenGravity
andTwoway
don't work wellFuture Changes regarding
Motion
2D
tocontrols
)vx
and similar in pixels, internally convert to correct scaleMotion
changes to children_cascade
"MotionChange" events, just like "Move" & "Rotate" events to_children