Using View - sinusinu/Flora GitHub Wiki
⚠️ Currently View
might have some implementation error because I can't figure things out - If you have a problem, a little help would be greatly appreciated!
What if you want to have a "camera" so you can move, scale, and/or rotate the screen?
or you want to have a fixed-size drawing screen regardless of window size/display resolution?
Flora provides a simple way to do that: View
. Let's take a look!
Begin with Drawing Textures (get your test.png
ready!):
using Flora;
using Flora.Gfx;
using Flora.Util;
namespace FloraTest {
class MyCore : FloraCore {
Texture texture;
View view;
public override void Prepare() {
texture = new Texture(PathUtils.Relative("test.png"));
view = new View(1920, 1080, true);
Gfx.SetView(view);
}
public override void Pause() {
}
public override void Resume() {
}
public override void Resize(int width, int height) {
}
public override void Render(float delta) {
Gfx.Begin();
Gfx.Clear(0, 0, 0);
Gfx.Draw(texture, 0, 0);
Gfx.End();
}
public override void Cleanup() {
texture.Dispose();
}
}
}
new View(1920, 1080, true);
creates a View
with size of 1920 * 1080
, letterboxed.
Newly created View
must be applied to Gfx
by calling Gfx.SetView(view)
.
View
does not need to be disposed.
After applying the view, you can draw just like you did previously; but the texture will be drawn a bit differently.
Without View
, Flora uses top-left origin, and only the area from (0, 0) to (window width, window height) can be seen.
With View
, Flora uses center origin, and area of size given when creating View
can be seen.
Think of it as if there is an infinitely large surface, and you are looking a part of it through the camera.
Visible area of the View
is always at least of given size at its creation. If letterBox
was set to true
, outside the region of given size won't be drawn, enforcing the given aspect ratio. It is good for hiding not-to-be-seen offscreen junks, but the empty areas might be distracting.
View
provides some metrics that can be useful for positioning some elements.
Continue with above program:
using Flora;
using Flora.Gfx;
using Flora.Util;
namespace FloraTest {
class MyCore : FloraCore {
Texture texture;
View view;
public override void Prepare() {
texture = new Texture(PathUtils.Relative("test.png"));
view = new View(1920, 1080, false); // letterBox set to false
Gfx.SetView(view);
}
public override void Pause() {
}
public override void Resume() {
}
public override void Resize(int width, int height) {
}
public override void Render(float delta) {
Gfx.Begin();
Gfx.Clear(0, 0, 0);
Gfx.Draw(texture, view.visibleLeft, view.visibleTop, view.visibleWidth, view.visibleHeight);
Gfx.End();
}
public override void Cleanup() {
texture.Dispose();
}
}
}
This will draw texture
full screen, regardless of window size.
If you can't resize the window, check out the Application Configuration.
View.visibleLeft
and View.visibleTop
gives current most top-left visible position.
These values will be updated in sync when you move the view.
View.visibleWidth
and View.visibleHeight
gives current visible width and height.
If letterBox
is true
, it will be same as the given size on creation. if false
, it will give you a 'stretched' size.
Now what can you do with this View
?
Continue with above program:
using Flora;
using Flora.Gfx;
using Flora.Util;
using System;
namespace FloraTest {
class MyCore : FloraCore {
Texture texture;
View view;
float tmp = 0f;
public override void Prepare() {
texture = new Texture(PathUtils.Relative("test.png"));
view = new View(1280, 720, false);
Gfx.SetView(view);
}
public override void Pause() {
}
public override void Resume() {
}
public override void Resize(int width, int height) {
}
public override void Render(float delta) {
tmp += delta * MathF.PI;
view.positionX = MathF.Cos(tmp) * 300f;
view.positionY = MathF.Sin(tmp) * 300f;
Gfx.Begin();
Gfx.Clear(0, 0, 0);
Gfx.Draw(texture, -view.visibleWidth / 2f, -view.visibleHeight / 2f, view.visibleWidth, view.visibleHeight);
Gfx.End();
}
public override void Cleanup() {
texture.Dispose();
}
}
}
Now texture will move in circle.
Note that the texture is being drawn on position -view.visibleWidth / 2f, -view.visibleHeight / 2f
because view.visibleLeft
and view.visibleTop
gets updated with moving view and using that value here will make texture look like it's not moving.
Continue with above program:
using Flora;
using Flora.Gfx;
using Flora.Util;
using System;
namespace FloraTest {
class MyCore : FloraCore {
Texture texture;
View view;
float tmp = 0f;
public override void Prepare() {
texture = new Texture(PathUtils.Relative("test.png"));
view = new View(1280, 720, false);
Gfx.SetView(view);
}
public override void Pause() {
}
public override void Resume() {
}
public override void Resize(int width, int height) {
}
public override void Render(float delta) {
tmp += delta * MathF.PI;
view.zoom = MathF.Sin(tmp) + 1f;
Gfx.Begin();
Gfx.Clear(0, 0, 0);
Gfx.Draw(texture, -view.visibleWidth / 2f, -view.visibleHeight / 2f, view.visibleWidth, view.visibleHeight);
Gfx.End();
}
public override void Cleanup() {
texture.Dispose();
}
}
}
Now texture will zoom in/out.
View.zoom
accepts positive value, and initial zoom is 1f
.
Continue with above program:
using Flora;
using Flora.Gfx;
using Flora.Util;
using System;
namespace FloraTest {
class MyCore : FloraCore {
Texture texture;
View view;
float tmp = 0f;
public override void Prepare() {
texture = new Texture(PathUtils.Relative("test.png"));
view = new View(1280, 720, false);
Gfx.SetView(view);
}
public override void Pause() {
}
public override void Resume() {
}
public override void Resize(int width, int height) {
}
public override void Render(float delta) {
tmp += delta * MathF.PI * 45f;
view.rotation = tmp;
Gfx.Begin();
Gfx.Clear(0, 0, 0);
Gfx.Draw(texture, -view.visibleWidth / 2f, -view.visibleHeight / 2f, view.visibleWidth, view.visibleHeight);
Gfx.End();
}
public override void Cleanup() {
texture.Dispose();
}
}
}
Now texture will rotate.
View.rotate
is a degree angle, so 180f
will be upside-down and 360f
will be the same as 0f
.