Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions internal/engine/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,28 @@ func SyncNewSprite(obj any, pos Vec2) *Sprite {
}

func SyncBindUI[T any](parentNode gdx.Object, path string) *T {

return gdx.BindUI[T](parentNode, path)
}
func SyncGetTimeScale() float64 {
return gdx.PlatformMgr.GetTimeScale()
}
func SyncGetMousePos() Vec2 {
return gdx.InputMgr.GetGlobalMousePos()
return inputMgr.SyncGetGlobalMousePos()
}

func SyncSetCameraPosition(pos Vec2) {
gdx.CameraMgr.SetCameraPosition(NewVec2(pos.X, -pos.Y))
cameraMgr.SyncSetCameraPosition(pos)
}

func SyncScreenToWorld(pos Vec2) Vec2 {
zoom := gdx.CameraMgr.GetCameraZoom().X
camPos := gdx.CameraMgr.GetCameraPosition()
camPos.Y *= -1
camPos := cameraMgr.SyncGetCameraPosition()
return pos.Divf(zoom / windowScale).Add(camPos.Mulf(windowScale))
}

func SyncWorldToScreen(pos Vec2) Vec2 {
zoom := gdx.CameraMgr.GetCameraZoom().X
camPos := gdx.CameraMgr.GetCameraPosition()
camPos.Y *= -1
camPos := cameraMgr.SyncGetCameraPosition()
return pos.Sub(camPos.Mulf(windowScale)).Mulf(zoom / windowScale)
}

Expand Down
297 changes: 297 additions & 0 deletions internal/enginewrap/coord_adapter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
package enginewrap

// This file provides coordinate system adapters for all managers.
// SPX uses Y-axis pointing up, while Godot uses Y-axis pointing down.
// All coordinate conversions are handled here by overriding manager methods.

import (
. "github.com/goplus/spbase/mathf"
gdx "github.com/goplus/spx/v2/pkg/gdspx/pkg/engine"
)

// flipY flips the Y coordinate to convert between SPX and Godot coordinate systems
func flipY(pos Vec2) Vec2 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Performance Concern: Frequent Allocations in Hot Path

The flipY function creates a new Vec2 struct on every call. Since this is called for every position/velocity operation (in rendering and physics updates), this creates significant memory pressure. At 60 FPS with 100 sprites, this could generate ~15,000-25,000 allocations/sec (~6-8 KB/frame).

Consider optimizing for hot paths. One approach is to modify the copy in-place:

func flipY(pos Vec2) Vec2 {
    pos.Y = -pos.Y
    return pos
}

Or consider pointer-based APIs for frequently-called methods like GetPosition/SetPosition to avoid repeated allocations in Get-Modify-Set patterns (e.g., AddPos calls GetPosition then SetPosition).

return Vec2{X: pos.X, Y: -pos.Y}
}

// ============================================================================
// Sprite Coordinate Adapters
// ============================================================================

func (pself *Sprite) SetPosition(pos Vec2) {
pself.Sprite.SetPosition(flipY(pos))
}

func (pself *Sprite) GetPosition() Vec2 {
return flipY(pself.Sprite.GetPosition())
}

func (pself *Sprite) SetChildPosition(path string, pos Vec2) {
pself.Sprite.SetChildPosition(path, flipY(pos))
}

func (pself *Sprite) GetChildPosition(path string) Vec2 {
return flipY(pself.Sprite.GetChildPosition(path))
}

func (pself *Sprite) SetVelocity(velocity Vec2) {
pself.Sprite.SetVelocity(flipY(velocity))
}

func (pself *Sprite) GetVelocity() Vec2 {
return flipY(pself.Sprite.GetVelocity())
}

func (pself *Sprite) SetPivot(pivot Vec2) {
pself.Sprite.SetPivot(flipY(pivot))
}

func (pself *Sprite) GetPivot() Vec2 {
return flipY(pself.Sprite.GetPivot())
}

func (pself *Sprite) CheckCollisionWithPoint(point Vec2, isTrigger bool) bool {
return pself.Sprite.CheckCollisionWithPoint(flipY(point), isTrigger)
}

// extra wrap functions
func (pself *Sprite) GetLastMotion() Vec2 {
return flipY(pself.Sprite.GetLastMotion())
}

func (pself *Sprite) GetPositionDelta() Vec2 {
return flipY(pself.Sprite.GetPositionDelta())
}

func (pself *Sprite) GetFloorNormal() Vec2 {
return flipY(pself.Sprite.GetFloorNormal())
}

func (pself *Sprite) GetWallNormal() Vec2 {
return flipY(pself.Sprite.GetWallNormal())
}

func (pself *Sprite) GetRealVelocity() Vec2 {
return flipY(pself.Sprite.GetRealVelocity())
}

func (pself *Sprite) SetAnimOffset(offset Vec2) {
pself.Sprite.SetAnimOffset(flipY(offset))
}

func (pself *Sprite) GetAnimOffset() Vec2 {
return flipY(pself.Sprite.GetAnimOffset())
}

// ============================================================================
// SpriteMgr Coordinate Adapters
// ============================================================================

func (pself *SpriteMgrImpl) SetPosition(obj gdx.Object, pos Vec2) {
pself.spriteMgrImpl.SetPosition(obj, flipY(pos))
}

func (pself *SpriteMgrImpl) GetPosition(obj gdx.Object) Vec2 {
return flipY(pself.spriteMgrImpl.GetPosition(obj))
}

func (pself *SpriteMgrImpl) SetChildPosition(obj gdx.Object, path string, pos Vec2) {
pself.spriteMgrImpl.SetChildPosition(obj, path, flipY(pos))
}

func (pself *SpriteMgrImpl) GetChildPosition(obj gdx.Object, path string) Vec2 {
return flipY(pself.spriteMgrImpl.GetChildPosition(obj, path))
}

func (pself *SpriteMgrImpl) SetVelocity(obj gdx.Object, velocity Vec2) {
pself.spriteMgrImpl.SetVelocity(obj, flipY(velocity))
}

func (pself *SpriteMgrImpl) GetVelocity(obj gdx.Object) Vec2 {
return flipY(pself.spriteMgrImpl.GetVelocity(obj))
}

func (pself *SpriteMgrImpl) SetPivot(obj gdx.Object, pivot Vec2) {
pself.spriteMgrImpl.SetPivot(obj, flipY(pivot))
}

func (pself *SpriteMgrImpl) GetPivot(obj gdx.Object) Vec2 {
return flipY(pself.spriteMgrImpl.GetPivot(obj))
}

func (pself *SpriteMgrImpl) CheckCollisionWithPoint(obj gdx.Object, point Vec2, isTrigger bool) bool {
return pself.spriteMgrImpl.CheckCollisionWithPoint(obj, flipY(point), isTrigger)
}

// extra wrap functions
func (pself *SpriteMgrImpl) GetLastMotion(obj gdx.Object) Vec2 {
return flipY(pself.spriteMgrImpl.GetLastMotion(obj))
}

func (pself *SpriteMgrImpl) GetPositionDelta(obj gdx.Object) Vec2 {
return flipY(pself.spriteMgrImpl.GetPositionDelta(obj))
}

func (pself *SpriteMgrImpl) GetFloorNormal(obj gdx.Object) Vec2 {
return flipY(pself.spriteMgrImpl.GetFloorNormal(obj))
}

func (pself *SpriteMgrImpl) GetWallNormal(obj gdx.Object) Vec2 {
return flipY(pself.spriteMgrImpl.GetWallNormal(obj))
}

func (pself *SpriteMgrImpl) GetRealVelocity(obj gdx.Object) Vec2 {
return flipY(pself.spriteMgrImpl.GetRealVelocity(obj))
}

func (pself *SpriteMgrImpl) SetAnimOffset(obj gdx.Object, offset Vec2) {
pself.spriteMgrImpl.SetAnimOffset(obj, flipY(offset))
}

func (pself *SpriteMgrImpl) GetAnimOffset(obj gdx.Object) Vec2 {
return flipY(pself.spriteMgrImpl.GetAnimOffset(obj))
}

func (pself *SpriteMgrImpl) AddImpulse(obj gdx.Object, impulse Vec2) {
pself.spriteMgrImpl.AddImpulse(obj, flipY(impulse))
}

func (pself *SpriteMgrImpl) GetGravity(obj gdx.Object) float64 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing Documentation

Gravity negation requires explanation. Unlike vectors, gravity is a scalar, so the sign flip is conceptually different. Add a comment:

// GetGravity returns gravity with inverted sign to match SPX's upward Y-axis convention.
// In SPX, positive Y is up, so positive gravity means upward force. In Godot, positive 
// Y is down, so positive gravity means downward force. The sign inversion maintains 
// consistent physical behavior across both coordinate systems.
func (pself *SpriteMgrImpl) GetGravity(obj gdx.Object) float64 {
    return -pself.spriteMgrImpl.GetGravity(obj)
}

return -pself.spriteMgrImpl.GetGravity(obj)
}

func (pself *SpriteMgrImpl) SetGravity(obj gdx.Object, gravity float64) {
pself.spriteMgrImpl.SetGravity(obj, -gravity)
}

// ============================================================================
// SceneMgr Coordinate Adapters
// ============================================================================

func (pself *SceneMgrImpl) CreateRenderSprite(texturePath string, pos Vec2, degree float64, scale Vec2, zindex int64, pivot Vec2) gdx.Object {
return pself.sceneMgrImpl.CreateRenderSprite(texturePath, flipY(pos), degree, scale, zindex, flipY(pivot))
}

func (pself *SceneMgrImpl) CreateStaticSprite(texturePath string, pos Vec2, degree float64, scale Vec2, zindex int64, pivot Vec2, colliderType int64, colliderPivot Vec2, colliderParams gdx.Array) gdx.Object {
return pself.sceneMgrImpl.CreateStaticSprite(texturePath, flipY(pos), degree, scale, zindex, flipY(pivot), colliderType, flipY(colliderPivot), colliderParams)
}

// ============================================================================
// PhysicMgr Coordinate Adapters
// ============================================================================

func (pself *PhysicMgrImpl) Raycast(from Vec2, to Vec2, collisionMask int64) gdx.Object {
return pself.physicMgrImpl.Raycast(flipY(from), flipY(to), collisionMask)
}

// RaycastWithDetails returns array: [collide, sprite_gid, pos.x, pos.y, normal.x, normal.y]
// This conversion should be handled at upper layer due to gdx.Array access limitations
Copy link
Contributor

Choose a reason for hiding this comment

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

Misleading documentation

The comment is confusing. Input coordinates ARE converted here via flipY(), but output array Y values are converted in physic.go:tryRaycastResult(). Clarify what's happening where:

Suggested change
// This conversion should be handled at upper layer due to gdx.Array access limitations
// RaycastWithDetails returns array: [collide, sprite_gid, pos.x, pos.y, normal.x, normal.y]
// Input coordinates are converted here via flipY, but output array pos/normal Y values
// must be converted at the upper layer (see physic.go:tryRaycastResult) due to gdx.Array
// access limitations preventing direct element modification.

Copy link
Contributor

Choose a reason for hiding this comment

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

Documentation Issue: Incomplete Comment

The comment is accurate that output conversion happens at the upper layer, but should clarify that only INPUT coordinates are converted here. The returned array's Y-coordinates (indices 3 and 5) must be handled by the caller:

// RaycastWithDetails returns array: [collide, sprite_gid, pos.x, pos.y, normal.x, normal.y]
// Note: Input coordinates (from, to) are converted here, but the returned array 
// Y-coordinates (pos.y at index 3, normal.y at index 5) must be converted by the 
// caller due to gdx.Array access limitations. See physic.go:tryRaycastResult().

func (pself *PhysicMgrImpl) RaycastWithDetails(from Vec2, to Vec2, ignoreSprites gdx.Array, collisionMask int64, collideWithAreas bool, collideWithBodies bool) gdx.Array {
return pself.physicMgrImpl.RaycastWithDetails(flipY(from), flipY(to), ignoreSprites, collisionMask, collideWithAreas, collideWithBodies)
}
Comment on lines +189 to +191

Choose a reason for hiding this comment

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

medium

For consistency with FindPath and to better centralize the coordinate conversion logic, consider handling the Y-coordinate flipping for the returned array within this function. This would make the adapter layer fully responsible for coordinate translations. This change would also require removing the manual Y-flipping from the ToArray and tryRaycastResult functions in physic.go, and updating the comments on lines 187-188.

Suggested change
func (pself *PhysicMgrImpl) RaycastWithDetails(from Vec2, to Vec2, ignoreSprites gdx.Array, collisionMask int64, collideWithAreas bool, collideWithBodies bool) gdx.Array {
return pself.physicMgrImpl.RaycastWithDetails(flipY(from), flipY(to), ignoreSprites, collisionMask, collideWithAreas, collideWithBodies)
}
func (pself *PhysicMgrImpl) RaycastWithDetails(from Vec2, to Vec2, ignoreSprites gdx.Array, collisionMask int64, collideWithAreas bool, collideWithBodies bool) gdx.Array {
arr := pself.physicMgrImpl.RaycastWithDetails(flipY(from), flipY(to), ignoreSprites, collisionMask, collideWithAreas, collideWithBodies)
if arr == nil {
return nil
}
result, ok := arr.([]int64)
if !ok {
// This case is unexpected, returning the original array. Consider logging an error.
return arr
}
if len(result) >= 6 {
// result[3] is pos.y, result[5] is normal.y
// Convert from Godot's coordinate system (y-down) to SPX's (y-up).
result[3] = -result[3]
result[5] = -result[5]
}
return result
}


func (pself *PhysicMgrImpl) CheckCollisionRect(pos Vec2, size Vec2, collisionMask int64) gdx.Array {
return pself.physicMgrImpl.CheckCollisionRect(flipY(pos), size, collisionMask)
}

func (pself *PhysicMgrImpl) CheckCollisionCircle(pos Vec2, radius float64, collisionMask int64) gdx.Array {
return pself.physicMgrImpl.CheckCollisionCircle(flipY(pos), radius, collisionMask)
}

// ============================================================================
// InputMgr Coordinate Adapters
// ============================================================================
func (pself *InputMgrImpl) SyncGetGlobalMousePos() Vec2 {
return flipY(gdx.InputMgr.GetGlobalMousePos())
}

func (pself *InputMgrImpl) GetGlobalMousePos() Vec2 {
return flipY(pself.inputMgrImpl.GetGlobalMousePos())
}

// ============================================================================
// CameraMgr Coordinate Adapters
// ============================================================================
func (pself *CameraMgrImpl) GetCameraPosition() Vec2 {
return flipY(pself.cameraMgrImpl.GetCameraPosition())
}
func (pself *CameraMgrImpl) SetCameraPosition(position Vec2) {
pself.cameraMgrImpl.SetCameraPosition(flipY(position))
}
func (pself *CameraMgrImpl) SyncGetCameraPosition() Vec2 {
return flipY(gdx.CameraMgr.GetCameraPosition())
}
func (pself *CameraMgrImpl) SyncSetCameraPosition(position Vec2) {
gdx.CameraMgr.SetCameraPosition(flipY(position))
}

// ============================================================================
// DebugMgr Coordinate Adapters
// ============================================================================

func (pself *DebugMgrImpl) DebugDrawCircle(pos Vec2, radius float64, color Color) {
pself.debugMgrImpl.DebugDrawCircle(flipY(pos), radius, color)
}

func (pself *DebugMgrImpl) DebugDrawRect(pos Vec2, size Vec2, color Color) {
pself.debugMgrImpl.DebugDrawRect(flipY(pos), size, color)
}

func (pself *DebugMgrImpl) DebugDrawLine(from Vec2, to Vec2, color Color) {
pself.debugMgrImpl.DebugDrawLine(flipY(from), flipY(to), color)
}

// ============================================================================
// TilemapMgr Coordinate Adapters
// ============================================================================

func (pself *TilemapMgrImpl) PlaceTile(pos Vec2, texturePath string) {
pself.tilemapMgrImpl.PlaceTile(flipY(pos), texturePath)
}

func (pself *TilemapMgrImpl) PlaceTileWithLayer(pos Vec2, texturePath string, layerIndex int64) {
pself.tilemapMgrImpl.PlaceTileWithLayer(flipY(pos), texturePath, layerIndex)
}

func (pself *TilemapMgrImpl) EraseTile(pos Vec2) {
pself.tilemapMgrImpl.EraseTile(flipY(pos))
}

func (pself *TilemapMgrImpl) EraseTileWithLayer(pos Vec2, layerIndex int64) {
pself.tilemapMgrImpl.EraseTileWithLayer(flipY(pos), layerIndex)
}

func (pself *TilemapMgrImpl) GetTile(pos Vec2) string {
return pself.tilemapMgrImpl.GetTile(flipY(pos))
}

func (pself *TilemapMgrImpl) GetTileWithLayer(pos Vec2, layerIndex int64) string {
return pself.tilemapMgrImpl.GetTileWithLayer(flipY(pos), layerIndex)
}

func (pself *TilemapMgrImpl) SetLayerOffset(index int64, offset Vec2) {
pself.tilemapMgrImpl.SetLayerOffset(index, flipY(offset))
}

func (pself *TilemapMgrImpl) GetLayerOffset(index int64) Vec2 {
return flipY(pself.tilemapMgrImpl.GetLayerOffset(index))
}

// ============================================================================
// NavigationMgr Coordinate Adapters
// ============================================================================

// FindPath returns array: [x0, y0, x1, y1, x2, y2, ...]
// This conversion should be handled at upper layer due to gdx.Array access limitations
Copy link
Contributor

Choose a reason for hiding this comment

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

Documentation inaccuracy

This comment states "conversion should be handled at upper layer" but the conversion IS done here (lines 163-165). Unlike RaycastWithDetails, this function actually converts the array elements.

Suggested change
// This conversion should be handled at upper layer due to gdx.Array access limitations
// FindPath returns array: [x0, y0, x1, y1, x2, y2, ...]
// Input coordinates are converted via flipY, and output array Y values are also
// converted here by negating all odd-indexed elements (y-coordinates).

Comment on lines +284 to +285

Choose a reason for hiding this comment

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

medium

This comment is misleading. The coordinate conversion is handled within this function, not at an upper layer. Please update the comment to accurately describe the function's behavior.

Suggested change
// FindPath returns array: [x0, y0, x1, y1, x2, y2, ...]
// This conversion should be handled at upper layer due to gdx.Array access limitations
// FindPath returns an array of path coordinates: [x0, y0, x1, y1, ...].
// The coordinates are converted from Godot's system (Y-down) to SPX's system (Y-up).

Copy link
Contributor

Choose a reason for hiding this comment

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

Documentation Issue: Misleading Comment

The comment states "This conversion should be handled at upper layer" but the function actually DOES perform output array conversion in lines 293-294. The comment from RaycastWithDetails was likely copied but doesn't apply here. Consider:

// FindPath returns array: [x0, y0, x1, y1, x2, y2, ...]
// Both input and output coordinates are converted here.
// Output Y-coordinates (at odd indices) are inverted to convert from Godot to SPX coordinate system.

func (pself *NavigationMgrImpl) FindPath(from Vec2, to Vec2, withJump bool) gdx.Array {
var arr = pself.navigationMgrImpl.FindPath(flipY(from), flipY(to), withJump)
result := arr.([]float32)
Copy link
Contributor

Choose a reason for hiding this comment

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

<!-- codeagent-review-id: pr-973 -->

Critical: Type assertion panic risk

This unsafe type assertion will panic if arr is not []float32, creating a denial-of-service vulnerability.

Suggested change
result := arr.([]float32)
result, ok := arr.([]float32)
if \!ok || result == nil {

Copy link
Contributor

Choose a reason for hiding this comment

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

Security/Reliability Issue: Unchecked Type Assertion

This unchecked type assertion will panic if the underlying type is not []float32, causing a potential denial of service. Use the safe two-value form:

result, ok := arr.([]float32)
if !ok || result == nil {
    return nil
}

if result == nil {
return nil
}
Comment on lines +287 to +291

Choose a reason for hiding this comment

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

critical

The type assertion arr.([]float32) is unsafe and will cause a panic if arr is nil or has a different underlying type. This can lead to a crash. Please use the two-value type assertion to handle these cases gracefully.

	arr := pself.navigationMgrImpl.FindPath(flipY(from), flipY(to), withJump)
	if arr == nil {
		return nil
	}
	result, ok := arr.([]float32)
	if !ok || result == nil {
		return nil
	}

// flipY to convert godot coord to spx coord
for i := 0; i+1 < len(result); i += 2 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Inconsistent approach + minor optimization

This inline Y-negation is inconsistent with the flipY() helper used everywhere else.

Also, simplify the loop to start at index 1 to avoid the addition in the condition:

Suggested change
for i := 0; i+1 < len(result); i += 2 {
for i := 1; i < len(result); i += 2 {
result[i] = -result[i]
}

result[i+1] = -result[i+1]
}
return result
}
Comment on lines +285 to +297

Choose a reason for hiding this comment

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

critical

The type assertion arr.([]float32) on line 159 is unsafe and will cause a panic if arr is nil or not of type []float32. You should use the "comma ok" idiom to safely perform the type assertion. Additionally, the comment on line 156 is now misleading since the conversion is handled within this function, and should be removed or updated.

Suggested change
// This conversion should be handled at upper layer due to gdx.Array access limitations
func (pself *NavigationMgrImpl) FindPath(from Vec2, to Vec2, withJump bool) gdx.Array {
var arr = pself.navigationMgrImpl.FindPath(flipY(from), flipY(to), withJump)
result := arr.([]float32)
if result == nil {
return nil
}
// flipY to convert godot coord to spx coord
for i := 0; i+1 < len(result); i += 2 {
result[i+1] = -result[i+1]
}
return result
}
// The returned path coordinates are converted to the SPX coordinate system.
func (pself *NavigationMgrImpl) FindPath(from Vec2, to Vec2, withJump bool) gdx.Array {
arr := pself.navigationMgrImpl.FindPath(flipY(from), flipY(to), withJump)
if arr == nil {
return nil
}
result, ok := arr.([]float32)
if !ok {
// Consider logging an error here as this is an unexpected type.
return arr
}
// flipY to convert godot coord to spx coord
for i := 0; i+1 < len(result); i += 2 {
result[i+1] = -result[i+1]
}
return result
}

8 changes: 4 additions & 4 deletions physic.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ func (p *rayCastResult) ToArray() engine.Array {
}
ary[1] = p.SpriteId
ary[2] = engine.ConvertToInt64(p.PosX)
ary[3] = engine.ConvertToInt64(p.PosY)
ary[3] = -engine.ConvertToInt64(p.PosY) // here need flipY to convert spx coord to godot coord
ary[4] = engine.ConvertToInt64(p.NormalX)
ary[5] = engine.ConvertToInt64(p.NormalY)
ary[5] = -engine.ConvertToInt64(p.NormalY)
Comment on lines +88 to +90

Choose a reason for hiding this comment

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

medium

The comment on line 88 is a bit informal. Also, NormalY on line 90 is also flipped but lacks a comment. For better clarity and maintainability, it's good practice to use consistent and descriptive comments for coordinate system conversions.

Suggested change
ary[3] = -engine.ConvertToInt64(p.PosY) // here need flipY to convert spx coord to godot coord
ary[4] = engine.ConvertToInt64(p.NormalX)
ary[5] = engine.ConvertToInt64(p.NormalY)
ary[5] = -engine.ConvertToInt64(p.NormalY)
ary[3] = -engine.ConvertToInt64(p.PosY) // Flip Y for Godot's coordinate system (Y-down).
ary[4] = engine.ConvertToInt64(p.NormalX)
ary[5] = -engine.ConvertToInt64(p.NormalY) // Flip Y for Godot's coordinate system (Y-down).

return ary
}
func tryRaycastResult(ary engine.Array) (*rayCastResult, error) {
Expand All @@ -103,9 +103,9 @@ func tryRaycastResult(ary engine.Array) (*rayCastResult, error) {
p.Hited = dataAry[0] != 0
p.SpriteId = dataAry[1]
p.PosX = engine.ConvertToFloat64(dataAry[2])
p.PosY = engine.ConvertToFloat64(dataAry[3])
p.PosY = -engine.ConvertToFloat64(dataAry[3]) // here need flipY to convert to godot coord to spx coord
Copy link
Contributor

Choose a reason for hiding this comment

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

Grammar error in comment

Suggested change
p.PosY = -engine.ConvertToFloat64(dataAry[3]) // here need flipY to convert to godot coord to spx coord
p.PosY = -engine.ConvertToFloat64(dataAry[3]) // flipY to convert from Godot coord to SPX coord

p.NormalX = engine.ConvertToFloat64(dataAry[4])
p.NormalY = engine.ConvertToFloat64(dataAry[5])
p.NormalY = -engine.ConvertToFloat64(dataAry[5])
Comment on lines +106 to +108

Choose a reason for hiding this comment

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

medium

The comment on line 106 has a typo ("to godot coord to spx coord") and is a bit informal. The same conversion is done for NormalY on line 108. Using a clear and consistent comment style for these conversions will make the code easier to understand.

Suggested change
p.PosY = -engine.ConvertToFloat64(dataAry[3]) // here need flipY to convert to godot coord to spx coord
p.NormalX = engine.ConvertToFloat64(dataAry[4])
p.NormalY = engine.ConvertToFloat64(dataAry[5])
p.NormalY = -engine.ConvertToFloat64(dataAry[5])
p.PosY = -engine.ConvertToFloat64(dataAry[3]) // Flip Y to convert from Godot (Y-down) to SPX (Y-up).
p.NormalX = engine.ConvertToFloat64(dataAry[4])
p.NormalY = -engine.ConvertToFloat64(dataAry[5]) // Flip Y to convert from Godot (Y-down) to SPX (Y-up).

Copy link
Contributor

Choose a reason for hiding this comment

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

Same grammar fix needed

Suggested change
p.NormalY = -engine.ConvertToFloat64(dataAry[5])
p.NormalY = -engine.ConvertToFloat64(dataAry[5]) // flipY to convert from Godot coord to SPX coord

return p, nil
}
func raycast(from, to mathf.Vec2, ignoreSprites []int64, mask int64) *rayCastResult {
Expand Down
Loading