Add tappyplane; Fix design problems
TappyPlane is the new QuickWings using the Kenney assets
18
examples/tappyplane/CMakeLists.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
set(tappyplane_srcs tappyplane.cpp)
|
||||
set(tappyplane_assets
|
||||
assets/PNG/background.png
|
||||
)
|
||||
|
||||
set_source_files_properties(${tappyplane_assets} PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
|
||||
add_executable(tappyplane ${tappyplane_srcs} ${tappyplane_assets})
|
||||
|
||||
target_link_libraries(tappyplane paradiso_core)
|
||||
|
||||
#
|
||||
# copy files to bin/../assets folder
|
||||
#
|
||||
add_custom_command(TARGET tappyplane POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/assets/
|
||||
$<TARGET_FILE_DIR:tappyplane>/assets)
|
BIN
examples/tappyplane/assets/Font/kenvector_future.ttf
Normal file
BIN
examples/tappyplane/assets/Font/kenvector_future_thin.ttf
Normal file
BIN
examples/tappyplane/assets/PNG/Letters/letterA.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterB.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterC.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterD.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterE.png
Normal file
After Width: | Height: | Size: 747 B |
BIN
examples/tappyplane/assets/PNG/Letters/letterF.png
Normal file
After Width: | Height: | Size: 771 B |
BIN
examples/tappyplane/assets/PNG/Letters/letterG.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterH.png
Normal file
After Width: | Height: | Size: 795 B |
BIN
examples/tappyplane/assets/PNG/Letters/letterI.png
Normal file
After Width: | Height: | Size: 448 B |
BIN
examples/tappyplane/assets/PNG/Letters/letterJ.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterK.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterL.png
Normal file
After Width: | Height: | Size: 580 B |
BIN
examples/tappyplane/assets/PNG/Letters/letterM.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterN.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterO.png
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterP.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterQ.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterR.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterS.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterT.png
Normal file
After Width: | Height: | Size: 696 B |
BIN
examples/tappyplane/assets/PNG/Letters/letterU.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterV.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterW.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterX.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterY.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
examples/tappyplane/assets/PNG/Letters/letterZ.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/tappyplane/assets/PNG/Numbers/number0.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
examples/tappyplane/assets/PNG/Numbers/number1.png
Normal file
After Width: | Height: | Size: 948 B |
BIN
examples/tappyplane/assets/PNG/Numbers/number2.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
examples/tappyplane/assets/PNG/Numbers/number3.png
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
examples/tappyplane/assets/PNG/Numbers/number4.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/tappyplane/assets/PNG/Numbers/number5.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
examples/tappyplane/assets/PNG/Numbers/number6.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
examples/tappyplane/assets/PNG/Numbers/number7.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
examples/tappyplane/assets/PNG/Numbers/number8.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
examples/tappyplane/assets/PNG/Numbers/number9.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
examples/tappyplane/assets/PNG/Planes/planeBlue1.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
examples/tappyplane/assets/PNG/Planes/planeBlue2.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
examples/tappyplane/assets/PNG/Planes/planeBlue3.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
examples/tappyplane/assets/PNG/Planes/planeGreen1.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
examples/tappyplane/assets/PNG/Planes/planeGreen2.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
examples/tappyplane/assets/PNG/Planes/planeGreen3.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
examples/tappyplane/assets/PNG/Planes/planeRed1.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
examples/tappyplane/assets/PNG/Planes/planeRed2.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
examples/tappyplane/assets/PNG/Planes/planeRed3.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
examples/tappyplane/assets/PNG/Planes/planeYellow1.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
examples/tappyplane/assets/PNG/Planes/planeYellow2.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
examples/tappyplane/assets/PNG/Planes/planeYellow3.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
examples/tappyplane/assets/PNG/UI/UIbg.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
examples/tappyplane/assets/PNG/UI/buttonLarge.png
Normal file
After Width: | Height: | Size: 826 B |
BIN
examples/tappyplane/assets/PNG/UI/buttonSmall.png
Normal file
After Width: | Height: | Size: 832 B |
BIN
examples/tappyplane/assets/PNG/UI/medalBronze.png
Normal file
After Width: | Height: | Size: 9.1 KiB |
BIN
examples/tappyplane/assets/PNG/UI/medalGold.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
examples/tappyplane/assets/PNG/UI/medalSilver.png
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
examples/tappyplane/assets/PNG/UI/tap.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
examples/tappyplane/assets/PNG/UI/tapLeft.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/tappyplane/assets/PNG/UI/tapRight.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/tappyplane/assets/PNG/UI/tapTick.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
examples/tappyplane/assets/PNG/UI/textGameOver.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
examples/tappyplane/assets/PNG/UI/textGetReady.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
examples/tappyplane/assets/PNG/background.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
examples/tappyplane/assets/PNG/groundDirt.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
examples/tappyplane/assets/PNG/groundGrass.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
examples/tappyplane/assets/PNG/groundIce.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
examples/tappyplane/assets/PNG/groundRock.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
examples/tappyplane/assets/PNG/groundSnow.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
examples/tappyplane/assets/PNG/puffLarge.png
Normal file
After Width: | Height: | Size: 448 B |
BIN
examples/tappyplane/assets/PNG/puffSmall.png
Normal file
After Width: | Height: | Size: 291 B |
BIN
examples/tappyplane/assets/PNG/rock.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
examples/tappyplane/assets/PNG/rockDown.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
examples/tappyplane/assets/PNG/rockGrass.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
examples/tappyplane/assets/PNG/rockGrassDown.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
examples/tappyplane/assets/PNG/rockIce.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
examples/tappyplane/assets/PNG/rockIceDown.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
examples/tappyplane/assets/PNG/rockSnow.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
examples/tappyplane/assets/PNG/rockSnowDown.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
examples/tappyplane/assets/PNG/starBronze.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
examples/tappyplane/assets/PNG/starGold.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
examples/tappyplane/assets/PNG/starSilver.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
examples/tappyplane/assets/Spritesheet/planes.png
Normal file
After Width: | Height: | Size: 35 KiB |
14
examples/tappyplane/assets/Spritesheet/planes.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<TextureAtlas imagePath="sheet.png">
|
||||
<SubTexture name="planeBlue1.png" x="0" y="73" width="88" height="73"/>
|
||||
<SubTexture name="planeBlue2.png" x="0" y="0" width="88" height="73"/>
|
||||
<SubTexture name="planeBlue3.png" x="0" y="365" width="88" height="73"/>
|
||||
<SubTexture name="planeGreen1.png" x="88" y="219" width="88" height="73"/>
|
||||
<SubTexture name="planeGreen2.png" x="88" y="146" width="88" height="73"/>
|
||||
<SubTexture name="planeGreen3.png" x="88" y="73" width="88" height="73"/>
|
||||
<SubTexture name="planeRed1.png" x="88" y="0" width="88" height="73"/>
|
||||
<SubTexture name="planeRed2.png" x="0" y="438" width="88" height="73"/>
|
||||
<SubTexture name="planeRed3.png" x="88" y="292" width="88" height="73"/>
|
||||
<SubTexture name="planeYellow1.png" x="0" y="292" width="88" height="73"/>
|
||||
<SubTexture name="planeYellow2.png" x="0" y="219" width="88" height="73"/>
|
||||
<SubTexture name="planeYellow3.png" x="0" y="146" width="88" height="73"/>
|
||||
</TextureAtlas>
|
BIN
examples/tappyplane/assets/Spritesheet/sheet.png
Normal file
After Width: | Height: | Size: 246 KiB |
81
examples/tappyplane/assets/Spritesheet/sheet.xml
Normal file
|
@ -0,0 +1,81 @@
|
|||
<TextureAtlas imagePath="sheet.png">
|
||||
<SubTexture name="UIbg.png" x="0" y="986" width="264" height="264"/>
|
||||
<SubTexture name="background.png" x="0" y="355" width="800" height="480"/>
|
||||
<SubTexture name="buttonLarge.png" x="0" y="1250" width="196" height="70"/>
|
||||
<SubTexture name="buttonSmall.png" x="0" y="1320" width="136" height="80"/>
|
||||
<SubTexture name="groundDirt.png" x="0" y="0" width="808" height="71"/>
|
||||
<SubTexture name="groundGrass.png" x="0" y="142" width="808" height="71"/>
|
||||
<SubTexture name="groundIce.png" x="0" y="71" width="808" height="71"/>
|
||||
<SubTexture name="groundRock.png" x="0" y="284" width="808" height="71"/>
|
||||
<SubTexture name="groundSnow.png" x="0" y="213" width="808" height="71"/>
|
||||
<SubTexture name="letterA.png" x="412" y="835" width="61" height="64"/>
|
||||
<SubTexture name="letterB.png" x="487" y="1537" width="50" height="66"/>
|
||||
<SubTexture name="letterC.png" x="460" y="977" width="52" height="66"/>
|
||||
<SubTexture name="letterD.png" x="432" y="1613" width="54" height="66"/>
|
||||
<SubTexture name="letterE.png" x="511" y="1965" width="45" height="64"/>
|
||||
<SubTexture name="letterF.png" x="512" y="963" width="44" height="64"/>
|
||||
<SubTexture name="letterG.png" x="460" y="1107" width="52" height="66"/>
|
||||
<SubTexture name="letterH.png" x="473" y="835" width="51" height="64"/>
|
||||
<SubTexture name="letterI.png" x="524" y="835" width="22" height="64"/>
|
||||
<SubTexture name="letterJ.png" x="512" y="1027" width="42" height="66"/>
|
||||
<SubTexture name="letterK.png" x="432" y="1821" width="53" height="64"/>
|
||||
<SubTexture name="letterL.png" x="512" y="899" width="44" height="64"/>
|
||||
<SubTexture name="letterM.png" x="392" y="1967" width="66" height="64"/>
|
||||
<SubTexture name="letterN.png" x="432" y="1679" width="53" height="64"/>
|
||||
<SubTexture name="letterO.png" x="418" y="1284" width="60" height="66"/>
|
||||
<SubTexture name="letterP.png" x="489" y="1427" width="48" height="65"/>
|
||||
<SubTexture name="letterQ.png" x="418" y="1205" width="60" height="79"/>
|
||||
<SubTexture name="letterR.png" x="478" y="1249" width="51" height="65"/>
|
||||
<SubTexture name="letterS.png" x="511" y="1899" width="46" height="66"/>
|
||||
<SubTexture name="letterT.png" x="460" y="1043" width="52" height="64"/>
|
||||
<SubTexture name="letterU.png" x="485" y="1757" width="51" height="66"/>
|
||||
<SubTexture name="letterV.png" x="400" y="913" width="61" height="64"/>
|
||||
<SubTexture name="letterW.png" x="136" y="1320" width="76" height="64"/>
|
||||
<SubTexture name="letterX.png" x="418" y="1409" width="58" height="64"/>
|
||||
<SubTexture name="letterY.png" x="432" y="1473" width="57" height="64"/>
|
||||
<SubTexture name="letterZ.png" x="486" y="1613" width="50" height="64"/>
|
||||
<SubTexture name="medalBronze.png" x="0" y="1400" width="114" height="119"/>
|
||||
<SubTexture name="medalGold.png" x="0" y="1519" width="114" height="119"/>
|
||||
<SubTexture name="medalSilver.png" x="0" y="1638" width="114" height="119"/>
|
||||
<SubTexture name="number0.png" x="432" y="1743" width="53" height="78"/>
|
||||
<SubTexture name="number1.png" x="512" y="1093" width="37" height="76"/>
|
||||
<SubTexture name="number2.png" x="477" y="1350" width="51" height="77"/>
|
||||
<SubTexture name="number3.png" x="485" y="1679" width="51" height="78"/>
|
||||
<SubTexture name="number4.png" x="432" y="1537" width="55" height="76"/>
|
||||
<SubTexture name="number5.png" x="485" y="1823" width="50" height="76"/>
|
||||
<SubTexture name="number6.png" x="432" y="1885" width="53" height="77"/>
|
||||
<SubTexture name="number7.png" x="478" y="1173" width="51" height="76"/>
|
||||
<SubTexture name="number8.png" x="461" y="899" width="51" height="78"/>
|
||||
<SubTexture name="number9.png" x="458" y="1962" width="53" height="77"/>
|
||||
<SubTexture name="planeBlue1.png" x="330" y="1371" width="88" height="73"/>
|
||||
<SubTexture name="planeBlue2.png" x="372" y="1132" width="88" height="73"/>
|
||||
<SubTexture name="planeBlue3.png" x="222" y="1562" width="88" height="73"/>
|
||||
<SubTexture name="planeGreen1.png" x="114" y="1639" width="88" height="73"/>
|
||||
<SubTexture name="planeGreen2.png" x="216" y="1951" width="88" height="73"/>
|
||||
<SubTexture name="planeGreen3.png" x="222" y="1489" width="88" height="73"/>
|
||||
<SubTexture name="planeRed1.png" x="216" y="1878" width="88" height="73"/>
|
||||
<SubTexture name="planeRed2.png" x="372" y="1059" width="88" height="73"/>
|
||||
<SubTexture name="planeRed3.png" x="372" y="986" width="88" height="73"/>
|
||||
<SubTexture name="planeYellow1.png" x="304" y="1967" width="88" height="73"/>
|
||||
<SubTexture name="planeYellow2.png" x="330" y="1298" width="88" height="73"/>
|
||||
<SubTexture name="planeYellow3.png" x="330" y="1225" width="88" height="73"/>
|
||||
<SubTexture name="puffLarge.png" x="114" y="1712" width="42" height="35"/>
|
||||
<SubTexture name="puffSmall.png" x="196" y="1250" width="25" height="21"/>
|
||||
<SubTexture name="rock.png" x="114" y="1400" width="108" height="239"/>
|
||||
<SubTexture name="rockDown.png" x="324" y="1489" width="108" height="239"/>
|
||||
<SubTexture name="rockGrass.png" x="0" y="1757" width="108" height="239"/>
|
||||
<SubTexture name="rockGrassDown.png" x="264" y="986" width="108" height="239"/>
|
||||
<SubTexture name="rockIce.png" x="216" y="1639" width="108" height="239"/>
|
||||
<SubTexture name="rockIceDown.png" x="222" y="1250" width="108" height="239"/>
|
||||
<SubTexture name="rockSnow.png" x="324" y="1728" width="108" height="239"/>
|
||||
<SubTexture name="rockSnowDown.png" x="108" y="1757" width="108" height="239"/>
|
||||
<SubTexture name="starBronze.png" x="170" y="1996" width="39" height="37"/>
|
||||
<SubTexture name="starGold.png" x="369" y="1444" width="39" height="37"/>
|
||||
<SubTexture name="starSilver.png" x="330" y="1444" width="39" height="37"/>
|
||||
<SubTexture name="tap.png" x="156" y="1712" width="40" height="40"/>
|
||||
<SubTexture name="tapLeft.png" x="0" y="1996" width="85" height="42"/>
|
||||
<SubTexture name="tapRight.png" x="85" y="1996" width="85" height="42"/>
|
||||
<SubTexture name="tapTick.png" x="418" y="1350" width="59" height="59"/>
|
||||
<SubTexture name="textGameOver.png" x="0" y="835" width="412" height="78"/>
|
||||
<SubTexture name="textGetReady.png" x="0" y="913" width="400" height="73"/>
|
||||
</TextureAtlas>
|
510
examples/tappyplane/assets/Vector/vector.svg
Normal file
After Width: | Height: | Size: 446 KiB |
BIN
examples/tappyplane/assets/Vector/vector.swf
Normal file
14
examples/tappyplane/assets/license.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
###############################################################################
|
||||
|
||||
Tappy Plane by Kenney Vleugels (www.kenney.nl)
|
||||
|
||||
------------------------------
|
||||
|
||||
License (CC0)
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
You may use these graphics in personal and commercial projects.
|
||||
Credit (Kenney or www.kenney.nl) would be nice but is not mandatory.
|
||||
|
||||
###############################################################################
|
BIN
examples/tappyplane/assets/preview.png
Normal file
After Width: | Height: | Size: 159 KiB |
BIN
examples/tappyplane/assets/sample.png
Normal file
After Width: | Height: | Size: 80 KiB |
456
examples/tappyplane/tappyplane.cpp
Normal file
|
@ -0,0 +1,456 @@
|
|||
/**
|
||||
* paradiso - Paradigmen der Softwareentwicklung
|
||||
*
|
||||
* (c) Copyright 2023-2025 Hartmut Seichter and Contributors
|
||||
*
|
||||
*/
|
||||
|
||||
#include <paradiso/bitmap.hpp>
|
||||
#include <paradiso/bitmap_io.hpp>
|
||||
#include <paradiso/context.hpp>
|
||||
#include <paradiso/geometry.hpp>
|
||||
#include <paradiso/renderer.hpp>
|
||||
#include <paradiso/shader.hpp>
|
||||
#include <paradiso/sprite.hpp>
|
||||
#include <paradiso/utils.hpp>
|
||||
#include <paradiso/vector.hpp>
|
||||
#include <paradiso/window.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
static const unsigned int FRAME_RATE = 60;
|
||||
static const unsigned int WINDOW_WIDTH = 800;
|
||||
static const unsigned int WINDOW_HEIGHT = 480;
|
||||
static const unsigned int WINDOW_SCALE = 2;
|
||||
|
||||
// x,y+h --- x+w,y+h
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// x,y ----- x+w,y
|
||||
struct AABB {
|
||||
paradiso::Vector2<float> position{};
|
||||
paradiso::Vector2<float> size{};
|
||||
|
||||
bool is_colliding_with(const AABB& other) {
|
||||
return position.x() < other.position.x() + other.size.x() &&
|
||||
position.x() + size.x() > other.position.x() &&
|
||||
position.y() < other.position.y() + other.size.y() &&
|
||||
position.y() + size.y() > other.position.y();
|
||||
}
|
||||
};
|
||||
|
||||
struct Background {
|
||||
static constexpr float SCROLLING_SPEED = 0.003f;
|
||||
|
||||
std::array<paradiso::Sprite, 2> sprites;
|
||||
paradiso::Renderer renderer{};
|
||||
|
||||
paradiso::Bitmap image =
|
||||
paradiso::BitmapIO::get().load("PNG/background.png");
|
||||
|
||||
void init() {
|
||||
sprites = {paradiso::Sprite{
|
||||
.bitmap = image,
|
||||
.pivot = {paradiso::Vector2<float>::make(0.0f, 0.0f)},
|
||||
.scale = {paradiso::Vector2<float>::make(1.0f, 1.0f)}},
|
||||
paradiso::Sprite{
|
||||
.bitmap = image,
|
||||
.pivot = {paradiso::Vector2<float>::make(2.0f, 0.0f)},
|
||||
.scale = {paradiso::Vector2<float>::make(1.0f, 1.0f)}}};
|
||||
}
|
||||
|
||||
void update() {
|
||||
for (auto& sprite : sprites) {
|
||||
sprite.pivot.x() -= SCROLLING_SPEED;
|
||||
if (sprite.pivot.x() <= -2.0f) {
|
||||
sprite.pivot.x() += 4.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw(const paradiso::Shader& shader) {
|
||||
for (const auto& sprite : sprites) {
|
||||
shader.set_uniform("pivot", sprite.pivot);
|
||||
shader.set_uniform("scale", sprite.scale);
|
||||
shader.set_uniform("rotation", sprite.rotation);
|
||||
renderer.draw(sprite, shader);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Ground {
|
||||
static constexpr float SCROLLING_SPEED = 0.009f;
|
||||
|
||||
std::array<paradiso::Sprite, 2> sprites;
|
||||
paradiso::Renderer renderer{};
|
||||
|
||||
// Maybe put this into 'init()' because we might use the other textures
|
||||
// like snow, ice, ... and then we can parameterize this.
|
||||
paradiso::Bitmap image =
|
||||
paradiso::BitmapIO::get().load("PNG/groundGrass.png");
|
||||
|
||||
AABB aabb{};
|
||||
|
||||
void init() {
|
||||
// The image's height is 71 px.
|
||||
float scale_y = 71.0f / (float)WINDOW_HEIGHT;
|
||||
|
||||
float pivot_y = -1.0f + scale_y;
|
||||
|
||||
sprites = {
|
||||
paradiso::Sprite{
|
||||
.bitmap = image,
|
||||
.pivot = {paradiso::Vector2<float>::make(0.0f, pivot_y)},
|
||||
.scale = {paradiso::Vector2<float>::make(1.0f, scale_y)}},
|
||||
paradiso::Sprite{
|
||||
.bitmap = image,
|
||||
.pivot = {paradiso::Vector2<float>::make(2.0f, pivot_y)},
|
||||
.scale = {paradiso::Vector2<float>::make(1.0f, scale_y)}}};
|
||||
|
||||
// We'll make the height half the height of the texture.
|
||||
// (If you want 1:1 size, you need to double the scale of the sprite.)
|
||||
aabb = AABB{
|
||||
.position = {paradiso::Vector2<float>::make(-1.0f, -1.0f)},
|
||||
.size = {paradiso::Vector2<float>::make(2.0f, scale_y)}
|
||||
};
|
||||
}
|
||||
|
||||
void update() {
|
||||
for (auto& sprite : sprites) {
|
||||
sprite.pivot.x() -= SCROLLING_SPEED;
|
||||
if (sprite.pivot.x() <= -2.0f) {
|
||||
sprite.pivot.x() += 4.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw(const paradiso::Shader& shader) {
|
||||
for (const auto& sprite : sprites) {
|
||||
shader.set_uniform("pivot", sprite.pivot);
|
||||
shader.set_uniform("scale", sprite.scale);
|
||||
shader.set_uniform("rotation", sprite.rotation);
|
||||
renderer.draw(sprite, shader);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Rocks {
|
||||
static constexpr float SCROLLING_SPEED = 0.006f;
|
||||
static constexpr float GAP_SIZE = 1.6f;
|
||||
|
||||
paradiso::Sprite top_sprite;
|
||||
paradiso::Sprite bottom_sprite;
|
||||
|
||||
paradiso::Renderer top_renderer{};
|
||||
paradiso::Renderer bottom_renderer{};
|
||||
|
||||
// Maybe put this into 'init()' because we might use the other textures
|
||||
// like snow, ice, ... and then we can parameterize this.
|
||||
paradiso::Bitmap top_image =
|
||||
paradiso::BitmapIO::get().load("PNG/rockGrassDown.png");
|
||||
paradiso::Bitmap bottom_image =
|
||||
paradiso::BitmapIO::get().load("PNG/rockGrass.png");
|
||||
|
||||
AABB top_aabb;
|
||||
AABB bottom_aabb;
|
||||
|
||||
void init(float x) {
|
||||
// The image's size is 108x239 px.
|
||||
float scale_x = 108.0f / (float)WINDOW_WIDTH;
|
||||
float scale_y = 239.0f / (float)WINDOW_HEIGHT;
|
||||
auto scale = paradiso::Vector2<float>{
|
||||
paradiso::Vector2<float>::make(scale_x, scale_y)};
|
||||
|
||||
float top_position_y =
|
||||
1.0f - scale_y + ((float)(std::rand() % 60) / 100) + 0.04f;
|
||||
float bottom_position_y = top_position_y - GAP_SIZE;
|
||||
|
||||
top_sprite = paradiso::Sprite{
|
||||
.bitmap = top_image,
|
||||
.pivot = {paradiso::Vector2<float>::make(x, top_position_y)},
|
||||
.scale = scale};
|
||||
|
||||
bottom_sprite = paradiso::Sprite{
|
||||
.bitmap = bottom_image,
|
||||
.pivot = {paradiso::Vector2<float>::make(x, bottom_position_y)},
|
||||
.scale = scale};
|
||||
|
||||
// We'll make the width half the width of the texture.
|
||||
// (If you want 1:1 size, you need to double the scale of the sprite.)
|
||||
auto size = paradiso::Vector2<float>{
|
||||
paradiso::Vector2<float>::make(scale_x, scale_y * 2)};
|
||||
|
||||
auto top_position =
|
||||
paradiso::Vector2<float>{paradiso::Vector2<float>::make(
|
||||
top_sprite.pivot.x() - size.x() / 2,
|
||||
top_sprite.pivot.y() - size.y() / 2)};
|
||||
|
||||
auto bottom_position =
|
||||
paradiso::Vector2<float>{paradiso::Vector2<float>::make(
|
||||
bottom_sprite.pivot.x() - size.x() / 2,
|
||||
bottom_sprite.pivot.y() - size.y() / 2)};
|
||||
|
||||
top_aabb = AABB{top_position, size};
|
||||
bottom_aabb = AABB{bottom_position, size};
|
||||
}
|
||||
|
||||
void update() {
|
||||
top_sprite.pivot.x() -= SCROLLING_SPEED;
|
||||
bottom_sprite.pivot.x() -= SCROLLING_SPEED;
|
||||
|
||||
// +----------+
|
||||
// | |
|
||||
// | # #-------- the x it is.
|
||||
// | \ |
|
||||
// +----\-----+
|
||||
// \
|
||||
// *------- the x we need.
|
||||
|
||||
// @Efficiency: We could just scroll it with the sprite.
|
||||
top_aabb.position.x() = top_sprite.pivot.x() - top_aabb.size.x() / 2;
|
||||
bottom_aabb.position.x() =
|
||||
bottom_sprite.pivot.x() - bottom_aabb.size.x() / 2;
|
||||
|
||||
if (top_sprite.pivot.x() <= -1.2f) {
|
||||
// Reset.
|
||||
init(1.2f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void draw(const paradiso::Shader& shader) {
|
||||
shader.set_uniform("pivot", top_sprite.pivot);
|
||||
shader.set_uniform("scale", top_sprite.scale);
|
||||
shader.set_uniform("rotation", top_sprite.rotation);
|
||||
top_renderer.draw(top_sprite, shader);
|
||||
|
||||
shader.set_uniform("pivot", bottom_sprite.pivot);
|
||||
shader.set_uniform("scale", bottom_sprite.scale);
|
||||
shader.set_uniform("rotation", bottom_sprite.rotation);
|
||||
bottom_renderer.draw(bottom_sprite, shader);
|
||||
}
|
||||
};
|
||||
|
||||
struct Plane {
|
||||
static const unsigned int SPRITE_COUNT = 3;
|
||||
static constexpr float GRAVITY = -0.001f;
|
||||
static constexpr float JUMP_VELOCITY = 0.03f;
|
||||
static constexpr float MAX_VELOCITY = 0.03f;
|
||||
|
||||
std::array<paradiso::Sprite, SPRITE_COUNT> sprites;
|
||||
std::array<paradiso::Renderer, SPRITE_COUNT> renderers;
|
||||
|
||||
unsigned int anim_interval = 10;
|
||||
unsigned int anim_counter = 0;
|
||||
|
||||
// The direction where 'current_sprite' should go because the animation
|
||||
// shouldn't loop.
|
||||
int anim_direction = 1;
|
||||
|
||||
unsigned int current_sprite = 0;
|
||||
|
||||
float position_y = 0.5f;
|
||||
float rotation = 0.0f;
|
||||
|
||||
float velocity_y = 0.0f;
|
||||
|
||||
AABB aabb;
|
||||
|
||||
void init() {
|
||||
// The image's size is 88x73 px.
|
||||
float scale_x = 88.0f / (float)WINDOW_WIDTH;
|
||||
float scale_y = 73.0f / (float)WINDOW_HEIGHT;
|
||||
|
||||
auto pivot = paradiso::Vector2<float>{
|
||||
paradiso::Vector2<float>::make(0.0f, position_y)};
|
||||
auto scale = paradiso::Vector2<float>{
|
||||
paradiso::Vector2<float>::make(scale_x, scale_y)};
|
||||
|
||||
sprites = {
|
||||
paradiso::Sprite{.bitmap = paradiso::BitmapIO::get().load(
|
||||
"PNG/Planes/planeRed1.png"),
|
||||
.pivot = pivot,
|
||||
.scale = scale},
|
||||
paradiso::Sprite{.bitmap = paradiso::BitmapIO::get().load(
|
||||
"PNG/Planes/planeRed2.png"),
|
||||
.pivot = pivot,
|
||||
.scale = scale},
|
||||
paradiso::Sprite{.bitmap = paradiso::BitmapIO::get().load(
|
||||
"PNG/Planes/planeRed3.png"),
|
||||
.pivot = pivot,
|
||||
.scale = scale},
|
||||
};
|
||||
|
||||
// We'll make the size half the size of the texture.
|
||||
// (If you want 1:1 size, you need to double the scale of the sprite.)
|
||||
auto size = paradiso::Vector2<float>{
|
||||
paradiso::Vector2<float>::make(scale_x, scale_y)};
|
||||
|
||||
// Center it.
|
||||
auto position = paradiso::Vector2<float>{paradiso::Vector2<float>::make(
|
||||
pivot.x() - size.x() / 2, pivot.y() - size.y() / 2)};
|
||||
|
||||
aabb = AABB{position, size};
|
||||
}
|
||||
|
||||
void update(const paradiso::Window::KeyboardInputStack& input) {
|
||||
if (anim_counter < anim_interval) {
|
||||
anim_counter++;
|
||||
} else {
|
||||
anim_counter = 0;
|
||||
|
||||
current_sprite += anim_direction;
|
||||
if (current_sprite == SPRITE_COUNT - 1) {
|
||||
anim_direction = -1;
|
||||
} else if (current_sprite == 0) {
|
||||
anim_direction = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (input.size() && input.top().key == ' ' && input.top().action == 1) {
|
||||
velocity_y += JUMP_VELOCITY;
|
||||
} else {
|
||||
velocity_y += GRAVITY;
|
||||
}
|
||||
|
||||
velocity_y = std::clamp(velocity_y, -MAX_VELOCITY, MAX_VELOCITY);
|
||||
position_y += velocity_y;
|
||||
|
||||
// +---------+
|
||||
// | |
|
||||
// | #------- the y it is.
|
||||
// | |
|
||||
// +----#----+
|
||||
// \
|
||||
// *----- the y we need.
|
||||
|
||||
// @Efficiency: We could just add the velocity.
|
||||
aabb.position.y() = position_y - aabb.size.y() / 2;
|
||||
|
||||
rotation = velocity_y * 500.0f;
|
||||
}
|
||||
|
||||
void draw(const paradiso::Shader& shader) {
|
||||
auto sprite = sprites[current_sprite];
|
||||
sprite.rotation = rotation * (std::numbers::pi / 180.0f);
|
||||
sprite.pivot.y() = position_y;
|
||||
|
||||
shader.set_uniform("pivot", sprite.pivot);
|
||||
shader.set_uniform("scale", sprite.scale);
|
||||
shader.set_uniform("rotation", sprite.rotation);
|
||||
renderers[current_sprite].draw(sprite, shader);
|
||||
}
|
||||
};
|
||||
|
||||
auto main() -> int {
|
||||
std::srand(std::time(nullptr));
|
||||
|
||||
auto canvas_size = paradiso::Size{.width = WINDOW_WIDTH * WINDOW_SCALE,
|
||||
.height = WINDOW_HEIGHT * WINDOW_SCALE};
|
||||
|
||||
// Unser Fenster, auf das wir rendern.
|
||||
auto window = paradiso::Window();
|
||||
window
|
||||
.set_size(canvas_size) // ... Größe
|
||||
.set_position(paradiso::Point{.x = 200, .y = 200}) // ... Position
|
||||
.set_title("ParadiSO.TappyPlane") // ... Titel
|
||||
.set_visible(true); // ... und jetzt anzeigen!
|
||||
|
||||
// Der Fenster Context.
|
||||
auto context = paradiso::Context{};
|
||||
|
||||
// Ein Shader (Schattierungsprogramm).
|
||||
auto shader = paradiso::Shader{};
|
||||
|
||||
// Wir nutzen einen vorgefertigten Shader, der speziell für Sprites ist.
|
||||
shader.load_preset(paradiso::Shader::Preset::Sprite);
|
||||
|
||||
// Ein Viewport stellt die Sicht der Kamera dar, d.h. bei quadratischen
|
||||
// Pixeln sollte hier auch eine dementsprechende Größe eingestellt
|
||||
// werden.
|
||||
context.set_viewport(paradiso::Rectangle{
|
||||
.position = paradiso::Point{.x = 0, .y = 0}, .size = canvas_size});
|
||||
|
||||
// Conflower blue
|
||||
context.set_clearcolor(paradiso::RGBA::from_rgb(0x64, 0x95, 0xED));
|
||||
|
||||
// Der Asset Loader bekommt den Pfad.
|
||||
paradiso::BitmapIO::get().set_path("assets");
|
||||
|
||||
// Wir initialisieren unsere Sachen.
|
||||
auto background = Background{};
|
||||
background.init();
|
||||
|
||||
auto ground = Ground{};
|
||||
ground.init();
|
||||
|
||||
auto rocks1 = Rocks{};
|
||||
rocks1.init(1.2f);
|
||||
|
||||
auto rocks2 = Rocks{};
|
||||
rocks2.init(2.4f);
|
||||
|
||||
auto plane = Plane{};
|
||||
plane.init();
|
||||
|
||||
auto top_aabb =
|
||||
AABB{.position = {paradiso::Vector2<float>::make(-1.0f, 1.0f)},
|
||||
.size = {paradiso::Vector2<float>::make(2.0f, 0.5f)}};
|
||||
|
||||
while (window.update([&](paradiso::Window& window) -> bool {
|
||||
background.update();
|
||||
ground.update();
|
||||
|
||||
rocks1.update();
|
||||
rocks2.update();
|
||||
|
||||
plane.update(window.keyboard_input());
|
||||
|
||||
if (plane.aabb.is_colliding_with(rocks1.top_aabb) ||
|
||||
plane.aabb.is_colliding_with(rocks1.bottom_aabb) ||
|
||||
plane.aabb.is_colliding_with(rocks2.top_aabb) ||
|
||||
plane.aabb.is_colliding_with(rocks2.bottom_aabb) ||
|
||||
plane.aabb.is_colliding_with(top_aabb) ||
|
||||
plane.aabb.is_colliding_with(ground.aabb)) {
|
||||
|
||||
std::cout << "COLLIDING" << std::endl;
|
||||
}
|
||||
|
||||
auto t1 = std::chrono::high_resolution_clock::now();
|
||||
|
||||
context.set_viewport(paradiso::Rectangle{
|
||||
.position = paradiso::Point{.x = 0, .y = 0}, .size = canvas_size});
|
||||
context.clear();
|
||||
|
||||
background.draw(shader);
|
||||
|
||||
plane.draw(shader);
|
||||
|
||||
rocks1.draw(shader);
|
||||
rocks2.draw(shader);
|
||||
|
||||
ground.draw(shader);
|
||||
|
||||
// Einen kurzen Moment warten, um auf 60 FPS zu kommen.
|
||||
auto t2 = std::chrono::high_resolution_clock::now();
|
||||
auto duration =
|
||||
std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
|
||||
auto wait = std::chrono::microseconds(1000000 / FRAME_RATE) - duration;
|
||||
std::this_thread::sleep_for(wait);
|
||||
|
||||
if (window.keyboard_input().size() &&
|
||||
window.keyboard_input().top().key == 'Q') {
|
||||
// Update-Loop beenden.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
})) {
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|