GML Trying out an idea in GameMaker

R

RisingKane

Guest
Hello everyone!

I had an idea these days and I'd like to know if it's possible to implement it in GameMaker.

Let's say I have an object, like a square, and other objects, similar to blocks. Each of those blocks would contain actions, like walk, jump, attack, etc. My ideia is to put those blocks, organized like a queue, inside the square object, and when the player clicks the 'Start' button, all the corresponding actions according to the blocks inside the square object would be executed.

43.png

In the example above, as soon as the user clicks the Start button, the character would walk twice (grid-like movement) and then jump once.

Is it possible to do that? I'm trying to think of a way, but to no success.

Thanks a lot!
 

obscene

Member
Step 1 is to build a state machine in your player where it acts like you are describing. Forget the blocks for now... just build that part. Get your your player to stand idle, wait for a command and then enter a state where it takes a step and then stops to wait for another command.
 
D

davoid

Guest

You should easily be able to handle it with a state machine

Basically, then all you need to do is, instead of listening for user inputs, just use the array of commands you build to inform the object state
 
Last edited by a moderator:
R

RisingKane

Guest
Thanks for your answers, guys.

I think I know how state machines work now (never used them before). I made a simple test here, using inputs from the keyboard, and it's working nicely. Now I'm trying to move on to the blocks part, and I have some doubts going on:

- Since only the blocks that are inside the square are going to be executed, I need to check which blocks are inside it. To do that, I'm currently using place_meeting, but I'm not quite sure if that's the best option. Is there any other better way to do it?

- The other thing is about how I'm planning to do all this:
- Get the state machine working;
- Inside an step event, check which blocks are inside the square. For each block inside it, a change of state is stored somewhere (an array?). This includes repeated blocks;
- Add a delay of 2 seconds between each action;
- Make a script containing all the elements in the array. It'd be executed when the Start button is pressed.
I'd just like to know if I'm going on the right path. Sorry if I'm asking too much, it's because I've been stuck in this for a long time. Thanks again!
 

arirish

Member
Assuming you're using the mouse to drag the blocks, I'd use a mouse release event and a collision_rectangle (so, if mouse released and cursor is inside the square...), and then add the appropriate input to a ds queue. I'd hold each input in a separate script, and then you're just chaining scripts together.
 
R

RisingKane

Guest
I'm trying to use ds_queues, but it's getting kinda difficult. Here are my major issues at the moment:

- If a block is inside the square, its action is added to the queue. If I remove the same block from the square, its action should also be removed from the ds_queue, but it's still there. I know why, but I can't find a solution to delete it.
- I have one "original" block, which when it's clicked, a new instance of it is created. The newly cloned block can be dropped anywhere in the screen. If I put two equal blocks inside the square, then I should have the same action twice in the queue. For instance, if I have two blocks named UP inside the square, the ds_queue content should be UP, UP.
- Also, wouldn't ds_lists be a better option in this case? Because I think I may have to manipulate the middle of the data strucuture soon, not only its head or tail.

Thanks again!
 

arirish

Member
Yes, good point. I hadn't thought about the possibility of deleting. A list would definitely be preferable.
 

sylvain_l

Member
instead of a ds_queue I would prefer to go with a ds_priority
and you use as priority something like y_block*max(width_square+width_block,height_square+height_block)+x_block
(^^ and then use ds_priority_find_max/_min depending if you want right bottom block executed first and top left last with my formula or the opposite)
 
R

RisingKane

Guest
instead of a ds_queue I would prefer to go with a ds_priority
and you use as priority something like y_block*max(width_square+width_block,height_square+height_block)+x_block
(^^ and then use ds_priority_find_max/_min depending if you want right bottom block executed first and top left last with my formula or the opposite)
I see. I just didn't understand the the purpose of the formula used in the priority. Could you explain it?

Thanks!
 

sylvain_l

Member
rereading your OP I think, that my solution is overcomplicated (if you have just a single column with slot in the square it's over complicated. I was kinda assuming, that the block can be freely arranged in the square. Which mean one player could arrange his block in a row while an other could arrange them in a column (order of execution being run from left to right and top to bottom)

I didn't test the formula, and rereading it, it must be wrong. (was late :p - in fact the formula would work, but it does it by using a bigger multipcator than necessary)

idea is just to have a formula that allocate a different priority based on each pixel of the square, so any block in it will have a different priority automatically defined by its position in the square.

formula should be more like priority = block.y * (square.width + 1) + block.x for each block added in the square (ie. to the ds_priority).
(true formula corresponding to my idea shoud be the relative position, ie: block.y-square.y and block.x-square.x; but as square.y and square.x are constant (I suppose the square don't move and has a fixed size); while each block should have different x and y, I'm assuming that it's safe to remove those constant from the formula - you still have different priority.)
 

arirish

Member
Question: are the blocks read in the order they're dropped, or based on their position in the square? If I drop a 'move forward' block in at the bottom of the square, then a 'jump' block above it, which one is the first instruction given? I was wondering if it would be better to have a fixed number of slots to be filled, in a clear order, rather than a nebulous square.
 
R

RisingKane

Guest
Sorry I took too long to answer. I was studying this project, and I'll have to make some changes, especially in this part I asked you guys about.
Now, instead of using the square to check which blocks will be executed, I'll have a fixed block somewhere in the screen. Then, I'll need to attach the blocks I want to be executed to it, attach another one to the last one attached, and so on. Something like this:

att.png

At the moment I attach a block to the fixed one, its corresponding command will be added to a list. If I keep attaching them, one after the other, its commands are also added to the list. Then, when the START button is clicked, the game will run all the commands, first to last. So, I'll still use some data structure.

But I'm having some trouble to make this kind of attachment, because I'd like them to attach exactly in these spots:

att2.png

I tried to change their collision masks, so I could detect when the attachment could happen, but it's not working.

Sorry I had to change it, and thanks for your support.
 

arirish

Member
Seems to me that's a simple case of setting the new block's x to the previous, and the y to sprite_height-(the height of the protrusion).
 
R

RisingKane

Guest
Seems to me that's a simple case of setting the new block's x to the previous, and the y to sprite_height-(the height of the protrusion).
I tried to do it like you said, but it didn't work. I think it's because I need to refer the new block's y to the previous one. I did it like this:

newblock.x = previous.x;
newblock.y = previous.y + 32;

It works sometimes, but sometimes it doesn't.
 
R

RisingKane

Guest
Seems to me that's a simple case of setting the new block's x to the previous, and the y to sprite_height-(the height of the protrusion).
I tried to do it like you said, but it didn't work. I think it's because I need to refer the new block's y to the previous one. I did it like this:

newblock.x = previous.x;
newblock.y = previous.y + 32;

It works sometimes, but sometimes it doesn't. I don't know why.

Thanks man!

Sorry for the double post, just saw it now.
 
Last edited by a moderator:
Top