Skip to content

Commit

Permalink
Finished basic targeting functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
darkfrog26 committed Aug 13, 2023
1 parent 5a3bd25 commit a95446e
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 28 deletions.
41 changes: 38 additions & 3 deletions core/src/main/scala/org/sgine/component/Component.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package org.sgine.component
import org.sgine.Screen
import reactify._

trait Component {
trait Component { c =>
private val _initialized: Var[Boolean] = Var(false)
protected[sgine] val _parent: Var[Option[Component]] = Var(None)

Expand Down Expand Up @@ -33,8 +33,43 @@ trait Component {
*/
val parent: Val[Option[Component]] = _parent

def screenX: Double = parent().map(_.screenX).getOrElse(0.0)
def screenY: Double = parent().map(_.screenY).getOrElse(0.0)
protected def screenX: Double = parent().map(_.screenX).getOrElse(0.0)
protected def screenY: Double = parent().map(_.screenY).getOrElse(0.0)

/**
* Access to global coordinates within the screen
*/
object global {
def x: Double = screenX
def y: Double = screenY

protected def w: Double = c match {
case d: DimensionedSupport => d.width()
case _ => 0.0
}
protected def h: Double = c match {
case d: DimensionedSupport => d.height()
case _ => 0.0
}

def left: Double = x
def center: Double = x + (w / 2.0)
def right: Double = x + w

def top: Double = y
def middle: Double = y + (h / 2.0)
def bottom: Double = y + h

/**
* Converts a global x value to local coordinates
*/
def localizeX(x: Double): Double = x - screenX

/**
* Converts a global y value to local coordinates
*/
def localizeY(y: Double): Double = y - screenY
}

val screenOption: Val[Option[Screen]] = Val(parent() match {
case Some(s: Screen) => Some(s)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ trait DimensionedSupport extends Component {

def depth: Var[Int] = z

override def screenX: Double = super.screenX + x()
override def screenY: Double = super.screenY + y()
override protected def screenX: Double = super.screenX + x()
override protected def screenY: Double = super.screenY + y()

override protected def init(): Unit = {
super.init()
Expand Down
16 changes: 4 additions & 12 deletions core/src/main/scala/org/sgine/util/MathUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,11 @@ object MathUtils {
math.sqrt(math.pow(x2 - x1, 2.0) + math.pow(y2 - y1, 2.0))

def distanceFromCenter(c1: Component, c2: Component): Double = {
val (c1Center, c1Middle) = c1 match {
case ds: DimensionedSupport => ds.center() -> ds.middle()
case _ => 0.0 -> 0.0
}
val (c2Center, c2Middle) = c2 match {
case ds: DimensionedSupport => ds.center() -> ds.middle()
case _ => 0.0 -> 0.0
}
distance(
x1 = c1.screenX + c1Center,
y1 = c1.screenY + c1Middle,
x2 = c2.screenX + c2Center,
y2 = c2.screenY + c2Middle
x1 = c1.global.center,
y1 = c1.global.middle,
x2 = c2.global.center,
y2 = c2.global.middle
)
}

Expand Down
49 changes: 38 additions & 11 deletions core/src/test/scala/examples/TargetingExample.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,59 @@ package examples

import org.sgine.{Color, Pointer}
import org.sgine.component.{Children, Component, Container, Image, Label, MutableContainer}
import org.sgine.drawable.{Drawer, ShapeDrawable}
import org.sgine.util.MathUtils
import perfolation.double2Implicits
import reactify.Val

import scala.util.Random

object TargetingExample extends Example {
// TODO: outline on component showing targetting range
// TODO: draw line to nearest target if in range

private lazy val player = new Image("basketball.png") {
center := Pointer.screen.x
middle := Pointer.screen.y
}

private lazy val enemies = (0 until 10).toList.map(_ => new Enemy)
private lazy val nearest = Val(enemies.sortBy(_.distance()))

override protected lazy val component: Component = new MutableContainer[Component] {
width := screen.width
height := screen.height

children += player
children += Player
children ++= enemies
}

object Player extends Container {
center := Pointer.screen.x
middle := Pointer.screen.y
width @= 220.0
height @= 220.0

private lazy val image = new Image("basketball.png")
private lazy val drawing = new Image {
drawable @= shape
}

object shape extends ShapeDrawable {
override def draw(drawer: Drawer): Unit = {
drawer.color = Color.White
drawer.circle(110.0, 110.0, 500.0, 6.0)
nearest().headOption.foreach { first =>
if (first.distance() < 500.0) {
val x = global.localizeX(first.global.center)
val y = global.localizeY(first.global.middle)
drawer.color = Color.Green
drawer.line(110.0, 110.0, x, y, 6.0)
}
}
}

override def width: Double = 220.0
override def height: Double = 220.0
}

override lazy val children: Children[Component] = Children(
this, Vector(image, drawing)
)
}

class Enemy extends Container { e =>
private val r1 = Random.nextDouble()
private val r2 = Random.nextDouble()
Expand All @@ -37,14 +64,14 @@ object TargetingExample extends Example {
width @= 200.0
height @= 200.0

val distance: Val[Double] = Val[Double](MathUtils.distanceFromCenter(player, e))
val distance: Val[Double] = Val[Double](MathUtils.distanceFromCenter(Player, e))

private lazy val image = new Image("crate.jpg") {
width @= 200.0
height @= 200.0
color := {
if (nearest().head eq e) {
if (distance() <= 1000.0) {
if (distance() <= 500.0) {
Color.Green
} else {
Color.Red
Expand Down

0 comments on commit a95446e

Please sign in to comment.