From c234616fdfaeb6c60c758bcefae05b9d4cbd23d7 Mon Sep 17 00:00:00 2001 From: iegod Date: Tue, 5 Nov 2024 06:28:08 -0500 Subject: [PATCH] First commit. --- coordinates.go | 6 + explosion.go | 40 +++++++ fly-eye.png | Bin 0 -> 2035 bytes fly-eye2.png | Bin 0 -> 3518 bytes fly-eye3.png | Bin 0 -> 682 bytes game.go | 308 +++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 29 +++++ mover.go | 168 +++++++++++++++++++++++++++ projectile.go | 31 +++++ 9 files changed, 582 insertions(+) create mode 100644 coordinates.go create mode 100644 explosion.go create mode 100644 fly-eye.png create mode 100644 fly-eye2.png create mode 100644 fly-eye3.png create mode 100644 game.go create mode 100644 main.go create mode 100644 mover.go create mode 100644 projectile.go diff --git a/coordinates.go b/coordinates.go new file mode 100644 index 0000000..2265753 --- /dev/null +++ b/coordinates.go @@ -0,0 +1,6 @@ +package main + +type Coordinates struct { + X float64 + Y float64 +} diff --git a/explosion.go b/explosion.go new file mode 100644 index 0000000..6d9f101 --- /dev/null +++ b/explosion.go @@ -0,0 +1,40 @@ +package main + +type Explosion struct { + Radius float64 + Origin Coordinates + cycle int + Active bool +} + +func NewExplosion() *Explosion { + return &Explosion{ + cycle: 1, + Active: false, + } +} + +func (e *Explosion) Draw() { + +} + +func (e *Explosion) Update() { + + if e.Active { + e.Radius = float64(e.cycle) / 0.15 + e.cycle++ + } + +} + +func (e *Explosion) SetOrigin(origin Coordinates) { + e.Origin = origin +} + +func (e *Explosion) ToggleActivate() { + e.Active = !e.Active +} + +func (e *Explosion) Reset() { + e.cycle = 1 +} diff --git a/fly-eye.png b/fly-eye.png new file mode 100644 index 0000000000000000000000000000000000000000..ab706ab723a8ee5f3f2ef623645263c8cd19c64f GIT binary patch literal 2035 zcmVVdNhOJLF)3ItbAY@{@m(C0mvy*(vV>21okIdB5N9 z``+)ppCo``7=~dOhG7_nVHk#C7=~dOhG7_nVHk#Cm@k1?uMKb`C*}1SZ5&@C*|#?K zGxFYsuE`_j-%|M)<%zpImNo|bTy%trzAo)!S(^)eK%@L$A{SLa*FV420YI}I*W?jg z|NK_JDE)|P{C)l45h^->P@^;b4**z~_5mOgCm;d2(XRq(XSbb;+K-^^_O$|hiFg%I zKSol!?Na%;sf`#-33+cr@7F%K5%l<9>gM8{ly@~+-rLZxe|~Fz2g5lZ}Biv9qQ zN+mmra_xSba1xOH6;gEX!3~b#Mu8=m^F-BMf7G-SKb;RsMBPBTX=Sr$V<+S9 z1>X)Jt^%DFV1$$Lt)joGRsxAsU1iV)HBst05DSsKTs#i6L(`ykrQZ$ zKd9(0;x~Vm%Ey?>oH(vlqU~XC+lux-KKl^>uv&SJ^Mw^09DFd_{dM}4c~0yXIRFsu zmbM*A4aM{`n|uHOc>L>a09FTXWk2DTIkfASuU#Njt;Fn6*{O1GSItvrNc`*4eq`cr zg*_VC(c}^AD8u+Z``WbGZo8BC!`caQT5-q5M)6(gPg6W%+rb<6o7zXYOJzqC_0V)0 zS9VLT_5(2O7d7a&*7BVKscI#5n*C&^5S`}GVh#$pr#wN5KUXiz(S9XS0A(Y7=&A;=7gr+fs(LYnAn}JKd=c?3HrePW2NmOjT#GT_5WuylHMIH@+It(^)Vx+BlYjG|&Z_ZyLW$ z-Tu|G;RL6X>3Yj809Nrk+24&5gjNK%S`myC0@y0P#_d(L~F-oEkYTu?ZC)iPjk;%+LY2gG$ z!PpT0+2SS!!!oJ`%i3Hlh2}f@nW|y`!NCWNjg4B)(Xm$IR}uxF+WAe?t{#POD!%Ag zCpTCcOI|dH5sqpQ%9BOGyXBxFr;}-OQ$SqFltcl`+FUG5@sl8G#ggF!)meNTyop=G zhn5eebE5cri74drg%#{5!{+fvmyK0P{LnFC`y_7ZgQ`}1k8@WmKzZVBjGo7!9J*FN zS1Xn*H)9COp^4MUv?YIz3egGTi}Skn^p2+-l%NT?vTO94CP2lU(LfE=e3Kb%9C!t6 zp@bbJ4O}iXj>AYf9$hYA`y_4#rSo0)RV%7GfKb&+EM6?>J4)INM)oK!Zjd;MpT3LN zdEM6ST6p9De)e%`2O#QgPCGd%uXl1kgNo)WyCqXZQNOPMG+r748oBl9WEw-$&MPX} zOyf<(x?ONl+!LS&8_AY7UbwhkcDoRHXZ@hVR0DJ!5i}$X{j&8S#yLm-7lE-wt3W)KC=y-k{ zpjYA-ZSnj6qj*1^xd5b6Nj)d!buX`t=A^tXexk6i9e(ZbTl^C2HD3_+twlFPvGp?Y zcZ=6&{#()2onWTF=rqN=$l?b$?O_;(VHk#C7=~dOhG7_nVHk#C7=~e-_#dxJ3bNqf R%oG3s002ovPDHLkV1m{3;Sm4; literal 0 HcmV?d00001 diff --git a/fly-eye2.png b/fly-eye2.png new file mode 100644 index 0000000000000000000000000000000000000000..2b4d6c7237a2d595ce611a0b42f41518b5ddd92c GIT binary patch literal 3518 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 ju z(N)7R3`HFdOLUh`!Uzo15txKsGDi5J2a{9Bb}ZXcbnkCzEZ{xqIcbv+006)z%j^OG z_H6gC9lgGM%jp&az!YMUO9}eSG2bN?{#V4;?a;k@mXB4H33J_Nk7PHJzR4W) zQS~p`Tlg_OOi(5K&s+Xy9&7TY9wJKBKXW6QJDz4Uz0EEFuE}-}n-=jOPRptT4eb6g zQj_4Y`%f01e$grgjnxk3AV$>z{qC!IHR3@OvF#g7{mRDZY}mEt-S~1g=Rs zRa^9lDTxuu=p)qmtD{Wx_dHv_hR%Al!L>L6d_|x}@wc3bYI?6CK^=)-Q=O#{fxtB{ zCxGVo6T)A8sje#dIiDGyQ0@IWrB*CPofN(zP$e3^tDsS2FR!R7tg{3n5V*$21gPBn zYUunh1}4A`#D5O$`<4_K09=Csz%@Sh00j_ze8L0(*I)o}&GijXa0-<8 zE5X`3;_|UBM>SggXFRc9za^Le%CUNZ$qE<%T;t= 0.15 || inpx <= -0.15 { + g.mover.Pos.X += ebiten.GamepadAxisValue(0, 0) * 5 + } + + if inpy >= 0.15 || inpy <= -0.15 { + g.mover.Pos.Y += ebiten.GamepadAxisValue(0, 1) * 5 + } + + if !g.initialized { + g.Initialize() + + g.projectiles = make(map[int]*Projectile) + g.initialized = true + } else { + + if len(g.gamepadIDs) > 0 { + xaxis := ebiten.StandardGamepadAxisValue(0, ebiten.StandardGamepadAxisRightStickHorizontal) + yaxis := ebiten.StandardGamepadAxisValue(0, ebiten.StandardGamepadAxisRightStickVertical) + + maxButton := ebiten.GamepadButton(ebiten.GamepadButtonCount(0)) + for b := ebiten.GamepadButton(0); b < maxButton; b++ { + if ebiten.IsGamepadButtonPressed(0, ebiten.GamepadButton7) { + if !g.explosion.Active { + g.explosion.SetOrigin(g.mover.Pos) + g.explosion.Reset() + g.explosion.ToggleActivate() + } + } + } + + if yaxis <= 0.09 && yaxis >= -0.09 { + yaxis = 0 + } + if xaxis <= 0.09 && xaxis >= -0.09 { + xaxis = 0 + } + + inputangle := math.Atan2(yaxis, xaxis) + g.mover.SetAngle(inputangle) + } + /* + for id := range g.gamepadIDs { + xaxis := ebiten.StandardGamepadAxisValue(id, ebiten.StandardGamepadAxisRightStickHorizontal) + yaxis := ebiten.StandardGamepadAxisValue(id, ebiten.StandardGamepadAxisRightStickVertical) + + inputangle := math.Atan2(yaxis, xaxis) + g.mover.SetAngle(inputangle) + } + */ + + g.mover.Update() + g.explosion.Update() + + for _, target := range g.targets { + + if !target.Hit { + dx := g.mover.Pos.X - target.Pos.X + dy := g.mover.Pos.Y - target.Pos.Y + + //dist := math.Sqrt(dx*dx + dy + dy) + angle := math.Atan2(dy, dx) + + maxspeed := 3. + target.Pos.X += maxspeed * math.Cos(angle) + target.Pos.Y += maxspeed * math.Sin(angle) + } + + target.Update() + } + + for k, p := range g.projectiles { + + //for i := 0; i < len(g.projectiles); i++ { + // g.projectiles[i].Update() + p.Update() + + //if g.projectiles[i].Pos.X < 5 || g.projectiles[i].Pos.X > 635 || g.projectiles[i].Pos.Y < 5 || g.projectiles[i].Pos.Y > 475 { + if p.Pos.X < 5 || p.Pos.X > 635 || p.Pos.Y < 5 || p.Pos.Y > 475 { + p.Velocity = 0 + delete(g.projectiles, k) + } + + //compute collisions + for _, target := range g.targets { + //first, boundary check + if p.Pos.X >= target.Pos.X-MOVER_WIDTH/2 && p.Pos.X <= target.Pos.X+MOVER_WIDTH/2 && p.Pos.Y >= target.Pos.Y-MOVER_HEIGHT/2 && p.Pos.Y <= target.Pos.Y+MOVER_HEIGHT/2 && target.Action == MoverActionDamaged { + fmt.Println("potential collision") + + g.collisionMask.Clear() + g.collisionMask.DrawImage(g.projectileMask, nil) + + op := &ebiten.DrawImageOptions{} + op.GeoM.Reset() + op.Blend = ebiten.BlendSourceIn + op.GeoM.Translate(target.Pos.X-MOVER_WIDTH/2, target.Pos.Y-MOVER_HEIGHT/2) + g.collisionMask.DrawImage(target.Sprite, op) + + //var pixels []byte = make([]byte, MOVER_WIDTH*MOVER_HEIGHT*4) + var pixels []byte = make([]byte, screenWidth*screenHeight*4) + g.collisionMask.ReadPixels(pixels) + for i := 0; i < len(pixels); i = i + 4 { + if pixels[i+3] != 0 { + fmt.Println("pixel collision") + delete(g.projectiles, k) + //target.ToggleColor() + target.SetHit() + //target.SetOrigin(Coordinates{X: rand.Float64() * 640, Y: rand.Float64() * 480}) + target.Hit = true + break + } + } + } + } + } + + //append new projectiles + if g.counter%14 == 0 { + //g.projectiles = append(g.projectiles, NewProjectile(Coordinates{X: g.mover.Pos.X, Y: g.mover.Pos.Y}, g.mover.Angle, 5.)) + //g.projectiles = append(g.projectiles, NewProjectile(Coordinates{X: g.mover.Pos.X, Y: g.mover.Pos.Y}, g.mover.Angle+math.Pi, 5.)) + + g.projectiles[g.counter] = NewProjectile(Coordinates{X: g.mover.Pos.X, Y: g.mover.Pos.Y}, g.mover.Angle, 5.) + g.projectiles[g.counter+1] = NewProjectile(Coordinates{X: g.mover.Pos.X, Y: g.mover.Pos.Y}, g.mover.Angle+math.Pi, 5.) + } + + //add new target with increasing frequency + + f := 40000 / (g.counter + 1) + + if g.counter%f == 0 { + g.targets = append(g.targets, NewMover()) + g.targets[len(g.targets)-1].SetOrigin(Coordinates{X: rand.Float64() * 640, Y: rand.Float64() * 480}) + } + + //handle explosion updates + if g.explosion.Active { + if g.explosion.Radius > math.Sqrt(640*640+480*480) { + g.explosion.ToggleActivate() + g.explosion.Reset() + } + + //check collisions + for _, target := range g.targets { + dx := target.Pos.X - g.mover.Pos.X + dy := target.Pos.Y - g.mover.Pos.Y + r := math.Sqrt(dx*dx + dy*dy) + + if r >= g.explosion.Radius-5 && r <= g.explosion.Radius+5 && target.Action <= MoverActionDefault { + //target.ToggleColor() + target.SetHit() + } + } + } + + g.counter++ + } + + g.CleanupTargets() + + return nil +} + +func (g *Game) Draw(screen *ebiten.Image) { + + g.mover.Draw() + + op := &ebiten.DrawImageOptions{} + + /* + dx := 40 * math.Cos(float64(g.counter)/16) + dy := 40 * math.Sin(float64(g.counter)/16) + a := float64(g.counter) / (math.Pi * 2) + */ + op.GeoM.Translate(-MOVER_WIDTH/2, -MOVER_HEIGHT/2) + op.GeoM.Rotate(g.mover.Angle) + op.GeoM.Translate(g.mover.Pos.X, g.mover.Pos.Y) + screen.DrawImage(g.mover.Sprite, op) + + for _, target := range g.targets { + target.Draw() + + op.GeoM.Reset() + op.GeoM.Translate(-MOVER_WIDTH/2, -MOVER_HEIGHT/2) + op.GeoM.Rotate(target.Angle) + op.GeoM.Translate(target.Pos.X, target.Pos.Y) + screen.DrawImage(target.Sprite, op) + } + + g.projectileMask.Clear() + + //ebitenutil.DrawCircle() + for _, p := range g.projectiles { + //vector.DrawFilledCircle(screen, float32(p.Pos.X), float32(p.Pos.Y), 3, color.White, true) + vector.DrawFilledCircle(g.projectileMask, float32(p.Pos.X), float32(p.Pos.Y), 3, color.White, true) + } + + screen.DrawImage(g.projectileMask, nil) + + vector.StrokeCircle(screen, float32(g.explosion.Origin.X), float32(g.explosion.Origin.Y), float32(g.explosion.Radius), 3, color.White, true) + + /*for _, gamepad ebiten.StandardGamepadAxisValue(id, ebiten.StandardGamepadAxisRightStickHorizontal), + ebiten.StandardGamepadAxisValue(id, ebiten.StandardGamepadAxisRightStickVertical))*/ + +} + +func (g *Game) Layout(width, height int) (int, int) { + return screenWidth, screenHeight +} + +func (g *Game) CleanupTargets() { + // remove dead targets by 1) iterating over all targets + i := 0 + for _, target := range g.targets { + //moving valid targets to the front of the slice + if target.Action < MoverActionDead { + g.targets[i] = target + i++ + } + } + //then culling the last elements of the slice + if len(g.targets)-i > 0 { + fmt.Printf("Removing %d elements\n", len(g.targets)-i) + } + for j := i; j < len(g.targets); j++ { + g.targets[j] = nil + } + g.targets = g.targets[:i] +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..72e262c --- /dev/null +++ b/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "fmt" + "log" + + "github.com/hajimehoshi/ebiten/v2" +) + +const ( + screenWidth = 640 + screenHeight = 480 +) + +func main() { + ver := "Mover Test v0.05" + + fmt.Println(ver) + + moverGame := &Game{} + + ebiten.SetWindowSize(screenWidth*1.5, screenHeight*1.5) + ebiten.SetWindowTitle(ver) + + if err := ebiten.RunGame(moverGame); err != nil { + log.Fatal(err) + } + +} diff --git a/mover.go b/mover.go new file mode 100644 index 0000000..7f637b7 --- /dev/null +++ b/mover.go @@ -0,0 +1,168 @@ +package main + +import ( + "bytes" + "image" + "log" + + _ "embed" + "image/color" + _ "image/png" + + "github.com/hajimehoshi/ebiten/v2" +) + +var ( + flyeyeImage *ebiten.Image + flyeyeImage2 *ebiten.Image + flyeyeImage3 *ebiten.Image + + //go:embed fly-eye.png + flyeye_img []byte + //go:embed fly-eye2.png + flyeye_img2 []byte + //go:embed fly-eye3.png + flyeye_img3 []byte +) + +const ( + MoverActionDefault = iota + MoverActionDamaged + MoverActionDying + MoverActionExploding + MoverActionDead + MoverActionMax +) + +type MoverAction uint + +func init() { + img, _, err := image.Decode(bytes.NewReader(flyeye_img)) + if err != nil { + log.Fatal(err) + } + flyeyeImage = ebiten.NewImageFromImage(img) + + img, _, err = image.Decode(bytes.NewReader(flyeye_img2)) + if err != nil { + log.Fatal(err) + } + flyeyeImage2 = ebiten.NewImageFromImage(img) + + img, _, err = image.Decode(bytes.NewReader(flyeye_img3)) + if err != nil { + log.Fatal(err) + } + flyeyeImage3 = ebiten.NewImageFromImage(img) +} + +type Mover struct { + Sprite *ebiten.Image + Maks *ebiten.Image + MaksDest *ebiten.Image + Angle float64 + Pos Coordinates + Origin Coordinates + Action MoverAction + cycles int + rotating bool + Toggled bool + Hit bool + dyingcount int +} + +func NewMover() *Mover { + m := &Mover{ + Sprite: ebiten.NewImage(48, 48), + Maks: ebiten.NewImage(48, 48), + MaksDest: ebiten.NewImage(48, 48), + Action: MoverActionDefault, + cycles: 4, + Angle: 0, + rotating: false, + Toggled: false, + dyingcount: 0, + } + + m.Maks.Fill(color.White) + return m +} + +func (m *Mover) ToggleRotate() { + m.rotating = !m.rotating +} + +func (m *Mover) SetAngle(a float64) { + m.Angle = a +} + +func (m *Mover) SetOrigin(coords Coordinates) { + m.Origin = coords + m.Pos = coords +} + +func (m *Mover) Draw() { + m.Sprite.Clear() + m.MaksDest.Clear() + + idx := (m.cycles / 8) % 4 + + y0 := 0 + y1 := 48 + x0 := 48 * idx + x1 := x0 + 48 + + switch m.Action { + case MoverActionDefault: + m.Sprite.DrawImage(flyeyeImage.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil) + case MoverActionDamaged: + m.Sprite.DrawImage(flyeyeImage2.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil) + case MoverActionDying: + m.dyingcount++ + if (m.cycles/5)%2 == 0 { + + m.MaksDest.DrawImage(flyeyeImage2.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil) + op := &ebiten.DrawImageOptions{} + op.GeoM.Reset() + op.Blend = ebiten.BlendSourceAtop + m.MaksDest.DrawImage(m.Maks, op) + m.Sprite.DrawImage(m.MaksDest, nil) + + } else { + m.Sprite.DrawImage(flyeyeImage2.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil) + } + if m.dyingcount > 60 { + m.cycles = 0 + m.SetHit() + } + case MoverActionExploding: + m.Sprite.DrawImage(flyeyeImage3.SubImage(image.Rect(x0, y0, x1, y1)).(*ebiten.Image), nil) + if idx == 3 { + m.SetHit() + } + default: + } +} + +func (m *Mover) Update() { + /* + dx := 0. //40 * math.Cos(float64(m.cycles)/16) + dy := 0. //40 * math.Sin(float64(m.cycles)/16) + + m.Pos = Coordinates{X: m.Origin.X + dx, Y: m.Origin.Y + dy} + */ + /* + if m.rotating { + m.Angle = float64(m.cycles) / (math.Pi * 2) + } + */ + m.cycles++ +} + +func (m *Mover) SetHit() { + m.Action++ // = (m.Action + 1) % MoverActionMax +} + +func (m *Mover) ToggleColor() { + m.Toggled = !m.Toggled +} diff --git a/projectile.go b/projectile.go new file mode 100644 index 0000000..4e526d4 --- /dev/null +++ b/projectile.go @@ -0,0 +1,31 @@ +package main + +import "math" + +type Projectile struct { + Pos Coordinates + Velocity float64 + a float64 +} + +func NewProjectile(origin Coordinates, angle, velocity float64) *Projectile { + return &Projectile{ + Velocity: velocity, + a: angle, + Pos: origin, + } +} + +func (p *Projectile) Update() { + + dx := p.Velocity * math.Cos(p.a) + dy := p.Velocity * math.Sin(p.a) + + p.Pos.X += dx + p.Pos.Y += dy + +} + +func (p *Projectile) Draw() { + +}