Q
Qing Donnie Yoshi
Guest
OK so I did implement that but now he(also the rest) are just stuck going in one direction. should there be and if?
No, but put the switch in the End Step event.maybe I can put the switch part into create
switch direction {
case 0: sprite_index = sprite_right; break;
case 90: sprite_index = sprite_up; break;
case 180: sprite_index = sprite_left; break;
case 270: sprite_index = sprite_down; break;
}
var dx,dy;
if targetX<x dx=180
else if targetX>x dx = 0;
else dx = 360;
if targetY<y dy=90
else if targetY>y dy=270
else dy = 360;
///Step Event
if (floor(x) - grid/2) mod grid == 0 && (floor(y)-grid/2) mod grid == 0 {
for(var paths, i=0; i<4; i++;)
paths[i] = -1;
var n = 0;
for(i=0; i<360; i+= 90;) {
if i != (direction + 180) mod 360
if !position_meeting(x+lengthdir_x(grid,i), y+lengthdir_y(grid,i), oWall)
paths[n++] = i;
}
show_debug_message(paths)
if paths[0] == -1 { //this should NEVER happen, but just in case...
direction = 270;
exit;
}
if paths[1] == -1 { //this means there is only one path available
direction = paths[0];
exit;
}
var h = abs(targetX - x);
var v = abs(targetY - y);
var dx = point_direction(x,y,targetX,y);
var dy = point_direction(x,y,x,targetY);
if h > v {
//Try to move horizontally
for(i=0; i<4; i++;)
if paths[i] == dx {
direction = dx;
exit;
}
for(i=0; i<4; i++;)
if paths[i] == dy {
direction = dy;
exit;;
}
}
if v > h {
//Try to move vertically
for(i=0; i<4; i++;)
if paths[i] == dy {
direction = dy;
exit;
}
for(i=0; i<4; i++;)
if paths[i] == dx {
direction = dx;
exit;
}
}
//If both distances are the same or both desired paths are unavailable, pick a random one
n = -1
for(i=0; i<4; i++)
if paths[i] == dx
if n == -1
n = dx;
else {
n = choose(dx,dy);
break;
}
else
if paths[i] == dy
if n == -1
n = dy;
else {
n = choose(dx,dy);
break;
}
if n != -1
direction = n;
else {
i = irandom(3);
while paths[i] == -1
i = ++i mod 4;
direction = paths[i];
}
}
OK with the sprite change done how should I go about giving each ghost their own specific target/personality command?Starting small and scaling up in post-render is the easiest in my opinion. After posting my last code, I switched the project over to tile-based and started modifying speeds. One would think a larger grid size gives more room to work with, but it also gives more room for error. Speeds less than 1 are the simplest, but as soon as you get over 1pps, errors start popping up more frequently. Working with tile-based collisions, there are still movement speed considerations, but a little more room for dealing with possible errors.
for Clyde's code, it says that the variable paths is only referenced once while in the movement code it doesn't and it's only referenced once. Do I just say Paths = something in the create code?Okay, here's the breakdown of how each of the ghosts work using speed variables:
Blinky
targetX = Pacman.x
targetY = Pacman.y
Pinky
targetX = Pacman.x + grid * 3 * sign(Pacman.hspeed)
targetY = Pacman.y + grid * 3 * sign(Pacman.vspeed)
Inky
targetX = ( Pacman.x * 2 - Blinky.x ) mod maze_width maze_width is how many pixels wide the maze itself is
targetY = ( Pacman.y * 2 - Blinky.y) mod maze_height maze_height is how many pixels high the maze itself is
Clyde
if abs(Pacman.x - x) < grid*4 && abs(Pacman.y - y) < grid*4 {
var r = irandom(3),n;}
repeat 4 {
n = paths[r];}
if n > -1 && n != (direction + 180) mod 360 {
direction = n;}
break;
r = ++r mod 4;
else {
targetX = Pacman.x}
targetY = Pacman.y
Fruit
targetX = horizontal middle of ghost house
targetY = vertical middle of ghost house
(since the fruit can't cross the ghosts' door, it just circles around the ghost house)
A note about Inky's code. In the original code, maze_width and maze_height were both 256 pixels, which was larger than both the maze and the room. Regardless... Whether you should use maze_width vs. room_width or maze_height vs. room_height depends on how your room is set up. If the maze takes up the full width of the room, use room_width. If the maze takes up the full height of the room, use room_height. If the score is to the right of the maze, you should use maze_width. If the score is below the maze, use maze_height. If the score is to the left of the maze, the formula changes to (Pacman.x * 2 - Blinky.x - maze_left) mod maze_width + maze_left, where maze_left is how many pixels away from the left edge of the room the maze is. If the score is above the maze, the formula changes to (Pacman.y * 2 - Blinky.y - maze_top) mod maze_height + maze_top, where maze_top is how many pixels away from the top of the room the maze is. In any case, you could opt to just use room_width and room_height, which would cause a slight difference in Inky's behavior. For example, if the score is on the left or right side of the maze and you used room_width instead of maze_width, there is a possibility that targetX would be a point outside the maze. This is not as bad as it my seem, as the original code is just as quirky. See, Inky's behavior is to get on the opposite side of Pac-Man as Blinky using a pincer attack. However, the way the code is written, it's possible for Inky to try to move behind Blinky sometimes or get between Blinky and Pac-Man other times. This is because (Pacman.x * 2 - Blinky.x) might fall outside the maze, which makes "mod maze_width" put targetX on the opposite side of the maze. It was a glitch that wasn't game-breaking because of how the rest of the AI code works. Likewise, if you just used room_width and room_height instead of maze_width and maze_height, then targetX or targetY could potentially get set outside the maze, but as the ghost's AI prevents it from leaving the maze, there's no problem. A professional Pac-Man player might spot the difference in behavior, but the average gamer won't.
OKDamn, I forgot I made paths a temporary variable in this thread. Ok then, Clyde doesn't need a Begin Step event. His Step event is going to need to be changed. I will fix it up after Christmas.
No like, you know Pac-Man has 2 different eating sound effects right?You mean prevent too many sounds playing at once?
if (floor(x) - grid/2) mod grid == 0 && (floor(y)-grid/2) mod grid == 0 {
for(var i=0; i<4; i++;)
paths[i] = -1;
var n = 0;
for(i=0; i<360; i+= 90;) {
if i != (direction + 180) mod 360
if !position_meeting(x+lengthdir_x(grid,i), y+lengthdir_y(grid,i), oWall)
paths[n++] = i;
}
//Add this next block of code in
if object_index == Clyde && abs(Pacman.x - x) < grid*4 && abs(Pacman.y - y) < grid*4 {
var r = irandom(3),n;
repeat 4 {
n = paths[r];
if n > -1 && n != (direction + 180) mod 360 {
direction = n;
exit;
}
r = ++r mod 4; }
}
//The rest of Blinky's code is the same
What do you mean by remove var paths? doesn't the new code you gave me still have that in there? Also do I just put this new block of code right under the one on top?So first off, remove "var paths" from Blinky's Step event; it'd have been fine as a temporary variable if not for Clyde's AI. Just copy Blinky's Begin Step into Clyde, but change which corner he should run to if Pac-Man ate a power pill. Then change the beginning of Blinky's Step event to:
Code:if (floor(x) - grid/2) mod grid == 0 && (floor(y)-grid/2) mod grid == 0 { for(var paths, i=0; i<4; i++;) paths[i] = -1; var n = 0; for(i=0; i<360; i+= 90;) { if i != (direction + 180) mod 360 if !position_meeting(x+lengthdir_x(grid,i), y+lengthdir_y(grid,i), oWall) paths[n++] = i; } //Add this next block of code in if object_index == Clyde && abs(Pacman.x - x) < grid*4 && abs(Pacman.y - y) < grid*4 { var r = irandom(3),n; repeat 4 { n = paths[r]; if n > -1 && n != (direction + 180) mod 360 { direction = n; exit; } r = ++r mod 4; } } //The rest of Blinky's code is the same
Are your ghosts still able to move back and forth sometimes? I've got a weird bug in my porgram I'm trying to figure out which is causing them to move back and forth.
Edit: I think I resolved my bug. I was using speeds less than 1, so I needed to make sure the ghost moved at least 1 pixel before checking for a new path.
Oh wow oops my bad. I edited the code now.What do you mean by remove var paths? doesn't the new code you gave me still have that in there? Also do I just put this new block of code right under the one on top?
So Iput in the new code for Blinky's Step and all the ghost are now able to go back and forth instead of only finding a new path. I know you mentioned about speed and the only highest speed they can go to is 2 since I got everything on a 32 pixel scale and that's the current speed i got them going now. How can I fix that problem?Oh wow oops my bad. I edited the code now.
So in that code where it says "//Add this...", Copy everything from that comment down. Then go into Blinky step event and paste that code into his step event so that the beginning of the step event looks like what I had posted.
One thing I just realized about the code is it won't make Clyde run oh way every time. I have to go back and double-check the original code verify that was intended behavior or if I mist a step in the code, but I'm pretty sure it's intended.
STEPPost your full Blinky code now. A grid of 32 and speed of 2 should be fine, and my project was working fine.
You can reduce grid to 16 or 8 and it SHOULD still be ok, in theory.
I also tried to make a small opening for the ghost to come out of the ghost base but for some reason they can't and their collision mask is the same as always. I'm thinking it's the grid size.STEP
if (floor(x) - grid/2) mod grid == 0 && (floor(y)-grid/2) mod grid == 0 {
for(var i=0; i<4; i++
paths = -1;
var n = 0;
for(i=0; i<360; i+= 90 {
if i != (direction + 180) mod 360
if !position_meeting(x+lengthdir_x(grid,i), y+lengthdir_y(grid,i), obj_Pac_Collision)
paths[n++] = i;
}
//Add this next block of code in
if object_index == obj_Clyde && abs(obj_Player_1.x - x) < grid*4 && abs(obj_Player_1.y - y) < grid*4 {
var r = irandom(3),n;
repeat 4 {
n = paths[r];
if n > -1 && n != (direction + 180) mod 360 {
direction = n;
exit;
}
r = ++r mod 4; }
}
if paths[0] == -1 { //this should NEVER happen, but just in case...
direction = 270;
exit;
}
if paths[1] == -1 { //this means there is only one path available
direction = paths[0];
exit;
}
var h = abs(targetX - x);
var v = abs(targetY - y);
var dx = point_direction(x,y,targetX,y);
var dy = point_direction(x,y,x,targetY);
if h > v {
//Try to move horizontally
for(i=0; i<4; i++
if paths == dx {
direction = dx;
exit;
}
for(i=0; i<4; i++
if paths == dy {
direction = dy;
exit;;
}
}
else
if v > h {
//Try to move vertically
for(i=0; i<4; i++
if paths == dy {
direction = dy;
exit;
}
for(i=0; i<4; i++
if paths == dx {
direction = dx;
exit;
}
}
//If both distances are the same or both desired paths are unavailable, pick a random one
i = irandom(3);
while paths == -1
i = ++i mod 4;
direction = paths;
}
{
move_wrap(1,1,2);
}
CREATE
goHome = false;
global.PowerPellet = false;
grid = 16;
speed = 2;
sprite_up = Blinky_up;
sprite_down = Blinky_down;
sprite_right = Blinky_right;
sprite_left = Blinky_left;
BEGIN STEP
if goHome {
targetX = 511//whatever the x-coordinate is for the ghost's home;
targetY = 528//whatever the y-coordinate is for the ghost's home;
speed = 2;
}
else
if global.PowerPellet {
targetX = 0;
targetY = 0;
speed = 2;
}
else {
targetX = obj_Player_1.x;
targetY = obj_Player_1.y;
speed = 2;
}
END STEP
switch direction {
case 0: sprite_index = sprite_right; break;
case 90: sprite_index = sprite_up; break;
case 180: sprite_index = sprite_left; break;
case 270: sprite_index = sprite_down; break;
}
No it was just Pinky, Inky and Clyde but OK. Did you also I ended up going back to the code where they all was still working properly. I might be doing something wrong with the new code you gave me or the "/2" might be throwing me off.Make sure all the ghosts' coordinates are even numbers (0,2,4,6,8,10,12,14,16, etc.) for both starting x and y.
Are your ghosts all inside the ghost house? First off, Blinky starts in the maze, not in the house. But anyway, if you have them all inside the house, put them outside the house. We can deal with the house later as long as the ghosts move fine the rest of the time.
Also, the middle of the ghost house should be 512, not 511.
I'm testing out your code now. I'm curious why it stopped working, too.No it was just Pinky, Inky and Clyde but OK. Did you also I ended up going back to the code where they all was still working properly. I might be doing something wrong with the new code you gave me or the "/2" might be throwing me off.
now keep in mind that this is the downsized version of the program you're reviewing.I'm testing out your code now. I'm curious why it stopped working, too.
I have a hunch what's going on. Open your room. Then click on each of the ghosts. Tell me the x and y coordinates for each ghost.now keep in mind that this is the downsized version of the program you're reviewing.
show_debug_message(object_get_name(object_index)+": "+string(paths));
onward and paste them here.**********************************.
Entering main loop.
**********************************.
One more thing. Does your room look like this (ignore the ghosts and Pac-Man):where they're currently standing at-
Blinky: 224, 216
Pinky: 256, 216
Inky: 184, 264
Clyde: 328, 264
Summer: 288, 216
Sue: 256, 120
Funky: 184, 168
Spunky: 328, 168
Relatively speaking yes, if I change the grid size for the edible instances it would look exactly like that.One more thing. Does your room look like this (ignore the ghosts and Pac-Man):
where each wall and pellet take up exactly one cell, where each cell is 16pixels x 16pixels?
What do you mean he's missing a 90 on the next line, does it has something to do with the code?That readout is interesting...
obj_Inky: { { 90,270,-1,-1 }, }
obj_Inky: { { 90,-1,-1,-1 }, }
obj_Inky: { { 90,-1,-1,-1 }, }
obj_Inky: { { 0,-1,-1,-1 }, }
obj_Inky: { { 0,-1,-1,-1 }, }
obj_Inky: { { 0,-1,-1,-1 }, }
obj_Inky: { { 0,90,-1,-1 }, }
obj_Inky: { { 90,-1,-1,-1 }, }
obj_Inky: { { 90,-1,-1,-1 }, }
obj_Inky: { { 180,-1,-1,-1 }, }
obj_Inky: { { 180,-1,-1,-1 }, }
obj_Inky: { { 180,-1,-1,-1 }, }
obj_Inky: { { 90,-1,-1,-1 }, }
obj_Inky: { { 90,-1,-1,-1 }, }
obj_Inky: { { 90,-1,-1,-1 }, }
obj_Inky: { { 0,180,-1,-1 }, }
obj_Inky: { { 180,-1,-1,-1 }, }
obj_Inky: { { 180,-1,-1,-1 }, }
obj_Inky: { { 90,180,270,-1 }, }
obj_Inky: { { 180,-1,-1,-1 }, }
obj_Inky: { { 180,-1,-1,-1 }, }
obj_Inky: { { 180,-1,-1,-1 }, }
We can see here that Inky is indeed following the maze. He goes left 1 cell to a t-junction, goes up 3 cells to a right turn, goes right 3 cells to another t-junction, goes up 3 cells to a left turn, goes left three cells to an upward turn, goes up three cells to another t-junction, goes left three cells to four-way, keeps going left three more cells.
All of the other ghosts appear to be fine, except for Blinky, who appears to be moving right until he gets to a t-junction going up, which he ignores. Immediately after that is a junction moving down. Because 90 is missing on the next line, he clearly took the branch and is moving down, but then the next junction is a four-way which he gets stuck in...Or he moved outside of the grid.
obj_Blinky: { { 0,90,-1,-1 }, }
obj_Blinky: { { 0,270,-1,-1 }, }
obj_Blinky: { { 0,180,270,-1 }, }
obj_Blinky: { { 0,180,270,-1 }, }
obj_Blinky: { { 0,180,270,-1 }, }
obj_Blinky: { { 0,180,270,-1 }, }
By the way, try putting the move_wrap() at the top of the event. Because I use exit in a couple spots, that prevents move_wrap() from being called sometimes.