ActorAI's walk speed can be adjusted now

Former-commit-id: 556677bddf9cc29358471c81f7febc40e8e6cc7d
Former-commit-id: 35b994001dd034e166ba6c6709cb92fd5dca073e
This commit is contained in:
Song Minjae
2016-12-28 00:17:52 +09:00
parent d461eedd3e
commit 13faeb2947
7 changed files with 135 additions and 77 deletions

View File

@@ -86,21 +86,30 @@ constructor(gamename: String) : StateBasedGame(gamename) {
fontGame = GameFontWhite() fontGame = GameFontWhite()
fontSmallNumbers = TinyAlphNum() fontSmallNumbers = TinyAlphNum()
// search for real controller
// exclude controllers with name "Mouse", "keyboard"
val notControllerRegex = Regex("mouse|keyboard")
try { try {
hasController = gc.input.controllerCount > 0 // gc.input.controllerCount is unreliable
for (i in 0..255) {
val controllerInQuo = Controllers.getController(i)
if (hasController) { println("Controller $i: ${controllerInQuo.name}")
// check if the first controller is actually available
Controllers.getController(0).getAxisValue(0) // check the name
if (!controllerInQuo.name.toLowerCase().contains(notControllerRegex)) {
controller = controllerInQuo
println("Controller $i selected: ${controller!!.name}")
break
}
} }
} }
catch (e: ArrayIndexOutOfBoundsException) { catch (e: IndexOutOfBoundsException) {
hasController = false
} }
if (hasController) { if (controller != null) {
for (c in 0..Controllers.getController(0).axisCount - 1) { for (c in 0..controller!!.axisCount - 1) {
Controllers.getController(0).setDeadZone(c, CONTROLLER_DEADZONE) controller!!.setDeadZone(c, CONTROLLER_DEADZONE)
} }
} }
@@ -215,8 +224,10 @@ constructor(gamename: String) : StateBasedGame(gamename) {
val STATE_ID_TOOL_NOISEGEN = 0x200 val STATE_ID_TOOL_NOISEGEN = 0x200
var hasController = false //var hasController = false
val CONTROLLER_DEADZONE = 0.1f var controller: org.lwjgl.input.Controller? = null
private set
val CONTROLLER_DEADZONE = 0.2f
/** Available CPU threads */ /** Available CPU threads */
val THREADS = Runtime.getRuntime().availableProcessors() val THREADS = Runtime.getRuntime().availableProcessors()

View File

@@ -8,11 +8,11 @@ package net.torvald.terrarum.gameactors
interface AIControlled { interface AIControlled {
val scriptPath: String val scriptPath: String
fun moveLeft() fun moveLeft(amount: Float = 1f)
fun moveRight() fun moveRight(amount: Float = 1f)
fun moveUp() fun moveUp(amount: Float = 1f)
fun moveDown() fun moveDown(amount: Float = 1f)
fun moveJump() fun moveJump(amount: Float = 1f)
/** fly toward arbitrary angle WARNING: the map is looped! */ /** fly toward arbitrary angle WARNING: the map is looped! */
fun moveTo(bearing: Double) fun moveTo(bearing: Double)

View File

@@ -2,7 +2,6 @@ package net.torvald.terrarum.gameactors
import com.jme3.math.FastMath import com.jme3.math.FastMath
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.*
import net.torvald.terrarum.gameactors.faction.Faction import net.torvald.terrarum.gameactors.faction.Faction
import net.torvald.terrarum.gamecontroller.EnumKeyFunc import net.torvald.terrarum.gamecontroller.EnumKeyFunc
import net.torvald.terrarum.gamecontroller.KeyMap import net.torvald.terrarum.gamecontroller.KeyMap
@@ -11,7 +10,6 @@ import net.torvald.terrarum.gameitem.InventoryItem
import net.torvald.terrarum.realestate.RealEstateUtility import net.torvald.terrarum.realestate.RealEstateUtility
import org.dyn4j.geometry.Vector2 import org.dyn4j.geometry.Vector2
import org.lwjgl.input.Controller import org.lwjgl.input.Controller
import org.lwjgl.input.Controllers
import org.newdawn.slick.GameContainer import org.newdawn.slick.GameContainer
import org.newdawn.slick.Input import org.newdawn.slick.Input
import java.util.* import java.util.*
@@ -86,7 +84,6 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
// MOVEMENT RELATED FUNCTIONS // // MOVEMENT RELATED FUNCTIONS //
//////////////////////////////// ////////////////////////////////
var gamepad: Controller? = null
var axisX = 0f var axisX = 0f
var axisY = 0f var axisY = 0f
var axisRX = 0f var axisRX = 0f
@@ -121,7 +118,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
internal var noClip = false internal var noClip = false
@Transient private val AXIS_POSMAX = 1.0f @Transient private val AXIS_KEYBOARD = -13372f // leetz
@Transient private val GAMEPAD_JUMP = 7 @Transient private val GAMEPAD_JUMP = 7
protected var isUpDown = false protected var isUpDown = false
@@ -160,6 +157,10 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
isLeftDown = false isLeftDown = false
isRightDown = false isRightDown = false
isJumpDown = false isJumpDown = false
axisX = 0f
axisY = 0f
axisRX = 0f
axisRY = 0f
} }
// update inventory items // update inventory items
@@ -198,12 +199,11 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
isRightDown = isFuncDown(input, EnumKeyFunc.MOVE_RIGHT) isRightDown = isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)
isJumpDown = isFuncDown(input, EnumKeyFunc.JUMP) isJumpDown = isFuncDown(input, EnumKeyFunc.JUMP)
if (Terrarum.hasController) { if (Terrarum.controller != null) {
gamepad = Controllers.getController(0) axisX = Terrarum.controller!!.getAxisValue(3)
axisX = gamepad!!.getAxisValue(0) axisY = Terrarum.controller!!.getAxisValue(2)
axisY = gamepad!!.getAxisValue(1) axisRX = Terrarum.controller!!.getAxisValue(1)
axisRX = gamepad!!.getAxisValue(2) axisRY = Terrarum.controller!!.getAxisValue(0)
axisRY = gamepad!!.getAxisValue(3)
// deadzonning // deadzonning
if (Math.abs(axisX) < Terrarum.CONTROLLER_DEADZONE) axisX = 0f if (Math.abs(axisX) < Terrarum.CONTROLLER_DEADZONE) axisX = 0f
@@ -211,7 +211,8 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
if (Math.abs(axisRX) < Terrarum.CONTROLLER_DEADZONE) axisRX = 0f if (Math.abs(axisRX) < Terrarum.CONTROLLER_DEADZONE) axisRX = 0f
if (Math.abs(axisRY) < Terrarum.CONTROLLER_DEADZONE) axisRY = 0f if (Math.abs(axisRY) < Terrarum.CONTROLLER_DEADZONE) axisRY = 0f
gamepad!!.isButtonPressed(GAMEPAD_JUMP) isJumpDown = isFuncDown(input, EnumKeyFunc.JUMP) ||
Terrarum.controller!!.isButtonPressed(GAMEPAD_JUMP)
} }
} }
} }
@@ -230,6 +231,10 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
} }
} }
private val hasController: Boolean
get() = if (isGamer) Terrarum.controller != null
else true
override fun processInput(gc: GameContainer, delta: Int, input: Input) { override fun processInput(gc: GameContainer, delta: Int, input: Input) {
/////////////////// ///////////////////
// MOUSE CONTROL // // MOUSE CONTROL //
@@ -252,7 +257,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
/** /**
* L-R stop * L-R stop
*/ */
if (isGamer && Terrarum.hasController && !isWalkingH) { if (hasController && !isWalkingH) {
if (axisX == 0f) { if (axisX == 0f) {
walkHStop() walkHStop()
} }
@@ -265,7 +270,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
/** /**
* U-D stop * U-D stop
*/ */
if (isGamer && Terrarum.hasController) { if (hasController) {
if (axisY == 0f) { if (axisY == 0f) {
walkVStop() walkVStop()
} }
@@ -281,26 +286,26 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
* Left/Right movement * Left/Right movement
*/ */
if (isGamer && Terrarum.hasController) { if (hasController) {
if (axisX != 0f) { if (axisX != 0f) {
walkHorizontal(axisX < 0f, axisX.abs()) walkHorizontal(axisX < 0f, axisX.abs())
} }
} }
// ↑F, ↓S // ↑F, ↓S
if (isRightDown && !isLeftDown) { if (isRightDown && !isLeftDown) {
walkHorizontal(false, AXIS_POSMAX) walkHorizontal(false, AXIS_KEYBOARD)
prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT) prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT)
} // ↓F, ↑S } // ↓F, ↑S
else if (isLeftDown && !isRightDown) { else if (isLeftDown && !isRightDown) {
walkHorizontal(true, AXIS_POSMAX) walkHorizontal(true, AXIS_KEYBOARD)
prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT) prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT)
} // ↓F, ↓S } // ↓F, ↓S
/*else if (isLeftDown && isRightDown) { /*else if (isLeftDown && isRightDown) {
if (prevHMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT)) { if (prevHMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT)) {
walkHorizontal(false, AXIS_POSMAX) walkHorizontal(false, AXIS_KEYBOARD)
prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT) prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT)
} else if (prevHMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT)) { } else if (prevHMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT)) {
walkHorizontal(true, AXIS_POSMAX) walkHorizontal(true, AXIS_KEYBOARD)
prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT) prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT)
} }
}*/ }*/
@@ -309,26 +314,26 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
* Up/Down movement * Up/Down movement
*/ */
if (noClip) { if (noClip) {
if (isGamer && Terrarum.hasController) { if (hasController) {
if (axisY != 0f) { if (axisY != 0f) {
walkVertical(axisY < 0, axisY.abs()) walkVertical(axisY < 0, axisY.abs())
} }
} }
// ↑E, ↓D // ↑E, ↓D
if (isDownDown && !isUpDown) { if (isDownDown && !isUpDown) {
walkVertical(false, AXIS_POSMAX) walkVertical(false, AXIS_KEYBOARD)
prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN) prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN)
} // ↓E, ↑D } // ↓E, ↑D
else if (isUpDown && !isDownDown) { else if (isUpDown && !isDownDown) {
walkVertical(true, AXIS_POSMAX) walkVertical(true, AXIS_KEYBOARD)
prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP) prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP)
} // ↓E, ↓D } // ↓E, ↓D
/*else if (isUpDown && isDownDown) { /*else if (isUpDown && isDownDown) {
if (prevVMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP)) { if (prevVMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP)) {
walkVertical(false, AXIS_POSMAX) walkVertical(false, AXIS_KEYBOARD)
prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN) prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN)
} else if (prevVMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN)) { } else if (prevVMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN)) {
walkVertical(true, AXIS_POSMAX) walkVertical(true, AXIS_KEYBOARD)
prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP) prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP)
} }
}*/ }*/
@@ -345,7 +350,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
jump() jump()
} }
else { else {
walkVertical(true, AXIS_POSMAX) walkVertical(true, AXIS_KEYBOARD)
} }
} }
else { else {
@@ -376,23 +381,33 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
* Be warned. * Be warned.
* *
* @param left (even if the game is joypad controlled, you must give valid value) * @param left (even if the game is joypad controlled, you must give valid value)
* @param absAxisVal (set AXIS_POSMAX if keyboard controlled) * @param absAxisVal (set AXIS_KEYBOARD if keyboard controlled)
* @author minjaesong * @author minjaesong
*/ */
private fun walkHorizontal(left: Boolean, absAxisVal: Float) { private fun walkHorizontal(left: Boolean, absAxisVal: Float) {
if ((!walledLeft && left) || (!walledRight && !left)) { if ((!walledLeft && left) || (!walledRight && !left)) {
readonly_totalX = readonly_totalX =
absMax( // keyboard absMax( // keyboard
avAcceleration * applyVelo(walkCounterX) * (if (left) -1f else 1f), if (absAxisVal == AXIS_KEYBOARD)
avAcceleration * applyVelo(walkCounterX) * (if (left) -1f else 1f)
else
0.0
,
// gamepad // gamepad
avAcceleration * (if (left) -1f else 1f) * absAxisVal if (absAxisVal != AXIS_KEYBOARD)
avAcceleration * (if (left) -1f else 1f) * absAxisVal
else
0.0
) )
//applyForce(Vector2(readonly_totalX, 0.0)) //applyForce(Vector2(readonly_totalX, 0.0))
walkX += readonly_totalX walkX += readonly_totalX
walkX = readonly_totalX
walkX = walkX.bipolarClamp(avSpeedCap) walkX = walkX.bipolarClamp(avSpeedCap)
walkCounterX += 1 if (absAxisVal == AXIS_KEYBOARD) {
walkCounterX += 1
}
isWalkingH = true isWalkingH = true
} }
@@ -408,20 +423,29 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
* @param up (even if the game is joypad controlled, you must give valid value) * @param up (even if the game is joypad controlled, you must give valid value)
* * * *
* @param absAxisVal (set AXIS_POSMAX if keyboard controlled) * @param absAxisVal (set AXIS_KEYBOARD if keyboard controlled)
*/ */
private fun walkVertical(up: Boolean, absAxisVal: Float) { private fun walkVertical(up: Boolean, absAxisVal: Float) {
readonly_totalY = readonly_totalY =
absMax( // keyboard absMax( // keyboard
avAcceleration * applyVelo(walkCounterY) * (if (up) -1f else 1f), if (absAxisVal == AXIS_KEYBOARD)
avAcceleration * applyVelo(walkCounterY) * (if (up) -1f else 1f)
else
0.0
,
// gamepad // gamepad
avAcceleration * (if (up) -1f else 1f) * absAxisVal if (absAxisVal != AXIS_KEYBOARD)
avAcceleration * (if (up) -1f else 1f) * absAxisVal
else
0.0
) )
walkY += readonly_totalY walkY += readonly_totalY
walkY = walkY.bipolarClamp(avSpeedCap) walkY = walkY.bipolarClamp(avSpeedCap)
walkCounterY += 1 if (absAxisVal == AXIS_KEYBOARD) {
walkCounterY += 1
}
isWalkingV = true isWalkingV = true
} }

View File

@@ -84,23 +84,23 @@ open class HumanoidNPC(val luaScript: String, born: GameDate) : ActorHumanoid(bo
//moveRight() //moveRight()
} }
override fun moveLeft() { // hit the buttons on the controller box override fun moveLeft(amount: Float) { // hit the buttons on the controller box
isLeftDown = true axisX = -amount
} }
override fun moveRight() { // hit the buttons on the controller box override fun moveRight(amount: Float) { // hit the buttons on the controller box
isRightDown = true axisX = amount
} }
override fun moveUp() { // hit the buttons on the controller box override fun moveUp(amount: Float) { // hit the buttons on the controller box
isUpDown = true axisY = -amount
} }
override fun moveDown() { // hit the buttons on the controller box override fun moveDown(amount: Float) { // hit the buttons on the controller box
isDownDown = true axisY = amount
} }
override fun moveJump() { // hit the buttons on the controller box override fun moveJump(amount: Float) { // hit the buttons on the controller box
isJumpDown = true isJumpDown = true
} }

View File

@@ -43,13 +43,6 @@ class Player(born: GameDate) : ActorHumanoid(born) {
referenceID = PLAYER_REF_ID // forcibly set ID referenceID = PLAYER_REF_ID // forcibly set ID
density = BASE_DENSITY density = BASE_DENSITY
collisionType = COLLISION_KINEMATIC collisionType = COLLISION_KINEMATIC
try {
gamepad = Controllers.getController(0)
}
catch (e: IndexOutOfBoundsException) {
println("[Player] gamepad not detected.")
}
} }
override fun update(gc: GameContainer, delta: Int) { override fun update(gc: GameContainer, delta: Int) {

View File

@@ -126,32 +126,56 @@ internal class AILuaAPI(val g: Globals, actor: ActorWithBody) {
} }
} }
class MoveLeft(val actor: AIControlled) : ZeroArgFunction() { class MoveLeft(val actor: AIControlled) : LuaFunction() {
override fun call(): LuaValue { override fun call(): LuaValue { // hard key press
actor.moveLeft() actor.moveLeft()
return LuaValue.NONE return LuaValue.NONE
} }
/** @param amount [0.0 - 1.0] */
override fun call(amount: LuaValue): LuaValue { // stick tilt
actor.moveLeft(amount.checkdouble().toFloat())
return LuaValue.NONE
}
} }
class MoveRight(val actor: AIControlled) : ZeroArgFunction() { class MoveRight(val actor: AIControlled) : LuaFunction() {
override fun call(): LuaValue { override fun call(): LuaValue { // hard key press
actor.moveRight() actor.moveRight()
return LuaValue.NONE return LuaValue.NONE
} }
}
class MoveUp(val actor: AIControlled) : ZeroArgFunction() { /** @param amount [0.0 - 1.0] */
override fun call(): LuaValue { override fun call(amount: LuaValue): LuaValue { // stick tilt
actor.moveUp() actor.moveRight(amount.checkdouble().toFloat())
return LuaValue.NONE return LuaValue.NONE
} }
} }
class MoveDown(val actor: AIControlled) : ZeroArgFunction() { class MoveUp(val actor: AIControlled) : LuaFunction() {
override fun call(): LuaValue { override fun call(): LuaValue { // hard key press
actor.moveUp()
return LuaValue.NONE
}
/** @param amount [0.0 - 1.0] */
override fun call(amount: LuaValue): LuaValue { // stick tilt
actor.moveUp(amount.checkdouble().toFloat())
return LuaValue.NONE
}
}
class MoveDown(val actor: AIControlled) : LuaFunction() {
override fun call(): LuaValue { // hard key press
actor.moveDown() actor.moveDown()
return LuaValue.NONE return LuaValue.NONE
} }
/** @param amount [0.0 - 1.0] */
override fun call(amount: LuaValue): LuaValue { // stick tilt
actor.moveDown(amount.checkdouble().toFloat())
return LuaValue.NONE
}
} }
class MoveTo(val actor: AIControlled) : LuaFunction() { class MoveTo(val actor: AIControlled) : LuaFunction() {
@@ -166,11 +190,17 @@ internal class AILuaAPI(val g: Globals, actor: ActorWithBody) {
} }
} }
class Jump(val actor: AIControlled) : ZeroArgFunction() { class Jump(val actor: AIControlled) : LuaFunction() {
override fun call(): LuaValue { override fun call(): LuaValue {
actor.moveJump() actor.moveJump()
return LuaValue.NONE return LuaValue.NONE
} }
/** @param amount [0.0 - 1.0] */
override fun call(amount: LuaValue): LuaValue { // stick tilt
actor.moveJump(amount.checkdouble().toFloat())
return LuaValue.NONE
}
} }
} }

View File

@@ -40,9 +40,9 @@ function update(delta)
elseif currentMode == "move" then elseif currentMode == "move" then
-- move -- move
if moveMode == "left" then if moveMode == "left" then
ai.moveLeft() ai.moveLeft(0.5)
elseif moveMode == "right" then elseif moveMode == "right" then
ai.moveRight() ai.moveRight(0.5)
end end
-- reset counter -- reset counter
if timeCounter >= countMax then if timeCounter >= countMax then