Skip to content

Commit 1d32eb1

Browse files
committed
add working menu, broken physics
Signed-off-by: Lauren Kelly <[email protected]>
1 parent 8e3d034 commit 1d32eb1

32 files changed

+717
-142
lines changed

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ GRAPHICS := gfx
4141
ROMFS := romfs
4242
GFXBUILD := $(ROMFS)/gfx
4343

44+
APP_TITLE := Rhythm Run
45+
APP_AUTHOR := Lauren Kelly
46+
4447
#---------------------------------------------------------------------------------
4548
# options for code generation
4649
#---------------------------------------------------------------------------------

blobs_src/platform.png

28.4 KB
Loading

gfx/platform.png

28.4 KB
Loading

gfx/sprites.t3s

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
--atlas -f rgba8888 -z auto
22
lennycat.png
33
test_cat.png
4-
star.png
4+
star.png
5+
platform.png

include/Button.hpp

+28-4
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,15 @@
1818
class Button : public Entity
1919
{
2020
public:
21-
Button(float a_x, float a_y, C2D_SpriteSheet a_spriteSheet, size_t a_spriteIndex,
22-
float a_centerX, float a_centerY, float a_scaleX, float a_scaleY,
23-
float a_rotation);
21+
Button(float a_x, float a_y, C2D_SpriteSheet a_spriteSheet,
22+
size_t a_spriteIndex, size_t a_spriteIndex_pressed,
23+
float a_centerX, float a_centerY,
24+
float a_scaleX, float a_scaleY,
25+
float a_rotation)
26+
: Entity(a_x, a_y, a_spriteSheet, a_spriteIndex, a_centerX, a_centerY,
27+
a_scaleX, a_scaleY, a_rotation),
28+
isPressed(false),
29+
spriteIndex_pressed(a_spriteIndex_pressed) {};
2430
Button() {}; // default empty constructor
2531

2632
/// @brief Add event listener
@@ -29,7 +35,25 @@ class Button : public Entity
2935
void addEventListener(const touchEventKind_t a_eventType, const callback_t<touchEvent_t> &a_listener) {
3036
callbacks.push_back({a_listener, a_eventType});
3137
};
32-
private:
38+
39+
/// @brief Set the sprite graphic to be displayed
40+
/// @param a_index Index of the sprite to use (normal)
41+
/// @param a_spriteSheet Sprite sheet to use (defaults to the current)
42+
void setSprite(size_t a_index, C2D_SpriteSheet a_spriteSheet);
43+
44+
/// @brief Set the sprite graphic to be displayed
45+
/// @param a_index Index of the sprite to use (normal)
46+
/// @param a_index_pressed Index of the sprite to use (pressed state)
47+
/// @param a_spriteSheet Sprite sheet to use (defaults to the current)
48+
void setSprite(size_t a_index, size_t a_index_pressed, C2D_SpriteSheet a_spriteSheet);
49+
50+
inline bool getPressed() { return isPressed; }
51+
void setPressed(bool a_newState);
52+
protected:
53+
/// @brief Whether or not the button is in its pressed/held state.
54+
bool isPressed;
55+
/// @brief Index of sprite graphic currently being used from sheet
56+
size_t spriteIndex_pressed;
3357
/// @brief Registered callbacks
3458
std::vector<touchEventListener_t> callbacks;
3559
};

include/Entity.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class Entity : public Drawable
8181

8282
/// @brief Draw the sprite
8383
inline bool draw() { return C2D_DrawSprite(&sprite); };
84-
private:
84+
protected:
8585
/// @brief Current C2D sprite sheet
8686
C2D_SpriteSheet spriteSheet;
8787
/// @brief Index of sprite graphic currently being used from sheet

include/Events.hpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ typedef enum touchEventKind_t {
1717
TOUCH_MOVE = 2,
1818
} touchEventKind_t;
1919

20-
/// Touch event listener
21-
typedef struct touchEventListener_t {
22-
callback_t<touchEvent_t> cb;
23-
touchEventKind_t kind;
24-
} touchEventListener_t;
25-
2620
/// Touch event
2721
typedef struct touchEvent_t {
2822
touchEventKind_t kind;
2923
Point pos;
30-
} touchEvent_t;
24+
} touchEvent_t;
25+
26+
/// Touch event listener
27+
typedef struct touchEventListener_t {
28+
callback_t<touchEvent_t> cb;
29+
touchEventKind_t kind;
30+
} touchEventListener_t;

include/Game.hpp

+9-8
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,17 @@ class Game
3535
/// Draw frame for lower screen
3636
void drawLower();
3737
/// Render a full dual-screen frame
38-
void draw() {
39-
drawUpper();
40-
// drawLower();
41-
};
38+
void draw();
39+
40+
/// should we quit the program?
41+
/// ask scene manager.
42+
inline bool shouldQuit() {
43+
return sceneManager.shouldQuit();
44+
}
4245

43-
bool isRunning() { // Should the game continue running?
46+
inline bool isRunning() { // Should the game continue running?
4447
// Quit if APT says we should, or if we've set the quit flag
45-
return aptMainLoop() && !quitFlag;
48+
return aptMainLoop() && !shouldQuit();
4649
};
4750
private:
4851
RenderWindow upperScreen;
@@ -53,6 +56,4 @@ class Game
5356

5457
u64 lastTime;
5558
float timeDelta;
56-
57-
bool quitFlag;
5859
};

include/Geometry.hpp

+22-10
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,29 @@ class Rectangle {
2323
: topLeft(a_topLeft), lowerRight(a_lowerRight) { };
2424

2525
/// Returns true if this Rectangle intersects the given Rectangle.
26-
inline bool doesIntersect(Rectangle a_rect) {
27-
// Two rectangles DO NOT overlap if and only if:
28-
// * One rectangle is above the top edge of the other; AND/OR
29-
// * One rectangle is further left than the left edge of the other.
30-
// Therefore, this checks that neither of the above conditions are met.
26+
// inline bool doesIntersect(Rectangle a_rect) {
27+
// // Two rectangles DO NOT overlap if and only if:
28+
// // * One rectangle is above the top edge of the other; AND/OR
29+
// // * One rectangle is further left than the left edge of the other.
30+
// // Therefore, this checks that neither of the above conditions are met.
3131

32-
return !(
33-
(topLeft.x >= a_rect.lowerRight.x) ||
34-
(a_rect.topLeft.x >= lowerRight.x) ||
35-
(topLeft.y <= a_rect.lowerRight.y) ||
36-
(a_rect.topLeft.y <= lowerRight.y)
32+
// return !(
33+
// (topLeft.x >= a_rect.lowerRight.x) ||
34+
// (a_rect.topLeft.x >= lowerRight.x) ||
35+
// (topLeft.y <= a_rect.lowerRight.y) ||
36+
// (a_rect.topLeft.y <= lowerRight.y)
37+
// );
38+
// }
39+
inline bool doesIntersect(Rectangle a_rect) {
40+
return (
41+
(
42+
a_rect.topLeft.x >= topLeft.x &&
43+
a_rect.lowerRight.x <= lowerRight.x
44+
) &&
45+
(
46+
a_rect.topLeft.y >= topLeft.y &&
47+
a_rect.lowerRight.y <= lowerRight.y
48+
)
3749
);
3850
}
3951

include/Label.hpp

+9-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
class Label : public Drawable
2121
{
2222
public:
23-
Label(const char *a_text, float a_x, float a_y, u32 a_flags, float a_scaleX, float a_scaleY, size_t a_bufSize);
23+
Label(const char *a_text, float a_x, float a_y, u32 a_flags, float a_scaleX, float a_scaleY, u32 a_color, size_t a_bufSize);
2424
Label() {}; // default empty constructor
2525

2626
// Destructor -- clean up text buf
@@ -62,15 +62,19 @@ class Label : public Drawable
6262
scaleY *= a_scaleY;
6363
};
6464

65-
bool draw() {
66-
C2D_DrawText(&text, textFlags, posX, posY, 0.0f, scaleX, scaleY);
67-
return true;
68-
};
65+
/// Set label text
66+
void setText(const char *a_text, size_t a_bufSize);
67+
/// Set label color
68+
void setColor(u32 a_color) { color = a_color; };
69+
70+
bool draw();
6971
private:
7072
C2D_Text text;
7173
C2D_TextBuf textBuf;
7274
u32 textFlags;
7375

7476
float posX, posY;
7577
float scaleX, scaleY;
78+
79+
u32 color;
7680
};

include/LabelledButton.hpp

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Rhythm Run for Nintendo 3DS
3+
* Lauren Kelly, 2021
4+
*/
5+
6+
#pragma once
7+
#include <3ds.h>
8+
#include <citro2d.h>
9+
#include <stdint.h>
10+
#include <memory>
11+
12+
#include "Button.hpp"
13+
#include "Label.hpp"
14+
15+
/**
16+
* LabelledButton class
17+
*/
18+
19+
class LabelledButton : public Button
20+
{
21+
public:
22+
LabelledButton(float a_x, float a_y, C2D_SpriteSheet a_spriteSheet,
23+
size_t a_spriteIndex, size_t a_spriteIndex_pressed,
24+
float a_centerX, float a_centerY,
25+
const char *a_text,
26+
float a_scaleX, float a_scaleY,
27+
float a_rotation,
28+
u32 a_textColor);
29+
LabelledButton() {}; // default empty constructor
30+
31+
/// Set the state (pressed/not pressed)
32+
// inline void setPressed(bool a_newState) {
33+
// if(isPressed == a_newState) return;
34+
35+
// Button::setPressed(a_newState);
36+
// if(a_newState == true) {
37+
// textLabel->move(2.0f, 2.0f);
38+
// } else {
39+
// textLabel->move(-2.0f, -2.0f);
40+
// }
41+
// };
42+
43+
/// Draw the LabelledButton
44+
inline bool draw() {
45+
Button::draw();
46+
47+
Point newPosition = calculatePosition();
48+
49+
// eeprintf("textLabel->setPosition %.02f, %.02f\n",
50+
// floor(newPosition.x),
51+
// floor(newPosition.y)
52+
// );
53+
textLabel->setPosition(
54+
floor(newPosition.x),
55+
floor(newPosition.y)
56+
);
57+
58+
textLabel->draw();
59+
return true;
60+
};
61+
62+
/// @brief Move the button (relative)
63+
/// @param a_dX,a_dY Tranlation in each dimension
64+
inline void move(float a_dX, float a_dY) {
65+
Button::move(a_dX, a_dY);
66+
textLabel->move(a_dX, a_dY);
67+
};
68+
/// @brief Scale the button by some scale factor relative to its current size
69+
/// @param a_scaleX, a_scaleY Scale factor in each dimension
70+
inline void scale(float a_scaleX, float a_scaleY) {
71+
Button::scale(a_scaleX, a_scaleY);
72+
textLabel->scale(a_scaleX, a_scaleY);
73+
}
74+
75+
/// Set label text
76+
// inline void setText(const char *a_text, size_t a_bufSize = 0) { textLabel->setText(a_text, a_bufSize); };
77+
/// Set label color
78+
// inline void setColor(u32 a_color = 0) { textLabel->setColor(a_color); };
79+
/// @brief The button label
80+
std::shared_ptr<Label> textLabel;
81+
protected:
82+
Point calculatePosition() {
83+
Point topLeft = getRect().topLeft;
84+
85+
float fontScale = 0.75f * getHeight() / 30.0f; // 3ds font height = 30px
86+
// float fontScale = 0.75f;
87+
// eeprintf("Font scale: %.02f\n", fontScale);
88+
89+
float fontBaseline = 25.0f * fontScale;
90+
// float fontBaseline = 24.0f;
91+
// eeprintf("Font base : %.02f\n", fontBaseline);
92+
93+
return Point{
94+
topLeft.x + (getWidth() / 2),
95+
topLeft.y + fontBaseline
96+
};
97+
}
98+
};

include/RenderWindow.hpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class RenderWindow
3333
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
3434
C2D_SceneBegin(renderTarget);
3535

36-
clear(C2D_Color32(0xFF, 0x44, 0x77, 0xFF));
36+
// clear(C2D_Color32(0xFF, 0x44, 0x77, 0xFF));
3737
};
3838

3939
/// Draw something
@@ -45,6 +45,19 @@ class RenderWindow
4545
void endDraw() {
4646
// eprintf("EndDraw\n");
4747
C3D_FrameEnd(0);
48+
49+
// sync to 60fps
50+
float gpuTime = C3D_GetDrawingTime();
51+
float cpuTime = C3D_GetProcessingTime();
52+
// gfxFlushBuffers();
53+
if (gpuTime > 1000.0f / 30.f || cpuTime > 1000.0f / 30.0f) {
54+
printf("!! TOO SLOW !!\n");
55+
} else {
56+
gspWaitForVBlank();
57+
}
58+
printf("\x1b[29;1HGPU: %.02f ms; CPU: %.02f ms ", gpuTime, cpuTime);
59+
// eprintf("")
60+
// gfxSwapBuffers();
4861
};
4962

5063
/// Clear the window with a particular colour

include/Scene.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ class Scene
2727
/// Called whenever the scene loses focus ('blur')
2828
virtual void onBlur() {};
2929

30+
/// Whether it is safe to terminate the scene now
31+
virtual bool canQuit() { return true; };
32+
3033
// To be overridden as necessary
3134
virtual void processInput() {};
3235
virtual void update(float a_timeDelta) {};

include/SceneGameplay.hpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,17 @@ class SceneGameplay : public Scene
5151

5252
C2D_SpriteSheet spriteSheet;
5353

54-
std::shared_ptr<Entity> splashImageEntity;
54+
std::shared_ptr<Entity> playerEntity;
55+
56+
std::shared_ptr<Entity> platform1Entity;
57+
std::shared_ptr<Entity> platform2Entity;
58+
std::shared_ptr<Entity> platform3Entity;
59+
std::shared_ptr<Entity> platform4Entity;
60+
5561
std::shared_ptr<OggOpusFile> opusFile;
5662
unsigned int audioId;
57-
5863
bool isJumping;
64+
bool shouldRedraw;
5965
float velocityX, velocityY;
6066
float accelX, accelY;
6167
};

0 commit comments

Comments
 (0)