diff --git a/battle_srv/api/req_logger.go b/battle_srv/api/req_logger.go
index 517bace..e87b2cb 100644
--- a/battle_srv/api/req_logger.go
+++ b/battle_srv/api/req_logger.go
@@ -2,10 +2,10 @@ package api
import (
"bytes"
+ . "dnmshared"
"github.com/gin-gonic/gin"
"io"
"io/ioutil"
- . "server/common"
)
func RequestLogger() gin.HandlerFunc {
diff --git a/battle_srv/api/v1/player.go b/battle_srv/api/v1/player.go
index 9089c9f..2636826 100644
--- a/battle_srv/api/v1/player.go
+++ b/battle_srv/api/v1/player.go
@@ -16,6 +16,8 @@ import (
"server/models"
"server/storage"
"strconv"
+
+ . "dnmshared"
)
var Player = playerController{}
diff --git a/battle_srv/common/conf.go b/battle_srv/common/conf.go
index 55c4bef..41b06a2 100644
--- a/battle_srv/common/conf.go
+++ b/battle_srv/common/conf.go
@@ -1,16 +1,15 @@
package common
import (
+ . "dnmshared"
"encoding/json"
"fmt"
+ "go.uber.org/zap"
"os"
"path/filepath"
"strings"
-
- "go.uber.org/zap"
)
-// 隐式导入
var Conf *config
const (
@@ -72,11 +71,15 @@ func MustParseConfig() {
BotServer: new(botServerConf),
}
execPath, err := os.Executable()
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
pwd, err := os.Getwd()
Logger.Debug("os.GetWd", zap.String("pwd", pwd))
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
appRoot := pwd
confDir := filepath.Join(appRoot, "configs")
@@ -129,22 +132,21 @@ func loadJSON(fp string, v interface{}) {
fp = filepath.Join(Conf.General.ConfDir, fp)
}
_, err := os.Stat(fp)
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
fd, err := os.Open(fp)
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
defer fd.Close()
Logger.Info("Opened json file successfully.", zap.String("fp", fp))
err = json.NewDecoder(fd).Decode(v)
- ErrFatal(err)
- Logger.Info("Loaded json file successfully.", zap.String("fp", fp))
-}
-
-// Please only use this auxiliary function before server is fully started up, but not afterwards (启动过程可以使用,运行时不准使用).
-func ErrFatal(err error) {
- if err != nil {
- Logger.Fatal("ErrFatal", zap.NamedError("err", err))
+ if nil != err {
+ panic(err)
}
+ Logger.Info("Loaded json file successfully.", zap.String("fp", fp))
}
func isNotExist(p string) bool {
diff --git a/battle_srv/common/constants_loader.go b/battle_srv/common/constants_loader.go
index 3524cd8..c483323 100644
--- a/battle_srv/common/constants_loader.go
+++ b/battle_srv/common/constants_loader.go
@@ -5,9 +5,10 @@ import (
"github.com/imdario/mergo"
"go.uber.org/zap"
+
+ . "dnmshared"
)
-// 隐式导入
var Constants *constants
func MustParseConstants() {
@@ -24,13 +25,11 @@ func MustParseConstants() {
if !isNotExist(fp) {
testConstants := new(constants)
loadJSON(fp, testConstants)
- //Logger.Debug(spew.Sdump(Constants))
- //Logger.Debug(spew.Sdump(testConstants))
err := mergo.Merge(testConstants, Constants)
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
Constants = testConstants
- //Logger.Debug("mergo.Merge", zap.Error(err))
- //Logger.Debug(spew.Sdump(testConstants))
}
}
constantsPost()
diff --git a/battle_srv/common/utils/wechat.go b/battle_srv/common/utils/wechat.go
index b77f5ab..fc72524 100644
--- a/battle_srv/common/utils/wechat.go
+++ b/battle_srv/common/utils/wechat.go
@@ -3,6 +3,7 @@ package utils
import (
"bytes"
"crypto/sha1"
+ . "dnmshared"
"encoding/json"
"fmt"
"go.uber.org/zap"
diff --git a/battle_srv/common/vals.go b/battle_srv/common/vals.go
index 55f0b39..4d4061d 100644
--- a/battle_srv/common/vals.go
+++ b/battle_srv/common/vals.go
@@ -11,7 +11,6 @@ var (
RE_CHINA_PHONE_NUM = regexp.MustCompile(`^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$`)
)
-// 隐式导入
var ConstVals = &struct {
Player struct {
CaptchaExpire time.Duration
diff --git a/battle_srv/env_tools/load_pre_conf.go b/battle_srv/env_tools/load_pre_conf.go
index 55c6a97..f64b0a0 100644
--- a/battle_srv/env_tools/load_pre_conf.go
+++ b/battle_srv/env_tools/load_pre_conf.go
@@ -1,6 +1,7 @@
package env_tools
import (
+ . "dnmshared"
sq "github.com/Masterminds/squirrel"
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3"
@@ -15,7 +16,9 @@ func LoadPreConf() {
Logger.Info(`Merging PreConfSQLite data into MySQL`,
zap.String("PreConfSQLitePath", Conf.General.PreConfSQLitePath))
db, err := sqlx.Connect("sqlite3", Conf.General.PreConfSQLitePath)
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
defer db.Close()
loadPreConfToMysql(db)
@@ -39,7 +42,9 @@ func loadPreConfToMysql(db *sqlx.DB) {
func loadSqlite(db *sqlx.DB, tbs []string) {
for _, v := range tbs {
result, err := storage.MySQLManagerIns.Exec("truncate " + v)
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
Logger.Info("truncate", zap.Any("truncate "+v, result))
query, args, err := sq.Select("*").From(v).ToSql()
if err != nil {
@@ -70,19 +75,25 @@ func createMysqlData(rows *sqlx.Rows, v string) {
func maybeCreateNewPlayerFromBotTable(db *sqlx.DB, tableName string) {
var ls []*dbBotPlayer
err := db.Select(&ls, "SELECT name, magic_phone_country_code, magic_phone_num, display_name FROM "+tableName)
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
names := make([]string, len(ls), len(ls))
for i, v := range ls {
names[i] = v.Name
}
sql := "SELECT name FROM `player` WHERE name in (?)"
query, args, err := sqlx.In(sql, names)
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
query = storage.MySQLManagerIns.Rebind(query)
// existNames := make([]string, len(ls), len(ls))
var existPlayers []*models.Player
err = storage.MySQLManagerIns.Select(&existPlayers, query, args...)
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
for _, botPlayer := range ls {
var flag bool
diff --git a/battle_srv/env_tools/test_env_db.go b/battle_srv/env_tools/test_env_db.go
index c6afec7..df1bcaf 100644
--- a/battle_srv/env_tools/test_env_db.go
+++ b/battle_srv/env_tools/test_env_db.go
@@ -1,6 +1,7 @@
package env_tools
import (
+ . "dnmshared"
. "server/common"
"server/common/utils"
"server/models"
@@ -15,7 +16,9 @@ func MergeTestPlayerAccounts() {
fp := Conf.General.TestEnvSQLitePath
Logger.Info(`Initializing TestPlayerAccounts in runtime MySQLServer from SQLite file:`, zap.String("fp", fp))
db, err := sqlx.Connect("sqlite3", fp)
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
defer db.Close()
maybeCreateNewPlayer(db, "test_player")
}
@@ -29,31 +32,35 @@ type dbTestPlayer struct {
func maybeCreateNewPlayer(db *sqlx.DB, tableName string) {
var ls []*dbTestPlayer
err := db.Select(&ls, "SELECT name, magic_phone_country_code, magic_phone_num FROM "+tableName)
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
names := make([]string, len(ls), len(ls))
for i, v := range ls {
names[i] = v.Name
}
sql := "SELECT name FROM `player` WHERE name in (?)"
query, args, err := sqlx.In(sql, names)
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
query = storage.MySQLManagerIns.Rebind(query)
// existNames := make([]string, len(ls), len(ls))
var existPlayers []*models.Player
err = storage.MySQLManagerIns.Select(&existPlayers, query, args...)
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
for _, testPlayer := range ls {
var flag bool
for _, v := range existPlayers {
if testPlayer.Name == v.Name {
- // 已有数据,合并处理
flag = true
break
}
}
if !flag {
- // 找不到,新增
Logger.Debug("create", zap.Any(tableName, testPlayer))
err := createNewPlayer(testPlayer)
if err != nil {
diff --git a/battle_srv/go.mod b/battle_srv/go.mod
index 816c005..9bcd700 100644
--- a/battle_srv/go.mod
+++ b/battle_srv/go.mod
@@ -3,7 +3,6 @@ module server
go 1.19
require (
- github.com/ByteArena/box2d v1.0.2
github.com/Masterminds/squirrel v0.0.0-20180815162352-8a7e65843414
github.com/davecgh/go-spew v1.1.1
github.com/gin-contrib/cors v0.0.0-20180514151808-6f0a820f94be
@@ -21,6 +20,8 @@ require (
github.com/thoas/go-funk v0.0.0-20180716193722-1060394a7713
go.uber.org/zap v1.9.1
google.golang.org/protobuf v1.28.1
+
+ dnmshared v0.0.0
)
require (
@@ -44,3 +45,7 @@ require (
gopkg.in/go-playground/validator.v8 v8.18.2 // indirect
gopkg.in/yaml.v2 v2.2.1 // indirect
)
+
+replace (
+ dnmshared => ../dnmshared
+)
diff --git a/battle_srv/main.go b/battle_srv/main.go
index ce2aacf..81e4348 100644
--- a/battle_srv/main.go
+++ b/battle_srv/main.go
@@ -10,8 +10,6 @@ import (
"server/api"
"server/api/v1"
. "server/common"
- "server/common/utils"
- "server/configs"
"server/env_tools"
"server/models"
"server/storage"
@@ -19,6 +17,8 @@ import (
"syscall"
"time"
+ . "dnmshared"
+
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/robfig/cron"
@@ -30,8 +30,6 @@ func main() {
MustParseConstants()
storage.Init()
env_tools.LoadPreConf()
- utils.InitWechat(configs.WechatConfigIns)
- utils.InitWechatGame(configs.WechatGameConfigIns)
if Conf.General.ServerEnv == SERVER_ENV_TEST {
env_tools.MergeTestPlayerAccounts()
}
diff --git a/battle_srv/models/barrier.go b/battle_srv/models/barrier.go
index cb3db06..7df588e 100644
--- a/battle_srv/models/barrier.go
+++ b/battle_srv/models/barrier.go
@@ -1,5 +1,9 @@
package models
+import (
+ . "dnmshared"
+)
+
type Barrier struct {
Boundary *Polygon2D
}
diff --git a/battle_srv/models/math.go b/battle_srv/models/math.go
deleted file mode 100644
index 37e8f5b..0000000
--- a/battle_srv/models/math.go
+++ /dev/null
@@ -1,132 +0,0 @@
-package models
-
-import (
- "fmt"
- "github.com/ByteArena/box2d"
- "math"
-)
-
-// Use type `float64` for json unmarshalling of numbers.
-type Direction struct {
- Dx int32 `json:"dx,omitempty"`
- Dy int32 `json:"dy,omitempty"`
-}
-
-type Vec2D struct {
- X float64 `json:"x,omitempty"`
- Y float64 `json:"y,omitempty"`
-}
-
-func CreateVec2DFromB2Vec2(b2V2 box2d.B2Vec2) *Vec2D {
- return &Vec2D{
- X: b2V2.X,
- Y: b2V2.Y,
- }
-}
-
-func (v2 *Vec2D) ToB2Vec2() box2d.B2Vec2 {
- return box2d.MakeB2Vec2(v2.X, v2.Y)
-}
-
-type Polygon2D struct {
- Anchor *Vec2D `json:"-"` // This "Polygon2D.Anchor" is used to be assigned to "B2BodyDef.Position", which in turn is used as the position of the FIRST POINT of the polygon.
- Points []*Vec2D `json:"-"`
-
- /*
- When used to represent a "polyline directly drawn in a `Tmx file`", we can initialize both "Anchor" and "Points" simultaneously.
-
- Yet when used to represent a "polyline drawn in a `Tsx file`", we have to first initialize "Points w.r.t. center of the tile-rectangle", and then "Anchor(initially nil) of the tile positioned in the `Tmx file`".
-
- Refer to https://shimo.im/docs/SmLJJhXm2C8XMzZT for more information.
- */
-
- /*
- [WARNING] Used to cache "`TileWidth & TileHeight` of a Tsx file" only.
- */
- TileWidth int
- TileHeight int
-
- /*
- [WARNING] Used to cache "`Width & TileHeight` of an object in Tmx file" only.
- */
- TmxObjectWidth float64
- TmxObjectHeight float64
-}
-
-func MoveDynamicBody(body *box2d.B2Body, pToTargetPos *box2d.B2Vec2, inSeconds float64) {
- if body.GetType() != box2d.B2BodyType.B2_dynamicBody {
- return
- }
- body.SetTransform(*pToTargetPos, 0.0)
- body.SetLinearVelocity(box2d.MakeB2Vec2(0.0, 0.0))
- body.SetAngularVelocity(0.0)
-}
-
-func PrettyPrintFixture(fix *box2d.B2Fixture) {
- fmt.Printf("\t\tfriction:\t%v\n", fix.M_friction)
- fmt.Printf("\t\trestitution:\t%v\n", fix.M_restitution)
- fmt.Printf("\t\tdensity:\t%v\n", fix.M_density)
- fmt.Printf("\t\tisSensor:\t%v\n", fix.M_isSensor)
- fmt.Printf("\t\tfilter.categoryBits:\t%d\n", fix.M_filter.CategoryBits)
- fmt.Printf("\t\tfilter.maskBits:\t%d\n", fix.M_filter.MaskBits)
- fmt.Printf("\t\tfilter.groupIndex:\t%d\n", fix.M_filter.GroupIndex)
-
- switch fix.M_shape.GetType() {
- case box2d.B2Shape_Type.E_circle:
- {
- s := fix.M_shape.(*box2d.B2CircleShape)
- fmt.Printf("\t\tb2CircleShape shape: {\n")
- fmt.Printf("\t\t\tradius:\t%v\n", s.M_radius)
- fmt.Printf("\t\t\toffset:\t%v\n", s.M_p)
- fmt.Printf("\t\t}\n")
- }
- break
-
- case box2d.B2Shape_Type.E_polygon:
- {
- s := fix.M_shape.(*box2d.B2PolygonShape)
- fmt.Printf("\t\tb2PolygonShape shape: {\n")
- for i := 0; i < s.M_count; i++ {
- fmt.Printf("\t\t\t%v\n", s.M_vertices[i])
- }
- fmt.Printf("\t\t}\n")
- }
- break
-
- default:
- break
- }
-}
-
-func PrettyPrintBody(body *box2d.B2Body) {
- bodyIndex := body.M_islandIndex
-
- fmt.Printf("{\n")
- fmt.Printf("\tHeapRAM addr:\t%p\n", body)
- fmt.Printf("\ttype:\t%d\n", body.M_type)
- fmt.Printf("\tposition:\t%v\n", body.GetPosition())
- fmt.Printf("\tangle:\t%v\n", body.M_sweep.A)
- fmt.Printf("\tlinearVelocity:\t%v\n", body.GetLinearVelocity())
- fmt.Printf("\tangularVelocity:\t%v\n", body.GetAngularVelocity())
- fmt.Printf("\tlinearDamping:\t%v\n", body.M_linearDamping)
- fmt.Printf("\tangularDamping:\t%v\n", body.M_angularDamping)
- fmt.Printf("\tallowSleep:\t%d\n", body.M_flags&box2d.B2Body_Flags.E_autoSleepFlag)
- fmt.Printf("\tawake:\t%d\n", body.M_flags&box2d.B2Body_Flags.E_awakeFlag)
- fmt.Printf("\tfixedRotation:\t%d\n", body.M_flags&box2d.B2Body_Flags.E_fixedRotationFlag)
- fmt.Printf("\tbullet:\t%d\n", body.M_flags&box2d.B2Body_Flags.E_bulletFlag)
- fmt.Printf("\tactive:\t%d\n", body.M_flags&box2d.B2Body_Flags.E_activeFlag)
- fmt.Printf("\tgravityScale:\t%v\n", body.M_gravityScale)
- fmt.Printf("\tislandIndex:\t%v\n", bodyIndex)
- fmt.Printf("\tfixtures: {\n")
- for f := body.M_fixtureList; f != nil; f = f.M_next {
- PrettyPrintFixture(f)
- }
- fmt.Printf("\t}\n")
- fmt.Printf("}\n")
-}
-
-func Distance(pt1 *Vec2D, pt2 *Vec2D) float64 {
- dx := pt1.X - pt2.X
- dy := pt1.Y - pt2.Y
- return math.Sqrt(dx*dx + dy*dy)
-}
diff --git a/battle_srv/models/pb_type_convert.go b/battle_srv/models/pb_type_convert.go
index 562ff44..d460097 100644
--- a/battle_srv/models/pb_type_convert.go
+++ b/battle_srv/models/pb_type_convert.go
@@ -1,6 +1,7 @@
package models
import (
+ . "dnmshared"
pb "server/pb_output"
)
diff --git a/battle_srv/models/player.go b/battle_srv/models/player.go
index eb9424f..f2ce027 100644
--- a/battle_srv/models/player.go
+++ b/battle_srv/models/player.go
@@ -2,6 +2,7 @@ package models
import (
"database/sql"
+ . "dnmshared"
"fmt"
sq "github.com/Masterminds/squirrel"
"github.com/jmoiron/sqlx"
diff --git a/battle_srv/models/helper.go b/battle_srv/models/player_dao_helper.go
similarity index 99%
rename from battle_srv/models/helper.go
rename to battle_srv/models/player_dao_helper.go
index 5e51382..c09a257 100644
--- a/battle_srv/models/helper.go
+++ b/battle_srv/models/player_dao_helper.go
@@ -2,7 +2,7 @@ package models
import (
"database/sql"
- . "server/common"
+ . "dnmshared"
"server/storage"
sq "github.com/Masterminds/squirrel"
diff --git a/battle_srv/models/player_wallet.go b/battle_srv/models/player_wallet.go
index 23421f2..48c3425 100644
--- a/battle_srv/models/player_wallet.go
+++ b/battle_srv/models/player_wallet.go
@@ -2,6 +2,7 @@ package models
import (
"database/sql"
+ . "dnmshared"
"errors"
. "server/common"
"server/common/utils"
diff --git a/battle_srv/models/room.go b/battle_srv/models/room.go
index e10e0d4..5b0b0a6 100644
--- a/battle_srv/models/room.go
+++ b/battle_srv/models/room.go
@@ -1,17 +1,14 @@
package models
import (
- "encoding/xml"
+ . "dnmshared"
"fmt"
"github.com/golang/protobuf/proto"
"github.com/gorilla/websocket"
"github.com/solarlune/resolv"
"go.uber.org/zap"
- "io/ioutil"
"math"
"math/rand"
- "os"
- "path/filepath"
. "server/common"
"server/common/utils"
pb "server/pb_output"
@@ -19,6 +16,11 @@ import (
"sync"
"sync/atomic"
"time"
+
+ "encoding/xml"
+ "io/ioutil"
+ "os"
+ "path/filepath"
)
const (
@@ -261,10 +263,12 @@ func (pR *Room) ChooseStage() error {
* -- YFLu, 2019-09-04
*/
pwd, err := os.Getwd()
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
rand.Seed(time.Now().Unix())
- stageNameList := []string{ /*"pacman" ,*/ "richsoil"}
+ stageNameList := []string{ /*"simple" ,*/ "richsoil"}
chosenStageIndex := rand.Int() % len(stageNameList) // Hardcoded temporarily. -- YFLu
pR.StageName = stageNameList[chosenStageIndex]
@@ -324,7 +328,8 @@ func (pR *Room) ChooseStage() error {
barrierPolygon2DList := *(toRetStrToPolygon2DListMap["Barrier"])
var barrierLocalIdInBattle int32 = 0
- for _, polygon2D := range barrierPolygon2DList {
+ for _, polygon2DUnaligned := range barrierPolygon2DList {
+ polygon2D := AlignPolygon2DToBoundingBox(polygon2DUnaligned)
/*
// For debug-printing only.
Logger.Info("ChooseStage printing polygon2D for barrierPolygon2DList", zap.Any("barrierLocalIdInBattle", barrierLocalIdInBattle), zap.Any("polygon2D.Anchor", polygon2D.Anchor), zap.Any("polygon2D.Points", polygon2D.Points))
@@ -435,13 +440,13 @@ func (pR *Room) StartBattle() {
elapsedNanosSinceLastFrameIdTriggered := stCalculation - pR.LastRenderFrameIdTriggeredAt
if elapsedNanosSinceLastFrameIdTriggered < pR.RollbackEstimatedDtNanos {
Logger.Debug(fmt.Sprintf("Avoiding too fast frame@roomId=%v, renderFrameId=%v: elapsedNanosSinceLastFrameIdTriggered=%v", pR.Id, pR.RenderFrameId, elapsedNanosSinceLastFrameIdTriggered))
- continue
+ continue
}
if pR.RenderFrameId > pR.BattleDurationFrames {
Logger.Info(fmt.Sprintf("The `battleMainLoop` for roomId=%v is stopped@renderFrameId=%v, with battleDurationFrames=%v:\n%v", pR.Id, pR.RenderFrameId, pR.BattleDurationFrames, pR.InputsBufferString(true)))
pR.StopBattleForSettlement()
- return
+ return
}
if swapped := atomic.CompareAndSwapInt32(&pR.State, RoomBattleStateIns.IN_BATTLE, RoomBattleStateIns.IN_BATTLE); !swapped {
@@ -623,9 +628,9 @@ func (pR *Room) onInputFrameDownsyncAllConfirmed(inputFrameDownsync *pb.InputFra
inputFrameId := inputFrameDownsync.InputFrameId
if -1 == pR.LastAllConfirmedInputFrameIdWithChange || false == pR.equalInputLists(inputFrameDownsync.InputList, pR.LastAllConfirmedInputList) {
if -1 == playerId {
- Logger.Info(fmt.Sprintf("Key inputFrame change: roomId=%v, newInputFrameId=%v, lastInputFrameId=%v, newInputList=%v, lastInputList=%v, InputsBuffer=%v", pR.Id, inputFrameId, pR.LastAllConfirmedInputFrameId, inputFrameDownsync.InputList, pR.LastAllConfirmedInputList, pR.InputsBufferString(false)))
+ Logger.Debug(fmt.Sprintf("Key inputFrame change: roomId=%v, newInputFrameId=%v, lastInputFrameId=%v, newInputList=%v, lastInputList=%v, InputsBuffer=%v", pR.Id, inputFrameId, pR.LastAllConfirmedInputFrameId, inputFrameDownsync.InputList, pR.LastAllConfirmedInputList, pR.InputsBufferString(false)))
} else {
- Logger.Info(fmt.Sprintf("Key inputFrame change: roomId=%v, playerId=%v, newInputFrameId=%v, lastInputFrameId=%v, newInputList=%v, lastInputList=%v, InputsBuffer=%v", pR.Id, playerId, inputFrameId, pR.LastAllConfirmedInputFrameId, inputFrameDownsync.InputList, pR.LastAllConfirmedInputList, pR.InputsBufferString(false)))
+ Logger.Debug(fmt.Sprintf("Key inputFrame change: roomId=%v, playerId=%v, newInputFrameId=%v, lastInputFrameId=%v, newInputList=%v, lastInputList=%v, InputsBuffer=%v", pR.Id, playerId, inputFrameId, pR.LastAllConfirmedInputFrameId, inputFrameDownsync.InputList, pR.LastAllConfirmedInputList, pR.InputsBufferString(false)))
}
atomic.StoreInt32(&(pR.LastAllConfirmedInputFrameIdWithChange), inputFrameId)
}
@@ -637,7 +642,7 @@ func (pR *Room) onInputFrameDownsyncAllConfirmed(inputFrameDownsync *pb.InputFra
if -1 == playerId {
Logger.Debug(fmt.Sprintf("inputFrame lifecycle#2[forced-allconfirmed]: roomId=%v, InputsBuffer=%v", pR.Id, pR.InputsBufferString(false)))
} else {
- Logger.Info(fmt.Sprintf("inputFrame lifecycle#2[allconfirmed]: roomId=%v, playerId=%v, InputsBuffer=%v", pR.Id, playerId, pR.InputsBufferString(false)))
+ Logger.Debug(fmt.Sprintf("inputFrame lifecycle#2[allconfirmed]: roomId=%v, playerId=%v, InputsBuffer=%v", pR.Id, playerId, pR.InputsBufferString(false)))
}
}
@@ -789,8 +794,8 @@ func (pR *Room) OnDismissed() {
pR.NstDelayFrames = 8
pR.InputScaleFrames = uint32(2)
pR.ServerFps = 60
- pR.RollbackEstimatedDt = 0.016667 // Use fixed-and-low-precision to mitigate the inconsistent floating-point-number issue between Golang and JavaScript
- pR.RollbackEstimatedDtMillis = 16.667 // Use fixed-and-low-precision to mitigate the inconsistent floating-point-number issue between Golang and JavaScript
+ pR.RollbackEstimatedDt = 0.016667 // Use fixed-and-low-precision to mitigate the inconsistent floating-point-number issue between Golang and JavaScript
+ pR.RollbackEstimatedDtMillis = 16.667 // Use fixed-and-low-precision to mitigate the inconsistent floating-point-number issue between Golang and JavaScript
pR.RollbackEstimatedDtNanos = 16666666 // A little smaller than the actual per frame time, just for preventing FAST FRAME
pR.BattleDurationFrames = 30 * pR.ServerFps
pR.BattleDurationNanos = int64(pR.BattleDurationFrames) * (pR.RollbackEstimatedDtNanos + 1)
@@ -1142,17 +1147,23 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
encodedInput := inputList[joinIndex-1]
decodedInput := DIRECTION_DECODER[encodedInput]
decodedInputSpeedFactor := DIRECTION_DECODER_INVERSE_LENGTH[encodedInput]
+ if 0.0 == decodedInputSpeedFactor {
+ continue
+ }
baseChange := player.Speed * pR.RollbackEstimatedDt * decodedInputSpeedFactor
dx := baseChange * float64(decodedInput[0])
dy := baseChange * float64(decodedInput[1])
- // The collision lib seems very slow at worst cases, omitting for now
collisionPlayerIndex := COLLISION_PLAYER_INDEX_PREFIX + joinIndex
playerCollider := pR.CollisionSysMap[collisionPlayerIndex]
if collision := playerCollider.Check(dx, dy, "Barrier"); collision != nil {
changeWithCollision := collision.ContactWithObject(collision.Objects[0])
- dx = changeWithCollision.X()
- dy = changeWithCollision.Y()
+ Logger.Info(fmt.Sprintf("Collided: roomId=%v, playerId=%v, orig dx=%v, orig dy=%v, proposed new dx =%v, proposed new dy=%v", pR.Id, player.Id, dx, dy, changeWithCollision.X(), changeWithCollision.Y()))
+ // FIXME: Use a mechanism equivalent to that of the frontend!
+ // dx = changeWithCollision.X()
+ // dy = changeWithCollision.Y()
+ dx = 0
+ dy = 0
}
playerCollider.X += dx
playerCollider.Y += dy
@@ -1169,7 +1180,7 @@ func (pR *Room) applyInputFrameDownsyncDynamics(fromRenderFrameId int32, toRende
newRenderFrame := pb.RoomDownsyncFrame{
Id: collisionSysRenderFrameId + 1,
Players: toPbPlayers(pR.Players),
- CountdownNanos: (pR.BattleDurationNanos - int64(collisionSysRenderFrameId)*pR.RollbackEstimatedDtNanos),
+ CountdownNanos: (pR.BattleDurationNanos - int64(collisionSysRenderFrameId)*pR.RollbackEstimatedDtNanos),
}
pR.RenderFrameBuffer.Put(&newRenderFrame)
pR.CurDynamicsRenderFrameId++
@@ -1181,11 +1192,19 @@ func (pR *Room) inputFrameIdDebuggable(inputFrameId int32) bool {
}
func (pR *Room) refreshColliders() {
+ playerColliderRadius := float64(12) // hardcoded
// Kindly note that by now, we've already got all the shapes in the tmx file into "pR.(Players | Barriers)" from "ParseTmxLayersAndGroups"
- space := resolv.NewSpace(int(pR.StageDiscreteW), int(pR.StageDiscreteH), int(pR.StageTileW), int(pR.StageTileH)) // allocate a new collision space everytime after a battle is settled
+ spaceW := pR.StageDiscreteW * pR.StageTileW
+ spaceH := pR.StageDiscreteH * pR.StageTileH
+
+ spaceOffsetX := float64(spaceW) * 0.5
+ spaceOffsetY := float64(spaceH) * 0.5
+
+ minStep := int(3) // the approx minimum distance a player can move per frame
+ space := resolv.NewSpace(int(spaceW), int(spaceH), minStep, minStep) // allocate a new collision space everytime after a battle is settled
for _, player := range pR.Players {
- playerCollider := resolv.NewObject(player.X, player.Y, 12, 12) // Radius=12 is hardcoded
- playerColliderShape := resolv.NewCircle(player.X, player.Y, 12)
+ playerCollider := resolv.NewObject(player.X+spaceOffsetX, player.Y+spaceOffsetY, playerColliderRadius*2, playerColliderRadius*2)
+ playerColliderShape := resolv.NewCircle(0, 0, playerColliderRadius*2)
playerCollider.SetShape(playerColliderShape)
space.Add(playerCollider)
// Keep track of the collider in "pR.CollisionSysMap"
@@ -1196,8 +1215,10 @@ func (pR *Room) refreshColliders() {
}
for _, barrier := range pR.Barriers {
+
var w float64 = 0
var h float64 = 0
+
for i, pi := range barrier.Boundary.Points {
for j, pj := range barrier.Boundary.Points {
if i == j {
@@ -1214,13 +1235,12 @@ func (pR *Room) refreshColliders() {
barrierColliderShape := resolv.NewConvexPolygon()
for _, p := range barrier.Boundary.Points {
- barrierColliderShape.AddPoints(p.X+barrier.Boundary.Anchor.X, p.Y+barrier.Boundary.Anchor.Y)
+ barrierColliderShape.AddPoints(p.X, p.Y)
}
- barrierCollider := resolv.NewObject(barrier.Boundary.Anchor.X, barrier.Boundary.Anchor.Y, w, h, "Barrier")
+ barrierCollider := resolv.NewObject(barrier.Boundary.Anchor.X+spaceOffsetX, barrier.Boundary.Anchor.Y+spaceOffsetY, w, h, "Barrier")
barrierCollider.SetShape(barrierColliderShape)
space.Add(barrierCollider)
- pR.printBarrier(barrierCollider)
}
}
diff --git a/battle_srv/models/room_heap_manager.go b/battle_srv/models/room_heap_manager.go
index d788f0a..05daa76 100644
--- a/battle_srv/models/room_heap_manager.go
+++ b/battle_srv/models/room_heap_manager.go
@@ -2,9 +2,9 @@ package models
import (
"container/heap"
+ . "dnmshared"
"fmt"
"go.uber.org/zap"
- . "server/common"
"sync"
)
diff --git a/battle_srv/storage/mysql_manager.go b/battle_srv/storage/mysql_manager.go
index 9cca7f2..bfc8175 100644
--- a/battle_srv/storage/mysql_manager.go
+++ b/battle_srv/storage/mysql_manager.go
@@ -6,6 +6,8 @@ import (
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
"go.uber.org/zap"
+
+ . "dnmshared"
)
var (
@@ -15,8 +17,12 @@ var (
func initMySQL() {
var err error
MySQLManagerIns, err = sqlx.Connect("mysql", Conf.MySQL.DSN+"?charset=utf8mb4")
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
err = MySQLManagerIns.Ping()
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
Logger.Info("MySQLManagerIns", zap.Any("mysql", MySQLManagerIns))
}
diff --git a/battle_srv/storage/redis_manager.go b/battle_srv/storage/redis_manager.go
index 1458a7d..b977abf 100644
--- a/battle_srv/storage/redis_manager.go
+++ b/battle_srv/storage/redis_manager.go
@@ -7,6 +7,8 @@ import (
"github.com/go-redis/redis"
_ "github.com/go-sql-driver/mysql"
"go.uber.org/zap"
+
+ . "dnmshared"
)
var (
@@ -20,6 +22,8 @@ func initRedis() {
DB: Conf.Redis.Dbname, // use default DB
})
pong, err := RedisManagerIns.Ping().Result()
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
Logger.Info("Redis", zap.String("ping", pong))
}
diff --git a/battle_srv/test_cases/tests.go b/battle_srv/test_cases/tests.go
index a276a06..a5cee42 100644
--- a/battle_srv/test_cases/tests.go
+++ b/battle_srv/test_cases/tests.go
@@ -17,7 +17,9 @@ func loadTMX(fp string, pTmxMapIns *models.TmxMap) {
}
byteArr, err := ioutil.ReadFile(fp)
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
models.DeserializeToTmxMapIns(byteArr, pTmxMapIns)
for _, info := range pTmxMapIns.TreasuresInfo {
fmt.Printf("treasuresInfo: %v\n", info)
@@ -33,7 +35,9 @@ func loadTSX(fp string, pTsxIns *models.Tsx) {
}
byteArr, err := ioutil.ReadFile(fp)
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
models.DeserializeToTsxIns(byteArr, pTsxIns)
for _, Pos := range pTsxIns.TrapPolyLineList {
fmt.Printf("%v\n", Pos)
@@ -43,10 +47,14 @@ func loadTSX(fp string, pTsxIns *models.Tsx) {
func getTMXInfo() {
relativePath = "../frontend/assets/resources/map/treasurehunter.tmx"
execPath, err := os.Executable()
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
pwd, err := os.Getwd()
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
fmt.Printf("execPath = %v, pwd = %s, returning...\n", execPath, pwd)
@@ -61,10 +69,14 @@ func getTSXInfo() {
relativePath = "../frontend/assets/resources/map/tile_1.tsx"
execPath, err := os.Executable()
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
pwd, err := os.Getwd()
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
fmt.Printf("execPath = %v, pwd = %s, returning...\n", execPath, pwd)
tsxIns := models.Tsx{}
diff --git a/battle_srv/ws/serve.go b/battle_srv/ws/serve.go
index b27a4ca..0830d2c 100644
--- a/battle_srv/ws/serve.go
+++ b/battle_srv/ws/serve.go
@@ -14,6 +14,8 @@ import (
"strconv"
"sync/atomic"
"time"
+
+ . "dnmshared"
)
const (
diff --git a/collider_visualizer/Makefile b/collider_visualizer/Makefile
new file mode 100644
index 0000000..87d47c5
--- /dev/null
+++ b/collider_visualizer/Makefile
@@ -0,0 +1,21 @@
+PROJECTNAME=viscol.exe
+ROOT_DIR=.
+all: help
+## Available proxies for downloading go modules are listed in "https://github.com/golang/go/wiki/Modules#how-do-i-use-vendoring-with-modules-is-vendoring-going-away".
+GOPROXY=https://mirrors.aliyun.com/goproxy
+
+build:
+ go build -o $(ROOT_DIR)/$(PROJECTNAME)
+
+run: build
+ ./$(PROJECTNAME)
+
+.PHONY: help
+
+help: Makefile
+ @echo
+ @echo " Choose a command run:"
+ @echo
+ @sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /'
+ @echo
+
diff --git a/collider_visualizer/common.go b/collider_visualizer/common.go
new file mode 100644
index 0000000..feab531
--- /dev/null
+++ b/collider_visualizer/common.go
@@ -0,0 +1,52 @@
+package main
+
+import (
+ "github.com/hajimehoshi/ebiten/v2"
+ "github.com/solarlune/resolv"
+ "image/color"
+)
+
+var (
+ PolygonFillerImage = ebiten.NewImage(1, 1)
+)
+
+func DrawPolygon(screen *ebiten.Image, shape *resolv.ConvexPolygon, clr color.Color) {
+ PolygonFillerImage.Fill(clr)
+ indices := []uint16{}
+ vs := []ebiten.Vertex{}
+ coors := shape.Transformed()
+ centerX := float64(0)
+ centerY := float64(0)
+ n := uint16(len(coors))
+ for i, coor := range coors {
+ centerX += coor.X()
+ centerY += coor.Y()
+ vs = append(vs, ebiten.Vertex{
+ DstX: float32(coor.X()),
+ DstY: float32(coor.Y()),
+ SrcX: 0,
+ SrcY: 0,
+ ColorR: 1,
+ ColorG: 1,
+ ColorB: 1,
+ ColorA: 1,
+ })
+ indices = append(indices, uint16(i), uint16(i+1)%n, n)
+ }
+
+ centerX = centerX / float64(n)
+ centerY = centerY / float64(n)
+
+ vs = append(vs, ebiten.Vertex{
+ DstX: float32(centerX),
+ DstY: float32(centerY),
+ SrcX: 0,
+ SrcY: 0,
+ ColorR: 1,
+ ColorG: 1,
+ ColorB: 1,
+ ColorA: 1,
+ })
+
+ screen.DrawTriangles(vs, indices, PolygonFillerImage, nil)
+}
diff --git a/collider_visualizer/excel.ttf b/collider_visualizer/excel.ttf
new file mode 100644
index 0000000..820cfef
Binary files /dev/null and b/collider_visualizer/excel.ttf differ
diff --git a/collider_visualizer/go.mod b/collider_visualizer/go.mod
new file mode 100644
index 0000000..e05463a
--- /dev/null
+++ b/collider_visualizer/go.mod
@@ -0,0 +1,27 @@
+module viscol
+
+go 1.19
+
+require (
+ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
+ github.com/hajimehoshi/ebiten/v2 v2.4.7
+ github.com/solarlune/resolv v0.5.1
+ golang.org/x/image v0.0.0-20220902085622-e7cb96979f69
+ dnmshared v0.0.0
+)
+
+require (
+ github.com/ebitengine/purego v0.0.0-20220905075623-aeed57cda744 // indirect
+ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220806181222-55e207c401ad // indirect
+ github.com/hajimehoshi/file2byteslice v0.0.0-20210813153925-5340248a8f41 // indirect
+ github.com/jezek/xgb v1.0.1 // indirect
+ github.com/kvartborg/vector v0.0.0-20200419093813-2cba0cabb4f0 // indirect
+ go.uber.org/atomic v1.7.0 // indirect
+ go.uber.org/multierr v1.6.0 // indirect
+ go.uber.org/zap v1.23.0 // indirect
+ golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 // indirect
+ golang.org/x/mobile v0.0.0-20220722155234-aaac322e2105 // indirect
+ golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 // indirect
+)
+
+replace dnmshared => ../dnmshared
diff --git a/collider_visualizer/go.sum b/collider_visualizer/go.sum
new file mode 100644
index 0000000..3eb8bba
--- /dev/null
+++ b/collider_visualizer/go.sum
@@ -0,0 +1,96 @@
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/ebitengine/purego v0.0.0-20220905075623-aeed57cda744 h1:A8UnJ/5OKzki4HBDwoRQz7I6sxKsokpMXcGh+fUxpfc=
+github.com/ebitengine/purego v0.0.0-20220905075623-aeed57cda744/go.mod h1:Eh8I3yvknDYZeCuXH9kRNaPuHEwvXDCk378o9xszmHg=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220806181222-55e207c401ad h1:kX51IjbsJPCvzV9jUoVQG9GEUqIq5hjfYzXTqQ52Rh8=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220806181222-55e207c401ad/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
+github.com/hajimehoshi/bitmapfont/v2 v2.2.1 h1:y7zcy02/UgO24IL3COqYtrRZzhRucNBtmCo/SNU648k=
+github.com/hajimehoshi/bitmapfont/v2 v2.2.1/go.mod h1:wjrYAy8vKgj9JsFgnYAOK346/uvE22TlmqouzdnYIs0=
+github.com/hajimehoshi/ebiten/v2 v2.4.7 h1:XuvB7R0Rbw/O7g6vNU8gqr5b9e7MNhhAONMSsyreLDI=
+github.com/hajimehoshi/ebiten/v2 v2.4.7/go.mod h1:Ofk1EfQZZ8tL0TlEPF5wPrnN+8Oa/ywuQOYh+uYsqLQ=
+github.com/hajimehoshi/file2byteslice v0.0.0-20210813153925-5340248a8f41 h1:s01qIIRG7vN/5ndLwkDktjx44ulFk6apvAjVBYR50Yo=
+github.com/hajimehoshi/file2byteslice v0.0.0-20210813153925-5340248a8f41/go.mod h1:CqqAHp7Dk/AqQiwuhV1yT2334qbA/tFWQW0MD2dGqUE=
+github.com/hajimehoshi/go-mp3 v0.3.3/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
+github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
+github.com/hajimehoshi/oto/v2 v2.3.1/go.mod h1:seWLbgHH7AyUMYKfKYT9pg7PhUu9/SisyJvNTT+ASQo=
+github.com/jakecoffman/cp v1.2.1/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg=
+github.com/jezek/xgb v1.0.1 h1:YUGhxps0aR7J2Xplbs23OHnV1mWaxFVcOl9b+1RQkt8=
+github.com/jezek/xgb v1.0.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
+github.com/jfreymuth/oggvorbis v1.0.4/go.mod h1:1U4pqWmghcoVsCJJ4fRBKv9peUJMBHixthRlBeD6uII=
+github.com/jfreymuth/vorbis v1.0.2/go.mod h1:DoftRo4AznKnShRl1GxiTFCseHr4zR9BN3TWXyuzrqQ=
+github.com/kvartborg/vector v0.0.0-20200419093813-2cba0cabb4f0 h1:v8lWpj5957KtDMKu+xQtlu6G3ZoZR6Tn9bsfZCRG5Xw=
+github.com/kvartborg/vector v0.0.0-20200419093813-2cba0cabb4f0/go.mod h1:GAX7tMJqXx9fB1BrsTWPOXy6IBRX+J461BffVPAdpwo=
+github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/solarlune/resolv v0.5.1 h1:Ul6PAs/zaxiMUOEYz1Z6VeUj5k3CDcWMvSh+kivybDY=
+github.com/solarlune/resolv v0.5.1/go.mod h1:HjM2f/0NoVjVdZsi26GtugX5aFbA62COEFEXkOhveRw=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
+go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
+go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
+go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
+go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 h1:estk1glOnSVeJ9tdEZZc5mAMDZk5lNJNyJ6DvrBkTEU=
+golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
+golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/image v0.0.0-20220722155232-062f8c9fd539/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
+golang.org/x/image v0.0.0-20220902085622-e7cb96979f69 h1:Lj6HJGCSn5AjxRAH2+r35Mir4icalbqku+CLUtjnvXY=
+golang.org/x/image v0.0.0-20220902085622-e7cb96979f69/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
+golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
+golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
+golang.org/x/mobile v0.0.0-20220722155234-aaac322e2105 h1:3vUV5x5+3LfQbgk7paCM6INOaJG9xXQbn79xoNkwfIk=
+golang.org/x/mobile v0.0.0-20220722155234-aaac322e2105/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ=
+golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 h1:Sx/u41w+OwrInGdEckYmEuU5gHoGSL4QbDz3S9s6j4U=
+golang.org/x/sys v0.0.0-20220818161305-2296e01440c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/collider_visualizer/main.go b/collider_visualizer/main.go
new file mode 100644
index 0000000..516d45a
--- /dev/null
+++ b/collider_visualizer/main.go
@@ -0,0 +1,172 @@
+package main
+
+import (
+ _ "embed"
+ "fmt"
+ "image/color"
+
+ "go.uber.org/zap"
+
+ "github.com/golang/freetype/truetype"
+ "github.com/hajimehoshi/ebiten/v2"
+ "github.com/hajimehoshi/ebiten/v2/ebitenutil"
+ "github.com/hajimehoshi/ebiten/v2/text"
+ "github.com/solarlune/resolv"
+ "golang.org/x/image/font"
+
+ "encoding/xml"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+
+ . "dnmshared"
+)
+
+func parseStage(stageName string) (int32, int32, int32, int32, StrToVec2DListMap, StrToPolygon2DListMap, error) {
+ pwd, err := os.Getwd()
+ if nil != err {
+ Logger.Error("Failed to get current working dir:", zap.Any("pwd", pwd), zap.Any("err", err))
+ }
+
+ relativePathForAllStages := "../frontend/assets/resources/map"
+ relativePathForChosenStage := fmt.Sprintf("%s/%s", relativePathForAllStages, stageName)
+
+ pTmxMapIns := &TmxMap{}
+
+ absDirPathContainingDirectlyTmxFile := filepath.Join(pwd, relativePathForChosenStage)
+ absTmxFilePath := fmt.Sprintf("%s/map.tmx", absDirPathContainingDirectlyTmxFile)
+ if !filepath.IsAbs(absTmxFilePath) {
+ panic("Tmx filepath must be absolute!")
+ }
+
+ byteArr, err := ioutil.ReadFile(absTmxFilePath)
+ if nil != err {
+ panic(err)
+ }
+ err = xml.Unmarshal(byteArr, pTmxMapIns)
+ if nil != err {
+ panic(err)
+ }
+
+ // Obtain the content of `gidBoundariesMapInB2World`.
+ gidBoundariesMapInB2World := make(map[int]StrToPolygon2DListMap, 0)
+ for _, tileset := range pTmxMapIns.Tilesets {
+ relativeTsxFilePath := fmt.Sprintf("%s/%s", filepath.Join(pwd, relativePathForChosenStage), tileset.Source) // Note that "TmxTileset.Source" can be a string of "relative path".
+ absTsxFilePath, err := filepath.Abs(relativeTsxFilePath)
+ if nil != err {
+ panic(err)
+ }
+ if !filepath.IsAbs(absTsxFilePath) {
+ panic("Filepath must be absolute!")
+ }
+
+ byteArrOfTsxFile, err := ioutil.ReadFile(absTsxFilePath)
+ if nil != err {
+ panic(err)
+ }
+
+ DeserializeTsxToColliderDict(pTmxMapIns, byteArrOfTsxFile, int(tileset.FirstGid), gidBoundariesMapInB2World)
+ }
+
+ return ParseTmxLayersAndGroups(pTmxMapIns, gidBoundariesMapInB2World)
+}
+
+//go:embed excel.ttf
+var excelFont []byte
+
+type Game struct {
+ World WorldInterface
+ Width, Height int
+ Debug bool
+ ShowHelpText bool
+ Screen *ebiten.Image
+ FontFace font.Face
+}
+
+func NewGame() *Game {
+
+ // stageName := "simple" // Use this for calibration
+ stageName := "richsoil"
+ stageDiscreteW, stageDiscreteH, stageTileW, stageTileH, playerPosMap, barrierMap, err := parseStage(stageName)
+ if nil != err {
+ panic(err)
+ }
+ PolygonFillerImage.Fill(color.RGBA{60, 60, 60, 255}) // Required to init color of the polygons!
+
+ spaceW := stageDiscreteW * stageTileW
+ spaceH := stageDiscreteH * stageTileH
+
+ ebiten.SetWindowResizable(true)
+ ebiten.SetWindowTitle("resolv test")
+
+ g := &Game{
+ Width: int(spaceW),
+ Height: int(spaceH),
+ ShowHelpText: true,
+ }
+
+ g.World = NewWorldColliderDisplay(g, stageDiscreteW, stageDiscreteH, stageTileW, stageTileH, playerPosMap, barrierMap)
+
+ fontData, _ := truetype.Parse(excelFont)
+
+ g.FontFace = truetype.NewFace(fontData, &truetype.Options{Size: 10})
+
+ return g
+}
+
+func (g *Game) Update() error {
+ g.World.Update()
+ return nil
+}
+
+func (g *Game) Draw(screen *ebiten.Image) {
+ g.Screen = screen
+ screen.Fill(color.RGBA{20, 20, 40, 255})
+ g.World.Draw(screen)
+}
+
+func (g *Game) DrawText(screen *ebiten.Image, x, y int, textLines ...string) {
+ rectHeight := 10
+ for _, txt := range textLines {
+ w := float64(font.MeasureString(g.FontFace, txt).Round())
+ ebitenutil.DrawRect(screen, float64(x), float64(y-8), w, float64(rectHeight), color.RGBA{0, 0, 0, 192})
+
+ text.Draw(screen, txt, g.FontFace, x+1, y+1, color.RGBA{0, 0, 150, 255})
+ text.Draw(screen, txt, g.FontFace, x, y, color.RGBA{100, 150, 255, 255})
+ y += rectHeight
+ }
+}
+
+func (g *Game) DebugDraw(screen *ebiten.Image, space *resolv.Space) {
+
+ for y := 0; y < space.Height(); y++ {
+ for x := 0; x < space.Width(); x++ {
+ cell := space.Cell(x, y)
+
+ cw := float64(space.CellWidth)
+ ch := float64(space.CellHeight)
+ cx := float64(cell.X) * cw
+ cy := float64(cell.Y) * ch
+
+ drawColor := color.RGBA{20, 20, 20, 255}
+
+ if cell.Occupied() {
+ drawColor = color.RGBA{255, 255, 0, 255}
+ }
+
+ ebitenutil.DrawLine(screen, cx, cy, cx+cw, cy, drawColor)
+ ebitenutil.DrawLine(screen, cx+cw, cy, cx+cw, cy+ch, drawColor)
+ ebitenutil.DrawLine(screen, cx+cw, cy+ch, cx, cy+ch, drawColor)
+ ebitenutil.DrawLine(screen, cx, cy+ch, cx, cy, drawColor)
+ }
+ }
+
+}
+
+func (g *Game) Layout(w, h int) (int, int) {
+ return g.Width, g.Height
+}
+
+func main() {
+ ebiten.RunGame(NewGame())
+}
diff --git a/collider_visualizer/worldColliderDisplay.go b/collider_visualizer/worldColliderDisplay.go
new file mode 100644
index 0000000..b6f0b84
--- /dev/null
+++ b/collider_visualizer/worldColliderDisplay.go
@@ -0,0 +1,119 @@
+package main
+
+import (
+ . "dnmshared"
+ "fmt"
+ "github.com/hajimehoshi/ebiten/v2"
+ "github.com/hajimehoshi/ebiten/v2/ebitenutil"
+ "github.com/solarlune/resolv"
+ "go.uber.org/zap"
+ "image/color"
+
+ "math"
+)
+
+type WorldColliderDisplay struct {
+ Game *Game
+ Space *resolv.Space
+}
+
+func (world *WorldColliderDisplay) Init() {
+}
+
+func NewWorldColliderDisplay(game *Game, stageDiscreteW, stageDiscreteH, stageTileW, stageTileH int32, playerPosMap StrToVec2DListMap, barrierMap StrToPolygon2DListMap) *WorldColliderDisplay {
+
+ playerList := *(playerPosMap["PlayerStartingPos"])
+ barrierList := *(barrierMap["Barrier"])
+
+ world := &WorldColliderDisplay{Game: game}
+
+ Logger.Info("Parsed variables", zap.Any("stageDiscreteW", stageDiscreteW), zap.Any("stageDiscreteH", stageDiscreteH), zap.Any("stageTileW", stageTileW), zap.Any("stageTileH", stageTileH))
+
+ spaceW := stageDiscreteW * stageTileW
+ spaceH := stageDiscreteH * stageTileH
+
+ spaceOffsetX := float64(spaceW) * 0.5
+ spaceOffsetY := float64(spaceH) * 0.5
+
+ // TODO: Move collider y-axis transformation to a "dnmshared"
+ playerColliderRadius := float64(12) // hardcoded
+ space := resolv.NewSpace(int(spaceW), int(spaceH), 16, 16)
+ for _, player := range playerList {
+ playerCollider := resolv.NewObject(player.X+spaceOffsetX, player.Y+spaceOffsetY, playerColliderRadius*2, playerColliderRadius*2, "Player")
+ playerColliderShape := resolv.NewCircle(0, 0, playerColliderRadius*2)
+ playerCollider.SetShape(playerColliderShape)
+ space.Add(playerCollider)
+ }
+
+ barrierLocalId := 0
+ for _, barrierUnaligned := range barrierList {
+ barrier := AlignPolygon2DToBoundingBox(barrierUnaligned)
+
+ var w float64 = 0
+ var h float64 = 0
+
+ for i, pi := range barrier.Points {
+ for j, pj := range barrier.Points {
+ if i == j {
+ continue
+ }
+ if math.Abs(pj.X-pi.X) > w {
+ w = math.Abs(pj.X - pi.X)
+ }
+ if math.Abs(pj.Y-pi.Y) > h {
+ h = math.Abs(pj.Y - pi.Y)
+ }
+ }
+ }
+
+ barrierColliderShape := resolv.NewConvexPolygon()
+ for i := 0; i < len(barrier.Points); i++ {
+ p := barrier.Points[i]
+ barrierColliderShape.AddPoints(p.X, p.Y)
+ }
+
+ barrierCollider := resolv.NewObject(barrier.Anchor.X+spaceOffsetX, barrier.Anchor.Y+spaceOffsetY, w, h, "Barrier")
+ barrierCollider.SetShape(barrierColliderShape)
+
+ space.Add(barrierCollider)
+
+ barrierLocalId++
+ }
+
+ world.Space = space
+ return world
+}
+
+func (world *WorldColliderDisplay) Update() {
+
+}
+
+func (world *WorldColliderDisplay) Draw(screen *ebiten.Image) {
+
+ for _, o := range world.Space.Objects() {
+ if o.HasTags("Player") {
+ circle := o.Shape.(*resolv.Circle)
+ drawColor := color.RGBA{0, 255, 0, 255}
+ ebitenutil.DrawCircle(screen, circle.X, circle.Y, circle.Radius, drawColor)
+ } else {
+ drawColor := color.RGBA{60, 60, 60, 255}
+ DrawPolygon(screen, o.Shape.(*resolv.ConvexPolygon), drawColor)
+ }
+ }
+
+ world.Game.DebugDraw(screen, world.Space)
+
+ if world.Game.ShowHelpText {
+
+ world.Game.DrawText(screen, 16, 16,
+ "~ Collider Display test ~",
+ "F1: Toggle Debug View",
+ "F2: Show / Hide help text",
+ "R: Restart world",
+ fmt.Sprintf("%d FPS (frames per second)", int(ebiten.CurrentFPS())),
+ fmt.Sprintf("%d TPS (ticks per second)", int(ebiten.CurrentTPS())),
+ )
+
+ }
+
+}
diff --git a/collider_visualizer/worldinterface.go b/collider_visualizer/worldinterface.go
new file mode 100644
index 0000000..325b038
--- /dev/null
+++ b/collider_visualizer/worldinterface.go
@@ -0,0 +1,9 @@
+package main
+
+import "github.com/hajimehoshi/ebiten/v2"
+
+type WorldInterface interface {
+ Init()
+ Update()
+ Draw(*ebiten.Image)
+}
diff --git a/dnmshared/geometry.go b/dnmshared/geometry.go
new file mode 100644
index 0000000..c1c4edc
--- /dev/null
+++ b/dnmshared/geometry.go
@@ -0,0 +1,47 @@
+package dnmshared
+
+import (
+ "math"
+)
+
+// Use type `float64` for json unmarshalling of numbers.
+type Direction struct {
+ Dx int32 `json:"dx,omitempty"`
+ Dy int32 `json:"dy,omitempty"`
+}
+
+type Vec2D struct {
+ X float64 `json:"x,omitempty"`
+ Y float64 `json:"y,omitempty"`
+}
+
+type Polygon2D struct {
+ Anchor *Vec2D `json:"-"` // This "Polygon2D.Anchor" is used to be assigned to "B2BodyDef.Position", which in turn is used as the position of the FIRST POINT of the polygon.
+ Points []*Vec2D `json:"-"`
+
+ /*
+ When used to represent a "polyline directly drawn in a `Tmx file`", we can initialize both "Anchor" and "Points" simultaneously.
+
+ Yet when used to represent a "polyline drawn in a `Tsx file`", we have to first initialize "Points w.r.t. center of the tile-rectangle", and then "Anchor(initially nil) of the tile positioned in the `Tmx file`".
+
+ Refer to https://shimo.im/docs/SmLJJhXm2C8XMzZT for more information.
+ */
+
+ /*
+ [WARNING] Used to cache "`TileWidth & TileHeight` of a Tsx file" only.
+ */
+ TileWidth int
+ TileHeight int
+
+ /*
+ [WARNING] Used to cache "`Width & TileHeight` of an object in Tmx file" only.
+ */
+ TmxObjectWidth float64
+ TmxObjectHeight float64
+}
+
+func Distance(pt1 *Vec2D, pt2 *Vec2D) float64 {
+ dx := pt1.X - pt2.X
+ dy := pt1.Y - pt2.Y
+ return math.Sqrt(dx*dx + dy*dy)
+}
diff --git a/dnmshared/go.mod b/dnmshared/go.mod
new file mode 100644
index 0000000..5d40f79
--- /dev/null
+++ b/dnmshared/go.mod
@@ -0,0 +1,3 @@
+module tiled
+
+go 1.19
diff --git a/battle_srv/common/logger.go b/dnmshared/logger.go
similarity index 90%
rename from battle_srv/common/logger.go
rename to dnmshared/logger.go
index 8804ec5..820bde4 100644
--- a/battle_srv/common/logger.go
+++ b/dnmshared/logger.go
@@ -1,4 +1,4 @@
-package common
+package dnmshared
import (
"go.uber.org/zap"
@@ -19,5 +19,7 @@ func init() {
LoggerConfig.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
var err error
Logger, err = LoggerConfig.Build()
- ErrFatal(err)
+ if nil != err {
+ panic(err)
+ }
}
diff --git a/battle_srv/models/tiled_map.go b/dnmshared/tmx_parser.go
similarity index 92%
rename from battle_srv/models/tiled_map.go
rename to dnmshared/tmx_parser.go
index 6eadb62..31c4d50 100644
--- a/battle_srv/models/tiled_map.go
+++ b/dnmshared/tmx_parser.go
@@ -1,4 +1,4 @@
-package models
+package dnmshared
import (
"bytes"
@@ -9,7 +9,6 @@ import (
"go.uber.org/zap"
"io/ioutil"
"math"
- . "server/common"
"strconv"
"strings"
)
@@ -176,8 +175,8 @@ func (l *TmxLayer) decodeBase64() ([]uint32, error) {
type Vec2DList []*Vec2D
type Polygon2DList []*Polygon2D
-type StrToVec2DListMap map[string]*Vec2DList // Note that it's deliberately NOT using "map[string]Vec2DList", for the easy of passing return value to "models/room.go".
-type StrToPolygon2DListMap map[string]*Polygon2DList // Note that it's deliberately NOT using "map[string]Polygon2DList", for the easy of passing return value to "models/room.go".
+type StrToVec2DListMap map[string]*Vec2DList
+type StrToPolygon2DListMap map[string]*Polygon2DList
func tmxPolylineToPolygon2D(pTmxMapIns *TmxMap, singleObjInTmxFile *TmxOrTsxObject, targetPolyline *TmxOrTsxPolyline) (*Polygon2D, error) {
if nil == targetPolyline {
@@ -443,3 +442,40 @@ func (pTmxMapIns *TmxMap) continuousObjLayerOffsetToContinuousMapNodePos(continu
return toRet
}
+
+func AlignPolygon2DToBoundingBox(input *Polygon2D) *Polygon2D {
+ // Transform again to put "anchor" at the top-left point of the bounding box for "resolv"
+ float64Max := float64(99999999999999.9)
+ boundingBoxTL := &Vec2D{
+ X: float64Max,
+ Y: float64Max,
+ }
+ for _, p := range input.Points {
+ if p.X < boundingBoxTL.X {
+ boundingBoxTL.X = p.X
+ }
+ if p.Y < boundingBoxTL.Y {
+ boundingBoxTL.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"
+ output := &Polygon2D{
+ Anchor: &Vec2D{
+ X: input.Anchor.X+boundingBoxTL.X,
+ Y: input.Anchor.Y+boundingBoxTL.Y,
+ },
+ Points: make([]*Vec2D, len(input.Points)),
+ TileWidth: input.TileWidth,
+ TileHeight: input.TileHeight,
+ }
+
+ for i, p := range input.Points {
+ output.Points[i] = &Vec2D{
+ X: p.X-boundingBoxTL.X,
+ Y: p.Y-boundingBoxTL.Y,
+ }
+ }
+
+ return output
+}
diff --git a/frontend/assets/resources/map/pacman/BackgroundMap/Tile_W256_H128_S01.tsx.meta b/frontend/assets/resources/map/pacman/BackgroundMap/Tile_W256_H128_S01.tsx.meta
deleted file mode 100644
index 31b1b96..0000000
--- a/frontend/assets/resources/map/pacman/BackgroundMap/Tile_W256_H128_S01.tsx.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "ver": "2.0.0",
- "uuid": "51b3303a-7c55-4f8b-b6b9-b5efb6164d19",
- "subMetas": {}
-}
\ No newline at end of file
diff --git a/frontend/assets/resources/map/pacman/BackgroundMap/Tile_W256_H256_S01.tsx.meta b/frontend/assets/resources/map/pacman/BackgroundMap/Tile_W256_H256_S01.tsx.meta
deleted file mode 100644
index e87b0a8..0000000
--- a/frontend/assets/resources/map/pacman/BackgroundMap/Tile_W256_H256_S01.tsx.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "ver": "2.0.0",
- "uuid": "8347ba4a-e73c-4173-a9ba-f7711fae5a90",
- "subMetas": {}
-}
\ No newline at end of file
diff --git a/frontend/assets/resources/map/pacman/BackgroundMap/Tile_W256_H256_S02.tsx.meta b/frontend/assets/resources/map/pacman/BackgroundMap/Tile_W256_H256_S02.tsx.meta
deleted file mode 100644
index 707df4a..0000000
--- a/frontend/assets/resources/map/pacman/BackgroundMap/Tile_W256_H256_S02.tsx.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "ver": "2.0.0",
- "uuid": "05720598-8487-406c-b2f3-2059240fde56",
- "subMetas": {}
-}
\ No newline at end of file
diff --git a/frontend/assets/resources/map/pacman/BackgroundMap/map.tmx.meta b/frontend/assets/resources/map/pacman/BackgroundMap/map.tmx.meta
deleted file mode 100644
index 02f5b17..0000000
--- a/frontend/assets/resources/map/pacman/BackgroundMap/map.tmx.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "ver": "2.0.2",
- "uuid": "4e2296fe-8855-4fb4-a407-fea295ded82e",
- "subMetas": {}
-}
\ No newline at end of file
diff --git a/frontend/assets/resources/map/pacman/Tile_W300_H300_S01.tsx.meta b/frontend/assets/resources/map/pacman/Tile_W300_H300_S01.tsx.meta
deleted file mode 100644
index 08c04a6..0000000
--- a/frontend/assets/resources/map/pacman/Tile_W300_H300_S01.tsx.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "ver": "2.0.0",
- "uuid": "da664a14-58c3-4f57-8aca-1270f96bf3ee",
- "subMetas": {}
-}
\ No newline at end of file
diff --git a/frontend/assets/resources/map/pacman/Tile_W64_H64_S01.tsx.meta b/frontend/assets/resources/map/pacman/Tile_W64_H64_S01.tsx.meta
deleted file mode 100644
index d10cb1a..0000000
--- a/frontend/assets/resources/map/pacman/Tile_W64_H64_S01.tsx.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "ver": "2.0.0",
- "uuid": "59b65107-0da7-47b3-a08d-7de824dd5a39",
- "subMetas": {}
-}
\ No newline at end of file
diff --git a/frontend/assets/resources/map/pacman/map.tmx b/frontend/assets/resources/map/pacman/map.tmx
deleted file mode 100644
index e04fee4..0000000
--- a/frontend/assets/resources/map/pacman/map.tmx
+++ /dev/null
@@ -1,335 +0,0 @@
-
-
diff --git a/frontend/assets/resources/map/pacman/map.tmx.meta b/frontend/assets/resources/map/pacman/map.tmx.meta
deleted file mode 100644
index 0afb7ea..0000000
--- a/frontend/assets/resources/map/pacman/map.tmx.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "ver": "2.0.2",
- "uuid": "7fd0b77d-0736-4e00-89eb-7111f07ed4f1",
- "subMetas": {}
-}
\ No newline at end of file
diff --git a/frontend/assets/resources/map/richsoil/map.tmx b/frontend/assets/resources/map/richsoil/map.tmx
index 1bbfb8c..b945aea 100644
--- a/frontend/assets/resources/map/richsoil/map.tmx
+++ b/frontend/assets/resources/map/richsoil/map.tmx
@@ -1,5 +1,5 @@
-