mirror of
https://github.com/soconnor0919/eceg431.git
synced 2025-12-11 06:34:43 -05:00
188 lines
5.2 KiB
Plaintext
188 lines
5.2 KiB
Plaintext
// Manages snake body segments and movement mechanics
|
|
// Handles growth, collision detection, and rendering
|
|
class Snake {
|
|
field Array body;
|
|
field int length;
|
|
field int maxLength;
|
|
field int direction;
|
|
field int size;
|
|
field Point head;
|
|
|
|
// create snake with initial length at center screen
|
|
constructor Snake new() {
|
|
let maxLength = 200;
|
|
let length = 3;
|
|
let size = 8;
|
|
let direction = 4; // right
|
|
let body = Array.new(maxLength);
|
|
|
|
// initialize head at screen center (adjusted for header area)
|
|
let head = Point.new(256, 144);
|
|
let body[0] = head;
|
|
|
|
// create initial body segments
|
|
let body[1] = Point.new(248, 144);
|
|
let body[2] = Point.new(240, 144);
|
|
|
|
do draw();
|
|
return this;
|
|
}
|
|
|
|
// free memory
|
|
method void dispose() {
|
|
var int i;
|
|
var Point segment;
|
|
|
|
let i = 0;
|
|
while (i < length) {
|
|
let segment = body[i];
|
|
do segment.dispose();
|
|
let i = i + 1;
|
|
}
|
|
do body.dispose();
|
|
do Memory.deAlloc(this);
|
|
return;
|
|
}
|
|
|
|
// draw entire snake as solid squares
|
|
method void draw() {
|
|
var int i;
|
|
var Point segment;
|
|
|
|
do Screen.setColor(true);
|
|
let i = 0;
|
|
while (i < length) {
|
|
let segment = body[i];
|
|
do Screen.drawRectangle(segment.getX(), segment.getY(),
|
|
segment.getX() + size - 1, segment.getY() + size - 1);
|
|
let i = i + 1;
|
|
}
|
|
return;
|
|
}
|
|
|
|
// erase tail segment
|
|
method void eraseTail() {
|
|
var Point tail;
|
|
let tail = body[length - 1];
|
|
do Screen.setColor(false);
|
|
do Screen.drawRectangle(tail.getX(), tail.getY(),
|
|
tail.getX() + size, tail.getY() + size);
|
|
return;
|
|
}
|
|
|
|
// move snake one step forward with optional growth
|
|
method void move(boolean grow) {
|
|
var int i;
|
|
var Point newHead;
|
|
var Point oldTail;
|
|
var int newX, newY;
|
|
|
|
// calculate new head position based on direction
|
|
let newX = head.getX();
|
|
let newY = head.getY();
|
|
if (direction = 1) { let newY = newY - 8; } // up
|
|
if (direction = 2) { let newY = newY + 8; } // down
|
|
if (direction = 3) { let newX = newX - 8; } // left
|
|
if (direction = 4) { let newX = newX + 8; } // right
|
|
|
|
// create new head first
|
|
let newHead = Point.new(newX, newY);
|
|
|
|
if (grow) {
|
|
// growing: shift everything back and add new head
|
|
let i = length;
|
|
while (i > 0) {
|
|
let body[i] = body[i - 1];
|
|
let i = i - 1;
|
|
}
|
|
let body[0] = newHead;
|
|
let head = newHead;
|
|
let length = length + 1;
|
|
|
|
// draw new head only
|
|
do Screen.setColor(true);
|
|
do Screen.drawRectangle(head.getX(), head.getY(),
|
|
head.getX() + size - 1, head.getY() + size - 1);
|
|
} else {
|
|
// not growing: move tail to front as new head
|
|
let oldTail = body[length - 1];
|
|
|
|
// erase old tail first
|
|
do Screen.setColor(false);
|
|
do Screen.drawRectangle(oldTail.getX(), oldTail.getY(),
|
|
oldTail.getX() + size - 1, oldTail.getY() + size - 1);
|
|
|
|
// shift body segments back
|
|
let i = length - 1;
|
|
while (i > 0) {
|
|
let body[i] = body[i - 1];
|
|
let i = i - 1;
|
|
}
|
|
|
|
// dispose old tail and use new head
|
|
do oldTail.dispose();
|
|
let body[0] = newHead;
|
|
let head = newHead;
|
|
|
|
// draw new head
|
|
do Screen.setColor(true);
|
|
do Screen.drawRectangle(head.getX(), head.getY(),
|
|
head.getX() + size - 1, head.getY() + size - 1);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// change direction (prevent reverse moves)
|
|
method void setDirection(int newDirection) {
|
|
// prevent moving directly backwards
|
|
if (((direction = 1) & (newDirection = 2)) | // up -> down
|
|
((direction = 2) & (newDirection = 1)) | // down -> up
|
|
((direction = 3) & (newDirection = 4)) | // left -> right
|
|
((direction = 4) & (newDirection = 3))) { // right -> left
|
|
return;
|
|
}
|
|
let direction = newDirection;
|
|
return;
|
|
}
|
|
|
|
// check wall collision (adjusted for header area)
|
|
method boolean hitWall() {
|
|
return (head.getX() < 8) | (head.getX() > 496) |
|
|
(head.getY() < 33) | (head.getY() > 240);
|
|
}
|
|
|
|
// check self collision
|
|
method boolean hitSelf() {
|
|
var int i;
|
|
var Point segment;
|
|
|
|
let i = 1; // skip head (index 0)
|
|
while (i < length) {
|
|
let segment = body[i];
|
|
if (head.equals(segment)) {
|
|
return true;
|
|
}
|
|
let i = i + 1;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// get head position
|
|
method Point getHead() {
|
|
return head;
|
|
}
|
|
|
|
// get current length
|
|
method int getLength() {
|
|
return length;
|
|
}
|
|
|
|
// get current direction
|
|
method int getDirection() {
|
|
return direction;
|
|
}
|
|
|
|
|
|
}
|