Merge branch 'brxxh-main'
This commit is contained in:
commit
6abdc90a3a
7 changed files with 336 additions and 112 deletions
19
README.de.md
19
README.de.md
|
@ -1,24 +1,24 @@
|
||||||
# ParadiSO - eine minimale 2D-Grafikengine
|
# ParadiSO - eine minimale 2D-Grafikengine
|
||||||
|
|
||||||
**ParadiSO** wurde als stark abgespeckte 2D-Version meiner `pixwerx`-Engine konzipiert. *ParadiSO* verfolgt einen minimalistischen Ansatz f<>r 2D-Grafik zu Bildungszwecken. Es verwendet modernes C++ und ein datengetriebenes Design, jedoch keine ECS (Entity Component System).
|
**ParadiSO** wurde als stark abgespeckte 2D-Version meiner `pixwerx`-Engine konzipiert. _ParadiSO_ verfolgt einen minimalistischen Ansatz für 2D-Grafik zu Bildungszwecken. Es verwendet modernes C++ und ein datengetriebenes Design, jedoch keine ECS (Entity Component System).
|
||||||
|
|
||||||
## Bildungszwecke
|
## Bildungszwecke
|
||||||
|
|
||||||
Einige Argumente f<EFBFBD>r seinen Bildungsaspekt:
|
Einige Argumente für seinen Bildungsaspekt:
|
||||||
|
|
||||||
- Kombination verschiedener Konzepte und Paradigmen zur Erstellung ausdrucksstarker, aber knappen Codes
|
- Kombination verschiedener Konzepte und Paradigmen zur Erstellung ausdrucksstarker, aber knappen Codes
|
||||||
- Stark von Rust-Code inspiriert
|
- Stark von Rust-Code inspiriert
|
||||||
- F<EFBFBD>r den mathematischen Code wird eine sofortige Auswertung verwendet (keine Expression-Templates), jedoch mit der Verwendung von `constexpr`, um eventuelle Performance-Overheads auszugleichen und optimale Vektorisierung zu erreichen.
|
- Für den mathematischen Code wird eine sofortige Auswertung verwendet (keine Expression-Templates), jedoch mit der Verwendung von `constexpr`, um eventuelle Performance-Overheads auszugleichen und optimale Vektorisierung zu erreichen.
|
||||||
- Versteckt alte `C`-APIs hinter einer modernisierten Fassade
|
- Versteckt alte `C`-APIs hinter einer modernisierten Fassade
|
||||||
- Es lehnt sich stark an die STL und ihre Algorithmen an
|
- Es lehnt sich stark an die STL und ihre Algorithmen an
|
||||||
|
|
||||||
## Minimalistisch
|
## Minimalistisch
|
||||||
|
|
||||||
Da diese Engine einige Muster und Designkonzepte zeigen soll, versucht sie, unn<EFBFBD>tigen Ballast zu vermeiden.
|
Da diese Engine einige Muster und Designkonzepte zeigen soll, versucht sie, unnötigen Ballast zu vermeiden.
|
||||||
|
|
||||||
## Abh<EFBFBD>ngigkeiten
|
## Abhängigkeiten
|
||||||
|
|
||||||
ParadiSO wird mit den notwendigen Komponenten geliefert. Diese sollte jedoch hier erw<EFBFBD>hnt werden:
|
ParadiSO wird mit den notwendigen Komponenten geliefert. Diese sollte jedoch hier erwähnt werden:
|
||||||
|
|
||||||
- [GLFW 3.3.8](https://github.com/glfw/glfw)
|
- [GLFW 3.3.8](https://github.com/glfw/glfw)
|
||||||
- [GLAD](https://github.com/Dav1dde/glad)
|
- [GLAD](https://github.com/Dav1dde/glad)
|
||||||
|
@ -34,7 +34,8 @@ ParadiSO kann auf verschiedenen Plattformen gebaut werden
|
||||||
|
|
||||||
Andere Kombinationen sind möglich aber nicht getestet.
|
Andere Kombinationen sind möglich aber nicht getestet.
|
||||||
|
|
||||||
## Beitr<EFBFBD>ge
|
## Beiträge
|
||||||
|
|
||||||
* [Tim G<>tzelmann](https://code.technotecture.net/Timeplex) Windows Build
|
- [Tim Götzelmann](https://code.technotecture.net/Timeplex) Windows Build
|
||||||
* [Robin Rottst<73>dt](https://code.technotecture.net/robin_rottstaedt) Flappy Bird Clone, Bitmap Loader
|
- [Robin Rottstädt](https://code.technotecture.net/robin_rottstaedt) Flappy Bird Clone, Bitmap Loader
|
||||||
|
- [brxxh](https://code.technotecture.net/brxxh) Flappy Bird Clone
|
||||||
|
|
18
README.md
18
README.md
|
@ -1,16 +1,16 @@
|
||||||
# ParadiSO - a minimal 2D graphics engine
|
# ParadiSO - a minimal 2D graphics engine
|
||||||
|
|
||||||
**ParadiSO** was conceived as a heavily stripped down 2D version of my `pixwerx` engine. *ParadiSO* mimics a minimalistic approach to 2D graphics for educational purposes. It uses modern C++ and a data-driven design, but no ECS.
|
**ParadiSO** was conceived as a heavily stripped down 2D version of my `pixwerx` engine. _ParadiSO_ mimics a minimalistic approach to 2D graphics for educational purposes. It uses modern C++ and a data-driven design, but no ECS.
|
||||||
|
|
||||||
## Educational
|
## Educational
|
||||||
|
|
||||||
Some arguments for its educational side:
|
Some arguments for its educational side:
|
||||||
|
|
||||||
* mix and match of various concepts and paradigms to write expressive but concise code
|
- mix and match of various concepts and paradigms to write expressive but concise code
|
||||||
* heavily inspired by Rust code
|
- heavily inspired by Rust code
|
||||||
* math code is eager evaluation but `constexpr` to compensate overheads
|
- math code is eager evaluation but `constexpr` to compensate overheads
|
||||||
* hides old-style `C` APIs behind a renovated facade
|
- hides old-style `C` APIs behind a renovated facade
|
||||||
* it leans heavily on the STL and its algorithms
|
- it leans heavily on the STL and its algorithms
|
||||||
|
|
||||||
## Minimal
|
## Minimal
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@ ParadiSO is being developed to work on all major desktop systems.
|
||||||
|
|
||||||
Other combinations might work but are untested.
|
Other combinations might work but are untested.
|
||||||
|
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
* [Tim Götzelmann](https://code.technotecture.net/Timeplex) Windows Build
|
- [Tim Götzelmann](https://code.technotecture.net/Timeplex) Windows Build
|
||||||
* [Robin Rottstädt](https://code.technotecture.net/robin_rottstaedt) Flappy Bird Clone, Bitmap Loader
|
- [Robin Rottstädt](https://code.technotecture.net/robin_rottstaedt) Flappy Bird Clone, Bitmap Loader
|
||||||
|
- [brxxh](https://code.technotecture.net/brxxh) Flappy Bird Clone
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 10 KiB |
Binary file not shown.
Before Width: | Height: | Size: 470 B After Width: | Height: | Size: 1.9 KiB |
BIN
examples/quickwings/assets/gameover.png
Normal file
BIN
examples/quickwings/assets/gameover.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 758 B |
BIN
examples/quickwings/assets/message.png
Normal file
BIN
examples/quickwings/assets/message.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
|
@ -1,10 +1,14 @@
|
||||||
/**
|
/**
|
||||||
* paradiso - Paradigmen der Softwareentwicklung
|
* paradiso - Paradigmen der Softwareentwicklung
|
||||||
*
|
*
|
||||||
* (c) Copyright 2023 Hartmut Seichter, Robin Rottstädt
|
* (c) Copyright 2023 Hartmut Seichter, Robin Rottstädt, brxxh (Hannes Brothuhn)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <bits/iterator_concepts.h>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <ostream>
|
||||||
#include <paradiso/bitmap.hpp>
|
#include <paradiso/bitmap.hpp>
|
||||||
#include <paradiso/bitmap_io.hpp>
|
#include <paradiso/bitmap_io.hpp>
|
||||||
#include <paradiso/context.hpp>
|
#include <paradiso/context.hpp>
|
||||||
|
@ -20,10 +24,19 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
// #include "lib/image_loader.hpp"
|
// #include "lib/image_loader.hpp"
|
||||||
|
|
||||||
const int frame_rate = 60;
|
const int frame_rate = 60;
|
||||||
|
bool game_over = false;
|
||||||
|
float risky_pos_x;
|
||||||
|
float risky_pos_max_x;
|
||||||
|
float risky_pos_bottom_y;
|
||||||
|
float risky_pos_top_y;
|
||||||
|
float risky_pos_bottom_max_y;
|
||||||
|
float risky_pos_top_max_y;
|
||||||
|
|
||||||
struct Background {
|
struct Background {
|
||||||
paradiso::Sprite backgroundLeft;
|
paradiso::Sprite backgroundLeft;
|
||||||
|
@ -33,81 +46,179 @@ struct Background {
|
||||||
|
|
||||||
paradiso::Sprite* scrolling[2] = {&backgroundLeft, &backgroundRight};
|
paradiso::Sprite* scrolling[2] = {&backgroundLeft, &backgroundRight};
|
||||||
|
|
||||||
|
paradiso::Renderer renderer{};
|
||||||
|
|
||||||
Background() {
|
Background() {
|
||||||
auto backgroundImage =
|
auto backgroundImage =
|
||||||
paradiso::BitmapIO::get().load("background-day.png");
|
paradiso::BitmapIO::get().load("background-day.png");
|
||||||
backgroundLeft = paradiso::Sprite{
|
backgroundLeft = paradiso::Sprite{
|
||||||
.bitmap = backgroundImage,
|
.bitmap = backgroundImage,
|
||||||
.pivot = paradiso::Vector2<float>::make(0.0f, 0.0f),
|
.pivot = {paradiso::Vector2<float>::make(0.0f, 0.16f)},
|
||||||
.scale = paradiso::Vector2<float>::make(1.01f, 1.0f)};
|
.scale = {paradiso::Vector2<float>::make(1.01f, 1.3f)}};
|
||||||
backgroundRight = paradiso::Sprite{
|
backgroundRight = paradiso::Sprite{
|
||||||
.bitmap = backgroundImage,
|
.bitmap = backgroundImage,
|
||||||
.pivot = paradiso::Vector2<float>::make(2.0f, 0.0f),
|
.pivot = {paradiso::Vector2<float>::make(2.018f, 0.16f)},
|
||||||
.scale = paradiso::Vector2<float>::make(1.01f, 1.0f)};
|
.scale = {paradiso::Vector2<float>::make(1.01f, 1.3f)}};
|
||||||
|
|
||||||
auto grassImage = paradiso::BitmapIO::get().load("base.png");
|
auto grassImage = paradiso::BitmapIO::get().load("base.png");
|
||||||
grassLeft = paradiso::Sprite{
|
grassLeft = paradiso::Sprite{
|
||||||
.bitmap = grassImage,
|
.bitmap = grassImage,
|
||||||
.pivot = paradiso::Vector2<float>::make(0.0f, -1.0f),
|
.pivot = {paradiso::Vector2<float>::make(0.0f, -1.0f)},
|
||||||
.scale = paradiso::Vector2<float>::make(1.0f, 0.33333f)};
|
.scale = {paradiso::Vector2<float>::make(1.0f, 0.33333f)}};
|
||||||
grassRight = paradiso::Sprite{
|
grassRight = paradiso::Sprite{
|
||||||
.bitmap = grassImage,
|
.bitmap = grassImage,
|
||||||
.pivot = paradiso::Vector2<float>::make(2.0f, -1.0f),
|
.pivot = {paradiso::Vector2<float>::make(2.0f, -1.0f)},
|
||||||
.scale = paradiso::Vector2<float>::make(1.0f, 0.33333f)};
|
.scale = {paradiso::Vector2<float>::make(1.0f, 0.33333f)}};
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(const paradiso::Shader& shader) {
|
void draw(const paradiso::Shader& shader) {
|
||||||
for (auto sprite : scrolling) {
|
for (auto sprite : scrolling) {
|
||||||
|
if (game_over == false) {
|
||||||
if (sprite->pivot.x() <= -2.0f) {
|
if (sprite->pivot.x() <= -2.0f) {
|
||||||
sprite->pivot.x() += 4.0f;
|
sprite->pivot.x() += 4.0f;
|
||||||
}
|
}
|
||||||
sprite->pivot.x() -= 0.001f;
|
sprite->pivot.x() -= 0.002f;
|
||||||
|
}
|
||||||
shader.set_uniform("pivot", sprite->pivot);
|
shader.set_uniform("pivot", sprite->pivot);
|
||||||
shader.set_uniform("scale", sprite->scale);
|
shader.set_uniform("scale", sprite->scale);
|
||||||
shader.set_uniform("rotation", sprite->rotation);
|
shader.set_uniform("rotation", sprite->rotation);
|
||||||
renderer.draw(*sprite, shader);
|
renderer.draw(*sprite, shader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
paradiso::Renderer renderer{};
|
struct Pipe {
|
||||||
|
paradiso::Sprite pipe_top;
|
||||||
|
paradiso::Sprite pipe_bottom;
|
||||||
|
|
||||||
|
paradiso::Renderer renderer1{};
|
||||||
|
paradiso::Renderer renderer2{};
|
||||||
|
|
||||||
|
bool paused = false;
|
||||||
|
|
||||||
|
int pipe_spawn_rand_int = rand() % 80 + 15;
|
||||||
|
float pipe_spawn_rand = float(pipe_spawn_rand_int) / 100;
|
||||||
|
|
||||||
|
bool pos_reset = false;
|
||||||
|
|
||||||
|
Pipe() {
|
||||||
|
auto pipe_image = paradiso::BitmapIO::get().load("pipe-green.png");
|
||||||
|
|
||||||
|
pipe_top = paradiso::Sprite{
|
||||||
|
.bitmap = pipe_image,
|
||||||
|
.pivot = {paradiso::Vector2<float>::make(1.4f, pipe_spawn_rand + 1.0f)},
|
||||||
|
.scale = {paradiso::Vector2<float>::make(((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 320.0f)) / 700.0f) * 2.25f)},
|
||||||
|
.rotation = 3.1415926f};
|
||||||
|
pipe_bottom = paradiso::Sprite{
|
||||||
|
.bitmap = pipe_image,
|
||||||
|
.pivot = {paradiso::Vector2<float>::make(1.4f, pipe_spawn_rand - 1.5f)},
|
||||||
|
.scale = {paradiso::Vector2<float>::make(((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 320.0f)) / 700.0f) * 2.25f)}};
|
||||||
|
|
||||||
|
paused = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() {
|
||||||
|
|
||||||
|
if (game_over == true) {
|
||||||
|
paused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (paused == true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pipe_spawn_rand_int = rand() % 80 + 15;
|
||||||
|
pipe_spawn_rand = float(pipe_spawn_rand_int) / 100;
|
||||||
|
|
||||||
|
pipe_top.pivot.x() -= 0.02f;
|
||||||
|
pipe_bottom.pivot.x() -= 0.02f;
|
||||||
|
|
||||||
|
risky_pos_x = pipe_top.pivot.x();
|
||||||
|
risky_pos_max_x = pipe_top.pivot.x() + ((500.0f - (500.0f - 52.0f)) / 500.0f) * 2.25f;
|
||||||
|
|
||||||
|
risky_pos_top_y = pipe_top.pivot.y();
|
||||||
|
risky_pos_top_max_y = pipe_top.pivot.y() + 10.0f;
|
||||||
|
|
||||||
|
risky_pos_bottom_y = pipe_bottom.pivot.y();
|
||||||
|
risky_pos_bottom_max_y = pipe_bottom.pivot.y() - 10.0f;
|
||||||
|
|
||||||
|
if (pipe_top.pivot.x() <= -1.4f || pipe_bottom.pivot.x() <= -1.4f) {
|
||||||
|
pos_reset = true;
|
||||||
|
|
||||||
|
if (pos_reset == true) {
|
||||||
|
pipe_top.pivot.y() = pipe_spawn_rand + 1.0f;
|
||||||
|
pipe_bottom.pivot.y() = pipe_spawn_rand - 1.5;
|
||||||
|
|
||||||
|
pos_reset = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pipe_top.pivot.x() = 1.4f;
|
||||||
|
pipe_bottom.pivot.x() = 1.4f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw(const paradiso::Shader& shader) {
|
||||||
|
shader.set_uniform("pivot", pipe_bottom.pivot);
|
||||||
|
shader.set_uniform("scale", pipe_bottom.scale);
|
||||||
|
renderer1.draw(pipe_bottom, shader);
|
||||||
|
|
||||||
|
shader.set_uniform("pivot", pipe_top.pivot);
|
||||||
|
shader.set_uniform("scale", pipe_top.scale);
|
||||||
|
shader.set_uniform("rotation", pipe_top.rotation);
|
||||||
|
renderer1.draw(pipe_top, shader);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Grass {
|
struct Grass {
|
||||||
paradiso::Sprite grassLeft;
|
paradiso::Sprite grassLeft;
|
||||||
paradiso::Sprite grassRight;
|
paradiso::Sprite grassRight;
|
||||||
|
|
||||||
paradiso::Sprite* scrolling[2] = {&grassLeft, &grassRight};
|
paradiso::Sprite* scrolling[2] = {&grassLeft, &grassRight};
|
||||||
|
|
||||||
|
paradiso::Renderer renderer1{};
|
||||||
|
paradiso::Renderer renderer2{};
|
||||||
|
|
||||||
Grass() {
|
Grass() {
|
||||||
auto grassImage = paradiso::BitmapIO::get().load(std::string("base.png"));
|
auto grassImage = paradiso::BitmapIO::get().load("base.png");
|
||||||
grassLeft = paradiso::Sprite{
|
grassLeft = paradiso::Sprite{
|
||||||
.bitmap = grassImage,
|
.bitmap = grassImage,
|
||||||
.pivot = paradiso::Vector2<float>::make(0.0f, -0.9f),
|
.pivot = {paradiso::Vector2<float>::make(0.0f, -0.9f)},
|
||||||
.scale = paradiso::Vector2<float>::make(1.0f, 0.33333f)};
|
.scale = {paradiso::Vector2<float>::make(((500.0f - (500.0f - 504.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 112.0f)) / 700.0f) * 2.25f)}};
|
||||||
grassRight = paradiso::Sprite{
|
grassRight = paradiso::Sprite{
|
||||||
.bitmap = grassImage,
|
.bitmap = grassImage,
|
||||||
.pivot = paradiso::Vector2<float>::make(2.0f, -0.9f),
|
.pivot = {paradiso::Vector2<float>::make(1.002f, -0.9f)},
|
||||||
.scale = paradiso::Vector2<float>::make(1.0f, 0.33333f)};
|
.scale = {paradiso::Vector2<float>::make(((500.0f - (500.0f - 504.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 112.0f)) / 700.0f) * 2.25f)}};
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(const paradiso::Shader& shader) {
|
void draw(const paradiso::Shader& shader) {
|
||||||
for (auto sprite : scrolling) {
|
if (game_over == false) {
|
||||||
if (sprite->pivot.x() <= -2.0f) {
|
grassLeft.pivot.x() -= 0.02f;
|
||||||
sprite->pivot.x() += 4.0f;
|
grassRight.pivot.x() -= 0.02f;
|
||||||
|
|
||||||
|
if (grassRight.pivot.x() <= 0.0f) {
|
||||||
|
grassLeft.pivot.x() = 1.002f;
|
||||||
}
|
}
|
||||||
sprite->pivot.x() -= 0.035f;
|
if (grassRight.pivot.x() <= -1.002f) {
|
||||||
shader.set_uniform("pivot", sprite->pivot);
|
grassRight.pivot.x() = 1.002f;
|
||||||
shader.set_uniform("scale", sprite->scale);
|
|
||||||
shader.set_uniform("rotation", sprite->rotation);
|
|
||||||
renderer.draw(*sprite, shader);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
paradiso::Renderer renderer{};
|
shader.set_uniform("pivot", grassLeft.pivot);
|
||||||
|
shader.set_uniform("scale", grassLeft.scale);
|
||||||
|
shader.set_uniform("rotation", grassLeft.rotation);
|
||||||
|
|
||||||
|
shader.set_uniform("pivot", grassRight.pivot);
|
||||||
|
shader.set_uniform("scale", grassRight.scale);
|
||||||
|
shader.set_uniform("rotation", grassRight.rotation);
|
||||||
|
|
||||||
|
renderer1.draw(grassLeft, shader);
|
||||||
|
renderer2.draw(grassRight, shader);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QuickWings {
|
|
||||||
|
|
||||||
|
struct QuickWings {
|
||||||
paradiso::Renderer renderer1{};
|
paradiso::Renderer renderer1{};
|
||||||
paradiso::Renderer renderer2{};
|
paradiso::Renderer renderer2{};
|
||||||
paradiso::Renderer renderer3{};
|
paradiso::Renderer renderer3{};
|
||||||
|
@ -118,10 +229,10 @@ struct QuickWings {
|
||||||
unsigned int flapCounter = 0; // How many ticks since last flap
|
unsigned int flapCounter = 0; // How many ticks since last flap
|
||||||
|
|
||||||
float velocity = 0.0f;
|
float velocity = 0.0f;
|
||||||
const float max_velocity = 0.05f;
|
const float max_velocity = 0.02f;
|
||||||
|
|
||||||
const float gravity = -0.004f;
|
const float gravity = -0.002f;
|
||||||
const float move_up_velocity = 0.0055f;
|
const float move_up_velocity = 0.02f;
|
||||||
|
|
||||||
bool move_up = false;
|
bool move_up = false;
|
||||||
bool paused = true;
|
bool paused = true;
|
||||||
|
@ -129,30 +240,32 @@ struct QuickWings {
|
||||||
const float max_pos = 0.95f;
|
const float max_pos = 0.95f;
|
||||||
const float min_pos = -0.5f;
|
const float min_pos = -0.5f;
|
||||||
|
|
||||||
float pos = 0.0f;
|
float pos = 0.34f;
|
||||||
|
|
||||||
float rotation = 0.0f;
|
float rotation = 0.0f;
|
||||||
|
|
||||||
|
int collision_counter = 0;
|
||||||
|
|
||||||
QuickWings() {
|
QuickWings() {
|
||||||
float scaleh = 0.07f;
|
float scaleh = 0.08f;
|
||||||
float scalew = scaleh * 1.416666666666667f;
|
float scalew = 0.158f;
|
||||||
|
|
||||||
birds = {
|
birds = {
|
||||||
paradiso::Sprite{
|
paradiso::Sprite{
|
||||||
.bitmap =
|
.bitmap =
|
||||||
paradiso::BitmapIO::get().load("yellowbird-downflap.png"),
|
paradiso::BitmapIO::get().load("yellowbird-downflap.png"),
|
||||||
.pivot = paradiso::Vector2<float>::make(0.0f, 0.0f),
|
.pivot = {paradiso::Vector2<float>::make(0.0f, 0.0f)},
|
||||||
.scale = paradiso::Vector2<float>::make(scalew, scaleh)},
|
.scale = {paradiso::Vector2<float>::make(scalew, scaleh)}},
|
||||||
paradiso::Sprite{
|
paradiso::Sprite{
|
||||||
.bitmap =
|
.bitmap =
|
||||||
paradiso::BitmapIO::get().load("yellowbird-midflap.png"),
|
paradiso::BitmapIO::get().load("yellowbird-midflap.png"),
|
||||||
.pivot = paradiso::Vector2<float>::make(0.0f, 0.0f),
|
.pivot = {paradiso::Vector2<float>::make(0.0f, 0.0f)},
|
||||||
.scale = paradiso::Vector2<float>::make(scalew, scaleh)},
|
.scale = {paradiso::Vector2<float>::make(scalew, scaleh)}},
|
||||||
paradiso::Sprite{
|
paradiso::Sprite{
|
||||||
.bitmap =
|
.bitmap =
|
||||||
paradiso::BitmapIO::get().load("yellowbird-upflap.png"),
|
paradiso::BitmapIO::get().load("yellowbird-upflap.png"),
|
||||||
.pivot = paradiso::Vector2<float>::make(0.0f, 0.0f),
|
.pivot = {paradiso::Vector2<float>::make(0.0f, 0.0f)},
|
||||||
.scale = paradiso::Vector2<float>::make(scalew, scaleh)}};
|
.scale = {paradiso::Vector2<float>::make(scalew, scaleh)}}};
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(const paradiso::Shader& shader) {
|
void draw(const paradiso::Shader& shader) {
|
||||||
|
@ -185,10 +298,16 @@ struct QuickWings {
|
||||||
}
|
}
|
||||||
|
|
||||||
void update() {
|
void update() {
|
||||||
// Stop game
|
|
||||||
if (paused)
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
if (game_over == true) {
|
||||||
|
paused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop game
|
||||||
|
if (paused) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
// Apply gravity
|
// Apply gravity
|
||||||
velocity += gravity;
|
velocity += gravity;
|
||||||
|
|
||||||
|
@ -206,20 +325,46 @@ struct QuickWings {
|
||||||
if (pos < min_pos) {
|
if (pos < min_pos) {
|
||||||
pos = min_pos;
|
pos = min_pos;
|
||||||
velocity = 0.0f;
|
velocity = 0.0f;
|
||||||
|
game_over = true;
|
||||||
}
|
}
|
||||||
if (pos > max_pos) {
|
if (pos > max_pos) {
|
||||||
pos = max_pos;
|
pos = max_pos;
|
||||||
velocity = 0.0f;
|
velocity = 0.0f;
|
||||||
|
game_over = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update rotation
|
// Update rotation
|
||||||
rotation = velocity * 15.0f;
|
rotation = velocity * 10.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float final_risky_pos_top_y = risky_pos_top_y - 1.06f;
|
||||||
|
float final_risky_pos_bottom_y = risky_pos_bottom_y + 1.06f;
|
||||||
|
|
||||||
|
if (risky_pos_x - 0.3f <= 0.0f && risky_pos_max_x >= 0.0f) {
|
||||||
|
if (pos >= final_risky_pos_top_y && pos <= risky_pos_top_max_y) {
|
||||||
|
game_over = true;
|
||||||
|
}
|
||||||
|
if (pos <= final_risky_pos_bottom_y && pos >= risky_pos_bottom_max_y) {
|
||||||
|
if (collision_counter == 0) {
|
||||||
|
collision_counter++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
collision_counter = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (collision_counter == 2) {
|
||||||
|
game_over = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// keyboard handler
|
// keyboard handler
|
||||||
void on_keyboard(const paradiso::Window::KeyboardInputStack& input) {
|
void on_keyboard(const paradiso::Window::KeyboardInputStack& input) {
|
||||||
if (input.size()) {
|
if (input.size()) {
|
||||||
paused = false;
|
paused = false;
|
||||||
|
|
||||||
|
if (paused == false) {
|
||||||
bool pressed_up = input.top().key == ' ' || input.top().key == 'W';
|
bool pressed_up = input.top().key == ' ' || input.top().key == 'W';
|
||||||
|
|
||||||
if (input.top().action == 1 && pressed_up) {
|
if (input.top().action == 1 && pressed_up) {
|
||||||
|
@ -228,10 +373,69 @@ struct QuickWings {
|
||||||
move_up = false;
|
move_up = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Message {
|
||||||
|
paradiso::Sprite messageSprite;
|
||||||
|
paradiso::Renderer renderer{};
|
||||||
|
bool start = false;
|
||||||
|
float pos = 100.0f;
|
||||||
|
|
||||||
|
Message() {
|
||||||
|
auto messageImage = paradiso::BitmapIO::get().load("message.png");
|
||||||
|
messageSprite = paradiso::Sprite{
|
||||||
|
.bitmap = messageImage,
|
||||||
|
.pivot = {paradiso::Vector2<float>::make(0.0f, 0.0f)},
|
||||||
|
.scale = {paradiso::Vector2<float>::make(0.8f, 0.8f)}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
void draw(const paradiso::Shader& shader) {
|
||||||
|
shader.set_uniform("pivot", messageSprite.pivot);
|
||||||
|
shader.set_uniform("scale", messageSprite.scale);
|
||||||
|
renderer.draw(messageSprite, shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() {
|
||||||
|
if (start == true) {
|
||||||
|
messageSprite.pivot.y() = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_keyboard(const paradiso::Window::KeyboardInputStack& input) {
|
||||||
|
if (input.size()) {
|
||||||
|
start = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GameOverMessage {
|
||||||
|
paradiso::Sprite messageSprite;
|
||||||
|
paradiso::Renderer renderer{};
|
||||||
|
|
||||||
|
GameOverMessage() {
|
||||||
|
auto messageImage = paradiso::BitmapIO::get().load("gameover.png");
|
||||||
|
messageSprite = paradiso::Sprite{
|
||||||
|
.bitmap = messageImage,
|
||||||
|
.pivot = {paradiso::Vector2<float>::make(0.0f, 0.4f)},
|
||||||
|
.scale = {paradiso::Vector2<float>::make(((500.0f - (500.0f - 192.0f)) / 500.0f) * 2.25f, ((700.0f - (700.0f - 42.0f)) / 700.0f) * 2.25f)}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
void draw(const paradiso::Shader& shader) {
|
||||||
|
shader.set_uniform("pivot", messageSprite.pivot);
|
||||||
|
shader.set_uniform("scale", messageSprite.scale);
|
||||||
|
renderer.draw(messageSprite, shader);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto main() -> int {
|
auto main() -> int {
|
||||||
|
std::srand(std::time(nullptr));
|
||||||
|
|
||||||
// Ausgabefenster ... sieht aus als wäre es auf dem Stack
|
// Ausgabefenster ... sieht aus als wäre es auf dem Stack
|
||||||
auto window = paradiso::Window();
|
auto window = paradiso::Window();
|
||||||
|
@ -246,7 +450,7 @@ auto main() -> int {
|
||||||
*/
|
*/
|
||||||
window
|
window
|
||||||
.set_size(size) // ... Grösse
|
.set_size(size) // ... Grösse
|
||||||
.set_position(paradiso::Point{.x = 100, .y = 100}) // ... Position
|
.set_position(paradiso::Point{.x = 1920 / 2 - 500 / 2, .y = 1080 / 2 - 700 / 2}) // ... Position
|
||||||
.set_title("PardiSO.FlappyBird") // ... Titel
|
.set_title("PardiSO.FlappyBird") // ... Titel
|
||||||
.set_visible(true); // ... und jetzt anzeigen!
|
.set_visible(true); // ... und jetzt anzeigen!
|
||||||
|
|
||||||
|
@ -276,8 +480,11 @@ auto main() -> int {
|
||||||
// Load
|
// Load
|
||||||
auto background = Background{};
|
auto background = Background{};
|
||||||
auto grass = Grass{};
|
auto grass = Grass{};
|
||||||
|
|
||||||
auto quickwingsapp = QuickWings{};
|
auto quickwingsapp = QuickWings{};
|
||||||
|
auto pipe = Pipe{};
|
||||||
|
auto message = Message{};
|
||||||
|
auto gameover = GameOverMessage{};
|
||||||
|
|
||||||
|
|
||||||
// timer
|
// timer
|
||||||
|
|
||||||
|
@ -291,13 +498,29 @@ auto main() -> int {
|
||||||
ctx.clear();
|
ctx.clear();
|
||||||
auto t1 = std::chrono::high_resolution_clock::now();
|
auto t1 = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
// Keyboard and state change
|
// Keyboard and state change + update
|
||||||
|
if (quickwingsapp.paused == false) {
|
||||||
|
pipe.paused = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pipe.update();
|
||||||
|
|
||||||
quickwingsapp.on_keyboard(w.keyboard_input());
|
quickwingsapp.on_keyboard(w.keyboard_input());
|
||||||
quickwingsapp.update();
|
quickwingsapp.update();
|
||||||
|
|
||||||
|
message.on_keyboard(w.keyboard_input());
|
||||||
|
message.update();
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
background.draw(shader);
|
background.draw(shader);
|
||||||
|
pipe.draw(shader);
|
||||||
grass.draw(shader);
|
grass.draw(shader);
|
||||||
|
message.draw(shader);
|
||||||
|
|
||||||
|
if (game_over == true) {
|
||||||
|
gameover.draw(shader);
|
||||||
|
}
|
||||||
|
|
||||||
quickwingsapp.draw(shader);
|
quickwingsapp.draw(shader);
|
||||||
|
|
||||||
// wait for frame rate
|
// wait for frame rate
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue