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
|
newday: 02:00
|
||||||
tileSize: 48
|
tileSize: 48
|
||||||
yOffset: -4
|
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 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
|
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 = {
|
def saveTo(file: File): Unit = {
|
||||||
val ostream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))
|
val ostream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))
|
||||||
ostream.writeInt(width)
|
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]) {
|
class Tileset(val groundTiles: IndexedSeq[AutoTile], val doodadTiles: IndexedSeq[AutoTile], val info: IndexedSeq[TileInfo]) {
|
||||||
def groundInfo(index: Int) = info(index)
|
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(
|
case class TileInfo(
|
||||||
|
@ -14,6 +14,7 @@ import scalafx.Includes._
|
|||||||
import scalafx.animation.AnimationTimer
|
import scalafx.animation.AnimationTimer
|
||||||
import scalafx.beans.property._
|
import scalafx.beans.property._
|
||||||
import scalafx.collections.ObservableBuffer
|
import scalafx.collections.ObservableBuffer
|
||||||
|
import scalafx.geometry.Point2D
|
||||||
import scalafx.scene.control._
|
import scalafx.scene.control._
|
||||||
import scalafx.scene.image.ImageView
|
import scalafx.scene.image.ImageView
|
||||||
import scalafx.scene.input.{KeyCode, MouseEvent}
|
import scalafx.scene.input.{KeyCode, MouseEvent}
|
||||||
@ -41,6 +42,8 @@ class GameView {
|
|||||||
var heroImg: AnimatedImageView = _
|
var heroImg: AnimatedImageView = _
|
||||||
var currDir: Option[Direction.Value] = None
|
var currDir: Option[Direction.Value] = None
|
||||||
|
|
||||||
|
var level: GameMap = _
|
||||||
|
|
||||||
var lastTime = 0L
|
var lastTime = 0L
|
||||||
val timer = AnimationTimer(t => {
|
val timer = AnimationTimer(t => {
|
||||||
if (lastTime != 0L) {
|
if (lastTime != 0L) {
|
||||||
@ -50,6 +53,7 @@ class GameView {
|
|||||||
})
|
})
|
||||||
|
|
||||||
def loadLevel(level: GameMap): Unit = {
|
def loadLevel(level: GameMap): Unit = {
|
||||||
|
this.level = level
|
||||||
background.prefColumns = level.width
|
background.prefColumns = level.width
|
||||||
val tiles = for (y <- 0 until level.height; x <- 0 until level.width) yield {
|
val tiles = for (y <- 0 until level.height; x <- 0 until level.width) yield {
|
||||||
new ImageView(level.smoothed(x, y)).delegate
|
new ImageView(level.smoothed(x, y)).delegate
|
||||||
@ -109,14 +113,71 @@ class GameView {
|
|||||||
|
|
||||||
def act(dur: Duration): Unit = {
|
def act(dur: Duration): Unit = {
|
||||||
currDir match {
|
currDir match {
|
||||||
case Some(North) => hero.y -= dur.toSeconds() * Config.moveSpeed
|
case Some(North) => slide(hero, 0, -dur.toSeconds() * Config.moveSpeed)
|
||||||
case Some(East) => hero.x += dur.toSeconds() * Config.moveSpeed
|
case Some(East) => slide(hero, dur.toSeconds() * Config.moveSpeed, 0)
|
||||||
case Some(West) => hero.x -= dur.toSeconds() * Config.moveSpeed
|
case Some(West) => slide(hero, -dur.toSeconds() * Config.moveSpeed, 0)
|
||||||
case Some(South) => hero.y += dur.toSeconds() * Config.moveSpeed
|
case Some(South) => slide(hero, 0, +dur.toSeconds() * Config.moveSpeed)
|
||||||
case _ => ()
|
case _ => ()
|
||||||
}
|
}
|
||||||
heroImg.x = hero.x * Config.tileSize
|
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