Added eight way shooting to the game, so that the player can aim vertically as well as horizontally. Pressing up will set a flag that keeps track if the player can shoot upward. When looking upward, then the Y velocity is set to the projectile speed. If the player is not walking, then the player should shoot directly up, so the projectile’s X velocity is set to zero. If the player is walking, then the projectile will move diagonally up/left or up/right depending on which way the player is walking. I don’t have graphics for the player lookup up or down yet, so for now it just displays “looking up” or “looking down” over the player’s head. One feature I plan to add is making the player aim diagonally up or down when the left or right trigger is pressed. However, that will require an update to ResistorKit to handle those inputs, as well as adding methods in the ResistorKit screen class.
I went back and modified the velocity for the up/right and up/left shots, since it will actually go slightly faster than the projectile moving directly vertically or directly horizontally. Currently the projectile speed is set to 10, so that it moves 10 pixels each second. When shooting diagonally, the projectile will actually move 14.142 pixels according to the Pythagorean theorem ( square root of (10 squared plus 10 squared) ). To make the diagonal speed match, the values of the X and Y components can be found by dividing the projectile speed by 1.414 (or multiplying by 0.707) which is the square root of two. This is because Sqrt(1^2 + 1^2) = Sqrt(1 + 1) = Sqrt(2). Fortunately, finding the length of the two sides (projectile’s X and Y velocity) of the triangle from the hypotenuse just requires multiplying by a constant. I believe this is because the two sides of the right (90 degree) angle are equal, but I don’t have any formal proof of this. If I allowed precision aiming where the X velocity was not equal to the Y velocity, then more complex calculations would probably be needed.
The projectile collection class has been modified to handle more than one projectile using a List. A projectile is removed from the projectile from the List whenever it is inactive. The alive flag now indicates that the projectile is ready for removal from the collection. This may be slightly inefficient, since it is allocating memory for a projectile each time one is shot. I may revisit this later if there are performance issues. One problem is that I couldn’t just simply increase a counter variable to loop through each element and delete it if it is inactive, since that will modify the structure of the List which could result skipping elements if not careful. Therefore, I looped through the List in reverse starting at the List size minus one and going down to zero. That way if I delete an element then it will not effect the iterator.
Similar to enemies, I added code to handle passing a projectile from one room to the next. I removed the condition that if a projectile hits the room boundary, then it disappears. One interesting side effect is that now the projectile will live forever if it does not collide with an enemy, so it will loop forever as long as it is in the player’s room or an adjacent room. Therefore, I added a variable to track the lifetime of a projectile, which I currently have set to 60 frames. This may be upgradeable in the future with a socket.
Finally, on each projectile update I now check to see if the projectile has collided with a block. This uses the same collision method that I created in the map class to do the enemy collision. If the projectile has collided, then I set the alive flag to false, which will mark it for removal from the projectile list. I also added the player’s width to the starting position of a projectile when shooting right, that way it doesn’t look like the projectile is going through the player’s body.