Issue with game over room - game-maker

I am currently making my first Game Maker Studio 2 game in GML (the space rocks one from the tutorial series in the yoyo YouTube channel) and I don't know why but when I tried to run the game it didn't open and the IDE says that the issue is in the following code:
switch(room){
case rm_game:
draw_text(20, 20, "SCORE: " + string(score));
draw_text(20, 40, "LIVES: " + string(lives));
break;
case rm_start:
draw_set_halign(fa_center);
var c = c_yellow;
draw_text_transformed_color(
room_width/2, 100, "SPACE ROCKS",
3, 3, 0, c, c, c, c, 1
);
draw_text(
room_width/2, 200,
#"Score 1,000 points to win!
UP: move
LEFT/RIGHT: change direction
SPACE: shoot
>> PRESS ENTER TO START <<
"
);
draw_set_halign(fa_left);
break;
case rm_win:
draw_set_halign(fa_center);
var c = c_lime;
draw_text_transformed_color(
room_width/2, 200, "YOU WON!",
3, 3, 0, c, c, c, c, 1
);
draw_text(
room_width/2, 300,
"PRESS ENTER TO RESTART"
);
break;
case rm_gameover:
draw_set_halign(fa_center);
var c = c_red;
draw_text_transformed_color(
room_width/2, 150, "GAME OVER",
3, 3, 0, c, c, c, c, 1
);
draw_text(room_width/2, 250, "FINAL SCORE: " + string(score);
draw_text(room_width/2, 300, "PRESS ENTER TO RESTART");
break;
}
I checked and it says that the problem is in the lines 48, 49 and 51, but I definitely can't find what's wrong in this code.

draw_text(room_width/2, 250, "FINAL SCORE: " + string(score); is missing another closing ) at the end.

Related

Detect if Lines Intersect in Google Charts or Plot.ly

I have seen scripts that claim to enter coordinates and it'll tell you if they intersect, but I have an array of X,Y values for a couple of "lines" but how do I cycle through the points to find out if they intersect?
I've included a photo of my graph and as you see, eventually my plots cross over, I just want to know if my values ever cross over (intersect).
How do I run through this to find out if any intersection ever occurs?
var Test = {
x: [8043, 10695, 13292, 17163, 20716, 25270],
y: [1000, 274, 100, 27.4, 10, 2.74],
fill: 'tozeroy',
type: 'scatter',
name: 'Test'
};
var Test2 = {
x: [8043, 10063, 12491, 16081, 19408, 23763],
y: [1000, 274, 100, 27.4, 10, 2.74],
fill: 'tozeroy',
type: 'scatter',
name: 'Test2'
};
var Test3 = {
x: [4700, 5943, 7143, 8841, 10366, 13452],
y: [1000, 274, 100, 27.4, 10, 2.74],
fill: 'tozeroy',
type: 'scatter',
name: 'Test3'
};
var data = [Test, Test2, Test3];
var layout = {
width: 700,
height: 700,
xaxis: {
type: 'log',
range: [3,5]
},
yaxis: {
type: 'log',
range: [-2,3]
}
};
Plotly.newPlot('myDiv', data,layout);
Path intercepts
This answer is a follow on from my answer to your most resent question.
The code snippet below will find the intercepts of the paths in the tables as structured in this questions example data using a modified intercept function from the answer link in may comment from aforementioned answer.
Note I am assuming that each table eg Test in your example data represents a curve (Path as a set of line segments) and that intercepts are not expected within a table but rather between tables.
Basic solution
It does this by checking each line segment in one table against each line segment in the other and storing all intercepts in an array.
Note that if a intercept is found at the start or end point of a line it may appear in the array of intercepts twice as the intercept test includes these points.
Note lines that are parallel, even if they have matching start and or end points will not count as intercepts.
The example is run against the example data and has a verbose console output to guide, if needed, you working through what ever data sets you are wrangling. The console logs can be removed without ill effect.
var Test = {
x: [8043, 10695, 13292, 17163, 20716, 25270],
y: [1000, 274, 100, 27.4, 10, 2.74],
fill: 'tozeroy',
type: 'scatter',
name: 'Test'
};
var Test2 = {
x: [8043, 10063, 12491, 16081, 19408, 23763],
y: [1000, 274, 100, 27.4, 10, 2.74],
fill: 'tozeroy',
type: 'scatter',
name: 'Test2'
};
var Test3 = {
x: [4700, 5943, 7143, 8841, 10366, 13452],
y: [1000, 274, 100, 27.4, 10, 2.74],
fill: 'tozeroy',
type: 'scatter',
name: 'Test3'
};
// Copy from here to end comment and place into you page (code base)
// lines outputting to the console eg console.log are just there to help you out
// and can be removed
const lineIntercepts = (() => {
const Point = (x, y) => ({x, y});
const Line = (p1, p2) => ({p1, p2});
const Vector = line => Point(line.p2.x - line.p1.x, line.p2.y - line.p1.y);
function interceptSegs(line1, line2) {
const a = Vector(line1), b = Vector(line2);
const c = a.x * b.y - a.y * b.x;
if (c) {
const e = Point(line1.p1.x - line2.p1.x, line1.p1.y - line2.p1.y);
const u = (a.x * e.y - a.y * e.x) / c;
if (u >= 0 && u <= 1) {
const u = (b.x * e.y - b.y * e.x) / c;
if (u >= 0 && u <= 1) {
return Point(line1.p1.x + a.x * u, line1.p1.y + a.y * u);
}
}
}
}
const PointFromTable = (t, idx) => Point(t.x[idx], t.y[idx]);
const LineFromTable = (t, idx) => Line(PointFromTable(t, idx++), PointFromTable(t, idx));
return function (table1, table2) {
const results = [];
var i = 0, j;
while (i < table1.x.length - 1) {
const line1 = LineFromTable(table1, i);
j = 0;
while (j < table2.x.length - 1) {
const line2 = LineFromTable(table2, j);
const point = interceptSegs(line1, line2);
if (point) {
results.push({
description: `'${table1.name}' line seg index ${i}-${i+1} intercepts '${table2.name}' line seg index ${j} - ${j+1}`,
// The description (line above) can be replaced
// with relevant data as follows
/* remove this line to include additional info per intercept
tableName1: table1.name,
tableName2: table2.name,
table_1_PointStartIdx: i,
table_1_PointEndIdx: i + 1,
table_2_PointStartIdx: j,
table_2_PointEndIdx: j + 1,
and remove this line */
x: point.x,
y: point.y,
});
}
j ++;
}
i++;
}
if (results.length) {
console.log("Found " + results.length + " intercepts for '" + table1.name + "' and '" + table2.name + "'");
console.log(results);
return results;
}
console.log("No intercepts found for '" + table1.name + "' and '" + table2.name + "'");
}
})();
// end of code
// Test and example code only from here down.
var res1 = lineIntercepts(Test, Test2);
var res2 = lineIntercepts(Test, Test3);
var res3 = lineIntercepts(Test2, Test3);
Using the above function
This bit of code illustrates how you extract intercepts from the function results
// find all the intercepts for the paths in tabels Test and Test2
const results = lineIntercepts(Test, Test2); // pass two tables
// If results not undefined then intercepts have been found
if (results) { // results is an array of found intercepts
// to get the point/s as there could be several
for (const intercept of results) { // loop over every intercept
// a single intercept coordinate
const x = intercept.x; // get x
const y = intercept.y; // get y
}
}
Better solutions
The paths look very much like they are a plot of some function thus there are even simpler solutions.
Rather than list out lines of code, I will direct you towards graphing calculators in case you are unaware of such useful time savers. They would have solved your problem in the time it takes to enter the data (by copy&paste thats not very long)
Online graphing calculators example apps Geogebra and Desmos and many more.

SwiftUI List styles

I'm writing an Apple Watch app and I want to create a list just like this one in the Settings menu where the rows in the middle of the list are rectangles whereas the top and bottom are rounded rectangles. Is this a type of List style?
It is possible to do, though it requires using GeometryReader to handle drawing the rounded corners.
There is a great post by swiftui-lab.com that explains how to make the certain corners of a view rounded. Here is the code.
struct RoundedCorners: View {
var color: Color = .blue
var tl: CGFloat = 0.0
var tr: CGFloat = 0.0
var bl: CGFloat = 0.0
var br: CGFloat = 0.0
var body: some View {
GeometryReader { geometry in
Path { path in
let w = geometry.size.width
let h = geometry.size.height
// Make sure we do not exceed the size of the rectangle
let tr = min(min(self.tr, h/2), w/2)
let tl = min(min(self.tl, h/2), w/2)
let bl = min(min(self.bl, h/2), w/2)
let br = min(min(self.br, h/2), w/2)
path.move(to: CGPoint(x: w / 2.0, y: 0))
path.addLine(to: CGPoint(x: w - tr, y: 0))
path.addArc(center: CGPoint(x: w - tr, y: tr), radius: tr, startAngle: Angle(degrees: -90), endAngle: Angle(degrees: 0), clockwise: false)
path.addLine(to: CGPoint(x: w, y: h - br))
path.addArc(center: CGPoint(x: w - br, y: h - br), radius: br, startAngle: Angle(degrees: 0), endAngle: Angle(degrees: 90), clockwise: false)
path.addLine(to: CGPoint(x: bl, y: h))
path.addArc(center: CGPoint(x: bl, y: h - bl), radius: bl, startAngle: Angle(degrees: 90), endAngle: Angle(degrees: 180), clockwise: false)
path.addLine(to: CGPoint(x: 0, y: tl))
path.addArc(center: CGPoint(x: tl, y: tl), radius: tl, startAngle: Angle(degrees: 180), endAngle: Angle(degrees: 270), clockwise: false)
}
.fill(self.color)
}
}
}
We can then make a small example. Taking an array of items we can create a List. We will need the indices of the items so that we can tell which item is first (index of 0) and last (index of count - 1). The .listRowBackground modifier allows us to set the background of our rows so we will use that to set the view on it.
We create a helper function createRoundedCorners which will takes the index of the row and the number of rows that exist. This returns a RoundedCorrners view that the top left and right corners of the first row to be rounded and similarly the bottom left and right corners of the end row.
struct ContentView: View {
let items = ["Within 2 Minutes of Last Use",
"Within 1 Hour of Last Use",
"Always"]
var body: some View {
List {
ForEach(0..<items.count) { index in
Text(self.items[index]).font(.system(size: 24))
.listRowBackground(self.createRoundedCorners(at: index, count: self.items.count))
}
}
}
/// This function creates rounded corners for the first and last items in an array
func createRoundedCorners(at index: Int, count: Int) -> RoundedCorners {
switch index {
case 0:
return RoundedCorners(color: .blue, tl: 15, tr: 15, bl: 0, br: 0)
case (count - 1):
return RoundedCorners(color: .blue, tl: 0, tr: 0, bl: 15, br: 15)
default:
return RoundedCorners(color: .blue, tl: 0, tr: 0, bl: 0, br: 0)
}
}
}
This gives the following results
List at the top:
List at the bottom:
No, in SwiftUI Lists are very limited for configurations.
I recommend you to try making your own custom List-like view using ScrollView.

recursive binary search condition

I have a question about the condition of "entering" the "if condition" in the below recursive binary search:
http://www.fredosaurus.com/notes-cpp/algorithms/searching/rbinarysearch.html
int rBinarySearch(int sortedArray[], int first, int last, int key) {
// function:
// Searches sortedArray[first]..sortedArray[last] for key.
// returns: index of the matching element if it finds key,
// otherwise -(index where it could be inserted)-1.
// parameters:
// sortedArray in array of sorted (ascending) values.
// first, last in lower and upper subscript bounds
// key in value to search for.
// returns:
// index of key, or -insertion_position -1
// if key is not in the array.
if (first <= last) {
int mid = (first + last) / 2; // compute mid point.
if (key == sortedArray[mid])
return mid; // found it.
else if (key < sortedArray[mid])
// Call ourself for the lower part of the array
return rBinarySearch(sortedArray, first, mid-1, key);
else
// Call ourself for the upper part of the array
return rBinarySearch(sortedArray, mid+1, last, key);
}
return -(first + 1); // failed to find key
}
Specifically, I have a question regarding the part if (first <= last).
I was trying to hand trace the step of the above recursion function. For example, I write down an array of say [2, 5, 7, 11, 21, 26, 27, 36, 37, 42] and let the key be 1, i.e. key = 1.
Then I have in the first recursion, I think my first = 0, and last = 9.
So mid = (0 + 9)/2 = 4.5 (but mid will be 4 since mid is assigned to be int).
So mid[4] > 1, so then I have the next recursion being (arr[], 0, 4-1=3, 1),..... and so on.....
However it seems that the case of last < first doesn't seem to appear. I am just wondering is it actually possible for the case of last < first to happen? (i.e.. is the condition if (first <=last) necessary?)
If it is necessary, could someone illustrate with a very simple example that I can hand trace with to understand that this condition is necessary?
thanks
That condition is the stopping criterion for the case if the element that you are looking for is not an element of the array that you are searching.
In your example, if you further exercise it, the recursive calls will be
// first, last
rBinarySearch(arr[], 0, 3, 1); // -> mid = 1 -> else if
rBinarySearch(arr[], 0, 0, 1); // -> mid = 0 -> else if
rBinarySearch(arr[], 0, -1, 1); // there you go: last < first (i.e. -1 < 0)

GUI update in Qt

I'm working on a project which I need get some data(points) from a device and show them on the widget. I'm using Qt 5 and C++ language. the data come 12 times in a second and each time it has 895 points. actually its a simulation of PPI display of a Radar. I a have list which I put the point on that, and then I try to paint them on the widget. the problem is when I draw points on the widget it will connects the points and draw lines that obviously are unwanted.
void FormPPI::PPIUpdate()
{
QPainter* pdc = new QPainter();
ObservationList* list = monitoring->getObservationList();
ObservationList::iterator it = list->begin();
// qDebug() << list->size();
while (it != list->end())
{
Observation *o = &(*it);
int xp, yp;
float angle = calcPhi(o->pos().bearing());
//Find the pixel position on the screen
getPixelPos(o->pos().range() * cos(angle * DEG2RAD),
o->pos().range() * sin(angle * DEG2RAD), xp, yp);
//Draw observations here
//o->lifeTime() gets object lifetime which is initialized by 12
//used to reduce the intensity of color like antique radar system displays
pdc->fillRect(xp - 1, yp - 1, 2, 2, QColor(255, 255, 0, o->lifeTime() * 21));
//Decrease the observation life time by 1
o->decLifeTime();
if(o->lifeTime() <= 1)
list->erase(it);
it++;
}
qDebug() << list->size();
update();
list->release();
}
I am not able to explain why
pdc->fillRect(xp - 1, yp - 1, 2, 2, QColor(255, 255, 0, o->lifeTime() * 21));
fill rectanges between two consecutives point (xp1,yp1) and (xp2,yp2) .
But you have an alternative. You can draw points directly with a specific diameter d (seems you want a diameter of approximately 2 pixels).
int diameter = 2;
QPen pen = pdc->pen();
pen.setWidth(2);
pdc.setPen(pen);
while()
{
...
pen.setColor(QColor(255, 255, 0, o->lifeTime() * 21));
pdc->setPen(pen);
pdc->drawPoint(xp, yp);
...
}

Less lists as a mixin argument(s)

say i have this mixin:
.loop-strings("A, B, C", "1, 2, 3", "X, Y, Z";);
implemented like so:
.loop-strings(#list, #index: 1) when (isstring(extract(#list, #index))) {
#currentMember: extract(#list, #index);
.do-something-with(#currentMember);
.loop-strings(#list, (#index + 1)); /* loop the next member */
}
.do-something-with(...) {
#args1 : e(#arguments);
#args2 : A, B, C;
args1: #args1;
args2: #args2;
extract-args1-2: extract(#args1, 2);
extract-args2-2: extract(#args2, 2);
}
The result:
args1: A, B, C;
extract-args1-2: extract(A, B, C, 2);
args1: 1, 2, 3;
extract-args1-2: extract(1, 2, 3, 2);
args1: X, Y, Z;
args2: A, B, C;
extract-args1-2: extract(X, Y, Z, 2);
extract-args2-2: B;
These seams to be a difference between #foo:e("A, B, C"); or #foo:~"A, B, C"; and #foo:A, B, C;
I seems i can't use extract(#foo, 2); unless it is defined as an object list.
Is there a way to convert an esacaped string to an object list
It seams to be a difference between e("A, B, C") or ~"A, B, C" and A, B, C
Yes, both e("A, B, C") and ~"A, B, C" create so-called "anonymous value" type which is never considered as a meaningful type (it's not a list, not a number, not even a string). Basically an escaped values are just something like "Don't touch me" or "I know what I'm doing!" stuff, they are just being output "as is" and the compiler never tries to understand what's inside. This is basically what exactly the escaped values are for: "print" out something the compiler can't understand.
In general notice that you can use both comma and space as the value delimiter in a list. For example you can use .loop-strings(A B C, 1 2 3, X Y Z;); (two-dimensional list as a single parameter, so with a multi-argument mixin you even can get a tree-dimensional list in one line). Is there any particular reason you need to use quoted and/or escaped values? For example you could write it just as:
test {
.loop-lists(A, B, C; 1, 2, 3; X, Y, Z);
}
.loop-lists(#lists...) {
.loop(length(#lists));
.loop(#i) when (#i > 0) {
.loop((#i - 1));
.do-something-with(extract(#lists, #i));
}
}
.do-something-with(#list) {
v1: extract(#list, 1);
v2: extract(#list, 2);
v3: extract(#list, 3);
}
---
extract(A, B, C, 2);
For the moment this is incorrect extract syntax, extract accepts only two parameters so you could write this as:
extract(A B C, 2);
Or as:
#list: A, B, C;
extract(#list, 2);
---
Here's an example with couple of additional generic hints:
test {
.do-something(A B C, 1 2 3, X Y Z; foo bar, baz; banana);
}
.do-something(#p1, #p2, #p3) {
args1: #arguments; // 3D list
args2: extract(#arguments, 1); // 2D list: A B C, 1 2 3, X Y Z
args3: extract(extract(#arguments, 1), 1); // 1D list: A B C
args4: extract(extract(extract(#arguments, 1), 1), 1); // single value: A
p1- : #p1; // A B C, 1 2 3, X Y Z
p1-1: extract(#p1, 1); // A B C
p1-3: extract(#p1, 3); // X Y Z
#p2-1: extract(#p2, 1); // foo bar
p2-1: #p2-1; // foo bar
p2-1-2: extract(#p2-1, 2); // bar
p2-2: extract(#p2, 2); // baz
p3- : #p3; // banana
p3-1: extract(#p3, 1); // banana
// etc.
quoted-p2: "#{p2}"; // if you need a quoted string do it in reverse (i.e. non-quoted list to a quoted string)
}

Resources