mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-14 23:56:07 +09:00
ActorWithBody: broke CCD again for fundamental error-catching, new tile STONE_BRICKS
Former-commit-id: 3d98f83f3d40f4423b403eae717a06ac6fc22531 Former-commit-id: 13616655a392941e0c91c3384384475ae0adb5db
This commit is contained in:
@@ -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
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}")
|
||||
|
||||
Reference in New Issue
Block a user