Can objects be linked in Gamemaker? - game-maker

Within the game I'm currently building there's an interactive element that is supposed to work the same way when interacting with different elements. To make it easier to replicate numerous times, I duplicated the objects containing this code and changed the global.variable which is supposed to define each individual 'group' (two objects make up the element itself) so they work separately - however when I interact with one group in the game, it still triggers the other one to react at the same time.
Can objects be linked in gamemaker? And if so, how do I unlink these objects so that they work separately?
Here's the code for both in case it's more an issue with something in the code that I've overlooked. Basically how the group works is that when the player interacts with the object, the object changes it's instance and the new object picks up the functionality of the old one. First three image in each group refer to the first object, last three refer to the second.
Group 1 Object 1;
Create Event
global.ssscollission = 0;
Key Press E
if (global.ssscollission = 0)
{
global.ssscollission = 1;
}
else
{
global.ssscollission = 0;
}
instance_change(obj_snakeplush,false)
Draw GUI
If Collision, Stop Movement, Font Text and Draw Value DnD features here
.
Group 1 Object 2;
Draw GUI
If Collision, Stop Movement, Font Text and Draw Value DnD features here, as well as;
if (global.ssscollission)
{
draw_set_color(c_black);
draw_set_alpha(0.75);
draw_rectangle(0,0,room_width,room_height,0);
draw_set_alpha(1);
draw_set_color(c_white);
draw_set_halign(fa_center);
draw_sprite_ext(spr_sss,0,920,50,0.65,0.65,0,c_white,1);
draw_set_font(fnt_credit);
draw_text(1275,1400,"Press the [E] button to return.")
}
Key Press E
if (global.ssscollission = 0)
{
global.ssscollission = 1;
}
else
{
global.ssscollission = 0;
}
Animation End
image_index = image_number - 1;
image_speed = 0;
global.danielfound = global.danielfound + 1
.
Group 2 Object 1;
Create Event
global.danieltree = 0;
Key Press E
if (global.danieltree = 0)
{
global.danieltree = 1;
}
else
{
global.danieltree = 0;
}
instance_change(obj_danieltree,false)
Draw GUI
If Collision, Stop Movement, Font Text and Draw Value DnD features here
.
Group 2 Object 2;
Draw GUI
If Collision, Stop Movement, Font Text and Draw Value DnD features here, as well as;
if (global.danieltree)
{
draw_set_color(c_black);
draw_set_alpha(0.75);
draw_rectangle(0,0,room_width,room_height,0);
draw_set_alpha(1);
draw_set_color(c_white);
draw_set_halign(fa_center);
draw_sprite_ext(spr_sss,0,920,50,0.65,0.65,0,c_white,1);
draw_set_font(fnt_credit);
draw_text(1275,1400,"Press the [E] button to return.")
}
Key Press E
if (global.danieltree= 0)
{
global.danieltree= 1;
}
else
{
global.danieltree= 0;
}
Animation End
image_index = image_number - 1;
image_speed = 0;
global.danielfound = global.danielfound + 1
Cheers

Related

Player character won't go in front of buildings

Ok, so I managed to get all the buildings to stay in place, but now for some reason, the player character won't go in front of the buildings.
I tried switching the places in the code where the if the command for checking if the character's going behind the building and the if-else for checking if it's going in front of the code, but nothing changed.
here's the code:
var _dg = depth_grid;
var _inst_num = instance_number(obj_depth_buildings);
//below is for resizing the grid
ds_grid_resize(depth_grid,2, _inst_num);
//below adds instance info to grid
var _yy = 0;
with (obj_depth_buildings)
{
_dg[# 0,_yy] = id;
_dg[# 1,_yy] = y;
_yy++;
}
//below sorts the grid so that the ones with the biggest y variables end up at the top
ds_grid_sort(_dg,1,false);
//below goes through the grid and identifies everything
var _inst;
_yy = 0;
repeat (_inst_num)
{
//below pulls out an id
_inst = _dg[# 0, _yy];
//below gets the instance execute depth
with(_inst)
{
_inst.depth= layer_get_depth("collision") + _yy;
with (obj_nonbuilding_depths)
{
if object_index.y > _inst.y
{
object_index.depth = (_inst.depth + 1);
}
else if object_index.y <= _inst.y
{
object_index.depth = (_inst.depth - 1);
}
}
}
_yy++;
}
you should change the object depth by change the leyar depth in GMS2

Is there a way to tell CMFCColorButton, what colors not to present

Is there a way to tell CMFCColorButton what set of colors to display?
For example, when press, show me just orange white and black.
Update
I've tried by defining:
PALETTEENTRY palleteEntries[2] =
{
/*index 0 black*/
{0,0,0,PC_EXPLICIT},
/*index 1 white*/
{0xFF,0xFF,0xFF,PC_EXPLICIT},
};
CPalette colorPalette;
colorPalette.SetPaletteEntries(0,2,palleteEntries);
Then I get an assertion.
Just create a CPalette object.
Use void CMFCColorButton::SetPalette(CPalette* pPalette) to force usage of this palette.
CPalette colorPalette;
colorPalette.SetPaletteEntries(0,2,palleteEntries);
At this point colorPalette is just a C++ object, not HPALETTE resource object. SetPaletteEntries makes WinAPI call for a non-existing HPALETTE and fails. This is one of those times when MFC is not being helpful by hiding everything. But the debugger helps to point out the problem.
Start with LOGPALETTE instead. LOGPALETTE::palVersion should be 0x0300 otherwise CreatePalette fails. Use this instead:
CPalette pal;
LOGPALETTE* lg = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + 5 * sizeof(PALETTEENTRY));
lg->palNumEntries = 5;
lg->palVersion = 0x0300;
lg->palPalEntry[0] = { 255,0,0,0 };
lg->palPalEntry[1] = { 0,255,0,0 };
lg->palPalEntry[2] = { 0,0,255,0 };
lg->palPalEntry[3] = { 0,0,0,0 };
lg->palPalEntry[4] = { 255,255,255,0 };
if(pal.CreatePalette(lg))
{
m_myColorBtn.SetPalette(&pal);
}
free(lg);

Collision detection makes this game freeze when checking for collisions with multiple platforms

I have one platform which is colliding with the main character, and that works now. But if I want to add two or more platforms, the game sticks. I work with GameMaker Studio now.
// React to inputs
move = key_left + key_right;
hsp = move * movespeed;
if (vsp < 10)
vsp += grav;
if (place_meeting(x, y+1, obj_platform) || place_meeting(x, y+1, obj_platform1)) {
vsp = key_jump * -jumpspeed;
}
// Horizontal collision
if (place_meeting(x+hsp, y, obj_platform) || place_meeting(x+hsp, y, obj_platform1)) {
while (!place_meeting(x+sign(hsp), y, obj_platform) || place_meeting(x+sign(hsp), y, obj_platform1)) {
x += sign(hsp);
}
hsp = 0;
}
x += hsp;
// Vertical collision
if (place_meeting(x, y+vsp, obj_platform) || place_meeting(x, y+vsp, obj_platform1)) {
while (!place_meeting(x, y+sign(vsp), obj_platform) || place_meeting(x,y + sign(vsp), obj_platform1)) {
y += sign(vsp);
}
vsp = 0;
}
y += vsp;
// Diagonal collision
if(place_meeting(x+hsp, y+vsp, obj_platform) || place_meeting(x+hsp, y+vsp, obj_platform1)) {
while(!place_meeting(x+sign(hsp), y + sign(vsp), obj_platform) || place_meeting(x+sign(hsp), y + sign(vsp), obj_platform1)) {
x += sign(hsp);
y += sign(vsp);
}
hsp = 0;
vsp = 0;
}
What mistake am I making? Platform works like it should, but if you jump on platform1, the whole game sticks.
I have been working with Unity and GameMaker for the past two months, so I'm not really good at it.
It probably sticks in the while loop. The sign function returns 1 for positive numbers, -1 for negative numbers, and 0 for 0.
If GameMaker has a logging feature, or some kind of console output, write something in the while loop. Or, if it doesn't, try something like this:
counter = 0;
while(!place_meeting(x+sign(hsp), y + sign(vsp), obj_platform) || place_meeting(x+sign(hsp), y + sign(vsp), obj_platform1)) {
counter += 1;
x += sign(hsp);
y += sign(vsp);
if (counter>100) {
// Do something visible, for example teleport player.
}
}
I know it's not a very efficient method, but I remember GameMaker was always a terrible IDE in terms of debugging.
Regarding:
while (!place_meeting(x+sign(hsp), y, obj_platform) || place_meeting(x+sign(hsp), y, obj_platform1)) {
x += sign(hsp);
}
The logical NOT operator ! applies only to the first place_meeting here, so the while loop will continue as long as either
you are not colliding with obj_platform or
you are colliding with obj_platform1
Instead, you probably want the while loop to continue as long as you are not colliding with either of them, so you have to put brackets around everything and then negate the whole thing, like this:
while (!(place_meeting(x + sign(hsp), y, obj_platform) || place_meeting(x + sign(hsp), y, obj_platform1)))
Note that first the logical OR operator || inside the brackets gets applied, and then the whole thing is negated with ! outside the brackets.
You would have to do the same thing in the while loops for vertical and diagonal collision.
However, you should actually do this differently.
You seem to have separate objects for the first platform (obj_platform) and the second platform (obj_platform1). If you continue to use this method, you would have to add a new object for each platform you want to add to your game even though they share the same functionality, and you would have to add a new place_meeting check to your collision code for every single one of them. This is obviously very tedious and would make your collision code incredibly long.
Instead, you want to make a single object in GameMaker, for example called oPlatform, and then create multiple instances of this object. See here for more information on instances in GameMaker. The way you probably want to create the instances in this case is by placing them in the room with the room editor.
To do this, double click on your room to open the room editor, make sure the "Instances" layer is selected and not the background layer, select the object you want to place instances of in the asset browser and drag-and-drop it into the room to place an instance.
You can also "paint" with instances by holding down Alt and then pressing the left mouse button while the object is selected (make sure you have laptop mode turned off). You can also create instances in code with functions such as instance_create_layer (documentation).
When your platforms are all instances of the same object, you just have to check for collision with the object and it will check whether you are colliding with any instance of it, like this:
// Horizontal collision
if (place_meeting(x + hsp, y, oPlatform)) {
while (!place_meeting(x + sign(hsp), y, oPlatform)) {
x += sign(hsp);
}
hsp = 0;
}
x += hsp;
Remember that I called the platform object oPlatform in this example, and yours could be called differently. With this setup, you won't need to add anything to your collision code when you add more platform instances.
If you ever need to know which instance(s) of an object you collided with, use instance_place (documentation) or instance_place_list (documentation) instead of place_meeting (documentation). If you have an instance ID saved in a variable, you can also use place_meeting with that instance ID instead of the name of the object, and it will check for collision with only that instance.

Using Count To Split A Checklist Into 2 Columns in X++ Fetch Method

Here is what I have so far, this is returning two columns, but each counter is stopping and then duplicating the same value over and over...
if(lLogisticsControlTable.APMJobTypeId)
select count (RecID) from jobTypeCheck where jobTypeCheck.APMJobTypeId == lLogisticsControlTable.APMJobTypeId;
{
counter = jobTypeCheck.RecId;
}
while select jobTypeCheck where jobTypeCheck.APMJobTypeId == lLogisticsControlTable.APMJobTypeId
{
counter1 = counter / 2;
halfCount1 = counter - counter1;
if(halfcount <= counter1)
{
halfCount++;
jobListCheck1 = jobTypeCheck.Name;
}
if (halfCount1 > halfCount)
{
halfCount1++;
jobListCheck2 = jobTypeCheck.Name;
}
element.execute(2);
}
}
As Michael Brown indicated, it's difficult to understand the problem with half of the code ;)
However, I would suggest that you call the element.execute(2) method on every second pass through the loop? That way jobListCheck1 would be on the left, and jobListCheck2 would be on the right hand side. Finally you would then need to check immediately outside of your loop if you had an odd number of jobTypeCheck elements, and call the element.execute(2) method one last time remembering to set the jobListCheck2 variable as empty beforehand.
Regards

When to render Legend in Flex

My Flex chart has code that creates a legend from each data series. Currently, I have the drawLegend function execute when a button is clicked.
I am trying to get the legend to draw automatically but I am having trouble determining when to call the drawLegend function. Users click on an 'Update' button which retrieves data. I want the legend to get created after this, without the users having to click on another button.
I have put my drawLegend function in several places (ResultHandler, afterEffectEnd(for chart animation, etc.) and nothing works.
Sometime after the series has been added to the chart and after the series animation ends, the legend can be added.
How can I trap this point in time and call my function?
Any ideas?
Below is the code I used to create the legend. Note that even though the code processes each series, I noticed that the Fill color is null if it is called too early.
private function drawLegend(event:Event):void {
clearLegend();
// Use a counter for the series.
var z:int = 0;
var numRows:int;
if (chart.series.length % rowSize == 0) {
// The number of series is exactly divisible by the rowSize.
numRows = Math.floor(chart.series.length / rowSize);
} else {
// One extra row is needed if there is a remainder.
numRows = Math.floor(chart.series.length / rowSize) + 1;
}
for (var j:int = 0; j < numRows; j++) {
var gr:GridRow = new GridRow();
myGrid.addChild(gr);
for (var k:int = 0; k < rowSize; k++) {
// As long as the series counter is less than the number of series...
//skip columnset group
if (chart.series[z] is LineSeries || chart.series[z] is ColumnSeries){
if (z < chart.series.length) {
var gi:GridItem = new GridItem();
gr.addChild(gi);
var li:LegendItem = new LegendItem();
// Apply the current series' displayName to the LegendItem's label.
li.label = chart.series[z].displayName;
// Get the current series' fill.
var sc:SolidColor = new SolidColor();
sc.color = chart.series[z].items[0].fill.color;
// Apply the current series' fill to the corresponding LegendItem.
li.setStyle("fill", sc.color);//was just sc
// Apply other styles to make the LegendItems look uniform.
li.setStyle("textIndent", 5);
li.setStyle("labelPlacement", "left");
li.setStyle("fontSize", 9);
gi.setStyle("backgroundAlpha", "1");
gi.setStyle("backgroundColor", sc.color);
//gi.width = 80;
// Add the LegendItem to the GridItem.
gi.addChild(li);
}
}
// Increment any time a LegendItem is added.
z++;
}
}
}
Well, I couldn't quite figure out what event to trap so I used the following in the chart's parent container:
chart.addEventListener(ChartItemEvent.ITEM_ROLL_OVER,drawLegend);
Seems to work ok.

Resources