Tons of experimental updates.
This commit is contained in:
51
character/character.go
Normal file
51
character/character.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package character
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
p "loading/point"
|
||||||
|
"math"
|
||||||
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
agentIdMax = 100
|
||||||
|
offset = 15
|
||||||
|
xd = offset
|
||||||
|
yd = offset
|
||||||
|
)
|
||||||
|
|
||||||
|
type Character struct {
|
||||||
|
Name string
|
||||||
|
Pose p.Point
|
||||||
|
Shape []p.Point
|
||||||
|
Color color.RGBA
|
||||||
|
Angle float32
|
||||||
|
DeltaAngle float32
|
||||||
|
SignFlip float32
|
||||||
|
Buffer float32
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCharacter() Character {
|
||||||
|
return Character{
|
||||||
|
Name: "Agent-" + strconv.Itoa(rand.Intn(agentIdMax)),
|
||||||
|
Pose: p.Point{X: 0, Y: 0},
|
||||||
|
Shape: []p.Point{{X: 0, Y: 0}, {X: xd, Y: 0}, {X: xd, Y: yd}},
|
||||||
|
Color: color.RGBA{0xFF, 0xFF, 0xFF, 0xFF},
|
||||||
|
Angle: (rand.Float32() * 2 * math.Pi),
|
||||||
|
DeltaAngle: 0,
|
||||||
|
Buffer: offset,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Character) SetPose(x float32, y float32) {
|
||||||
|
c.Pose.X = x
|
||||||
|
c.Pose.Y = y
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Character) LoadShape(vertices []p.Point) {
|
||||||
|
|
||||||
|
c.Shape = c.Shape[:0]
|
||||||
|
c.Shape = append(c.Shape, vertices...)
|
||||||
|
}
|
||||||
147
drawer.go
Normal file
147
drawer.go
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"image/color"
|
||||||
|
"loading/character"
|
||||||
|
"loading/objects"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/text"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/vector"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DrawBobble(b objects.Bobble, image *ebiten.Image) {
|
||||||
|
|
||||||
|
if b.Radius < 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
vector.DrawFilledCircle(image, b.Pose.X, b.Pose.Y, b.Radius+10, b.Bordercolor, true)
|
||||||
|
vector.DrawFilledCircle(image, b.Pose.X, b.Pose.Y, b.Radius, b.Color, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DrawCharacter(c character.Character, image *ebiten.Image) {
|
||||||
|
|
||||||
|
if len(c.Shape) <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var path vector.Path
|
||||||
|
path.MoveTo(c.Pose.X, c.Pose.Y)
|
||||||
|
for _, p := range c.Shape {
|
||||||
|
|
||||||
|
//rotation time *dance*
|
||||||
|
newX := c.Pose.X + float32(math.Cos(float64(c.Angle)))*(p.X) - float32(math.Sin(float64(c.Angle)))*(p.Y)
|
||||||
|
newY := c.Pose.Y + float32(math.Sin(float64(c.Angle)))*(p.X) + float32(math.Cos(float64(c.Angle)))*(p.Y)
|
||||||
|
path.LineTo(newX, newY)
|
||||||
|
}
|
||||||
|
path.Close()
|
||||||
|
|
||||||
|
var vs []ebiten.Vertex
|
||||||
|
var is []uint16
|
||||||
|
|
||||||
|
vs, is = path.AppendVerticesAndIndicesForFilling(nil, nil)
|
||||||
|
|
||||||
|
for i := range vs {
|
||||||
|
vs[i].SrcX = 1
|
||||||
|
vs[i].SrcY = 1
|
||||||
|
vs[i].ColorR = float32(c.Color.R) / 0xFF
|
||||||
|
vs[i].ColorG = float32(c.Color.B) / 0xFF
|
||||||
|
vs[i].ColorB = float32(c.Color.G) / 0xFF
|
||||||
|
vs[i].ColorA = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
op := &ebiten.DrawTrianglesOptions{}
|
||||||
|
|
||||||
|
//pose information
|
||||||
|
//angle := fmt.Sprintf("%.2f", c.Angle*180/math.Pi)
|
||||||
|
//delta := fmt.Sprintf("%.2f", c.DeltaAngle*180/math.Pi)
|
||||||
|
|
||||||
|
//text.Draw(image, angle, mplusTinyFont, int(c.Pose.X+20), int(c.Pose.Y), color.White)
|
||||||
|
//text.Draw(image, delta, mplusTinyFont, int(c.Pose.X+20), int(c.Pose.Y+15), color.White)
|
||||||
|
|
||||||
|
image.DrawTriangles(vs, is, whiteSubImage, op)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Game) DrawLoading(image *ebiten.Image) {
|
||||||
|
|
||||||
|
//identifier
|
||||||
|
text.Draw(image, versionInfo, mplusTinyFont, 20, 60, color.White)
|
||||||
|
|
||||||
|
//radial
|
||||||
|
var xs []int
|
||||||
|
var ys []int
|
||||||
|
var tc []uint8
|
||||||
|
var scales []float32
|
||||||
|
|
||||||
|
fade_scale := 0xFF / numTiles
|
||||||
|
|
||||||
|
for i := 0; i < numTiles; i++ {
|
||||||
|
xs = append(xs, int(math.Cos(float64(g.counter)/(math.Pi*3)-float64(i)*math.Pi/3)*40+screenWidth/2-float64(tileWidth)/2))
|
||||||
|
ys = append(ys, int(math.Sin(float64(g.counter)/(math.Pi*3)-float64(i)*math.Pi/3)*40+screenHeight/2-float64(tileHeight)/2))
|
||||||
|
tc = append(tc, uint8(0xFF-fade_scale*i))
|
||||||
|
|
||||||
|
scales = append(scales, float32(math.Sin(float64(g.counter)/(math.Pi*12))/2+1))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := numTiles - 1; i >= 0; i-- {
|
||||||
|
drawTile(image, float32(xs[i]), float32(ys[i]), scales[i], color.RGBA{tc[i], tc[i], tc[i], 0xFF})
|
||||||
|
}
|
||||||
|
|
||||||
|
//Percentage >:]
|
||||||
|
//percent := (maxPercent - 1/math.Exp(float64(g.counter-1)-10/6)) / maxPercent
|
||||||
|
offset := float64(4.605)
|
||||||
|
exppart0 := float64(g.counter-1) / 10000
|
||||||
|
|
||||||
|
percent := maxPercent - 1/math.Exp(exppart0-offset)
|
||||||
|
if percent < 0 {
|
||||||
|
percent = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
//100-1/e^(x/1000 - 4.6)
|
||||||
|
|
||||||
|
text.Draw(image, fmt.Sprintf("%.2f%%", percent), mplusTinyFont, screenWidth/2-70/2, screenHeight-80, color.RGBA{0xC0, 0xC0, 0xC0, 0xC0})
|
||||||
|
}
|
||||||
|
|
||||||
|
func drawTile(screen *ebiten.Image, x float32, y float32, scale float32, c color.RGBA) {
|
||||||
|
var scaleFactor float32 = 1
|
||||||
|
if scale > 0 {
|
||||||
|
scaleFactor = scale
|
||||||
|
}
|
||||||
|
drawTileToScale(screen, x, y, scaleFactor, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func drawTileToScale(screen *ebiten.Image, x float32, y float32, scale float32, c color.RGBA) {
|
||||||
|
|
||||||
|
var path vector.Path
|
||||||
|
|
||||||
|
//scale delta
|
||||||
|
xd := tileWidth * scale
|
||||||
|
yd := tileHeight * scale
|
||||||
|
|
||||||
|
//position at object origin shifted slightly for the half width/height adjustment
|
||||||
|
path.MoveTo(x-xd/2, y-yd/2)
|
||||||
|
path.LineTo(x+xd/2, y-yd/2)
|
||||||
|
path.LineTo(x+xd/2, y+yd/2)
|
||||||
|
path.LineTo(x-xd/2, y+yd/2)
|
||||||
|
path.LineTo(x-xd/2, y+yd/2)
|
||||||
|
path.Close()
|
||||||
|
|
||||||
|
var vs []ebiten.Vertex
|
||||||
|
var is []uint16
|
||||||
|
|
||||||
|
vs, is = path.AppendVerticesAndIndicesForFilling(nil, nil)
|
||||||
|
|
||||||
|
for i := range vs {
|
||||||
|
vs[i].SrcX = 1
|
||||||
|
vs[i].SrcY = 1
|
||||||
|
vs[i].ColorR = float32(c.R) / 0xFF
|
||||||
|
vs[i].ColorG = float32(c.B) / 0xFF
|
||||||
|
vs[i].ColorB = float32(c.G) / 0xFF
|
||||||
|
vs[i].ColorA = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
op := &ebiten.DrawTrianglesOptions{}
|
||||||
|
screen.DrawTriangles(vs, is, whiteSubImage, op)
|
||||||
|
}
|
||||||
64
game.go
Normal file
64
game.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
c "loading/character"
|
||||||
|
"loading/objects"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/text"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Game implements ebiten.Game interface.
|
||||||
|
type Game struct {
|
||||||
|
counter int
|
||||||
|
player c.Character
|
||||||
|
enemies []c.Character
|
||||||
|
keys []ebiten.Key
|
||||||
|
bobbles []objects.Bobble
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layout takes the outside size (e.g., the window size) and returns the (logical) screen size.
|
||||||
|
// If you don't have to adjust the screen size with the outside size, just return a fixed size.
|
||||||
|
func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
|
||||||
|
return 800, 600
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw draws the game screen.
|
||||||
|
// Draw is called every frame (typically 1/60[s] for 60Hz display).
|
||||||
|
func (g *Game) Draw(screen *ebiten.Image) {
|
||||||
|
dst := screen
|
||||||
|
dst.Fill(color.RGBA{0x28, 0x28, 0x28, 0xff})
|
||||||
|
|
||||||
|
// render the info text
|
||||||
|
text.Draw(dst, bsofttext, mplusNormalFont, 20, 40, color.White)
|
||||||
|
|
||||||
|
//g.DrawChase(dst)
|
||||||
|
//g.DrawLoading(dst)
|
||||||
|
g.DrawBobbles(dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Game) DrawBobbles(image *ebiten.Image) {
|
||||||
|
//identifier
|
||||||
|
text.Draw(image, bobblesInfo, mplusTinyFont, 20, 60, color.White)
|
||||||
|
|
||||||
|
//light up the bobbles
|
||||||
|
for i := 0; i < len(g.bobbles); i++ {
|
||||||
|
DrawBobble(g.bobbles[i], image)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Game) DrawChase(image *ebiten.Image) {
|
||||||
|
|
||||||
|
//identifier
|
||||||
|
text.Draw(image, sceneInfo, mplusTinyFont, 20, 60, color.White)
|
||||||
|
|
||||||
|
//draw the enemies first
|
||||||
|
for i := 0; i < len(g.enemies); i++ {
|
||||||
|
DrawCharacter(g.enemies[i], image)
|
||||||
|
}
|
||||||
|
|
||||||
|
//followed by the player character
|
||||||
|
DrawCharacter(g.player, image)
|
||||||
|
|
||||||
|
}
|
||||||
108
loader.go
Normal file
108
loader.go
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"image/color"
|
||||||
|
c "loading/character"
|
||||||
|
"loading/objects"
|
||||||
|
"log"
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/examples/resources/fonts"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/text"
|
||||||
|
"golang.org/x/image/font"
|
||||||
|
"golang.org/x/image/font/opentype"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
//tt, err := opentype.Parse(fonts.MPlus1pRegular_ttf)
|
||||||
|
tt, err := opentype.Parse(fonts.PressStart2P_ttf)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
const dpi = 72
|
||||||
|
mplusNormalFont, err = opentype.NewFace(tt, &opentype.FaceOptions{
|
||||||
|
Size: 24,
|
||||||
|
DPI: dpi,
|
||||||
|
Hinting: font.HintingVertical,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
mplusBigFont, err = opentype.NewFace(tt, &opentype.FaceOptions{
|
||||||
|
Size: 48,
|
||||||
|
DPI: dpi,
|
||||||
|
Hinting: font.HintingFull, // Use quantization to save glyph cache images.
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
mplusTinyFont, err = opentype.NewFace(tt, &opentype.FaceOptions{
|
||||||
|
Size: 10,
|
||||||
|
DPI: dpi,
|
||||||
|
Hinting: font.HintingVertical,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust the line height.
|
||||||
|
mplusBigFont = text.FaceWithLineHeight(mplusBigFont, 54)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loading() {
|
||||||
|
game := &Game{}
|
||||||
|
whiteImage.Fill(color.White)
|
||||||
|
ebiten.SetWindowSize(screenWidth, screenHeight)
|
||||||
|
ebiten.SetWindowTitle(bsofttext)
|
||||||
|
fmt.Println(bsofttext)
|
||||||
|
|
||||||
|
//loadCharacters(game)
|
||||||
|
loadBobbles(game)
|
||||||
|
|
||||||
|
// Call ebiten.RunGame to start your game loop.
|
||||||
|
if err := ebiten.RunGame(game); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadBobbles(game *Game) {
|
||||||
|
|
||||||
|
// generate bobbles
|
||||||
|
gridWidth := bubbleGridSpacing * bubbleGridCols
|
||||||
|
gridHeight := bubbleGridSpacing * bubbleGridRows
|
||||||
|
|
||||||
|
gridStartX := float32((screenWidth - gridWidth - bubbleGridSpacing) / 2)
|
||||||
|
gridStartY := float32((screenHeight - gridHeight - bubbleGridSpacing) / 2)
|
||||||
|
|
||||||
|
for i := 0; i < totalBobbles; i++ {
|
||||||
|
game.bobbles = append(game.bobbles, objects.NewBobble())
|
||||||
|
|
||||||
|
ix := float32(i%bubbleGridRows*bubbleGridSpacing + i%bubbleGridRows*bubbleGridSpacing)
|
||||||
|
iy := float32(i/bubbleGridCols*bubbleGridSpacing + i/bubbleGridCols*bubbleGridSpacing)
|
||||||
|
|
||||||
|
game.bobbles[i].Color = color.RGBA{0xFF, 0x00, 0x00, 0xFF}
|
||||||
|
game.bobbles[i].Bordercolor = color.RGBA{0x80, 0x00, 0x00, 0xFF}
|
||||||
|
game.bobbles[i].SetPose(gridStartX+ix, gridStartY+iy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadCharacters(game *Game) {
|
||||||
|
// generate player character
|
||||||
|
game.player = c.NewCharacter()
|
||||||
|
game.player.SetPose(float32(rand.Intn(screenWidth)), float32(rand.Intn(screenHeight)))
|
||||||
|
|
||||||
|
// generate enemies
|
||||||
|
for i := 0; i < enemyCount; i++ {
|
||||||
|
//create new enemy, slip 'em in
|
||||||
|
game.enemies = append(game.enemies, c.NewCharacter())
|
||||||
|
|
||||||
|
//set random position based on screen dimensions
|
||||||
|
game.enemies[i].SetPose(float32(rand.Intn(screenWidth)), float32(rand.Intn(screenHeight)))
|
||||||
|
|
||||||
|
//distinguish them from the player character
|
||||||
|
game.enemies[i].Color = color.RGBA{0xFF, 0x00, 0x00, 0xFF}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
loading.go
Normal file
23
loading.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "loading/scenes"
|
||||||
|
|
||||||
|
type Loading struct {
|
||||||
|
//Manager scenes.SceneManager
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Loading) Update() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Loading) Draw() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Loading) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
|
||||||
|
return 800, 600
|
||||||
|
}
|
||||||
33
main.go
33
main.go
@@ -1,5 +1,38 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
"golang.org/x/image/font"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 600
|
||||||
|
bsofttext = `bsoft games`
|
||||||
|
versionInfo = `loading screen MKI`
|
||||||
|
sceneInfo = `scene a`
|
||||||
|
bobblesInfo = `bobbles`
|
||||||
|
enemyCount = 12
|
||||||
|
totalBobbles = 9
|
||||||
|
bubbleGridRows = 3
|
||||||
|
bubbleGridCols = 3
|
||||||
|
bubbleGridSpacing = 40
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
mplusNormalFont font.Face
|
||||||
|
mplusBigFont font.Face
|
||||||
|
mplusTinyFont font.Face
|
||||||
|
tileWidth float32 = 20
|
||||||
|
tileHeight float32 = 20
|
||||||
|
numTiles int = 5
|
||||||
|
maxPercent float64 = 100
|
||||||
|
whiteImage = ebiten.NewImage(3, 3)
|
||||||
|
whiteSubImage = whiteImage.SubImage(image.Rect(1, 1, 2, 2)).(*ebiten.Image)
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
loading()
|
loading()
|
||||||
}
|
}
|
||||||
|
|||||||
40
objects/bobble.go
Normal file
40
objects/bobble.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package objects
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
p "loading/point"
|
||||||
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultRadius = 20
|
||||||
|
)
|
||||||
|
|
||||||
|
type Bobble struct {
|
||||||
|
Radius float32
|
||||||
|
Pose p.Point
|
||||||
|
Id string
|
||||||
|
Color color.RGBA
|
||||||
|
Bordercolor color.RGBA
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBobble() Bobble {
|
||||||
|
//default bobble values, with white center and black border
|
||||||
|
return Bobble{
|
||||||
|
Radius: defaultRadius,
|
||||||
|
Pose: p.Point{X: 0, Y: 0},
|
||||||
|
Color: color.RGBA{0xFF, 0xFF, 0xFF, 0xFF},
|
||||||
|
Bordercolor: color.RGBA{0x00, 0x00, 0x00, 0xFF},
|
||||||
|
Id: "ID-" + strconv.Itoa(rand.Intn(100)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDefaultRadius() float32 {
|
||||||
|
return float32(defaultRadius)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Bobble) SetPose(x float32, y float32) {
|
||||||
|
b.Pose.X = x
|
||||||
|
b.Pose.Y = y
|
||||||
|
}
|
||||||
23
scenes/menu.go
Normal file
23
scenes/menu.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package scenes
|
||||||
|
|
||||||
|
import "github.com/hajimehoshi/ebiten/v2"
|
||||||
|
|
||||||
|
type Menu struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateNewMenu() Menu {
|
||||||
|
return Menu{}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Menu) Draw(screen *ebiten.Image) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Menu) Update() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Menu) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
|
||||||
|
return 800, 600
|
||||||
|
}
|
||||||
9
scenes/scene.go
Normal file
9
scenes/scene.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package scenes
|
||||||
|
|
||||||
|
import "github.com/hajimehoshi/ebiten/v2"
|
||||||
|
|
||||||
|
type Scene interface {
|
||||||
|
Update() error
|
||||||
|
Draw(screen *ebiten.Image)
|
||||||
|
Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int)
|
||||||
|
}
|
||||||
1
scenes/splash.go
Normal file
1
scenes/splash.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package scenes
|
||||||
126
updater.go
Normal file
126
updater.go
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"loading/objects"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Update proceeds the game state.
|
||||||
|
// Update is called every tick (1/60 [s] by default).
|
||||||
|
func (g *Game) Update() error {
|
||||||
|
// Write your game's logical update.
|
||||||
|
g.counter++
|
||||||
|
|
||||||
|
g.UpdatePlayer()
|
||||||
|
//g.UpdateEnemies()
|
||||||
|
g.UpdateBobbles()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Game) UpdateBobbles() {
|
||||||
|
|
||||||
|
for i := 0; i < len(g.bobbles); i++ {
|
||||||
|
bobby := &g.bobbles[i]
|
||||||
|
bobby.Radius = objects.GetDefaultRadius() + float32(10*math.Sin(float64(g.counter)/(math.Pi*4)))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Game) UpdatePlayer() {
|
||||||
|
|
||||||
|
//update player angle based on mouse position
|
||||||
|
mx, my := ebiten.CursorPosition()
|
||||||
|
playerAngle := float32(math.Atan2(float64(float32(my)-g.player.Pose.Y), float64(float32(mx)-g.player.Pose.X)))
|
||||||
|
g.player.Angle = playerAngle
|
||||||
|
|
||||||
|
//update position based on wasd input
|
||||||
|
g.keys = inpututil.AppendPressedKeys(g.keys[:0])
|
||||||
|
step := float32(10)
|
||||||
|
for _, k := range g.keys {
|
||||||
|
switch k {
|
||||||
|
case ebiten.KeyW:
|
||||||
|
g.player.Pose.Y = g.player.Pose.Y - step
|
||||||
|
case ebiten.KeyA:
|
||||||
|
g.player.Pose.X = g.player.Pose.X - step
|
||||||
|
case ebiten.KeyS:
|
||||||
|
g.player.Pose.Y = g.player.Pose.Y + step
|
||||||
|
case ebiten.KeyD:
|
||||||
|
g.player.Pose.X = g.player.Pose.X + step
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Game) UpdateEnemies() {
|
||||||
|
/*
|
||||||
|
we're going to rotate the enemies so they slowly face the player, to do this we'll find the angle delta
|
||||||
|
between the player and the enemy via atan2, then add approximately one quarter of this value to the
|
||||||
|
current enemy angle
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
for _, e := range g.enemies {
|
||||||
|
//diff := float32(math.Atan2(float64(g.player.Pose.Y-e.Pose.Y), float64(g.player.Pose.X-e.Pose.X)))
|
||||||
|
e.Angle = e.Angle + math.Pi/4
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
for i := 0; i < len(g.enemies); i++ {
|
||||||
|
enemy := &g.enemies[i]
|
||||||
|
|
||||||
|
//find distancees between enemy and player
|
||||||
|
dx := float64(g.player.Pose.X - enemy.Pose.X)
|
||||||
|
dy := float64(g.player.Pose.Y - enemy.Pose.Y)
|
||||||
|
|
||||||
|
//current sign
|
||||||
|
currentSign := enemy.DeltaAngle / float32(math.Abs(float64(enemy.DeltaAngle)))
|
||||||
|
|
||||||
|
targetAngle := float32(math.Atan2(dy, dx)) + math.Pi*2
|
||||||
|
|
||||||
|
//_, absTargetAngle := math.Modf(float64(targetAngle))
|
||||||
|
|
||||||
|
phi := float32(math.Mod(float64(targetAngle-enemy.Angle), float64(2*math.Pi)))
|
||||||
|
if phi > math.Pi {
|
||||||
|
enemy.DeltaAngle = math.Pi - phi
|
||||||
|
} else {
|
||||||
|
enemy.DeltaAngle = phi
|
||||||
|
}
|
||||||
|
|
||||||
|
//enemy.DeltaAngle = float32(math.Min(2*math.Pi-math.Abs(float64(enemy.Angle-targetAngle)), math.Abs(float64(enemy.Angle-targetAngle))))
|
||||||
|
|
||||||
|
enemy.Angle = enemy.Angle + enemy.DeltaAngle/16
|
||||||
|
|
||||||
|
enemy.SignFlip = currentSign
|
||||||
|
|
||||||
|
for j := 0; j < len(g.enemies); j++ {
|
||||||
|
if j == i {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
xdist := (g.enemies[j].Pose.X - enemy.Pose.X)
|
||||||
|
ydist := (g.enemies[j].Pose.Y - enemy.Pose.Y)
|
||||||
|
|
||||||
|
//quick boundary check before we get to the algebra
|
||||||
|
if xdist > enemy.Buffer || ydist > enemy.Buffer {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
dist := float32(math.Sqrt(float64(xdist*xdist + ydist*ydist)))
|
||||||
|
if dist < enemy.Buffer {
|
||||||
|
enemy.Pose.X = enemy.Pose.X + dist*float32(math.Cos(float64(targetAngle)))
|
||||||
|
enemy.Pose.Y = enemy.Pose.Y + dist*float32(math.Sin(float64(targetAngle)))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
enemy.Pose.X = enemy.Pose.X + float32(dx)/360
|
||||||
|
enemy.Pose.Y = enemy.Pose.Y + float32(dy)/360
|
||||||
|
|
||||||
|
//enemy.Angle = enemy.Angle + enemy.DeltaAngle/(math.Pi/4)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user