JS13K Games 2019 Day 31
Oh, boy! It's 4:53pm right now and I have only about 14 hours to finish my game. Hopefully, I can get something playable by then.
My first goal was to finish the collisions with the Backscatter Buster shots. I have them moving, but they're only affected by the walls. It's been a while since I did collision checking, so I had to think about it. I decided to create a separate function called collisionCheck to check for collisions between two objects. It would be cleaner, and smaller, to have this check be in a function that I can reuse. So, what is the algorithm that I should use?
What does it mean when two objects collide? I drew it out, and I think checking the corners on one object to see if they are within the bounds of the object. I think that will work for a majority of cases, but probably not all of them.
As I was eating dinner, I was thinking about objects that overlap each other but their corners don't touch. That's when I remembered that I already solved this issue before: for Orion's Revenge, I have a collision function in its GameObjects.java! I'll have to clean it up a bit and port it over to JavaScript, but that shouldn't be too hard. I can remove anything dealing with a GameObject's faction: faction was used to tell if the object was a player (0), an enemy (1), or an effect/explosion (2). That was because all my objects inherited a GameObject, and they all existed in one array. In Shield Bearer, I got objects in separate lists, so there's no need for faction. Though, I might want to remember that next time; in case only dealing with one array is the better way to go. So, how does my old collision check work?
It compares the position and size of the calling object (this) with another object's position and size (other). That algorithm states, if the caller's (x,y) position is greater than or equal to the other object, but the caller's size engulfs or touches the (x,y) position of the other object, then we have a collision. This function is called twice in GamePanel.java: each object in the list is tested if it collides with any object in that list. That's why in the original collision function I have "other != this", because each object would be tested to see if it collides with itself if that section was missing; then nothing would be drawn because that is a true statement. So, to test things twice in Shield Bearer, I looked up how to set default parameters for functions.
What I did with my new collisionCheck function was turn it into a small recursive function. A recursive function can call itself to solve a certain issue: like adding up the Fibonacci sequence or doing factorials. My collisionCheck will call itself one more time, but the obj1 and obj2 will be swapped. This means that it checks to see if obj1 overlaps obj2 first, then uses the same algorithm to check to see if obj2 overlaps obj1. I then used the new collisionCheck function inside of the playerProjectile's update function. It checks to see if it collided with the shield first: if it did, it marks itself dead. Then it checks to see if it collided with the Bearer: if it did, it marks itself dead, but also send some damage to the Bearer using its hit(dmg) function. The hit(dmg) function lowers the hp value by dmg, and then checks to see if hp less than or equal to zero. If hp is less than or equal to zero, then we move to the "game over" state. When the playerProjectiles are marked dead, they stop colliding with stuff and are eventually spliced out of the playerPro array. I gave it a quick test: playerProjectiles are removed when they hit the shield, playerProjectiles are removed when the hit the Bearer, the Bearer is damaged and loses hp when hit by playerProjectiles, a game over happens when hp reaches zero or less.
Alright, my collisions are good! Now all we need is some robot spider enemies, and we're all set to upload. Well, I would like to add some sprites, but the deadline is looming near! I wanted to get the player used to shooting at the robot spiders, so I made a variable called maxSpiders. It's used to state how many spider can be on the screen at once. I'll start it out at 1, increase it each time the player gets five points, up to a maximum of ten spiders on the screen at once. After I got that down, I started working on the spider class that would hold the properties of the robot spiders. I wanted to draw a web from the spider's starting position down to the spider's current position, so I saved starting y position in startY. I also gave it a variable called stopped, because when it reaches its destination, I want it to stop and start firing at the Bearer. I also wanted to randomize the spider's start x and end y positions so I looked up Math.random. To draw the web, I used the lineTo function of the Canvas' Context. Along with strokeStyle, I was able to draw a white line from the spider's start position to the spider's current position.
Ah, darn! It's time for me to close the blog for "today" as it is past midnight as of writing. I did manage to get a new timeout set up called spawnInt; which, calls a function called spawnEnemies. That function spawnEnemies will create a spider object each second, unless the length of the enemies array is at maxSpiders. I got the update and draw functions of the spider working: it's a red square with a white web that slowly crawls down to its destination y. I hope my friends don't mind firing at red spiders, since they are pretty big fans of Spider-Man. I like Spider-Man, too, but these squares were supposed to be temporary. However, I only got about 6 hours left to get this done and upload it to the JS13K Games Competition! My spiders are unaffected by the Backscatter Buster shots right now, and they cannot fire at the Bearer either. I might have to ship it with no sprites...oh, well!
My first goal was to finish the collisions with the Backscatter Buster shots. I have them moving, but they're only affected by the walls. It's been a while since I did collision checking, so I had to think about it. I decided to create a separate function called collisionCheck to check for collisions between two objects. It would be cleaner, and smaller, to have this check be in a function that I can reuse. So, what is the algorithm that I should use?
What does it mean when two objects collide? I drew it out, and I think checking the corners on one object to see if they are within the bounds of the object. I think that will work for a majority of cases, but probably not all of them.
As I was eating dinner, I was thinking about objects that overlap each other but their corners don't touch. That's when I remembered that I already solved this issue before: for Orion's Revenge, I have a collision function in its GameObjects.java! I'll have to clean it up a bit and port it over to JavaScript, but that shouldn't be too hard. I can remove anything dealing with a GameObject's faction: faction was used to tell if the object was a player (0), an enemy (1), or an effect/explosion (2). That was because all my objects inherited a GameObject, and they all existed in one array. In Shield Bearer, I got objects in separate lists, so there's no need for faction. Though, I might want to remember that next time; in case only dealing with one array is the better way to go. So, how does my old collision check work?
It compares the position and size of the calling object (this) with another object's position and size (other). That algorithm states, if the caller's (x,y) position is greater than or equal to the other object, but the caller's size engulfs or touches the (x,y) position of the other object, then we have a collision. This function is called twice in GamePanel.java: each object in the list is tested if it collides with any object in that list. That's why in the original collision function I have "other != this", because each object would be tested to see if it collides with itself if that section was missing; then nothing would be drawn because that is a true statement. So, to test things twice in Shield Bearer, I looked up how to set default parameters for functions.
What I did with my new collisionCheck function was turn it into a small recursive function. A recursive function can call itself to solve a certain issue: like adding up the Fibonacci sequence or doing factorials. My collisionCheck will call itself one more time, but the obj1 and obj2 will be swapped. This means that it checks to see if obj1 overlaps obj2 first, then uses the same algorithm to check to see if obj2 overlaps obj1. I then used the new collisionCheck function inside of the playerProjectile's update function. It checks to see if it collided with the shield first: if it did, it marks itself dead. Then it checks to see if it collided with the Bearer: if it did, it marks itself dead, but also send some damage to the Bearer using its hit(dmg) function. The hit(dmg) function lowers the hp value by dmg, and then checks to see if hp less than or equal to zero. If hp is less than or equal to zero, then we move to the "game over" state. When the playerProjectiles are marked dead, they stop colliding with stuff and are eventually spliced out of the playerPro array. I gave it a quick test: playerProjectiles are removed when they hit the shield, playerProjectiles are removed when the hit the Bearer, the Bearer is damaged and loses hp when hit by playerProjectiles, a game over happens when hp reaches zero or less.
Alright, my collisions are good! Now all we need is some robot spider enemies, and we're all set to upload. Well, I would like to add some sprites, but the deadline is looming near! I wanted to get the player used to shooting at the robot spiders, so I made a variable called maxSpiders. It's used to state how many spider can be on the screen at once. I'll start it out at 1, increase it each time the player gets five points, up to a maximum of ten spiders on the screen at once. After I got that down, I started working on the spider class that would hold the properties of the robot spiders. I wanted to draw a web from the spider's starting position down to the spider's current position, so I saved starting y position in startY. I also gave it a variable called stopped, because when it reaches its destination, I want it to stop and start firing at the Bearer. I also wanted to randomize the spider's start x and end y positions so I looked up Math.random. To draw the web, I used the lineTo function of the Canvas' Context. Along with strokeStyle, I was able to draw a white line from the spider's start position to the spider's current position.
Ah, darn! It's time for me to close the blog for "today" as it is past midnight as of writing. I did manage to get a new timeout set up called spawnInt; which, calls a function called spawnEnemies. That function spawnEnemies will create a spider object each second, unless the length of the enemies array is at maxSpiders. I got the update and draw functions of the spider working: it's a red square with a white web that slowly crawls down to its destination y. I hope my friends don't mind firing at red spiders, since they are pretty big fans of Spider-Man. I like Spider-Man, too, but these squares were supposed to be temporary. However, I only got about 6 hours left to get this done and upload it to the JS13K Games Competition! My spiders are unaffected by the Backscatter Buster shots right now, and they cannot fire at the Bearer either. I might have to ship it with no sprites...oh, well!
Comments
Post a Comment