227 lines
7.2 KiB
Go
227 lines
7.2 KiB
Go
package main
|
|
|
|
import (
|
|
"math/rand"
|
|
|
|
"os"
|
|
"runtime"
|
|
"strconv"
|
|
|
|
gui "github.com/gen2brain/raylib-go/raygui"
|
|
rl "github.com/gen2brain/raylib-go/raylib"
|
|
)
|
|
|
|
const (
|
|
screenWidth = 1280
|
|
screenHeight = 720
|
|
ballRadius = 10
|
|
squareSize = 110
|
|
debug = false
|
|
cosmeticResize = 4
|
|
)
|
|
|
|
var (
|
|
speed = 200
|
|
ballPos = rl.Vector2{X: (squareSize * 64) / 2, Y: (squareSize * 64) / 2}
|
|
cameraPos = rl.Vector2{X: ballPos.X - screenWidth/2, Y: ballPos.Y - screenHeight/2}
|
|
ballColor = rl.Black
|
|
paints = []paint{}
|
|
chatBoxText = ""
|
|
inputText = ""
|
|
loadedMap = []string{}
|
|
loadedTextures = []rl.Texture2D{}
|
|
walls = []rl.Vector2{}
|
|
liquids = []rl.Vector2{}
|
|
cosmetic = rl.Texture2D{}
|
|
notification = rl.Sound{}
|
|
chatMessage = rl.Sound{}
|
|
)
|
|
|
|
func main() {
|
|
userData := loadJson("account.json")
|
|
checkUserDataValid(userData)
|
|
ballColor = convertHex(userData["color"].(string))
|
|
|
|
rl.InitWindow(screenWidth, screenHeight, "balls offline")
|
|
rl.InitAudioDevice()
|
|
rl.SetTargetFPS(60)
|
|
|
|
guessy := rl.LoadFont("./assets/font/guessy4.ttf")
|
|
carlito := rl.LoadFont("./assets/font/carlito.ttf")
|
|
|
|
notification = rl.LoadSound("./assets/sound/Notification.ogg")
|
|
chatMessage = rl.LoadSound("./assets/sound/ChatMessage.ogg")
|
|
|
|
gui.LoadStyle("./assets/bf.rgs")
|
|
chatBoxText = userData["username"].(string) + " joined the game."
|
|
rl.PlaySound(notification)
|
|
|
|
rawMap, Error := os.ReadFile("./assets/maps/" + strconv.Itoa(rand.Intn(9)) + ".txt")
|
|
loadedMap = sliceMap(string(rawMap))
|
|
check(Error)
|
|
|
|
walls = getBlocks(loadedMap, []int{51, 52})
|
|
liquids = getBlocks(loadedMap, []int{53})
|
|
|
|
cosmetic = loadCosmetic(userData)
|
|
|
|
loadedTextures = cropTexturePack("./assets/img/textures/" + userData["texture"].(string))
|
|
|
|
icon := rl.LoadImage("icon.png")
|
|
rl.SetWindowIcon(*icon)
|
|
|
|
for !rl.WindowShouldClose() {
|
|
|
|
rl.BeginDrawing()
|
|
rl.ClearBackground(rl.NewColor(128, 128, 128, 255))
|
|
|
|
drawMap(loadedMap)
|
|
drawPaint()
|
|
drawBall(ballPos, ballColor, rl.White, cosmetic)
|
|
moveBall()
|
|
|
|
usernamePosisiton := rl.Vector2Subtract(ballPos, rl.Vector2{ballRadius + 24, ballRadius + 40})
|
|
usernamePosisiton = rl.Vector2Subtract(usernamePosisiton, cameraPos)
|
|
|
|
fpsText := "FPS: " + strconv.Itoa(int(rl.GetFPS()))
|
|
|
|
var spacing int = 21
|
|
drawTextShadow("Balls Offline", rl.Vector2{12, 5}, carlito, rl.White)
|
|
rl.DrawCircleV(rl.Vector2{135, 14}, 8, rl.NewColor(0, 255, 0, 255))
|
|
drawTextShadow(fpsText, rl.Vector2{155, 5}, carlito, rl.NewColor(0, 255, 0, 255))
|
|
rl.DrawLine(10, 33, 120, 33, rl.NewColor(221, 221, 221, 255))
|
|
drawTextShadow("Version: 1.0.0", rl.Vector2{10, float32(2*spacing + 1)}, carlito, rl.NewColor(168, 168, 252, 255))
|
|
drawTextShadow("Platform: "+runtime.GOOS, rl.Vector2{10, float32(3*spacing + 1)}, carlito, rl.NewColor(168, 168, 252, 255))
|
|
drawTextShadow("Client ID: none", rl.Vector2{10, float32(5*spacing + 1)}, carlito, rl.NewColor(221, 221, 221, 255))
|
|
|
|
x := strconv.FormatFloat(float64(ballPos.X), 'f', -1, 64)[0:4]
|
|
y := strconv.FormatFloat(float64(ballPos.Y), 'f', -1, 64)[0:4]
|
|
|
|
drawTextShadow("Position: "+x+" | "+y, rl.Vector2{10, float32(6*spacing + 1)}, carlito, rl.White)
|
|
|
|
drawTextShadow(userData["username"].(string), usernamePosisiton, guessy, rl.NewColor(221, 221, 221, 255))
|
|
|
|
if rl.IsKeyPressed(rl.KeyEnter) && inputText != "" {
|
|
rl.PlaySound(chatMessage)
|
|
chatBoxText = chatBoxText + "\n" + userData["username"].(string) + ": " + inputText
|
|
inputText = ""
|
|
}
|
|
gui.TextBox(rl.NewRectangle(screenWidth-screenWidth/4, 0, screenWidth/4, 220), &chatBoxText, 100, false)
|
|
gui.TextBox(rl.NewRectangle(screenWidth-screenWidth/4, 220, screenWidth/4, 20), &inputText, 100, true)
|
|
rl.EndDrawing()
|
|
|
|
}
|
|
|
|
rl.CloseAudioDevice()
|
|
rl.CloseWindow()
|
|
}
|
|
|
|
func loadCosmetic(userData map[string]interface{}) rl.Texture2D {
|
|
if userData["costmetic"].(string) == "none" {
|
|
return rl.NewTexture2D(0, 0, 0, 0, 0)
|
|
}
|
|
image := rl.LoadImage("./assets/img/cosmetics/" + userData["costmetic"].(string))
|
|
|
|
rl.ImageResizeNN(image, ballRadius*cosmeticResize, ballRadius*cosmeticResize)
|
|
|
|
return rl.LoadTextureFromImage(image)
|
|
}
|
|
|
|
func moveBall() {
|
|
if rl.IsKeyDown(rl.KeyLeftShift) {
|
|
draw()
|
|
}
|
|
|
|
ballSpeed := float32(speed) * rl.GetFrameTime()
|
|
if rl.IsKeyDown(rl.KeyRight) && !checkCollision(rl.Vector2{X: ballPos.X + ballSpeed, Y: ballPos.Y}) {
|
|
ballPos.X = ballPos.X + ballSpeed
|
|
cameraPos.X = cameraPos.X + ballSpeed
|
|
}
|
|
if rl.IsKeyDown(rl.KeyLeft) && !checkCollision(rl.Vector2{X: ballPos.X - ballSpeed, Y: ballPos.Y}) {
|
|
ballPos.X = ballPos.X - ballSpeed
|
|
cameraPos.X = cameraPos.X - ballSpeed
|
|
}
|
|
if rl.IsKeyDown(rl.KeyUp) && !checkCollision(rl.Vector2{X: ballPos.X, Y: ballPos.Y - ballSpeed}) {
|
|
ballPos.Y = ballPos.Y - ballSpeed
|
|
cameraPos.Y = cameraPos.Y - ballSpeed
|
|
}
|
|
if rl.IsKeyDown(rl.KeyDown) && !checkCollision(rl.Vector2{X: ballPos.X, Y: ballPos.Y + ballSpeed}) {
|
|
ballPos.Y = ballPos.Y + ballSpeed
|
|
cameraPos.Y = cameraPos.Y + ballSpeed
|
|
}
|
|
}
|
|
|
|
func drawBall(pos rl.Vector2, color, outline rl.Color, ballCosmetic rl.Texture2D) {
|
|
rl.DrawCircleV(rl.Vector2Subtract(pos, cameraPos), ballRadius+1, outline)
|
|
rl.DrawCircleV(rl.Vector2Subtract(pos, cameraPos), ballRadius, color)
|
|
rl.DrawTextureV(ballCosmetic, rl.Vector2Subtract(rl.Vector2{pos.X - ballRadius*cosmeticResize/2, pos.Y - ballRadius*cosmeticResize/2}, cameraPos), rl.White)
|
|
}
|
|
|
|
func drawTextShadow(text string, textPos rl.Vector2, font rl.Font, color rl.Color) {
|
|
var textShadowPos rl.Vector2 = rl.Vector2{X: textPos.X + 2, Y: textPos.Y + 2}
|
|
rl.DrawTextEx(font, text, textShadowPos, 20, 1, rl.Black)
|
|
rl.DrawTextEx(font, text, textPos, 20, 1, color)
|
|
}
|
|
|
|
func checkCollision(newPos rl.Vector2) bool {
|
|
|
|
for x := range liquids {
|
|
if rl.CheckCollisionPointRec(newPos, rl.NewRectangle(liquids[x].X*squareSize, liquids[x].Y*squareSize, squareSize, squareSize)) {
|
|
chatBoxText = chatBoxText + "\n" + "You've drowned!"
|
|
ballPos = rl.Vector2{X: (squareSize * 64) / 2, Y: (squareSize * 64) / 2}
|
|
cameraPos = rl.Vector2{X: ballPos.X - screenWidth/2, Y: ballPos.Y - screenHeight/2}
|
|
rl.PlaySound(chatMessage)
|
|
}
|
|
}
|
|
for x := range walls {
|
|
if rl.CheckCollisionPointRec(newPos, rl.NewRectangle(walls[x].X*squareSize, walls[x].Y*squareSize, squareSize, squareSize)) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
if newPos.X > float32(64*squareSize) {
|
|
return true
|
|
}
|
|
if newPos.X < 0 {
|
|
return true
|
|
}
|
|
if newPos.Y < 0 {
|
|
return true
|
|
}
|
|
if newPos.Y > float32(64*squareSize) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func convertHex(hex string) rl.Color {
|
|
hex1 := hex[0:2]
|
|
hex2 := hex[2:4]
|
|
hex3 := hex[4:6]
|
|
decimal, err := strconv.ParseInt(hex1, 16, 64)
|
|
checkLog(err)
|
|
decimal2, err := strconv.ParseInt(hex2, 16, 64)
|
|
checkLog(err)
|
|
decimal3, err := strconv.ParseInt(hex3, 16, 64)
|
|
checkLog(err)
|
|
|
|
return rl.NewColor(uint8(decimal), uint8(decimal2), uint8(decimal3), 255)
|
|
}
|
|
|
|
func cropTexturePack(textureLocation string) []rl.Texture2D {
|
|
var textures []rl.Texture2D
|
|
|
|
for i := 0; i < 6; i++ {
|
|
image := rl.LoadImage(textureLocation)
|
|
croppedImage := image
|
|
rl.ImageCrop(croppedImage, rl.NewRectangle(float32(i*32), 0, 32, 32))
|
|
rl.ImageResizeNN(croppedImage, squareSize, squareSize)
|
|
|
|
croppedTexture := rl.LoadTextureFromImage(croppedImage)
|
|
rl.SetTextureFilter(croppedTexture, rl.FilterPoint)
|
|
|
|
textures = append(textures, croppedTexture)
|
|
}
|
|
return textures
|
|
}
|