+Random Terrain Posted March 17, 2011 Share Posted March 17, 2011 I created this thread so it can be linked to from the bB page. Please post your Enemy AI tips here so they can help current and future users of batari Basic. Thanks. 1 Quote Link to comment Share on other sites More sharing options...
Albert Posted March 17, 2011 Share Posted March 17, 2011 I thought this said "Enemy Al" and I was a bit concerned. ..Al 3 1 Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 17, 2011 Author Share Posted March 17, 2011 I thought this said "Enemy Al" and I was a bit concerned. ..Al The dangers of not using Verdana as the default font on a message board. Quote Link to comment Share on other sites More sharing options...
Rybags Posted March 17, 2011 Share Posted March 17, 2011 Repost by request from the other recent thread: Quite a lot of old game logic is just a mix of randomness and "seek player" type of thing. Obviously a game will usually be too hard if the enemy constantly heads for the player, so you can do stuff like only change direction periodically, and make that direction change a mix of randomness and seeking. Then you have the arcade Pac-Man "Head him off at the pass" philosophy - don't necessarily head for the player, head for a position that's near where the player is. And you have Asteroids Deluxe "prediction" logic where the enemy saucer will sometimes shoot at a position where the player is anticipated to be if he keeps moving at current speed/direction. So, for a simple algorithm for an enemy you might have a few variables that you periodically change: Timer - this counts down and at zero you load a new timer value, which can be random. When the timer hits zero, you then make a decision to change other variables. Velocity X/Y- dictates direction and speed of an enemy. This changes when enemy hits a boundary, obstacle, or timer counts down. You can decide randomly whether the new value is random, or is set to a strategic value based on "seeking". Randomness - a threshold value that dictates what percentage of an enemies behaviour is random and how much it's based on strategic seeking. On top of that, you might also have set paths that are followed and broken on certain conditions, e.g. randomly, or if the player wanders within a certain range. To add a little further info - you might also have trigger points where a player might pass, and they can be used to alter the way a particular enemy/s behave. 1 Quote Link to comment Share on other sites More sharing options...
man vs. 2600 Posted April 20, 2011 Share Posted April 20, 2011 I was playing around with some really basic enemy AI today and built a small enemy wanders around on his own program that includes some collision detection based on parts from move_around_rooms. Hope this is useful. enemy routine.bas 1 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted April 22, 2011 Share Posted April 22, 2011 (edited) I've learned it's handy to incorporate a "stuck" routine in my enemy AI. Sometimes just heading toward a player will leave the critter just banging into the same wall. I increment a variable every turn the monster stays stuck in one location. When a certain threshold is reached I tell the monster to move in a new direction or change behavior. Edited April 22, 2011 by theloon Quote Link to comment Share on other sites More sharing options...
+Atarius Maximus Posted November 18, 2011 Share Posted November 18, 2011 This is my first attempt at writing an Enemy AI routine. It's not absolutely perfect, but it works fairly well. The enemy will always follow the player until it hits a wall. If it gets stuck on a wall for too long, it will choose a random alternate path to try and get around the obstacle. The demo has a player sprite you control and an enemy sprite that will follow you. If you stay still for long enough, the enemy will eventually find his way to you. The biggest area this could be improved would be the logic used when the enemy chooses a different path. It's completely random right now, but checking the current position of the player and heading in that general direction would make it better. The problem is that heading directly to the player isn't always the best path to take. It would be easier to code it if the playfield was always static, but I was looking to do something that would work with any playfield configuration. Putting in a very complex playfield would probably make this sample code much less effective. The distance traveled when an alternate path is chosen would have to be tweaked, as well as how many turns are taken and how long that routine runs before switching back to the simple "head towards the player" movement. I'll post again when I've had more time to work on it, but I wanted to share what I have so far. Any thoughts, comments or suggestions would be appreciated. Steve enemyai.txt enemyai.txt.bin 2 Quote Link to comment Share on other sites More sharing options...
scitari Posted April 11, 2020 Share Posted April 11, 2020 Would love to see additional examples. Thanks! Quote Link to comment Share on other sites More sharing options...
Sknarp Posted April 19, 2020 Share Posted April 19, 2020 This was the absolute smallest one I ever came up with. Quote for sswap = 0 to 3 if !COLUP2[sswap] || diceroll/32<sswap then goto skipthisenemy if NUSIZ2[sswap]=%00100000 then player2x[sswap]=player2x[sswap]-1 if player2x[sswap]<15 then NUSIZ2[sswap]=%00101000 if NUSIZ2[sswap]=%00101000 then player2x[sswap]=player2x[sswap]+1 if player2x[sswap]>147 then NUSIZ2[sswap]=%00100000 skipthisenemy next In this program when an enemy was "dead" I just made them colored black because of the cycle efficiency of checking for it. This bit of code made each of four enemy sprites move from one side of the screen to the other, turning around when they hit the edge to face the other way, and they all moved at different speeds (Which was governed by the single "diceroll" randomizer that I used for every pseudo-random operation I needed to do) and when they either got hit a bad dice roll or had been marked as "dead" they would get skipped over completely to save extra cycles. I calculated at the time that it was about 138bytes lighter than if I had done it without a loop. It just shows that if you think a little outside the box you can save a lot of resources. Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted April 19, 2020 Share Posted April 19, 2020 Sometimes you can let the players position determine monster behavior. In this case the AI uses the players (player1 sprite) coordinates to decide some of the dragons (player0) movements. Usually people just use the players coordinates to "heat seek" towards the player. But, you can do more than that. Not really a code example. I glossed over _west, _east, _north and _south being constants. Also didn't explain p0ref being a bitwise define of a variable. Just included the code from one of my games to demonstrate intent movegdragon if direction = _west then player0x = player0x + 1 : p0ref = 0 if direction = _east then player0x = player0x - 1 : p0ref = 1 if direction = _north then player0y = player0y + 1 if direction = _south then player0y = player0y - 1 goto main_begin moveydragon if player1y > player0y then player0y = player0y + 1 if player1y < player0y then player0y = player0y - 1 if direction = _west then player0x = player0x + 1 : p0ref = 0 if direction = _east then player0x = player0x - 1 : p0ref = 1 if direction = _north then player0y = player0y + 1 if direction = _south then player0y = player0y - 1 goto main_begin moverdragon if player1x > player0x then player0x = player0x + 1 : p0ref = 0 if player1x < player0x then player0x = player0x - 1 : p0ref = 1 if player1y > player0y then player0y = player0y + 1 if player1y < player0y then player0y = player0y - 1 if direction = _west then player0x = player0x + 1 : p0ref = 0 if direction = _east then player0x = player0x - 1 : p0ref = 1 if direction = _north then player0y = player0y + 1 if direction = _south then player0y = player0y - 1 goto main_begin 1 Quote Link to comment Share on other sites More sharing options...
KevKelley Posted April 19, 2020 Share Posted April 19, 2020 In Bag Boy, the closest thing I have to an enemy was the boss at the top of the screen. It starts off with simple right to left movement. But to make them more difficult I have their position determined by the location of the passing cars below so that the move in a somewhat erratic but not too limited way. In Manatee Madness, I have a couple different enemies. Some are simple back and forth movement with maybe a change to the y-axis based on player location. Some move in a set path. Right now the most complicated are the gator and diver. The gator moves towards the player. So does the diver. But if the gator gets too close to the diver he goes towards the diver. If the manatee hides behind the sea grass, the diver tries to surface until the player is visible again. I haven't made any real complex AIs to date, as I am still learning, but so far I have found a mix of randomness and conditional statements give a good degree of simulated intelligence. 1 Quote Link to comment Share on other sites More sharing options...
Captain Spazer Posted April 26, 2020 Share Posted April 26, 2020 This is how I do extremely simple platforming enemy AI that can walk and fall of ledges: rem gravity player0y = player0y + 1 rem enemy stops when in contact with playfield if collision(player0,playfield) then player0y = player0y - 1 rem enemy walks right or left if it touches the screen borders if u = 0 then _P0_L_R = _P0_L_R - 0.35 if u = 1 then _P0_L_R = _P0_L_R + 0.35 if player0x = 15 then u = 1 if player0x = 140 then u = 0 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.