All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.barrybecker4.simulation.snake.Snake Maven / Gradle / Ivy

/** Copyright by Barry G. Becker, 2000-2011. Licensed under MIT License: http://www.opensource.org/licenses/MIT  */
package com.barrybecker4.simulation.snake;

import com.barrybecker4.simulation.snake.data.ISnakeData;
import com.barrybecker4.simulation.snake.geometry.HeadSegment;
import com.barrybecker4.simulation.snake.geometry.Segment;

import javax.vecmath.Point2d;
import javax.vecmath.Vector2d;

/**
 *  Data structure and methods for representing a single dynamic snake
 *  The geometry of the snake is defined by ISnakeData
 *  General Improvements:
 *    - auto optimize with hill-climbing (let the snake learn how to move faster on its own)
 *    - add texture for snake skin
 *    - collision detection, walls, multiple snakes
 *    - goal directed path search
 *
 *  Performance Improvements:
 *    - profile (where is the time spent? rendering or computation)
 *    - only draw every nth frame
 *    - run OptimizeIt
 *  3/2011 frames per second for basic snake = 64.5
 *         Speed = 0.32
 *
 *  @author Barry Becker
 */
public class Snake {

    /** defines the snake geometry */
    private ISnakeData snakeData_;

    /** the array of segments which make up the snake */
    private Segment[] segment_ = null;


    /**
     * Constructor
     * use a hardcoded static data interface to initialize
     * so it can be easily run in an applet without using resources.
     */
    public Snake(ISnakeData snakeData) {
        setData(snakeData);
    }

    /**
     * @param snakeData the data defining the snakes geometrical shape.
     */
    public void setData(ISnakeData snakeData) {
        snakeData_ = snakeData;
        initFromData();
    }

    public void reset() {
        resetFromData();
    }

    public int getNumSegments() {
        return snakeData_.getNumSegments();
    }

    public Segment getSegment(int i) {
        return segment_[i];
    }

    /** use this if you need to avoid reading from a file */
    private void initFromData()  {

        segment_ = new Segment[snakeData_.getNumSegments()];
        resetFromData();
    }

    private void resetFromData() {

        double width1 = snakeData_.getWidths()[0];
        double width2 = snakeData_.getWidths()[1];
        int numSegments = snakeData_.getNumSegments();
        double segmentLength = snakeData_.getSegmentLength();

        double length = 80 + numSegments * segmentLength;
        Segment segment = new HeadSegment(width1, width2, segmentLength, length, 320.0, 0, this);
        segment_[0] = segment;
        Segment segmentInFront = segment;
        width1 = width2;

        for ( int i = 1; i < numSegments-1; i++ ) {
            width2 = snakeData_.getWidths()[i];

            segment = new Segment( width1, width2, segmentLength, segmentInFront, i, this );
            segment_[i] = segment;
            segmentInFront = segment;
            width1 = width2;
        }
        segment_[numSegments - 1] = new Segment(width1, width2, segmentLength, segmentInFront, numSegments-1, this);
    }

    /**
     * @return the center point of the snake
     */
    public Point2d getCenter() {
        Point2d center = new Point2d( 0.0, 0.0 );
        int ct = 0;
        for ( int i = 0; i < snakeData_.getNumSegments(); i += 2 ) {
            ct++;
            center.add( segment_[i].getCenterParticle() );
        }
        center.scale( 1.0 / (double) ct );
        return center;
    }

    /**
     * shift/translate the whole snake by the specified vector
     */
    public void translate( Vector2d vec ) {
        for ( int i = 0; i < snakeData_.getNumSegments(); i++ ) {
            segment_[i].translate( vec );
        }
    }

    /**
     * the snake is not considered stable if the angle between any edge segments exceeds Snake.MIN_EDGE_ANGLE
     * @return true if the snake has not gotten twisted too badly
     */
    public boolean isStable() {
        for ( int i = 2; i < snakeData_.getNumSegments(); i++ )
            if ( !segment_[i].isStable() )
                return false;
        return true;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy