You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
5.7 KiB
C#
234 lines
5.7 KiB
C#
using IntelOrca.Launchpad;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace IntelOrca.LaunchpadTests
|
|
{
|
|
struct Point
|
|
{
|
|
public Point(int x, int y)
|
|
: this()
|
|
{
|
|
X = x;
|
|
Y = y;
|
|
}
|
|
|
|
public int X { get; set; }
|
|
public int Y { get; set; }
|
|
}
|
|
|
|
class Snake
|
|
{
|
|
private LaunchpadDevice mLaunchpadDevice;
|
|
|
|
private Random mRandom = new Random();
|
|
private long mCurrentTicks = 0;
|
|
|
|
private Point[] mBody;
|
|
private Point mDirection;
|
|
|
|
private bool mFoodActive;
|
|
private Point mFood;
|
|
|
|
private bool snakeFrozen = false;
|
|
private bool gameEnd = false;
|
|
|
|
public Snake(LaunchpadDevice device)
|
|
{
|
|
mLaunchpadDevice = device;
|
|
|
|
mLaunchpadDevice.ButtonPressed += mLaunchpadDevice_ButtonPressed;
|
|
mLaunchpadDevice.GetButton(SideButton.Arm).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off);
|
|
mLaunchpadDevice.GetButton(SideButton.Solo).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Full);
|
|
|
|
Restart();
|
|
}
|
|
|
|
private void mLaunchpadDevice_ButtonPressed(object sender, ButtonPressEventArgs e)
|
|
{
|
|
if (e.Type == ButtonType.Grid) {
|
|
mFood.X = e.X;
|
|
mFood.Y = e.Y;
|
|
mFoodActive = true;
|
|
}
|
|
|
|
if (e.Type == ButtonType.Side)
|
|
{
|
|
if(e.SidebarButton == SideButton.Solo)
|
|
{
|
|
if (snakeFrozen)
|
|
snakeFrozen = false;
|
|
else
|
|
snakeFrozen = true;
|
|
}
|
|
}
|
|
|
|
if (e.Type == ButtonType.Side)
|
|
{
|
|
if (e.SidebarButton == SideButton.Arm)
|
|
{
|
|
mLaunchpadDevice.Reset();
|
|
gameEnd = true;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public void Run()
|
|
{
|
|
// Kontrolle des internen Ticks (6*12 Frames werden pro "nächster" aktion verstreichen gelassen)
|
|
long last_tick = Environment.TickCount;
|
|
long delay = 12;
|
|
delay = 12 * 6;
|
|
|
|
// GameLoop
|
|
while (true && !gameEnd) {
|
|
if (Environment.TickCount - last_tick < delay)
|
|
continue;
|
|
mCurrentTicks += Environment.TickCount - last_tick;
|
|
last_tick = Environment.TickCount;
|
|
|
|
// Spielroutine (mit "Pause" Funktion [bei einem Snake Spiel natürlich quasi cheaten xD])
|
|
if(!snakeFrozen)
|
|
{
|
|
// Update aller Positionen
|
|
Update();
|
|
// Neu Zeichnen des Brettes
|
|
Draw();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
SetSnakeDirection();
|
|
MoveSnake();
|
|
}
|
|
|
|
private void Draw()
|
|
{
|
|
ButtonBrightness[,] redgrid = new ButtonBrightness[8, 8];
|
|
ButtonBrightness[,] greengrid = new ButtonBrightness[8, 8];
|
|
|
|
// Draw snake
|
|
foreach (Point p in mBody)
|
|
if (InBounds(p))
|
|
greengrid[p.X, p.Y] = ButtonBrightness.Full;
|
|
if (InBounds(mBody[0]))
|
|
redgrid[mBody[0].X, mBody[0].Y] = ButtonBrightness.Full;
|
|
|
|
// Draw food
|
|
if (mFoodActive)
|
|
redgrid[mFood.X, mFood.Y] = ButtonBrightness.Full;
|
|
|
|
// Invalidate (Neu Zeichnen aller Kacheln anhand was in red/greengrid drin steht
|
|
for (int y = 0; y < 8; y++)
|
|
for (int x = 0; x < 8; x++)
|
|
mLaunchpadDevice[x, y].SetBrightness(redgrid[x, y], greengrid[x, y]);
|
|
// Refresh um neue Konstellation anzuzeigen
|
|
mLaunchpadDevice.Refresh();
|
|
}
|
|
|
|
private void Restart()
|
|
{
|
|
mBody = new Point[4];
|
|
for (int y = 8; y < 8 + 4; y++)
|
|
mBody[y - 8] = new Point(3, y);
|
|
mDirection = new Point(0, -1);
|
|
|
|
mFoodActive = false;
|
|
|
|
// PlaceFood();
|
|
}
|
|
|
|
private void MoveSnake()
|
|
{
|
|
// Nachrücken aller Steine nach vorne (Letzer wird entfernt)
|
|
for (int i = mBody.Length - 1; i > 0; i--)
|
|
mBody[i] = mBody[i - 1];
|
|
//Kopf wird in Richtung bewegt
|
|
mBody[0].X += mDirection.X;
|
|
mBody[0].Y += mDirection.Y;
|
|
|
|
// Wenn
|
|
for (int i = 1; i < mBody.Length; i++) {
|
|
if (mBody[0].X == mBody[i].X && mBody[0].Y == mBody[i].Y)
|
|
Restart();
|
|
}
|
|
|
|
if (mBody[0].X == mFood.X && mBody[0].Y == mFood.Y) {
|
|
mFoodActive = false;
|
|
ExtendSnake();
|
|
// PlaceFood();
|
|
}
|
|
}
|
|
|
|
public void SetSnakeDirection()
|
|
{
|
|
bool danger = false;
|
|
|
|
Point head = mBody[0];
|
|
if (head.X == 7 && mDirection.X > 0) {
|
|
if (head.Y < 7) mDirection = new Point(0, 1);
|
|
else mDirection = new Point(0, -1);
|
|
danger = true;
|
|
} else if (head.X == 0 && mDirection.X < 0) {
|
|
if (head.Y < 7) mDirection = new Point(0, 1);
|
|
else mDirection = new Point(0, -1);
|
|
danger = true;
|
|
}
|
|
|
|
if (head.Y == 7 && mDirection.Y > 0) {
|
|
if (head.X < 7) mDirection = new Point(1, 0);
|
|
else mDirection = new Point(-1, 0);
|
|
danger = true;
|
|
} else if (head.Y == 0 && mDirection.Y < 0) {
|
|
if (head.X < 7) mDirection = new Point(1, 0);
|
|
else mDirection = new Point(-1, 0);
|
|
danger = true;
|
|
}
|
|
|
|
if (!danger && mFoodActive) {
|
|
if (mDirection.X != 0) {
|
|
if (mBody[0].X == mFood.X) {
|
|
if (mBody[0].Y < mFood.Y) mDirection = new Point(0, 1);
|
|
else mDirection = new Point(0, -1);
|
|
}
|
|
} else {
|
|
if (mBody[0].Y == mFood.Y) {
|
|
if (mBody[0].X < mFood.X) mDirection = new Point(1, 0);
|
|
else mDirection = new Point(-1, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ExtendSnake()
|
|
{
|
|
Point[] newBody = new Point[mBody.Length + 1];
|
|
newBody[0] = mBody[0];
|
|
Array.Copy(mBody, 0, newBody, 1, mBody.Length);
|
|
mBody = newBody;
|
|
}
|
|
|
|
private void PlaceFood()
|
|
{
|
|
List<Point> possiblePlaces = new List<Point>();
|
|
for (int y = 0; y < 8; y++)
|
|
for (int x = 0; x < 8; x++)
|
|
if (!mBody.Contains(new Point(x, y)))
|
|
possiblePlaces.Add(new Point(x, y));
|
|
|
|
int index = mRandom.Next(possiblePlaces.Count);
|
|
mFood = possiblePlaces[index];
|
|
}
|
|
|
|
private bool InBounds(Point p)
|
|
{
|
|
return (p.X >= 0 && p.Y >= 0 && p.X < 8 && p.Y < 8);
|
|
}
|
|
}
|
|
}
|