mirror of
https://github.com/genxium/DelayNoMore
synced 2024-12-26 11:48:56 +00:00
Updated barrier boundaries and player collider paddings to feature almost-all-integer coordinates.
This commit is contained in:
parent
eedcf5c4dc
commit
db2bc0e3cd
@ -775,7 +775,7 @@ func (pR *Room) OnDismissed() {
|
|||||||
},
|
},
|
||||||
HitboxOffset: float64(12.0), // should be about the radius of the PlayerCollider
|
HitboxOffset: float64(12.0), // should be about the radius of the PlayerCollider
|
||||||
HitboxSize: &Vec2D{
|
HitboxSize: &Vec2D{
|
||||||
X: float64(23.0),
|
X: float64(24.0),
|
||||||
Y: float64(32.0),
|
Y: float64(32.0),
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -789,9 +789,9 @@ func (pR *Room) OnDismissed() {
|
|||||||
|
|
||||||
pR.SnapIntoPlatformOverlap = float64(0.1)
|
pR.SnapIntoPlatformOverlap = float64(0.1)
|
||||||
pR.SnapIntoPlatformThreshold = float64(0.5)
|
pR.SnapIntoPlatformThreshold = float64(0.5)
|
||||||
pR.JumpingInitVelY = int32(float64(6) * pR.WorldToVirtualGridRatio)
|
pR.JumpingInitVelY = int32(float64(7) * pR.WorldToVirtualGridRatio)
|
||||||
pR.GravityX = 0
|
pR.GravityX = 0
|
||||||
pR.GravityY = -(4*pR.JumpingInitVelY + (pR.ServerFps - 1)) / pR.ServerFps // i.e. -Math.ceil(4*jumpingInitVelY / serverFps)
|
pR.GravityY = -int32(float64(0.5)*pR.WorldToVirtualGridRatio) // makes all "playerCollider.Y" a multiple of 0.5 in all cases
|
||||||
|
|
||||||
pR.ChooseStage()
|
pR.ChooseStage()
|
||||||
pR.EffectivePlayerCount = 0
|
pR.EffectivePlayerCount = 0
|
||||||
@ -1396,7 +1396,8 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF
|
|||||||
// Reset playerCollider position from the "virtual grid position"
|
// Reset playerCollider position from the "virtual grid position"
|
||||||
newVx, newVy := currPlayerDownsync.VirtualGridX+currPlayerDownsync.VelX, currPlayerDownsync.VirtualGridY+currPlayerDownsync.VelY
|
newVx, newVy := currPlayerDownsync.VirtualGridX+currPlayerDownsync.VelX, currPlayerDownsync.VirtualGridY+currPlayerDownsync.VelY
|
||||||
|
|
||||||
playerCollider.X, playerCollider.Y = VirtualGridToPolygonColliderAnchorPos(newVx, newVy, player.ColliderRadius, player.ColliderRadius, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.VirtualGridToWorldRatio)
|
colliderWidth, colliderHeight := player.ColliderRadius*2, player.ColliderRadius*4
|
||||||
|
playerCollider.X, playerCollider.Y = VirtualGridToPolygonColliderBLPos(newVx, newVy, colliderWidth*0.5, colliderHeight*0.5, pR.SnapIntoPlatformOverlap, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.VirtualGridToWorldRatio)
|
||||||
// Update in the collision system
|
// Update in the collision system
|
||||||
playerCollider.Update()
|
playerCollider.Update()
|
||||||
|
|
||||||
@ -1423,7 +1424,7 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF
|
|||||||
offenderWx, offenderWy := VirtualGridToWorldPos(offender.VirtualGridX, offender.VirtualGridY, pR.VirtualGridToWorldRatio)
|
offenderWx, offenderWy := VirtualGridToWorldPos(offender.VirtualGridX, offender.VirtualGridY, pR.VirtualGridToWorldRatio)
|
||||||
bulletWx, bulletWy := offenderWx+xfac*meleeBullet.HitboxOffset, offenderWy
|
bulletWx, bulletWy := offenderWx+xfac*meleeBullet.HitboxOffset, offenderWy
|
||||||
|
|
||||||
newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, meleeBullet.HitboxSize.X, meleeBullet.HitboxSize.Y, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, "MeleeBullet")
|
newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, meleeBullet.HitboxSize.X, meleeBullet.HitboxSize.Y, 0, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, "MeleeBullet")
|
||||||
newBulletCollider.Data = meleeBullet
|
newBulletCollider.Data = meleeBullet
|
||||||
pR.Space.Add(newBulletCollider)
|
pR.Space.Add(newBulletCollider)
|
||||||
collisionSysMap[collisionBulletIndex] = newBulletCollider
|
collisionSysMap[collisionBulletIndex] = newBulletCollider
|
||||||
@ -1601,17 +1602,18 @@ func (pR *Room) applyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputF
|
|||||||
playerShape := playerCollider.Shape.(*resolv.ConvexPolygon)
|
playerShape := playerCollider.Shape.(*resolv.ConvexPolygon)
|
||||||
// Update "virtual grid position"
|
// Update "virtual grid position"
|
||||||
currPlayerDownsync, thatPlayerInNextFrame := currRenderFrame.Players[playerId], nextRenderFramePlayers[playerId]
|
currPlayerDownsync, thatPlayerInNextFrame := currRenderFrame.Players[playerId], nextRenderFramePlayers[playerId]
|
||||||
thatPlayerInNextFrame.VirtualGridX, thatPlayerInNextFrame.VirtualGridY = PolygonColliderAnchorToVirtualGridPos(playerCollider.X-effPushbacks[joinIndex-1].X, playerCollider.Y-effPushbacks[joinIndex-1].Y, player.ColliderRadius, player.ColliderRadius, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.WorldToVirtualGridRatio)
|
colliderWidth, colliderHeight := player.ColliderRadius*2, player.ColliderRadius*4
|
||||||
|
thatPlayerInNextFrame.VirtualGridX, thatPlayerInNextFrame.VirtualGridY = PolygonColliderBLToVirtualGridPos(playerCollider.X-effPushbacks[joinIndex-1].X, playerCollider.Y-effPushbacks[joinIndex-1].Y, colliderWidth*0.5, colliderHeight*0.5, pR.SnapIntoPlatformOverlap, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, pR.WorldToVirtualGridRatio)
|
||||||
|
|
||||||
if 1 == thatPlayerInNextFrame.JoinIndex {
|
if 1 == thatPlayerInNextFrame.JoinIndex {
|
||||||
if thatPlayerInNextFrame.InAir && (0 != thatPlayerInNextFrame.VelY) {
|
if thatPlayerInNextFrame.InAir && (0 != thatPlayerInNextFrame.VelY) {
|
||||||
Logger.Info(fmt.Sprintf("playerId=%d, joinIndex=%d inAir trajectory: {nextRenderFrame.id: %d, nextVirtualX: %d, nextVirtualY: %d, nextVelX: %d, nextVelX: %d}, with playerColliderPos={%.3f, %.3f}, effPushback={%.3f, %.3f}", playerId, joinIndex, currRenderFrame.Id+1, thatPlayerInNextFrame.VirtualGridX, thatPlayerInNextFrame.VirtualGridY, thatPlayerInNextFrame.VelX, thatPlayerInNextFrame.VelY, playerShape.X-pR.collisionSpaceOffsetX, playerShape.Y-pR.collisionSpaceOffsetY, effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y))
|
Logger.Info(fmt.Sprintf("playerId=%d, joinIndex=%d inAir trajectory: {nextRenderFrame.id: %d, nextVirtualX: %d, nextVirtualY: %d, nextVelX: %d, nextVelY: %d}, with playerColliderPos={%.3f, %.3f}, effPushback={%.3f, %.3f}", playerId, joinIndex, currRenderFrame.Id+1, thatPlayerInNextFrame.VirtualGridX, thatPlayerInNextFrame.VirtualGridY, thatPlayerInNextFrame.VelX, thatPlayerInNextFrame.VelY, playerShape.X-pR.collisionSpaceOffsetX, playerShape.Y-pR.collisionSpaceOffsetY, effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y))
|
||||||
}
|
}
|
||||||
if currPlayerDownsync.InAir && !thatPlayerInNextFrame.InAir {
|
if currPlayerDownsync.InAir && !thatPlayerInNextFrame.InAir {
|
||||||
Logger.Warn(fmt.Sprintf("playerId=%d, joinIndex=%d fallStopping#2 at {nextRenderFrame.id: %d, nextVirtualX: %d, nextVirtualY: %d, nextVelX: %d, nextVelX: %d}, with playerColliderPos={%.3f, %.3f}, effPushback={%.3f, %.3f}", playerId, joinIndex, currRenderFrame.Id+1, thatPlayerInNextFrame.VirtualGridX, thatPlayerInNextFrame.VirtualGridY, thatPlayerInNextFrame.VelX, thatPlayerInNextFrame.VelY, playerShape.X-pR.collisionSpaceOffsetX, playerShape.Y-pR.collisionSpaceOffsetY, effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y))
|
Logger.Warn(fmt.Sprintf("playerId=%d, joinIndex=%d fallStopping#2 at {nextRenderFrame.id: %d, nextVirtualX: %d, nextVirtualY: %d, nextVelX: %d, nextVelY: %d}, with playerColliderPos={%.3f, %.3f}, effPushback={%.3f, %.3f}", playerId, joinIndex, currRenderFrame.Id+1, thatPlayerInNextFrame.VirtualGridX, thatPlayerInNextFrame.VirtualGridY, thatPlayerInNextFrame.VelX, thatPlayerInNextFrame.VelY, playerShape.X-pR.collisionSpaceOffsetX, playerShape.Y-pR.collisionSpaceOffsetY, effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y))
|
||||||
}
|
}
|
||||||
if !currPlayerDownsync.InAir && thatPlayerInNextFrame.InAir {
|
if !currPlayerDownsync.InAir && thatPlayerInNextFrame.InAir {
|
||||||
Logger.Warn(fmt.Sprintf("playerId=%d, joinIndex=%d took off at {nextRenderFrame.id: %d, nextVirtualX: %d, nextVirtualY: %d, nextVelX: %d, nextVelX: %d}, with playerColliderPos={%.3f, %.3f}, effPushback={%.3f, %.3f}", playerId, joinIndex, currRenderFrame.Id+1, thatPlayerInNextFrame.VirtualGridX, thatPlayerInNextFrame.VirtualGridY, thatPlayerInNextFrame.VelX, thatPlayerInNextFrame.VelY, playerShape.X-pR.collisionSpaceOffsetX, playerShape.Y-pR.collisionSpaceOffsetY, effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y))
|
Logger.Warn(fmt.Sprintf("playerId=%d, joinIndex=%d took off at {nextRenderFrame.id: %d, nextVirtualX: %d, nextVirtualY: %d, nextVelX: %d, nextVelY: %d}, with playerColliderPos={%.3f, %.3f}, effPushback={%.3f, %.3f}", playerId, joinIndex, currRenderFrame.Id+1, thatPlayerInNextFrame.VirtualGridX, thatPlayerInNextFrame.VirtualGridY, thatPlayerInNextFrame.VelX, thatPlayerInNextFrame.VelY, playerShape.X-pR.collisionSpaceOffsetX, playerShape.Y-pR.collisionSpaceOffsetY, effPushbacks[joinIndex-1].X, effPushbacks[joinIndex-1].Y))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1648,7 +1650,7 @@ func (pR *Room) refreshColliders(spaceW, spaceH int32) {
|
|||||||
for _, player := range pR.Players {
|
for _, player := range pR.Players {
|
||||||
wx, wy := VirtualGridToWorldPos(player.VirtualGridX, player.VirtualGridY, pR.VirtualGridToWorldRatio)
|
wx, wy := VirtualGridToWorldPos(player.VirtualGridX, player.VirtualGridY, pR.VirtualGridToWorldRatio)
|
||||||
colliderWidth, colliderHeight := player.ColliderRadius*2, player.ColliderRadius*4
|
colliderWidth, colliderHeight := player.ColliderRadius*2, player.ColliderRadius*4
|
||||||
playerCollider := GenerateRectCollider(wx, wy, colliderWidth, colliderHeight, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, "Player")
|
playerCollider := GenerateRectCollider(wx, wy, colliderWidth, colliderHeight, pR.SnapIntoPlatformOverlap, pR.collisionSpaceOffsetX, pR.collisionSpaceOffsetY, "Player") // the coords of all barrier boundaries are multiples of tileWidth(i.e. 16), by adding snapping y-padding when "landedOnGravityPushback" all "playerCollider.Y" would be a multiple of 1.0
|
||||||
playerCollider.Data = player
|
playerCollider.Data = player
|
||||||
pR.Space.Add(playerCollider)
|
pR.Space.Add(playerCollider)
|
||||||
// Keep track of the collider in "pR.CollisionSysMap"
|
// Keep track of the collider in "pR.CollisionSysMap"
|
||||||
|
@ -40,9 +40,11 @@ func NewWorldColliderDisplay(game *Game, stageDiscreteW, stageDiscreteH, stageTi
|
|||||||
minStep := (int(float64(playerDefaultSpeed)*virtualGridToWorldRatio) << 2)
|
minStep := (int(float64(playerDefaultSpeed)*virtualGridToWorldRatio) << 2)
|
||||||
playerColliderRadius := float64(12)
|
playerColliderRadius := float64(12)
|
||||||
playerColliders := make([]*resolv.Object, len(playerPosList.Eles))
|
playerColliders := make([]*resolv.Object, len(playerPosList.Eles))
|
||||||
|
snapIntoPlatformOverlap := float64(0.1)
|
||||||
space := resolv.NewSpace(int(spaceW), int(spaceH), minStep, minStep)
|
space := resolv.NewSpace(int(spaceW), int(spaceH), minStep, minStep)
|
||||||
for i, playerPos := range playerPosList.Eles {
|
for i, playerPos := range playerPosList.Eles {
|
||||||
playerCollider := GenerateRectCollider(playerPos.X, playerPos.Y, playerColliderRadius*2, playerColliderRadius*4, spaceOffsetX, spaceOffsetY, "Player") // [WARNING] Deliberately not using a circle because "resolv v0.5.1" doesn't yet align circle center with space cell center, regardless of the "specified within-object offset"
|
colliderWidth, colliderHeight := playerColliderRadius*2, playerColliderRadius*4
|
||||||
|
playerCollider := GenerateRectCollider(playerPos.X, playerPos.Y, colliderWidth, colliderHeight, snapIntoPlatformOverlap, spaceOffsetX, spaceOffsetY, "Player") // [WARNING] Deliberately not using a circle because "resolv v0.5.1" doesn't yet align circle center with space cell center, regardless of the "specified within-object offset"
|
||||||
Logger.Info(fmt.Sprintf("Player Collider#%d: player world pos=(%.2f, %.2f), shape=%v", i, playerPos.X, playerPos.Y, ConvexPolygonStr(playerCollider.Shape.(*resolv.ConvexPolygon))))
|
Logger.Info(fmt.Sprintf("Player Collider#%d: player world pos=(%.2f, %.2f), shape=%v", i, playerPos.X, playerPos.Y, ConvexPolygonStr(playerCollider.Shape.(*resolv.ConvexPolygon))))
|
||||||
playerColliders[i] = playerCollider
|
playerColliders[i] = playerCollider
|
||||||
space.Add(playerCollider)
|
space.Add(playerCollider)
|
||||||
@ -58,12 +60,13 @@ func NewWorldColliderDisplay(game *Game, stageDiscreteW, stageDiscreteH, stageTi
|
|||||||
|
|
||||||
world.Space = space
|
world.Space = space
|
||||||
|
|
||||||
moveToCollide := true
|
moveToCollide := false
|
||||||
if moveToCollide {
|
if moveToCollide {
|
||||||
effPushback := Vec2D{X: float64(0), Y: float64(0)}
|
effPushback := Vec2D{X: float64(0), Y: float64(0)}
|
||||||
toTestPlayerCollider := playerColliders[0]
|
toTestPlayerCollider := playerColliders[0]
|
||||||
newVx, newVy := int32(43900), int32(-451350)
|
newVx, newVy := int32(27999), int32(-420270)
|
||||||
toTestPlayerCollider.X, toTestPlayerCollider.Y = VirtualGridToPolygonColliderAnchorPos(newVx, newVy, playerColliderRadius, playerColliderRadius, spaceOffsetX, spaceOffsetY, virtualGridToWorldRatio)
|
colliderWidth, colliderHeight := playerColliderRadius*2, playerColliderRadius*4
|
||||||
|
toTestPlayerCollider.X, toTestPlayerCollider.Y = VirtualGridToPolygonColliderTLPos(newVx, newVy, colliderWidth, colliderHeight, spaceOffsetX, spaceOffsetY, virtualGridToWorldRatio)
|
||||||
|
|
||||||
Logger.Info(fmt.Sprintf("Checking collision for playerShape=%v", ConvexPolygonStr(toTestPlayerCollider.Shape.(*resolv.ConvexPolygon))))
|
Logger.Info(fmt.Sprintf("Checking collision for playerShape=%v", ConvexPolygonStr(toTestPlayerCollider.Shape.(*resolv.ConvexPolygon))))
|
||||||
|
|
||||||
@ -117,7 +120,7 @@ func NewWorldColliderDisplay(game *Game, stageDiscreteW, stageDiscreteH, stageTi
|
|||||||
offenderWx, offenderWy := playerPosList.Eles[0].X, playerPosList.Eles[0].Y
|
offenderWx, offenderWy := playerPosList.Eles[0].X, playerPosList.Eles[0].Y
|
||||||
bulletWx, bulletWy := offenderWx+xfac*meleeBullet.HitboxOffset, offenderWy
|
bulletWx, bulletWy := offenderWx+xfac*meleeBullet.HitboxOffset, offenderWy
|
||||||
|
|
||||||
newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, meleeBullet.HitboxSize.X, meleeBullet.HitboxSize.Y, spaceOffsetX, spaceOffsetY, "MeleeBullet")
|
newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, meleeBullet.HitboxSize.X, meleeBullet.HitboxSize.Y, 0, spaceOffsetX, spaceOffsetY, "MeleeBullet")
|
||||||
space.Add(newBulletCollider)
|
space.Add(newBulletCollider)
|
||||||
bulletShape := newBulletCollider.Shape.(*resolv.ConvexPolygon)
|
bulletShape := newBulletCollider.Shape.(*resolv.ConvexPolygon)
|
||||||
Logger.Warn(fmt.Sprintf("bullet ->: Added bullet collider to space: a=%v", ConvexPolygonStr(bulletShape)))
|
Logger.Warn(fmt.Sprintf("bullet ->: Added bullet collider to space: a=%v", ConvexPolygonStr(bulletShape)))
|
||||||
@ -140,7 +143,7 @@ func NewWorldColliderDisplay(game *Game, stageDiscreteW, stageDiscreteH, stageTi
|
|||||||
offenderWx, offenderWy := playerPosList.Eles[1].X, playerPosList.Eles[1].Y
|
offenderWx, offenderWy := playerPosList.Eles[1].X, playerPosList.Eles[1].Y
|
||||||
bulletWx, bulletWy := offenderWx+xfac*meleeBullet.HitboxOffset, offenderWy
|
bulletWx, bulletWy := offenderWx+xfac*meleeBullet.HitboxOffset, offenderWy
|
||||||
|
|
||||||
newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, meleeBullet.HitboxSize.X, meleeBullet.HitboxSize.Y, spaceOffsetX, spaceOffsetY, "MeleeBullet")
|
newBulletCollider := GenerateRectCollider(bulletWx, bulletWy, meleeBullet.HitboxSize.X, meleeBullet.HitboxSize.Y, 0, spaceOffsetX, spaceOffsetY, "MeleeBullet")
|
||||||
space.Add(newBulletCollider)
|
space.Add(newBulletCollider)
|
||||||
bulletShape := newBulletCollider.Shape.(*resolv.ConvexPolygon)
|
bulletShape := newBulletCollider.Shape.(*resolv.ConvexPolygon)
|
||||||
Logger.Warn(fmt.Sprintf("bullet <-: Added bullet collider to space: a=%v", ConvexPolygonStr(bulletShape)))
|
Logger.Warn(fmt.Sprintf("bullet <-: Added bullet collider to space: a=%v", ConvexPolygonStr(bulletShape)))
|
||||||
|
@ -10,33 +10,33 @@ func NormVec2D(dx, dy float64) Vec2D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func AlignPolygon2DToBoundingBox(input *Polygon2D) *Polygon2D {
|
func AlignPolygon2DToBoundingBox(input *Polygon2D) *Polygon2D {
|
||||||
// Transform again to put "anchor" at the top-left point of the bounding box for "resolv"
|
// Transform again to put "anchor" at the "bottom-left point (w.r.t. world space)" of the bounding box for "resolv"
|
||||||
boundingBoxTL := &Vec2D{
|
boundingBoxBL := &Vec2D{
|
||||||
X: math.MaxFloat64,
|
X: math.MaxFloat64,
|
||||||
Y: math.MaxFloat64,
|
Y: math.MaxFloat64,
|
||||||
}
|
}
|
||||||
for _, p := range input.Points {
|
for _, p := range input.Points {
|
||||||
if p.X < boundingBoxTL.X {
|
if p.X < boundingBoxBL.X {
|
||||||
boundingBoxTL.X = p.X
|
boundingBoxBL.X = p.X
|
||||||
}
|
}
|
||||||
if p.Y < boundingBoxTL.Y {
|
if p.Y < boundingBoxBL.Y {
|
||||||
boundingBoxTL.Y = p.Y
|
boundingBoxBL.Y = p.Y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now "input.Anchor" should move to "input.Anchor+boundingBoxTL", thus "boundingBoxTL" is also the value of the negative diff for all "input.Points"
|
// Now "input.Anchor" should move to "input.Anchor+boundingBoxBL", thus "boundingBoxBL" is also the value of the negative diff for all "input.Points"
|
||||||
output := &Polygon2D{
|
output := &Polygon2D{
|
||||||
Anchor: &Vec2D{
|
Anchor: &Vec2D{
|
||||||
X: input.Anchor.X + boundingBoxTL.X,
|
X: input.Anchor.X + boundingBoxBL.X,
|
||||||
Y: input.Anchor.Y + boundingBoxTL.Y,
|
Y: input.Anchor.Y + boundingBoxBL.Y,
|
||||||
},
|
},
|
||||||
Points: make([]*Vec2D, len(input.Points)),
|
Points: make([]*Vec2D, len(input.Points)),
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, p := range input.Points {
|
for i, p := range input.Points {
|
||||||
output.Points[i] = &Vec2D{
|
output.Points[i] = &Vec2D{
|
||||||
X: p.X - boundingBoxTL.X,
|
X: p.X - boundingBoxBL.X,
|
||||||
Y: p.Y - boundingBoxTL.Y,
|
Y: p.Y - boundingBoxBL.Y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,19 +12,19 @@ import (
|
|||||||
func ConvexPolygonStr(body *resolv.ConvexPolygon) string {
|
func ConvexPolygonStr(body *resolv.ConvexPolygon) string {
|
||||||
var s []string = make([]string, len(body.Points))
|
var s []string = make([]string, len(body.Points))
|
||||||
for i, p := range body.Points {
|
for i, p := range body.Points {
|
||||||
s[i] = fmt.Sprintf("[%.3f, %.3f]", p[0]+body.X, p[1]+body.Y)
|
s[i] = fmt.Sprintf("[%.2f, %.2f]", p[0]+body.X, p[1]+body.Y)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("{\n%s\n}", strings.Join(s, ",\n"))
|
return fmt.Sprintf("{\n%s\n}", strings.Join(s, ",\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateRectCollider(origX, origY, w, h, spaceOffsetX, spaceOffsetY float64, tag string) *resolv.Object {
|
func GenerateRectCollider(wx, wy, w, h, bottomPadding, spaceOffsetX, spaceOffsetY float64, tag string) *resolv.Object {
|
||||||
cx, cy := WorldToPolygonColliderAnchorPos(origX, origY, w*0.5, h*0.5, spaceOffsetX, spaceOffsetY)
|
blX, blY := WorldToPolygonColliderBLPos(wx, wy, w*0.5, h*0.5, bottomPadding, spaceOffsetX, spaceOffsetY)
|
||||||
return GenerateRectColliderInCollisionSpace(cx, cy, w, h, tag)
|
return generateRectColliderInCollisionSpace(blX, blY, w, h+bottomPadding, tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateRectColliderInCollisionSpace(cx, cy, w, h float64, tag string) *resolv.Object {
|
func generateRectColliderInCollisionSpace(blX, blY, w, h float64, tag string) *resolv.Object {
|
||||||
collider := resolv.NewObject(cx, cy, w, h, tag)
|
collider := resolv.NewObject(blX, blY, w, h, tag) // Unlike its frontend counter part, the position of a "resolv.Object" must be specified by "bottom-left point" because "w" and "h" must be positive, see "resolv.Object.BoundsToSpace" for details
|
||||||
shape := resolv.NewRectangle(0, 0, w, h)
|
shape := resolv.NewRectangle(0, 0, w, h)
|
||||||
collider.SetShape(shape)
|
collider.SetShape(shape)
|
||||||
return collider
|
return collider
|
||||||
@ -246,20 +246,38 @@ func VirtualGridToWorldPos(vx, vy int32, virtualGridToWorldRatio float64) (float
|
|||||||
return wx, wy
|
return wx, wy
|
||||||
}
|
}
|
||||||
|
|
||||||
func WorldToPolygonColliderAnchorPos(wx, wy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64) (float64, float64) {
|
func WorldToPolygonColliderBLPos(wx, wy, halfBoundingW, halfBoundingH, bottomPadding, collisionSpaceOffsetX, collisionSpaceOffsetY float64) (float64, float64) {
|
||||||
return wx - halfBoundingW + collisionSpaceOffsetX, wy - halfBoundingH + collisionSpaceOffsetY
|
return wx - halfBoundingW + collisionSpaceOffsetX, wy - halfBoundingH - bottomPadding + collisionSpaceOffsetY
|
||||||
}
|
}
|
||||||
|
|
||||||
func PolygonColliderAnchorToWorldPos(cx, cy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64) (float64, float64) {
|
func WorldToPolygonColliderTLPos(wx, wy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64) (float64, float64) {
|
||||||
return cx + halfBoundingW - collisionSpaceOffsetX, cy + halfBoundingH - collisionSpaceOffsetY
|
return wx - halfBoundingW + collisionSpaceOffsetX, wy + halfBoundingH + collisionSpaceOffsetY
|
||||||
}
|
}
|
||||||
|
|
||||||
func PolygonColliderAnchorToVirtualGridPos(cx, cy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64, worldToVirtualGridRatio float64) (int32, int32) {
|
func PolygonColliderBLToWorldPos(cx, cy, halfBoundingW, halfBoundingH, bottomPadding, collisionSpaceOffsetX, collisionSpaceOffsetY float64) (float64, float64) {
|
||||||
wx, wy := PolygonColliderAnchorToWorldPos(cx, cy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY)
|
return cx + halfBoundingW - collisionSpaceOffsetX, cy + halfBoundingH + bottomPadding - collisionSpaceOffsetY
|
||||||
|
}
|
||||||
|
|
||||||
|
func PolygonColliderTLToWorldPos(cx, cy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64) (float64, float64) {
|
||||||
|
return cx + halfBoundingW - collisionSpaceOffsetX, cy - halfBoundingH - collisionSpaceOffsetY
|
||||||
|
}
|
||||||
|
|
||||||
|
func PolygonColliderBLToVirtualGridPos(cx, cy, halfBoundingW, halfBoundingH, bottomPadding, collisionSpaceOffsetX, collisionSpaceOffsetY float64, worldToVirtualGridRatio float64) (int32, int32) {
|
||||||
|
wx, wy := PolygonColliderBLToWorldPos(cx, cy, halfBoundingW, halfBoundingH, bottomPadding, collisionSpaceOffsetX, collisionSpaceOffsetY)
|
||||||
return WorldToVirtualGridPos(wx, wy, worldToVirtualGridRatio)
|
return WorldToVirtualGridPos(wx, wy, worldToVirtualGridRatio)
|
||||||
}
|
}
|
||||||
|
|
||||||
func VirtualGridToPolygonColliderAnchorPos(vx, vy int32, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64, virtualGridToWorldRatio float64) (float64, float64) {
|
func PolygonColliderTLToVirtualGridPos(cx, cy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64, worldToVirtualGridRatio float64) (int32, int32) {
|
||||||
wx, wy := VirtualGridToWorldPos(vx, vy, virtualGridToWorldRatio)
|
wx, wy := PolygonColliderTLToWorldPos(cx, cy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY)
|
||||||
return WorldToPolygonColliderAnchorPos(wx, wy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY)
|
return WorldToVirtualGridPos(wx, wy, worldToVirtualGridRatio)
|
||||||
|
}
|
||||||
|
|
||||||
|
func VirtualGridToPolygonColliderBLPos(vx, vy int32, halfBoundingW, halfBoundingH, bottomPadding, collisionSpaceOffsetX, collisionSpaceOffsetY float64, virtualGridToWorldRatio float64) (float64, float64) {
|
||||||
|
wx, wy := VirtualGridToWorldPos(vx, vy, virtualGridToWorldRatio)
|
||||||
|
return WorldToPolygonColliderBLPos(wx, wy, halfBoundingW, halfBoundingH, bottomPadding, collisionSpaceOffsetX, collisionSpaceOffsetY)
|
||||||
|
}
|
||||||
|
|
||||||
|
func VirtualGridToPolygonColliderTLPos(vx, vy int32, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY float64, virtualGridToWorldRatio float64) (float64, float64) {
|
||||||
|
wx, wy := VirtualGridToWorldPos(vx, vy, virtualGridToWorldRatio)
|
||||||
|
return WorldToPolygonColliderTLPos(wx, wy, halfBoundingW, halfBoundingH, collisionSpaceOffsetX, collisionSpaceOffsetY)
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.2" tiledversion="1.2.3" orientation="orthogonal" renderorder="right-down" width="128" height="128" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="83">
|
<map version="1.2" tiledversion="1.2.3" orientation="orthogonal" renderorder="right-down" width="128" height="128" tilewidth="16" tileheight="16" infinite="0" nextlayerid="3" nextobjectid="87">
|
||||||
<tileset firstgid="1" source="tiles0.tsx"/>
|
<tileset firstgid="1" source="tiles0.tsx"/>
|
||||||
<tileset firstgid="65" source="tiles1.tsx"/>
|
<tileset firstgid="65" source="tiles1.tsx"/>
|
||||||
<tileset firstgid="129" source="tiles2.tsx"/>
|
<tileset firstgid="129" source="tiles2.tsx"/>
|
||||||
<layer id="2" name="Ground" width="128" height="128">
|
<layer id="2" name="Ground" width="128" height="128">
|
||||||
<data encoding="base64" compression="zlib">
|
<data encoding="base64" compression="zlib">
|
||||||
eJzt3DFv00AYgOEoFUuHigqBVGYGJP4EI+qAOsHG1H/CzsjIRP8njhRLwUpi52L7O/t7hmdpOiT33tmXtJebzWZzAwAAAAAAAAAAAAAAAAAABW73op8H83k+0PZ/Tii6Q2T/7V7b/0fj8YTtCun/f/9T9F+fw/6PPf1vK2il/3T9j9F/3Xav/e3esbHpXhOiW+k/b/8M9Nc/ukNk/1cFopvpr7/++usf078G+uuvv/7666//svr/Gvh793v6r6v/38afE4/t/v780viqf3j/0jFtP1P8eSX99ddf/91zeejQf/39Hzr9rX/99Y/v/7rHmP0P6R/bv6/7sf6/G98u1Pa3/6un/9D2Txv7/6UY2n9o+63+i9LX/1jjT427E+27/bueLqR/XP9j7e8OdLtP0f9d44P+1fQ/d90/7D82/evtX7JHvJT+8/cfMge6Yzlm3z5j9t9W0KLG/mON8Tkl7fVfT/9o+ueeA/rrr7/+0S2i+kePf7Ts7/+ixz+a/rnpn5v+uemfm/656Z+b/rnpn5v+uemfm/656Z+b/rnpn5v+uelf7k1HdEv9l93/vscU/6Omfz39rf+6+3d7679s9n/6zz3ep+7tkf23FbSouf/3ve71vv159BrWf9r+5+75+i/XkP7nzgb1vV+LvK5f0j+6Q639284fr1D7GTL9p1X7OcLs/ac+81n7WdLs/eda/63aPifSf97+7Ry4lP7z9R9zP1/y3T7617P+r50Hpd/vNNd9Qv9hSufB+8L+L40v+lfTv1TT/3Np/9aU8yB7f+I7AAAAAAAAAAAAAAAAAPP7B3wkkY4=
|
eJzt3DFq3EAUgOFlTRoXJiEkkNQpAr5EyuDKVdKl8k1yh9wg94wMK1DEaqXVjvRGel/xgXFh7PnfSBqx+O5wONwBAAAAAAAAAAAAAAAAAMAM9yfRvwfreelo+78kFN0hsv/xpO3/q/E04LhD+v/ff4j++9Pt/zTS/76CVvov1/8c/fft9W//cHJubfrXhOhW+q/bPwP99Y/uENn//QzRzfSP7b+nGdBf/+gOW+xfE/1z9rf/c/cvMQP6b5f9r7/+efuXmAH9y69t+07x942W3vv666//Nvp/OtE/T/9u7+7X+uuvf1z/tyNK9u/SP7b/WPdz/f80flyp7e/5r57+U9s/Hzz/b8XU/lPbH/XflLH+5xo/Nh4G2vf79z1fSf+4/ufaP3T0uy/R/2Pji/7V9L903e/2L03/evvPeUa8lv7r958yA/21LNl3TMn+xwpa1Ni/1BpfMqe9/vvpf82MLPGz9d/GDCxF/9wzoL/+mftHr3+07Oe/6PWPpn9u+uemf27656Z/bvrnpn9u+uemf27656Z/bvrnpn9u+uemf276z7eHzwnpX0//dyPeDNB/H/3t/7r77/Fzovrnpv+6hu7tkf2PFbSouf/Pk/71vv1+9B7Wf9n+l+75+m/XlP5DZ65XY+e1yOv6Nf2jO9Tav+389Qa3ns/1j93/tyrxjkb/5fqXfp821L/WGcjef63936rtPZH+6/ZvZyDq/73oP96/5PP8pfPDEP3r2f+3zsGc/mveJ/SfZu4cfJ7Z/2/ju/7V9J+r6f9tbv/WknOQvT/xHQAAAAAAAAAAAAAAAID1/QPUuKyX
|
||||||
</data>
|
</data>
|
||||||
</layer>
|
</layer>
|
||||||
<objectgroup id="1" name="PlayerStartingPos">
|
<objectgroup id="1" name="PlayerStartingPos">
|
||||||
<object id="135" x="1010" y="1451">
|
<object id="135" x="1010" y="1432">
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
<object id="137" x="951" y="1452">
|
<object id="137" x="950" y="1432">
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
@ -20,151 +20,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<property name="type" value="barrier_and_shelter"/>
|
<property name="type" value="barrier_and_shelter"/>
|
||||||
</properties>
|
</properties>
|
||||||
<object id="8" x="648.242" y="480.606">
|
<object id="54" x="656" y="1504" width="80" height="16">
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 0,18.6667 1041.33,21.3333 1041.33,-1.33333"/>
|
|
||||||
</object>
|
|
||||||
<object id="10" x="634.485" y="505.455">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 4,1110 24,1110 24,-8"/>
|
|
||||||
</object>
|
|
||||||
<object id="11" x="1677.64" y="501.333">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 4,1110 24,1110 24,-8"/>
|
|
||||||
</object>
|
|
||||||
<object id="14" x="688.667" y="464">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 -0.666667,78 33.3333,78 32,-0.666667"/>
|
|
||||||
</object>
|
|
||||||
<object id="15" x="833.333" y="495.333">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 -112,1.33333 -111.333,44.6667 -1.33333,44.6667"/>
|
|
||||||
</object>
|
|
||||||
<object id="17" x="832" y="574">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 -67.3333,0 -67.3333,-76.6667 0.666667,-76"/>
|
|
||||||
</object>
|
|
||||||
<object id="18" x="865.333" y="606.667">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 -210,-0.666667 -210,143.333 0,142.667"/>
|
|
||||||
</object>
|
|
||||||
<object id="19" x="754.667" y="1055.33">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="-2,1.33333 -100,0.666667 -97.3333,-454 -9.33333,-451.333"/>
|
|
||||||
</object>
|
|
||||||
<object id="20" x="769.333" y="747.333">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 -115.333,0.666667 -114.667,160.667 -2,162"/>
|
|
||||||
</object>
|
|
||||||
<object id="21" x="768" y="960.667">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 -18,0.666667 -18.6667,95.3333 0,95.3333"/>
|
|
||||||
</object>
|
|
||||||
<object id="23" x="786" y="1058.67">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 0,-52.6667 -20,-52 -19.3333,-1.33333"/>
|
|
||||||
</object>
|
|
||||||
<object id="24" x="1118.67" y="749.333">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 -0.666667,-94 -254,-93.3333 -256.667,1.33333"/>
|
|
||||||
</object>
|
|
||||||
<object id="25" x="1168" y="975.333">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 0,16.6667 224.667,17.3333 225.333,-2"/>
|
|
||||||
</object>
|
|
||||||
<object id="28" x="1394.67" y="958">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 -210.667,1.33333 -210.667,17.3333 -2,18"/>
|
|
||||||
</object>
|
|
||||||
<object id="29" x="1119" y="654.5">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 0,63.5 272.5,65 273,-1"/>
|
|
||||||
</object>
|
|
||||||
<object id="30" x="1136.5" y="717.5">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 -0.5,17 255,17.5 255,1.5"/>
|
|
||||||
</object>
|
|
||||||
<object id="31" x="1152" y="735.667">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 0,15 80.3333,15.3333 80.3333,-2"/>
|
|
||||||
</object>
|
|
||||||
<object id="32" x="1280.67" y="734.667">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 -0.666667,64.3333 48,65 48,0"/>
|
|
||||||
</object>
|
|
||||||
<object id="34" x="1329" y="783">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 63.3333,0.333333 63,-48.3333 -0.666667,-48.3333"/>
|
|
||||||
</object>
|
|
||||||
<object id="35" x="1296.67" y="799">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 -0.666667,31.3333 31.3333,31.6667 31.3333,-0.333333"/>
|
|
||||||
</object>
|
|
||||||
<object id="36" x="1280" y="848">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 0.333333,62 112,63 111.667,-1.33333"/>
|
|
||||||
</object>
|
|
||||||
<object id="37" x="1392.33" y="911.333">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 -81.3333,-0.666667 -81,45 -0.666667,46.3333"/>
|
|
||||||
</object>
|
|
||||||
<object id="38" x="1344.33" y="800.667">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 0,46.3333 47,46.3333 47,-1"/>
|
|
||||||
</object>
|
|
||||||
<object id="46" x="1200" y="1406.67">
|
|
||||||
<properties>
|
|
||||||
<property name="boundary_type" value="barrier"/>
|
|
||||||
</properties>
|
|
||||||
<polyline points="0,0 -97.3334,0 -97,17.3333 0,16.6667"/>
|
|
||||||
</object>
|
|
||||||
<object id="54" x="656" y="1503.5" width="80.5" height="15.5">
|
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
@ -174,52 +30,52 @@
|
|||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="57" x="768" y="1470.5" width="32.5" height="16.5">
|
<object id="57" x="768" y="1472" width="32" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="58" x="1039.5" y="1536" width="80" height="16">
|
<object id="58" x="1040" y="1536" width="80" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="59" x="1039.75" y="1568" width="224.25" height="47.75">
|
<object id="59" x="1040" y="1568" width="224" height="48">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="60" x="1216" y="1342.5" width="224.5" height="17.5">
|
<object id="60" x="1216" y="1344" width="224" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="62" x="1040.13" y="1552.5" width="208" height="15.5">
|
<object id="62" x="1040" y="1552" width="208" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="63" x="1040.25" y="1503" width="47.75" height="16">
|
<object id="63" x="1040" y="1504" width="48" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="64" x="1051.25" y="1518.75" width="52.75" height="16">
|
<object id="64" x="1040" y="1520" width="64" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="65" x="1040.63" y="1487.25" width="31.5" height="14.75">
|
<object id="65" x="1040" y="1488" width="32" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="66" x="1040" y="1472.13" width="16" height="14.75">
|
<object id="66" x="1040" y="1472" width="16" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="67" x="784.167" y="1456.17" width="256" height="14.6667">
|
<object id="67" x="784" y="1456" width="256" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
@ -234,22 +90,42 @@
|
|||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="79" x="624.25" y="1616" width="1094.75" height="17.25">
|
<object id="79" x="640" y="1616" width="1056" height="16">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
</object>
|
</object>
|
||||||
<object id="80" x="1296.5" y="1600.25">
|
<object id="80" x="1296" y="1600">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
<polyline points="0,0 -32.5,0 -32.25,-16.5 -16.5,-16.5"/>
|
<polyline points="0,0 -32.5,0 -32.25,-16.5 -16.5,-16.5"/>
|
||||||
</object>
|
</object>
|
||||||
<object id="82" x="1328.5" y="1616">
|
<object id="82" x="1328" y="1616">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="boundary_type" value="barrier"/>
|
<property name="boundary_type" value="barrier"/>
|
||||||
</properties>
|
</properties>
|
||||||
<polyline points="0,0 -64.5,0 -64.0038,-15.75 -16.4734,-15.75"/>
|
<polyline points="0,0 -64.5,0 -64.0038,-15.75 -16.4734,-15.75"/>
|
||||||
</object>
|
</object>
|
||||||
|
<object id="83" x="640" y="480" width="1056" height="16">
|
||||||
|
<properties>
|
||||||
|
<property name="boundary_type" value="barrier"/>
|
||||||
|
</properties>
|
||||||
|
</object>
|
||||||
|
<object id="84" x="640" y="480" width="16" height="1152">
|
||||||
|
<properties>
|
||||||
|
<property name="boundary_type" value="barrier"/>
|
||||||
|
</properties>
|
||||||
|
</object>
|
||||||
|
<object id="85" x="1680" y="480" width="16" height="1152">
|
||||||
|
<properties>
|
||||||
|
<property name="boundary_type" value="barrier"/>
|
||||||
|
</properties>
|
||||||
|
</object>
|
||||||
|
<object id="86" x="1104" y="1408" width="96" height="16">
|
||||||
|
<properties>
|
||||||
|
<property name="boundary_type" value="barrier"/>
|
||||||
|
</properties>
|
||||||
|
</object>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
@ -97,7 +97,7 @@
|
|||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
"_children": [],
|
"_children": [],
|
||||||
"_active": false,
|
"_active": true,
|
||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 3
|
"__id__": 3
|
||||||
@ -129,7 +129,7 @@
|
|||||||
"ctor": "Float64Array",
|
"ctor": "Float64Array",
|
||||||
"array": [
|
"array": [
|
||||||
0,
|
0,
|
||||||
20,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -440,7 +440,7 @@
|
|||||||
"array": [
|
"array": [
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
216.19964242526865,
|
209.7905580006813,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -454,7 +454,7 @@
|
|||||||
"array": [
|
"array": [
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
215.64032554232523,
|
209.7905580006813,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -786,11 +786,11 @@ cc.Class({
|
|||||||
playerScriptIns.mapNode = self.node;
|
playerScriptIns.mapNode = self.node;
|
||||||
const colliderWidth = playerDownsyncInfo.colliderRadius * 2,
|
const colliderWidth = playerDownsyncInfo.colliderRadius * 2,
|
||||||
colliderHeight = playerDownsyncInfo.colliderRadius * 4;
|
colliderHeight = playerDownsyncInfo.colliderRadius * 4;
|
||||||
const [x0, y0] = self.virtualGridToPolygonColliderAnchorPos(vx, vy, colliderWidth, colliderHeight),
|
const cpos = self.virtualGridToPolygonColliderTLPos(vx, vy, colliderWidth*0.5, colliderHeight*0.5); // the top-left corner is kept having integer coords
|
||||||
pts = [[0, 0], [colliderWidth, 0], [colliderWidth, colliderHeight], [0, colliderHeight]];
|
const pts = [[0, 0], [colliderWidth, 0], [colliderWidth, -colliderHeight-self.snapIntoPlatformOverlap], [0, -colliderHeight-self.snapIntoPlatformOverlap]];
|
||||||
|
|
||||||
// [WARNING] The animNode "anchor & offset" are tuned to fit in this collider by "ControlledCharacter prefab & AttackingCharacter.js"!
|
// [WARNING] The animNode "anchor & offset" are tuned to fit in this collider by "ControlledCharacter prefab & AttackingCharacter.js"!
|
||||||
const newPlayerCollider = self.collisionSys.createPolygon(x0, y0, pts);
|
const newPlayerCollider = self.collisionSys.createPolygon(cpos[0], cpos[1], pts);
|
||||||
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||||
newPlayerCollider.data = playerDownsyncInfo;
|
newPlayerCollider.data = playerDownsyncInfo;
|
||||||
self.collisionSysMap.set(collisionPlayerIndex, newPlayerCollider);
|
self.collisionSysMap.set(collisionPlayerIndex, newPlayerCollider);
|
||||||
@ -1048,8 +1048,8 @@ cc.Class({
|
|||||||
const [offenderWx, offenderWy] = self.virtualGridToWorldPos(offender.virtualGridX, offender.virtualGridY);
|
const [offenderWx, offenderWy] = self.virtualGridToWorldPos(offender.virtualGridX, offender.virtualGridY);
|
||||||
const bulletWx = offenderWx + xfac * meleeBullet.hitboxOffset;
|
const bulletWx = offenderWx + xfac * meleeBullet.hitboxOffset;
|
||||||
const bulletWy = offenderWy + 0.5 * meleeBullet.hitboxSize.y;
|
const bulletWy = offenderWy + 0.5 * meleeBullet.hitboxSize.y;
|
||||||
const [bulletCx, bulletCy] = self.worldToPolygonColliderAnchorPos(bulletWx, bulletWy, meleeBullet.hitboxSize.x * 0.5, meleeBullet.hitboxSize.y * 0.5),
|
const [bulletCx, bulletCy] = self.worldToPolygonColliderTLPos(bulletWx, bulletWy, meleeBullet.hitboxSize.x * 0.5, meleeBullet.hitboxSize.y * 0.5);
|
||||||
pts = [[0, 0], [meleeBullet.hitboxSize.x, 0], [meleeBullet.hitboxSize.x, meleeBullet.hitboxSize.y], [0, meleeBullet.hitboxSize.y]];
|
const pts = [[0, 0], [meleeBullet.hitboxSize.x, 0], [meleeBullet.hitboxSize.x, -meleeBullet.hitboxSize.y], [0, -meleeBullet.hitboxSize.y]];
|
||||||
|
|
||||||
g.moveTo(bulletCx, bulletCy);
|
g.moveTo(bulletCx, bulletCy);
|
||||||
for (let j = 0; j < pts.length; j += 1) {
|
for (let j = 0; j < pts.length; j += 1) {
|
||||||
@ -1118,7 +1118,8 @@ cc.Class({
|
|||||||
const joinIndex = parseInt(j) + 1;
|
const joinIndex = parseInt(j) + 1;
|
||||||
const playerRichInfo = self.playerRichInfoArr[j];
|
const playerRichInfo = self.playerRichInfoArr[j];
|
||||||
const playerId = playerRichInfo.id;
|
const playerId = playerRichInfo.id;
|
||||||
const [currPlayerDownsync, thatPlayerInNextFrame] = [currRenderFrame.players[playerId], nextRenderFramePlayers[playerId]];
|
const currPlayerDownsync = currRenderFrame.players[playerId];
|
||||||
|
const thatPlayerInNextFrame = nextRenderFramePlayers[playerId];
|
||||||
if (0 < thatPlayerInNextFrame.framesToRecover) {
|
if (0 < thatPlayerInNextFrame.framesToRecover) {
|
||||||
// No need to process inputs for this player, but there might be bullet pushbacks on this player
|
// No need to process inputs for this player, but there might be bullet pushbacks on this player
|
||||||
continue;
|
continue;
|
||||||
@ -1184,11 +1185,15 @@ cc.Class({
|
|||||||
const playerId = playerRichInfo.id;
|
const playerId = playerRichInfo.id;
|
||||||
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||||
const playerCollider = collisionSysMap.get(collisionPlayerIndex);
|
const playerCollider = collisionSysMap.get(collisionPlayerIndex);
|
||||||
const [currPlayerDownsync, thatPlayerInNextFrame] = [currRenderFrame.players[playerId], nextRenderFramePlayers[playerId]];
|
const currPlayerDownsync = currRenderFrame.players[playerId];
|
||||||
|
const thatPlayerInNextFrame = nextRenderFramePlayers[playerId];
|
||||||
// Reset playerCollider position from the "virtual grid position"
|
// Reset playerCollider position from the "virtual grid position"
|
||||||
const [newVx, newVy] = [currPlayerDownsync.virtualGridX + currPlayerDownsync.velX, currPlayerDownsync.virtualGridY + currPlayerDownsync.velY];
|
const [newVx, newVy] = [currPlayerDownsync.virtualGridX + currPlayerDownsync.velX, currPlayerDownsync.virtualGridY + currPlayerDownsync.velY];
|
||||||
[playerCollider.x, playerCollider.y] = self.virtualGridToPolygonColliderAnchorPos(newVx, newVy, self.playerRichInfoArr[joinIndex - 1].colliderRadius, self.playerRichInfoArr[joinIndex - 1].colliderRadius);
|
const colliderWidth = self.playerRichInfoArr[joinIndex - 1].colliderRadius * 2,
|
||||||
|
colliderHeight = self.playerRichInfoArr[joinIndex - 1].colliderRadius * 4;
|
||||||
|
const newCpos = self.virtualGridToPolygonColliderTLPos(newVx, newVy, colliderWidth*0.5, colliderHeight*0.5);
|
||||||
|
playerCollider.x = newCpos[0];
|
||||||
|
playerCollider.y = newCpos[1];
|
||||||
|
|
||||||
if (currPlayerDownsync.inAir) {
|
if (currPlayerDownsync.inAir) {
|
||||||
thatPlayerInNextFrame.velX += self.gravityX;
|
thatPlayerInNextFrame.velX += self.gravityX;
|
||||||
@ -1218,8 +1223,8 @@ cc.Class({
|
|||||||
const [offenderWx, offenderWy] = self.virtualGridToWorldPos(offender.virtualGridX, offender.virtualGridY);
|
const [offenderWx, offenderWy] = self.virtualGridToWorldPos(offender.virtualGridX, offender.virtualGridY);
|
||||||
const bulletWx = offenderWx + xfac * meleeBullet.hitboxOffset;
|
const bulletWx = offenderWx + xfac * meleeBullet.hitboxOffset;
|
||||||
const bulletWy = offenderWy + 0.5 * meleeBullet.hitboxSize.y;
|
const bulletWy = offenderWy + 0.5 * meleeBullet.hitboxSize.y;
|
||||||
const [bulletCx, bulletCy] = self.worldToPolygonColliderAnchorPos(bulletWx, bulletWy, meleeBullet.hitboxSize.x * 0.5, meleeBullet.hitboxSize.y * 0.5),
|
const [bulletCx, bulletCy] = self.worldToPolygonColliderTLPos(bulletWx, bulletWy, meleeBullet.hitboxSize.x * 0.5, meleeBullet.hitboxSize.y * 0.5),
|
||||||
pts = [[0, 0], [meleeBullet.hitboxSize.x, 0], [meleeBullet.hitboxSize.x, meleeBullet.hitboxSize.y], [0, meleeBullet.hitboxSize.y]];
|
pts = [[0, 0], [meleeBullet.hitboxSize.x, 0], [meleeBullet.hitboxSize.x, -meleeBullet.hitboxSize.y], [0, -meleeBullet.hitboxSize.y]];
|
||||||
const newBulletCollider = collisionSys.createPolygon(bulletCx, bulletCy, pts);
|
const newBulletCollider = collisionSys.createPolygon(bulletCx, bulletCy, pts);
|
||||||
newBulletCollider.data = meleeBullet;
|
newBulletCollider.data = meleeBullet;
|
||||||
collisionSysMap.set(collisionBulletIndex, newBulletCollider);
|
collisionSysMap.set(collisionBulletIndex, newBulletCollider);
|
||||||
@ -1241,7 +1246,8 @@ cc.Class({
|
|||||||
const potentials = playerCollider.potentials();
|
const potentials = playerCollider.potentials();
|
||||||
hardPushbackNorms[joinIndex - 1] = self.calcHardPushbacksNorms(playerCollider, potentials, result, self.snapIntoPlatformOverlap, effPushbacks[joinIndex - 1]);
|
hardPushbackNorms[joinIndex - 1] = self.calcHardPushbacksNorms(playerCollider, potentials, result, self.snapIntoPlatformOverlap, effPushbacks[joinIndex - 1]);
|
||||||
|
|
||||||
const [currPlayerDownsync, thatPlayerInNextFrame] = [currRenderFrame.players[playerId], nextRenderFramePlayers[playerId]];
|
const currPlayerDownsync = currRenderFrame.players[playerId];
|
||||||
|
const thatPlayerInNextFrame = nextRenderFramePlayers[playerId];
|
||||||
let fallStopping = false;
|
let fallStopping = false;
|
||||||
let possiblyFallStoppedOnAnotherPlayer = false;
|
let possiblyFallStoppedOnAnotherPlayer = false;
|
||||||
for (const potential of potentials) {
|
for (const potential of potentials) {
|
||||||
@ -1370,8 +1376,13 @@ cc.Class({
|
|||||||
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
const collisionPlayerIndex = self.collisionPlayerIndexPrefix + joinIndex;
|
||||||
const playerCollider = collisionSysMap.get(collisionPlayerIndex);
|
const playerCollider = collisionSysMap.get(collisionPlayerIndex);
|
||||||
// Update "virtual grid position"
|
// Update "virtual grid position"
|
||||||
const [currPlayerDownsync, thatPlayerInNextFrame] = [currRenderFrame.players[playerId], nextRenderFramePlayers[playerId]];
|
const currPlayerDownsync = currRenderFrame.players[playerId];
|
||||||
[thatPlayerInNextFrame.virtualGridX, thatPlayerInNextFrame.virtualGridY] = self.polygonColliderAnchorToVirtualGridPos(playerCollider.x - effPushbacks[joinIndex - 1][0], playerCollider.y - effPushbacks[joinIndex - 1][1], self.playerRichInfoArr[j].colliderRadius, self.playerRichInfoArr[j].colliderRadius);
|
const thatPlayerInNextFrame = nextRenderFramePlayers[playerId];
|
||||||
|
const colliderWidth = self.playerRichInfoArr[joinIndex - 1].colliderRadius * 2,
|
||||||
|
colliderHeight = self.playerRichInfoArr[joinIndex - 1].colliderRadius * 4;
|
||||||
|
const newVpos = self.polygonColliderTLToVirtualGridPos(playerCollider.x - effPushbacks[joinIndex - 1][0], playerCollider.y - effPushbacks[joinIndex - 1][1], colliderWidth*0.5, colliderHeight*0.5);
|
||||||
|
thatPlayerInNextFrame.virtualGridX = newVpos[0];
|
||||||
|
thatPlayerInNextFrame.virtualGridY = newVpos[1];
|
||||||
|
|
||||||
if (1 == thatPlayerInNextFrame.joinIndex) {
|
if (1 == thatPlayerInNextFrame.joinIndex) {
|
||||||
if (thatPlayerInNextFrame.inAir && 0 != thatPlayerInNextFrame.velY) {
|
if (thatPlayerInNextFrame.inAir && 0 != thatPlayerInNextFrame.velY) {
|
||||||
@ -1507,24 +1518,24 @@ cc.Class({
|
|||||||
return [wx, wy];
|
return [wx, wy];
|
||||||
},
|
},
|
||||||
|
|
||||||
worldToPolygonColliderAnchorPos(wx, wy, halfBoundingW, halfBoundingH) {
|
worldToPolygonColliderTLPos(wx, wy, halfBoundingW, halfBoundingH) {
|
||||||
return [wx - halfBoundingW, wy - halfBoundingH];
|
return [wx - halfBoundingW, wy + halfBoundingH];
|
||||||
},
|
},
|
||||||
|
|
||||||
polygonColliderAnchorToWorldPos(cx, cy, halfBoundingW, halfBoundingH) {
|
polygonColliderTLToWorldPos(cx, cy, halfBoundingW, halfBoundingH) {
|
||||||
return [cx + halfBoundingW, cy + halfBoundingH];
|
return [cx + halfBoundingW, cy - halfBoundingH];
|
||||||
},
|
},
|
||||||
|
|
||||||
polygonColliderAnchorToVirtualGridPos(cx, cy, halfBoundingW, halfBoundingH) {
|
polygonColliderTLToVirtualGridPos(cx, cy, halfBoundingW, halfBoundingH) {
|
||||||
const self = this;
|
const self = this;
|
||||||
const [wx, wy] = self.polygonColliderAnchorToWorldPos(cx, cy, halfBoundingW, halfBoundingH);
|
const [wx, wy] = self.polygonColliderTLToWorldPos(cx, cy, halfBoundingW, halfBoundingH);
|
||||||
return self.worldToVirtualGridPos(wx, wy)
|
return self.worldToVirtualGridPos(wx, wy)
|
||||||
},
|
},
|
||||||
|
|
||||||
virtualGridToPolygonColliderAnchorPos(vx, vy, halfBoundingW, halfBoundingH) {
|
virtualGridToPolygonColliderTLPos(vx, vy, halfBoundingW, halfBoundingH) {
|
||||||
const self = this;
|
const self = this;
|
||||||
const [wx, wy] = self.virtualGridToWorldPos(vx, vy);
|
const [wx, wy] = self.virtualGridToWorldPos(vx, vy);
|
||||||
return self.worldToPolygonColliderAnchorPos(wx, wy, halfBoundingW, halfBoundingH)
|
return self.worldToPolygonColliderTLPos(wx, wy, halfBoundingW, halfBoundingH)
|
||||||
},
|
},
|
||||||
|
|
||||||
calcHardPushbacksNorms(collider, potentials, result, snapIntoPlatformOverlap, effPushback) {
|
calcHardPushbacksNorms(collider, potentials, result, snapIntoPlatformOverlap, effPushback) {
|
||||||
|
@ -75,10 +75,10 @@ cc.Class({
|
|||||||
|
|
||||||
Moreover, "snapIntoPlatformOverlap" should be small enough such that the walking "velX" or jumping initial "velY" can escape from it by 1 renderFrame (when jumping is triggered, the character is waived from snappig for 1 renderFrame).
|
Moreover, "snapIntoPlatformOverlap" should be small enough such that the walking "velX" or jumping initial "velY" can escape from it by 1 renderFrame (when jumping is triggered, the character is waived from snappig for 1 renderFrame).
|
||||||
*/
|
*/
|
||||||
self.snapIntoPlatformOverlap = 0.01;
|
self.snapIntoPlatformOverlap = 0.1;
|
||||||
self.snapIntoPlatformThreshold = 0.5; // a platform must be "horizontal enough" for a character to "stand on"
|
self.snapIntoPlatformThreshold = 0.5; // a platform must be "horizontal enough" for a character to "stand on"
|
||||||
self.jumpingInitVelY = 6 * self.worldToVirtualGridRatio; // unit: (virtual grid length/renderFrame)
|
self.jumpingInitVelY = 7 * self.worldToVirtualGridRatio; // unit: (virtual grid length/renderFrame)
|
||||||
[self.gravityX, self.gravityY] = [0, -Math.ceil(4 * self.jumpingInitVelY / self.serverFps)]; // unit: (virtual grid length/renderFrame^2)
|
[self.gravityX, self.gravityY] = [0, -0.5*self.worldToVirtualGridRatio]; // unit: (virtual grid length/renderFrame^2)
|
||||||
|
|
||||||
const tiledMapIns = self.node.getComponent(cc.TiledMap);
|
const tiledMapIns = self.node.getComponent(cc.TiledMap);
|
||||||
|
|
||||||
@ -196,7 +196,7 @@ cc.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.selfPlayerInfo = {
|
self.selfPlayerInfo = {
|
||||||
id: 11
|
id: 10
|
||||||
};
|
};
|
||||||
self._initPlayerRichInfoDict(startRdf.players);
|
self._initPlayerRichInfoDict(startRdf.players);
|
||||||
self.onRoomDownsyncFrame(startRdf);
|
self.onRoomDownsyncFrame(startRdf);
|
||||||
|
Loading…
Reference in New Issue
Block a user