admin管理员组

文章数量:1220453

I have a code below which an updated version of RTS Camera2d - and for the most part, it works really well. That is - until I try this on an Android OS.

On Android, keyboard scrolling works as expected but the drag-scrolling will always reset the camera, so that when I start dragging, it kinda snaps to the center of that camera and drags from there.

Here’s a video showing the problem on Android:

And here is my code:

# Copyright 2017 Kamil Lewan <[email protected]>
# 
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

extends Camera2D

var debug_mode: bool = true

# Camera control settings:
# key - by keyboard
# drag - by clicking mouse button, left mouse button by default;
# edge - by moving mouse to the window edge
# wheel - zoom in/out by mouse wheel
var key: bool = true
var drag: bool = true
var edge: bool = false if ( OS.has_feature( "android" ) or OS.has_feature( "mobile" ) or OS.has_feature( "ios" ) or OS.has_feature( "web_android" ) or OS.has_feature( "web_ios" ) ) else true

# Camera speed in px/s.
var camera_speed: int = 450 

# Camera speed in px/s when the SHIFT key is pressed - i.e. TURBO.
var camera_speed_turbo: int = 1000 

# Value meaning how near to the window edge (in px) the mouse must be,
# to move a view.
var camera_margin: int = 50

# Vector of camera's movement / second.
var camera_movement = Vector2()

# Previous mouse position used to count delta of the mouse movement.
var _prev_mouse_pos = null

# Viewport rectangle - this is constant unless the window size changes, so we'll cache it.
@onready var viewport_rect = get_viewport_rect()

# INPUTS

# Left mouse button was or is pressed.
var __lmbk: bool = false
# SHIFT key was or is pressed.
var __shift: bool = false
# Whether left mouse button was released outside of the viewport,
# in which case we will ignore edge scrolling, as it would contradict
# the drag-scroll that just happened.
var __lmb_released_outside: bool = false
# Move camera by keys: left, top, right, bottom.
var __keys = [false, false, false, false]
# Mouse is in the window
var __mousein: bool = false

func _s( msg ):
    if debug_mode:
        print( msg )

func _ready():
    set_drag_horizontal_enabled(false)
    set_drag_vertical_enabled(false)
    #position_smoothing_enabled = true
    #position_smoothing_speed = 4

    # update viewport size on window change event   
    get_tree().root.connect( "size_changed", self._on_viewport_size_changed )

func _notification(what):
    if what == NOTIFICATION_WM_MOUSE_ENTER:
        __mousein = true
        __lmb_released_outside = false # reset this now that we're back in the window, so edge scrolling works again
    elif what == NOTIFICATION_WM_MOUSE_EXIT:
        __mousein = false

func _on_viewport_size_changed(): 
    viewport_rect = get_viewport_rect()

func _physics_process(delta):
    var curpos = get_local_mouse_position()
    var update_camera = false
    var actual_left_limit = viewport_rect.end.x / 2
    var actual_top_limit = viewport_rect.end.y / 2
    var current_camera_speed = camera_speed_turbo if __shift else camera_speed

    var can_scroll_left = ( position.x - ( current_camera_speed * delta ) > actual_left_limit )
    var can_scroll_top = ( position.y - ( current_camera_speed * delta ) > actual_top_limit )
    var can_scroll_right = ( position.x + ( viewport_rect.size.x / 2 ) < limit_right )
    var can_scroll_bottom = ( position.y + ( viewport_rect.size.y / 2 ) < limit_bottom )

    # Move camera by keys defined in InputMap (ui_left/top/right/bottom).
    if key:
        if __keys[0] and can_scroll_left:
            camera_movement.x -= current_camera_speed * delta
            update_camera = true
        if __keys[1] and can_scroll_top:
            camera_movement.y -= current_camera_speed * delta
            update_camera = true
        if __keys[2] and can_scroll_right:
            camera_movement.x += current_camera_speed * delta
            update_camera = true
        if __keys[3] and can_scroll_bottom:
            camera_movement.y += current_camera_speed * delta
            update_camera = true

    # no need for further calculations if we've already updated camera by using a keyboard
    if !update_camera:
        # When LMB is pressed, move camera by difference of mouse position
        if drag and __lmbk:
            camera_movement = _prev_mouse_pos - curpos
            # now check that we're not over the camera limits, and if so, reset those values over limits to their previous values
            if ( ( camera_movement.x < 0 and !can_scroll_left ) or ( camera_movement.x > 0 and !can_scroll_right ) ):
                camera_movement.x = 0
            if ( ( camera_movement.y < 0 and !can_scroll_top ) or ( camera_movement.y > 0 and !can_scroll_bottom ) ):
                camera_movement.y = 0
            update_camera = true

        # Move camera by mouse, when it's on the margin (defined by camera_margin).
        elif edge and !__lmb_released_outside:# and __mousein:
            var v = curpos + viewport_rect.size/2
            if viewport_rect.size.x - v.x <= camera_margin and can_scroll_right:
                camera_movement.x += current_camera_speed * delta
                update_camera = true
            if v.x <= camera_margin and can_scroll_left:
                camera_movement.x -= current_camera_speed * delta
                update_camera = true
            if viewport_rect.size.y - v.y <= camera_margin and can_scroll_bottom:
                camera_movement.y += current_camera_speed * delta
                update_camera = true
            if v.y <= camera_margin and can_scroll_top:
                camera_movement.y -= current_camera_speed * delta
                update_camera = true

    # Update position of the camera.
    if update_camera:
        position += camera_movement# * get_zoom()

        #var center = get_screen_center_position()
        #var current_target = get_target_position()
        #if current_target != center:
            #position = center

        # Set camera movement to zero
        camera_movement = Vector2(0,0)
        
    # Update old mouse position.
    _prev_mouse_pos = curpos

func _unhandled_input( event ):
    if event is InputEventMouseButton:
        if drag and event.button_index == MOUSE_BUTTON_LEFT:
            # Control by left mouse button.
            if event.pressed:
                __lmbk = true
                print("down, prev = ", _prev_mouse_pos, ", now = ", get_local_mouse_position())
            else:
                __lmbk = false
                print("up, prev = ", _prev_mouse_pos, ", now = ", get_local_mouse_position())
                if !__mousein:
                    __lmb_released_outside = true
                else:
                    __lmb_released_outside = false

    # SHIFT key press detection
    if event.is_action_pressed("turbo"):
        __shift = true
    if event.is_action_released("turbo"):
        __shift = false

    # Control by keyboard handled by InpuMap.
    if event.is_action_pressed("ui_left"):
        __keys[0] = true
    if event.is_action_pressed("ui_up"):
        __keys[1] = true
    if event.is_action_pressed("ui_right"):
        __keys[2] = true
    if event.is_action_pressed("ui_down"):
        __keys[3] = true
    if event.is_action_released("ui_left"):
        __keys[0] = false
    if event.is_action_released("ui_up"):
        __keys[1] = false
    if event.is_action_released("ui_right"):
        __keys[2] = false
    if event.is_action_released("ui_down"):
        __keys[3] = false

本文标签: godotDragscrolling of a Camera2D works on Windowsdoesn39t quite on AndroidStack Overflow