bool Character::update(float elapsed)
{
	float distance = speed * elapsed;

	//Distanz zum nächsten Feld berechnen
	CL_Point nextField = getNextField(moveDirection);
	CL_Pointf nextFieldCoordinates = getCoordinates(nextField);
	float distanceToField = abs(position.x - nextFieldCoordinates.x) + abs(position.y - nextFieldCoordinates.y);

	//Ist die zurückzulegende Distanz größer als die Distanz zum nächsten Feldmittelpunkt
	//und ist das Feld frei, so muss eine eventuelle Richtungsänderung geprüft werden
	while (distance > distanceToField && world->getLevel()->isFreeField(nextField))
	{
		//Zum Feldmittelpunkt bewegen
		move(distanceToField);

		distance -= distanceToField;

		currentField = getIndices(nextFieldCoordinates);

		//wird für erbende Klassen aufgerufen, um Aktionen auf dem Feldmittelpunkt ausführen zu können
		onFieldCenter();

		//Ist eine Richtungsänderung möglich, dann Richtung ändern
		if(world->getLevel()->isFreeField(getNextField(newDirection)))
			moveDirection = newDirection;

		//Distanz zum nächsten Feld berechnen
		nextField = getNextField(moveDirection);
		nextFieldCoordinates = getCoordinates(nextField);
		distanceToField = abs(position.x - nextFieldCoordinates.x) + abs(position.y - nextFieldCoordinates.y);
	}

	//Spielfigur weiterbewegen bzw. Richtung ändern
	if(world->getLevel()->isFreeField(nextField))
		move(distance);
	else if(world->getLevel()->isFreeField(getNextField(newDirection)))
		moveDirection = newDirection;

	animationPos += elapsed * animationSpeed;

	while (animationPos >= animationLength)
		animationPos -= animationLength;

	body.set_frame(getAnimationPos());

	return true;
}
Exemple #2
0
// bestimmt die Richtung anhand eines Ziel-Felds
void Character::goTo(const CL_Point& field, bool force)
{
	// Abstand zum Ziel berechnen
	CL_Vec2<int> delta = currentField - field;
	CL_Vec2<int> direction;

	// Richtungen in x und y Richtung bestimmen
	direction.x = (delta.x != 0) ? 2 + delta.x / abs(delta.x) : 1;
	direction.y = (delta.y != 0) ? 1 - delta.y / abs(delta.y) : 0;

	// Richtung mit der größeren Entfernung wählen
	targetDirection = (abs(delta.x) > abs(delta.y)) ? direction.x : direction.y;
	targetField = field;
	newDirection = targetDirection;

	// umliegende Felder abrufen
	CL_Point moveField = getNextField(moveDirection);
	CL_Point rightField = getNextField((moveDirection + 1) % 4);
	CL_Point leftField = getNextField((moveDirection - 1) % 4);

	const Level& level = world->getLevel();

	// wenn umliegende Felder (vorne, links, rechts) nicht frei
	if (!level.isFreeField(moveField) && !level.isFreeField(leftField) && !level.isFreeField(rightField))
		// umdrehen
		newDirection = (moveDirection + 2) % 4;
	// wenn Feld in gewünschter Richtung nicht frei
	else if (!level.isFreeField(getNextField(newDirection)) || (abs(newDirection - moveDirection) == 2 && !force))
	{
		// Richtung mit der kleineren Entfernung wählen
		newDirection = (newDirection == direction.x) ? direction.y : direction.x;

		// solange Feld in gewünschter Richtung nicht frei
		while (!level.isFreeField(getNextField(newDirection)) || (abs(newDirection - moveDirection) == 2 && !force))
			// im Uhrzeigersinn drehen
			newDirection = (newDirection + 1) % 4;
	}
}
Exemple #3
0
int moveInhabitants() {
    for(int iinhabitant = 0; iinhabitant < g_inhabitantCount; iinhabitant++) {
        inhabitant* cSnake = &g_inhabitants[iinhabitant];
        //if the snakes direction is null too, use a random one
        if(cSnake->direction == 0 && iinhabitant != 0 && (iinhabitant != 1 || !g_confTwoPlayer)) {
            cSnake->direction = getRandomDirection();
        }

        int nextCollision;
        int actCollision;
        point nextPosition = getNextField(cSnake->direction, cSnake->body[cSnake->length-1]);

        actCollision = collisionDetection(cSnake->body[cSnake->length-1]);
        nextCollision = collisionDetection(nextPosition);

        if ((nextCollision == EMPTY || nextCollision == FRUIT)) { // && cSnake->length < MAX_INHABITANT_LENGTH){
            cSnake->body[cSnake->length] = nextPosition;
        } else {
            // snake dead !
            cSnake->alive = false;
        }

        if (actCollision != FRUIT) {
            int count;
            for(count = 0; count < cSnake->length; count++) {
                cSnake->body[count] = cSnake->body[count + 1];
            }
            if(cSnake->alive && rand() % POINTS_LEN_ROUNDS == 0) {
                //for every 10 length -> get one point per round
                cSnake->points = cSnake->points + (cSnake->length/POINTS_LEN);
            }
        } else {
            reInitFruit(cSnake->body[cSnake->length-1]);
            if(cSnake->length < MAX_INHABITANT_LENGTH) {
                cSnake->length++;
            }
            //get points for eating fruit!
            cSnake->points =  cSnake->points + POINTS_FRUIT;
        }
        if(cSnake->points > g_confWin) {
            return 0;
        }
    }
    return 1;
}
Exemple #4
0
void initWalls(int wallCount) {
    int count;
    int innerCount;
    int wallLength;
    for(count = 0 ; count < wallCount; count++) {

        wallLength = getRandomWallLength();
        g_walls[count].parts[0] = getRandomCoordinateInField();
        g_walls[count].colorpair = COLOR_PAIR_WALL;
        g_walls[count].length = wallLength;
        int direction = getRandomDirection();

        for (innerCount = 1; innerCount < wallLength; innerCount++) {
            g_walls[count].parts[innerCount] = getNextField(direction, g_walls[count].parts[innerCount - 1]);
        }
        g_wallCount++;
    }
}
Exemple #5
0
void drawInhabitants() {

    //loop through all inhabitants (snakes)
    for(int iinhabitant = 0; iinhabitant < g_inhabitantCount; iinhabitant++) {
        inhabitant cinhabitant = g_inhabitants[iinhabitant];
        if(cinhabitant.alive) {
            attron(COLOR_PAIR(cinhabitant.colorpair));

            //loop through all parts of the snake
            //count backwards because the snake parts are saved in the array from tail to head
            for(int ipart = 0; ipart < cinhabitant.length; ipart++) {
                point cpart = cinhabitant.body[ipart];

                if(ipart == cinhabitant.length - 1) {
                    //draw head element
                    mvaddch(cpart.y, cpart.x, ACS_DIAMOND);
                } else if (ipart == 0) {
                    point cLastPart = cinhabitant.body[ipart+1];
                    if(point_equals(cLastPart, getNextField(DIRECTION_UP, cpart))
                            || point_equals(cLastPart, getNextField(DIRECTION_DOWN, cpart))) {
                        mvaddch(cpart.y, cpart.x, ACS_VLINE);
                    } else {
                        mvaddch(cpart.y, cpart.x, ACS_HLINE);
                    }
                } else {
                    //draw body element
                    point cNextPart = cinhabitant.body[ipart-1];
                    point cLastPart = cinhabitant.body[ipart+1];
                    //mvaddch(cpart.y, cpart.x, '~');

                    // draw top to down line
                    if((point_equals(cLastPart, getNextField(DIRECTION_UP, cpart)) || point_equals(cLastPart, getNextField(DIRECTION_DOWN, cpart)))
                            && (point_equals(cNextPart, getNextField(DIRECTION_UP, cpart)) || point_equals(cNextPart, getNextField(DIRECTION_DOWN, cpart)))) {
                        mvaddch(cpart.y, cpart.x, ACS_VLINE);

                        // draw left right element
                    } else  if((point_equals(cLastPart, getNextField(DIRECTION_LEFT, cpart)) || point_equals(cLastPart, getNextField(DIRECTION_RIGHT, cpart)))
                               && (point_equals(cNextPart, getNextField(DIRECTION_LEFT, cpart)) || point_equals(cNextPart, getNextField(DIRECTION_RIGHT, cpart)))) {
                        mvaddch(cpart.y, cpart.x, ACS_HLINE);

                        // draw top left element
                    } else  if((point_equals(cLastPart, getNextField(DIRECTION_UP, cpart)) || point_equals(cLastPart, getNextField(DIRECTION_LEFT, cpart)))
                               && (point_equals(cNextPart, getNextField(DIRECTION_UP, cpart)) || point_equals(cNextPart, getNextField(DIRECTION_LEFT, cpart)))) {
                        mvaddch(cpart.y, cpart.x, ACS_LRCORNER);

                        // drwa top right element
                    } else  if((point_equals(cLastPart, getNextField(DIRECTION_UP, cpart)) || point_equals(cLastPart, getNextField(DIRECTION_RIGHT, cpart)))
                               && (point_equals(cNextPart, getNextField(DIRECTION_UP, cpart)) || point_equals(cNextPart, getNextField(DIRECTION_RIGHT, cpart)))) {
                        mvaddch(cpart.y, cpart.x, ACS_LLCORNER);

                        // draw down left
                    } else  if((point_equals(cLastPart, getNextField(DIRECTION_DOWN, cpart)) || point_equals(cLastPart, getNextField(DIRECTION_LEFT, cpart)))
                               && (point_equals(cNextPart, getNextField(DIRECTION_DOWN, cpart)) || point_equals(cNextPart, getNextField(DIRECTION_LEFT, cpart)))) {
                        mvaddch(cpart.y, cpart.x, ACS_URCORNER);

                        // draw down right
                    } else  if((point_equals(cLastPart, getNextField(DIRECTION_DOWN, cpart)) || point_equals(cLastPart, getNextField(DIRECTION_RIGHT, cpart)))
                               && (point_equals(cNextPart, getNextField(DIRECTION_DOWN, cpart)) || point_equals(cNextPart, getNextField(DIRECTION_RIGHT, cpart)))) {
                        mvaddch(cpart.y, cpart.x, ACS_ULCORNER);

                        // draw
                    }

                }

            }
            attroff(COLOR_PAIR(cinhabitant.colorpair)); //end coloring
        }
        //draw points on bottom
        mvprintw(iinhabitant, g_confX+1, "Player %d: %d Punkte    ", iinhabitant, cinhabitant.points);
    }
}
Exemple #6
0
bool Character::update(float elapsed)
{
	// zurückzulegende Distanz berechnen
	float distance = speed * elapsed;

	// aktuelle Animationsposition berechnen und setzen
	animationPos += elapsed * animationSpeed;

	while (animationPos >= animationLength)
		animationPos -= animationLength;

	body.set_frame(getAnimationPos());

	const Level& level = world->getLevel();

	// nächstes Feld in Bewegungsrichtung abrufen
	CL_Point nextField = getNextField(moveDirection);

	// wenn Richtung geändert werden soll und nächste Feld nicht frei ist
	if (moveDirection != newDirection && !level.isFreeField(nextField))
	{
		// Richtung ändern
		moveDirection = newDirection;

		// nächstes Feld in neuer Richtung abrufen
		nextField = getNextField(moveDirection);
	}

	CL_Pointf coordinates = level.getCoordinates(nextField);

	// Distanz zum Mittelpunkt des nächsten Feldes berechnen
	float distanceToField = abs(position.x - coordinates.x) + abs(position.y - coordinates.y);

	// solange nächstes Feld frei und zurückzulegende Distanz größer als Distanz zum Mittelpunkt
	while (level.isFreeField(nextField) && distance > distanceToField)
	{
		// zum Mittelpunkt des nächsten Feldes gehen
		move(distanceToField);

		// aktuelles Feld ändern
		currentField = nextField;

		// Benachrichtigung für Subklassen (zur Pfadfindung)
		arrivedAtField();

		// zurückzulegende Distanz verringern
		distance -= distanceToField;

		// wenn nächstes Feld in gewünschter Richtung
		if (level.isFreeField(getNextField(newDirection)))
			// zur gewünschten Richtung
			moveDirection = newDirection;

		// nächstes Feld abrufen
		nextField = getNextField(moveDirection);

		// Distanz zum nächsten Feld berechnen
		coordinates = level.getCoordinates(nextField);		
		distanceToField = abs(position.x - coordinates.x) + abs(position.y - coordinates.y);
	}

	// wenn nächstes Feld frei
	if (level.isFreeField(nextField))
		// Restdistanz in Bewegungsrichtung zurücklegen
		move(distance);

	return true;
}