diff --git a/res/graphics/fonts/han_johab.png b/res/graphics/fonts/han_johab.png index 376ca60a7..351d61d73 100644 Binary files a/res/graphics/fonts/han_johab.png and b/res/graphics/fonts/han_johab.png differ diff --git a/res/graphics/gui/progress_round_sheet.png b/res/graphics/gui/progress_round_sheet.png index 583ab2c22..d19e06cf7 100644 Binary files a/res/graphics/gui/progress_round_sheet.png and b/res/graphics/gui/progress_round_sheet.png differ diff --git a/res/graphics/terrain/terrain.png b/res/graphics/terrain/terrain.png index 477b6b02a..99e7f0f32 100644 Binary files a/res/graphics/terrain/terrain.png and b/res/graphics/terrain/terrain.png differ diff --git a/res/graphics/terrain/wall.png b/res/graphics/terrain/wall.png index d680d2d11..bbd263fb5 100644 Binary files a/res/graphics/terrain/wall.png and b/res/graphics/terrain/wall.png differ diff --git a/res/locales/polyglot.csv b/res/locales/polyglot.csv index ff5a0bbcd..31e0c7345 100644 --- a/res/locales/polyglot.csv +++ b/res/locales/polyglot.csv @@ -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" diff --git a/src/net/torvald/point/Point2d.kt b/src/net/torvald/point/Point2d.kt index 111beb2fc..5d62f55ac 100644 --- a/src/net/torvald/point/Point2d.kt +++ b/src/net/torvald/point/Point2d.kt @@ -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 diff --git a/src/net/torvald/spriteanimation/SpriteAnimation.kt b/src/net/torvald/spriteanimation/SpriteAnimation.kt index 347c69fe8..a2efd78e6 100644 --- a/src/net/torvald/spriteanimation/SpriteAnimation.kt +++ b/src/net/torvald/spriteanimation/SpriteAnimation.kt @@ -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 diff --git a/src/net/torvald/terrarum/COPYING.md b/src/net/torvald/terrarum/COPYING.md index f7a74d276..ea57aa429 100644 --- a/src/net/torvald/terrarum/COPYING.md +++ b/src/net/torvald/terrarum/COPYING.md @@ -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. \ No newline at end of file diff --git a/src/net/torvald/terrarum/StateFontPrinter.kt b/src/net/torvald/terrarum/StateFontPrinter.kt new file mode 100644 index 000000000..193a1a10e --- /dev/null +++ b/src/net/torvald/terrarum/StateFontPrinter.kt @@ -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 +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/Game.kt b/src/net/torvald/terrarum/StateGame.kt similarity index 99% rename from src/net/torvald/terrarum/Game.kt rename to src/net/torvald/terrarum/StateGame.kt index 4b876aeaa..c63d6181a 100644 --- a/src/net/torvald/terrarum/Game.kt +++ b/src/net/torvald/terrarum/StateGame.kt @@ -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( diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index d57c0d3f0..299e7d6cc 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -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 diff --git a/src/net/torvald/terrarum/console/CodexEdictis.kt b/src/net/torvald/terrarum/console/CodexEdictis.kt index cc8227429..5dbc94fef 100644 --- a/src/net/torvald/terrarum/console/CodexEdictis.kt +++ b/src/net/torvald/terrarum/console/CodexEdictis.kt @@ -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 diff --git a/src/net/torvald/terrarum/console/SetAV.kt b/src/net/torvald/terrarum/console/SetAV.kt index bfbd18210..9d04eb3c7 100644 --- a/src/net/torvald/terrarum/console/SetAV.kt +++ b/src/net/torvald/terrarum/console/SetAV.kt @@ -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 /** diff --git a/src/net/torvald/terrarum/console/TeleportPlayer.kt b/src/net/torvald/terrarum/console/TeleportPlayer.kt index 32509d494..a97f43c08 100644 --- a/src/net/torvald/terrarum/console/TeleportPlayer.kt +++ b/src/net/torvald/terrarum/console/TeleportPlayer.kt @@ -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 diff --git a/src/net/torvald/terrarum/console/ToggleNoClip.kt b/src/net/torvald/terrarum/console/ToggleNoClip.kt index 4bd17d63b..c81ecae8b 100644 --- a/src/net/torvald/terrarum/console/ToggleNoClip.kt +++ b/src/net/torvald/terrarum/console/ToggleNoClip.kt @@ -1,6 +1,6 @@ package net.torvald.terrarum.console -import net.torvald.terrarum.Game +import net.torvald.terrarum.StateGame import net.torvald.terrarum.Terrarum /** diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index 10dbf5a55..8036f1e84 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -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 - */ \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/Hitbox.kt b/src/net/torvald/terrarum/gameactors/Hitbox.kt index abe0d113d..85d5dd789 100644 --- a/src/net/torvald/terrarum/gameactors/Hitbox.kt +++ b/src/net/torvald/terrarum/gameactors/Hitbox.kt @@ -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) } diff --git a/src/net/torvald/terrarum/mapdrawer/MapCamera.kt b/src/net/torvald/terrarum/mapdrawer/MapCamera.kt index 664ed0d75..d2e1d8b10 100644 --- a/src/net/torvald/terrarum/mapdrawer/MapCamera.kt +++ b/src/net/torvald/terrarum/mapdrawer/MapCamera.kt @@ -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 diff --git a/src/net/torvald/terrarum/tileproperties/TileNameCode.kt b/src/net/torvald/terrarum/tileproperties/TileNameCode.kt index 9daa03af4..207bc19ea 100644 --- a/src/net/torvald/terrarum/tileproperties/TileNameCode.kt +++ b/src/net/torvald/terrarum/tileproperties/TileNameCode.kt @@ -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) diff --git a/src/net/torvald/terrarum/tileproperties/TilePropUtil.kt b/src/net/torvald/terrarum/tileproperties/TilePropUtil.kt index 344a42daa..9d7e80517 100644 --- a/src/net/torvald/terrarum/tileproperties/TilePropUtil.kt +++ b/src/net/torvald/terrarum/tileproperties/TilePropUtil.kt @@ -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 diff --git a/src/net/torvald/terrarum/tileproperties/tileprop.csv b/src/net/torvald/terrarum/tileproperties/tileprop.csv index 94b4cb104..58287ad95 100644 --- a/src/net/torvald/terrarum/tileproperties/tileprop.csv +++ b/src/net/torvald/terrarum/tileproperties/tileprop.csv @@ -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" diff --git a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt index bfbd1a5fe..e257288fb 100644 --- a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt +++ b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt @@ -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}") diff --git a/src/org/dyn4j/geometry/ChainedVector2.kt b/src/org/dyn4j/geometry/ChainedVector2.kt deleted file mode 100644 index 550d41ba3..000000000 --- a/src/org/dyn4j/geometry/ChainedVector2.kt +++ /dev/null @@ -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 - } - } -} \ No newline at end of file diff --git a/src/org/dyn4j/geometry/Vector2.kt b/src/org/dyn4j/geometry/Vector2.kt index 91591054c..4ca532add 100644 --- a/src/org/dyn4j/geometry/Vector2.kt +++ b/src/org/dyn4j/geometry/Vector2.kt @@ -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]. diff --git a/work_files/civil_settlement.tmx b/work_files/civil_settlement.tmx new file mode 100644 index 000000000..615c139db --- /dev/null +++ b/work_files/civil_settlement.tmx @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + eJzt2TEOwjAQRcEYTsL9L4loECBsLGC9gZ2RfpUi7p6jbBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQ4dTaddWeAUBVe+qx/gNAjNseVhsAVJXd4MwBQFXZDc4cAFSV3eDMAUBV2Q2+rB3vt+q9AFDVqtY+22P3V98DAKCq6Mb29qr9K+4AAFBVZF9H038AyBPZ19H0HwDyRPZ1NP0HgDyRfR1N/wEgT6+Lo2Z+49ls/yPPAgBV6T8A1KP/AFBPr5HR8/8fAPJE9nU0/QeAtSKbOjv9B4C1Ips6O/0HgLUimzo7/QeAtSKbOrs2ucgzAMCva4d2t1mRfR3N9z8AfO7d/u+d/gNAn/5rPwD1/Gv/AYA+/QcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPnEGIseuBw== + + + + + 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= + + +