Skip to content

Commit 5d68279

Browse files
More element controls, minor refactors
Alpha v0.3
1 parent 761c119 commit 5d68279

File tree

8 files changed

+108
-51
lines changed

8 files changed

+108
-51
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ endif()
2424
# Find dependencies
2525
find_package(SDL2_image REQUIRED)
2626
find_package(SDL2_ttf REQUIRED)
27-
include_directories(${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS} ${SDL2_TTF_INCLUDE_DIRS})
27+
include_directories(${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS})
2828

2929
# Include source directories and add executable
3030
include_directories(src/JSON)

changelog.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
Information on historical builds from before this was public may be missing or incomplete. These were pretty messy and had little version control.
2+
3+
### Alpha v0.3 (LATEST)
4+
- Changed font from Droid Sans to Open Sans.
5+
- Element code has been refactored slightly.
6+
- Right clicking an element now deletes it.
7+
- Double clicking an element now duplicates it relative to the corner it was clicked on.
8+
9+
### Alpha v0.2
10+
- ImGui has been added and has yet to be used.
11+
- Disabled VSync.
12+
- Removed unused element code.
13+
14+
### Alpha v0.1.2
15+
- Re-enabled VSync.
16+
17+
### Alpha v0.1.1
18+
- Changed font from Roboto to Droid Sans.
19+
- Fixed animation code.
20+
- Changed asset folders.
21+
- Disabled VSync.
22+
23+
### Alpha v0.1
24+
- Windows is now supported.
25+
- Added FPS counter.
26+
- Elements are no longer Z-sorted unless needed.
27+
- VSync temporarily re-enabled.
28+
29+
### Pre-alpha v0.2
30+
- Elements now have text below them.
31+
- Z-indexing now works properly?
32+
- Minor fixes and refactoring.
33+
34+
### Pre-alpha v0.1
35+
- Added version text in the top left corner.
36+
- Added animations?
37+
- Disabled VSync.
38+
39+
### xreation test 2
40+
- Various fixes.
41+
- Elements can now be spawned by double clicking?
42+
43+
### xreation test 1
44+
- Initial version?
45+
- Fire and air are spawned by default. There are no means of spawning more elements.

src/GFX/Animation.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#include <SDL2/SDL.h>
2-
#include <stdlib.h>
32
#include <stdbool.h>
43
#include "SDL_FontCache.h"
54
#include "../Game/Sprite.hpp"

src/GFX/SDL_FontCache.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ THE SOFTWARE.
3333
#ifndef _SDL_FONTCACHE_H__
3434
#define _SDL_FONTCACHE_H__
3535

36-
#include "SDL.h"
37-
#include "SDL_ttf.h"
36+
#include <SDL2/SDL.h>
37+
#include <SDL2/SDL_ttf.h>
3838

3939
#ifdef FC_USE_SDL_GPU
4040
#include "SDL_gpu.h"

src/Game/Element.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include <unordered_map>
88
#include <algorithm>
99
#include <memory>
10-
#include <cmath>
1110
#include "Element.hpp"
1211
#include "Sprite.hpp"
1312
#include "../GFX/Animation.hpp"
@@ -16,8 +15,6 @@
1615
#include "../Misc/IO.hpp"
1716
#include "../Menu/Lang.hpp"
1817

19-
bool compareZIndexRaw(DraggableElement* d1, DraggableElement* d2) { return d1->z > d2->z; } //Z-index comparison for raw pointers
20-
2118
// Constructor
2219
DraggableElement::DraggableElement(std::string elemID, int mX, int mY) {
2320
SDL_Rect* newElemBox = (SDL_Rect*) malloc(sizeof(struct SDL_Rect)); //Allocate space for new element's rectangle
@@ -44,7 +41,6 @@ DraggableElement::~DraggableElement() {
4441

4542
// Checks if two elements are colliding and combines them if possible
4643
void DraggableElement::makeCombo(std::vector<std::unique_ptr<DraggableElement>> &draggables, std::vector<std::string> &elementsUnlocked) {
47-
elem::firstParentElem = this;
4844
// Place newly unlocked elements on screen
4945
DraggableElement* matchingElem;
5046
bool comboMade = false; //This indicates if a valid combination was made and allows the function to unlock that element
@@ -62,7 +58,12 @@ void DraggableElement::makeCombo(std::vector<std::unique_ptr<DraggableElement>>
6258
}
6359
}
6460
if (!collidedElements.empty()) {
65-
std::stable_sort(collidedElements.begin(), collidedElements.end(), compareZIndexRaw);
61+
std::stable_sort(collidedElements.begin(), collidedElements.end(), [this]
62+
(DraggableElement* d1, DraggableElement* d2) {
63+
SDL_Rect* d1Intersect; SDL_IntersectRect(this->box, d1->box, d1Intersect);
64+
SDL_Rect* d2Intersect; SDL_IntersectRect(this->box, d2->box, d2Intersect); //The intersecting rectangles between the combined elements. The combination with the largest intersection area will be the combined element
65+
return d1->z > d2->z && (d1Intersect->x * d1Intersect->y) > (d2Intersect->x * d2Intersect->y);
66+
});
6667
matchingElem = collidedElements.back(); //Match with the element with the lowest Z-index
6768
elem::secondParentElem = collidedElements.back(); //Match with the element with the lowest Z-index
6869
}
@@ -97,7 +98,7 @@ void DraggableElement::makeCombo(std::vector<std::unique_ptr<DraggableElement>>
9798
}
9899

99100
// Queue combined elements to start despawning
100-
elem::firstParentElem->anim = ANIM_SHRINK;
101+
this->anim = ANIM_SHRINK;
101102
elem::secondParentElem->anim = ANIM_SHRINK;
102103
anim::animInProgress = true; //Start animations
103104
}
@@ -111,7 +112,6 @@ void DraggableElement::deleteElem(std::vector<std::unique_ptr<DraggableElement>>
111112

112113
namespace elem {
113114
std::unordered_map<std::string, SDL_Texture*> textureIndex;
114-
DraggableElement* firstParentElem;
115115
DraggableElement* secondParentElem; //First and second selected elements
116116
cJSON* root = NULL; //Root of combination JSON data
117117

src/Game/Element.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#include <stdlib.h>
21
#include <stdbool.h>
32
#include <vector>
43
#include <string>
@@ -27,12 +26,9 @@ class DraggableElement : public Sprite {
2726
static void deleteElem(std::vector<std::unique_ptr<DraggableElement>> &draggables, DraggableElement* elem);
2827
};
2928

30-
bool compareZIndexRaw(DraggableElement* d1, DraggableElement* d2);
31-
3229
namespace elem {
3330
extern std::unordered_map<std::string, SDL_Texture*> textureIndex;
3431
extern cJSON* root; //Root of combination JSON data
35-
extern DraggableElement* firstParentElem;
3632
extern DraggableElement* secondParentElem; //First and second selected elements
3733
void loadTexture(SDL_Renderer* ren, DraggableElement* elem);
3834
void spawnDraggable(std::vector<std::unique_ptr<DraggableElement>> &draggables, int x, int y, std::string name);

src/Game/Sprite.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#include <SDL2/SDL.h>
22
#include <SDL2/SDL_image.h>
3-
#include <stdio.h>
4-
#include <stdlib.h>
53
#include <stdbool.h>
64
#include <vector>
75
#ifndef SPRITE_HPP_ //Include guard

src/main.cpp

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ int main(int argc, char* argv[])
3434
return EXIT_FAILURE;
3535
}
3636
// Initialize window
37-
SDL_Window* win = SDL_CreateWindow("Alchemy++ alpha v0.2", 64, 64, 800, 600, SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE);
37+
SDL_Window* win = SDL_CreateWindow("Alchemy++ alpha v0.3", 64, 64, 800, 600, SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE);
3838
if (win == NULL) {
3939
fprintf(stderr, "SDL_CreateWindow Error: %s\n", SDL_GetError());
4040
return EXIT_FAILURE;
@@ -79,8 +79,6 @@ int main(int argc, char* argv[])
7979
FC_Font* font = FC_CreateFont();
8080
FC_LoadFont(font, ren, "gamedata/default/font/Open-Sans.ttf", 12, FC_MakeColor(255,255,255,255), TTF_STYLE_NORMAL);
8181

82-
//FC_LoadFontFromTTF(font, ren, ttfFont, FC_MakeColor(255,255,255,255));
83-
8482
elem::JSONInit(); //Initialize JSON
8583
Text::loadAll("en-us"); //Load game text
8684

@@ -103,14 +101,14 @@ int main(int argc, char* argv[])
103101

104102
auto endTick = Clock::now();
105103
double deltaTime = 1.0/60;
104+
// Game flags
105+
bool deleteNeeded = false; //Used to determine if any elements need to be deleted
106106
bool zSortNeeded = false; //Used to indicate if elements need to be sorted
107107
bool quit = false; //Main loop exit flag
108108
while (!quit) {
109109
SDL_GetWindowSize(win, &winWidth, &winHeight); //Get screen size
110110
auto startTick = Clock::now();
111111

112-
//deltaTime = endTick-startTick;
113-
114112
SDL_Event e;
115113
ImGui_ImplSDL2_ProcessEvent(&e);
116114
while (SDL_PollEvent(&e)) {
@@ -136,40 +134,58 @@ int main(int argc, char* argv[])
136134
selectedElem = NULL; //Release selected rectangle when left is released
137135
zSortNeeded = true; //Re-sort Z-index after element was dropped
138136
}
137+
// Remove if right clicked
139138
if (rightClickDown && e.button.button == SDL_BUTTON_RIGHT) {
140139
rightClickDown = false;
140+
if (selectedElem != NULL) {
141+
selectedElem->anim = ANIM_SHRINK;
142+
anim::animInProgress = true;
143+
selectedElem = nullptr;
144+
}
141145
}
142146
break;
143147
case SDL_MOUSEBUTTONDOWN:
148+
// Get element clicked regardless of mouse button
149+
std::vector<DraggableElement*> clickMatches; //Every element that the cursor clicked on
150+
if (selectedElem == NULL) {
151+
for (auto &d : draggables) {
152+
if (SDL_PointInRect(&mousePos, d->box)) {
153+
clickMatches.push_back(d.get());
154+
}
155+
}
156+
if (!clickMatches.empty()) {
157+
zSortNeeded = true; //Z-index will need to be resorted as this element will be moved to the front
158+
std::stable_sort(clickMatches.begin(), clickMatches.end(), [](DraggableElement* d1, DraggableElement* d2) {
159+
return d1->z > d2->z;
160+
});
161+
162+
selectedElem = clickMatches.back(); //Select rectangle with highest Z-index
163+
selectedElem->z = 0; //Move to front of z-index
164+
}
165+
}
144166
if (!leftClickDown && e.button.button == SDL_BUTTON_LEFT) {
145167
leftClickDown = true;
146-
147-
std::vector<DraggableElement*> clickMatches; //Every element that the mouse clicked on
148168
if (selectedElem == NULL) {
149-
for (auto &d : draggables) {
150-
if (SDL_PointInRect(&mousePos, d->box)) {
151-
clickMatches.push_back(d.get());
152-
}
153-
}
154169
if (!clickMatches.empty()) {
155-
zSortNeeded = true; //Z-index will need to be resorted as this element will be moved to the front
156-
std::stable_sort(clickMatches.begin(), clickMatches.end(), compareZIndexRaw); //Sort matching elements by Z-index, with the highest coming last
157-
158-
selectedElem = clickMatches.back(); //Select rectangle with highest Z-index
159-
selectedElem->z = 0; //Move to front of z-index
160170
clickOffset.x = mousePos.x - selectedElem->box->x;
161171
clickOffset.y = mousePos.y - selectedElem->box->y; //Get clicked point in element box relative to its boundary
162172
}
163173
} else {
164174
clickOffset.x = mousePos.x - selectedElem->box->x;
165175
clickOffset.y = mousePos.y - selectedElem->box->y; //Don't look for a new element to select if one is already selected
166176
}
167-
//Spawn new elements on double click
168-
if (SDL_GetTicks64() > leftClickTick && SDL_GetTicks64() <= leftClickTick + 250) { //Double clicks have to be within 3/8 second of each other
169-
elem::spawnDraggable(draggables, mousePos.x, mousePos.y+32, "air");
170-
elem::spawnDraggable(draggables, mousePos.x, mousePos.y-32, "earth");
171-
elem::spawnDraggable(draggables, mousePos.x-32, mousePos.y, "fire");
172-
elem::spawnDraggable(draggables, mousePos.x+32, mousePos.y, "water");
177+
// Spawn new elements on double click
178+
if (SDL_GetTicks64() > leftClickTick && SDL_GetTicks64() <= leftClickTick + 250) { //Double clicks have to be within 1/4 second of each other
179+
if (selectedElem == NULL) {
180+
elem::spawnDraggable(draggables, mousePos.x, mousePos.y+40, "air");
181+
elem::spawnDraggable(draggables, mousePos.x, mousePos.y-40, "earth");
182+
elem::spawnDraggable(draggables, mousePos.x-40, mousePos.y, "fire");
183+
elem::spawnDraggable(draggables, mousePos.x+40, mousePos.y, "water");
184+
} else {
185+
int hSpawnOffset = ((selectedElem->box->x + selectedElem->box->w/2) > mousePos.x) ? -40 : 40;
186+
int vSpawnOffset = ((selectedElem->box->y + selectedElem->box->h/2) > mousePos.y) ? -40 : 40; //Duplocate the element to the corner it was clicked
187+
elem::spawnDraggable(draggables, selectedElem->box->x+hSpawnOffset, selectedElem->box->y+vSpawnOffset, selectedElem->id); //Duplicate element if it's double clicked
188+
}
173189
}
174190
leftClickTick = SDL_GetTicks64(); //Get next click tick
175191
}
@@ -182,7 +198,8 @@ int main(int argc, char* argv[])
182198
}
183199
// Sort draggable elements by z index when animations finish
184200
if (zSortNeeded && !anim::animInProgress) {
185-
std::stable_sort(draggables.begin(), draggables.end(), [](const std::unique_ptr<DraggableElement> &d1, const std::unique_ptr<DraggableElement> &d2) {
201+
std::stable_sort(draggables.begin(), draggables.end(), []
202+
(const std::unique_ptr<DraggableElement> &d1, const std::unique_ptr<DraggableElement> &d2) {
186203
return d1->z > d2->z;
187204
});
188205
zSortNeeded = false;
@@ -194,21 +211,23 @@ int main(int argc, char* argv[])
194211
if (d->anim == ANIM_SHRINK) {
195212
anim::animateShrink(d.get(), deltaTime);
196213
animDone = true;
214+
} else if (d->anim == ANIM_SHRINK_END) {
215+
d->queuedForDeletion = true; //Queue element for deletion when it finishes shrinking
216+
deleteNeeded = true; //Remove elements when they finish shrinking
217+
animDone = true;
197218
} else if (d->anim == ANIM_GROW) {
198219
anim::animateGrow(d.get(), deltaTime);
199220
animDone = true;
200221
}
201222
anim::animInProgress = animDone; //Stop animations if none are running
202223
}
203-
// Remove combined elements when they finish shrinking
204-
if (elem::firstParentElem != NULL && elem::secondParentElem != NULL && elem::firstParentElem->anim == ANIM_SHRINK_END && elem::secondParentElem->anim == ANIM_SHRINK_END) {
205-
//elem::firstParentElem->queuedForDeletion = true;
206-
//elem::secondParentElem->queuedForDeletion = true;
207-
DraggableElement::deleteElem(draggables, elem::firstParentElem);
208-
DraggableElement::deleteElem(draggables, elem::secondParentElem); //Delete combo elements when they finish shrinking
209-
elem::firstParentElem = NULL;
210-
elem::secondParentElem = NULL;
211-
}
224+
}
225+
// Remove elements that are queued for deletion if needed
226+
if (deleteNeeded) {
227+
draggables.erase(std::remove_if(draggables.begin(), draggables.end(), []
228+
(const std::unique_ptr<DraggableElement> &d) { return d->queuedForDeletion; }
229+
), draggables.end());
230+
deleteNeeded = false;
212231
}
213232

214233
// Load draggable element textures
@@ -227,7 +246,7 @@ int main(int argc, char* argv[])
227246
SDL_RenderCopy(ren, addBtn, NULL, &r); //Render add button
228247

229248
//Render text
230-
FC_Draw(font, ren, 0, 0, "Alchemy++ alpha v0.2");
249+
FC_Draw(font, ren, 0, 0, "Alchemy++ alpha v0.3");
231250

232251
FC_Draw(font, ren, 20, winHeight-20, "elems: %d", draggables.size());
233252

0 commit comments

Comments
 (0)