Added some collision with terrain. Needs some fixing since it doesn't stop in quite the right location and 'sticks'
This commit is contained in:
parent
c10da7ccf9
commit
0071e5af80
@ -8,4 +8,4 @@ maxBoost: 6
|
||||
newday: 02:00
|
||||
tileSize: 48
|
||||
yOffset: -4
|
||||
moveSpeed: 2.0
|
||||
moveSpeed: 3.0
|
||||
|
@ -15,6 +15,8 @@ class GameMap(val width: Int, val height: Int, val tileset: Tileset) {
|
||||
var tiles: IndexedSeq[AutoTile] = for (y <- 0 until height; x <- 0 until width) yield tileset.groundTiles.head
|
||||
var doodads: IndexedSeq[AutoTile] = for (y <- 0 until height; x <- 0 until width) yield tileset.doodadTiles.head
|
||||
|
||||
def tileInfo(index: Int) = tileset.infoOf(tiles(index))
|
||||
|
||||
def saveTo(file: File): Unit = {
|
||||
val ostream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))
|
||||
ostream.writeInt(width)
|
||||
|
@ -7,7 +7,9 @@ import fmon.draw.tile._
|
||||
|
||||
class Tileset(val groundTiles: IndexedSeq[AutoTile], val doodadTiles: IndexedSeq[AutoTile], val info: IndexedSeq[TileInfo]) {
|
||||
def groundInfo(index: Int) = info(index)
|
||||
def doodadInfo(index: Int) = info(index - groundTiles.size)
|
||||
def doodadInfo(index: Int) = info(index + groundTiles.size)
|
||||
|
||||
val infoOf = (groundTiles.zipWithIndex.map{case (t, i) => (t, groundInfo(i))} ++ doodadTiles.zipWithIndex.map{case (t, i) => (t, doodadInfo(i))}).toMap
|
||||
}
|
||||
|
||||
case class TileInfo(
|
||||
|
@ -14,6 +14,7 @@ import scalafx.Includes._
|
||||
import scalafx.animation.AnimationTimer
|
||||
import scalafx.beans.property._
|
||||
import scalafx.collections.ObservableBuffer
|
||||
import scalafx.geometry.Point2D
|
||||
import scalafx.scene.control._
|
||||
import scalafx.scene.image.ImageView
|
||||
import scalafx.scene.input.{KeyCode, MouseEvent}
|
||||
@ -41,6 +42,8 @@ class GameView {
|
||||
var heroImg: AnimatedImageView = _
|
||||
var currDir: Option[Direction.Value] = None
|
||||
|
||||
var level: GameMap = _
|
||||
|
||||
var lastTime = 0L
|
||||
val timer = AnimationTimer(t => {
|
||||
if (lastTime != 0L) {
|
||||
@ -50,6 +53,7 @@ class GameView {
|
||||
})
|
||||
|
||||
def loadLevel(level: GameMap): Unit = {
|
||||
this.level = level
|
||||
background.prefColumns = level.width
|
||||
val tiles = for (y <- 0 until level.height; x <- 0 until level.width) yield {
|
||||
new ImageView(level.smoothed(x, y)).delegate
|
||||
@ -109,14 +113,71 @@ class GameView {
|
||||
|
||||
def act(dur: Duration): Unit = {
|
||||
currDir match {
|
||||
case Some(North) => hero.y -= dur.toSeconds() * Config.moveSpeed
|
||||
case Some(East) => hero.x += dur.toSeconds() * Config.moveSpeed
|
||||
case Some(West) => hero.x -= dur.toSeconds() * Config.moveSpeed
|
||||
case Some(South) => hero.y += dur.toSeconds() * Config.moveSpeed
|
||||
case Some(North) => slide(hero, 0, -dur.toSeconds() * Config.moveSpeed)
|
||||
case Some(East) => slide(hero, dur.toSeconds() * Config.moveSpeed, 0)
|
||||
case Some(West) => slide(hero, -dur.toSeconds() * Config.moveSpeed, 0)
|
||||
case Some(South) => slide(hero, 0, +dur.toSeconds() * Config.moveSpeed)
|
||||
case _ => ()
|
||||
}
|
||||
heroImg.x = hero.x * Config.tileSize
|
||||
heroImg.y = hero.y * Config.tileSize
|
||||
heroImg.y = hero.y * Config.tileSize + Config.yOffset
|
||||
}
|
||||
|
||||
def slide(actor: Actor, dx: Double, dy: Double): Unit = {
|
||||
// Need to do all corners
|
||||
val px = if (dx < 0) actor.x else actor.x + 1
|
||||
val py = if (dy < 0) actor.y else actor.y + 1
|
||||
val tiles = tilesOnLine(new Point2D(px, py), new Point2D(px + dx, py + dy))
|
||||
|
||||
val condition = if (dx < 0 && dy < 0) {
|
||||
info:TileInfo => info.doesPassSouth && info.doesPassEast
|
||||
} else if (dx < 0) {
|
||||
info: TileInfo => info.doesPassNorth && info.doesPassEast
|
||||
} else if (dy < 0) {
|
||||
info: TileInfo => info.doesPassSouth && info.doesPassWest
|
||||
} else {
|
||||
info: TileInfo => info.doesPassNorth && info.doesPassWest
|
||||
}
|
||||
|
||||
val collisions = tiles.filterNot{case (i, _) => condition(level.tileInfo(i))}
|
||||
if (!collisions.isEmpty) {
|
||||
val (i, pt) = collisions.head
|
||||
println(actor.y, pt.y)
|
||||
actor.x += (pt.x - px)
|
||||
actor.y += (pt.y - py)
|
||||
//println(actor.x, actor.y)
|
||||
} else {
|
||||
actor.x += dx
|
||||
actor.y += dy
|
||||
}
|
||||
}
|
||||
|
||||
def tilesOnLine(p: Point2D, q: Point2D): Seq[(Int, Point2D)] = {
|
||||
val dx = q.x - p.x
|
||||
val dy = q.y - p.y
|
||||
val nx = Math.abs(dx).toInt
|
||||
val ny = Math.abs(dy).toInt
|
||||
val sx = Math.signum(dx)
|
||||
val sy = Math.signum(dy)
|
||||
|
||||
var pts = Seq(p)
|
||||
var pt = p
|
||||
var ix = 0
|
||||
var iy = 0
|
||||
while (ix < nx || iy < ny) {
|
||||
if ((0.5+ix) * ny < (0.5+iy) * nx) {
|
||||
// next step is horizontal
|
||||
pt = new Point2D(pt.x + sx, pt.y)
|
||||
ix += 1
|
||||
} else {
|
||||
// next step is vertical
|
||||
pt = new Point2D(pt.x, pt.y + sy)
|
||||
ix += 1
|
||||
}
|
||||
pts :+= pt
|
||||
}
|
||||
|
||||
pts.map(pt => (level.pt2index(pt.x.toInt, pt.y.toInt), pt))
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user