Why is my "for()" not working - game-maker

for(xwingwaves = 0 ; xwingwaves < xwingwc ; xwingwaves += 1)
{
if(alarm[3] = -1) alarm[3] = 500;
}
my for is getting activated but my if is not getting started. Coded in gamemaker.
xwingwc = 2;

is there a var xwingwaves before the loop? I think you're just missing the declaration.

== instead of =
if(alarm[3] == -1) alarm[3] = 500;
and for(var xwingwaves = 0; instead of for(xwingwaves = 0;
GameMaker: Studio - Loops

Your code is correct, but you do strange thing.
for (xwingwaves = 0 ; xwingwaves < xwingwc ; xwingwaves += 1)
{
if(alarm[3] = -1) alarm[3] = 500;
}
Here you start alarm[3], if it isn't started.
Here you check alarm[3] multiple times. You do same thing 2 times. No reason to do this. No reason to use for loop. No any difference with simple:
if (alarm[3] = -1) alarm[3] = 500;
Keep in mind that if you haven't any code inside alarm[3] event (empty event), it won't be started (in this case just add one line od code, like // empty inside)
And keep in mind that this code starts alarm[3] insde object, where this code placed (or called from, if the code placed in script).

for(xwingwaves = 0 ; xwingwaves < xwingwc ; xwingwaves += 1)
{
if(alarm[3] <= -1) alarm[3] = 500;
}
//also i dont understand why you loop this? heres the code you need
if(alarm[3] <= -1) alarm[3] = 500; //the loop is meaningless put it in step event

Related

Multiline tooltips and CMFCButton

At the moment I am using a standard CButton control and my own derived CMultilineToolTipCtrl to be able to display multiline tool tips.
I thought I would try out the CMFCButton control as an alternative because it has native support for a tooltip by calling SetTooltip.
However, it does not seem to support multiline text from what I can tell. Is there a simple solution to this or should I stick with what I have coded?
This is the derived tooltip control that determines the correct width for the tool tip control:
UINT CMultilineToolTipCtrl::FitText(CString &rStrText)
{
CClientDC *pDC ;
CFont *pFntTip, *pFntOld ;
CRect rctMargin, rctTip ;
CSize sizText ;
CString strTextCopy, strLine, strChaff ;
CStringArray aryStrLines ;
UINT uMaxWidth;
INT_PTR uNumLines, uLineIndex ;
uMaxWidth = 0 ; // Fallback.
GetMargin(&rctMargin);
GetClientRect(&rctTip);
// Reduce by the given margins to get the true area.
rctTip.left += rctMargin.left ;
rctTip.top += rctMargin.top ;
rctTip.right -= rctMargin.right ;
rctTip.bottom -= rctMargin.bottom ;
pDC = new CClientDC(this);
if (pDC != nullptr)
{
pFntTip = GetFont();
pFntOld = (CFont *)pDC->SelectObject(pFntTip);
// First, find the longest line.
strTextCopy = rStrText ;
uMaxWidth = 0 ;
while (strTextCopy != _T("") )
{
strLine = strTextCopy.SpanExcluding(_T("\r\n") );
strTextCopy.Delete(0, strLine.GetLength() );
strChaff = strTextCopy.SpanIncluding(_T("\r\n") );
strTextCopy.Delete(0, strChaff.GetLength() );
sizText = pDC->GetTextExtent(strLine);
if (sizText.cx > (int)uMaxWidth)
uMaxWidth = sizText.cx ;
aryStrLines.Add(strLine);
}
rStrText = _T("");
uNumLines = aryStrLines.GetSize();
// Now, pad all lines to that max width.
for (uLineIndex = 0 ; uLineIndex < uNumLines ; uLineIndex++)
{
strLine = aryStrLines.GetAt(uLineIndex);
sizText = pDC->GetTextExtent(strLine);
while (sizText.cx <= (int)uMaxWidth)
{
strLine += _T(" ");
sizText = pDC->GetTextExtent(strLine);
}
rStrText += strLine ;
}
SendMessage(TTM_SETMAXTIPWIDTH, 0, uMaxWidth);
pDC->SelectObject(pFntOld);
delete pDC ;
}
return uMaxWidth ;
}
If you have a simpler way to calculate the width then I welcome your answers.

Is there an efficient algorithm for calculating which tiles are within a set walking distance of your character in a 2d grid?

Lets say that on a 2d grid of 20x20, you have your character at position (5,5).
He is able to walk up to 4 tiles in his move. However, there may be obstacles blocking your path such as a wall.
Is there any efficient / easy way for calculating exactly which tiles he would be able to walk to without checking every single possible move ( e.g. move up 0 and right 0 then move up 0 and right 1 e.t.c )?
At the moment I'm calculating the places that you can walk through with this horrific thing:
int playerx = GridPane.getRowIndex(button);
int playery = GridPane.getColumnIndex(button);
int position = playery*8+playerx;
for (int i = 0; i < 5; i++)
{
for (int j = i-4; j < 5-i; j++)
{
try
{
int expectedCollumn = playerx+j;
int actualCollumn = ((position+i+j*8)-((position+i+j*8)%8))/8;
if(expectedCollumn==actualCollumn)
{
Button temp = (Button)gridPane.getChildren()
.get(position+i+j*8);
if (!temp.getText().equals("W") &&
!temp.getText().equals("P"))
{
temp.setText("T");
}
}
actualCollumn = ((position-i+j*8)-((position-i+j*8)%8))/8;
if(expectedCollumn==actualCollumn)
{
Button temp2 = (Button)
gridPane.getChildren().get(position-i+j*8);
if (!temp2.getText().equals("W") &&
!temp2.getText().equals("P"))
{
temp2.setText("T");
}
}
}
}
}
However, its showing as if you are able to walk to the otherside of the wall and I'm not sure how I would go about fixing this.
Many thanks in advance.
For path finding, you should figure out how this works:
https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
and then move on to A* or something more efficient.
Thanks to everyone that answered but the solution was simple
incase somehow someone finds this post and is interested it was a simple recursive call
void getReachableTiles(Tile current, Int stamina, List<Tile> visited, List<Tile> reachable) {
if (stamina <= 0) return;
List<Tile> neighbours = new List<>(current + up, current + left, ..)
for (Tile t in neighbours) {
if (!visited.contains(t)) {
visited.append(t);
if (!t.isWall()) {
reachable.append(t);
getReachableTiles(t, stamina - 1, visited, reachable);
}
}
}
}

QGraphicsItem: Why no `stackAfter` method?

I'm having an annoying time trying to get around the 'recommended' way of doing something.
So, I have a stack of cards. I want to make it so that when I deal a card, it becomes the last-drawn object of the entire scene (typical bring_to_front functionality).
The recommended way to do this is just adding to the object's zValue until it is larger than all the rest, but I was hoping to do away with rather "lazy" integers running around all over the place with judicious use of the stackBefore method, which simulates reorganizing the order in which objects were added to the scene.
This works perfectly fine when I shuffle my cards in a limited set (get list of selected items, random.shuffle, for item do item.stackBefore(next item)), but it is certainly not working when it comes to bubbling the card to the top of the entire scene.
I considered adding a copy of the object to the scene and then removing the original, but it just seems like I should be able to do stackAfter like I would when using a Python list (or insertAt or something).
Sample code:
def deal_items(self):
if not self.selection_is_stack():
self.statusBar().showMessage("You must deal from a stack")
return
item_list = self.scene.sorted_selection()
for i,item in enumerate(item_list[::-1]):
width = item.boundingRect().width()
item.moveBy(width+i*width*0.6,0)
another_list = self.scene.items()[::-1]
idx = another_list.index(item)
for another_item in another_list[idx+1:]:
another_item.stackBefore(item)
This works. It just seems somewhat... ugly.
self.scene.items returns the items in the stacking order (link). So if you want to stackAfter an item, you can just query the z value of the current topmost item and then set the z value of the new topmost card to a value one larger.
item.setZValue(self.scene.items().first().zValue() + 1)
Hope that helps.
Edit added src for stackBefore and setZValue from http://gitorious.org/qt/
src/gui/graphicsview/qgraphicsitem.cpp
void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
{
if (sibling == this)
return;
if (!sibling || d_ptr->parent != sibling->parentItem()) {
qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
return;
}
QList<QGraphicsItem *> *siblings = d_ptr->parent
? &d_ptr->parent->d_ptr->children
: (d_ptr->scene ? &d_ptr->scene->d_func()->topLevelItems : 0);
if (!siblings) {
qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
return;
}
// First, make sure that the sibling indexes have no holes. This also
// marks the children list for sorting.
if (d_ptr->parent)
d_ptr->parent->d_ptr->ensureSequentialSiblingIndex();
else
d_ptr->scene->d_func()->ensureSequentialTopLevelSiblingIndexes();
// Only move items with the same Z value, and that need moving.
int siblingIndex = sibling->d_ptr->siblingIndex;
int myIndex = d_ptr->siblingIndex;
if (myIndex >= siblingIndex) {
siblings->move(myIndex, siblingIndex);
// Fixup the insertion ordering.
for (int i = 0; i < siblings->size(); ++i) {
int &index = siblings->at(i)->d_ptr->siblingIndex;
if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
++index;
}
d_ptr->siblingIndex = siblingIndex;
for (int i = 0; i < siblings->size(); ++i) {
int &index = siblings->at(i)->d_ptr->siblingIndex;
if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
siblings->at(i)->d_ptr->siblingOrderChange();
}
d_ptr->siblingOrderChange();
}
}
void QGraphicsItem::setZValue(qreal z)
{
const QVariant newZVariant(itemChange(ItemZValueChange, z));
qreal newZ = newZVariant.toReal();
if (newZ == d_ptr->z)
return;
if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) {
// Z Value has changed, we have to notify the index.
d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ);
}
d_ptr->z = newZ;
if (d_ptr->parent)
d_ptr->parent->d_ptr->needSortChildren = 1;
else if (d_ptr->scene)
d_ptr->scene->d_func()->needSortTopLevelItems = 1;
if (d_ptr->scene)
d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
itemChange(ItemZValueHasChanged, newZVariant);
if (d_ptr->flags & ItemNegativeZStacksBehindParent)
setFlag(QGraphicsItem::ItemStacksBehindParent, z < qreal(0.0));
if (d_ptr->isObject)
emit static_cast<QGraphicsObject *>(this)->zChanged();
}

Run time debug error message - Iterator not incrementable

Here is the code I have that whenever I run throws a "Iterator not incrementable" error at run time. If I comment out the sp++ line or the asteroids.push_back(*sp); line then it runs fine. So it has something to do with those lines...I saw in a previous post that the line sp->getSize() is incremented the pointer as well and may be the cause of the issues? thanks for the help!
while(sp != asteroids.end()){
if(sp->getSize() == .5 || sp->getSize() == 0.25){
glPushMatrix();
glScalef(.1, .1, .1);
glTranslatef(3,3,0);
sp->display_asteriod(sp->getSize(), random, randomTwo);
glPopMatrix();
asteroidCount++;
spawn.setSize(sp->getSize());
//spawn.setLife(it->getLife());
random = ((double) rand() / (RAND_MAX+1));
randomTwo = ((double) rand() / (RAND_MAX+1)) * 7;
spawn = createAsteroid(spawn);
x_speed_asteriod = (spawn.getXDirection())*(spawn.getRandomVelocity());// + x_speed_asteriod;
y_speed_asteriod = (spawn.getYDirection())*(spawn.getRandomVelocity());// + y_speed_asteriod;
spawn.setXSpeed(x_speed_asteriod);
spawn.setYSpeed(y_speed_asteriod);
if(spawn.getRandomAxis() == 0){
glRotatef(spawn.getAngleRotation(), 1, 0, 0);
}else if(spawn.getRandomAxis() == 1){
glRotatef(spawn.getAngleRotation(), 0, 1, 0);
}else if(spawn.getRandomAxis() == 2){
glRotatef(spawn.getAngleRotation(), 0, 0, 1);
}
//it = asteroids.begin() + asteroidCount;
//asteroids.insert(it, spawn);
//asteroids.resize(asteroidCount);
asteroids.push_back(*sp);
glPushMatrix();
glScalef(.1,.1,.1);
glTranslatef(spawn.getXPosition()-3, spawn.getYPosition()-3, 0);
spawn.display_asteriod(spawn.getSize(), random, randomTwo);
glPopMatrix();
}else{
sp++;
}
Your iterator sp is getting invalidated by the call to push_back. You are modifying the asteroids vector but you are still using the old iterator that you obtained before the modification.
This post contains a summary of rules for when iterators are invalidated.
Keeping track of new items to work on is often done using a queue (or a deque) in a safe way like this:
#include<deque>
vector<Asteroid> asteroids;
deque<Asteroid> asteroid_queue;
//add all current asteroids into the queue
asteroid_queue.assign(asteroids.begin(), asteroids.end());
while(!asteroid_queue.empty())
{
//grab the next asteroid to process
Asteroid asteroid = asteroid_queue.front();
//remove it from the queue
asteroid_queue.pop_front();
do_some_work()
//if necessary add a new asteroid .. be careful not to end in an infinite loop
asteroid_queue.push_back(..);
}

QValueList reverse iterator

How to make reverse looping for QValueList?
i found, thanks to all
QValueList<int> l;
for (int i = 0; i < 10; i++) l.append(i);
QValueListIterator<int> it = l.end(); --it;
for (; it != l.end(); --it)
{
qDebug(QString::number(*it));
}
The first thing you should do is change it to a QLinkedList
As it happens, the linked article shows an example of reverse looping.

Resources