|
|
|
|
Reply From: |
njamster |
Disclaimer: I never played “Sky Force 2014”, so this might or might not be what you want. But either way it should help you to understand the general approach.
Attach this script to a sprite representing your player (if you want to use something else, e.g. a KinematicBody2D you’ll need to adapt the script, but it should be fairly obvious where and none of the required changes are complicated):
extends Sprite
const SPEED = 300 # pixel per second
const MAX_TRACKING_DISTANCE = 400 # pixel
var screen_touch = false
var path = []
func _unhandled_input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
screen_touch = event.pressed
if screen_touch:
add_to_path(event.global_position)
elif event is InputEventMouseMotion and screen_touch:
add_to_path(event.global_position)
func add_to_path(position):
var distance = global_position.distance_to(position)
if distance > MAX_TRACKING_DISTANCE:
path.clear()
path.push_back(position)
func _physics_process(delta):
if path.empty(): return
var next_pos = path.front()
var direction = global_position.direction_to(next_pos)
var distance = global_position.distance_to(next_pos)
var reach = SPEED * delta
if distance > reach:
# next_pos is out of reach in this frame
# => move as far as possible towards it!
global_position += direction * reach
elif distance < reach:
# next_pos is reachable in this frame
# => move there and remove it from the path
while distance < reach:
global_position += direction * distance
reach -= distance
path.pop_front()
# check if theres another position in the path
# that we can already move towards
if path.empty(): return
next_pos = path.front()
direction = global_position.direction_to(next_pos)
distance = global_position.distance_to(next_pos)
I have incorrectly explained what I need, I’m sorry.
I need the player to simply move towards the finger, or repeat his movements from his position.
for example: the player is in position 4; 2 (X; Y) and the finger touched the screen at point 7; 5. The player does not move.
the finger moved 2 by X and 8 by Y. The player also moved from its place to 2 by X and 8 by Y like a finger.
it turns out that the finger is at 9; 13 and the player is at 6; 10.
AndrewD | 2020-03-31 11:09
Alright, I’m confused…
I need the player to simply move towards the finger, or repeat his movements from his position.
Which of the two options do you want?
for example: the player is in position 4; 2 (X; Y) and the finger touched the screen at point 7; 5. The player does not move.
According to your example, the player will not simply move towards the finger. In fact it will do nothing at all if the screen is touched for the first time?!
the finger moved 2 by X and 8 by Y. The player also moved from its place to 2 by X and 8 by Y like a finger.
So it’s simply mirroring the finger motion from it’s local point of view. Like my code does! If you don’t want to move the player on the first touch event, all you have to do is remove the first call to add_to_path
in _unhandled_input
.
njamster | 2020-03-31 18:29
Well, I understood how to configure the first control option . I just needed to give MAX_TRACKING_DISTANCE a small value.
And the second option I could not explain, because my English is very bad, and I wrote through Google translate (and still write). In any case, I uploaded a video on YouTube with an example of the second control option.
https://youtu.be/qz-Jr_GS1IY
AndrewD | 2020-04-01 06:38
Try this:
extends Sprite
const SPEED = 50 # pixel per second
const MAX_TRACKING_DISTANCE = 200 # pixel
const SMALLEST_REGISTERED_OFFSET = 1.0
var screen_touch = false
var move_by = Vector2.ZERO
var path = []
func _unhandled_input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
screen_touch = event.pressed
elif event is InputEventMouseMotion and screen_touch:
var distance = global_position.distance_to(event.global_position)
if distance <= MAX_TRACKING_DISTANCE:
if event.relative.length() >= SMALLEST_REGISTERED_OFFSET:
path.push_back(event.relative)
else:
path.clear()
path.push_back(global_position.direction_to(event.global_position) * distance)
else:
path.clear()
func _physics_process(delta):
if path.empty(): return
var next_offset = path.front()
var direction = next_offset.normalized()
var distance = next_offset.length()
var reach = SPEED * delta
if distance > reach:
global_position += direction * reach
path[0] *= 1-reach/distance
else:
while distance <= reach:
global_position += direction * distance
reach -= distance
path.pop_front()
if path.empty(): return
next_offset = path.front()
direction = next_offset.normalized()
distance = next_offset.length()
if distance > reach:
global_position += direction * reach
path[0] *= 1-reach/distance
njamster | 2020-04-01 12:46
thank you very much!
But, for some reason, touches are not read on the ColorRect which I use as the background.
Why is this happening?
AndrewD | 2020-04-01 16:03
But, for some reason, touches are not read on the ColorRect which I use as the background.
In the inspector, set the mouse_filter
-property of your ColorRect to “Ignore”. Otherwise it will consume the mouse-events before they reach your node.
njamster | 2020-04-01 17:29
and for some reason, the second option control works on the PC from the mouse, but does not work on the phone from the touch. At the same time, mouse emulation from touching is enabled.
AndrewD | 2020-04-02 06:53
I did it. But at the same time, in the function func _unhandled_input(event):
, I had to replace event.global_position
with event.position
and the line path.push_back (global_position.direction_to (event.global_position) * distance)
with path.push_back (position.direction_to (event.position) * distance)
.
Now the player just doesn’t move.
AndrewD | 2020-04-02 11:55