Making a homing enemy

A place for people with an interest in developing new shmups.
Post Reply
alex12898
Posts: 2
Joined: Sat Mar 30, 2019 1:18 pm

Making a homing enemy

Post by alex12898 »

Hello, I'm making a shmup for my university project. I am using Love2D and Lua. So far I have made rudimentary systems for:
Drawing + moving the player
Firing bullets - a spread type shot and a focused type shot which halves your movement speed
Spawning enemies
Creating boxes for both bullets and enemies + the player
Iterating over boxes and checking for collisions - removing enemies if their boxes collide with a bullet's box and their hp < 0, kill the player if their box collides with an enemy's box.
Wave system - which spawn enemies at specific timings and end when all enemies have died or gone off screen - then progress to next wave.

I am having a problem programming enemy behavior that is more simple than simply moving down. I would like to create an enemy that homes in on the enemy, a "popcorn" type enemy, that I have found in some shmups I've played. These enemies tend to be fast, have low HP and come in large numbers vs the player and are mowed down by the player's bullets. However I do not know how to implement this.
For context, each enemy has an x and y value, and a velocity.x and velocity.y value. The player has an x and y value and a single speed value. For each loop in the game, the enemy's x/y value is incremented by their velocity.x/velocity.y value multiplied by dt.

The only code sample I found to be useful online is this post here:
https://www.lexaloffle.com/bbs/?pid=20374#p

However I tried to implement this in my game with no success. The enemy will behave very strangely - like hugging the top left of the screen, or even moving away from the player depending on where the player is placed. In short I am quite confused and wondering how I should approach this.

I have a github page for my project which is quite loosely managed as it is my first time using it. This is the most recent version of the project:
https://github.com/coolguy420/STGprojec ... s/main.lua

Thanks for reading.
User avatar
MrJBRPG
Posts: 231
Joined: Wed Jan 04, 2017 10:42 pm

Re: Making a homing enemy

Post by MrJBRPG »

I think that there may be a tutorial that can help you refactor your code to make the homing projectiles work. It is in UNity, and with some tweaks, you can make it work.

https://www.gamasutra.com/blogs/VivekTa ... _Unity.php
User avatar
CaptainKraken
Posts: 45
Joined: Wed Nov 30, 2016 1:04 am

Re: Making a homing enemy

Post by CaptainKraken »

Ahoy there, alex12898!

I have some code advice I think may help you.

The main thing is that I would recommend using trigonometry for movement of game objects.
This would be good because it would make coding complex movements a lot simpler.

Here is my code for movement (it's in Java so syntax will probably slightly different):

Code: Select all

public void move(double amount, double direction){
        this.x += Math.cos(direction  * (Math.PI / 180)) * amount;
        this.y -= Math.sin(direction  * (Math.PI / 180)) * amount;
}
(Math.PI / 180) is to convert radians to degrees. If Lua automatically does this then omit that bit.

Notice how all you have to do here to code movement is specify a magnitude and direction.

It's a bit more complicated to have something point at the player, and it took me a while to figure out, but I found something that works for me.

Code: Select all

 public double pointTowards(double primaryX, double primaryY, double targetX, double targetY){
        if (targetX != primaryX) {
            if (targetX > primaryX) {
                return 0 - (180 / Math.PI) * Math.atan((targetY - primaryY) / (targetX - primaryX));
            } else {
                return 180 - (180 / Math.PI) * Math.atan((primaryY - targetY) / (primaryX - targetX));
            }
        } else {
            if (targetY > primaryY) {
                return 270;
            } else {
                return 90;
            }
        }
    }
Again, (180/Math.PI) converts from degrees to radians and may need to be omitted depending on how Lua handles things.

primaryX and primaryY are the starting position (the homing enemy), and
targetX and targetY are where you want it to be pointing at (the player)

The method returns a direction to be fed into the move() method.

Hope this helps!
Squire Grooktook wrote:Make a game because there's something you want to exist that doesn't.
Shooting game never die!
alex12898
Posts: 2
Joined: Sat Mar 30, 2019 1:18 pm

Re: Making a homing enemy

Post by alex12898 »

Thank you for the responses! I contacted a professor at my university and he figured out the math and somehow my Lua implementation worked on the first attempt. I'm going to try and explain what he did from looking at his notes - I don't understand the math at all so this might be a bit wonky:
For context, each enemy gets their x/y value incremented by its own velocity value (velocityX, velocityY) - I couldn't tell you why exactly I implemented it this way, but there you go.

V = math.sqrt((velocityX * velocityX) + (velocityY * velocityY))

Dx = player.x - enemy.x
Dy = player.y - enemy.y

D = math.sqrt((Dx * Dx) + (Dy * Dy))

velocityX = (Dx / D) * 500
velocityY = (Dy / D) * 500
note - 500 is just an arbitrary speed value with how fast you want the enemy to go

then increment the enemy's x/y by the velocity

enemy.x = enemy.x + velocityX
enemy.y = enemy.y + velocityY

I *think* V stood for unit vector, D for direction.
I hope this helps someone who's also using Lua. It seems like there's a lot of ways to go about implementing this.
Post Reply