summaryrefslogtreecommitdiff
path: root/objects.go
diff options
context:
space:
mode:
Diffstat (limited to 'objects.go')
-rw-r--r--objects.go198
1 files changed, 198 insertions, 0 deletions
diff --git a/objects.go b/objects.go
new file mode 100644
index 0000000..9eb4167
--- /dev/null
+++ b/objects.go
@@ -0,0 +1,198 @@
+package main
+
+import (
+ "log"
+ "image"
+ "github.com/hajimehoshi/ebiten/v2"
+ "github.com/hajimehoshi/ebiten/v2/ebitenutil"
+)
+
+const (
+ SPRING_FORCE = 8
+)
+
+type GameObject struct {
+ startx, starty float32
+ x, y float32
+ vx, vy float32
+
+ offsetX, offsetY int
+
+ friction float32
+ resistance float32
+ image *ebiten.Image
+ onGround bool
+ onCollideX func(this, other *GameObject) bool
+ onCollideY func(this, other *GameObject) bool
+}
+
+
+type Player struct {
+ GameObject
+}
+
+func (o * GameObject) Update(tilemap Tilemap, others []*GameObject) {
+ o.vy += gravity
+
+ o.vx *= o.resistance
+ o.vy *= o.resistance
+
+ o.x += o.vx
+ if o.HasCollision(tilemap, others, true) {
+ o.x -= o.vx
+ o.vx = 0
+ }
+
+ o.y += o.vy
+ if o.HasCollision(tilemap, others, false) {
+ o.onGround = true;
+ o.vx *= o.friction
+
+ o.y -= o.vy
+ o.vy = 0
+ } else {
+ o.onGround = false;
+ }
+}
+
+func (o * GameObject) HasCollision(tilemap Tilemap, others []*GameObject, x bool) bool {
+ if tilemap.CollideObject(o) {
+ return true
+ }
+ for _, obj := range others {
+ if obj.Collide(o) {
+ var f func(this, other *GameObject) bool
+ if x {
+ f = obj.onCollideX
+ } else {
+ f = obj.onCollideY
+ }
+
+ if f == nil{
+ return true
+ }
+ return f(obj, o)
+ }
+ }
+ return false
+}
+
+func (o * GameObject) Draw(screen *ebiten.Image, tilemap Tilemap) {
+ op := &ebiten.DrawImageOptions{}
+ op.GeoM.Translate(float64(o.x), float64(o.y))
+ screen.DrawImage(o.image, op)
+}
+
+func (object * GameObject) Collide(other *GameObject) bool {
+ maxX1 := object.x + float32(object.image.Bounds().Dx())
+ maxY1 := object.y + float32(object.image.Bounds().Dy())
+ minX1 := object.x
+ minY1 := object.y
+
+ maxX2 := other.x + float32(other.image.Bounds().Dx())
+ maxY2 := other.y + float32(other.image.Bounds().Dy())
+ minX2 := other.x
+ minY2 := other.y
+
+ if (minX1 == minX2 && maxX1 == maxX2 && minY1 == minY2 && maxY1 == maxY2) {
+ return false
+ }
+
+ return ! ( minX2 >= maxX1 || maxX2 <= minX1 || minY2 >= maxY1 || maxY2 <= minY1)
+}
+
+func (object * GameObject) ToRect() image.Rectangle {
+ width := object.image.Bounds().Dx()
+ height := object.image.Bounds().Dy()
+ x := int(object.x)
+ y := int(object.y)
+ return image.Rect(x, y, x+width, y+height)
+}
+
+func OnCollideGeneric(this, other *GameObject) bool {
+ return true
+}
+
+func NewObject(x, y float32) *GameObject{
+ obj := &GameObject{
+ startx: x,
+ starty: y,
+ }
+
+ obj.friction = friction
+ obj.resistance = airResistance
+ obj.x = obj.startx
+ obj.y = obj.starty
+ return obj
+}
+
+func NewPlayer(x, y float32) *GameObject{
+ player := NewObject(x, y)
+
+ playerImage, _, err := ebitenutil.NewImageFromFile("Assets/Main Characters/Ninja Frog/Idle (32x32).png")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ player.image = playerImage.SubImage(image.Rect(4, 8, 27, 32)).(*ebiten.Image)
+
+ return player
+}
+
+func NewExit(x, y float32) *GameObject{
+ exit := NewObject(x, y)
+
+ exit.image = tilesImage.SubImage(image.Rect(0, 16, 32, 48)).(*ebiten.Image)
+
+ return exit
+}
+
+func NewBox(x, y float32) *GameObject{
+ box := NewObject(x, y)
+
+ box.image = tilesImage.SubImage(image.Rect(160, 0, 176, 16)).(*ebiten.Image)
+
+ return box
+}
+
+func NewSpring(x, y float32) *GameObject{
+ spring := NewObject(x, y)
+
+ spring.image = tilesImage.SubImage(image.Rect(176, 0, 192, 16)).(*ebiten.Image)
+ spring.onCollideY = OnCollideSpring
+
+ return spring
+}
+
+func NewSpike(x, y float32) *GameObject{
+ spike := NewObject(x, y)
+
+ spike.offsetY = 3
+ spike.image = tilesImage.SubImage(image.Rect(192, 3, 208, 16)).(*ebiten.Image)
+ spike.onCollideY = OnCollideSpike
+
+ return spike
+}
+
+func NewLeftSpike(x, y float32) *GameObject{
+ spike := NewObject(x, y)
+
+ spike.offsetX = 3
+ spike.image = tilesImage.SubImage(image.Rect(195, 16, 208, 32)).(*ebiten.Image)
+ spike.onCollideX = OnCollideSpike
+
+ return spike
+}
+
+func OnCollideSpring(this, other *GameObject) bool {
+ other.vy -= SPRING_FORCE
+ other.onGround = true
+ return false
+}
+
+func OnCollideSpike(this, other *GameObject) bool {
+ other.x = other.startx
+ other.y = other.starty
+ return true
+}
+