@TheRetroRoomRoo sure I can break things down for you.
TheRetroRoomRoo wrote: ↑Tue Mar 16, 2021 8:28 pm
also which languages are we using here? It is definitely new to me not to use brackets of some sort on conditionals like an "IF" statement.
First, let me go over the two languages DSGM 5.12 allows which is C and DSGM's own language called "DBAS".
In the below example code I provided you, I used a mix of the two languages because DSGM allows you to use them interchangeably but I should have just used 1 language to make things simpler for you. Sorry for the confusion.
Code: Select all
'If npc is facing direction 0 (Right), is not collided with the player, other objects, nor the collision map, then move NPC in 1 in every 2 chances randomly per game update frame.
If Direction == 0
if !Sprite_Collision([Me], Get_Single_ID(Player1))
If !Object_Under_Point(Top_Screen, [X]+[Width]+2, [Y] + [Height]/2, NPC1)
if(PA_EasyBgGetPixelCol(Top_Screen, 3,[X] + [Width]+2, [Y] + [Height]/2)!= PA_RGB(0,0, 0)){
if Test_Chance(2)
[X]+= 2;
End if
End if
End if
End if
End if
'In 1 in every 100 chances choose a random NPC direction
if Test_Chance(100)
Direction=Random(0, 3);
End if
The difference between C and DBAS is basically DBAS is a simplified version of C where you don't need brackets or symbols like semicolons which makes it overall a simpler and more beginner-friendly language to read. Though it's ideal to only use 1 language (preferably C) there are some cases where you may have to use both languages in order for DSGM to read no errors and compile your game. DSGM can sometimes be very fussy for the littlest mistakes such as extra spaces in the code.
Below is the same code now entirely written with C. However you may have errors if you try to run the same code as I didn't test it.
Code: Select all
//If npc is facing direction 0 (Right), is not collided with the player, other objects, nor the collision map, then move NPC in 1 in every 2 chances randomly per game update frame.
if (Direction == 0){
if !(Sprite_Collision([Me], Get_Single_ID(Player1))){
if !(Object_Under_Point(Top_Screen, [X]+[Width]+2, [Y] + [Height]/2, NPC1)){
if (PA_EasyBgGetPixelCol(Top_Screen, 3,[X] + [Width]+2, [Y] + [Height]/2)!= PA_RGB(0,0, 0)){
if (Test_Chance(2)){
[X] += 2;
}
}
}
}
}
//In 1 in every 100 chances choose a random NPC direction
if (Test_Chance(100)){
Direction = Random(0, 3);
}
TheRetroRoomRoo wrote: ↑Tue Mar 16, 2021 8:28 pm
In the code example sent above, what is considered global variables and what is considered functions? Lets say my player object is called "Player1" and my Npc character object is called "NPC1"...If its not too much trouble could you show me notes of what is going on in the context of what is a function VS what is a Global Variables.
Now let me explain the global variables and functions used in the above code.
Direction is a global integer variable I made which is responsible for keeping track of which direction the NPC is facing. Integers variables have an integer-based value, meaning they can only be equal to whole numbers as opposed to Float variables which allow for numbers with decimals. Note that you can declare global variables in the tools menu or in an external .h file. In this example, I have decided that when Direction = 0, then the NPC is facing right and that the movement code will only run when the NPC is facing right.
Code: Select all
if !(Sprite_Collision([Me], Get_Single_ID(Player1))){
Here I'm using the function Sprite_Collision(InstanceID1, InstanceID2) where we check to see if the NPC has collided with the player. If NOT, then continue running the rest of the code that follows. In coding, a function is just premade code that carries out a certain task for you without you needing to write all the directions yourself. If we were not to use the Sprite_Collision Function, we would then have to use many 'if' statements to check to see if the x and y coordinates of the two game objects are overlapping. Why re-create code that's already been created for you and many others to use right? That's the purpose of DSGM's built-in functions.
Code: Select all
if !(Object_Under_Point(Top_Screen, [X]+[Width]+2, [Y] + [Height]/2, NPC1)){
Now we use the Object_Under_Point(Screen, Xposition, Yposition, ObjectName) function to check to see if any other instances (i.e duplicates) of NPC1 are going to be in the way of NPC1's movement. Assuming the game takes place on the Nintendo DS's top screen we have specified as such in the "Screen" parameter of the function. The Xposition is just the current x position of our moving NPC1 (i.e [X]) plus its sprite width and 2 pixels. We add this offset from [X] because our NPC is going to be moving right by 2 pixels in this example and so we need to check if the space 2px to the right of our NPC1 is unoccupied. The sprite width is added because in DSGM the position of a game object is actually measured from the very top left corner of a sprite. So you always need to add offset numbers when dealing with sprite positions to get accurate results. The Yposition is just the vertical midpoint of the sprite (i.e [Y] + half the sprite's height). Also, note that the y-axis in DSGM is more positive as you go down and more negative as you go up in the game world. That's backwards from what you learned in elementary school, I know.
Code: Select all
if (PA_EasyBgGetPixelCol(Top_Screen, 3,[X] + [Width]+2, [Y] + [Height]/2)!= PA_RGB(0,0, 0)){
Next, we check if our NPC is going to collide with the collision map with the PA_EasyBgGetPixelCol(Screen, BackgroundLayer, Xposition, Yposition) function. This function returns (i.e gives us) the pixel's color in RGB values from the position and background layer we specify. Just like the Object_Under_Point function we check to see if the NPC has NOT collided with the collision map by checking the pixel that is 2 pixels to the right of the NPC's very edge and is vertically in the middle of the NPC. So long as the pixel's color isn't black (i.e 0,0,0) then proceed with the next line of code.
In this example, the Test_Chance(sides) function is being used to randomize the movement of the NPC. In this case, every time the game updates/refreshes its frame there's a one in 2 chance of the NPC being able to move. This causes the NPC to have a stutter-like movement so you may want to use a combination of randomized timers instead to get NPC movement that's more commonly found in RPG games.
If all the above conditions are met, then the NPC can finally move exactly 2 pixels to right every time the game refreshes/updates. (DSGM games has a frame/refresh rate of 60 frames per second).
Code: Select all
if (Test_Chance(100)){
Direction = Random(0, 3);
}
Lastly, we set the NPC to randomly change its direction whenever the Test_Chance function returns true. I felt a 1 in every 100 chance was appropriate for this example.
That's the breakdown of the code that I used for random NPC movement. I only provided what you need for the NPC to move in the RIGHT direction, but you should have everything you need to allow the NPC to move in the other 3 possible directions (left, up, down). You basically reuse the same code 3 more times except with different values for the x and y movement and position values.