AI Help

Talk about making games.

Re: AI Help

Postby linkshards » Fri May 14, 2010 4:02 am

Woops. Totally misinterpreted that.
So then the original MoveTo method is fine right?
The animations never stop they keep repeating. If I had to scale each step per #pixels then I'd have a lot of still animations to import and I'd have to create an array for that, correct?

EDIT: Also, how does the coding know which direction the monster should face/animate?
User avatar
linkshards
 
Posts: 45
Joined: Tue Apr 27, 2010 3:40 am
Location: Cibolo, Texas
Score: 1 Give a positive score

Re: AI Help

Postby DST » Fri May 14, 2010 8:56 am

I'm not sure what you're asking with the animations. Take link himself, he has four running animations. Each one is a full cycle. All we've done here is use the STOPPED option in our animation, and animate the frames one by one based on his speed; i set it to be >= 4 and that would be the number of pixels he has to move to have taken another step.

I called a changeanimation, where each animation is complete - so you don't really need an array for the average monster. I usually have 6 animations - walking up, down, left, and right, attacking, and dying. My walking is usually 3-4 frames each, but i usually put more work into the attack and the dying. I like ghosts because you only have to draw one or two frames for them.

So the angle faced was where i said angle=direction(x, y, hero.x, hero.y). this returned the angle, which is a built-in variable of every actor, from 0-360 degrees.

The angle starts at 0 being right; 90 is up, 180 is left, 270 down, and 360 is right again. (that 360/0 break in the scale is why we had to compensate for angles over 315).

So then i took round(angle/90) to get the dir face....if your angle was 45, it would return .5, which rounds up to 1, thus if the monster moves upwards, he is at animation 1. If your angle was 134, it would return 1.49 which also rounds to 1. Thus we split the circle of direction into an x, with each quarter being a different 'dir', from 0-3.

To use angle for movement, you use the directional_velocity command. Otherwise, you just use moveto, which is good for making the character avoid walls.

I then used the sprintf command to write the dir number into a word; then called the animation to change to that word. The word was turned into a piece of code. Sprintf'ing the code in that way makes sorting and calling the animations easier.

If i used the werewolf method, i'd write it slightly differently, let's say your enemy has a hammer, and can swing that in any of four directions....:

char anim[20]=""; //creates empty word of 20 characters
char dirs[4]=""; //creates empty word of 4 characters

strcpy(anim, "attack"); //write 'attack' to the word anim
sprintf(dirs, "%i", dir); //write dir to the word dirs
strncat(anim, dirs, 1); //take anim and add 1 char of dirs. = attack1.

I hope i'm not confusing you further.
It's easier to be clever than it is to be kind.
http://www.lostsynapse.com
http://www.dstgames.com
User avatar
DST
 
Posts: 1117
Joined: Sun Apr 15, 2007 5:36 pm
Location: 20 minutes into the future
Score: 151 Give a positive score

Re: AI Help

Postby Hblade » Fri May 14, 2010 4:18 pm

DST, lol, you almost always confuse me farter xD sometimes I'll pretend to know when you explain things but in reality I'll be like "O.o?" lol
Subscribe to my YouTube? - Yes| No
User avatar
Hblade
 
Posts: 4455
Joined: Fri Dec 08, 2006 11:14 pm
Score: 181 Give a positive score

Re: AI Help

Postby linkshards » Sat May 15, 2010 3:11 am

I got it!
I got my AI work correctly! :D
Thanks for the consideration and help!

Nao I just gotta work on randomly spawning enemies.
User avatar
linkshards
 
Posts: 45
Joined: Tue Apr 27, 2010 3:40 am
Location: Cibolo, Texas
Score: 1 Give a positive score

Re: AI Help

Postby linkshards » Sat May 15, 2010 3:58 am

Wait wait, I have a tricky AI to create.
I've created a monster that is designed to appear, wait awhile, then disappear.
Then when he appears, it's closer and it's still the same monster.

While the monster is visible, he does not move.

The monster looks like this:
Image

It's a stick in the ground that comes up, stays up for awhile, then goes back into the ground (and while he's in the ground, he moves a certain distance closer to the player,) then comes back up.)

I have no clue where to get started with this guy. :(
User avatar
linkshards
 
Posts: 45
Joined: Tue Apr 27, 2010 3:40 am
Location: Cibolo, Texas
Score: 1 Give a positive score

Re: AI Help

Postby DST » Sat May 15, 2010 4:57 am

Code: Select all
var++;                   //start counting
if(var%vlimit==0){ //if vlimit is reached
mode++;  //change mode
mode=iLoop(mode, 0, 3); //remember that loop function? :D

switch(mode){        //do one of these actions depending on what mode is
case 0:                    //going below ground
ChangeAnimationDirection("Event Actor", REVERSE);
vlimit=20; //number of frames to wait to do next action
break;
case 1:                    //below ground
VisibilityState("Event Actor", DISABLE);  //cannot be seen or collided with
x=rand(view.width);     //move somewhere random
y=rand(view.height);
vlimit=60; //he'll spend two seconds underground
break;
case 2:                     //emerging from ground
VisibilityState("Event Actor", ENABLE);  //make visible
ChangeAnimationDirection("Event Actor", FORWARD); //move up
vlimit=20;   //estimation of animation time(2/3 of a second)
break;
case 3:                     //above ground
//do whatever you do above ground here.
vlimit=30;  //spend one second above ground
break;
}        //end case switch

}        //end var check


Where var , vlimit, and mode are actor variables you made.

Then add the event "AnimationFinish" and tell it to ChangeDirection("Event Actor", STOPPED), so he stops animating after rising or falling.

It may seem complicated, but i assure you it isn't. The logic is all right there, and the code is customizable enough so that it won't look clumsy in action - you can make it tight.

Just change the vlimits settings to adjust the timing.
It's easier to be clever than it is to be kind.
http://www.lostsynapse.com
http://www.dstgames.com
User avatar
DST
 
Posts: 1117
Joined: Sun Apr 15, 2007 5:36 pm
Location: 20 minutes into the future
Score: 151 Give a positive score

Re: AI Help

Postby linkshards » Fri May 21, 2010 3:57 am

Sorry to necro this thread a bit.
Thank you for the help DST.
All my monsters do exactly what I want them to do nao.

Nao, I'm stuck again. :(
I did some digging in the the Game-Editor's Forum to see what I could find with the healthbar and random spawning.

I found some work about the healthbar, but it continues to animate when there is nothing colliding with the main player. Could you show me a step by step of how get that set right? The healthbar is a graphic (frames, 11) I created, and is designed to decrease in everytime a monster collides with the player.

Also, nao that my monsters have been created and look alive, it's time for me to give then places to go. I can't seem to correct the code to get my monsters to spawn around the main player (atleast 10 pixels all-around) one after the other. I also can't seem to get the CreateTimer function to work correctly either.
Basically, I'm trying to get the code to randomly select a monster (monster1, monster2, monster3) and randomly spawn it at a random x or y position inside the view actor.
AND keep put a timer on it so more and more monster start spawning the longer the player survives. So it's easy at first, then gets ridiculously (and infinitely) difficult as it progresses.
User avatar
linkshards
 
Posts: 45
Joined: Tue Apr 27, 2010 3:40 am
Location: Cibolo, Texas
Score: 1 Give a positive score

Re: AI Help

Postby DST » Mon May 31, 2010 5:33 pm

For healthbar, it's best to use the draw actor of the player to assign it's value; because getting hurt isn't the only thing that changes it, getting a health powerup also changes it.

Player>Draw Actor>

Code: Select all
int i=round(health*0.1);
healthbar.animpos=i;


If the player only has 10 health points anyway, you can skip the i/round part and just assign the animpos directly.
I used (health*0.1), it does the same as (health/10) but it's good to get in the habit of using multiplication instead of division, as its faster (though it doesn't matter with single objects like player; it's enemies and bullets where this is really important).

With other things, i like to make a 'control' actor to handle events that aren't actor specific. here's what i mean:
WIth the healthbar script, i just put it in player, because health is a player variable, and we may do other things with it too, like link can throw swords when his health is full. Therefore, it's good to keep all script referring to player health inside player's draw actor.

Now the monster spawn rate is not linked to any specific creature, so i'd put that, along with level script and music code inside an actor called 'control'.

So to make a game harder as time goes on, use a specific variable to count down with, like this:

timera++;
if(timera==tlimit){
timera=0;
tlimit--; //every time tlimit is reached, it gets smaller, therefore spawning enemies faster!
//do spawn stuff here
}

When tlimit reaches a tiny number, like 0, you can then say that player has won the level. Then, to disable the script, just set tlimit to a negative number. timera counting up will never get to that negative number, then you can set tlimit positive again to start spawning all over again.

Now when you want to make your random spawning positions, precalculate them (don't use complex math inside a function call)

i=round(rand(20))-10; //rand 20 -10 results in answer from -10 to 10.
j=round(rand(20))-10;
CreateActor("Monster", "m1", "", "", i, j, true); //use i and j here, not the rand() math.

So throw that inside the timera script, and boom! Randomly spawning actors that spawn faster as the level progresses.

One thing you can do is if you have waves, or levels, you can work that into the same script - putting this before you calculate i an j and spawn the monsters:

for(i=0; i<=wave; i++){
i=round...etc; etc. //rest of spawning script here
}

Now, not only does the level get harder as time goes on, but each level spawns one more enemy each time than the last one.

Two notes: I always use i and j as my example ints; usually i is reserved for loops, it's good to name them something that's easy to work with but also describes what they are, if i were making this script in my own game i'd probably call the monster
random spawn values mx and my, (for monsterx and monstery).

Also, you see i am fond of using variables to count instead of the timer() function; timers aren't really meant to be used as frame counts. This is a big misconception for many GE beginners;

A timer is to get a specific amount of time, for performing time-sensitive but not GAME TIME sensitive operations, such as....starting a new song immediately after the current song finishes.

Since framerate can change depending upon the action and the computer speed, timers can screw stuff up. I had a game where stuff spawned in timers; the game slowed down, the timer didn't, more stuff spawned, slowing the game down further, and so on in a snowball effect until the game crashed.

Also, timer is an actor specific variable; it's not global. This means that if link dies, he cannot disable any timers in any other actors but himself. If control were spawning enemies on a timer, link would have to find a way to stop control when he died, (DestroyTimer() only works inside the actor the timer is called for!) while using a variable, link can just say
"control.tlimit=-1;" and control will stop spawning.
It's easier to be clever than it is to be kind.
http://www.lostsynapse.com
http://www.dstgames.com
User avatar
DST
 
Posts: 1117
Joined: Sun Apr 15, 2007 5:36 pm
Location: 20 minutes into the future
Score: 151 Give a positive score

Previous

Return to Game Development