Alright, so I've had this problem for well over two weeks now, and I think I've fixed it, but before I get ahead of myself, I would like your help. I need the turrets in my Tower Defense game to focus primarily on the enemy that is both at the front of the line of enemies, and closest within range. Here's an example:
O = turret
I = projectile from turret
() = range of turret
# = enemies
I don't want the turret to do this:
( O )
I
# # # #
See how the enemy furthest to the right is within range of the turret? Well, I want that to be the turrets' focus until that enemy is out of range of the turret or destroyed by it. Are there any efficient means of doing this (always checking to make sure the turret is firing at the appropriate enemy) without its prioritization glitching out? I've encountered numerous errors in coding this and tonight I've found a way to solve all of them, but it requires the code being extremely long. I'd like a way for it to be shorter while accomplishing the same task because if not, the game will lag during moments such as upgrading, advancing to the next wave/level, etc. Plus, there will be 10 turrets available for purchase altogether which will each perform the same long and complicated tasks rendering the game a beast in terms of size and memory. If anyone understands this gibberish, please, if you could be so kind, help me. Thanks in advance, and happy scratching!
-TGZ
Last edited by Zparx (2012-06-28 04:43:25)
Offline
Umm... lemme think here.
Create a list called "ranges". Now, for each enemy, add a "0".
For each enemy, add this script:
when gf clicked forever if <in range?> //Whatever. replace item (1 v) of [ranges v] with [1] //The first 1 is the enemy number. Change. else replace item (1 v) of [ranges v] with [0] //The 1 is the enemy number. Change. end endNow, for the turret, you need a variable called "counter" and this script:
when gf clicked forever set [counter v] to [1] repeat until <<(item (counter) of [ranges v]) = [1]> or <(loopcounter) = ((length of [ranges v]) + (1))>> change [counter v] by (1) end if <not <(loopcounter) = ((length of [ranges v]) + (1))>> repeat until <(item (counter) of [ranges v]) = [0]> fire at enemy number (counter) end end endJust replace all of the red blocks with your scripts.
Last edited by SciTecCf (2012-06-29 03:30:46)
Offline
SciTecCf wrote:
Umm... lemme think here.
Create a list called "ranges". Now, for each enemy, add a "0".
For each enemy, add this script:when gf clicked forever if <in range?> //Whatever. replace item (1 v) of [ranges v] with [1] //The first 1 is the enemy number. Change. else replace item (1 v) of [ranges v] with [0] //The 1 is the enemy number. Change. end endNow, for the turret, you need a variable called "counter" and this script:when gf clicked forever set [counter v] to [1] repeat until <<(item (counter) of [ranges v]) = [1]> or <(loopcounter) = ((length of [ranges v]) + (1))>> change [counter v] by (1) end if <not <(loopcounter) = ((length of [ranges v]) + (1))>> repeat until <(item (counter) of [ranges v]) = [0]> fire at enemy number (counter) end end endJust replace all of the red blocks with your scripts.
This script only works for 1 turret. For more, make variables like, "counter2", and lists like "ranges2" and stuff.
I suppose I'll have to just work with what I've got being as how not enough details about my game can be given.. thanks for your help though!
Offline
Why does it have to be both the first and last? Usually you assign first or last or strongest or weakest to a turret. If both first and last are beside it, it's going to break down
Offline
Andres-Vander wrote:
Why does it have to be both the first and last? Usually you assign first or last or strongest or weakest to a turret. If both first and last are beside it, it's going to break down
First and last...what? I think you mis read my post haha (:
Offline
Zparx wrote:
Andres-Vander wrote:
Why does it have to be both the first and last? Usually you assign first or last or strongest or weakest to a turret. If both first and last are beside it, it's going to break down
First and last...what? I think you mis read my post haha (:
Oh, yeah I did. Sorry about that, it's 5AM here. Let me just re-read everything
I'm not sure if scratch can assign numbers to sprites that are actually usable by other things, but if it could, you could make the turret always target the lowest number within range. Since it can't you could always do something messy like "if [#1] in range, target that, else: if [#2] in range, target that, else: if [#3] in range.. etc." but I'm guessing that's what you want to avoid because you'd have to keep expanding it until it accommodates all maybe 20 or so incoming enemies (if 20 is the most that ever come at once).
Last edited by Andres-Vander (2012-06-29 06:08:12)
Offline
Andres-Vander wrote:
Zparx wrote:
Andres-Vander wrote:
Why does it have to be both the first and last? Usually you assign first or last or strongest or weakest to a turret. If both first and last are beside it, it's going to break down
First and last...what? I think you mis read my post haha (:
Oh, yeah I did. Sorry about that, it's 5AM here. Let me just re-read everything
I'm not sure if scratch can assign numbers to sprites that are actually usable by other things, but if it could, you could make the turret always target the lowest number within range. Since it can't you could always do something messy like "if [#1] in range, target that, else: if [#2] in range, target that, else: if [#3] in range.. etc." but I'm guessing that's what you want to avoid because you'd have to keep expanding it until it accommodates all maybe 20 or so incoming enemies (if 20 is the most that ever come at once).
Well here's the thing, If it ONLY detects enemies in range (with no means of priority), I'm risking the possibility of the turret targeting random enemies in the line. Also, to add onto what you said about assigning numbers, what I COULD do, is assign them each a variable called "number" (or something) and set it to whichever numerical order they came out in (for example, sprite 7 comes out first. set its variable to 1. etc for 2nd and third) and make the turret target the lowest number based on "if touching (number) of (temp)" where as "temp" would equal the enemy the turret's range is touching. I don't know if you understand that but you seem like a well rounded person so maybe you do. The only problem is that if I have two turrets and say I have 3 enemies in line. If the middle enemy is destroyed, it becomes a challenge to figure out how to "tell" the turret to target the next POSSIBLE enemy in line. THEN, TO MAKE MATTERS EVEN MORE DIFFICULT, if an enemy exits a turret's range, then re-enters (trust me it happens A LOT because the range is round shaped) the turret won't know to fire at it because the variable for it's prioritization is ahead of that enemy's line number! It's very difficult, and as I previously stated, I HAVE in fact come up with a fool proof method of making this work flawlessly, but it requires the code to be un-godly long. I'm hoping I can find a more efficient way to code it than what I already have. Thanks a lot for actually putting thought and time into my question!
Last edited by Zparx (2012-06-29 06:56:07)
Offline
I circumvented this problem by making all the turrets user-controlled.
Offline
Wes64 wrote:
I circumvented this problem by making all the turrets user-controlled.
Mine are user controlled, all the way up to the point of choosing which enemy to shoot at. That's all ai controlled.
Offline