Skip to content
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

Supporting two controls for engine #2

Closed
wants to merge 8 commits into from

Conversation

akbashev
Copy link

This adds two controls support to engine.

It's really hard to move Player with just one control on mobile phones. Better would be supporting two controls — one for rotation and the other one for movement.

For this purposes this change adds:

  • moving view to a separate one;
  • splitting this view into two with gesture recognisers on each side;
  • changing Input speed property to a vector;
  • update World to move according new Input.

Kinda hard part is that movement should be always adjusted to direction. For this I calculate the rotation of direction from initial position and adjust speed vector. Straightforward, but works.

@akbashev akbashev changed the title Strafing Supporting two controls for engine Jul 13, 2019
@nicklockwood
Copy link
Owner

This looks great, thanks! I'll do a thorough review when I get a chance, but just a couple of preliminary thoughts:

  1. Instead of one view with two joysticks, would it maybe make sense to have a single Joystick view and then have two instances of it? Might reduce some of the code duplication (e.g. for the inputVector method).

  2. are you sure all the extra math functions are needed? It seems like the only new movement in the new control system is the strafing itself, which should just be speed * direction.orthogonal, so I'm not sure why you need to use the cosine or multiply two vectors? (I've not looked at the code in detail yet though)

Copy link
Owner

@nicklockwood nicklockwood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work! I have a few suggestions to simplify the code, but functionality-wise it's perfect, and it's certainly much nicer to play the game with strafing!

I'll cover dual stick controls in a future tutorial, but in the meantime this PR is a great example - thanks!

} else {
rotation = Rotation(sine: sine, cosine: cosine)
}
player.velocity = input.speed.rotated(by: rotation) * player.speed
player.position += player.velocity * timeStep
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be simplified to the following:

    mutating func update(timeStep: Double, input: Input) {
        player.direction = player.direction.rotated(by: input.rotation)
        let forwardVelocity = player.direction * input.speed.x * player.speed
        let strafingVelocity = player.direction.orthogonal * input.speed.y * player.speed
        player.velocity = forwardVelocity + strafingVelocity
        player.position += player.velocity * timeStep
        while let intersection = player.intersection(with: map) {
            player.position -= intersection
        }
    }

Having to useinput.speed.x for forward motion and input.speed.y for strafing is a little confusing, but it's because you're passing leftInputVector.orthogonal as the input speed in ViewController (see below).

let input = Input(
speed: -inputVector.y,
speed: leftInputVector.orthogonal,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you change this to speed: Vector(x: leftInputVector.x, y: -leftInputVector.y) then you can swap input.speed.x and input.speed.y in the World.update() code above, which I think would be more intuitive.

return imageView
}()

private let leftJoyStick = UIView()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest you create a new UIView subclass called JoystickView (or whatever) and move all of the gesture logic into that, so that you only need to create two view instances in the view controller instead of two copies of everything.

@nicklockwood
Copy link
Owner

@akbashev sorry this was auto-closed when I restructured the project after the latest update and I can't reopen it because the history no longer matches up. Please rebase and re-open it when you get a chance, thanks!

@akbashev
Copy link
Author

@nicklockwood hello! first of all thx for quick response :) and no problem, I'm a bit busy, but will try to do it by tomorrow evening...

@nicklockwood
Copy link
Owner

@akbashev do you still plan to update your PR? Otherwise I might create one myself.

@akbashev
Copy link
Author

@nicklockwood sorry I was very busy last several months. What is the status now, should I update pull request or it's already done?

@nicklockwood
Copy link
Owner

@akbashev it's not been done yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants