Hi guys this is my first question, so feel free to give constructive criticism.
I am making a space shooter game with ScalaFX and I'm facing a problem where when I am drawing the bullet laser
in my AnimationTimer
loop, whenever the player shoots another bullet, the program only renders the newest bullet and the old bullet just disappears.
For the sake of brevity, I'm going to post the main AnimationTimer
loop related to the bullet input and rendering only:
//List of stuffs (Bullets, enemies etc)
var laserListB : ListBuffer[Laser] = ListBuffer()
val timer = AnimationTimer( currentNanoTime => {
//Calculating time since last frame for frame independant rendering
var elapsedTime : Double = (currentNanoTime - lastNanoTime) / 1000000000.0;
lastNanoTime = currentNanoTime;
//Input check
//SKIPPED PLAYER MOVEMENT CODE
if(shootPress){
var now = System.nanoTime()
//Checking for atkSpeed cooldwon
if((lastShootNano <= 0L) || ((now - lastShootNano) >= player.atkSpeed)){
laserListB += player.shoot()
}
lastShootNano = now
}
//Updating position
for(laser <- laserListB){
laser.sprite.velocityX = 0
laser.sprite.velocityY = -400
laser.sprite.update(elapsedTime)
}
//Rendering
//Bullets
for(laser <- laserListB){
laser.sprite.render(gc)
}
})
And the following is my Sprite
class:
import scalafx.scene.image.Image
import scalafx.scene.canvas.GraphicsContext
import scalafx.geometry.Rectangle2D
class Sprite(
private var _image : Image,
private var _positionX : Double,
private var _positionY : Double,
private var _velocityX : Double,
private var _velocityY : Double,
private var _width : Double,
private var _height : Double){
//Functions
def render(gc : GraphicsContext){
gc.drawImage(_image, _positionX, _positionY);
}
}
And if you need, here's my player's shoot function:
def shoot() = {
//Setting up laser sprite
val laser = new Laser(_atkSprite, damage, true)
laser.sprite.velocityX = 0
laser.sprite.velocityY = -400
laser.sprite.positionX = _sprite.positionX + (_sprite.width / 2) //Center laser horizontally on player sprite
laser.sprite.positionY = _sprite.positionY - 10 //Slight offset to be a bit higher than the player sprite
laser
}
Thank you for reading this far :D
Edit 1: Here's a video demonstrating the problem: https://youtu.be/DliNyBoa1DI
Ok I solved it, it wasn't a problem with GraphicsContext but rather due to the fact, Laser
is instantiated with the same Sprite
in player.shoot(), therefore all Laser
s will have the same X and Y, and be overlapped, thus appearing as if it "disappeared".
The new code instantiates a new Sprite
everytime Laser
is instantiated as follows:
def shoot() = {
//Laser sprites
val atkImg = new Image(getClass.getResourceAsStream("/Images/small_laser_blue.png"))
val atkSprite = new Sprite(atkImg, 0, 0, 0, 0, atkImg.getWidth(), atkImg.getHeight())
val laser_ = new Laser(atkSprite, _damage, true)
laser_.sprite.velocityX = 0
laser_.sprite.velocityY = -400
laser_.sprite.positionX = _sprite.positionX + (_sprite.width / 2) //Center laser horizontally on player sprite
laser_.sprite.positionY = _sprite.positionY - 10 //Slight offset to be a bit higher than the player sprite
}