在移动或调整元素大小时,定位会出错
我一直在研究一种“进化式”的井字棋游戏,它在一个7x7的棋盘上进行,并且有额外的功能和规则来适应。起初我把它做成一个小窗口(1450 x 1018),但现在在移到其他事情之前,我想把分辨率改成4K,或者至少保持16:9的纵横比。问题在于,当前我的实现方式是井字棋的网格只是一个图像,通过一些代码来在图像上找到放置X或O记号的正确位置(也许这并不最优,但现在如果可以的话我想保持这种方式)。现在为了让每位玩家都能在同一台电脑上控制,O玩家用鼠标点击网格来放置O,而X玩家用方向键控制一个光标。但是每当我尝试移动或调整棋盘图像的大小时,仍然只能在棋盘原来的位置放置两种记号和X玩家的光标,仿佛在那儿还有一个看不见的棋盘。我猜这跟它想要在原点和局部位置等方面有关,但我不知道该如何修复。
下面是与标记如何被放置相关的代码(注意handle_move那段,有大量与棋规相关的逻辑我做了裁剪,那里保留的代码与放置记号直接相关):
func _ready() -> void:
boardSize = $Board.get_rect().size.x
cellSize = boardSize/7.0
#Create a Node2D container for Player 2's cursor
cursorMarker = Node2D.new()
cursorMarker.name = "CursorMarker"
add_child(cursorMarker)
#Create a 1x1 yellow image
var img := Image.create(1, 1, false, Image.FORMAT_RGBA8)
img.set_pixel(0, 0, Color(1.0, 1.0, 0.0, 0.471))
#Make a texture from that image
var tex := ImageTexture.create_from_image(img)
#Create a sprite to display it
var spr := Sprite2D.new()
spr.texture = tex
spr.centered = false # top-left corner aligns with cell
spr.scale = Vector2(cellSize, cellSize) # scale 1×1px up to a full cell
cursorMarker.add_child(spr)
updateCursorPosition()
func _input(event):
#Player 1 input with the mouse
if event is InputEventMouseButton:
if event .button_index == MOUSE_BUTTON_LEFT and event.pressed:
#Check if mouse is on the game board
if event.position.x < boardSize:
#Convert mouse position into grid location
gridPos = Vector2i(event.position / cellSize)
handle_move(1, gridPos)
#Player 2 input with arrow keys and Enter
if event is InputEventKey and event.pressed:
match event.keycode:
KEY_UP:
player2Cursor.y = max(player2Cursor.y - 1, 0)
updateCursorPosition()
KEY_DOWN:
player2Cursor.y = min(player2Cursor.y + 1, 6)
updateCursorPosition()
KEY_LEFT:
player2Cursor.x = max(player2Cursor.x - 1, 0)
updateCursorPosition()
KEY_RIGHT:
player2Cursor.x = min(player2Cursor.x + 1, 6)
updateCursorPosition()
KEY_ENTER, KEY_KP_ENTER:
if canPlace2:
handle_move(-1, player2Cursor)
#Runs when Player 1 or 2 tries to make an input
func handle_move(currentPlayer: float, gridPos: Vector2i) -> void:
...
#If the spot is empty, or if it contains the other Player's symbol and the current Player can replace it
gridData[gridPos.y][gridPos.x] = currentPlayer #Put a 1 or -1 in the corresponding 2D array spot
var target = gridPos * cellSize + Vector2i(cellSize / 2, cellSize / 2) #Get the location on the image
#Clear existing markers if replacing
for cross in get_tree().get_nodes_in_group("crosses"):
if cross.position == Vector2(target):
cross.queue_free()
for circle in get_tree().get_nodes_in_group("circles"):
if circle.position == Vector2(target):
circle.queue_free()
createMarker(currentPlayer, target) #Places the marker in the spot
...
func createMarker (player, position, temp=false, gray=false):
#Create marker node and add it as a child
if player == 1:
var circle = circleScene.instantiate()
circle.position = position
if gray: #Gray is an optional indicator which makes the symbol dark
enter image description hereenter image description here circle.modulate = Color(0.5, 0.5, 0.5, 1.0)
add_child(circle)
if temp: tempMarker = circle
elif player == -1:
var cross = crossScene.instantiate()
cross.position = position
if gray:
cross.modulate = Color(0.5, 0.5, 0.5, 1.0)
add_child(cross)
if temp: tempMarker = cross
#Moving Player 2 cursor
func updateCursorPosition() -> void:
if cursorMarker == null:
return
cursorMarker.position = Vector2(player2Cursor) * cellSize
解决方案
我没有看到在调整窗口大小时更新 boardsize 的任何代码。下面给出一些示例代码:
func _ready():
get_tree().root.size_changed.connect(on_viewport_size_changed)## connect the function to the signal
func on_viewport_size_changed():
boardsize = $Board.get_rect().size.x
## note that this may mess up some of your other logic
希望这能帮到你!
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。