Game Maker 8 Enemy Aircrat
Blog Elementi Di. Free alphasim freeware aircraft download software at UpdateStar - 1,746,000 recognized programs. Game Maker 8 Enemy Ai Mods.
Motion is critical to just about any video game. Nearly every game has moving things in it, and how they move is a vital part of the game. Learning how to program motion and control it effectively is one of the most important parts of a successful game. There are a number of possible approaches to handling position and movement.
Learning how these work will help you make better games. This isn’t absolutely everything there is to know about motion, but it’s a great overview to start with, and covers everything I’ve learned with respect to motion in GM:S. Position Variables: x, y The current x and y coordinates of the instance. These are in reference to the absolute x and y coordinates in the room. The left-top corner of the room is (0,0), and the right-bottom corner of the room is (room_width, room_height).
Coordinates outside the room are valid locations — objects don’t automatically cease to exist or stop functioning just because they are outside the room. Indeed, they continue to exist and function, unless you code them otherwise, and of course they can come back inside the room. Think of the room as the “stage” of a theater that the player views; the area outside the room is “off-stage”. Stuff still exists when it goes off-stage, and things can happen to that stuff. However, positions that lie outside the room will never be displayed in the game.
The game will stop scrolling at the edge of a room, showing no space outside of it. Xprevious, yprevious The former x and y coordinate of the instance, from the previous step. Comes in handy when you need to compare where an object is to where it was, or if you’re trying to handle collisions with high-speed objects (see below).
Xstart, ystart The x and y coordinates of the instance when it was created. Useful if you need to return an object back to where it started from. You can also change the values to update the starting point (such as if the player reaches a new save point.) GML move_ functions There are a number of GML functions built in to GameMaker, whose names start with “move_” that are good to be aware of. Move_snap(hsnap, vsnap) Moves the instance to the nearest position in the room, aligned to an invisible grid of “cells” of a size defined by the hsnap and vsnap arguments. This is pretty easy to understand.
Let’s say you want to base your game off of a grid of 32×32 pixel cells. You want your instances to align to this grid. If an instance is at a position such that instance.x and instance.y are both mulitples of 32, then it is aligned to the grid.
If the instance is not aligned to the grid, this function will move the instance to the nearest location that is a grid intersection. A common problem you may encounter with this function is if you have a grid within the room but that does not take up the entire room. Say you have a chess board in the room, but there is a border around the chess board. You want cells in the invisible grid to align with the squares of the chess board, but because of the border, there’s an offset because the border is not a width that aligns to the grid. To adjust, you simply need to offset the positions of the instance after calling move_snap.
Move_snap ( 32, 32 ); x += border_x; //border_x and border_y must be defined by the programmer. Y += border_y; move_snap(32, 32); x += border_x; //border_x and border_y must be defined by the programmer. Y += border_y; Keep in mind, too, that the instance’s sprite origin can confuse the location where the instance is being drawn. If the origin is centered, the instance will appear centered on the grid intersection (like a stone in Go) rather than centered inside the grid cell (like a chess piece). The results from move_snap are based on the instance’s x and y, so how it ends up looking will depend on the instance’s sprite’s origin. Move_random(hsnap, vsnap) The move_random() function moves the instance to a random location in the room that is an intersection on the invisible grid defined by the hsnap and vsnap arguments.
As with move_snap(), move_random() has the same issues to be aware of with grid offset and sprite offset. Move_towards_point(x, y, speed) This function sets the speed and direction of the instance so that it will move towards the point (x, y) as defined by the first two arguments. It’s convenient in that the function figures out the direction to travel for you, based on the spatial relationship between the calling instance and the destination point. Move_contact_all(dir, maxdist), move_contact_solid(dir, maxdist) Moves the calling instance in direction dir, up to maxdist pixels, or until the instance contacts another instance. This does not set a speed, so it is using the position assignment method to move the instance. If the moving instance does encounter an obstacle, it stops just short of triggering a collision.
The move_contact_solid function works only with objects that have the solid property. This is a very useful function for platformer games. Move_bounce_all(advanced), move_bounce_solid(advanced) Calling this function causes the object to bounce when it encounters another instance (or solid instance) in the game. The instance will only bounce off of other instances if they have a sprite or mask index. The bounce function calculates the new direction and applies it to the instance. If the advanced parameter is set to true, the bounce direction is calculated with greater precision. This requires greater processing and can slow the game down if too many instances are using it.
Realistic bouncing is probably better done using the new Box2D physics. This move_bounce is an older GML function that has been around in GameMaker since long before the new physics engine was added. You can still use this function if you don’t want to bother with the full physics system. Move_outside_all(direction, maxdist), move_outside_solid(direction, maxdist) These two functions are the inverse of move_contact_all and move_contact_solid. They are intended for when two objects are in collision, and can be useful to resolve a collision event so that the collision event does not happen automatically again during the next step. They work by relocating the calling instance up to maxdist pixels away, in direction, until a collision condition is no longer present. If no value is provided for maxdist, GameMaker will assume a value of 1000 pixels.
The catch here is that the instance will move until it is outside of any collision condition. So if the move_outside function is triggered by a collision with one instance, and moving just outside of collision with the first instance would result in a collision with another instance, the calling object will continue to move until it is positioned outside of any and all collisions, or maxdist is reached. This is possibly not desirable, since you may need the collision with the next instance to be triggered as well. In this case, the best thing to do is set maxdist to a small value, such as the calling instance’s sprite offset. The move_outside_solid() function can be useful to get an object out of collision condition with solid objects. One of the annoying things about solid objects is that when they overlap (collide) with an object, they prevent the object from moving, causing it to become stuck or embedded inside the solid object.
An object with a speed and direction will not move through a Solid object, and if it is in collision with a Solid object, it cannot move by its speed and direction vector any longer. The only way to move it is by position assignment.
The move_outside_solid() function does the necessary calculations to place the calling instance just outside of the collision mask of the Solid object. A lot of GameMaker developers avoid using the Solid property entirely, opting instead to handle objects which they wish to behave as though they were solid using their own code. Move_wrap Mentioned here for completeness, but discussed in depth in the section.
Vector variables: In GameMaker, a motion vector is a speed (in pixels per step), combined with a direction. Direction The current direction of motion of the instance, in degrees.
0 = right/”east”. 90 = up/”north”. 180 = left/”west”. 270 = down/”south”.
Direction model for Box2D Physics You’ll need to compensate for this if you ever need to convert a GM Object’s direction to a Box2D fixture’s direction. GameMaker direction = Box2D direction + 90 Box2D direction = GameMaker direction – 90 Related to direction is image_angle, which is a built-in GML variable that is used to rotate the sprite belonging to an instance. If you only change an instance’s direction, it will move in that direction but the sprite will continue to be drawn with its orientation unchanged. If you want the sprite to rotate, you can set image_angle = direction. This is why it is usually best to draw your sprites so that they face right, so that image_angle = 0 looks correct for direction = 0. Speed The speed in pixels per step in the current direction. Negative = moving “backward”; positive = moving “forward” with respect to the current direction.
Hspeed The horizontal component of the instance’s speed, in pixels/step. Negative = moving left; positive = moving right. Vspeed The vertical component of the instance’s speed, in pixels/step.
Negative = moving up, positive = moving down. Up being negative often seems counter-intuitive to new programmers, since “up” should be “higher”. Just remember that the room coordinate system starts with its origin at top left, at (0,0), and counts upward to positions that are vertically down from the origin. Tip: speed, hspeed, and vspeed The values of speed/ direction, hspeed, and vspeed are interdependent, and are updated automatically by the game each step when one of their values changes. For example, if you set and speed = 8 direction = 0, your instance will be moving to the right at a speed of 8px/step.
If you look at the value of hspeed, it will also be 8, even though you never directly set hspeed. This means that hspeed and vspeed and speed are always accurate to the actual motion of the object in the game. This is very useful. For example, if your instance is not moving at an orthogonal angle (eg, 0, 90, 180, 270), and you need to know the horizontal or vertical component of motion for some reason, without hspeed and vspeed, in order to know its precise horizontal or vertical speed, you would need to perform trigonometry functions in order to isolate the horizontal and vertical components of the object’s motion vector. But, thanks to hspeed and vspeed, this is already done for you, “for free.” One thing to note about this is that changes to hspeed or vspeed can change direction, but changes to absolute speed do not change direction.
To illustrate this, take an instance in your game moving at speed = 8, direction = 0. It is moving 8px/step to the right. To reverse its motion, you could use either speed = -speed, or direction += 180. In the first case, you’ve reversed speed but in the other you’ve reversed direction. Visually, the result is identical (unless the sprite’s image_angle is also updated, or you swap sprite_facing_right with sprite_facing_left).
If we watch the variables, we see that it’s possible to have negative speed, so that it’s possible to move “backward” at a negative speed, but that when hspeed or vspeed reverses, direction also reverses. An object with a negative hspeed will always have a direction between 90 and 270; positive hspeed, a direction between 0-90 or 270-360. And object with a negative vspeed will have a direction between 0-180; positive vspeed, between 180-360. This can be easier to understand with the following demo. Your browser does not support iframes. Go to to experience the demo.
Use the left/right arrow keys to increase/decrease hspeed. Up/Down arrows to increase/decrease vspeed. W/S to increase/decrease absolute speed, A/D to increase/decrease direction.
Watch how the values relate to each other as they change. Gravity Acceleration in a given direction (270 == down) at a given rate. Gravity can be a little tricky to get right. We think of gravity in the real world as a force which attracts massive objects together. In GameMaker, it is just a vector, a force which adds speed in a given direction.The vector is added to the instance each step, so it can add up quickly and come to dominate the instance’s motion.
In the real world, we think of gravity as a force which affects everything equally, but in GameMaker, gravity is set on a per-instance basis. This means that you can set different forces and/or direction for each instance. Brookstone Slcd V3 0 Manualidades. This could be used, for example, to create MC Escher spaces in 2D where gravity works differently for each object, depending which surface they are standing on.
Or for creating some objects that are affected by gravity while others are not. The official documentation recommends using a small value, such as 0.2.
I often like to start with a small value, but add to gravity over time to give a more pronounced accelerating effect. Over time the acceleration due to gravity can really add up, leading to very high speeds, which can lead to problems with collision detection (see below). Often it’s desirable/necessary to cap an instance’s speed with a “terminal velocity” so speed doesn’t get too crazy. You can set a negative speed to gravity, which is equivalent to setting gravity in the opposite direction. Gravity is very useful as a component of jumping mechanics, or for ballistic trajectories of flying objects.
You can also use gravity for more novel purposes, such as to simulate the force of a strong wind pushing against objects, blowing them away. Unfortunately, you cannot have multiple gravity forces acting on a single instance. (You can, however, write your own “pseudo-gravity” functions to do this.) Also, gravity does not have a location — it does not attract an instance to a particular point in the room, it just adds speed in the direction set by the instance’s gravity_direction. (You can fake a gravity toward some object or point in the room, if you update gravity’s direction each step, and use point_direction(x, y, attractor_x, attractor_y) Again, you can just write your own code to create this behavior if desired.
Friction Deceleration, slowing the instance, until speed reaches 0. Friction is useful for simulating slippery surfaces like ice, where an object shouldn’t stop immediately, or viscous surfaces, like mud, where constant effort is necessary in order to keep moving. Friction has no direction; by its nature it works in opposition to the present direction of the instance it is working on, by reducing its speed until it reaches 0. You can set negative friction, which is essentially the same as setting gravity in a direction which constantly matches the instance’s direction. Techniques You can change the values of these functions in any mathematical way you can imagine.
Understanding the math is important to getting the behavior you expected. Position assignment. Speed = min (max_speed, speed + accel ); speed = min(max_speed, speed + accel); Speed increases each step by accel pixels/step until max_speed is reached. Note max_speed and accel are not built-in variables, and must be created and assigned values in the program. As you can see, most normal motion can be expressed through simple value assignment (the equals sign) or through addition or subtraction. Other math is possible, of course.
These numbers are just numbers, and you can perform any math on numbers. You can get some interesting effects using multiply, divide, exponents, square root, logarithms, trig functions, etc. In many different ways to modify position, speed, or direction.Oftentimes it’s useful to multiply a base speed by another number to get a range of relative speeds for walking, running, or whatever. Linear interpolation and extrapolation with the lerp() function One gml function that is very useful for movement is lerp(), the linear interpolation function. Lerp(a, b, amt) returns a value between a and b that is interpolated by the amount (when amt is between 0 and 1). Lerp can be used in many ways, usually it’s best to lerp iteratively each step, so in the Step event, or in an Alarm loop: lerp the position (x,y) coordinates of an instance, to smoothly approach a position: x = lerp(x, destination_x, percent); y = lerp(y, destination_y, percent); lerp the speed to smoothly accelerate or decelerate to a target speed.
Speed = lerp(speed, desired_speed, accl); lerp direction, to smoothly turn towards a desired direction. Direction = lerp(direction, desired_direction, turn_rate); You can even use lerp to extrapolate rather than interpolate, by using a value greater than 1 for the amt argument. The help file provides a cool example that you can use to predict the position of an instance one second in the future based on its current hspeed and vspeed: future_x = lerp(x, x+hspeed, room_speed); future_y = lerp(y, y+vspeed, room_speed); This can be used to target where an object will be, assuming its speed and direction don’t change. You can replace room_speed in the example above with the number of steps in the future you need. Other techniques Find the distance or direction GML provides a few functions that are useful for determining where things are, which can help you know where you want to go: • instance_nearest(x,y,obj): returns the id of the nearest instance of the named object class to the point named at (x,y). If you call a parent object, the function will return the nearest object that is of the parent class, or any of its descendants. • instance_furthest(x,y,obj): returns the id of the most distant instance of the named object to the point named at (x,y).
• distance_to_point(x,y): returns the distance from the bounding box of the current instance to (x,y). Note that there is a subtle, crucial difference between the bounding box and the x,y position of the calling object (normally a point somewhere within the bounding box of the object’s sprite). • distance_to_object(obj): returns the distance in pixels from the calling object to the nearest edge of the bounding box of the instance specified in argument0, or the nearest object specified if an object name is used instead of an instance. Again, there is a difference between the bounding box edge and the x,y position of the target instance.
• point_direction(x1,y1,x2,y2): returns the direction (in degrees) from point (x1,y1) to (x2,y2). • point_distance(x1,y1,x2,y2): returns the distance (in pixels) from point (x1,y1) to (x2,y2). Relative Positioning An instance’s x and y variables always refer to the absolute coordinates within (or sometimes outside of) the room. Oftentimes, though, it’s easier to think of a position as being relative to the position of some other instance. We don’t care where in the room something happens, we care that it happens exactly M pixels to the left and N pixels up from some object in the room, which might be anywhere.
It’s easy to use the object of interest’s position as a reference point, by calling instance.x and instance.y, and then using simple math to offset an amount of room pixels relative to the instance’s position. Rather than using the instance’s x and y position, it’s also possible to use the bounding box of the instance’s sprite: • instance.bbox_top • instance.bbox_bottom • instance.bbox_left • instance.bbox_right You can also use the sprite’s height and width: • instance.sprite_width • instance.sprite_height Finally, you may want a position that is some distance from a point, in an arbitrary direction. To do this you can use trig functions;in GML, the trig functions all take the angle argument in radians, and direction is in degrees, so you have to convert direction to radians using degtorad().
[Update: this is changing with GM:S 1.3, which will introduce degrees-based trig functions.] As well, the image_angle variable is also degrees. • x - distance * sin(degtorad(direction)) • y + distance * cos(degtorad(direction)) GM:S 1.3 on: • x - distance * dsin(direction); • y + distance * dcos(direction); Actually, in GameMaker, there is a pair of functions that do this math for you. I included the trig functions method to expose the underlying math, and to make the example more relevant to other languages and frameworks, but if you’re using GameMaker, you can use these built-in functions instead: • lengthdir_x(length, direction) • lengthdir_y(length, direction) When using the lengthdir functions, it expects the direction argument in degrees, so you don’t need to convert it to radians.
Sprite direction and Motion direction are independent If you change an instance’s direction, it will move at speed in the new direction. Note however that the instance’s sprite still points in the same orientation as before. Unless your sprite is completely symmetrical, this probably doesn’t look right. In the Lite edition of GameMaker, you can use the sprite editor to create a rotation animation, and then every step in the game you can update the image_index for the object to match the correct facing image in the sprite. This is a tedious and limited approach, since it uses up the sprite’s animation capability to perform the rotation, eliminating the possibility of performing other animation. In the paid editions of GameMaker, you can rotate the sprite in code, and make it point in the direction of motion: image_angle = direction; This works fine if all you need is for your sprite to rotate to point the direction of the instance’s motion.
It’s a great approach to take for top-down spaceship or car games. This approach is not right for all games, though.
For example, the original Legend of Zelda had separate views of each side of each character: front, back, left, right. These were not simple rotations of the same image, but rather were different images depicting the character from the front, side, side, or back. There are a lot of ways to implement a 4-sprite system. You could use a single object, and just change which sprite is drawn based on the direction the object is facing.
Or you could create a group of objects, each one representing the character facing a given direction. The four-object approach sounds like more work and more complexity, but it actually allows you to keep each object much simpler.
To start out, it’s optional, but handy to create constants to make your code more legible. If your goal is simply to make a ball that will bounce, that’s not too hard. There are many ways to do it, but is probably the easiest. In general, the GameMaker documentation available at is the best place to start when you want to learn how to do something.
There’s also good tutorials built into GM:S, if you look at the projects in the Tutorials tab you can see clearly how many different types of games are built. If you’re new to GameMaker, they’re the best place to start. If you actually want to draw a line that traces the path the ball takes when it bounces, that’s a different matter. Your best bet would be to ask your question on the, in the Questions & Answers forum. If you haven’t yet, try asking this on the.
Lots of people will help. This could be tricky if you need to calculate the motion with each step, but could be very easy to do if you use Paths, which I didn’t cover in this article. The easiest non-paths way to do it would be to provide an initial motion to the projectile, by setting speed and direction, and give the projectile some gravity. A linear velocity plus downward acceleration due to gravity will result in a parabolic arc emerging naturally, although to get it to be positioned exactly where you want it, at the speed you want it, could take some trial and error tweaking.
Thanks so much for the kind words. When I was learning the basics in GameMaker, I found that as I learned things, I'd forget them again if I didn't use them all the time. After a while, I realized that taking notes and explaining to myself how stuff worked helped a lot — as much as reading the Help file, if not more so. And I realized that this had value beyond simply writing it for myself, so I put it up on my website to share with people, hoping it could benefit many. To this day, this is the most popular thing I've written, and it's always good to hear from people who found it useful.
Here's the situation. Question 1: I've got an instance of a naval vessel.
It creates a turret at x,y (which is a point inside the sprite). The vessel rotates so that it is always facing the direction of motion. (sprite rotates 360 degrees in 180 frames, during the step event image_single=direction/2. ) How can I keep the turret at the same relative point on the body? Some of the vessels have too many guns to just put the coding in the ship instance.
Question 2: These turrets of mine are auto-targeting and auto firing. They use instance_nearest for targeting. (all enemies are the same object, they just fire differently based on how they are created) Can I get my turrets to ignore some targets in favor of others? A sort of weighted targeting system? Any suggestions appreciated. Have the ship create it's turrets and just keep them locked to an x and y on each ship as it moves. So in the turrets step event have x = ship.x+(what x on the ship you want it) and do the same for y.
For the second question you could you something like collision_circle and prioritize them with some if statements. Use the collision_circle to check what's inside the area and set a variable for each type, if one is in the circle set the variable to 1(true) and say if this enemy is in range and so if the other one then attack this enemy. The first suggestion would only work for a sprite that always faces the same way. The second sounded promising, but I think it would require too much coding. As all enemy turrets are instances of the same object, the check would return as true even if they fire differently. It's hard to explain, but the same object will have roughly 30ish different ways of fire depending on which fleet it belongs to and what types of turrets each can use.
One fleet may have 7 different turrets while another only has three. I thought perhaps I could set a variable at each creation, and my turrets could check that variable when determining which nearest instance to fire. I just don't know how to make them ignore lower valued targets. Did that make sense? I appreciate the time you're all taking to help me.
Code: player.x = 200; player.y = 200; len = 120; dir = 37; x1 = x+lengthdir_x(len,dir); y1 = y+lengthdir_y(len,dir); x1 and y1 is the exact point 120 pixels away, facing degree 37. Now how do you implement this? Make your sprite facing right. WHen you change image_angle you'll always have a value between 0 and 359. The turret position will have to be updated every step, using lengthdir_x and lengthdir_y. When rotating the player, you'll change its image_angle. Now, for ds_priority.
It's not complicated. A ds_priority queue is a special data structure where values is ordered by the priorities (always real numbers) that the values have been assigned. The best example I can give you is a leaderboard. Ds_priority_add(id, val, priority).
Click to expand.Okay, what's going on here is. The turret offset locoations are stored in turret_array. The offset locations are the location of each turret relative to the ship's origin. You measure these offsets by just counting the pixels in between the turret and the ship's origin, both along the x and the y axes. For each turret, the offset is copied into temporary variables _x, _y, just to avoid having to look them up twice. Then the turret's world position is calculated by rotating the point (_x, _y) by the angle 'image_angle', and then adding the result to the ship's world position (x, y).
(turret_world_x, turret_world_y) is the turret's world position. I am using priority targets in my game. All enemies are in few classes. For example Heavy towers are checking if heavy enemies are in the range and they are targets, if not, other enemies are.
In the beginning I had only enemyParent, but later I switched to a structure like this: Enemy->LandEnemy; AircraftEnemy LandEnemy->BuildingsEnemy; MobileEnemy MobileEnemy->Tanks; Trucks, etc. This structure is very useful for prioritising because I want some units to target primarily Aircraft, other Buildings, etc. Another option is if you have only one type of enemy but your turrets are shooting to an invisible helpers, that are stick to the enemy. When the enemy is hit by the bullet it takes damages and when is destroyed kills the helper too. So helpers will have the same structure as above. I recommend to use such structure. I've come up with, I think, a pretty great system for AI target selection.
First, every step, the game selects one or two or three units from each side, and builds a list for them of all the enemies that are near them. That way, ai will only consider targets which are near enough from them to reach, and we wont waste any time processing enemies that are farther away. The game will go through all the units on each side sequentially so that no unit has to wait more than perhaps a second or two to get their target list updated with new data. Second, each unit, ever 2 or 3 steps, will consider the next target in its target list. It will do this sequentially. It will consider this target by measuring the distance to that target, the direction of the target, whether the target is moving toward or away from it, how many other units are attacking the target, how damaged the target is, how dangerous the target is.
It may consider a few other factors as well. It calculates a score for all of these factors, and adds them up. If the final score is greater than the score held by the currently selected target, then the ai will switch targets to the one it was considering in this step. The ai should also occationally reevaluate the value of the currently selected target to keep it up to date.
It probably doesn't need to do othat more often than once or twice a second. Saucer, that sounds beautiful.
And incredibly complicated. If you think I could understand it, could you share it?
And I think I understand your other post now. I'll test it later and see. And I'm not sure I was able to express in enough detail how my turrets work, so now that I'm at a keyboard(with Internet! Not at home) and not my cramped phone Vboard.
There are, at present, 10 different (planned) fleets. Each fleet can only create its specific type of turrets It does this in the creation event. At this time, no matter what fleet it is, IT CREATES MULTIPLE INSTANCES, OF THE SAME OBJECT AS ANY OTHER FLEET/VESSEL. Each fleet has multiple vessels of varying size/power/weapons, (and the user can BE one of those fleets) so it's not like a single standard ship creating whatever turrets. This turret is then assigned a variable called wepclass that tells it 'you can only use this fleet's guns' by acting as an alarm reference. THEN it is assigned a variable called type, that determines what type of bullets, cooldown etc.
Like this- (I do a lot of my work in the execute code action) creates a turret by trt1=inst_crt(x,y,myturrets) trt1.wepclass=1 trt1.type=3 trt1.alarm[wepclas]=// for now, until I have all the mechanics working, it's just random(200) //continues with other turrets the turret starts its life by in whatever alarm wepclass starts, it is structured thus- if variable type=1 execute code//which contains the firing rules for this turret. I've got this stuff down perfectly.
The types aren't just numerical based on how many total guns that fleet can use, but based on the power of the turret, up to 10. What I'd like to be able to do is refer to myturrets type, check the type of enemy turrets and use that to prioritize what enemy type it can target.
It'd be great to be able to target a range of the variable type. On that note.Can I refer to alarms that don't actually exist, such as a hypothetical alarm[12,13, etc]. Thanks Nazghul, your lengthdir explanation helped put me on the right track.