Added FPS2, Sprites & Sprite Editor
This commit is contained in:
parent
7571cd4f12
commit
75cd9d66a0
BIN
FPSSprites/fps_fireball1.spr
Normal file
BIN
FPSSprites/fps_fireball1.spr
Normal file
Binary file not shown.
BIN
FPSSprites/fps_lamp1.spr
Normal file
BIN
FPSSprites/fps_lamp1.spr
Normal file
Binary file not shown.
BIN
FPSSprites/fps_wall1.spr
Normal file
BIN
FPSSprites/fps_wall1.spr
Normal file
Binary file not shown.
376
OneLoneCoder_ComandLineFPS_2.cpp
Normal file
376
OneLoneCoder_ComandLineFPS_2.cpp
Normal file
@ -0,0 +1,376 @@
|
||||
/*
|
||||
OneLoneCoder.com - Upgraded Command Line First Person Shooter (FPS) Engine
|
||||
"Bricks and Lamps people, bricks and lamps..." - @Javidx9
|
||||
|
||||
Disclaimer
|
||||
~~~~~~~~~~
|
||||
I don't care what you use this for. It's intended to be educational, and perhaps
|
||||
to the oddly minded - a little bit of fun. Please hack this, change it and use it
|
||||
in any way you see fit. BUT, you acknowledge that I am not responsible for anything
|
||||
bad that happens as a result of your actions. However, if good stuff happens, I
|
||||
would appreciate a shout out, or at least give the blog some publicity for me.
|
||||
Cheers!
|
||||
|
||||
Background
|
||||
~~~~~~~~~~
|
||||
The FPS video was one of my first youtube videos, and I feel one of my better
|
||||
ones, but its not had the popularity it deserves. So I'm upgrading the engine
|
||||
to make it more appealling.
|
||||
|
||||
IMPORTANT!!
|
||||
~~~~~~~~~~~
|
||||
You'll need the FPSSprites folder too!
|
||||
|
||||
|
||||
Author
|
||||
~~~~~~
|
||||
Twitter: @javidx9
|
||||
Blog: www.onelonecoder.com
|
||||
|
||||
Video:
|
||||
~~~~~~
|
||||
https://youtu.be/HEb2akswCcw
|
||||
|
||||
Last Updated: 23/10/2017
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
#include "olcConsoleGameEngine.h"
|
||||
|
||||
class OneLoneCoder_UltimateFPS : public olcConsoleGameEngine
|
||||
{
|
||||
public:
|
||||
OneLoneCoder_UltimateFPS()
|
||||
{
|
||||
m_sAppName = L"Ultimate First Person Shooter";
|
||||
}
|
||||
|
||||
private:
|
||||
int nMapWidth = 32; // World Dimensions
|
||||
int nMapHeight = 32;
|
||||
|
||||
float fPlayerX = 14.7f; // Player Start Position
|
||||
float fPlayerY = 8;// 5.09f;
|
||||
float fPlayerA = -3.14159f / 2.0f; // Player Start Rotation
|
||||
float fFOV = 3.14159f / 4.0f; // Field of View
|
||||
float fDepth = 16.0f; // Maximum rendering distance
|
||||
float fSpeed = 5.0f; // Walking Speed
|
||||
wstring map;
|
||||
|
||||
olcSprite *spriteWall;
|
||||
olcSprite *spriteLamp;
|
||||
olcSprite *spriteFireBall;
|
||||
|
||||
float *fDepthBuffer = nullptr;
|
||||
|
||||
struct sObject
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float vx;
|
||||
float vy;
|
||||
bool bRemove;
|
||||
olcSprite *sprite;
|
||||
};
|
||||
|
||||
list<sObject> listObjects;
|
||||
|
||||
protected:
|
||||
virtual bool OnUserCreate()
|
||||
{
|
||||
map += L"#########.......#########.......";
|
||||
map += L"#...............#...............";
|
||||
map += L"#.......#########.......########";
|
||||
map += L"#..............##..............#";
|
||||
map += L"#......##......##......##......#";
|
||||
map += L"#......##..............##......#";
|
||||
map += L"#..............##..............#";
|
||||
map += L"###............####............#";
|
||||
map += L"##.............###.............#";
|
||||
map += L"#............####............###";
|
||||
map += L"#..............................#";
|
||||
map += L"#..............##..............#";
|
||||
map += L"#..............##..............#";
|
||||
map += L"#...........#####...........####";
|
||||
map += L"#..............................#";
|
||||
map += L"###..####....########....#######";
|
||||
map += L"####.####.......######..........";
|
||||
map += L"#...............#...............";
|
||||
map += L"#.......#########.......##..####";
|
||||
map += L"#..............##..............#";
|
||||
map += L"#......##......##.......#......#";
|
||||
map += L"#......##......##......##......#";
|
||||
map += L"#..............##..............#";
|
||||
map += L"###............####............#";
|
||||
map += L"##.............###.............#";
|
||||
map += L"#............####............###";
|
||||
map += L"#..............................#";
|
||||
map += L"#..............................#";
|
||||
map += L"#..............##..............#";
|
||||
map += L"#...........##..............####";
|
||||
map += L"#..............##..............#";
|
||||
map += L"################################";
|
||||
|
||||
|
||||
spriteWall = new olcSprite(L"FPSSprites/fps_wall1.spr");
|
||||
spriteLamp = new olcSprite(L"FPSSprites/fps_lamp1.spr");
|
||||
spriteFireBall = new olcSprite(L"FPSSprites/fps_fireball1.spr");
|
||||
fDepthBuffer = new float[ScreenWidth()];
|
||||
|
||||
listObjects = {
|
||||
{ 8.5f, 8.5f, 0.0f, 0.0f, false, spriteLamp },
|
||||
{ 7.5f, 7.5f, 0.0f, 0.0f, false, spriteLamp },
|
||||
{ 10.5f, 3.5f, 0.0f, 0.0f, false, spriteLamp },
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
virtual bool OnUserUpdate(float fElapsedTime)
|
||||
{
|
||||
// Handle CCW Rotation
|
||||
if (m_keys[L'A'].bHeld)
|
||||
fPlayerA -= (fSpeed * 0.5f) * fElapsedTime;
|
||||
|
||||
// Handle CW Rotation
|
||||
if (m_keys[L'D'].bHeld)
|
||||
fPlayerA += (fSpeed * 0.5f) * fElapsedTime;
|
||||
|
||||
// Handle Forwards movement & collision
|
||||
if (m_keys[L'W'].bHeld)
|
||||
{
|
||||
fPlayerX += sinf(fPlayerA) * fSpeed * fElapsedTime;;
|
||||
fPlayerY += cosf(fPlayerA) * fSpeed * fElapsedTime;;
|
||||
if (map.c_str()[(int)fPlayerX * nMapWidth + (int)fPlayerY] == '#')
|
||||
{
|
||||
fPlayerX -= sinf(fPlayerA) * fSpeed * fElapsedTime;;
|
||||
fPlayerY -= cosf(fPlayerA) * fSpeed * fElapsedTime;;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle backwards movement & collision
|
||||
if (m_keys[L'S'].bHeld)
|
||||
{
|
||||
fPlayerX -= sinf(fPlayerA) * fSpeed * fElapsedTime;;
|
||||
fPlayerY -= cosf(fPlayerA) * fSpeed * fElapsedTime;;
|
||||
if (map.c_str()[(int)fPlayerX * nMapWidth + (int)fPlayerY] == '#')
|
||||
{
|
||||
fPlayerX += sinf(fPlayerA) * fSpeed * fElapsedTime;;
|
||||
fPlayerY += cosf(fPlayerA) * fSpeed * fElapsedTime;;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Strafe Right movement & collision
|
||||
if (m_keys[L'E'].bHeld)
|
||||
{
|
||||
fPlayerX += cosf(fPlayerA) * fSpeed * fElapsedTime;
|
||||
fPlayerY -= sinf(fPlayerA) * fSpeed * fElapsedTime;
|
||||
if (map.c_str()[(int)fPlayerX * nMapWidth + (int)fPlayerY] == '#')
|
||||
{
|
||||
fPlayerX -= cosf(fPlayerA) * fSpeed * fElapsedTime;
|
||||
fPlayerY += sinf(fPlayerA) * fSpeed * fElapsedTime;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Strafe Left movement & collision
|
||||
if (m_keys[L'Q'].bHeld)
|
||||
{
|
||||
fPlayerX -= cosf(fPlayerA) * fSpeed * fElapsedTime;
|
||||
fPlayerY += sinf(fPlayerA) * fSpeed * fElapsedTime;
|
||||
if (map.c_str()[(int)fPlayerX * nMapWidth + (int)fPlayerY] == '#')
|
||||
{
|
||||
fPlayerX += cosf(fPlayerA) * fSpeed * fElapsedTime;
|
||||
fPlayerY -= sinf(fPlayerA) * fSpeed * fElapsedTime;
|
||||
}
|
||||
}
|
||||
|
||||
// Fire Bullets
|
||||
if (m_keys[VK_SPACE].bReleased)
|
||||
{
|
||||
sObject o;
|
||||
o.x = fPlayerX;
|
||||
o.y = fPlayerY;
|
||||
float fNoise = (((float)rand() / (float)RAND_MAX) - 0.5f) * 0.1f;
|
||||
o.vx = sinf(fPlayerA + fNoise) * 8.0f;
|
||||
o.vy = cosf(fPlayerA + fNoise) * 8.0f;
|
||||
o.sprite = spriteFireBall;
|
||||
o.bRemove = false;
|
||||
listObjects.push_back(o);
|
||||
}
|
||||
|
||||
for (int x = 0; x < ScreenWidth(); x++)
|
||||
{
|
||||
// For each column, calculate the projected ray angle into world space
|
||||
float fRayAngle = (fPlayerA - fFOV / 2.0f) + ((float)x / (float)ScreenWidth()) * fFOV;
|
||||
|
||||
// Find distance to wall
|
||||
float fStepSize = 0.01f; // Increment size for ray casting, decrease to increase
|
||||
float fDistanceToWall = 0.0f; // resolution
|
||||
|
||||
bool bHitWall = false; // Set when ray hits wall block
|
||||
bool bBoundary = false; // Set when ray hits boundary between two wall blocks
|
||||
|
||||
float fEyeX = sinf(fRayAngle); // Unit vector for ray in player space
|
||||
float fEyeY = cosf(fRayAngle);
|
||||
|
||||
float fSampleX = 0.0f;
|
||||
|
||||
bool bLit = false;
|
||||
|
||||
// Incrementally cast ray from player, along ray angle, testing for
|
||||
// intersection with a block
|
||||
while (!bHitWall && fDistanceToWall < fDepth)
|
||||
{
|
||||
fDistanceToWall += fStepSize;
|
||||
int nTestX = (int)(fPlayerX + fEyeX * fDistanceToWall);
|
||||
int nTestY = (int)(fPlayerY + fEyeY * fDistanceToWall);
|
||||
|
||||
// Test if ray is out of bounds
|
||||
if (nTestX < 0 || nTestX >= nMapWidth || nTestY < 0 || nTestY >= nMapHeight)
|
||||
{
|
||||
bHitWall = true; // Just set distance to maximum depth
|
||||
fDistanceToWall = fDepth;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ray is inbounds so test to see if the ray cell is a wall block
|
||||
if (map.c_str()[nTestX * nMapWidth + nTestY] == '#')
|
||||
{
|
||||
// Ray has hit wall
|
||||
bHitWall = true;
|
||||
|
||||
// Determine where ray has hit wall. Break Block boundary
|
||||
// int 4 line segments
|
||||
float fBlockMidX = (float)nTestX + 0.5f;
|
||||
float fBlockMidY = (float)nTestY + 0.5f;
|
||||
|
||||
float fTestPointX = fPlayerX + fEyeX * fDistanceToWall;
|
||||
float fTestPointY = fPlayerY + fEyeY * fDistanceToWall;
|
||||
|
||||
float fTestAngle = atan2f((fTestPointY - fBlockMidY), (fTestPointX - fBlockMidX));
|
||||
|
||||
if (fTestAngle >= -3.14159f * 0.25f && fTestAngle < 3.14159f * 0.25f)
|
||||
fSampleX = fTestPointY - (float)nTestY;
|
||||
if (fTestAngle >= 3.14159f * 0.25f && fTestAngle < 3.14159f * 0.75f)
|
||||
fSampleX = fTestPointX - (float)nTestX;
|
||||
if (fTestAngle < -3.14159f * 0.25f && fTestAngle >= -3.14159f * 0.75f)
|
||||
fSampleX = fTestPointX - (float)nTestX;
|
||||
if (fTestAngle >= 3.14159f * 0.75f || fTestAngle < -3.14159f * 0.75f)
|
||||
fSampleX = fTestPointY - (float)nTestY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate distance to ceiling and floor
|
||||
int nCeiling = (float)(ScreenHeight() / 2.0) - ScreenHeight() / ((float)fDistanceToWall);
|
||||
int nFloor = ScreenHeight() - nCeiling;
|
||||
|
||||
// Update Depth Buffer
|
||||
fDepthBuffer[x] = fDistanceToWall;
|
||||
|
||||
for (int y = 0; y < ScreenHeight(); y++)
|
||||
{
|
||||
// Each Row
|
||||
if (y <= nCeiling)
|
||||
Draw(x, y, L' ');
|
||||
else if (y > nCeiling && y <= nFloor)
|
||||
{
|
||||
// Draw Wall
|
||||
if (fDistanceToWall < fDepth)
|
||||
{
|
||||
float fSampleY = ((float)y - (float)nCeiling) / ((float)nFloor - (float)nCeiling);
|
||||
Draw(x, y, spriteWall->SampleGlyph(fSampleX, fSampleY), spriteWall->SampleColour(fSampleX, fSampleY));
|
||||
}
|
||||
else
|
||||
Draw(x, y, PIXEL_SOLID, 0);
|
||||
}
|
||||
else // Floor
|
||||
{
|
||||
Draw(x, y, PIXEL_SOLID, FG_DARK_GREEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update & Draw Objects
|
||||
for (auto &object : listObjects)
|
||||
{
|
||||
// Update Object Physics
|
||||
object.x += object.vx * fElapsedTime;
|
||||
object.y += object.vy * fElapsedTime;
|
||||
|
||||
// Check if object is inside wall - set flag for removal
|
||||
if (map.c_str()[(int)object.x * nMapWidth + (int)object.y] == '#')
|
||||
object.bRemove = true;
|
||||
|
||||
// Can object be seen?
|
||||
float fVecX = object.x - fPlayerX;
|
||||
float fVecY = object.y - fPlayerY;
|
||||
float fDistanceFromPlayer = sqrtf(fVecX*fVecX + fVecY*fVecY);
|
||||
|
||||
float fEyeX = sinf(fPlayerA);
|
||||
float fEyeY = cosf(fPlayerA);
|
||||
|
||||
// Calculate angle between lamp and players feet, and players looking direction
|
||||
// to determine if the lamp is in the players field of view
|
||||
float fObjectAngle = atan2f(fEyeY, fEyeX) - atan2f(fVecY, fVecX);
|
||||
if (fObjectAngle < -3.14159f)
|
||||
fObjectAngle += 2.0f * 3.14159f;
|
||||
if (fObjectAngle > 3.14159f)
|
||||
fObjectAngle -= 2.0f * 3.14159f;
|
||||
|
||||
bool bInPlayerFOV = fabs(fObjectAngle) < fFOV / 2.0f;
|
||||
|
||||
if (bInPlayerFOV && fDistanceFromPlayer >= 0.5f && fDistanceFromPlayer < fDepth && !object.bRemove)
|
||||
{
|
||||
float fObjectCeiling = (float)(ScreenHeight() / 2.0) - ScreenHeight() / ((float)fDistanceFromPlayer);
|
||||
float fObjectFloor = ScreenHeight() - fObjectCeiling;
|
||||
float fObjectHeight = fObjectFloor - fObjectCeiling;
|
||||
float fObjectAspectRatio = (float)object.sprite->nHeight / (float)object.sprite->nWidth;
|
||||
float fObjectWidth = fObjectHeight / fObjectAspectRatio;
|
||||
float fMiddleOfObject = (0.5f * (fObjectAngle / (fFOV / 2.0f)) + 0.5f) * (float)ScreenWidth();
|
||||
|
||||
// Draw Lamp
|
||||
for (float lx = 0; lx < fObjectWidth; lx++)
|
||||
{
|
||||
for (float ly = 0; ly < fObjectHeight; ly++)
|
||||
{
|
||||
float fSampleX = lx / fObjectWidth;
|
||||
float fSampleY = ly / fObjectHeight;
|
||||
wchar_t c = object.sprite->SampleGlyph(fSampleX, fSampleY);
|
||||
int nObjectColumn = (int)(fMiddleOfObject + lx - (fObjectWidth / 2.0f));
|
||||
if (nObjectColumn >= 0 && nObjectColumn < ScreenWidth())
|
||||
if (c != L' ' && fDepthBuffer[nObjectColumn] >= fDistanceFromPlayer)
|
||||
{
|
||||
Draw(nObjectColumn, fObjectCeiling + ly, c, object.sprite->SampleColour(fSampleX, fSampleY));
|
||||
fDepthBuffer[nObjectColumn] = fDistanceFromPlayer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove dead objects from object list
|
||||
listObjects.remove_if([](sObject &o) {return o.bRemove; });
|
||||
|
||||
// Display Map & Player
|
||||
for (int nx = 0; nx < nMapWidth; nx++)
|
||||
for (int ny = 0; ny < nMapWidth; ny++)
|
||||
Draw(nx+1, ny+1, map[ny * nMapWidth + nx]);
|
||||
Draw(1 + (int)fPlayerY, 1 + (int)fPlayerX, L'P');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
OneLoneCoder_UltimateFPS game;
|
||||
game.ConstructConsole(320, 240,4,4);
|
||||
game.Start();
|
||||
return 0;
|
||||
}
|
240
OneLoneCoder_SpriteEditor.cpp
Normal file
240
OneLoneCoder_SpriteEditor.cpp
Normal file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
OneLoneCoder.com - Sprite Editor
|
||||
"Stop Crying about Paint ya big baby" - @Javidx9
|
||||
|
||||
Disclaimer
|
||||
~~~~~~~~~~
|
||||
I don't care what you use this for. It's intended to be educational, and perhaps
|
||||
to the oddly minded - a little bit of fun. Please hack this, change it and use it
|
||||
in any way you see fit. BUT, you acknowledge that I am not responsible for anything
|
||||
bad that happens as a result of your actions. However, if good stuff happens, I
|
||||
would appreciate a shout out, or at least give the blog some publicity for me.
|
||||
Cheers!
|
||||
|
||||
Background
|
||||
~~~~~~~~~~
|
||||
Editing ASCII is not a simple as it should be, especially if you want to
|
||||
include all the weird characters
|
||||
|
||||
Controls
|
||||
~~~~~~~~
|
||||
|
||||
|
||||
Author
|
||||
~~~~~~
|
||||
Twitter: @javidx9
|
||||
Blog: www.onelonecoder.com
|
||||
|
||||
Video:
|
||||
~~~~~~
|
||||
Several...
|
||||
|
||||
Last Updated:
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
#include "olcConsoleGameEngine.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class OneLoneCoder_SpriteEditor : public olcConsoleGameEngine
|
||||
{
|
||||
public:
|
||||
OneLoneCoder_SpriteEditor()
|
||||
{
|
||||
m_sAppName = L"Sprite Editor";
|
||||
}
|
||||
|
||||
private:
|
||||
int nPosX = 0;
|
||||
int nPosY = 0;
|
||||
int nOffsetX = 0;
|
||||
int nOffsetY = 0;
|
||||
int nZoom = 4;
|
||||
int nCurrentGlyph = PIXEL_SOLID;
|
||||
int nCurrentColourFG = FG_RED;
|
||||
int nCurrentColourBG = FG_BLACK;
|
||||
|
||||
olcSprite *sprite = nullptr;
|
||||
wstring sCurrentSpriteFile;
|
||||
|
||||
protected:
|
||||
// Called by olcConsoleGameEngine
|
||||
virtual bool OnUserCreate()
|
||||
{
|
||||
sprite = new olcSprite(8, 32);
|
||||
sCurrentSpriteFile = L"fps_fireball1.spr";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called by olcConsoleGameEngine
|
||||
virtual bool OnUserUpdate(float fElapsedTime)
|
||||
{
|
||||
|
||||
// Zooming
|
||||
if (m_keys[VK_PRIOR].bReleased)
|
||||
nZoom <<= 1;
|
||||
|
||||
if (m_keys[VK_NEXT].bReleased)
|
||||
nZoom >>= 1;
|
||||
|
||||
if (nZoom > 32) nZoom = 32;
|
||||
if (nZoom < 2) nZoom = 2;
|
||||
|
||||
// Brushes
|
||||
if (m_keys[VK_F1].bReleased) nCurrentGlyph = PIXEL_SOLID;
|
||||
if (m_keys[VK_F2].bReleased) nCurrentGlyph = PIXEL_THREEQUARTERS;
|
||||
if (m_keys[VK_F3].bReleased) nCurrentGlyph = PIXEL_HALF;
|
||||
if (m_keys[VK_F4].bReleased) nCurrentGlyph = PIXEL_QUARTER;
|
||||
|
||||
// Colours
|
||||
for (int i = 0; i < 8; i++)
|
||||
if (m_keys[L"01234567"[i]].bReleased)
|
||||
if (m_keys[VK_SHIFT].bHeld)
|
||||
nCurrentColourFG = i + 8;
|
||||
else
|
||||
nCurrentColourFG = i;
|
||||
|
||||
|
||||
if (m_keys[VK_F7].bReleased)
|
||||
nCurrentColourBG--;
|
||||
|
||||
if (m_keys[VK_F8].bReleased)
|
||||
nCurrentColourBG++;
|
||||
|
||||
if (nCurrentColourBG < 0) nCurrentColourBG = 15;
|
||||
if (nCurrentColourBG > 15) nCurrentColourBG = 0;
|
||||
|
||||
// Cursing :-)
|
||||
if (m_keys[VK_SHIFT].bHeld)
|
||||
{
|
||||
if (m_keys[VK_UP].bReleased) nOffsetY++;
|
||||
if (m_keys[VK_DOWN].bReleased) nOffsetY--;
|
||||
if (m_keys[VK_LEFT].bReleased) nOffsetX++;
|
||||
if (m_keys[VK_RIGHT].bReleased) nOffsetX--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_keys[VK_UP].bReleased) nPosY--;
|
||||
if (m_keys[VK_DOWN].bReleased) nPosY++;
|
||||
if (m_keys[VK_LEFT].bReleased) nPosX--;
|
||||
if (m_keys[VK_RIGHT].bReleased) nPosX++;
|
||||
}
|
||||
|
||||
if (sprite != nullptr)
|
||||
{
|
||||
if (nPosX < 0) nPosX = 0;
|
||||
if (nPosX >= sprite->nWidth) nPosX = sprite->nWidth - 1;
|
||||
if (nPosY < 0) nPosY = 0;
|
||||
if (nPosY >= sprite->nHeight) nPosY = sprite->nHeight - 1;
|
||||
|
||||
if (m_keys[VK_SPACE].bReleased)
|
||||
{
|
||||
sprite->SetGlyph(nPosX - 0, nPosY - 0, nCurrentGlyph);
|
||||
sprite->SetColour(nPosX - 0, nPosY - 0, nCurrentColourFG | (nCurrentColourBG << 4));
|
||||
}
|
||||
|
||||
if (m_keys[VK_DELETE].bReleased)
|
||||
{
|
||||
sprite->SetGlyph(nPosX - 0, nPosY - 0, L' ');
|
||||
sprite->SetColour(nPosX - 0, nPosY - 0, 0);
|
||||
}
|
||||
|
||||
if (m_keys[VK_F9].bReleased)
|
||||
{
|
||||
sprite->Load(sCurrentSpriteFile);
|
||||
}
|
||||
|
||||
if (m_keys[VK_F10].bReleased)
|
||||
{
|
||||
sprite->Save(sCurrentSpriteFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Erase All
|
||||
Fill(0, 0, ScreenWidth(), ScreenHeight(), L' ', 0);
|
||||
|
||||
// Draw Menu
|
||||
DrawString(1, 1, L"F1 = 100% F2 = 75% F3 = 50% F4 = 25% F9 = Load File F10 = Save File");
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
DrawString(1 + 6 * i, 3, to_wstring(i) + L" = ");
|
||||
if (m_keys[VK_SHIFT].bHeld)
|
||||
Draw(1 + 6 * i + 4, 3, PIXEL_SOLID, (i + 8));
|
||||
else
|
||||
Draw(1 + 6 * i + 4, 3, PIXEL_SOLID, (i));
|
||||
}
|
||||
|
||||
DrawString(1, 5, L"Current Brush = ");
|
||||
Draw(18, 5, nCurrentGlyph, nCurrentColourFG | (nCurrentColourBG << 4));
|
||||
|
||||
// Draw Canvas
|
||||
for (int x = 9; x < 138; x++)
|
||||
{
|
||||
Draw(x, 9);
|
||||
Draw(x, 74);
|
||||
}
|
||||
|
||||
for (int y = 9; y < 75; y++)
|
||||
{
|
||||
Draw(9, y);
|
||||
Draw(138, y);
|
||||
}
|
||||
|
||||
// Draw Visible Sprite
|
||||
if (sprite != nullptr)
|
||||
{
|
||||
int nVisiblePixelsX = 128 / nZoom;
|
||||
int nVisiblePixelsY = 64 / nZoom;
|
||||
|
||||
for (int x = 0; x < nVisiblePixelsX; x++)
|
||||
for (int y = 0; y < nVisiblePixelsY; y++)
|
||||
{
|
||||
if (x - nOffsetX < sprite->nWidth && y - nOffsetY < sprite->nHeight && x - nOffsetX >= 0 && y - nOffsetY >= 0)
|
||||
{
|
||||
// Draw Sprite
|
||||
Fill(x * nZoom + 10, y*nZoom + 10, (x + 1)*nZoom + 10, (y + 1)*nZoom + 10, sprite->GetGlyph(x - nOffsetX, y - nOffsetY), sprite->GetColour(x - nOffsetX, y - nOffsetY));
|
||||
|
||||
|
||||
// Draw Pixel Markers
|
||||
if (sprite->GetGlyph(x - nOffsetX, y - nOffsetY) == L' ')
|
||||
Draw((x)* nZoom + 10, (y)* nZoom + 10, L'.');
|
||||
}
|
||||
|
||||
if (x - nOffsetX == nPosX && y - nOffsetY == nPosY)
|
||||
Draw((x)* nZoom + 10, (y)* nZoom + 10, L'O');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Draw Actual Sprite
|
||||
for (int x = 0; x < sprite->nWidth; x++)
|
||||
for (int y = 0; y < sprite->nHeight; y++)
|
||||
Draw(x + 10, y + 80, sprite->GetGlyph(x, y), sprite->GetColour(x, y));
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
// Use olcConsoleGameEngine derived app
|
||||
OneLoneCoder_SpriteEditor game;
|
||||
game.ConstructConsole(160, 100, 8, 8);
|
||||
game.Start();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user