|
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
namespace BubbleShot.Net
{
public partial class WindowMain : Window
{
public const int CanvasHeight = 600;
public const int CanvasWidth = 520;
public const int BubbleWeight = 40;
public const int BubbleRadious = BubbleWeight/2;
public const int BubbleVerticalSpace = 35;
public const int BubbleCollisionIndex = 33;
internal static UIElementCollection _children;
private readonly RadialGradientBrush[] _brushes = new RadialGradientBrush[8];
private readonly Random _random = new Random();
private Ellipse _bubble;
private readonly BubbleGrid _grid = new BubbleGrid();
private string[] _levels;
private int _level;
public WindowMain()
{
InitializeComponent();
var children = canvas.Children;
_children = children;
for (int i = 0; i < 8; i++)
_brushes[i] = _CreateBrush((i & 1) == 1, (i & 2) == 2, (i & 4) == 4);
_levels = Directory.GetFiles("Levels");
_LoadLevel();
_CreateNextBubble();
_ShowAngle(Math.PI/2);
}
private void _LoadLevel()
{
string name = _levels[_level];
int bubbleCount = _children.Count;
for(int i=bubbleCount-1; i>=0; i--)
if (_children[i] is Ellipse)
_children.RemoveAt(i);
_grid.Clear();
using(var file = File.OpenText(name))
{
for(int lineIndex=0; lineIndex<12; lineIndex++)
{
var textLine = file.ReadLine();
if (textLine == null)
return;
var bubbleLine = _grid._lines[lineIndex];
int lineCount = Math.Min(textLine.Length, bubbleLine.Length);
for(int columnIndex=0; columnIndex<lineCount; columnIndex++)
{
char c = textLine[columnIndex];
if (c < '0' || c > '7')
continue;
int colorValue = c - '0';
var bubble = _CreateBubble(colorValue);
_grid.Add(columnIndex, lineIndex, bubble);
_children.Add(bubble);
}
}
}
}
private void _CreateNextBubble()
{
_bubble = _CreateBubble();
Canvas.SetTop(_bubble, CanvasHeight - BubbleWeight);
Canvas.SetLeft(_bubble, (CanvasWidth-BubbleWeight)/2);
canvas.Children.Add(_bubble);
}
private Ellipse _CreateBubble()
{
var brushes = _GetAvailableBubbleColors();
int index = _random.Next(brushes.Count);
var result = _CreateBubble(brushes[index]);
return result;
}
private Ellipse _CreateBubble(int index)
{
var brush = _brushes[index];
var result = _CreateBubble(brush);
return result;
}
private Ellipse _CreateBubble(Brush brush)
{
var result = new Ellipse();
result.Width = BubbleWeight;
result.Height = BubbleWeight;
result.Fill = brush;
return result;
}
private RadialGradientBrush _CreateBrush(bool red, bool green, bool blue)
{
var brush = new RadialGradientBrush();
brush.Center = new Point(0.5, 0.5);
brush.GradientOrigin = new Point(0.3, 0.3);
var gradientStops = brush.GradientStops;
gradientStops.Add(new GradientStop(Colors.White, 0));
gradientStops.Add(new GradientStop(_CreateColor(red, green, blue, 0xEE), 0.25));
gradientStops.Add(new GradientStop(_CreateColor(red, green, blue, 0xBB), 0.7));
gradientStops.Add(new GradientStop(_CreateColor(red, green, blue, 0x55), 1));
brush.Freeze();
return brush;
}
private Color _CreateColor(bool red, bool green, bool blue, byte valueForTrue)
{
byte redIndex = 0;
byte greenIndex = 0;
byte blueIndex = 0;
if (red || green || blue)
{
if (red)
redIndex = valueForTrue;
if (green)
greenIndex = valueForTrue;
if (blue)
blueIndex = valueForTrue;
}
else
{
redIndex = (byte)(valueForTrue / 3);
greenIndex = redIndex;
blueIndex = redIndex;
}
var result = Color.FromArgb(255, redIndex, greenIndex, blueIndex);
return result;
}
private void canvas_MouseMove(object sender, MouseEventArgs e)
{
var position = e.MouseDevice.GetPosition(canvas);
double x = position.X - CanvasWidth/2;
double y = CanvasHeight - BubbleRadious - position.Y;
var angle = Math.Atan2(y, x);
_ShowAngle(angle);
}
private void _ShowAngle(double angle)
{
double centerX = Math.Cos(angle) * 50;
double centerY = -Math.Sin(angle) * 50;
centerX += CanvasWidth/2;
centerY += CanvasHeight - BubbleRadious;
Canvas.SetLeft(angleSquare, centerX - 10);
Canvas.SetTop(angleSquare, centerY - 10);
rotateTransform.Angle = -angle * 180 / Math.PI;
}
private readonly TimeSpan _420FramesPerSecond = TimeSpan.FromMilliseconds(1000.0/60.0/7.0);
private void canvas_MouseUp(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
var position = e.MouseDevice.GetPosition(canvas);
double x = position.X - CanvasWidth/2;
double y = CanvasHeight - BubbleRadious - position.Y;
var angle = Math.Atan2(y, x);
double xSpeed = Math.Cos(angle);
double ySpeed = Math.Sin(angle);
if (ySpeed <= 0)
return;
IsEnabled = false;
var animation = _Animation(xSpeed, ySpeed);
CompositionTargetAnimationManager.AddAnimation(animation, _420FramesPerSecond, null);
}
private void _EndGame()
{
_LoadLevel();
}
private IEnumerator<bool> _Animation(double xSpeed, double ySpeed)
{
try
{
double top = CanvasHeight-BubbleWeight;
double left = (CanvasWidth-BubbleWeight)/2;
while(top > 0)
{
top -= ySpeed;
double oldLeft = left;
left += xSpeed;
if (left < 0 || left > CanvasWidth-BubbleWeight)
{
xSpeed = -xSpeed;
left = oldLeft + xSpeed;
}
if (_grid.Collides((int)left, (int)top))
yield break;
Canvas.SetLeft(_bubble, left);
Canvas.SetTop(_bubble, top);
yield return true;
}
}
finally
{
var bubbleStatus = _grid.AddOrBlow(_bubble);
switch (bubbleStatus)
{
case BubbleStatus.GameOver:
_EndGame();
break;
case BubbleStatus.SomeBlown:
if (!_children.OfType<Ellipse>().Any())
{
_level++;
if (_level >= _levels.Length)
_level = 0;
_LoadLevel();
}
break;
}
IsEnabled = true;
_CreateNextBubble();
}
}
private List<RadialGradientBrush> _GetAvailableBubbleColors()
{
var result = new List<RadialGradientBrush>();
foreach(var child in _children)
{
var ellipse = child as Ellipse;
if (ellipse == null)
continue;
var brush =_GetBrushByBubble(ellipse);
//if (!result.Contains(brush)) add again, so the more it has,
//the more chances it will appear.
result.Add(brush);
}
return result;
}
private RadialGradientBrush _GetBrushByBubble(Ellipse ellipse)
{
var brushOrCopy = (RadialGradientBrush)ellipse.Fill;
return _GetBrushByColor(brushOrCopy.GradientStops[1].Color);
}
private RadialGradientBrush _GetBrushByColor(Color color)
{
foreach(var brush in _brushes)
if (brush.GradientStops[1].Color == color)
return brush;
throw new ApplicationException("Can't find brush.");
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I started to program computers when I was 11 years old, as a hobbyist, programming in AMOS Basic and Blitz Basic for Amiga.
At 12 I had my first try with assembler, but it was too difficult at the time. Then, in the same year, I learned C and, after learning C, I was finally able to learn assembler (for Motorola 680x0).
Not sure, but probably between 12 and 13, I started to learn C++. I always programmed "in an object oriented way", but using function pointers instead of virtual methods.
At 15 I started to learn Pascal at school and to use Delphi. At 16 I started my first internship (using Delphi). At 18 I started to work professionally using C++ and since then I've developed my programming skills as a professional developer in C++ and C#, generally creating libraries that help other developers do their work easier, faster and with less errors.
Want more info or simply want to contact me?
Take a look at:
http://paulozemek.azurewebsites.net/
Or e-mail me at: paulozemek@outlook.com
Codeproject MVP 2012, 2015 & 2016
Microsoft MVP 2013-2014 (in October 2014 I started working at Microsoft, so I can't be a Microsoft MVP anymore).