void KGrFigure::walkDown(int WALKDELAY, int FALLDELAY) { if (hangAtPole() || (! canStand())) { // On bar or no firm ground underneath: so must fall. initFall (FALL2, FALLDELAY); } else { actualPixmap = (actualPixmap == CLIMB1) ? CLIMB2 : CLIMB1; if (walkCounter++ < 4) { // Not end of 4-step cycle: move one step down, if possible. if (canWalkDown()) { rely += STEP; absy += STEP; } walkTimer->start ((WALKDELAY * NSPEED) / speed, TRUE); } else { // End of 4-step cycle: move down to next cell, if possible. if (canWalkDown()) { y++; } // Always reset position, in case we are stuck partly into a brick. rely = 0; absy = y*16; // Must be able to halt at a pole when going down. if (! (canStand() || hangAtPole())) initFall(FALL2, FALLDELAY); // kein Halt....urgs else // Wait for caller to set next direction. status = STANDING; } } }
void KGrFigure::walkRight(int WALKDELAY, int FALLDELAY) { if (walkCounter++) { // wenn 0, soll sich Figur nur umdrehen if (++actualPixmap % 4) { // wenn true, dann ist kein vollständiger Schritt gemacht if (canWalkRight()) { relx += STEP; absx += STEP; // nur vorwärts gehen, wenn es auch möglich ist } walkTimer->start ((WALKDELAY * NSPEED) / speed, TRUE); } else { actualPixmap -= 4; // Schritt war vollendet if (canWalkRight()) { x++; } //gehe entgültig nach rechts // Always reset position, in case we are stuck partly into a brick. relx = 0; absx = x*16; if (!(canStand()||hangAtPole())) // kein Halt mehr...arrrgghhh initFall (FALL2, FALLDELAY); else status = STANDING; // Figur hat Halt } } else { status = STANDING; // Figur sollte sich nur Umdrehen. } }
void KGrFigure::walkLeft (int WALKDELAY, int FALLDELAY) { // If counter != 0, the figure is walking, otherwise he is turning around. if (walkCounter++ != 0) { // Change to the next pixmap in the animation. if ((++actualPixmap%4) != 0) { // Not end of 4-pixmap cycle: move one step left, if possible. if (canWalkLeft()) { relx -= STEP; absx -=STEP; } walkTimer->start ((WALKDELAY * NSPEED) / speed, TRUE); } else { // End of 4-pixmap cycle: start again, in next cell if possible. actualPixmap -= 4; if (canWalkLeft()) { x--; } // Always reset position, in case we are stuck partly into a brick. relx = 0; absx = x*16; // If cannot stand or hang, start fall, else await next assignment. if (! (canStand() || hangAtPole())) initFall (FALL1, FALLDELAY); else status = STANDING; // Caller should set next direction. } } else { status = STANDING; // The figure is turning around. } }
void TriangleWindow::initialize() { generateTerrain(); initFall(); m_program = new QOpenGLShaderProgram(this); m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/map.vert"); m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/map.frag"); m_program->link(); m_posAttr = m_program->attributeLocation("posAttr"); m_colAttr = m_program->attributeLocation("colAttr"); m_normal = m_program->attributeLocation("normal"); m_texCoord = m_program->attributeLocation("texCoord"); m_matrixUniform = m_program->uniformLocation("matrix"); m_texAttr = glGetUniformLocation(m_program->programId(), "texture"); glUniform1i(m_texAttr, 0); size_t verticesSize = _map.size()*sizeof(QVector3D), colorsSize = _color.size()*sizeof(QVector3D), normalSize = _normal.size()*sizeof(QVector3D), texCoordSize = _texture.size()*sizeof(GLfloat); vao.create(); vao.bind(); vbo.create(); vbo.setUsagePattern(QOpenGLBuffer::StaticDraw); vbo.bind(); vbo.allocate(verticesSize + colorsSize + normalSize + texCoordSize); vbo.bind(); vbo.write(0, _map.constData(), verticesSize); vbo.write(verticesSize, _color.constData(), colorsSize); vbo.write(verticesSize + colorsSize, _normal.constData(), normalSize); vbo.write(verticesSize + colorsSize + normalSize, _texture.constData(), texCoordSize); m_program->setAttributeBuffer(m_posAttr, GL_FLOAT, 0, 3, 0); m_program->setAttributeBuffer(m_colAttr, GL_FLOAT, verticesSize, 3, 0); m_program->setAttributeBuffer(m_normal, GL_FLOAT, verticesSize + colorsSize, 3, 0); m_program->setAttributeBuffer(m_texCoord, GL_FLOAT, verticesSize + colorsSize + normalSize, 2, 0); m_program->enableAttributeArray(m_posAttr); m_program->enableAttributeArray(m_colAttr); m_program->enableAttributeArray(m_normal); m_program->enableAttributeArray(m_texCoord); vao.release(); QImage image(QString(":/heightmap-2.png")); texture = new QOpenGLTexture(image); m_program->bind(); m_program->setUniformValue("ambiant_color", QVector4D(0.7, 0.7, 0.7, 1.0)); m_program->setUniformValue("light_direction", QVector4D(0.0, 0.0, 1.0, 1.0)); m_program->release(); glEnable(GL_DEPTH_TEST); }
void KGrEnemy::walkTimeDone () { if (KGrObject::frozen) {walkFrozen = TRUE; return; } // Check we are alive BEFORE checking for friends being in the way. // Maybe a friend overhead is blocking our escape from a brick. if ((*playfield)[x][y]->whatIam()==BRICK) { // sollte er aber in einem Brick dieAndReappear(); // sein, dann stirbt er wohl return; // Must leave "walkTimeDone" when an enemy dies. } if (! bumpingFriend()) { switch (direction) { case UP: walkUp (WALKDELAY); if ((rely == 0) && ((*playfield)[x][y+1]->whatIam() == USEDHOLE)) // Enemy kletterte grad aus einem Loch hinaus // -> gib es frei! ((KGrBrick *)(*playfield)[x][y+1])->unUseHole(); break; case DOWN: walkDown (WALKDELAY, FALLDELAY); break; case RIGHT: walkRight (WALKDELAY, FALLDELAY); break; case LEFT: walkLeft (WALKDELAY, FALLDELAY); break; default: // Switch search direction in KGoldrunner search (only). searchStatus = (searchStatus==VERTIKAL) ? HORIZONTAL : VERTIKAL; // In KGoldrunner rules, if a hole opens under an enemy // who is standing and waiting to move, he should fall. if (!(canStand()||hangAtPole())) { initFall (actualPixmap, FALLDELAY); } else { status = STANDING; } break; } // wenn die Figur genau ein Feld gelaufen ist if (status == STANDING) { // dann suche den Helden direction = searchbestway(x,y,herox,heroy); // und if (walkCounter >= 4) { if (! nuggets) collectNugget(); else dropNugget(); } status = WALKING; // initialisiere die Zählervariablen und walkCounter = 1; // den Timer um den Held weiter walkTimer->start ((WALKDELAY * NSPEED) / speed, TRUE); // zu jagen startWalk (); } } else { // A friend is in the way. Try a new direction, but not if leaving a hole. Direction dirn; // In KGoldrunner rules, change the search strategy, // to avoid enemy-enemy deadlock. searchStatus = (searchStatus==VERTIKAL) ? HORIZONTAL : VERTIKAL; dirn = searchbestway (x, y, herox, heroy); if ((dirn != direction) && ((*playfield)[x][y]->whatIam() != USEDHOLE)) { direction = dirn; status = WALKING; walkCounter = 1; relx = 0; absx = 16 * x; rely = 0; absy = 16 * y; startWalk (); } walkTimer->start ((WALKDELAY * NSPEED) / speed, TRUE); } showFigure(); }
void KGrHero::walkTimeDone () { if (! started) return; // Ignore signals from earlier play. if (KGrObject::frozen) {walkFrozen = TRUE; return; } if ((*playfield)[x][y]->whatIam() == BRICK) { emit caughtHero(); // Brick closed over hero. return; } if ((y==1)&&(nuggets<=0)) { // If on top row and all nuggets collected, emit leaveLevel(); // the hero has won and can go to next level. return; } if (status == STANDING) setNextDir(); if ((status == STANDING) && (nextDir != STAND)) { if ((standOnEnemy()) && (nextDir == DOWN)) { emit caughtHero(); // Hero is going to step down into an enemy. return; } startWalk(); } if (status != STANDING) { switch (direction) { case UP: walkUp (WALKDELAY); break; case DOWN: walkDown (WALKDELAY, FALLDELAY); break; case RIGHT: walkRight (WALKDELAY, FALLDELAY); break; case LEFT: walkLeft (WALKDELAY, FALLDELAY); break; default : // The following code is strange. It makes the hero fall off a pole. // It works because of other strange code in "startWalk(), case DOWN:". if (!canStand()||hangAtPole()) // falling initFall(FALL1, FALLDELAY); else status = STANDING; break; } herox=x;heroy=y; // Koordinatenvariablen neu // wenn Held genau ein Feld weitergelaufen ist, if ((relx==0)&&(rely==0)) // dann setzte statische { collectNugget(); // und nehme evtl. Nugget } showFigure(); // Is this REDUNDANT now? See showFigure() below. ////////////////////////////////////////////////// } if (status == STANDING) if (!canStand()&&!hangAtPole()) initFall(FALL1, FALLDELAY); else walkTimer->start ((WALKDELAY * NSPEED) / speed, TRUE); // This additional showFigure() is to update the hero position after it is // altered by the hero-enemy deadlock fix in standOnEnemy(). Messy, but ... //////////////////////////////////////////////////////////////////////////// showFigure(); if(isInEnemy()) { walkTimer->stop(); emit caughtHero(); } }