ActorWithBody: broke CCD again for fundamental error-catching, new tile STONE_BRICKS
Former-commit-id: 3d98f83f3d40f4423b403eae717a06ac6fc22531 Former-commit-id: 13616655a392941e0c91c3384384475ae0adb5db
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 347 KiB After Width: | Height: | Size: 349 KiB |
|
Before Width: | Height: | Size: 318 KiB After Width: | Height: | Size: 340 KiB |
@@ -51,7 +51,7 @@
|
||||
|
||||
"CONTEXT_DESCRIPTION_BIG";"[Adjective]";"Big";"Gros";"Grande";"Groß";"Grande";"Grande";"Grande";"Большой";"Μεγάλο";"Büyük";"Stor";"Stor";"Stor";"Groot";"Duży";"Iso";"大";"大";"大";"대";"Velký";"Nagy";"Mare";"ใหญ่";"Голям";"גדול";"だい";"Stór"
|
||||
"CONTEXT_DESCRIPTION_HUGE";"[Adjective] Very large";"Huge";"Énorme";"Enorme";"Riesig";"Enorme";"Enorme";"Enorme";"Огромный";"Τεράστιο";"Devasa";"Enorm";"Enorm";"Enorm";"Enorm";"Ogromny";"Jättimäinen";"巨大";"极大";"極大";"특대";"Obrovský";"Hatalmas";"Enorm";"ใหญ่มาก";"Огромен";"ענק";"きょだい";"Gífurlegur"
|
||||
"CONTEXT_DESCRIPTION_SMALL";"[Adjective]";"Small";"Petit";"Pequeño";"Klein";"Piccolo";"Pequeno";"Pequeno";"Маленький";"Μικρό";"Küçük";"Lille";"Liten";"Liten";"Klein";"Mały";"Pieni";"小";"小";"小";"소";"Malý";"Kicsi";"Mic";"เล็ก";"Малък";"קטן";"こ";"Lítill"
|
||||
"CONTEXT_DESCRIPTION_SMALL";"[Adjective]";"Small";"Petit";"Pequeño";"Klein";"Piccolo";"Pequeno";"Pequeno";"Маленький";"Μικρό";"Küçük";"Lille";"Liten";"Liten";"Klein";"Mały";"Pieni";"小";"小";"小";"소";"Malý";"Kicsi";"Mic";"เล็ก";"Малък";"קטן";"しょう";"Lítill"
|
||||
"CONTEXT_DESCRIPTION_TINY";"[Adjective] Very small";"Tiny";"Minuscule";"Diminuto";"Winzig";"Minuscolo";"Muito pequeno";"Muito pequeno";"Крошечный";"Μικροσκοπικό";"Minik";"Lillebitte";"Bitteliten";"Pytteliten";"Minuscuul";"Malutki";"Pikkuriikkinen";"極小";"极小";"極小";"특소";"Maličký";"Apró";"Minuscul";"เล็กจิ๋ว";"Миниатюрен";"קטנטן";"きょくしょう";"Pínulítill"
|
||||
|
||||
"CONTEXT_ITEM_ARMOR";"[Noun] Body armor";"Armor";"Armure";"Armadura";"Rüstung";"Armatura";"Armadura";"Armadura";"Броня";"Πανοπλία";"Zırh";"Rustning";"Rustning";"Rustning";"Pantser";"Zbroja";"Panssari";"鎧";"护甲";"護甲";"갑옷";"Brnění";"Páncél";"Armură";"ชุดเกราะ";"Броня";"שריון";"よろい";"brynja"
|
||||
|
||||
|
@@ -5,6 +5,10 @@ package net.torvald.point
|
||||
*/
|
||||
class Point2d(var x: Double, var y: Double) : Cloneable {
|
||||
|
||||
override fun toString(): String {
|
||||
return "($x, $y)"
|
||||
}
|
||||
|
||||
fun set(x: Double, y: Double) {
|
||||
this.x = x
|
||||
this.y = y
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
package net.torvald.spriteanimation
|
||||
|
||||
import net.torvald.terrarum.Game
|
||||
import net.torvald.terrarum.StateGame
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import com.jme3.math.FastMath
|
||||
import org.newdawn.slick.Graphics
|
||||
|
||||
@@ -2,8 +2,52 @@
|
||||
Copyright 2015-2016 Torvald. All rights reserved.
|
||||
mailto: skyhi14 *64* __115875741922660__ *46* __6516589__
|
||||
|
||||
----
|
||||
|
||||
* *Simplex Noise Generator*, version 2012-03-09 by Stefan Gustavson
|
||||
Released as public domain
|
||||
|
||||
----
|
||||
|
||||
* *Joise* modular noise library
|
||||
Copyright (C) 2013 Jason Taylor. Released as open-source under Apache License, Version 2.0.
|
||||
Copyright (C) 2013 Jason Taylor.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
----
|
||||
|
||||
* *Vector2* from Dyn4j
|
||||
Copyright (c) 2010-2015 William Bittle http://www.dyn4j.org/
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||
provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
||||
and the following disclaimer in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of dyn4j nor the names of its contributors may be used to endorse or
|
||||
promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Kotlin translated and modified code Copyright (c) 2016 Torvald aka skyhi14.
|
||||
31
src/net/torvald/terrarum/StateFontPrinter.kt
Normal file
@@ -0,0 +1,31 @@
|
||||
package net.torvald.terrarum
|
||||
|
||||
import org.newdawn.slick.Font
|
||||
import org.newdawn.slick.GameContainer
|
||||
import org.newdawn.slick.Graphics
|
||||
import org.newdawn.slick.state.BasicGameState
|
||||
import org.newdawn.slick.state.StateBasedGame
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-06-28.
|
||||
*/
|
||||
class StateFontPrinter : BasicGameState() {
|
||||
val textToPrint = "Font printer 서체 인쇄기"
|
||||
|
||||
lateinit var canvas: Graphics
|
||||
lateinit var gameFont: Font
|
||||
|
||||
override fun init(gc: GameContainer, game: StateBasedGame) {
|
||||
canvas = Graphics(1024, 1024)
|
||||
}
|
||||
|
||||
override fun update(gc: GameContainer, game: StateBasedGame, delta: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun render(gc: GameContainer, game: StateBasedGame, g: Graphics) {
|
||||
|
||||
}
|
||||
|
||||
override fun getID(): Int = 666
|
||||
}
|
||||
@@ -35,7 +35,7 @@ import java.util.*
|
||||
/**
|
||||
* Created by minjaesong on 15-12-30.
|
||||
*/
|
||||
class Game @Throws(SlickException::class)
|
||||
class StateGame @Throws(SlickException::class)
|
||||
constructor() : BasicGameState() {
|
||||
private val ACTOR_UPDATE_RANGE = 4096
|
||||
|
||||
@@ -315,9 +315,7 @@ constructor() : BasicGameState() {
|
||||
GameController.controllerButtonReleased(controller, button)
|
||||
}
|
||||
|
||||
override fun getID(): Int {
|
||||
return Terrarum.SCENE_ID_GAME
|
||||
}
|
||||
override fun getID(): Int = Terrarum.SCENE_ID_GAME
|
||||
|
||||
private fun drawSkybox(g: Graphics) {
|
||||
val skyColourFill = GradientFill(
|
||||
@@ -57,7 +57,7 @@ constructor(gamename: String) : StateBasedGame(gamename) {
|
||||
|
||||
appgc.input.enableKeyRepeat()
|
||||
|
||||
game = Game()
|
||||
game = StateGame()
|
||||
addState(game)
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ constructor(gamename: String) : StateBasedGame(gamename) {
|
||||
var VSYNC = true
|
||||
val VSYNC_TRIGGER_THRESHOLD = 56
|
||||
|
||||
lateinit var game: Game
|
||||
lateinit var game: StateGame
|
||||
lateinit var gameConfig: GameConfig
|
||||
|
||||
lateinit var OSName: String
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package net.torvald.terrarum.console
|
||||
|
||||
import net.torvald.terrarum.Game
|
||||
import net.torvald.terrarum.StateGame
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.ui.ConsoleWindow
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package net.torvald.terrarum.console
|
||||
|
||||
import net.torvald.imagefont.GameFontBase
|
||||
import net.torvald.terrarum.Game
|
||||
import net.torvald.terrarum.StateGame
|
||||
import net.torvald.terrarum.Terrarum
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package net.torvald.terrarum.console
|
||||
|
||||
import net.torvald.terrarum.Game
|
||||
import net.torvald.terrarum.StateGame
|
||||
import net.torvald.terrarum.mapdrawer.MapDrawer
|
||||
import net.torvald.terrarum.Terrarum
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package net.torvald.terrarum.console
|
||||
|
||||
import net.torvald.terrarum.Game
|
||||
import net.torvald.terrarum.StateGame
|
||||
import net.torvald.terrarum.Terrarum
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
package net.torvald.terrarum.gameactors
|
||||
|
||||
import net.torvald.random.HQRNG
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.gamemap.GameMap
|
||||
import net.torvald.terrarum.mapdrawer.MapDrawer
|
||||
import net.torvald.terrarum.tileproperties.TilePropCodex
|
||||
import net.torvald.spriteanimation.SpriteAnimation
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.terrarum.tileproperties.TileNameCode
|
||||
import org.dyn4j.Epsilon
|
||||
import org.dyn4j.geometry.ChainedVector2
|
||||
import org.dyn4j.geometry.Vector2
|
||||
import org.newdawn.slick.GameContainer
|
||||
import org.newdawn.slick.Graphics
|
||||
@@ -21,14 +18,26 @@ import org.newdawn.slick.Graphics
|
||||
*/
|
||||
open class ActorWithBody : Actor(), Visible {
|
||||
|
||||
override var referenceID: Int = generateUniqueReferenceID()
|
||||
override var actorValue: ActorValue = ActorValue()
|
||||
|
||||
@Transient var sprite: SpriteAnimation? = null
|
||||
@Transient var spriteGlow: SpriteAnimation? = null
|
||||
|
||||
@Transient private val map: GameMap = Terrarum.game.map
|
||||
|
||||
var hitboxTranslateX: Double = 0.0// relative to spritePosX
|
||||
var hitboxTranslateY: Double = 0.0// relative to spritePosY
|
||||
var baseHitboxW: Int = 0
|
||||
var baseHitboxH: Int = 0
|
||||
|
||||
@Transient private val map: GameMap = Terrarum.game.map
|
||||
internal var baseSpriteWidth: Int = 0
|
||||
internal var baseSpriteHeight: Int = 0
|
||||
/**
|
||||
* * Position: top-left point
|
||||
* * Unit: pixel
|
||||
*/
|
||||
override val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0)
|
||||
@Transient val nextHitbox = Hitbox(0.0, 0.0, 0.0, 0.0)
|
||||
|
||||
/**
|
||||
* Velocity vector for newtonian sim.
|
||||
@@ -46,31 +55,7 @@ open class ActorWithBody : Actor(), Visible {
|
||||
var walkX: Double = 0.0
|
||||
var walkY: Double = 0.0
|
||||
val moveDelta = Vector2(0.0, 0.0)
|
||||
@Transient private val VELO_HARD_LIMIT = 10000.0
|
||||
|
||||
var grounded = false
|
||||
|
||||
@Transient var sprite: SpriteAnimation? = null
|
||||
@Transient var spriteGlow: SpriteAnimation? = null
|
||||
/** Default to 'false' */
|
||||
var isVisible = false
|
||||
/** Default to 'true' */
|
||||
var isUpdate = true
|
||||
|
||||
var isNoSubjectToGrav = false
|
||||
var isNoCollideWorld = false
|
||||
var isNoSubjectToFluidResistance = false
|
||||
|
||||
internal var baseSpriteWidth: Int = 0
|
||||
internal var baseSpriteHeight: Int = 0
|
||||
|
||||
override var referenceID: Int = generateUniqueReferenceID()
|
||||
/**
|
||||
* * Position: top-left point
|
||||
* * Unit: pixel
|
||||
*/
|
||||
override val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0)
|
||||
@Transient val nextHitbox = Hitbox(0.0, 0.0, 0.0, 0.0)
|
||||
@Transient private val VELO_HARD_LIMIT = 100.0
|
||||
|
||||
/**
|
||||
* Physical properties.
|
||||
@@ -92,6 +77,7 @@ open class ActorWithBody : Actor(), Visible {
|
||||
|
||||
actorValue[AVKey.BASEMASS] = value
|
||||
}
|
||||
@Transient private val MASS_DEFAULT: Double = 60.0
|
||||
/** Valid range: [0, 1] */
|
||||
var elasticity: Double = 0.0
|
||||
set(value) {
|
||||
@@ -119,6 +105,31 @@ open class ActorWithBody : Actor(), Visible {
|
||||
|
||||
private var density = 1000.0
|
||||
|
||||
/**
|
||||
* Flags and Properties
|
||||
*/
|
||||
|
||||
var grounded = false
|
||||
/** Default to 'false' */
|
||||
var isVisible = false
|
||||
/** Default to 'true' */
|
||||
var isUpdate = true
|
||||
var isNoSubjectToGrav = false
|
||||
var isNoCollideWorld = false
|
||||
var isNoSubjectToFluidResistance = false
|
||||
/** Time-freezing. The actor won't even budge but the velocity will accumulate
|
||||
* EXCEPT FOR friction, gravity and buoyancy SHOULD NOT.
|
||||
*
|
||||
* (this would give something to do to the player otherwise it would be dull to travel far,
|
||||
* think of a grass cutting on the Zelda games. It would also make a great puzzle to solve.
|
||||
* --minjaesong)
|
||||
*/
|
||||
var isChronostasis = false
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
@Transient private val METER = 24.0
|
||||
/**
|
||||
* [m / s^2] * SI_TO_GAME_ACC -> [px / InternalFrame^2]
|
||||
@@ -148,44 +159,23 @@ open class ActorWithBody : Actor(), Visible {
|
||||
@Transient private val UD_COMPENSATOR_MAX = TSIZE
|
||||
@Transient private val LR_COMPENSATOR_MAX = TSIZE
|
||||
|
||||
/**
|
||||
* A constant to make falling faster so that the game is more playable
|
||||
*/
|
||||
@Transient private val G_MUL_PLAYABLE_CONST = 1.4142
|
||||
|
||||
/**
|
||||
* Post-hit invincibility, in milliseconds
|
||||
*/
|
||||
@Transient val INVINCIBILITY_TIME: Int = 500
|
||||
|
||||
@Transient private val MASS_DEFAULT: Double = 60.0
|
||||
|
||||
internal var physSleep: Boolean = false
|
||||
private set
|
||||
|
||||
/**
|
||||
* for collide-to-world compensation
|
||||
*/
|
||||
@Transient private var posAdjustX = 0
|
||||
@Transient private var posAdjustY = 0
|
||||
|
||||
@Transient internal val BASE_FRICTION = 0.3
|
||||
|
||||
@Transient val KINEMATIC = 1 // does not be budged by external forces
|
||||
@Transient val DYNAMIC = 2
|
||||
@Transient val STATIC = 3 // does not be budged by external forces, target of collision
|
||||
|
||||
var collisionType = DYNAMIC
|
||||
|
||||
@Transient private val CCD_TICK = 1.0 / 256.0
|
||||
@Transient private val CCD_TRY_MAX = 25600
|
||||
|
||||
// to use with Controller (incl. player)
|
||||
internal var walledLeft = false
|
||||
internal var walledRight = false
|
||||
@Transient private val CCD_TICK = 1.0 / 16.0
|
||||
@Transient private val CCD_TRY_MAX = 12800
|
||||
|
||||
// just some trivial magic numbers
|
||||
@Transient private val A_PIXEL = 2.0
|
||||
@Transient private val A_PIXEL = 1.4
|
||||
@Transient private val COLLIDING_TOP = 0
|
||||
@Transient private val COLLIDING_RIGHT = 1
|
||||
@Transient private val COLLIDING_BOTTOM = 2
|
||||
@@ -194,8 +184,18 @@ open class ActorWithBody : Actor(), Visible {
|
||||
@Transient private val COLLIDING_LR = 5
|
||||
@Transient private val COLLIDING_ALLSIDE = 6
|
||||
|
||||
/**
|
||||
* Temporary variables
|
||||
*/
|
||||
|
||||
@Transient private var assertPrinted = false
|
||||
|
||||
// to use with Controller (incl. player)
|
||||
internal var walledLeft = false
|
||||
internal var walledRight = false
|
||||
|
||||
var ccdCollided = false
|
||||
|
||||
init {
|
||||
// some initialiser goes here...
|
||||
}
|
||||
@@ -240,17 +240,22 @@ open class ActorWithBody : Actor(), Visible {
|
||||
* Add vector value to the velocity, in the time unit of single frame.
|
||||
*
|
||||
* Since we're adding some value every frame, the value is equivalent to the acceleration.
|
||||
* Find about Newton's second law for the background knowledge.
|
||||
* Look for Newton's second law for the background knowledge.
|
||||
* @param vec : Acceleration in Vector2
|
||||
*/
|
||||
fun applyForce(vec: Vector2) {
|
||||
velocity += vec
|
||||
physSleep = false
|
||||
}
|
||||
|
||||
override fun update(gc: GameContainer, delta: Int) {
|
||||
if (isUpdate) {
|
||||
|
||||
/**
|
||||
* Temporary variables to reset
|
||||
*/
|
||||
ccdCollided = false
|
||||
/******************************/
|
||||
|
||||
if (!assertPrinted) assertInit()
|
||||
|
||||
// make NoClip work for player
|
||||
@@ -276,22 +281,22 @@ open class ActorWithBody : Actor(), Visible {
|
||||
}
|
||||
|
||||
// hard limit velocity
|
||||
if (veloX > VELO_HARD_LIMIT) veloX = VELO_HARD_LIMIT
|
||||
if (veloY > VELO_HARD_LIMIT) veloY = VELO_HARD_LIMIT
|
||||
veloX = veloX.bipolarClamp(VELO_HARD_LIMIT)
|
||||
veloY = veloY.bipolarClamp(VELO_HARD_LIMIT)
|
||||
|
||||
moveDelta.set(velocity + Vector2(walkX, walkY))
|
||||
|
||||
if (!physSleep) {
|
||||
if (!isChronostasis) {
|
||||
// Set 'next' position (hitbox) from canonical and walking velocity
|
||||
setNewNextHitbox()
|
||||
|
||||
applyNormalForce()
|
||||
/**
|
||||
* solveCollision()?
|
||||
* If and only if:
|
||||
* This body is NON-STATIC and the other body is STATIC
|
||||
*/
|
||||
displaceByCCD()
|
||||
applyNormalForce()
|
||||
|
||||
setHorizontalFriction()
|
||||
if (isPlayerNoClip) // or hanging on the rope, etc.
|
||||
@@ -304,8 +309,8 @@ open class ActorWithBody : Actor(), Visible {
|
||||
clampHitbox()
|
||||
}
|
||||
|
||||
walledLeft = isColliding(COLLIDING_LEFT)
|
||||
walledRight = isColliding(COLLIDING_RIGHT)
|
||||
walledLeft = isColliding(hitbox, COLLIDING_LEFT)
|
||||
walledRight = isColliding(hitbox, COLLIDING_RIGHT)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,10 +345,8 @@ open class ActorWithBody : Actor(), Visible {
|
||||
private fun applyNormalForce() {
|
||||
if (!isNoCollideWorld) {
|
||||
// axis Y
|
||||
if (moveDelta.y >= 0.0) { // check downward
|
||||
//FIXME "isColliding" (likely the newer one) is the perkeleen vittupää
|
||||
if (isColliding(COLLIDING_UD)) {
|
||||
// the actor is hitting the ground
|
||||
if (moveDelta.y >= 0.0) { // was moving downward?
|
||||
if (ccdCollided) { // actor hit something on its bottom
|
||||
hitAndReflectY()
|
||||
grounded = true
|
||||
}
|
||||
@@ -351,17 +354,16 @@ open class ActorWithBody : Actor(), Visible {
|
||||
grounded = false
|
||||
}
|
||||
}
|
||||
else if (moveDelta.y < 0.0) { // check upward
|
||||
else if (moveDelta.y < 0.0) { // or was moving upward?
|
||||
grounded = false
|
||||
if (isColliding(COLLIDING_UD)) {
|
||||
// the actor is hitting the ceiling
|
||||
if (ccdCollided) { // actor hit something on its top
|
||||
hitAndReflectY()
|
||||
}
|
||||
else { // the actor is not grounded at all
|
||||
}
|
||||
}
|
||||
// axis X
|
||||
if (isColliding(COLLIDING_LR) && moveDelta.x != 0.0) { // check right and left
|
||||
if (ccdCollided && moveDelta.x != 0.0) { // check right and left
|
||||
// the actor is hitting the wall
|
||||
hitAndReflectX()
|
||||
}
|
||||
@@ -373,48 +375,27 @@ open class ActorWithBody : Actor(), Visible {
|
||||
*/
|
||||
private fun displaceByCCD() {
|
||||
if (!isNoCollideWorld){
|
||||
// vector, toward the previous position; implies linear interpolation
|
||||
val deltaNegative = Vector2(hitbox.toVector() - nextHitbox.toVector()) // we need to traverse back, so may as well negate at the first place
|
||||
val ccdDelta = if (deltaNegative.magnitudeSquared > CCD_TICK.sqr())
|
||||
deltaNegative.setMagnitude(CCD_TICK)
|
||||
else
|
||||
deltaNegative
|
||||
var ccdCount = 0
|
||||
// do some CCD between hitbox and nextHitbox
|
||||
val ccdBox = hitbox.clone()
|
||||
val ccdDelta = hitbox.toVector() to nextHitbox.toVector()
|
||||
val ccdStep = Math.max(ccdDelta.x, ccdDelta.y)
|
||||
|
||||
// Q&D fix: quantise hitbox by direction
|
||||
/*if (deltaNegative.y < 0) {
|
||||
if (deltaNegative.x > 0)
|
||||
nextHitbox.setPosition(
|
||||
nextHitbox.posX.floor(),
|
||||
nextHitbox.endPointY.ceil().minus(nextHitbox.height)
|
||||
)
|
||||
else if (deltaNegative.x < 0)
|
||||
nextHitbox.setPosition(
|
||||
nextHitbox.endPointX.ceil().minus(nextHitbox.width),
|
||||
nextHitbox.endPointY.ceil().minus(nextHitbox.height)
|
||||
)
|
||||
}
|
||||
else if (deltaNegative.y > 0) {
|
||||
if (deltaNegative.x > 0)
|
||||
nextHitbox.setPosition(
|
||||
nextHitbox.posX.floor(),
|
||||
nextHitbox.posY.floor()
|
||||
)
|
||||
else if (deltaNegative.x < 0)
|
||||
nextHitbox.setPosition(
|
||||
nextHitbox.endPointX.ceil().minus(nextHitbox.width),
|
||||
nextHitbox.posY.floor()
|
||||
)
|
||||
}*/
|
||||
for (step in 0..ccdStep.floorInt()) {
|
||||
ccdBox.translate(ccdDelta * (step.toDouble() / ccdStep))
|
||||
|
||||
while (isColliding(COLLIDING_ALLSIDE) && ccdCount < CCD_TRY_MAX) { // no thresholding?
|
||||
nextHitbox.translate(ccdDelta)
|
||||
ccdCount += 1
|
||||
println(ccdDelta * (step.toDouble() / ccdStep))
|
||||
println(ccdBox)
|
||||
|
||||
if (isColliding(ccdBox)) {
|
||||
ccdCollided = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (ccdCount > 0) {
|
||||
println("Displacement: ${ccdDelta.magnitude * ccdCount} ($ccdCount times)")
|
||||
}
|
||||
nextHitbox.reassign(ccdBox)
|
||||
}
|
||||
else {
|
||||
ccdCollided = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,9 +421,9 @@ open class ActorWithBody : Actor(), Visible {
|
||||
}
|
||||
}
|
||||
|
||||
private fun isColliding() = isColliding(0)
|
||||
private fun isColliding(hitbox: Hitbox) = isColliding(hitbox, 0)
|
||||
|
||||
private fun isColliding(option: Int): Boolean {
|
||||
private fun isColliding(hitbox: Hitbox, option: Int): Boolean {
|
||||
if (isNoCollideWorld) return false
|
||||
|
||||
// offsets will stretch and shrink detection box according to the argument
|
||||
@@ -451,41 +432,41 @@ open class ActorWithBody : Actor(), Visible {
|
||||
val offsetX = if (option == COLLIDING_LR) A_PIXEL else 0.0
|
||||
val offsetY = if (option == COLLIDING_UD) A_PIXEL else 0.0
|
||||
|
||||
x1 = nextHitbox.posX - offsetX + offsetY
|
||||
x2 = nextHitbox.posX + offsetX - offsetY + nextHitbox.width
|
||||
y1 = nextHitbox.posY + offsetX - offsetY
|
||||
y2 = nextHitbox.posY - offsetX + offsetY + nextHitbox.height
|
||||
x1 = hitbox.posX - offsetX + offsetY
|
||||
x2 = hitbox.posX + offsetX - offsetY + hitbox.width
|
||||
y1 = hitbox.posY + offsetX - offsetY
|
||||
y2 = hitbox.posY - offsetX + offsetY + hitbox.height
|
||||
}
|
||||
else {
|
||||
if (option == COLLIDING_LEFT) {
|
||||
x1 = nextHitbox.posX - A_PIXEL
|
||||
x2 = nextHitbox.posX - A_PIXEL + nextHitbox.width
|
||||
y1 = nextHitbox.posY + A_PIXEL
|
||||
y2 = nextHitbox.posY - A_PIXEL + nextHitbox.height
|
||||
x1 = hitbox.posX - A_PIXEL
|
||||
x2 = hitbox.posX - A_PIXEL + hitbox.width
|
||||
y1 = hitbox.posY + A_PIXEL
|
||||
y2 = hitbox.posY - A_PIXEL + hitbox.height
|
||||
}
|
||||
else if (option == COLLIDING_RIGHT) {
|
||||
x1 = nextHitbox.posX + A_PIXEL
|
||||
x2 = nextHitbox.posX + A_PIXEL + nextHitbox.width
|
||||
y1 = nextHitbox.posY + A_PIXEL
|
||||
y2 = nextHitbox.posY - A_PIXEL + nextHitbox.height
|
||||
x1 = hitbox.posX + A_PIXEL
|
||||
x2 = hitbox.posX + A_PIXEL + hitbox.width
|
||||
y1 = hitbox.posY + A_PIXEL
|
||||
y2 = hitbox.posY - A_PIXEL + hitbox.height
|
||||
}
|
||||
else if (option == COLLIDING_TOP) {
|
||||
x1 = nextHitbox.posX + A_PIXEL
|
||||
x2 = nextHitbox.posX - A_PIXEL + nextHitbox.width
|
||||
y1 = nextHitbox.posY - A_PIXEL
|
||||
y2 = nextHitbox.posY - A_PIXEL + nextHitbox.height
|
||||
x1 = hitbox.posX + A_PIXEL
|
||||
x2 = hitbox.posX - A_PIXEL + hitbox.width
|
||||
y1 = hitbox.posY - A_PIXEL
|
||||
y2 = hitbox.posY - A_PIXEL + hitbox.height
|
||||
}
|
||||
else if (option == COLLIDING_BOTTOM) {
|
||||
x1 = nextHitbox.posX + A_PIXEL
|
||||
x2 = nextHitbox.posX - A_PIXEL + nextHitbox.width
|
||||
y1 = nextHitbox.posY + A_PIXEL
|
||||
y2 = nextHitbox.posY + A_PIXEL + nextHitbox.height
|
||||
x1 = hitbox.posX + A_PIXEL
|
||||
x2 = hitbox.posX - A_PIXEL + hitbox.width
|
||||
y1 = hitbox.posY + A_PIXEL
|
||||
y2 = hitbox.posY + A_PIXEL + hitbox.height
|
||||
}
|
||||
else {
|
||||
x1 = nextHitbox.posX
|
||||
x2 = nextHitbox.posX + nextHitbox.width
|
||||
y1 = nextHitbox.posY
|
||||
y2 = nextHitbox.posY + nextHitbox.height
|
||||
x1 = hitbox.posX
|
||||
x2 = hitbox.posX + hitbox.width
|
||||
y1 = hitbox.posY
|
||||
y2 = hitbox.posY + hitbox.height
|
||||
}
|
||||
}
|
||||
|
||||
@@ -707,7 +688,7 @@ open class ActorWithBody : Actor(), Visible {
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateHitbox() = hitbox.set(nextHitbox)
|
||||
private fun updateHitbox() = hitbox.reassign(nextHitbox)
|
||||
|
||||
override fun drawGlow(gc: GameContainer, g: Graphics) {
|
||||
if (isVisible && spriteGlow != null) {
|
||||
@@ -810,6 +791,10 @@ open class ActorWithBody : Actor(), Visible {
|
||||
fun Double.abs() = Math.abs(this)
|
||||
fun Double.sqr() = this * this
|
||||
fun Int.abs() = if (this < 0) -this else this
|
||||
fun Double.bipolarClamp(limit: Double) =
|
||||
if (this > 0 && this > limit) limit
|
||||
else if (this < 0 && this < -limit) -limit
|
||||
else this
|
||||
|
||||
private fun assertInit() {
|
||||
// errors
|
||||
@@ -851,19 +836,3 @@ open class ActorWithBody : Actor(), Visible {
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Give new random ReferenceID and initialise ActorValue
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
= = ↑
|
||||
=== ===@!
|
||||
=↑ =↑
|
||||
=↑ =
|
||||
=↑ =
|
||||
=@ (pressing R) =
|
||||
================== ==================
|
||||
|
||||
Fig. 1: the fix was not applied
|
||||
*/
|
||||
@@ -1,13 +1,12 @@
|
||||
package net.torvald.terrarum.gameactors
|
||||
|
||||
import net.torvald.point.Point2d
|
||||
import org.dyn4j.geometry.ChainedVector2
|
||||
import org.dyn4j.geometry.Vector2
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-01-15.
|
||||
*/
|
||||
class Hitbox(x1: Double, y1: Double, width: Double, height: Double) : Cloneable {
|
||||
class Hitbox(x1: Double, y1: Double, width: Double, height: Double) {
|
||||
|
||||
@Volatile var hitboxStart: Point2d
|
||||
private set
|
||||
@@ -25,6 +24,10 @@ class Hitbox(x1: Double, y1: Double, width: Double, height: Double) : Cloneable
|
||||
this.height = height
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "[$hitboxStart - $hitboxEnd]"
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns bottom-centered point of hitbox.
|
||||
* @return pointX
|
||||
@@ -58,10 +61,7 @@ class Hitbox(x1: Double, y1: Double, width: Double, height: Double) : Cloneable
|
||||
this.height = height
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this hitbox from other
|
||||
*/
|
||||
fun set(other: Hitbox) {
|
||||
fun reassign(other: Hitbox) {
|
||||
set(other.posX, other.posY, other.width, other.height)
|
||||
}
|
||||
|
||||
@@ -69,10 +69,6 @@ class Hitbox(x1: Double, y1: Double, width: Double, height: Double) : Cloneable
|
||||
setPosition(posX + x, posY + y)
|
||||
}
|
||||
|
||||
fun translate(vec: ChainedVector2) {
|
||||
translate(vec.x, vec.y)
|
||||
}
|
||||
|
||||
fun translate(vec: Vector2) {
|
||||
translate(vec.x, vec.y)
|
||||
}
|
||||
@@ -139,4 +135,6 @@ class Hitbox(x1: Double, y1: Double, width: Double, height: Double) : Cloneable
|
||||
fun toVector(): Vector2 {
|
||||
return Vector2(posX, posY)
|
||||
}
|
||||
|
||||
fun clone(): Hitbox = Hitbox(posX, posY, width, height)
|
||||
}
|
||||
|
||||
@@ -111,6 +111,9 @@ object MapCamera {
|
||||
*/
|
||||
val TILES_CONNECT_MUTUAL = arrayOf(
|
||||
TileNameCode.STONE
|
||||
, TileNameCode.STONE_QUARRIED
|
||||
, TileNameCode.STONE_TILE_WHITE
|
||||
, TileNameCode.STONE_BRICKS
|
||||
, TileNameCode.DIRT
|
||||
, TileNameCode.GRASS
|
||||
, TileNameCode.PLANK_BIRCH
|
||||
|
||||
@@ -11,6 +11,8 @@ object TileNameCode {
|
||||
|
||||
val STONE = TilePropCodex.idDamageToIndex(1, 0)
|
||||
val STONE_QUARRIED = TilePropCodex.idDamageToIndex(1, 1)
|
||||
val STONE_TILE_WHITE = TilePropCodex.idDamageToIndex(1, 2)
|
||||
val STONE_BRICKS = TilePropCodex.idDamageToIndex(1, 3)
|
||||
|
||||
val DIRT = TilePropCodex.idDamageToIndex(2, 0)
|
||||
val GRASS = TilePropCodex.idDamageToIndex(2, 1)
|
||||
|
||||
@@ -24,16 +24,23 @@ object TilePropUtil {
|
||||
|
||||
val random = HQRNG();
|
||||
|
||||
var flickerPatternThis = getNewRandom()
|
||||
var flickerPatternNext = getNewRandom()
|
||||
//var flickerPatternThis = getNewRandom()
|
||||
//var flickerPatternNext = getNewRandom()
|
||||
var flickerP0 = getNewRandom()
|
||||
var flickerP1 = getNewRandom()
|
||||
var flickerP2 = getNewRandom()
|
||||
var flickerP3 = getNewRandom()
|
||||
|
||||
init {
|
||||
|
||||
}
|
||||
|
||||
private fun getTorchFlicker(baseLum: Int): Int {
|
||||
val funcY = linearInterpolation1D(flickerPatternThis, flickerPatternNext,
|
||||
flickerFuncX.toFloat() / flickerFuncDomain
|
||||
//val funcY = linearInterpolation1D(flickerPatternThis, flickerPatternNext,
|
||||
// flickerFuncX.toFloat() / flickerFuncDomain
|
||||
//)
|
||||
val funcY = FastMath.interpolateCatmullRom(0.0f, flickerFuncX.toFloat() / flickerFuncDomain,
|
||||
flickerP0, flickerP1, flickerP2, flickerP3
|
||||
)
|
||||
|
||||
return LightmapRenderer.alterBrightnessUniform(baseLum, funcY)
|
||||
@@ -63,8 +70,12 @@ object TilePropUtil {
|
||||
if (flickerFuncX > flickerFuncDomain) {
|
||||
flickerFuncX -= flickerFuncDomain
|
||||
|
||||
flickerPatternThis = flickerPatternNext
|
||||
flickerPatternNext = getNewRandom()
|
||||
//flickerPatternThis = flickerPatternNext
|
||||
//flickerPatternNext = getNewRandom()
|
||||
flickerP0 = flickerP1
|
||||
flickerP1 = flickerP2
|
||||
flickerP2 = flickerP3
|
||||
flickerP3 = getNewRandom()
|
||||
}
|
||||
|
||||
// breath-related vars
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
"0"; "0";"TILE_AIR" ; "8396808"; "0"; "1"; "1"; "0"; "0"; "0"; "0"; "0"; "0"; "0";"4"
|
||||
"1"; "0";"TILE_STONE" ; "33587232"; "25";"2400"; "0"; "1"; "1"; "0"; "1"; "0"; "0"; "0";"16"
|
||||
"1"; "1";"TILE_STONE_QUARRIED" ; "33587232"; "25";"2400"; "0"; "1"; "1"; "0"; "1"; "1"; "0"; "0";"16"
|
||||
"1"; "2";"TILE_STONE_TILE_WHITE" ; "33587232"; "25";"2400"; "0"; "1"; "1"; "0"; "1"; "2"; "0"; "0";"16"
|
||||
"1"; "3";"TILE_STONE_BRICKS" ; "33587232"; "25";"2400"; "0"; "1"; "1"; "0"; "1"; "3"; "0"; "0";"16"
|
||||
"2"; "0";"TILE_DIRT" ; "33587232"; "6";"1400"; "0"; "1"; "1"; "0"; "2"; "0"; "0"; "0";"16"
|
||||
"2"; "1";"TILE_GRASS" ; "33587232"; "6";"1400"; "0"; "1"; "1"; "0"; "2"; "1"; "0"; "0";"16"
|
||||
"3"; "0";"TILE_PLANK_NORMAL" ; "33587232"; "12"; "740"; "0"; "1"; "1"; "0"; "3"; "0"; "0"; "0";"16"
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 1 and column 18.
|
@@ -89,8 +89,8 @@ class BasicDebugInfoWindow:UICanvas {
|
||||
+ (hitbox.pointedY / MapDrawer.TILE_SIZE).toInt().toString()
|
||||
+ ")")
|
||||
|
||||
printLine(g, 3, "veloX reported $ccG${if (player.physSleep) "(sleep)" else player.moveDelta.x}")
|
||||
printLine(g, 4, "veloY reported $ccG${if (player.physSleep) "(sleep)" else player.moveDelta.y}")
|
||||
printLine(g, 3, "veloX reported $ccG${player.moveDelta.x}")
|
||||
printLine(g, 4, "veloY reported $ccG${player.moveDelta.y}")
|
||||
|
||||
printLineColumn(g, 2, 3, "veloX measured $ccG${xdelta}")
|
||||
printLineColumn(g, 2, 4, "veloY measured $ccG${ydelta}")
|
||||
|
||||
@@ -1,873 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2015 William Bittle http://www.dyn4j.org/
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||
* provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
* and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
||||
* and the following disclaimer in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
|
||||
* promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Kotlin translated and modified code Copyright (c) 2016 Torvald aka skyhi14.
|
||||
*/
|
||||
package org.dyn4j.geometry
|
||||
|
||||
import org.dyn4j.Epsilon
|
||||
|
||||
/**
|
||||
* This class represents a vector or point in 2D space.
|
||||
*
|
||||
*
|
||||
* The operations [ChainedVector2.setMagnitude], [ChainedVector2.getNormalized],
|
||||
* [ChainedVector2.project], and [ChainedVector2.normalize] require the [ChainedVector2]
|
||||
* to be non-zero in length.
|
||||
*
|
||||
*
|
||||
* Some methods also return the vector to facilitate chaining. For example:
|
||||
*
|
||||
* Vector a = new Vector();
|
||||
* a.zero().plus(1, 2).times(2);
|
||||
*
|
||||
* In this Kotlin code, you can use regular operations like + - * /.
|
||||
*
|
||||
* |operator |function |
|
||||
* |-----------|------------|
|
||||
* |a + b |a.plus(b) | equivalent of plusAssign
|
||||
* |a - b |a.minus(b) | equivalent of minusAssign
|
||||
* |a * b |a.times(b) | equivalent of timesAssign
|
||||
* |a / b |a.div(b) | equivalent of divAssign
|
||||
* |a dot b |a.dot(b) | equivalent of dotAssign
|
||||
* |a cross b |a.cross(b) | equivalent of crossAssign
|
||||
* |!a |negate(a) |
|
||||
* |a rotate th|a.rotate(th)| equivalent of rotateAssign
|
||||
*
|
||||
* @author William Bittle
|
||||
* *
|
||||
* @version 3.1.11
|
||||
* *
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class ChainedVector2 {
|
||||
|
||||
/** The magnitude of the x component of this [ChainedVector2] */
|
||||
var x: Double = 0.toDouble()
|
||||
|
||||
/** The magnitude of the y component of this [ChainedVector2] */
|
||||
var y: Double = 0.toDouble()
|
||||
|
||||
/** Default constructor. */
|
||||
constructor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
* @param vector the [ChainedVector2] to copy from
|
||||
*/
|
||||
constructor(vector: ChainedVector2) {
|
||||
this.x = vector.x
|
||||
this.y = vector.y
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional constructor.
|
||||
* @param x the x component
|
||||
* *
|
||||
* @param y the y component
|
||||
*/
|
||||
constructor(x: Double, y: Double) {
|
||||
this.x = x
|
||||
this.y = y
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional constructor.
|
||||
* @param vector non-chainable Vector2
|
||||
*/
|
||||
constructor(vector: Vector2) {
|
||||
this.x = vector.x
|
||||
this.y = vector.y
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a [ChainedVector2] from the first point to the second point.
|
||||
* @param x1 the x coordinate of the first point
|
||||
* *
|
||||
* @param y1 the y coordinate of the first point
|
||||
* *
|
||||
* @param x2 the x coordinate of the second point
|
||||
* *
|
||||
* @param y2 the y coordinate of the second point
|
||||
*/
|
||||
constructor(x1: Double, y1: Double, x2: Double, y2: Double) {
|
||||
this.x = x2 - x1
|
||||
this.y = y2 - y1
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a [ChainedVector2] from the first point to the second point.
|
||||
* @param p1 the first point
|
||||
* *
|
||||
* @param p2 the second point
|
||||
*/
|
||||
constructor(p1: ChainedVector2, p2: ChainedVector2) {
|
||||
this.x = p2.x - p1.x
|
||||
this.y = p2.y - p1.y
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a unit length vector in the given direction.
|
||||
* @param direction the direction in radians
|
||||
* *
|
||||
* @since 3.0.1
|
||||
*/
|
||||
constructor(direction: Double) {
|
||||
this.x = Math.cos(direction)
|
||||
this.y = Math.sin(direction)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this [ChainedVector2].
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
fun copy(): ChainedVector2 {
|
||||
return ChainedVector2(this.x, this.y)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the distance from this point to the given point.
|
||||
* @param x the x coordinate of the point
|
||||
* *
|
||||
* @param y the y coordinate of the point
|
||||
* *
|
||||
* @return double
|
||||
*/
|
||||
fun distance(x: Double, y: Double): Double {
|
||||
//return Math.hypot(this.x - x, this.y - y);
|
||||
val dx = this.x - x
|
||||
val dy = this.y - y
|
||||
return Math.sqrt(dx * dx + dy * dy)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the distance from this point to the given point.
|
||||
* @param point the point
|
||||
* *
|
||||
* @return double
|
||||
*/
|
||||
fun distance(point: ChainedVector2): Double {
|
||||
//return Math.hypot(this.x - point.x, this.y - point.y);
|
||||
val dx = this.x - point.x
|
||||
val dy = this.y - point.y
|
||||
return Math.sqrt(dx * dx + dy * dy)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the distance from this point to the given point squared.
|
||||
* @param x the x coordinate of the point
|
||||
* *
|
||||
* @param y the y coordinate of the point
|
||||
* *
|
||||
* @return double
|
||||
*/
|
||||
fun distanceSquared(x: Double, y: Double): Double {
|
||||
//return (this.x - x) * (this.x - x) + (this.y - y) * (this.y - y);
|
||||
val dx = this.x - x
|
||||
val dy = this.y - y
|
||||
return dx * dx + dy * dy
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the distance from this point to the given point squared.
|
||||
* @param point the point
|
||||
* *
|
||||
* @return double
|
||||
*/
|
||||
fun distanceSquared(point: ChainedVector2): Double {
|
||||
//return (this.x - point.x) * (this.x - point.x) + (this.y - point.y) * (this.y - point.y);
|
||||
val dx = this.x - point.x
|
||||
val dy = this.y - point.y
|
||||
return dx * dx + dy * dy
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
override fun hashCode(): Int {
|
||||
val prime = 31
|
||||
var result = 1
|
||||
var temp: Long
|
||||
temp = java.lang.Double.doubleToLongBits(x)
|
||||
result = prime * result + (temp xor temp.ushr(32)).toInt()
|
||||
temp = java.lang.Double.doubleToLongBits(y)
|
||||
result = prime * result + (temp xor temp.ushr(32)).toInt()
|
||||
return result
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
override fun equals(obj: Any?): Boolean {
|
||||
if (obj == null) return false
|
||||
if (obj === this) return true
|
||||
if (obj is ChainedVector2) {
|
||||
return this.x == obj.x && this.y == obj.y
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the x and y components of this [ChainedVector2]
|
||||
* are the same as the given [ChainedVector2].
|
||||
* @param vector the [ChainedVector2] to compare to
|
||||
* *
|
||||
* @return boolean
|
||||
*/
|
||||
fun equals(vector: ChainedVector2?): Boolean {
|
||||
if (vector == null) return false
|
||||
if (this === vector) {
|
||||
return true
|
||||
}
|
||||
else {
|
||||
return this.x == vector.x && this.y == vector.y
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the x and y components of this [ChainedVector2]
|
||||
* are the same as the given x and y components.
|
||||
* @param x the x coordinate of the [ChainedVector2] to compare to
|
||||
* *
|
||||
* @param y the y coordinate of the [ChainedVector2] to compare to
|
||||
* *
|
||||
* @return boolean
|
||||
*/
|
||||
fun equals(x: Double, y: Double): Boolean {
|
||||
return this.x == x && this.y == y
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
override fun toString(): String {
|
||||
val sb = StringBuilder()
|
||||
sb.append("(").append(this.x).append(", ").append(this.y).append(")")
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this [ChainedVector2] to the given [ChainedVector2].
|
||||
* @param vector the [ChainedVector2] to set this [ChainedVector2] to
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun set(vector: ChainedVector2): ChainedVector2 {
|
||||
this.x = vector.x
|
||||
this.y = vector.y
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this [ChainedVector2] to the given [ChainedVector2].
|
||||
* @param x the x component of the [ChainedVector2] to set this [ChainedVector2] to
|
||||
* *
|
||||
* @param y the y component of the [ChainedVector2] to set this [ChainedVector2] to
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun set(x: Double, y: Double): ChainedVector2 {
|
||||
this.x = x
|
||||
this.y = y
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the x component of this [ChainedVector2].
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
val xComponent: ChainedVector2
|
||||
get() = ChainedVector2(this.x, 0.0)
|
||||
|
||||
/**
|
||||
* Returns the y component of this [ChainedVector2].
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
val yComponent: ChainedVector2
|
||||
get() = ChainedVector2(0.0, this.y)
|
||||
|
||||
/**
|
||||
* Returns the magnitude of this [ChainedVector2].
|
||||
* @return double
|
||||
*/
|
||||
// the magnitude is just the pathagorean theorem
|
||||
val magnitude: Double
|
||||
get() = Math.sqrt(this.x * this.x + this.y * this.y)
|
||||
|
||||
/**
|
||||
* Returns the magnitude of this [ChainedVector2] squared.
|
||||
* @return double
|
||||
*/
|
||||
val magnitudeSquared: Double
|
||||
get() = this.x * this.x + this.y * this.y
|
||||
|
||||
/**
|
||||
* Sets the magnitude of the [ChainedVector2].
|
||||
* @param magnitude the magnitude
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun setMagnitude(magnitude: Double): ChainedVector2 {
|
||||
// check the given magnitude
|
||||
if (Math.abs(magnitude) <= Epsilon.E) {
|
||||
this.x = 0.0
|
||||
this.y = 0.0
|
||||
return this
|
||||
}
|
||||
// is this vector a zero vector?
|
||||
if (this.isZero) {
|
||||
return this
|
||||
}
|
||||
// get the magnitude
|
||||
var mag = Math.sqrt(this.x * this.x + this.y * this.y)
|
||||
// normalize and multiply by the new magnitude
|
||||
mag = magnitude / mag
|
||||
this.x *= mag
|
||||
this.y *= mag
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the direction of this [ChainedVector2]
|
||||
* as an angle in radians.
|
||||
* @return double angle in radians [-, ]
|
||||
*/
|
||||
val direction: Double
|
||||
get() = Math.atan2(this.y, this.x)
|
||||
|
||||
/**
|
||||
* Sets the direction of this [ChainedVector2].
|
||||
* @param angle angle in radians
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun setDirection(angle: Double): ChainedVector2 {
|
||||
//double magnitude = Math.hypot(this.x, this.y);
|
||||
val magnitude = Math.sqrt(this.x * this.x + this.y * this.y)
|
||||
this.x = magnitude * Math.cos(angle)
|
||||
this.y = magnitude * Math.sin(angle)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given [ChainedVector2] to this [ChainedVector2].
|
||||
* @param vector the [ChainedVector2]
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun plus(vector: ChainedVector2): ChainedVector2 {
|
||||
this.x += vector.x
|
||||
this.y += vector.y
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given [ChainedVector2] to this [ChainedVector2].
|
||||
* @param x the x component of the [ChainedVector2]
|
||||
* *
|
||||
* @param y the y component of the [ChainedVector2]
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun plus(x: Double, y: Double): ChainedVector2 {
|
||||
this.x += x
|
||||
this.y += y
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds this [ChainedVector2] and the given [ChainedVector2] returning
|
||||
* a new [ChainedVector2] containing the result.
|
||||
* @param vector the [ChainedVector2]
|
||||
* *
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
fun sum(vector: ChainedVector2): ChainedVector2 {
|
||||
return ChainedVector2(this.x + vector.x, this.y + vector.y)
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds this [ChainedVector2] and the given [ChainedVector2] returning
|
||||
* a new [ChainedVector2] containing the result.
|
||||
* @param x the x component of the [ChainedVector2]
|
||||
* *
|
||||
* @param y the y component of the [ChainedVector2]
|
||||
* *
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
fun sum(x: Double, y: Double): ChainedVector2 {
|
||||
return ChainedVector2(this.x + x, this.y + y)
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts the given [ChainedVector2] from this [ChainedVector2].
|
||||
* @param vector the [ChainedVector2]
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun minus(vector: ChainedVector2): ChainedVector2 {
|
||||
this.x -= vector.x
|
||||
this.y -= vector.y
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts the given [ChainedVector2] from this [ChainedVector2].
|
||||
* @param x the x component of the [ChainedVector2]
|
||||
* *
|
||||
* @param y the y component of the [ChainedVector2]
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun minus(x: Double, y: Double): ChainedVector2 {
|
||||
this.x -= x
|
||||
this.y -= y
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts the given [ChainedVector2] from this [ChainedVector2] returning
|
||||
* a new [ChainedVector2] containing the result.
|
||||
* @param vector the [ChainedVector2]
|
||||
* *
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
fun difference(vector: ChainedVector2): ChainedVector2 {
|
||||
return ChainedVector2(this.x - vector.x, this.y - vector.y)
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts the given [ChainedVector2] from this [ChainedVector2] returning
|
||||
* a new [ChainedVector2] containing the result.
|
||||
* @param x the x component of the [ChainedVector2]
|
||||
* *
|
||||
* @param y the y component of the [ChainedVector2]
|
||||
* *
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
fun difference(x: Double, y: Double): ChainedVector2 {
|
||||
return ChainedVector2(this.x - x, this.y - y)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a [ChainedVector2] from this [ChainedVector2] to the given [ChainedVector2].
|
||||
* @param vector the [ChainedVector2]
|
||||
* *
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
fun to(vector: ChainedVector2): ChainedVector2 {
|
||||
return ChainedVector2(vector.x - this.x, vector.y - this.y)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a [ChainedVector2] from this [ChainedVector2] to the given [ChainedVector2].
|
||||
* @param x the x component of the [ChainedVector2]
|
||||
* *
|
||||
* @param y the y component of the [ChainedVector2]
|
||||
* *
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
fun to(x: Double, y: Double): ChainedVector2 {
|
||||
return ChainedVector2(x - this.x, y - this.y)
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies this [ChainedVector2] by the given scalar.
|
||||
* @param scalar the scalar
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun times(scalar: Double): ChainedVector2 {
|
||||
this.x *= scalar
|
||||
this.y *= scalar
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies this [ChainedVector2] by the given scalar.
|
||||
* @param scalar the scalar
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun div(scalar: Double): ChainedVector2 {
|
||||
this.x /= scalar
|
||||
this.y /= scalar
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies this [ChainedVector2] by the given scalar returning
|
||||
* a new [ChainedVector2] containing the result.
|
||||
* @param scalar the scalar
|
||||
* *
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
fun product(scalar: Double): ChainedVector2 {
|
||||
return ChainedVector2(this.x * scalar, this.y * scalar)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the dot product of the given [ChainedVector2]
|
||||
* and this [ChainedVector2].
|
||||
* @param vector the [ChainedVector2]
|
||||
* *
|
||||
* @return double
|
||||
*/
|
||||
fun dot(vector: ChainedVector2): Double {
|
||||
return this.x * vector.x + this.y * vector.y
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the dot product of the given [ChainedVector2]
|
||||
* and this [ChainedVector2].
|
||||
* @param x the x component of the [ChainedVector2]
|
||||
* *
|
||||
* @param y the y component of the [ChainedVector2]
|
||||
* *
|
||||
* @return double
|
||||
*/
|
||||
fun dot(x: Double, y: Double): Double {
|
||||
return this.x * x + this.y * y
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cross product of the this [ChainedVector2] and the given [ChainedVector2].
|
||||
* @param vector the [ChainedVector2]
|
||||
* *
|
||||
* @return double
|
||||
*/
|
||||
fun cross(vector: ChainedVector2): Double {
|
||||
return this.x * vector.y - this.y * vector.x
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cross product of the this [ChainedVector2] and the given [ChainedVector2].
|
||||
* @param x the x component of the [ChainedVector2]
|
||||
* *
|
||||
* @param y the y component of the [ChainedVector2]
|
||||
* *
|
||||
* @return double
|
||||
*/
|
||||
fun cross(x: Double, y: Double): Double {
|
||||
return this.x * y - this.y * x
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cross product of this [ChainedVector2] and the z value of the right [ChainedVector2].
|
||||
* @param z the z component of the [ChainedVector2]
|
||||
* *
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
fun cross(z: Double): ChainedVector2 {
|
||||
return ChainedVector2(-1.0 * this.y * z, this.x * z)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given [ChainedVector2] is orthogonal (perpendicular)
|
||||
* to this [ChainedVector2].
|
||||
*
|
||||
*
|
||||
* If the dot product of this vector and the given vector is
|
||||
* zero then we know that they are perpendicular
|
||||
* @param vector the [ChainedVector2]
|
||||
* *
|
||||
* @return boolean
|
||||
*/
|
||||
fun isOrthogonal(vector: ChainedVector2): Boolean {
|
||||
return if (Math.abs(this.x * vector.x + this.y * vector.y) <= Epsilon.E) true else false
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given [ChainedVector2] is orthogonal (perpendicular)
|
||||
* to this [ChainedVector2].
|
||||
*
|
||||
*
|
||||
* If the dot product of this vector and the given vector is
|
||||
* zero then we know that they are perpendicular
|
||||
* @param x the x component of the [ChainedVector2]
|
||||
* *
|
||||
* @param y the y component of the [ChainedVector2]
|
||||
* *
|
||||
* @return boolean
|
||||
*/
|
||||
fun isOrthogonal(x: Double, y: Double): Boolean {
|
||||
return if (Math.abs(this.x * x + this.y * y) <= Epsilon.E) true else false
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this [ChainedVector2] is the zero [ChainedVector2].
|
||||
* @return boolean
|
||||
*/
|
||||
val isZero: Boolean
|
||||
get() = Math.abs(this.x) <= Epsilon.E && Math.abs(this.y) <= Epsilon.E
|
||||
|
||||
/**
|
||||
* Negates this [ChainedVector2].
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun not() = negate()
|
||||
|
||||
/**
|
||||
* Negates this [ChainedVector2].
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun negate(): ChainedVector2 {
|
||||
this.x *= -1.0
|
||||
this.y *= -1.0
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a [ChainedVector2] which is the negative of this [ChainedVector2].
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
val negative: ChainedVector2
|
||||
get() = ChainedVector2(-this.x, -this.y)
|
||||
|
||||
/**
|
||||
* Sets the [ChainedVector2] to the zero [ChainedVector2]
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun zero(): ChainedVector2 {
|
||||
this.x = 0.0
|
||||
this.y = 0.0
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates about the origin.
|
||||
* @param theta the rotation angle in radians
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun rotate(theta: Double): ChainedVector2 {
|
||||
val cos = Math.cos(theta)
|
||||
val sin = Math.sin(theta)
|
||||
val x = this.x
|
||||
val y = this.y
|
||||
this.x = x * cos - y * sin
|
||||
this.y = x * sin + y * cos
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the [ChainedVector2] about the given coordinates.
|
||||
* @param theta the rotation angle in radians
|
||||
* *
|
||||
* @param x the x coordinate to rotate about
|
||||
* *
|
||||
* @param y the y coordinate to rotate about
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun rotate(theta: Double, x: Double, y: Double): ChainedVector2 {
|
||||
this.x -= x
|
||||
this.y -= y
|
||||
this.rotate(theta)
|
||||
this.x += x
|
||||
this.y += y
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates the [ChainedVector2] about the given point.
|
||||
* @param theta the rotation angle in radians
|
||||
* *
|
||||
* @param point the point to rotate about
|
||||
* *
|
||||
* @return [ChainedVector2] this vector
|
||||
*/
|
||||
fun rotate(theta: Double, point: ChainedVector2): ChainedVector2 {
|
||||
return this.rotate(theta, point.x, point.y)
|
||||
}
|
||||
|
||||
/**
|
||||
* Projects this [ChainedVector2] onto the given [ChainedVector2].
|
||||
* @param vector the [ChainedVector2]
|
||||
* *
|
||||
* @return [ChainedVector2] the projected [ChainedVector2]
|
||||
*/
|
||||
fun project(vector: ChainedVector2): ChainedVector2 {
|
||||
val dotProd = this.dot(vector)
|
||||
var denominator = vector.dot(vector)
|
||||
if (denominator <= Epsilon.E) return ChainedVector2()
|
||||
denominator = dotProd / denominator
|
||||
return ChainedVector2(denominator * vector.x, denominator * vector.y)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the right-handed normal of this vector.
|
||||
* @return [ChainedVector2] the right hand orthogonal [ChainedVector2]
|
||||
*/
|
||||
val rightHandOrthogonalVector: ChainedVector2
|
||||
get() = ChainedVector2(-this.y, this.x)
|
||||
|
||||
/**
|
||||
* Sets this vector to the right-handed normal of this vector.
|
||||
* @return [ChainedVector2] this vector
|
||||
* *
|
||||
* @see .getRightHandOrthogonalVector
|
||||
*/
|
||||
fun right(): ChainedVector2 {
|
||||
val temp = this.x
|
||||
this.x = -this.y
|
||||
this.y = temp
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the left-handed normal of this vector.
|
||||
* @return [ChainedVector2] the left hand orthogonal [ChainedVector2]
|
||||
*/
|
||||
val leftHandOrthogonalVector: ChainedVector2
|
||||
get() = ChainedVector2(this.y, -this.x)
|
||||
|
||||
/**
|
||||
* Sets this vector to the left-handed normal of this vector.
|
||||
* @return [ChainedVector2] this vector
|
||||
* *
|
||||
* @see .getLeftHandOrthogonalVector
|
||||
*/
|
||||
fun left(): ChainedVector2 {
|
||||
val temp = this.x
|
||||
this.x = this.y
|
||||
this.y = -temp
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unit [ChainedVector2] of this [ChainedVector2].
|
||||
*
|
||||
*
|
||||
* This method requires the length of this [ChainedVector2] is not zero.
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
val normalized: ChainedVector2
|
||||
get() {
|
||||
var magnitude = this.magnitude
|
||||
if (magnitude <= Epsilon.E) return ChainedVector2()
|
||||
magnitude = 1.0 / magnitude
|
||||
return ChainedVector2(this.x * magnitude, this.y * magnitude)
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this [ChainedVector2] into a unit [ChainedVector2] and returns
|
||||
* the magnitude before normalization.
|
||||
*
|
||||
*
|
||||
* This method requires the length of this [ChainedVector2] is not zero.
|
||||
* @return double
|
||||
*/
|
||||
fun normalize(): Double {
|
||||
val magnitude = Math.sqrt(this.x * this.x + this.y * this.y)
|
||||
if (magnitude <= Epsilon.E) return 0.0
|
||||
val m = 1.0 / magnitude
|
||||
this.x *= m
|
||||
this.y *= m
|
||||
//return 1.0 / m;
|
||||
return magnitude
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the smallest angle between the given [ChainedVector2]s.
|
||||
*
|
||||
*
|
||||
* Returns the angle in radians in the range - to .
|
||||
* @param vector the [ChainedVector2]
|
||||
* *
|
||||
* @return angle in radians [-, ]
|
||||
*/
|
||||
fun getAngleBetween(vector: ChainedVector2): Double {
|
||||
val a = Math.atan2(vector.y, vector.x) - Math.atan2(this.y, this.x)
|
||||
if (a > Math.PI) return a - 2.0 * Math.PI
|
||||
if (a < -Math.PI) return a + 2.0 * Math.PI
|
||||
return a
|
||||
}
|
||||
|
||||
fun toVector(): Vector2 {
|
||||
return Vector2(x, y)
|
||||
}
|
||||
|
||||
companion object {
|
||||
/** A vector representing the x-axis; this vector should not be changed at runtime; used internally */
|
||||
internal val X_AXIS = ChainedVector2(1.0, 0.0)
|
||||
|
||||
/** A vector representing the y-axis; this vector should not be changed at runtime; used internally */
|
||||
internal val Y_AXIS = ChainedVector2(0.0, 1.0)
|
||||
|
||||
/**
|
||||
* Returns a new [ChainedVector2] given the magnitude and direction.
|
||||
* @param magnitude the magnitude of the [ChainedVector2]
|
||||
* *
|
||||
* @param direction the direction of the [ChainedVector2] in radians
|
||||
* *
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
fun create(magnitude: Double, direction: Double): ChainedVector2 {
|
||||
val x = magnitude * Math.cos(direction)
|
||||
val y = magnitude * Math.sin(direction)
|
||||
return ChainedVector2(x, y)
|
||||
}
|
||||
|
||||
/**
|
||||
* The triple product of [ChainedVector2]s is defined as:
|
||||
*
|
||||
* a x (b x c)
|
||||
*
|
||||
* However, this method performs the following triple product:
|
||||
*
|
||||
* (a x b) x c
|
||||
*
|
||||
* this can be simplified to:
|
||||
*
|
||||
* -a * (b c) + b * (a c)
|
||||
*
|
||||
* or:
|
||||
*
|
||||
* b * (a c) - a * (b c)
|
||||
*
|
||||
* @param a the a [ChainedVector2] in the above equation
|
||||
* *
|
||||
* @param b the b [ChainedVector2] in the above equation
|
||||
* *
|
||||
* @param c the c [ChainedVector2] in the above equation
|
||||
* *
|
||||
* @return [ChainedVector2]
|
||||
*/
|
||||
fun tripleProduct(a: ChainedVector2, b: ChainedVector2, c: ChainedVector2): ChainedVector2 {
|
||||
// expanded version of above formula
|
||||
val r = ChainedVector2()
|
||||
// perform a.dot(c)
|
||||
val ac = a.x * c.x + a.y * c.y
|
||||
// perform b.dot(c)
|
||||
val bc = b.x * c.x + b.y * c.y
|
||||
// perform b * a.dot(c) - a * b.dot(c)
|
||||
r.x = b.x * ac - a.x * bc
|
||||
r.y = b.y * ac - a.y * bc
|
||||
return r
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,22 +40,23 @@ import org.dyn4j.Epsilon
|
||||
*
|
||||
* Chaining is not available.
|
||||
*
|
||||
* In this Kotlin code, you can use regular operations like + - * /.
|
||||
* In this Kotlin code, you can use regular operators like + - * /.
|
||||
*
|
||||
* |operator |function |
|
||||
* |-----------|------------|
|
||||
* |a + b |Vector(a).plus(b) |
|
||||
* |a - b |Vector(a).minus(b) |
|
||||
* |a * b |Vector(a).times(b) |
|
||||
* |a / b |Vector(a).div(b) |
|
||||
* |a += b |Vector(a).plusAssign(b)|
|
||||
* |a -= b |Vector(a).minusAssign(b)|
|
||||
* |a *= b |Vector(a).timesAssign(b)|
|
||||
* |a /= b |Vector(a).divAssign(b)|
|
||||
* |a dot b |Vector(a).dot(b) |
|
||||
* |a cross b |Vector(a).cross(b) |
|
||||
* |!a |Vector(negate(a) |
|
||||
* |a rotate th|Vector(a).rotate(th)|
|
||||
* |operator |function |
|
||||
* |-----------|---------------------|
|
||||
* |a + b |Vector2(a).plus(b) |
|
||||
* |a - b |Vector2(a).minus(b) |
|
||||
* |a * b |Vector2(a).times(b) |
|
||||
* |a / b |Vector2(a).div(b) |
|
||||
* |a += b |a.plusAssign(b) |
|
||||
* |a -= b |a.minusAssign(b) |
|
||||
* |a *= b |a.timesAssign(b) |
|
||||
* |a /= b |a.divAssign(b) |
|
||||
* |a dot b |Vector2(a).dot(b) |
|
||||
* |a cross b |Vector2(a).cross(b) |
|
||||
* |!a |this.negative |
|
||||
* |a rotate th|Vector2(a).rotate(th)|
|
||||
* |a to b |Vector2(a).to(b) |
|
||||
*
|
||||
* @author William Bittle
|
||||
* *
|
||||
@@ -392,22 +393,22 @@ class Vector2 {
|
||||
|
||||
/**
|
||||
* Creates a [Vector2] from this [Vector2] to the given [Vector2].
|
||||
* @param vector the [Vector2]
|
||||
* @param other : the other [Vector2]
|
||||
* *
|
||||
* @return [Vector2]
|
||||
*/
|
||||
fun to(vector: Vector2): Vector2 {
|
||||
return Vector2(vector.x - this.x, vector.y - this.y)
|
||||
infix fun to(other: Vector2): Vector2 {
|
||||
return Vector2(other.x - this.x, other.y - this.y)
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies this [Vector2] by the given scalar.
|
||||
* Get product of this vector.
|
||||
* @param scalar the scalar
|
||||
* *
|
||||
* @return [Vector2] this vector
|
||||
*/
|
||||
operator fun times(scalar: Double): Vector2 {
|
||||
return Vector2(this.x * scalar, this.y * scalar)
|
||||
return product(scalar)
|
||||
}
|
||||
|
||||
operator fun timesAssign(scalar: Double) {
|
||||
@@ -540,21 +541,13 @@ class Vector2 {
|
||||
* Negates this [Vector2].
|
||||
* @return [Vector2] this vector
|
||||
*/
|
||||
operator fun not() = negate()
|
||||
operator fun not() = this.negative
|
||||
|
||||
/**
|
||||
* Negates this [Vector2].
|
||||
* @return [Vector2] this vector
|
||||
*/
|
||||
operator fun unaryMinus() = negate()
|
||||
|
||||
/**
|
||||
* Negates this [Vector2].
|
||||
* @return [Vector2] this vector
|
||||
*/
|
||||
fun negate(): Vector2 {
|
||||
return Vector2(-x, -y)
|
||||
}
|
||||
operator fun unaryMinus() = this.negative
|
||||
|
||||
/**
|
||||
* Returns a [Vector2] which is the negative of this [Vector2].
|
||||
|
||||
22
work_files/civil_settlement.tmx
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.0" orientation="orthogonal" renderorder="right-down" width="512" height="100" tilewidth="16" tileheight="16" nextobjectid="3">
|
||||
<tileset firstgid="1" name="TerrarumTerrain" tilewidth="16" tileheight="16" tilecount="65536" columns="256">
|
||||
<image source="../res/graphics/terrain/terrain.png" width="4096" height="4096"/>
|
||||
</tileset>
|
||||
<tileset firstgid="65537" name="TerrarumWall" tilewidth="16" tileheight="16" tilecount="65536" columns="256">
|
||||
<image source="../res/graphics/terrain/wall.png" width="4096" height="4096"/>
|
||||
</tileset>
|
||||
<imagelayer name="Image Layer 1">
|
||||
<image source="../../../../Pictures/tiledmap_background_512_100.png"/>
|
||||
</imagelayer>
|
||||
<layer name="Wall" width="512" height="100">
|
||||
<data encoding="base64" compression="zlib">
|
||||
eJzt2TEOwjAQRcEYTsL9L4loECBsLGC9gZ2RfpUi7p6jbBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQ4dTaddWeAUBVe+qx/gNAjNseVhsAVJXd4MwBQFXZDc4cAFSV3eDMAUBV2Q2+rB3vt+q9AFDVqtY+22P3V98DAKCq6Mb29qr9K+4AAFBVZF9H038AyBPZ19H0HwDyRPZ1NP0HgDyRfR1N/wEgT6+Lo2Z+49ls/yPPAgBV6T8A1KP/AFBPr5HR8/8fAPJE9nU0/QeAtSKbOjv9B4C1Ips6O/0HgLUimzo7/QeAtSKbOrs2ucgzAMCva4d2t1mRfR3N9z8AfO7d/u+d/gNAn/5rPwD1/Gv/AYA+/QcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPnEGIseuBw==
|
||||
</data>
|
||||
</layer>
|
||||
<layer name="Terrain" width="512" height="100">
|
||||
<data encoding="base64" compression="zlib">
|
||||
eJzt3WtrE0EYhuHdtKhEWvCAYL7VA1LB///3TNDFsG7SPUx23p25brjwS9VASZ7ZNEmbRpIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkSVIJvd/lvgWSJGntTvvvDCBJUj2ddr+1/5IkVZX9lySprrrtb50BJEmqpv7+OwNIklR2Q9vf7b8zgCRJZXZp/50BpHr72TbNl6Nvbe5bIukWXdt+PweQ6u35uPtPR1/tv1RU3XX9S9vvDCDVmf2XymvK7jsDSHVm/6Vt1F3PjzFn+9vev9H/fyWVlf2X4rdk01OcBTw3IJWX/ZfitvR6PvV5QFI5Rdv//V3TvPrr/i73rZHyFWn77b9UXlH2v9v912eb/+AcoEqLtv3OAFJ55d7/x4Hd7/fgDKCKirr99l8qq9z7P7a39l+FF3n3nQGk8rL/Up5SvWfPGUDSnOy/dL3D7v+tHnKtlO/Rj8D+S9sv5/5/2DfNp/2fbf94/PPdBd3XSGt3mLiJt/hMnojsv7T9Ilz/j9l2+68cfQ6wtVGNfe5Dqq2t3C/svzTclGv/2m3l8U5K1Zjn+iLdL7rf9Xvuyf5Lg7n2dwaQ+s35mV6Ens/2vs/+S/9y7Z/+DOBsoK2V6nU8Efp13PjvF/zIvP9e/6co2f40Z4Chx03PEShSa71mV8M9vvDZf12nzwB84wygG3ZIfJ/n+vkgUlN+t/KU930qfxHekyMpbq75850Dcu5rii1wFohXtPfdSopT/zN9cj8+cNmSa/O1P5PhlrfV8xDD5byuH0vSul373L7cjweQUmnnhZxnuCjfn9T67/3r263g/ux1hvuFf19lNvbzdkt4XIBccu+R++66Lr33r7PW7ei2vJ3JOWFeqXbVfR9gW6Ls/1qWPj9R2u7m/n4AkEdt+z/X3J9t2F0AIrL/AFAf+w8A9bH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAq/AQvXoTU=
|
||||
</data>
|
||||
</layer>
|
||||
</map>
|
||||