God jul!
Vi vill önska alla prenumeranter och läsare en riktigt god jul! Vi vill också förmedla lite julkänsla med lite programmering som passar högtiden.
Följ processen i Youtube-klippet nedan eller ladda hem koden. Vi har denna gång även gjort en enklare installer för dem som kanske vill provköra direkt.
Xmas 2023 - MonoGame projekt
Ladda ned
9,91 MB
Xmas.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using SharpDX.Direct2D1.Effects;
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using Drawing = System.Drawing;
using Forms = System.Windows.Forms;
namespace Xmas2023
{
public class Xmas : Game
{
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
Texture2D _background;
Texture2D _textureXmas;
Texture2D _textureWhite;
byte[] _rawTexture;
int _screenWidth;
int _screenHeight;
bool wasFocused;
int _scale = 4;
List<FallingPixel> _fallingPixels = new List<FallingPixel>();
List<FallingPixel> _pixels = new List<FallingPixel>();
Random _random = new Random();
float[] _baseLine;
Song song;
public Xmas()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
if(GraphicsDevice == null)
{
_graphics.ApplyChanges();
}
_graphics.IsFullScreen = true;
_graphics.PreferredBackBufferWidth = GraphicsDevice.Adapter.CurrentDisplayMode.Width;
_graphics.PreferredBackBufferHeight = GraphicsDevice.Adapter.CurrentDisplayMode.Height;
_graphics.ApplyChanges();
}
protected override void Initialize()
{
Drawing.Bitmap bmp = new Drawing.Bitmap(Forms.Screen.PrimaryScreen.Bounds.Width,
Forms.Screen.PrimaryScreen.Bounds.Height);
using (Drawing.Graphics g = Drawing.Graphics.FromImage(bmp))
{
g.CopyFromScreen(0, 0, 0, 0, Forms.Screen.PrimaryScreen.Bounds.Size);
}
_screenWidth = GraphicsDevice.PresentationParameters.BackBufferWidth;
_screenHeight = GraphicsDevice.PresentationParameters.BackBufferHeight;
_background = new Texture2D(GraphicsDevice, _screenWidth, _screenHeight);
_textureWhite = new Texture2D(GraphicsDevice, 1, 1);
int white = int.MaxValue;
_textureWhite.SetData<int>(new int[] { white });
_baseLine = new float[_screenWidth / _scale];
GetTexture2DFromBitmap(bmp);
for(int x = 0; x<_screenWidth / _scale; x++)
{
for(int y = 0; y<_screenHeight / _scale; y++)
{
_pixels.Add(new FallingPixel(x * _scale, y * _scale, _random.Next(10)));
}
}
base.Initialize();
}
public void GetTexture2DFromBitmap(Drawing.Bitmap bitmap)
{
BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat);
unsafe
{
uint* byteData = (uint*)data.Scan0;
// Switch bgra -> rgba
for (int i = 0; i < data.Height * data.Width; i++)
{
byteData[i] = (byteData[i] & 0x000000ff) << 16 | (byteData[i] & 0x0000FF00) | (byteData[i] & 0x00FF0000) >> 16 | (byteData[i] & 0xFF000000);
}
}
int bufferSize = data.Height * data.Stride;
_rawTexture = new byte[bufferSize];
Marshal.Copy(data.Scan0, _rawTexture, 0, _rawTexture.Length);
_background.SetData(_rawTexture);
bitmap.UnlockBits(data);
}
void checkAppRegainedFocus()
{
if (!this.IsActive)
{
wasFocused = false;
}
else if (!wasFocused && _graphics.IsFullScreen)
{
wasFocused = true;
_graphics.ToggleFullScreen();
_graphics.ToggleFullScreen();
}
}
void SetPixel(int x, int y, Color color)
{
for (int xx = x; xx < x + _scale && xx < _screenWidth; xx++)
{
for (int yy = y; yy < y + _scale && yy < _screenHeight; yy++)
{
int index = xx * 4 + yy * 4 * _screenWidth;
_rawTexture[index] = color.R;
_rawTexture[index + 1] = color.G;
_rawTexture[index + 2] = color.B;
_rawTexture[index + 3] = color.A;
}
}
}
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
_textureXmas = Content.Load<Texture2D>("godjul");
song = Content.Load<Song>("WinterWonderland");
MediaPlayer.IsRepeating = true;
MediaPlayer.Play(song);
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
if(_pixels.Count > 0 && _fallingPixels.Count < 800)
{
int pIndex = _random.Next(0, _pixels.Count);
_fallingPixels.Add(_pixels[pIndex]);
SetPixel(_pixels[pIndex].X, _pixels[pIndex].Y, Color.Transparent);
_pixels.RemoveAt(pIndex);
}
foreach(var item in _fallingPixels)
{
item.Update();
if(item.Position.Y >= (_screenHeight - _baseLine[item.X / _scale] * _scale))
{
_baseLine[item.X / _scale] += 0.1f;
SetPixel(item.X, (int)(_screenHeight - _baseLine[item.X / _scale] * _scale), Color.White);
}
}
_fallingPixels.RemoveAll(p => p.Position.Y > _screenHeight);
_background.SetData(_rawTexture);
checkAppRegainedFocus();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
_spriteBatch.Begin();
_spriteBatch.Draw(_textureXmas, new Vector2(_screenWidth / 2 - _textureXmas.Width / 2,
_screenHeight / 2 - _textureXmas.Height / 2), Color.White);
_spriteBatch.Draw(_background, Vector2.Zero, Color.White);
_spriteBatch.Draw(_textureXmas, new Vector2(_screenWidth / 2 - _textureXmas.Width / 2,
_screenHeight / 2 - _textureXmas.Height / 2), new Color(0.3f, 0.3f, 0.3f, 0.1f));
foreach (var pixel in _fallingPixels)
{
_spriteBatch.Draw(_textureWhite, new Rectangle((int) pixel.Position.X, (int)pixel.Position.Y, _scale, _scale),
Color.White);
}
_spriteBatch.End();
base.Draw(gameTime);
}
}
}
FallingPixel.cs
using Microsoft.Xna.Framework;
namespace Xmas2023
{
class FallingPixel
{
public int X { get; set; }
public int Y { get; set; }
public Vector2 Position { get; set; }
public Vector2 Velocity { get; set; }
public FallingPixel(int x, int y, int speed)
{
X = x;
Y = y;
Position = new Vector2(x, y);
Velocity = new Vector2(0, 1 - speed / 20f);
}
public void Update()
{
Position += Velocity;
}
}
}
Senaste kommentarer