diff --git a/core/src/tdt4240/netrunner/game/GameController.kt b/core/src/tdt4240/netrunner/game/GameController.kt index 3a59cf6850f9392b98570992b9006f8ad409a0f7..6de016470417db295d2c3175d5d07bfc2c02b36d 100644 --- a/core/src/tdt4240/netrunner/game/GameController.kt +++ b/core/src/tdt4240/netrunner/game/GameController.kt @@ -14,6 +14,7 @@ import tdt4240.netrunner.model.util.gsonImpl import tdt4240.netrunner.view.GameScreen import tdt4240.netrunner.view.controllers.CameraController import tdt4240.netrunner.view.controllers.GroundRenderer +import tdt4240.netrunner.view.controllers.ParallaxRenderer import tdt4240.netrunner.view.controllers.PlayerRenderer /** @@ -32,6 +33,9 @@ class GameController(val game: Netrunner) { val engine = EcsEngine().apply { + // NOTE: ParalaxController MUST be listed before all other renderers, + // as it's meant to be the background. + addController(ParallaxRenderer(this@GameController, this)) addController(PlayerRenderer(this@GameController, this)) addController(GroundRenderer(this@GameController, this)) addController(CameraController(this@GameController, this)) @@ -86,6 +90,7 @@ class GameController(val game: Netrunner) { fun deregisterGameEvents() { // Note: Any registered `sock.on()`s made in this class MUST be deregistered here. Client.sock.off("entities") + Client.sock.off("counter") logger.debug("Game events deregistered") // Note: this is not an elegant solution. It would be better for the server to emit diff --git a/core/src/tdt4240/netrunner/view/GameScreen.kt b/core/src/tdt4240/netrunner/view/GameScreen.kt index 724d2a98a6d8e275f7dd065d1aabeb4b54239942..d37557b9fa62610980116bdecded95bb565a698f 100644 --- a/core/src/tdt4240/netrunner/view/GameScreen.kt +++ b/core/src/tdt4240/netrunner/view/GameScreen.kt @@ -10,6 +10,7 @@ import com.badlogic.gdx.scenes.scene2d.InputEvent import com.badlogic.gdx.scenes.scene2d.Stage import com.badlogic.gdx.scenes.scene2d.ui.ImageButton import com.badlogic.gdx.scenes.scene2d.ui.ImageButton.ImageButtonStyle +import com.badlogic.gdx.scenes.scene2d.ui.Label import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.TextButton import com.badlogic.gdx.scenes.scene2d.utils.ClickListener @@ -36,13 +37,23 @@ class GameScreen(private val game: Netrunner, private val controller: GameContro init { val buttonStyle = TextButton.TextButtonStyle() buttonStyle.font = game.skin.getFont("default-font") - buttonStyle.downFontColor = Color.RED; + buttonStyle.downFontColor = Color.RED - val exitButton = TextButton("Exit", buttonStyle) //bruk evt. game.skin + val exitButton = TextButton("Exit", buttonStyle) //bruk evt. game.skin //if we want an exact position //exitButton.setPosition(1000f, 10f) // stage.addActor(exitButton) + val labelStyle = Label.LabelStyle() + labelStyle.font = game.skin.getFont("default-font") + labelStyle.fontColor = Color.WHITE + val label = Label(" ", labelStyle) + label.setFontScale(5F,5F) + label.setPosition(20f,20f) + stage.addActor(label) + + + exitButton.addListener(object : ClickListener() { override fun clicked(event: InputEvent?, x: Float, y: Float) { game.screen = MenuScreen(game) @@ -50,6 +61,23 @@ class GameScreen(private val game: Netrunner, private val controller: GameContro } }) + + + Client.sock.on("counter") { it -> + if (it.isEmpty()) return@on + if(it[0] == "0"){ + logger.debug("Du kom deg inn i ifen!") + label.setText("")} + else + label.setText(it[0].toString()) + + + } + + + + + val table = Table() table.setFillParent(true) table.row() diff --git a/core/src/tdt4240/netrunner/view/controllers/ParallaxRenderer.kt b/core/src/tdt4240/netrunner/view/controllers/ParallaxRenderer.kt new file mode 100644 index 0000000000000000000000000000000000000000..9c1bea94f9bf4902274f65fe5bc0c3f41f27d06a --- /dev/null +++ b/core/src/tdt4240/netrunner/view/controllers/ParallaxRenderer.kt @@ -0,0 +1,74 @@ +package tdt4240.netrunner.view.controllers + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.graphics.Texture +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import tdt4240.netrunner.Netrunner +import tdt4240.netrunner.game.GameController +import tdt4240.netrunner.model.game.EcsController +import tdt4240.netrunner.model.game.EcsEngine +import tdt4240.netrunner.model.game.components.dynamic.VelocityComponent +import tdt4240.netrunner.model.game.components.living.PlayerComponent +import tdt4240.netrunner.model.util.Vec2f +import tdt4240.netrunner.view.GameScreen + +class ParallaxRenderer(val gController: GameController, engine: EcsEngine) : EcsController(engine) { + private val batch = SpriteBatch() + private val textures = listOf( + Texture(Gdx.files.internal("bg_0.png")), + Texture(Gdx.files.internal("bg_1.png")), + Texture(Gdx.files.internal("bg_2.png")), + ) + + private val layerWidth = textures[1].width + private val layer1Pos = Vec2f(0f, 0f) + private val layer2Pos = Vec2f(0f, 0f) + + override fun render() { + // The paralax controller is better off with the UI viewport to keep absolute-ish coords + // for the fixed background + gController.game.uiViewport.also { + it.apply() + batch.begin() + batch.projectionMatrix = it.camera.combined + batch.draw(textures[0], 0f, 0f, Netrunner.MIN_WIDTH, Netrunner.MIN_HEIGHT) + + + batch.draw(textures[1], layer1Pos.x, layer1Pos.y, Netrunner.MIN_WIDTH, Netrunner.MIN_HEIGHT) + batch.draw(textures[1], layer1Pos.x + Netrunner.MIN_WIDTH, layer1Pos.y, Netrunner.MIN_WIDTH, Netrunner.MIN_HEIGHT) + + batch.draw(textures[2], layer2Pos.x, layer1Pos.y, Netrunner.MIN_WIDTH, Netrunner.MIN_HEIGHT) + batch.draw(textures[2], layer2Pos.x + Netrunner.MIN_WIDTH, layer1Pos.y, Netrunner.MIN_WIDTH, Netrunner.MIN_HEIGHT) + + batch.end() + } + // reset to the normal game viewport + (gController.game.screen as GameScreen).gameViewport.apply() + } + + override fun tick(delta: Double) { + val players = ecs.getEntitiesByComponent(PlayerComponent::class.java) + for (player in players) { + if (player.getComponent(PlayerComponent::class.java)!!.uid == gController.playerUid) { + if (player.getComponent(VelocityComponent::class.java)!!.velocity.x > 0) { + // possible future TODO: make the scroll velocity dependent on the player velocity + updateAndCheckXPositionExceedingWidth(layer1Pos, SCROLL_SPEED_LAYER_1, delta) + updateAndCheckXPositionExceedingWidth(layer2Pos, SCROLL_SPEED_LAYER_2, delta) + } + break; + } + } + } + + private fun updateAndCheckXPositionExceedingWidth(pos: Vec2f, scrollSpeed: Float, delta: Double) { + pos.x -= scrollSpeed * delta.toFloat() + if (pos.x <= -Netrunner.MIN_WIDTH) { + pos.x = 0f + } + } + + companion object { + const val SCROLL_SPEED_LAYER_1 = 15f + const val SCROLL_SPEED_LAYER_2 = 150f + } +} \ No newline at end of file diff --git a/model/src/main/kotlin/tdt4240/netrunner/model/game/components/dynamic/GravityComponent.kt b/model/src/main/kotlin/tdt4240/netrunner/model/game/components/dynamic/GravityComponent.kt index 20c834b1adf67b27f10de335e85baefc79921e91..cbdc942895be4de8bc19aeb5ff1f0c9d8dd432e7 100644 --- a/model/src/main/kotlin/tdt4240/netrunner/model/game/components/dynamic/GravityComponent.kt +++ b/model/src/main/kotlin/tdt4240/netrunner/model/game/components/dynamic/GravityComponent.kt @@ -7,7 +7,10 @@ import tdt4240.netrunner.model.util.Vec2f class GravityComponent(val gravSpeed: Vec2f = Vec2f(0f, GRAVITY)) : Component { override val componentName: String = this::class.java.name + + companion object { - const val GRAVITY = 9.81f + const val GRAVITY = -700.0f + //TODO: } } \ No newline at end of file diff --git a/model/src/main/kotlin/tdt4240/netrunner/model/game/factories/PlayerFactory.kt b/model/src/main/kotlin/tdt4240/netrunner/model/game/factories/PlayerFactory.kt index 5d255ba9cf827889bbe7a7a6a9dc00fd86ffa804..0fd0178d91e6e1b61fd71b6fde5b77df5efe3252 100644 --- a/model/src/main/kotlin/tdt4240/netrunner/model/game/factories/PlayerFactory.kt +++ b/model/src/main/kotlin/tdt4240/netrunner/model/game/factories/PlayerFactory.kt @@ -1,6 +1,7 @@ package tdt4240.netrunner.model.game.factories import tdt4240.netrunner.model.game.Entity +import tdt4240.netrunner.model.game.components.dynamic.GravityComponent import tdt4240.netrunner.model.game.components.dynamic.PositionComponent import tdt4240.netrunner.model.game.components.dynamic.VelocityComponent import tdt4240.netrunner.model.game.components.living.LivingComponent @@ -37,7 +38,8 @@ class PlayerFactory { PositionComponent(initPosition), VelocityComponent(Vec2f()), PlayerComponent(username, color, uid), - LivingComponent(100, DEFAULT_MAX_PLAYER_SPEED) + LivingComponent(100, DEFAULT_MAX_PLAYER_SPEED), + GravityComponent() )) } diff --git a/server/src/main/java/tdt4240/netrunner/server/game/GameRoom.kt b/server/src/main/java/tdt4240/netrunner/server/game/GameRoom.kt index dd17eb3172fb776de729c51b6b2c6661625acdfb..8dcacbf0962c6ec62dc7bdadd84f485535918266 100644 --- a/server/src/main/java/tdt4240/netrunner/server/game/GameRoom.kt +++ b/server/src/main/java/tdt4240/netrunner/server/game/GameRoom.kt @@ -14,7 +14,7 @@ import tdt4240.netrunner.model.response.EntityData import tdt4240.netrunner.model.util.Vec2f import tdt4240.netrunner.model.util.gsonImpl import tdt4240.netrunner.server.controllers.GameController -import java.util.UUID +import java.util.* import java.util.concurrent.ConcurrentHashMap class GameRoom(val socketRoomID: String, val server: SocketIoServer, val controller: GameController){ @@ -59,17 +59,28 @@ class GameRoom(val socketRoomID: String, val server: SocketIoServer, val control if (System.currentTimeMillis() - createdAt >= MAX_WAIT_TIME * 1000 && players.size >= MIN_PLAYERS || players.size == MAX_PLAYERS) { logger.info("Play threshold reached. Starting game") + started = true // TODO: timer + // TODO: broadcast time remaining every second or so? // How many players have joined is automatically broadcast whenever someone joins or leaves, // so that doesn't need to be handled here. prevTime = System.currentTimeMillis() ecs.entities.addAll(players.values.toMutableList()) - server.namespace("/").broadcast(socketRoomID, "game-started") controller.notifyStart(this) + Thread.sleep(1000) + server.namespace("/").broadcast(socketRoomID, "counter", gsonImpl.toJson(3)) + Thread.sleep(1000) + server.namespace("/").broadcast(socketRoomID, "counter", gsonImpl.toJson(2)) + Thread.sleep(1000) + server.namespace("/").broadcast(socketRoomID, "counter", gsonImpl.toJson(1)) + Thread.sleep(1000) + server.namespace("/").broadcast(socketRoomID, "counter", gsonImpl.toJson(0)) + server.namespace("/").broadcast(socketRoomID, "game-started") + } else if (System.currentTimeMillis() - createdAt >= MAX_WAIT_TIME * 1000 && players.size == 0) { synchronized(this) { done = true @@ -82,7 +93,7 @@ class GameRoom(val socketRoomID: String, val server: SocketIoServer, val control } } - val delta = (System.currentTimeMillis() - prevTime).toDouble() + val delta = ((System.currentTimeMillis() - prevTime).toDouble())/1000.0 ecs.tick(delta) @@ -203,6 +214,8 @@ class GameRoom(val socketRoomID: String, val server: SocketIoServer, val control } } } + + // }}} override fun toString(): String { @@ -223,7 +236,7 @@ class GameRoom(val socketRoomID: String, val server: SocketIoServer, val control const val STANDARD_FIELD_LENGTH = 40_000 - const val PLAYER_JUMP_VELOCITY = 10f + const val PLAYER_JUMP_VELOCITY = 600f } }