There's a snake in my flute!



  • alt text

    Content.makeFrontInterface(700, 500);
    
    const var CANVAS_SIZE = 40
    const var TILE_SIZE = 10;
    reg lastKey = 0;
    reg score = 0;
    
    const var drawCanvas = function(g)
    {	
    	g.fillAll(0xFFFFFFFF);
    	
    	g.setColour(0xFF000000);
    	//Canvas is drawn as a grid of tiles
    	for (i = 0; i < CANVAS_SIZE*TILE_SIZE; i++)
    	{
    		for (j = 0; j < CANVAS_SIZE*TILE_SIZE; j++)
    		{
    			g.fillRect([i*TILE_SIZE, j*TILE_SIZE, TILE_SIZE, TILE_SIZE]);
    		}
    	}
    }
    
    const var drawBoard = function(g)
    {
    	reg segment;
    	
    	g.setColour(0xFF00FF00);
    	
    	for (i = 0; i < path.getLength(); i++)
    	{
    		segment = path.getElementAt(i);
    		
    		g.fillRect([segment.x*TILE_SIZE, segment.y*TILE_SIZE, TILE_SIZE, TILE_SIZE]);
    	}
    	
    	//Draw food
    	g.setColour(0xFFFF0000);
    	g.fillRect([food.getX()*TILE_SIZE, food.getY()*TILE_SIZE, TILE_SIZE, TILE_SIZE]);
    }
    
    const var background = Content.addPanel("background", 0, 0)
    background.set("width", CANVAS_SIZE*TILE_SIZE+20);
    background.set("height", CANVAS_SIZE*TILE_SIZE+20);
    background.setPaintRoutine(function(g){g.fillAll(0xFFFFFFFF);});
    
    const var canvas = Content.addPanel("canvas", 10, 10);
    canvas.set("width", CANVAS_SIZE*TILE_SIZE);
    canvas.set("height", CANVAS_SIZE*TILE_SIZE);
    canvas.setPaintRoutine(drawCanvas);
    
    //Snake and food drawn on another panel over canvas - this means the canvas doesn't have to be redrawn for each update
    const var board = Content.addPanel("board", 0, 0);
    board.set("width", CANVAS_SIZE*TILE_SIZE);
    board.set("height", CANVAS_SIZE*TILE_SIZE);
    board.set("parentComponent", "canvas");
    board.setPaintRoutine(drawBoard);
    
    const var btnStart = Content.addButton("btnStart", 450, 0);
    btnStart.set("text", "Start/Pause");
    
    const var lblScore = Content.addLabel("lblScore", 450, 50);
    lblScore.set("width", 150);
    lblScore.set("height", 50);
    lblScore.set("text", "Points: 0");
    lblScore.set("textColour", 0xFF000000);
    lblScore.set("fontSize", 24);
    lblScore.set("alignment", "left");
    
    const var knbSpeed = Content.addKnob("knbSpeed", 450, 100);
    knbSpeed.set("text", "Speed");
    knbSpeed.setRange(1, 5, 1);
    
    const var gameLoop = Engine.createTimerObject();
    
    inline function checkDirection()
    {
    	switch(lastKey)
    	{		
    		case controls.N: if (path.getDirection() != controls.S) path.setDirection(controls.N); break;
    		case controls.S: if (path.getDirection() != controls.N) path.setDirection(controls.S); break;
    		case controls.E: if (path.getDirection() != controls.W) path.setDirection(controls.E); break;
    		case controls.W: if (path.getDirection() != controls.E) path.setDirection(controls.W); break;
    	}
    
    	switch(path.getDirection())
    	{
    		case controls.N: path.moveHead(0, -1); break; //Keep moving n
    		case controls.S: path.moveHead(0, 1); break; //Keep moving s
    		case controls.E: path.moveHead(1, 0); break; //Keep moving e
    		case controls.W: path.moveHead(-1, 0); break; //Keep moving w
    	}
    }
    
    //Check for a collision with the edge of the canvas
    inline function checkBoundary()
    {
    	reg head = path.getHead();
    
    	if (head.x < 0 || head.x+1 > canvas.get("width")/TILE_SIZE || head.y < 0 || head.y+1 > canvas.get("height")/TILE_SIZE)
    	{
    		return true;
    	}
    	return false;
    }
    
    //Check for a collision with food
    inline function checkFood()
    {
    	reg head = path.getHead();
    	
    	if (head.x == food.getX() && head.y == food.getY())
    	{
    		return true;
    	}
    	return false;		
    }
    
    //Check if the snake has eaten itself
    inline function checkCannibalism()
    {
    	reg head = path.getHead();
    	reg segment;
    	
    	for (i = 1; i < path.getLength(); i++) //Start at 1 to skip head
    	{
    		segment = path.getElementAt(i);
    		if (head.x == segment.x && head.y == segment.y)
    		{
    			return true;
    		}
    	}
    	return false;
    }
    
    gameLoop.callback = function()
    {			
    	if (checkBoundary() == true || checkCannibalism() == true)
    	{
    		gameLoop.stopTimer();
    		path.reset();
    		lastKey = 0;
    		btnStart.setValue(0);
    		lblScore.set("text", "***GAME OVER***");
    	}
    	else if (checkFood() == true)
    	{
    		food.changePosition();
    		path.grow();
    		lblScore.set("text", "Points: " + ++score);
    	}
    	
    	path.ripple();	
    	checkDirection();
    	board.repaint();
    };
    
    namespace controls
    {
    	const var N = 60;
    	const var S = 62;
    	const var E = 65;
    	const var W = 64;
    }
    
    namespace food 
    {
    	reg posX;
    	reg posY;
    	
    	inline function changePosition()
    	{
    		posX = Math.randInt(0, CANVAS_SIZE-1);
    		posY = Math.randInt(0, CANVAS_SIZE-1);
    	}
    	
    	inline function getX()
    	{
    		return posX;
    	}
    	
    	inline function getY()
    	{
    		return posY;
    	}
    }
    
    namespace path
    {
    	reg posX = [];
    	reg posY = [];
    	reg direction;
    
    	inline function reset()
    	{
    		posX = [CANVAS_SIZE/2];
    		posY = [CANVAS_SIZE/2];
    		direction = 0;
    	}
    	
    	function grow()
    	{
    		posX.push(0);
    		posY.push(0);
    	}
    	
    	inline function ripple()
    	{
    		for (i = posX.length-1; i > 0; i--)
    		{
    			posX[i] = posX[i-1];
    			posY[i] = posY[i-1];
    		}
    	}
    	   
    	inline function getHead()
    	{
    		return {"x":posX[0], "y":posY[0]};
    	}
    		
    	inline function moveHead(x, y)
    	{
    		posX[0] = posX[0]+x;
    		posY[0] = posY[0]+y;
    	}
    	
    	inline function getElementAt(i)
    	{
    		return {"x":posX[i], "y":posY[i]};
    	}
    	
    	inline function getLength()
    	{
    		return posX.length;
    	}
    	
    	inline function getDirection()
    	{
    		return direction;
    	}
    	
    	inline function setDirection(d)
    	{
    		direction = d;
    	}
    }function onNoteOn()
    {
    	if ([controls.N, controls.S, controls.E, controls.W].contains(Message.getNoteNumber()))
    	{
    		lastKey = Message.getNoteNumber();	
    	}	
    }
    function onNoteOff()
    {
    	
    }
    function onController()
    {
    	
    }
    function onTimer()
    {
    	
    }
    function onControl(number, value)
    {
    	if (number == btnStart) 
    	{
    		if (value == 0)
    		{
    			gameLoop.stopTimer();
    		}
    		else 
    		{
    			path.setDirection(0);
    			food.changePosition();
    			lblScore.set("text", "Points: 0");
    			gameLoop.startTimer(50*(6-knbSpeed.getValue()));
    		}
    	}
    }
    


  • omg bravo D.Healey!



  • Great! I need to dust off the Pong script then we can make a HISE Retro Games collection.


 

3
Online

353
Users

1.1k
Topics

7.6k
Posts