mirror of
https://github.com/raylib-cs/raylib-cs
synced 2025-06-30 19:03:42 -04:00
Update/merge examples back into main repo (#192)
This commit is contained in:
132
Examples/Text/CodepointsLoading.cs
Normal file
132
Examples/Text/CodepointsLoading.cs
Normal file
@ -0,0 +1,132 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [text] example - Codepoints loading
|
||||
*
|
||||
* Example originally created with raylib 4.2, last time updated with raylib 2.5
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2022-2023 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using System.Collections.Generic;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Text;
|
||||
|
||||
class CodepointsLoading
|
||||
{
|
||||
public unsafe static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - codepoints loading");
|
||||
|
||||
// Text to be displayed, must be UTF-8 (save this code file as UTF-8)
|
||||
// NOTE: It can contain all the required text for the game,
|
||||
// this text will be scanned to get all the required codepoints
|
||||
const string text =
|
||||
"いろはにほへと ちりぬるを\nわかよたれそ つねならむ\nうゐのおくやま けふこえて\nあさきゆめみし ゑひもせす";
|
||||
|
||||
// Get codepoints from text
|
||||
List<int> codepoints = GetCodePoints(text);
|
||||
|
||||
// Remove duplicate codepoints to generate smaller font atlas
|
||||
int[] codepointsNoDuplicates = codepoints.Distinct().ToArray();
|
||||
|
||||
// Load font containing all the provided codepoint glyphs
|
||||
// A texture font atlas is automatically generated
|
||||
Font font = LoadFontEx(
|
||||
"resources/DotGothic16-Regular.ttf",
|
||||
36,
|
||||
codepointsNoDuplicates,
|
||||
codepointsNoDuplicates.Length
|
||||
);
|
||||
|
||||
// Set bilinear scale filter for better font scaling
|
||||
SetTextureFilter(font.Texture, TextureFilter.TEXTURE_FILTER_BILINEAR);
|
||||
|
||||
bool showFontAtlas = false;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KeyboardKey.KEY_SPACE))
|
||||
{
|
||||
showFontAtlas = !showFontAtlas;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RAYWHITE);
|
||||
|
||||
DrawRectangle(0, 0, GetScreenWidth(), 70, Color.BLACK);
|
||||
DrawText($"Total codepoints contained in provided text: {codepoints.Count}", 10, 10, 20, Color.GREEN);
|
||||
DrawText(
|
||||
$"Total codepoints required for font atlas (duplicates excluded): {codepointsNoDuplicates.Length}",
|
||||
10,
|
||||
40,
|
||||
20,
|
||||
Color.GREEN
|
||||
);
|
||||
|
||||
if (showFontAtlas)
|
||||
{
|
||||
// Draw generated font texture atlas containing provided codepoints
|
||||
DrawTexture(font.Texture, 150, 100, Color.BLACK);
|
||||
DrawRectangleLines(150, 100, font.Texture.Width, font.Texture.Height, Color.BLACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw provided text with laoded font, containing all required codepoint glyphs
|
||||
DrawTextEx(font, text, new Vector2(160, 110), 48, 5, Color.BLACK);
|
||||
}
|
||||
|
||||
DrawText("Press SPACE to toggle font atlas view!", 10, GetScreenHeight() - 30, 20, Color.GRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadFont(font);
|
||||
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static List<int> GetCodePoints(string text)
|
||||
{
|
||||
List<int> codePoints = new();
|
||||
|
||||
StringInfo stringInfo = new(text);
|
||||
TextElementEnumerator enumerator = StringInfo.GetTextElementEnumerator(text);
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
int codePoint = char.ConvertToUtf32(enumerator.Current.ToString(), 0);
|
||||
codePoints.Add(codePoint);
|
||||
}
|
||||
|
||||
return codePoints;
|
||||
}
|
||||
}
|
146
Examples/Text/FontFilters.cs
Normal file
146
Examples/Text/FontFilters.cs
Normal file
@ -0,0 +1,146 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [text] example - Font filters
|
||||
*
|
||||
* After font loading, font texture atlas filter could be configured for a softer
|
||||
* display of the font when scaling it to different sizes, that way, it's not required
|
||||
* to generate multiple fonts at multiple sizes (as long as the scaling is not very different)
|
||||
*
|
||||
* This example has been created using raylib 1.3.0 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Text;
|
||||
|
||||
public class FontFilters
|
||||
{
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - font filters");
|
||||
|
||||
string msg = "Loaded Font";
|
||||
|
||||
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
// TTF Font loading with custom generation parameters
|
||||
Font font = LoadFontEx("resources/fonts/KAISG.ttf", 96, null, 0);
|
||||
|
||||
// Generate mipmap levels to use trilinear filtering
|
||||
// NOTE: On 2D drawing it won't be noticeable, it looks like TEXTURE_FILTER_BILINEAR
|
||||
GenTextureMipmaps(ref font.Texture);
|
||||
|
||||
float fontSize = font.BaseSize;
|
||||
Vector2 fontPosition = new(40, screenHeight / 2 - 80);
|
||||
Vector2 textSize = new(0.0f, 0.0f);
|
||||
|
||||
// Setup texture scaling filter
|
||||
SetTextureFilter(font.Texture, TextureFilter.TEXTURE_FILTER_POINT);
|
||||
TextureFilter currentFontFilter = TextureFilter.TEXTURE_FILTER_POINT;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
fontSize += GetMouseWheelMove() * 4.0f;
|
||||
|
||||
// Choose font texture filter method
|
||||
if (IsKeyPressed(KeyboardKey.KEY_ONE))
|
||||
{
|
||||
SetTextureFilter(font.Texture, TextureFilter.TEXTURE_FILTER_POINT);
|
||||
currentFontFilter = TextureFilter.TEXTURE_FILTER_POINT;
|
||||
}
|
||||
else if (IsKeyPressed(KeyboardKey.KEY_TWO))
|
||||
{
|
||||
SetTextureFilter(font.Texture, TextureFilter.TEXTURE_FILTER_BILINEAR);
|
||||
currentFontFilter = TextureFilter.TEXTURE_FILTER_BILINEAR;
|
||||
}
|
||||
else if (IsKeyPressed(KeyboardKey.KEY_THREE))
|
||||
{
|
||||
// NOTE: Trilinear filter won't be noticed on 2D drawing
|
||||
SetTextureFilter(font.Texture, TextureFilter.TEXTURE_FILTER_TRILINEAR);
|
||||
currentFontFilter = TextureFilter.TEXTURE_FILTER_TRILINEAR;
|
||||
}
|
||||
|
||||
textSize = MeasureTextEx(font, msg, fontSize, 0);
|
||||
|
||||
if (IsKeyDown(KeyboardKey.KEY_LEFT))
|
||||
{
|
||||
fontPosition.X -= 10;
|
||||
}
|
||||
else if (IsKeyDown(KeyboardKey.KEY_RIGHT))
|
||||
{
|
||||
fontPosition.X += 10;
|
||||
}
|
||||
|
||||
// Load a dropped TTF file dynamically (at current fontSize)
|
||||
if (IsFileDropped())
|
||||
{
|
||||
string[] files = Raylib.GetDroppedFiles();
|
||||
|
||||
// NOTE: We only support first ttf file dropped
|
||||
if (IsFileExtension(files[0], ".ttf"))
|
||||
{
|
||||
UnloadFont(font);
|
||||
font = LoadFontEx(files[0], (int)fontSize, null, 0);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RAYWHITE);
|
||||
|
||||
DrawText("Use mouse wheel to change font size", 20, 20, 10, Color.GRAY);
|
||||
DrawText("Use KEY_RIGHT and KEY_LEFT to move text", 20, 40, 10, Color.GRAY);
|
||||
DrawText("Use 1, 2, 3 to change texture filter", 20, 60, 10, Color.GRAY);
|
||||
DrawText("Drop a new TTF font for dynamic loading", 20, 80, 10, Color.DARKGRAY);
|
||||
|
||||
DrawTextEx(font, msg, fontPosition, fontSize, 0, Color.BLACK);
|
||||
|
||||
DrawRectangle(0, screenHeight - 80, screenWidth, 80, Color.LIGHTGRAY);
|
||||
DrawText("CURRENT TEXTURE FILTER:", 250, 400, 20, Color.GRAY);
|
||||
|
||||
if (currentFontFilter == TextureFilter.TEXTURE_FILTER_POINT)
|
||||
{
|
||||
DrawText("POINT", 570, 400, 20, Color.BLACK);
|
||||
}
|
||||
else if (currentFontFilter == TextureFilter.TEXTURE_FILTER_POINT)
|
||||
{
|
||||
DrawText("BILINEAR", 570, 400, 20, Color.BLACK);
|
||||
}
|
||||
else if (currentFontFilter == TextureFilter.TEXTURE_FILTER_TRILINEAR)
|
||||
{
|
||||
DrawText("TRILINEAR", 570, 400, 20, Color.BLACK);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadFont(font);
|
||||
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
102
Examples/Text/FontLoading.cs
Normal file
102
Examples/Text/FontLoading.cs
Normal file
@ -0,0 +1,102 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [text] example - Font loading
|
||||
*
|
||||
* raylib can load fonts from multiple file formats:
|
||||
*
|
||||
* - TTF/OTF > Sprite font atlas is generated on loading, user can configure
|
||||
* some of the generation parameters (size, characters to include)
|
||||
* - BMFonts > Angel code font fileformat, sprite font image must be provided
|
||||
* together with the .fnt file, font generation cna not be configured
|
||||
* - XNA Spritefont > Sprite font image, following XNA Spritefont conventions,
|
||||
* Characters in image must follow some spacing and order rules
|
||||
*
|
||||
* This example has been created using raylib 2.6 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2016-2019 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Text;
|
||||
|
||||
public class FontLoading
|
||||
{
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - font loading");
|
||||
|
||||
// Define characters to draw
|
||||
// NOTE: raylib supports UTF-8 encoding, following list is actually codified as UTF8 internally
|
||||
string msg = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI\nJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmn\nopqrstuvwxyz{|}~¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓ\nÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷\nøùúûüýþÿ";
|
||||
|
||||
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
// BMFont (AngelCode) : Font data and image atlas have been generated using external program
|
||||
Font fontBm = LoadFont("resources/fonts/pixantiqua.fnt");
|
||||
|
||||
// TTF font : Font data and atlas are generated directly from TTF
|
||||
// NOTE: We define a font base size of 32 pixels tall and up-to 250 characters
|
||||
Font fontTtf = LoadFontEx("resources/fonts/pixantiqua.ttf", 32, null, 250);
|
||||
|
||||
bool useTtf = false;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyDown(KeyboardKey.KEY_SPACE))
|
||||
{
|
||||
useTtf = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
useTtf = false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RAYWHITE);
|
||||
|
||||
DrawText("Hold SPACE to use TTF generated font", 20, 20, 20, Color.LIGHTGRAY);
|
||||
|
||||
if (!useTtf)
|
||||
{
|
||||
DrawTextEx(fontBm, msg, new Vector2(20.0f, 100.0f), fontBm.BaseSize, 2, Color.MAROON);
|
||||
DrawText("Using BMFont (Angelcode) imported", 20, GetScreenHeight() - 30, 20, Color.GRAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTextEx(fontTtf, msg, new Vector2(20.0f, 100.0f), fontTtf.BaseSize, 2, Color.LIME);
|
||||
DrawText("Using TTF font generated", 20, GetScreenHeight() - 30, 20, Color.GRAY);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadFont(fontBm);
|
||||
UnloadFont(fontTtf);
|
||||
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
162
Examples/Text/FontSdf.cs
Normal file
162
Examples/Text/FontSdf.cs
Normal file
@ -0,0 +1,162 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [text] example - TTF loading and usage
|
||||
*
|
||||
* This example has been created using raylib 1.3.0 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using System.Runtime.InteropServices;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Text;
|
||||
|
||||
public class FontSdf
|
||||
{
|
||||
public unsafe static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - SDF fonts");
|
||||
|
||||
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
|
||||
string msg = "Signed Distance Fields";
|
||||
|
||||
// Loading file to memory
|
||||
uint fileSize = 0;
|
||||
byte* fileData = LoadFileData("resources/fonts/anonymous_pro_bold.ttf", ref fileSize);
|
||||
|
||||
// Default font generation from TTF font
|
||||
Font fontDefault = new();
|
||||
fontDefault.BaseSize = 16;
|
||||
fontDefault.GlyphCount = 95;
|
||||
|
||||
// Loading font data from memory data
|
||||
// Parameters > font size: 16, no chars array provided (0), chars count: 95 (autogenerate chars array)
|
||||
fontDefault.Glyphs = LoadFontData(fileData, (int)fileSize, 16, null, 95, FontType.FONT_DEFAULT);
|
||||
// Parameters > chars count: 95, font size: 16, chars padding in image: 4 px, pack method: 0 (default)
|
||||
Image atlas = GenImageFontAtlas(fontDefault.Glyphs, &fontDefault.Recs, 95, 16, 4, 0);
|
||||
fontDefault.Texture = LoadTextureFromImage(atlas);
|
||||
UnloadImage(atlas);
|
||||
|
||||
// SDF font generation from TTF font
|
||||
Font fontSDF = new();
|
||||
fontSDF.BaseSize = 16;
|
||||
fontSDF.GlyphCount = 95;
|
||||
// Parameters > font size: 16, no chars array provided (0), chars count: 0 (defaults to 95)
|
||||
fontSDF.Glyphs = LoadFontData(fileData, (int)fileSize, 16, null, 0, FontType.FONT_SDF);
|
||||
// Parameters > chars count: 95, font size: 16, chars padding in image: 0 px, pack method: 1 (Skyline algorythm)
|
||||
atlas = GenImageFontAtlas(fontSDF.Glyphs, &fontSDF.Recs, 95, 16, 0, 1);
|
||||
fontSDF.Texture = LoadTextureFromImage(atlas);
|
||||
UnloadImage(atlas);
|
||||
|
||||
// Free memory from loaded file
|
||||
UnloadFileData(fileData);
|
||||
|
||||
// Load SDF required shader (we use default vertex shader)
|
||||
Shader shader = LoadShader(null, "resources/shaders/glsl330/sdf.fs");
|
||||
// Required for SDF font
|
||||
SetTextureFilter(fontSDF.Texture, TextureFilter.TEXTURE_FILTER_BILINEAR);
|
||||
|
||||
Vector2 fontPosition = new(40, screenHeight / 2 - 50);
|
||||
Vector2 textSize = new(0.0f);
|
||||
float fontSize = 16.0f;
|
||||
// 0 - fontDefault, 1 - fontSDF
|
||||
int currentFont = 0;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
fontSize += GetMouseWheelMove() * 8.0f;
|
||||
|
||||
if (fontSize < 6)
|
||||
{
|
||||
fontSize = 6;
|
||||
}
|
||||
|
||||
if (IsKeyDown(KeyboardKey.KEY_SPACE))
|
||||
{
|
||||
currentFont = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentFont = 0;
|
||||
}
|
||||
|
||||
if (currentFont == 0)
|
||||
{
|
||||
textSize = MeasureTextEx(fontDefault, msg, fontSize, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
textSize = MeasureTextEx(fontSDF, msg, fontSize, 0);
|
||||
}
|
||||
|
||||
fontPosition.X = GetScreenWidth() / 2 - textSize.X / 2;
|
||||
fontPosition.Y = GetScreenHeight() / 2 - textSize.Y / 2 + 80;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RAYWHITE);
|
||||
|
||||
if (currentFont == 1)
|
||||
{
|
||||
// NOTE: SDF fonts require a custom SDf shader to compute fragment color
|
||||
BeginShaderMode(shader);
|
||||
DrawTextEx(fontSDF, msg, fontPosition, fontSize, 0, Color.BLACK);
|
||||
EndShaderMode();
|
||||
|
||||
DrawTexture(fontSDF.Texture, 10, 10, Color.BLACK);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTextEx(fontDefault, msg, fontPosition, fontSize, 0, Color.BLACK);
|
||||
DrawTexture(fontDefault.Texture, 10, 10, Color.BLACK);
|
||||
}
|
||||
|
||||
if (currentFont == 1)
|
||||
{
|
||||
DrawText("SDF!", 320, 20, 80, Color.RED);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawText("default font", 315, 40, 30, Color.GRAY);
|
||||
}
|
||||
|
||||
DrawText("FONT SIZE: 16.0", GetScreenWidth() - 240, 20, 20, Color.DARKGRAY);
|
||||
DrawText($"RENDER SIZE: {fontSize:2F}", GetScreenWidth() - 240, 50, 20, Color.DARKGRAY);
|
||||
DrawText("Use MOUSE WHEEL to SCALE TEXT!", GetScreenWidth() - 240, 90, 10, Color.DARKGRAY);
|
||||
|
||||
DrawText("PRESS SPACE to USE SDF FONT VERSION!", 340, GetScreenHeight() - 30, 20, Color.MAROON);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadFont(fontDefault);
|
||||
UnloadFont(fontSDF);
|
||||
UnloadShader(shader);
|
||||
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
96
Examples/Text/FontSpritefont.cs
Normal file
96
Examples/Text/FontSpritefont.cs
Normal file
@ -0,0 +1,96 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [text] example - Sprite font loading
|
||||
*
|
||||
* Loaded sprite fonts have been generated following XNA SpriteFont conventions:
|
||||
* - Characters must be ordered starting with character 32 (Space)
|
||||
* - Every character must be contained within the same Rectangle height
|
||||
* - Every character and every line must be separated the same distance
|
||||
* - Rectangles must be defined by a magenta color background
|
||||
*
|
||||
* If following this constraints, a font can be provided just by an image,
|
||||
* this is quite handy to avoid additional information files (like BMFonts use).
|
||||
*
|
||||
* This example has been created using raylib 1.0 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Text;
|
||||
|
||||
public class FontSpritefont
|
||||
{
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - sprite font loading");
|
||||
|
||||
string msg1 = "THIS IS A custom SPRITE FONT...";
|
||||
string msg2 = "...and this is ANOTHER CUSTOM font...";
|
||||
string msg3 = "...and a THIRD one! GREAT! :D";
|
||||
|
||||
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
|
||||
Font font1 = LoadFont("resources/fonts/custom_mecha.png");
|
||||
Font font2 = LoadFont("resources/fonts/custom_alagard.png");
|
||||
Font font3 = LoadFont("resources/fonts/custom_jupiter_crash.png");
|
||||
|
||||
Vector2 fontPosition1 = new(
|
||||
screenWidth / 2 - MeasureTextEx(font1, msg1, font1.BaseSize, -3).X / 2,
|
||||
screenHeight / 2 - font1.BaseSize / 2 - 80
|
||||
);
|
||||
|
||||
Vector2 fontPosition2 = new(
|
||||
screenWidth / 2 - MeasureTextEx(font2, msg2, font2.BaseSize, -2).X / 2,
|
||||
screenHeight / 2 - font2.BaseSize / 2 - 10
|
||||
);
|
||||
|
||||
Vector2 fontPosition3 = new(
|
||||
screenWidth / 2 - MeasureTextEx(font3, msg3, font3.BaseSize, 2).X / 2,
|
||||
screenHeight / 2 - font3.BaseSize / 2 + 50
|
||||
);
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update variables here...
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RAYWHITE);
|
||||
|
||||
DrawTextEx(font1, msg1, fontPosition1, font1.BaseSize, -3, Color.WHITE);
|
||||
DrawTextEx(font2, msg2, fontPosition2, font2.BaseSize, -2, Color.WHITE);
|
||||
DrawTextEx(font3, msg3, fontPosition3, font3.BaseSize, 2, Color.WHITE);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadFont(font1);
|
||||
UnloadFont(font2);
|
||||
UnloadFont(font3);
|
||||
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
63
Examples/Text/FormatText.cs
Normal file
63
Examples/Text/FormatText.cs
Normal file
@ -0,0 +1,63 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [text] example - Text formatting
|
||||
*
|
||||
* This example has been created using raylib 1.1 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Text;
|
||||
|
||||
public class FormatText
|
||||
{
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - text formatting");
|
||||
|
||||
int score = 100020;
|
||||
int hiscore = 200450;
|
||||
int lives = 5;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RAYWHITE);
|
||||
|
||||
DrawText($"Score: {score}", 200, 80, 20, Color.RED);
|
||||
DrawText($"HiScore: {hiscore}", 200, 120, 20, Color.GREEN);
|
||||
DrawText($"Lives: {lives}", 200, 160, 40, Color.BLUE);
|
||||
DrawText($"Elapsed Time: {GetFrameTime() * 1000} ms", 200, 220, 20, Color.BLACK);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
166
Examples/Text/InputBox.cs
Normal file
166
Examples/Text/InputBox.cs
Normal file
@ -0,0 +1,166 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [text] example - Input Box
|
||||
*
|
||||
* This example has been created using raylib 1.7 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Text;
|
||||
|
||||
public class InputBox
|
||||
{
|
||||
public const int MaxInputChars = 9;
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - input box");
|
||||
|
||||
// NOTE: One extra space required for line ending char '\0'
|
||||
char[] name = new char[MaxInputChars];
|
||||
int letterCount = 0;
|
||||
|
||||
Rectangle textBox = new(screenWidth / 2 - 100, 180, 225, 50);
|
||||
bool mouseOnText = false;
|
||||
|
||||
int framesCounter = 0;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (CheckCollisionPointRec(GetMousePosition(), textBox))
|
||||
{
|
||||
mouseOnText = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouseOnText = false;
|
||||
}
|
||||
|
||||
if (mouseOnText)
|
||||
{
|
||||
// Set the window's cursor to the I-Beam
|
||||
SetMouseCursor(MouseCursor.MOUSE_CURSOR_IBEAM);
|
||||
|
||||
// Check if more characters have been pressed on the same frame
|
||||
int key = GetCharPressed();
|
||||
|
||||
while (key > 0)
|
||||
{
|
||||
// NOTE: Only allow keys in range [32..125]
|
||||
if ((key >= 32) && (key <= 125) && (letterCount < MaxInputChars))
|
||||
{
|
||||
name[letterCount] = (char)key;
|
||||
letterCount++;
|
||||
}
|
||||
|
||||
// Check next character in the queue
|
||||
key = GetCharPressed();
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.KEY_BACKSPACE))
|
||||
{
|
||||
letterCount -= 1;
|
||||
if (letterCount < 0)
|
||||
{
|
||||
letterCount = 0;
|
||||
}
|
||||
name[letterCount] = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetMouseCursor(MouseCursor.MOUSE_CURSOR_DEFAULT);
|
||||
}
|
||||
|
||||
if (mouseOnText)
|
||||
{
|
||||
framesCounter += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
framesCounter = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RAYWHITE);
|
||||
|
||||
DrawText("PLACE MOUSE OVER INPUT BOX!", 240, 140, 20, Color.GRAY);
|
||||
DrawRectangleRec(textBox, Color.LIGHTGRAY);
|
||||
|
||||
if (mouseOnText)
|
||||
{
|
||||
DrawRectangleLines(
|
||||
(int)textBox.X,
|
||||
(int)textBox.Y,
|
||||
(int)textBox.Width,
|
||||
(int)textBox.Height,
|
||||
Color.RED
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawRectangleLines(
|
||||
(int)textBox.X,
|
||||
(int)textBox.Y,
|
||||
(int)textBox.Width,
|
||||
(int)textBox.Height,
|
||||
Color.DARKGRAY
|
||||
);
|
||||
}
|
||||
|
||||
DrawText(new string(name), (int)textBox.X + 5, (int)textBox.Y + 8, 40, Color.MAROON);
|
||||
DrawText($"INPUT CHARS: {letterCount}/{MaxInputChars}", 315, 250, 20, Color.DARKGRAY);
|
||||
|
||||
if (mouseOnText)
|
||||
{
|
||||
if (letterCount < MaxInputChars)
|
||||
{
|
||||
// Draw blinking underscore char
|
||||
if ((framesCounter / 20 % 2) == 0)
|
||||
{
|
||||
DrawText(
|
||||
"_",
|
||||
(int)textBox.X + 8 + MeasureText(new string(name), 40),
|
||||
(int)textBox.Y + 12,
|
||||
40,
|
||||
Color.MAROON
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawText("Press BACKSPACE to delete chars...", 230, 300, 20, Color.GRAY);
|
||||
}
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
121
Examples/Text/RaylibFonts.cs
Normal file
121
Examples/Text/RaylibFonts.cs
Normal file
@ -0,0 +1,121 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [text] example - raylib font loading and usage
|
||||
*
|
||||
* NOTE: raylib is distributed with some free to use fonts (even for commercial pourposes!)
|
||||
* To view details and credits for those fonts, check raylib license file
|
||||
*
|
||||
* This example has been created using raylib 1.7 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Text;
|
||||
|
||||
public class RaylibFonts
|
||||
{
|
||||
public const int MaxFonts = 8;
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - raylib fonts");
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
Font[] fonts = new Font[MaxFonts];
|
||||
|
||||
fonts[0] = LoadFont("resources/fonts/alagard.png");
|
||||
fonts[1] = LoadFont("resources/fonts/pixelplay.png");
|
||||
fonts[2] = LoadFont("resources/fonts/mecha.png");
|
||||
fonts[3] = LoadFont("resources/fonts/setback.png");
|
||||
fonts[4] = LoadFont("resources/fonts/romulus.png");
|
||||
fonts[5] = LoadFont("resources/fonts/pixantiqua.png");
|
||||
fonts[6] = LoadFont("resources/fonts/alpha_beta.png");
|
||||
fonts[7] = LoadFont("resources/fonts/jupiter_crash.png");
|
||||
|
||||
string[] messages = new string[MaxFonts] {
|
||||
"ALAGARD FONT designed by Hewett Tsoi",
|
||||
"PIXELPLAY FONT designed by Aleksander Shevchuk",
|
||||
"MECHA FONT designed by Captain Falcon",
|
||||
"SETBACK FONT designed by Brian Kent (AEnigma)",
|
||||
"ROMULUS FONT designed by Hewett Tsoi",
|
||||
"PIXANTIQUA FONT designed by Gerhard Grossmann",
|
||||
"ALPHA_BETA FONT designed by Brian Kent (AEnigma)",
|
||||
"JUPITER_CRASH FONT designed by Brian Kent (AEnigma)"
|
||||
};
|
||||
|
||||
int[] spacings = new int[MaxFonts] { 2, 4, 8, 4, 3, 4, 4, 1 };
|
||||
Vector2[] positions = new Vector2[MaxFonts];
|
||||
|
||||
for (int i = 0; i < MaxFonts; i++)
|
||||
{
|
||||
float halfWidth = MeasureTextEx(fonts[i], messages[i], fonts[i].BaseSize * 2, spacings[i]).X / 2;
|
||||
positions[i].X = screenWidth / 2 - halfWidth;
|
||||
positions[i].Y = 60 + fonts[i].BaseSize + 45 * i;
|
||||
}
|
||||
|
||||
// Small Y position corrections
|
||||
positions[3].Y += 8;
|
||||
positions[4].Y += 2;
|
||||
positions[7].Y -= 8;
|
||||
|
||||
Color[] colors = new Color[MaxFonts] {
|
||||
Color.MAROON,
|
||||
Color.ORANGE,
|
||||
Color.DARKGREEN,
|
||||
Color.DARKBLUE,
|
||||
Color.DARKPURPLE,
|
||||
Color.LIME,
|
||||
Color.GOLD,
|
||||
Color.RED
|
||||
};
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RAYWHITE);
|
||||
|
||||
DrawText("free fonts included with raylib", 250, 20, 20, Color.DARKGRAY);
|
||||
DrawLine(220, 50, 590, 50, Color.DARKGRAY);
|
||||
|
||||
for (int i = 0; i < MaxFonts; i++)
|
||||
{
|
||||
DrawTextEx(fonts[i], messages[i], positions[i], fonts[i].BaseSize * 2, spacings[i], colors[i]);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
for (int i = 0; i < MaxFonts; i++)
|
||||
{
|
||||
UnloadFont(fonts[i]);
|
||||
}
|
||||
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
357
Examples/Text/RectangleBounds.cs
Normal file
357
Examples/Text/RectangleBounds.cs
Normal file
@ -0,0 +1,357 @@
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Text;
|
||||
|
||||
public class RectangleBounds
|
||||
{
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - draw text inside a rectangle");
|
||||
|
||||
string text = "";
|
||||
text += "Text cannot escape this container ...word wrap also works when active so here's a long text for testing.";
|
||||
text += "\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor ";
|
||||
text += "incididunt ut labore et dolore magna aliqua. Nec ullamcorper sit amet risus nullam eget felis eget.";
|
||||
|
||||
bool resizing = false;
|
||||
bool wordWrap = true;
|
||||
|
||||
Rectangle container = new(25, 25, screenWidth - 50, screenHeight - 250);
|
||||
Rectangle resizer = new(
|
||||
container.X + container.Width - 17,
|
||||
container.Y + container.Height - 17,
|
||||
14,
|
||||
14
|
||||
);
|
||||
|
||||
// Minimum width and heigh for the container rectangle
|
||||
const int minWidth = 60;
|
||||
const int minHeight = 60;
|
||||
const int maxWidth = screenWidth - 50;
|
||||
const int maxHeight = screenHeight - 160;
|
||||
|
||||
Vector2 lastMouse = new(0.0f, 0.0f);
|
||||
Color borderColor = Color.MAROON;
|
||||
Font font = GetFontDefault();
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KeyboardKey.KEY_SPACE))
|
||||
{
|
||||
wordWrap = !wordWrap;
|
||||
}
|
||||
|
||||
Vector2 mouse = GetMousePosition();
|
||||
|
||||
// Check if the mouse is inside the container and toggle border color
|
||||
if (CheckCollisionPointRec(mouse, container))
|
||||
{
|
||||
borderColor = ColorAlpha(Color.MAROON, 0.4f);
|
||||
}
|
||||
else if (!resizing)
|
||||
{
|
||||
borderColor = Color.MAROON;
|
||||
}
|
||||
|
||||
// Container resizing logic
|
||||
if (resizing)
|
||||
{
|
||||
if (IsMouseButtonReleased(MouseButton.MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
resizing = false;
|
||||
}
|
||||
|
||||
int width = (int)(container.Width + (mouse.X - lastMouse.X));
|
||||
container.Width = (width > minWidth) ? ((width < maxWidth) ? width : maxWidth) : minWidth;
|
||||
|
||||
int height = (int)(container.Height + (mouse.Y - lastMouse.Y));
|
||||
container.Height = (height > minHeight) ? ((height < maxHeight) ? height : maxHeight) : minHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if we're resizing
|
||||
if (IsMouseButtonDown(MouseButton.MOUSE_LEFT_BUTTON) && CheckCollisionPointRec(mouse, resizer))
|
||||
{
|
||||
resizing = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Move resizer rectangle properly
|
||||
resizer.X = container.X + container.Width - 17;
|
||||
resizer.Y = container.Y + container.Height - 17;
|
||||
|
||||
lastMouse = mouse; // Update mouse
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RAYWHITE);
|
||||
|
||||
// Draw container border
|
||||
DrawRectangleLinesEx(container, 3, borderColor);
|
||||
|
||||
// Draw text in container (add some padding)
|
||||
DrawTextBoxed(
|
||||
font,
|
||||
text,
|
||||
new Rectangle(container.X + 4, container.Y + 4, container.Width - 4, container.Height - 4),
|
||||
20.0f,
|
||||
2.0f,
|
||||
wordWrap,
|
||||
Color.GRAY
|
||||
);
|
||||
|
||||
DrawRectangleRec(resizer, borderColor);
|
||||
|
||||
// Draw bottom info
|
||||
DrawRectangle(0, screenHeight - 54, screenWidth, 54, Color.GRAY);
|
||||
DrawRectangleRec(new Rectangle(382, screenHeight - 34, 12, 12), Color.MAROON);
|
||||
|
||||
DrawText("Word Wrap: ", 313, screenHeight - 115, 20, Color.BLACK);
|
||||
|
||||
if (wordWrap)
|
||||
{
|
||||
DrawText("ON", 447, screenHeight - 115, 20, Color.RED);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawText("OFF", 447, screenHeight - 115, 20, Color.BLACK);
|
||||
}
|
||||
|
||||
DrawText("Press [SPACE] to toggle word wrap", 218, screenHeight - 86, 20, Color.GRAY);
|
||||
DrawText("Click hold & drag the to resize the container", 155, screenHeight - 38, 20, Color.RAYWHITE);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Draw text using font inside rectangle limits
|
||||
static void DrawTextBoxed(
|
||||
Font font,
|
||||
string text,
|
||||
Rectangle rec,
|
||||
float fontSize,
|
||||
float spacing,
|
||||
bool wordWrap,
|
||||
Color tint
|
||||
)
|
||||
{
|
||||
DrawTextBoxedSelectable(font, text, rec, fontSize, spacing, wordWrap, tint, 0, 0, Color.WHITE, Color.WHITE);
|
||||
}
|
||||
|
||||
// Draw text using font inside rectangle limits with support for text selection
|
||||
static unsafe void DrawTextBoxedSelectable(
|
||||
Font font,
|
||||
string text,
|
||||
Rectangle rec,
|
||||
float fontSize,
|
||||
float spacing,
|
||||
bool wordWrap,
|
||||
Color tint,
|
||||
int selectStart,
|
||||
int selectLength,
|
||||
Color selectTint,
|
||||
Color selectBackTint
|
||||
)
|
||||
{
|
||||
int length = text.Length;
|
||||
|
||||
// Offset between lines (on line break '\n')
|
||||
float textOffsetY = 0;
|
||||
|
||||
// Offset X to next character to draw
|
||||
float textOffsetX = 0.0f;
|
||||
|
||||
// Character rectangle scaling factor
|
||||
float scaleFactor = fontSize / (float)font.BaseSize;
|
||||
|
||||
// Word/character wrapping mechanism variables
|
||||
bool shouldMeasure = wordWrap;
|
||||
|
||||
// Index where to begin drawing (where a line begins)
|
||||
int startLine = -1;
|
||||
|
||||
// Index where to stop drawing (where a line ends)
|
||||
int endLine = -1;
|
||||
|
||||
// Holds last value of the character position
|
||||
int lastk = -1;
|
||||
|
||||
using var textNative = new Utf8Buffer(text);
|
||||
|
||||
for (int i = 0, k = 0; i < length; i++, k++)
|
||||
{
|
||||
// Get next codepoint from byte string and glyph index in font
|
||||
int codepointByteCount = 0;
|
||||
int codepoint = GetCodepoint(&textNative.AsPointer()[i], &codepointByteCount);
|
||||
int index = GetGlyphIndex(font, codepoint);
|
||||
|
||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||
// but we need to draw all of the bad bytes using the '?' symbol moving one byte
|
||||
if (codepoint == 0x3f)
|
||||
{
|
||||
codepointByteCount = 1;
|
||||
}
|
||||
|
||||
i += (codepointByteCount - 1);
|
||||
|
||||
float glyphWidth = 0;
|
||||
if (codepoint != '\n')
|
||||
{
|
||||
glyphWidth = (font.Glyphs[index].AdvanceX == 0) ?
|
||||
font.Recs[index].Width * scaleFactor :
|
||||
font.Glyphs[index].AdvanceX * scaleFactor;
|
||||
|
||||
if (i + 1 < length)
|
||||
{
|
||||
glyphWidth = glyphWidth + spacing;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside of
|
||||
// the rec container. We store this info in startLine and endLine, then we change states, draw the text
|
||||
// between those two variables and change states again and again recursively until the end of the text
|
||||
// (or until we get outside of the container). When wordWrap is OFF we don't need the measure state so
|
||||
// we go to the drawing state immediately and begin drawing on the next line before we can get outside
|
||||
// the container.
|
||||
if (shouldMeasure)
|
||||
{
|
||||
// TODO: There are multiple types of spaces in UNICODE, maybe it's a good idea to add support for
|
||||
// more. Ref: http://jkorpela.fi/chars/spaces.html
|
||||
if ((codepoint == ' ') || (codepoint == '\t') || (codepoint == '\n'))
|
||||
{
|
||||
endLine = i;
|
||||
}
|
||||
|
||||
if ((textOffsetX + glyphWidth) > rec.Width)
|
||||
{
|
||||
endLine = (endLine < 1) ? i : endLine;
|
||||
if (i == endLine)
|
||||
{
|
||||
endLine -= codepointByteCount;
|
||||
}
|
||||
if ((startLine + codepointByteCount) == endLine)
|
||||
{
|
||||
endLine = (i - codepointByteCount);
|
||||
}
|
||||
|
||||
shouldMeasure = !shouldMeasure;
|
||||
}
|
||||
else if ((i + 1) == length)
|
||||
{
|
||||
endLine = i;
|
||||
shouldMeasure = !shouldMeasure;
|
||||
}
|
||||
else if (codepoint == '\n')
|
||||
{
|
||||
shouldMeasure = !shouldMeasure;
|
||||
}
|
||||
|
||||
if (!shouldMeasure)
|
||||
{
|
||||
textOffsetX = 0;
|
||||
i = startLine;
|
||||
glyphWidth = 0;
|
||||
|
||||
// Save character position when we switch states
|
||||
int tmp = lastk;
|
||||
lastk = k - 1;
|
||||
k = tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (codepoint == '\n')
|
||||
{
|
||||
if (!wordWrap)
|
||||
{
|
||||
textOffsetY += (font.BaseSize + font.BaseSize / 2) * scaleFactor;
|
||||
textOffsetX = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!wordWrap && ((textOffsetX + glyphWidth) > rec.Width))
|
||||
{
|
||||
textOffsetY += (font.BaseSize + font.BaseSize / 2) * scaleFactor;
|
||||
textOffsetX = 0;
|
||||
}
|
||||
|
||||
// When text overflows rectangle height limit, just stop drawing
|
||||
if ((textOffsetY + font.BaseSize * scaleFactor) > rec.Height)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Draw selection background
|
||||
bool isGlyphSelected = false;
|
||||
if ((selectStart >= 0) && (k >= selectStart) && (k < (selectStart + selectLength)))
|
||||
{
|
||||
DrawRectangleRec(
|
||||
new Rectangle(
|
||||
rec.X + textOffsetX - 1,
|
||||
rec.Y + textOffsetY,
|
||||
glyphWidth,
|
||||
(float)font.BaseSize * scaleFactor
|
||||
),
|
||||
selectBackTint
|
||||
);
|
||||
isGlyphSelected = true;
|
||||
}
|
||||
|
||||
// Draw current character glyph
|
||||
if ((codepoint != ' ') && (codepoint != '\t'))
|
||||
{
|
||||
DrawTextCodepoint(
|
||||
font,
|
||||
codepoint,
|
||||
new Vector2(rec.X + textOffsetX, rec.Y + textOffsetY),
|
||||
fontSize,
|
||||
isGlyphSelected ? selectTint : tint
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (wordWrap && (i == endLine))
|
||||
{
|
||||
textOffsetY += (font.BaseSize + font.BaseSize / 2) * scaleFactor;
|
||||
textOffsetX = 0;
|
||||
startLine = endLine;
|
||||
endLine = -1;
|
||||
glyphWidth = 0;
|
||||
selectStart += lastk - k;
|
||||
k = lastk;
|
||||
|
||||
shouldMeasure = !shouldMeasure;
|
||||
}
|
||||
}
|
||||
|
||||
if ((textOffsetX != 0) || (codepoint != ' '))
|
||||
{
|
||||
// avoid leading spaces
|
||||
textOffsetX += glyphWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
330
Examples/Text/Unicode.cs
Normal file
330
Examples/Text/Unicode.cs
Normal file
@ -0,0 +1,330 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [text] example - Using unicode with raylib
|
||||
*
|
||||
* This example has been created using raylib 2.5 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Copyright (c) 2019 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using Raylib_cs;
|
||||
using static Raylib_cs.Raylib;
|
||||
using static Raylib_cs.Color;
|
||||
|
||||
namespace Examples.Text
|
||||
{
|
||||
public class Unicode
|
||||
{
|
||||
const int EMOJI_PER_WIDTH = 8;
|
||||
const int EMOJI_PER_HEIGHT = 4;
|
||||
|
||||
// String containing 180 emoji codepoints separated by a '\0' char
|
||||
string emojiCodepoints = @"\xF0\x9F\x8C\x80\x00\xF0\x9F\x98\x80\x00\xF0\x9F\x98\x82\x00\xF0\x9F\xA4\xA3\x00\xF0\x9F\x98\x83\x00\xF0\x9F\x98\x86\x00\xF0\x9F\x98\x89\x00"
|
||||
"\xF0\x9F\x98\x8B\x00\xF0\x9F\x98\x8E\x00\xF0\x9F\x98\x8D\x00\xF0\x9F\x98\x98\x00\xF0\x9F\x98\x97\x00\xF0\x9F\x98\x99\x00\xF0\x9F\x98\x9A\x00\xF0\x9F\x99\x82\x00"
|
||||
"\xF0\x9F\xA4\x97\x00\xF0\x9F\xA4\xA9\x00\xF0\x9F\xA4\x94\x00\xF0\x9F\xA4\xA8\x00\xF0\x9F\x98\x90\x00\xF0\x9F\x98\x91\x00\xF0\x9F\x98\xB6\x00\xF0\x9F\x99\x84\x00"
|
||||
"\xF0\x9F\x98\x8F\x00\xF0\x9F\x98\xA3\x00\xF0\x9F\x98\xA5\x00\xF0\x9F\x98\xAE\x00\xF0\x9F\xA4\x90\x00\xF0\x9F\x98\xAF\x00\xF0\x9F\x98\xAA\x00\xF0\x9F\x98\xAB\x00"
|
||||
"\xF0\x9F\x98\xB4\x00\xF0\x9F\x98\x8C\x00\xF0\x9F\x98\x9B\x00\xF0\x9F\x98\x9D\x00\xF0\x9F\xA4\xA4\x00\xF0\x9F\x98\x92\x00\xF0\x9F\x98\x95\x00\xF0\x9F\x99\x83\x00"
|
||||
"\xF0\x9F\xA4\x91\x00\xF0\x9F\x98\xB2\x00\xF0\x9F\x99\x81\x00\xF0\x9F\x98\x96\x00\xF0\x9F\x98\x9E\x00\xF0\x9F\x98\x9F\x00\xF0\x9F\x98\xA4\x00\xF0\x9F\x98\xA2\x00"
|
||||
"\xF0\x9F\x98\xAD\x00\xF0\x9F\x98\xA6\x00\xF0\x9F\x98\xA9\x00\xF0\x9F\xA4\xAF\x00\xF0\x9F\x98\xAC\x00\xF0\x9F\x98\xB0\x00\xF0\x9F\x98\xB1\x00\xF0\x9F\x98\xB3\x00"
|
||||
"\xF0\x9F\xA4\xAA\x00\xF0\x9F\x98\xB5\x00\xF0\x9F\x98\xA1\x00\xF0\x9F\x98\xA0\x00\xF0\x9F\xA4\xAC\x00\xF0\x9F\x98\xB7\x00\xF0\x9F\xA4\x92\x00\xF0\x9F\xA4\x95\x00"
|
||||
"\xF0\x9F\xA4\xA2\x00\xF0\x9F\xA4\xAE\x00\xF0\x9F\xA4\xA7\x00\xF0\x9F\x98\x87\x00\xF0\x9F\xA4\xA0\x00\xF0\x9F\xA4\xAB\x00\xF0\x9F\xA4\xAD\x00\xF0\x9F\xA7\x90\x00"
|
||||
"\xF0\x9F\xA4\x93\x00\xF0\x9F\x98\x88\x00\xF0\x9F\x91\xBF\x00\xF0\x9F\x91\xB9\x00\xF0\x9F\x91\xBA\x00\xF0\x9F\x92\x80\x00\xF0\x9F\x91\xBB\x00\xF0\x9F\x91\xBD\x00"
|
||||
"\xF0\x9F\x91\xBE\x00\xF0\x9F\xA4\x96\x00\xF0\x9F\x92\xA9\x00\xF0\x9F\x98\xBA\x00\xF0\x9F\x98\xB8\x00\xF0\x9F\x98\xB9\x00\xF0\x9F\x98\xBB\x00\xF0\x9F\x98\xBD\x00"
|
||||
"\xF0\x9F\x99\x80\x00\xF0\x9F\x98\xBF\x00\xF0\x9F\x8C\xBE\x00\xF0\x9F\x8C\xBF\x00\xF0\x9F\x8D\x80\x00\xF0\x9F\x8D\x83\x00\xF0\x9F\x8D\x87\x00\xF0\x9F\x8D\x93\x00"
|
||||
"\xF0\x9F\xA5\x9D\x00\xF0\x9F\x8D\x85\x00\xF0\x9F\xA5\xA5\x00\xF0\x9F\xA5\x91\x00\xF0\x9F\x8D\x86\x00\xF0\x9F\xA5\x94\x00\xF0\x9F\xA5\x95\x00\xF0\x9F\x8C\xBD\x00"
|
||||
"\xF0\x9F\x8C\xB6\x00\xF0\x9F\xA5\x92\x00\xF0\x9F\xA5\xA6\x00\xF0\x9F\x8D\x84\x00\xF0\x9F\xA5\x9C\x00\xF0\x9F\x8C\xB0\x00\xF0\x9F\x8D\x9E\x00\xF0\x9F\xA5\x90\x00"
|
||||
"\xF0\x9F\xA5\x96\x00\xF0\x9F\xA5\xA8\x00\xF0\x9F\xA5\x9E\x00\xF0\x9F\xA7\x80\x00\xF0\x9F\x8D\x96\x00\xF0\x9F\x8D\x97\x00\xF0\x9F\xA5\xA9\x00\xF0\x9F\xA5\x93\x00"
|
||||
"\xF0\x9F\x8D\x94\x00\xF0\x9F\x8D\x9F\x00\xF0\x9F\x8D\x95\x00\xF0\x9F\x8C\xAD\x00\xF0\x9F\xA5\xAA\x00\xF0\x9F\x8C\xAE\x00\xF0\x9F\x8C\xAF\x00\xF0\x9F\xA5\x99\x00"
|
||||
"\xF0\x9F\xA5\x9A\x00\xF0\x9F\x8D\xB3\x00\xF0\x9F\xA5\x98\x00\xF0\x9F\x8D\xB2\x00\xF0\x9F\xA5\xA3\x00\xF0\x9F\xA5\x97\x00\xF0\x9F\x8D\xBF\x00\xF0\x9F\xA5\xAB\x00"
|
||||
"\xF0\x9F\x8D\xB1\x00\xF0\x9F\x8D\x98\x00\xF0\x9F\x8D\x9D\x00\xF0\x9F\x8D\xA0\x00\xF0\x9F\x8D\xA2\x00\xF0\x9F\x8D\xA5\x00\xF0\x9F\x8D\xA1\x00\xF0\x9F\xA5\x9F\x00"
|
||||
"\xF0\x9F\xA5\xA1\x00\xF0\x9F\x8D\xA6\x00\xF0\x9F\x8D\xAA\x00\xF0\x9F\x8E\x82\x00\xF0\x9F\x8D\xB0\x00\xF0\x9F\xA5\xA7\x00\xF0\x9F\x8D\xAB\x00\xF0\x9F\x8D\xAF\x00"
|
||||
"\xF0\x9F\x8D\xBC\x00\xF0\x9F\xA5\x9B\x00\xF0\x9F\x8D\xB5\x00\xF0\x9F\x8D\xB6\x00\xF0\x9F\x8D\xBE\x00\xF0\x9F\x8D\xB7\x00\xF0\x9F\x8D\xBB\x00\xF0\x9F\xA5\x82\x00"
|
||||
"\xF0\x9F\xA5\x83\x00\xF0\x9F\xA5\xA4\x00\xF0\x9F\xA5\xA2\x00\xF0\x9F\x91\x81\x00\xF0\x9F\x91\x85\x00\xF0\x9F\x91\x84\x00\xF0\x9F\x92\x8B\x00\xF0\x9F\x92\x98\x00"
|
||||
"\xF0\x9F\x92\x93\x00\xF0\x9F\x92\x97\x00\xF0\x9F\x92\x99\x00\xF0\x9F\x92\x9B\x00\xF0\x9F\xA7\xA1\x00\xF0\x9F\x92\x9C\x00\xF0\x9F\x96\xA4\x00\xF0\x9F\x92\x9D\x00"
|
||||
"\xF0\x9F\x92\x9F\x00\xF0\x9F\x92\x8C\x00\xF0\x9F\x92\xA4\x00\xF0\x9F\x92\xA2\x00\xF0\x9F\x92\xA3\x00";
|
||||
|
||||
struct {
|
||||
string text;
|
||||
string language;
|
||||
}
|
||||
const messages[] = { // Array containing all of the emojis messages
|
||||
{"\x46\x61\x6C\x73\x63\x68\x65\x73\x20\xC3\x9C\x62\x65\x6E\x20\x76\x6F\x6E\x20\x58\x79\x6C\x6F\x70\x68\x6F\x6E\x6D\x75\x73\x69\x6B\x20\x71\x75\xC3\xA4\x6C"
|
||||
"\x74\x20\x6A\x65\x64\x65\x6E\x20\x67\x72\xC3\xB6\xC3\x9F\x65\x72\x65\x6E\x20\x5A\x77\x65\x72\x67", "German"},
|
||||
{"\x42\x65\x69\xC3\x9F\x20\x6E\x69\x63\x68\x74\x20\x69\x6E\x20\x64\x69\x65\x20\x48\x61\x6E\x64\x2C\x20\x64\x69\x65\x20\x64\x69\x63\x68\x20\x66\xC3\xBC\x74"
|
||||
"\x74\x65\x72\x74\x2E", "German"},
|
||||
{"\x41\x75\xC3\x9F\x65\x72\x6F\x72\x64\x65\x6E\x74\x6C\x69\x63\x68\x65\x20\xC3\x9C\x62\x65\x6C\x20\x65\x72\x66\x6F\x72\x64\x65\x72\x6E\x20\x61\x75\xC3\x9F"
|
||||
"\x65\x72\x6F\x72\x64\x65\x6E\x74\x6C\x69\x63\x68\x65\x20\x4D\x69\x74\x74\x65\x6C\x2E", "German"},
|
||||
{"\xD4\xBF\xD6\x80\xD5\xB6\xD5\xA1\xD5\xB4\x20\xD5\xA1\xD5\xBA\xD5\xA1\xD5\xAF\xD5\xAB\x20\xD5\xB8\xD6\x82\xD5\xBF\xD5\xA5\xD5\xAC\x20\xD6\x87\x20\xD5\xAB"
|
||||
"\xD5\xB6\xD5\xAE\xD5\xAB\x20\xD5\xA1\xD5\xB6\xD5\xB0\xD5\xA1\xD5\xB6\xD5\xA3\xD5\xAB\xD5\xBD\xD5\xBF\x20\xD5\xB9\xD5\xA8\xD5\xB6\xD5\xA5\xD6\x80", "Armenian"},
|
||||
{"\xD4\xB5\xD6\x80\xD5\xA2\x20\xD5\xB8\xD6\x80\x20\xD5\xAF\xD5\xA1\xD6\x81\xD5\xAB\xD5\xB6\xD5\xA8\x20\xD5\xA5\xD5\xAF\xD5\xA1\xD6\x82\x20\xD5\xA1\xD5\xB6\xD5"
|
||||
"\xBF\xD5\xA1\xD5\xBC\x2C\x20\xD5\xAE\xD5\xA1\xD5\xBC\xD5\xA5\xD6\x80\xD5\xA8\x20\xD5\xA1\xD5\xBD\xD5\xA1\xD6\x81\xD5\xAB\xD5\xB6\x2E\x2E\x2E\x20\xC2\xAB\xD4\xBF"
|
||||
"\xD5\xB8\xD5\xBF\xD5\xA8\x20\xD5\xB4\xD5\xA5\xD6\x80\xD5\xB8\xD5\xB6\xD6\x81\xD5\xAB\xD6\x81\x20\xD5\xA7\x3A\xC2\xBB", "Armenian"},
|
||||
{"\xD4\xB3\xD5\xA1\xD5\xBC\xD5\xA8\xD5\x9D\x20\xD5\xA3\xD5\xA1\xD6\x80\xD5\xB6\xD5\xA1\xD5\xB6\x2C\x20\xD5\xB1\xD5\xAB\xD6\x82\xD5\xB6\xD5\xA8\xD5\x9D\x20\xD5"
|
||||
"\xB1\xD5\xB4\xD5\xBC\xD5\xA1\xD5\xB6", "Armenian"},
|
||||
{"\x4A\x65\xC5\xBC\x75\x20\x6B\x6C\xC4\x85\x74\x77\x2C\x20\x73\x70\xC5\x82\xC3\xB3\x64\xC5\xBA\x20\x46\x69\x6E\x6F\x6D\x20\x63\x7A\xC4\x99\xC5\x9B\xC4\x87"
|
||||
"\x20\x67\x72\x79\x20\x68\x61\xC5\x84\x62\x21", "Polish"},
|
||||
{"\x44\x6F\x62\x72\x79\x6D\x69\x20\x63\x68\xC4\x99\x63\x69\x61\x6D\x69\x20\x6A\x65\x73\x74\x20\x70\x69\x65\x6B\xC5\x82\x6F\x20\x77\x79\x62\x72\x75\x6B\x6F"
|
||||
"\x77\x61\x6E\x65\x2E", "Polish"},
|
||||
{"\xC3\x8E\xC8\x9B\x69\x20\x6D\x75\x6C\xC8\x9B\x75\x6D\x65\x73\x63\x20\x63\xC4\x83\x20\x61\x69\x20\x61\x6C\x65\x73\x20\x72\x61\x79\x6C\x69\x62\x2E\x0A\xC8\x98"
|
||||
"\x69\x20\x73\x70\x65\x72\x20\x73\xC4\x83\x20\x61\x69\x20\x6F\x20\x7A\x69\x20\x62\x75\x6E\xC4\x83\x21", "Romanian"},
|
||||
{"\xD0\xAD\xD1\x85\x2C\x20\xD1\x87\xD1\x83\xD0\xB6\xD0\xB0\xD0\xBA\x2C\x20\xD0\xBE\xD0\xB1\xD1\x89\xD0\xB8\xD0\xB9\x20\xD1\x81\xD1\x8A\xD1\x91\xD0\xBC\x20"
|
||||
"\xD1\x86\xD0\xB5\xD0\xBD\x20\xD1\x88\xD0\xBB\xD1\x8F\xD0\xBF\x20\x28\xD1\x8E\xD1\x84\xD1\x82\xD1\x8C\x29\x20\xD0\xB2\xD0\xB4\xD1\x80\xD1\x8B\xD0\xB7\xD0\xB3\x21", "Russian"},
|
||||
{"\xD0\xAF\x20\xD0\xBB\xD1\x8E\xD0\xB1\xD0\xBB\xD1\x8E\x20\x72\x61\x79\x6C\x69\x62\x21", "Russian"},
|
||||
{"\xD0\x9C\xD0\xBE\xD0\xBB\xD1\x87\xD0\xB8\x2C\x20\xD1\x81\xD0\xBA\xD1\x80\xD1\x8B\xD0\xB2\xD0\xB0\xD0\xB9\xD1\x81\xD1\x8F\x20\xD0\xB8\x20\xD1\x82\xD0\xB0\xD0\xB8"
|
||||
"\x0A\xD0\x98\x20\xD1\x87\xD1\x83\xD0\xB2\xD1\x81\xD1\x82\xD0\xB2\xD0\xB0\x20\xD0\xB8\x20\xD0\xBC\xD0\xB5\xD1\x87\xD1\x82\xD1\x8B\x20\xD1\x81\xD0\xB2\xD0\xBE\xD0\xB8\x20"
|
||||
"\xE2\x80\x93\x0A\xD0\x9F\xD1\x83\xD1\x81\xD0\xBA\xD0\xB0\xD0\xB9\x20\xD0\xB2\x20\xD0\xB4\xD1\x83\xD1\x88\xD0\xB5\xD0\xB2\xD0\xBD\xD0\xBE\xD0\xB9\x20\xD0\xB3\xD0\xBB\xD1"
|
||||
"\x83\xD0\xB1\xD0\xB8\xD0\xBD\xD0\xB5\x0A\xD0\x98\x20\xD0\xB2\xD1\x81\xD1\x85\xD0\xBE\xD0\xB4\xD1\x8F\xD1\x82\x20\xD0\xB8\x20\xD0\xB7\xD0\xB0\xD0\xB9\xD0\xB4\xD1\x83\xD1"
|
||||
"\x82\x20\xD0\xBE\xD0\xBD\xD0\xB5\x0A\xD0\x9A\xD0\xB0\xD0\xBA\x20\xD0\xB7\xD0\xB2\xD0\xB5\xD0\xB7\xD0\xB4\xD1\x8B\x20\xD1\x8F\xD1\x81\xD0\xBD\xD1\x8B\xD0\xB5\x20\xD0\xB2"
|
||||
"\x20\xD0\xBD\xD0\xBE\xD1\x87\xD0\xB8\x2D\x0A\xD0\x9B\xD1\x8E\xD0\xB1\xD1\x83\xD0\xB9\xD1\x81\xD1\x8F\x20\xD0\xB8\xD0\xBC\xD0\xB8\x20\xE2\x80\x93\x20\xD0\xB8\x20\xD0\xBC"
|
||||
"\xD0\xBE\xD0\xBB\xD1\x87\xD0\xB8\x2E", "Russian"},
|
||||
{"\x56\x6F\x69\x78\x20\x61\x6D\x62\x69\x67\x75\xC3\xAB\x20\x64\xE2\x80\x99\x75\x6E\x20\x63\xC5\x93\x75\x72\x20\x71\x75\x69\x20\x61\x75\x20\x7A\xC3\xA9\x70"
|
||||
"\x68\x79\x72\x20\x70\x72\xC3\xA9\x66\xC3\xA8\x72\x65\x20\x6C\x65\x73\x20\x6A\x61\x74\x74\x65\x73\x20\x64\x65\x20\x6B\x69\x77\x69", "French"},
|
||||
{"\x42\x65\x6E\x6A\x61\x6D\xC3\xAD\x6E\x20\x70\x69\x64\x69\xC3\xB3\x20\x75\x6E\x61\x20\x62\x65\x62\x69\x64\x61\x20\x64\x65\x20\x6B\x69\x77\x69\x20\x79\x20"
|
||||
"\x66\x72\x65\x73\x61\x3B\x20\x4E\x6F\xC3\xA9\x2C\x20\x73\x69\x6E\x20\x76\x65\x72\x67\xC3\xBC\x65\x6E\x7A\x61\x2C\x20\x6C\x61\x20\x6D\xC3\xA1\x73\x20\x65\x78"
|
||||
"\x71\x75\x69\x73\x69\x74\x61\x20\x63\x68\x61\x6D\x70\x61\xC3\xB1\x61\x20\x64\x65\x6C\x20\x6D\x65\x6E\xC3\xBA\x2E", "Spanish"},
|
||||
{"\xCE\xA4\xCE\xB1\xCF\x87\xCE\xAF\xCF\x83\xCF\x84\xCE\xB7\x20\xCE\xB1\xCE\xBB\xCF\x8E\xCF\x80\xCE\xB7\xCE\xBE\x20\xCE\xB2\xCE\xB1\xCF\x86\xCE\xAE\xCF\x82\x20"
|
||||
"\xCF\x88\xCE\xB7\xCE\xBC\xCE\xAD\xCE\xBD\xCE\xB7\x20\xCE\xB3\xCE\xB7\x2C\x20\xCE\xB4\xCF\x81\xCE\xB1\xCF\x83\xCE\xBA\xCE\xB5\xCE\xBB\xCE\xAF\xCE\xB6\xCE\xB5\xCE"
|
||||
"\xB9\x20\xCF\x85\xCF\x80\xCE\xAD\xCF\x81\x20\xCE\xBD\xCF\x89\xCE\xB8\xCF\x81\xCE\xBF\xCF\x8D\x20\xCE\xBA\xCF\x85\xCE\xBD\xCF\x8C\xCF\x82", "Greek"},
|
||||
{"\xCE\x97\x20\xCE\xBA\xCE\xB1\xCE\xBB\xCF\x8D\xCF\x84\xCE\xB5\xCF\x81\xCE\xB7\x20\xCE\xAC\xCE\xBC\xCF\x85\xCE\xBD\xCE\xB1\x20\xCE\xB5\xCE\xAF\xCE\xBD"
|
||||
"\xCE\xB1\xCE\xB9\x20\xCE\xB7\x20\xCE\xB5\xCF\x80\xCE\xAF\xCE\xB8\xCE\xB5\xCF\x83\xCE\xB7\x2E", "Greek"},
|
||||
{"\xCE\xA7\xCF\x81\xCF\x8C\xCE\xBD\xCE\xB9\xCE\xB1\x20\xCE\xBA\xCE\xB1\xCE\xB9\x20\xCE\xB6\xCE\xB1\xCE\xBC\xCE\xAC\xCE\xBD\xCE\xB9\xCE\xB1\x21", "Greek"},
|
||||
{"\xCE\xA0\xCF\x8E\xCF\x82\x20\xCF\x84\xCE\xB1\x20\xCF\x80\xCE\xB1\xCF\x82\x20\xCF\x83\xCE\xAE\xCE\xBC\xCE\xB5\xCF\x81\xCE\xB1\x3B", "Greek"},
|
||||
|
||||
{"\xE6\x88\x91\xE8\x83\xBD\xE5\x90\x9E\xE4\xB8\x8B\xE7\x8E\xBB\xE7\x92\x83\xE8\x80\x8C\xE4\xB8\x8D\xE4\xBC\xA4\xE8\xBA\xAB\xE4\xBD\x93\xE3\x80\x82", "Chinese"},
|
||||
{"\xE4\xBD\xA0\xE5\x90\x83\xE4\xBA\x86\xE5\x90\x97\xEF\xBC\x9F", "Chinese"},
|
||||
{"\xE4\xB8\x8D\xE4\xBD\x9C\xE4\xB8\x8D\xE6\xAD\xBB\xE3\x80\x82", "Chinese"},
|
||||
{"\xE6\x9C\x80\xE8\xBF\x91\xE5\xA5\xBD\xE5\x90\x97\xEF\xBC\x9F", "Chinese"},
|
||||
{"\xE5\xA1\x9E\xE7\xBF\x81\xE5\xA4\xB1\xE9\xA9\xAC\xEF\xBC\x8C\xE7\x84\x89\xE7\x9F\xA5\xE9\x9D\x9E\xE7\xA6\x8F\xE3\x80\x82", "Chinese"},
|
||||
{"\xE5\x8D\x83\xE5\x86\x9B\xE6\x98\x93\xE5\xBE\x97\x2C\x20\xE4\xB8\x80\xE5\xB0\x86\xE9\x9A\xBE\xE6\xB1\x82", "Chinese"},
|
||||
{"\xE4\xB8\x87\xE4\xBA\x8B\xE5\xBC\x80\xE5\xA4\xB4\xE9\x9A\xBE\xE3\x80\x82", "Chinese"},
|
||||
{"\xE9\xA3\x8E\xE6\x97\xA0\xE5\xB8\xB8\xE9\xA1\xBA\xEF\xBC\x8C\xE5\x85\xB5\xE6\x97\xA0\xE5\xB8\xB8\xE8\x83\x9C\xE3\x80\x82", "Chinese"},
|
||||
{"\xE6\xB4\xBB\xE5\x88\xB0\xE8\x80\x81\xEF\xBC\x8C\xE5\xAD\xA6\xE5\x88\xB0\xE8\x80\x81\xE3\x80\x82", "Chinese"},
|
||||
{"\xE4\xB8\x80\xE8\xA8\x80\xE6\x97\xA2\xE5\x87\xBA\xEF\xBC\x8C\xE9\xA9\xB7\xE9\xA9\xAC\xE9\x9A\xBE\xE8\xBF\xBD\xE3\x80\x82", "Chinese"},
|
||||
{"\xE8\xB7\xAF\xE9\x81\xA5\xE7\x9F\xA5\xE9\xA9\xAC\xE5\x8A\x9B\xEF\xBC\x8C\xE6\x97\xA5\xE4\xB9\x85\xE8\xA7\x81\xE4\xBA\xBA\xE5\xBF\x83", "Chinese"},
|
||||
{"\xE6\x9C\x89\xE7\x90\x86\xE8\xB5\xB0\xE9\x81\x8D\xE5\xA4\xA9\xE4\xB8\x8B\xEF\xBC\x8C\xE6\x97\xA0\xE7\x90\x86\xE5\xAF\xB8\xE6\xAD\xA5\xE9\x9A\xBE\xE8\xA1\x8C\xE3\x80\x82", "Chinese"},
|
||||
|
||||
{"\xE7\x8C\xBF\xE3\x82\x82\xE6\x9C\xA8\xE3\x81\x8B\xE3\x82\x89\xE8\x90\xBD\xE3\x81\xA1\xE3\x82\x8B", "Japanese"},
|
||||
{"\xE4\xBA\x80\xE3\x81\xAE\xE7\x94\xB2\xE3\x82\x88\xE3\x82\x8A\xE5\xB9\xB4\xE3\x81\xAE\xE5\x8A\x9F", "Japanese"},
|
||||
{"\xE3\x81\x86\xE3\x82\x89\xE3\x82\x84\xE3\x81\xBE\xE3\x81\x97\x20\x20\xE6\x80\x9D\xE3\x81\xB2\xE5\x88\x87\xE3\x82\x8B\xE6\x99\x82\x20\x20\xE7\x8C\xAB\xE3\x81\xAE\xE6\x81\x8B", "Japanese"},
|
||||
{"\xE8\x99\x8E\xE7\xA9\xB4\xE3\x81\xAB\xE5\x85\xA5\xE3\x82\x89\xE3\x81\x9A\xE3\x82\x93\xE3\x81\xB0\xE8\x99\x8E\xE5\xAD\x90\xE3\x82\x92\xE5\xBE\x97\xE3\x81\x9A\xE3\x80\x82", "Japanese"},
|
||||
{"\xE4\xBA\x8C\xE5\x85\x8E\xE3\x82\x92\xE8\xBF\xBD\xE3\x81\x86\xE8\x80\x85\xE3\x81\xAF\xE4\xB8\x80\xE5\x85\x8E\xE3\x82\x92\xE3\x82\x82\xE5\xBE\x97\xE3\x81\x9A\xE3\x80\x82", "Japanese"},
|
||||
{"\xE9\xA6\xAC\xE9\xB9\xBF\xE3\x81\xAF\xE6\xAD\xBB\xE3\x81\xAA\xE3\x81\xAA\xE3\x81\x8D\xE3\x82\x83\xE6\xB2\xBB\xE3\x82\x89\xE3\x81\xAA\xE3\x81\x84\xE3\x80\x82", "Japanese"},
|
||||
{"\xE6\x9E\xAF\xE9\x87\x8E\xE8\xB7\xAF\xE3\x81\xAB\xE3\x80\x80\xE5\xBD\xB1\xE3\x81\x8B\xE3\x81\x95\xE3\x81\xAA\xE3\x82\x8A\xE3\x81\xA6\xE3\x80\x80\xE3\x82\x8F\xE3\x81\x8B\xE3\x82\x8C\xE3\x81\x91\xE3\x82\x8A", "Japanese"},
|
||||
{"\xE7\xB9\xB0\xE3\x82\x8A\xE8\xBF\x94\xE3\x81\x97\xE9\xBA\xA6\xE3\x81\xAE\xE7\x95\x9D\xE7\xB8\xAB\xE3\x81\xB5\xE8\x83\xA1\xE8\x9D\xB6\xE5\x93\x89", "Japanese"},
|
||||
|
||||
{"\xEC\x95\x84\xEB\x93\x9D\xED\x95\x9C\x20\xEB\xB0\x94\xEB\x8B\xA4\x20\xEC\x9C\x84\xEC\x97\x90\x20\xEA\xB0\x88\xEB\xA7\xA4\xEA\xB8\xB0\x20\xEB\x91\x90\xEC\x97\x87\x20"
|
||||
"\xEB\x82\xA0\xEC\x95\x84\x20\xEB\x8F\x88\xEB\x8B\xA4\x2E\x0A\xEB\x84\x88\xED\x9B\x8C\xEB\x84\x88\xED\x9B\x8C\x20\xEC\x8B\x9C\xEB\xA5\xBC\x20\xEC\x93\xB4\xEB\x8B\xA4\x2E"
|
||||
"\x20\xEB\xAA\xA8\xEB\xA5\xB4\xEB\x8A\x94\x20\xEB\x82\x98\xEB\x9D\xBC\x20\xEA\xB8\x80\xEC\x9E\x90\xEB\x8B\xA4\x2E\x0A\xEB\x84\x90\xEB\x94\xB0\xEB\x9E\x80\x20\xED\x95\x98"
|
||||
"\xEB\x8A\x98\x20\xEB\xB3\xB5\xED\x8C\x90\xEC\x97\x90\x20\xEB\x82\x98\xEB\x8F\x84\x20\xEA\xB0\x99\xEC\x9D\xB4\x20\xEC\x8B\x9C\xEB\xA5\xBC\x20\xEC\x93\xB4\xEB\x8B\xA4\x2E", "Korean"},
|
||||
{"\xEC\xA0\x9C\x20\xEB\x88\x88\xEC\x97\x90\x20\xEC\x95\x88\xEA\xB2\xBD\xEC\x9D\xB4\xEB\x8B\xA4", "Korean"},
|
||||
{"\xEA\xBF\xA9\x20\xEB\xA8\xB9\xEA\xB3\xA0\x20\xEC\x95\x8C\x20\xEB\xA8\xB9\xEB\x8A\x94\xEB\x8B\xA4", "Korean"},
|
||||
{"\xEB\xA1\x9C\xEB\xA7\x88\xEB\x8A\x94\x20\xED\x95\x98\xEB\xA3\xA8\xEC\x95\x84\xEC\xB9\xA8\xEC\x97\x90\x20\xEC\x9D\xB4\xEB\xA3\xA8\xEC\x96\xB4\xEC\xA7\x84\x20\xEA\xB2\x83\xEC\x9D\xB4"
|
||||
"\x20\xEC\x95\x84\xEB\x8B\x88\xEB\x8B\xA4", "Korean"},
|
||||
{"\xEA\xB3\xA0\xEC\x83\x9D\x20\xEB\x81\x9D\xEC\x97\x90\x20\xEB\x82\x99\xEC\x9D\xB4\x20\xEC\x98\xA8\xEB\x8B\xA4", "Korean"},
|
||||
{"\xEA\xB0\x9C\xEC\xB2\x9C\xEC\x97\x90\xEC\x84\x9C\x20\xEC\x9A\xA9\x20\xEB\x82\x9C\xEB\x8B\xA4", "Korean"},
|
||||
{"\xEC\x95\x88\xEB\x85\x95\xED\x95\x98\xEC\x84\xB8\xEC\x9A\x94\x3F", "Korean"},
|
||||
{"\xEB\xA7\x8C\xEB\x82\x98\xEC\x84\x9C\x20\xEB\xB0\x98\xEA\xB0\x91\xEC\x8A\xB5\xEB\x8B\x88\xEB\x8B\xA4", "Korean"},
|
||||
{"\xED\x95\x9C\xEA\xB5\xAD\xEB\xA7\x90\x20\xED\x95\x98\xEC\x8B\xA4\x20\xEC\xA4\x84\x20\xEC\x95\x84\xEC\x84\xB8\xEC\x9A\x94\x3F", "Korean"},
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Module functions declaration
|
||||
//--------------------------------------------------------------------------------------
|
||||
static void RandomizeEmoji(void); // Fills the emoji array with random emojis
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Global variables
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Arrays that holds the random emojis
|
||||
struct emoji
|
||||
{
|
||||
int index; // Index inside `emojiCodepoints`
|
||||
int message; // Message index
|
||||
Color color; // Emoji color
|
||||
}
|
||||
emoji[EMOJI_PER_WIDTH * EMOJI_PER_HEIGHT] = { 0 };
|
||||
|
||||
static int hovered = -1, selected = -1;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - unicode");
|
||||
|
||||
// Load the font resources
|
||||
// NOTE: fontAsian is for asian languages,
|
||||
// fontEmoji is the emojis and fontDefault is used for everything else
|
||||
Font fontDefault = LoadFont("resources/fonts/dejavu.fnt");
|
||||
Font fontAsian = LoadFont("resources/fonts/notoCJK.fnt");
|
||||
Font fontEmoji = LoadFont("resources/fonts/emoji.fnt");
|
||||
|
||||
Vector2 hoveredPos = new(0.0f, 0.0f);
|
||||
Vector2 selectedPos = new(0.0f, 0.0f);
|
||||
|
||||
// Set a random set of emojis when starting up
|
||||
RandomizeEmoji();
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Add a new set of emojis when SPACE is pressed
|
||||
if (IsKeyPressed(KEY_SPACE)) RandomizeEmoji();
|
||||
|
||||
// Set the selected emoji and copy its text to clipboard
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) && (hovered != -1) && (hovered != selected))
|
||||
{
|
||||
selected = hovered;
|
||||
selectedPos = hoveredPos;
|
||||
SetClipboardText(messages[emoji[selected].message].text);
|
||||
}
|
||||
|
||||
Vector2 mouse = GetMousePosition();
|
||||
Vector2 pos = new(28.8f, 10.0f);
|
||||
hovered = -1;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Draw random emojis in the background
|
||||
//------------------------------------------------------------------------------
|
||||
for (int i = 0; i < SIZEOF(emoji); ++i)
|
||||
{
|
||||
const char* txt = ref[emoji[i].index];
|
||||
Rectangle emojiRect = new(pos.X, pos.Y, fontEmoji.BaseSize, fontEmoji.BaseSize);
|
||||
|
||||
if (!CheckCollisionPointRec(mouse, emojiRect))
|
||||
{
|
||||
DrawTextEx(fontEmoji, txt, pos, fontEmoji.BaseSize, 1.0, selected == i ? emoji[i].Color : ColorAlpha(LIGHTGRAY, 0.4f));
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTextEx(fontEmoji, txt, pos, fontEmoji.BaseSize, 1.0, emoji[i].Color);
|
||||
hovered = i;
|
||||
hoveredPos = pos;
|
||||
}
|
||||
|
||||
if ((i != 0) && (i % EMOJI_PER_WIDTH == 0)) { pos.Y += fontEmoji.BaseSize + 24.25f; pos.X = 28.8f; }
|
||||
else pos.X += fontEmoji.BaseSize + 28.8f;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Draw the message when a emoji is selected
|
||||
//------------------------------------------------------------------------------
|
||||
if (selected != -1)
|
||||
{
|
||||
const int message = emoji[selected].message;
|
||||
const int horizontalPadding = 20, verticalPadding = 30;
|
||||
Font* font = ref;
|
||||
|
||||
// Set correct font for asian languages
|
||||
if (TextIsEqual(messages[message].language, "Chinese") ||
|
||||
TextIsEqual(messages[message].language, "Korean") ||
|
||||
TextIsEqual(messages[message].language, "Japanese")) font = ref;
|
||||
|
||||
// Calculate size for the message box (approximate the height and width)
|
||||
Vector2 sz = MeasureTextEx(*font, messages[message].text, font->baseSize, 1.0f);
|
||||
if (sz.X > 300) { sz.Y *= sz.X / 300; sz.X = 300; }
|
||||
else if (sz.X < 160) sz.X = 160;
|
||||
|
||||
Rectangle msgRect = new(selectedPos.X - 38.8f, selectedPos.Y, 2 * horizontalPadding + sz.X, 2 * verticalPadding + sz.Y);
|
||||
msgRect.Y -= msgRect.Height;
|
||||
|
||||
// Coordinates for the chat bubble triangle
|
||||
Vector2 a = new(selectedPos.X, msgRect.Y + msgRect.Height);
|
||||
Vector2 b = new(a.X + 8, a.Y + 10);
|
||||
Vector2 c = new(a.X + 10, a.Y);
|
||||
|
||||
// Don't go outside the screen
|
||||
if (msgRect.X < 10) msgRect.X += 28;
|
||||
if (msgRect.Y < 10)
|
||||
{
|
||||
msgRect.Y = selectedPos.Y + 84;
|
||||
a.Y = msgRect.Y;
|
||||
c.Y = a.Y;
|
||||
b.Y = a.Y - 10;
|
||||
|
||||
// Swap values so we can actually render the triangle :(
|
||||
Vector2 tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
if (msgRect.X + msgRect.Width > screenWidth) msgRect.X -= (msgRect.X + msgRect.Width) - screenWidth + 10;
|
||||
|
||||
// Draw chat bubble
|
||||
DrawRectangleRec(msgRect, emoji[selected].Color);
|
||||
DrawTriangle(a, b, c, emoji[selected].Color);
|
||||
|
||||
// Draw the main text message
|
||||
Rectangle textRect = new(msgRect.X + horizontalPadding / 2, msgRect.Y + verticalPadding / 2, msgRect.Width - horizontalPadding, msgRect.Height);
|
||||
DrawTextRec(*font, messages[message].text, textRect, font->baseSize, 1.0f, true, WHITE);
|
||||
|
||||
// Draw the info text below the main message
|
||||
int size = strlen(messages[message].text);
|
||||
int len = GetCodepointsCount(messages[message].text);
|
||||
const char* info = TextFormat("%s %u characters %i bytes", messages[message].language, len, size);
|
||||
sz = MeasureTextEx(GetFontDefault(), info, 10, 1.0f);
|
||||
Vector2 pos = new(textRect.X + textRect.Width - sz.X, msgRect.Y + msgRect.Height - sz.Y - 2);
|
||||
DrawText(info, pos.X, pos.Y, 10, RAYWHITE);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Draw the info text
|
||||
DrawText("These emojis have something to tell you, click each to find out!", (screenWidth - 650) / 2, screenHeight - 40, 20, GRAY);
|
||||
DrawText("Each emoji is a unicode character from a font, not a texture... Press [SPACEBAR] to refresh", (screenWidth - 484) / 2, screenHeight - 16, 10, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadFont(fontDefault); // Unload font resource
|
||||
UnloadFont(fontAsian); // Unload font resource
|
||||
UnloadFont(fontEmoji); // Unload font resource
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Fills the emoji array with random emoji (only those emojis present in fontEmoji)
|
||||
static void RandomizeEmoji(void)
|
||||
{
|
||||
hovered = selected = -1;
|
||||
int start = GetRandomValue(45, 360);
|
||||
|
||||
for (int i = 0; i < SIZEOF(emoji); ++i)
|
||||
{
|
||||
// 0-179 emoji codepoints (from emoji char array) each 4bytes + null char
|
||||
emoji[i].index = GetRandomValue(0, 179) * 5;
|
||||
|
||||
// Generate a random color for this emoji
|
||||
Vector3 hsv = new((start * (i + 1)) % 360, 0.6f, 0.85f);
|
||||
emoji[i].Color = ColorAlpha(ColorFromHSV(hsv), 0.8f);
|
||||
|
||||
// Set a random message for this emoji
|
||||
emoji[i].message = GetRandomValue(0, SIZEOF(messages) - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
74
Examples/Text/WritingAnim.cs
Normal file
74
Examples/Text/WritingAnim.cs
Normal file
@ -0,0 +1,74 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [text] example - Text Writing Animation
|
||||
*
|
||||
* This example has been created using raylib 1.4 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2016 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Text;
|
||||
|
||||
public class WritingAnim
|
||||
{
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - text writing anim");
|
||||
|
||||
string message = "This sample illustrates a text writing\nanimation effect! Check it out! ;)";
|
||||
int framesCounter = 0;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyDown(KeyboardKey.KEY_SPACE))
|
||||
{
|
||||
framesCounter += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
framesCounter += 1;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.KEY_ENTER))
|
||||
{
|
||||
framesCounter = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RAYWHITE);
|
||||
|
||||
DrawText(message.SubText(0, framesCounter / 10), 210, 160, 20, Color.MAROON);
|
||||
|
||||
DrawText("PRESS [ENTER] to RESTART!", 240, 260, 20, Color.LIGHTGRAY);
|
||||
DrawText("PRESS [SPACE] to SPEED UP!", 239, 300, 20, Color.LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user