From a8e3f6a7b3d0b2d889f54a703a329c07d50f094e Mon Sep 17 00:00:00 2001 From: JanEhehalt Date: Fri, 25 Nov 2022 11:44:47 +0100 Subject: [PATCH] Sprites on World Coordinates --- Input/inputHandler.c | 42 +++++++++++++++++++------------- Input/inputHandler.h | 1 + IsometricMap/isometricMap.c | 33 ++++++------------------- IsometricMap/isometricMap.h | 11 +++++---- IsometricMap/isometricRenderer.c | 9 ++++--- IsometricMap/isometricRenderer.h | 1 + List/list.c | 4 +-- List/list.h | 4 ++- README.md | 2 +- main.c | 15 ++++++------ sprite.c | 21 +++++++++++++--- sprite.h | 4 ++- 12 files changed, 80 insertions(+), 67 deletions(-) diff --git a/Input/inputHandler.c b/Input/inputHandler.c index 05a342f..2cdadef 100644 --- a/Input/inputHandler.c +++ b/Input/inputHandler.c @@ -60,11 +60,16 @@ void mouseInput(InputHandler *inputHandler, List *sprites, Texture2D *texture, C inputHandler->cursorPos.y = GetMousePosition().y; // resetting last selected Tile to grass texture - int n = 9; if(inputHandler->selectedLayer != -1){ - IsometricMapChangeTextureIdOfTile(layers[inputHandler->selectedLayer], (int) inputHandler->cursorWorldPos.x, (int) inputHandler->cursorWorldPos.y, 0); - } - // TODO: n=2 no good style, but Segmentation fault when > layerAmount + IsometricMapChangeTextureIdOfTile(layers[inputHandler->selectedLayer], (int) inputHandler->cursorWorldTile.x, (int) inputHandler->cursorWorldTile.y, 0); + } + /* + TODO: n=9 no good style, Segmentation fault when n > layerAmount + impossible to find out size of array on the fly? + -> Stash size in another variable. + printf("%ld \n", sizeof(*layers) / sizeof(layers[0])); + */ + int n = 9; for(n = 9; n >= 0 ; n--){ if(layers[n] != 0){ float tileWidthHalf = layers[n]->tileTextures[0].width / 2; @@ -77,11 +82,11 @@ void mouseInput(InputHandler *inputHandler, List *sprites, Texture2D *texture, C Tile *selectedTile = IsometricMapGetTileFromWorldCoordinates(layers[n], inputHandler->cursorWorldPos.x, inputHandler->cursorWorldPos.y); if(selectedTile != 0){ - inputHandler->cursorWorldPos.x = selectedTile->x; - inputHandler->cursorWorldPos.y = selectedTile->y; - // setting currently selected tile to tower + inputHandler->cursorWorldTile.x = selectedTile->x; + inputHandler->cursorWorldTile.y = selectedTile->y; inputHandler->selectedLayer = n; - IsometricMapChangeTextureIdOfTile(layers[n], (int) inputHandler->cursorWorldPos.x, (int) inputHandler->cursorWorldPos.y, 1); + // setting currently selected tile to tower + IsometricMapChangeTextureIdOfTile(layers[n], inputHandler->cursorWorldTile.x, inputHandler->cursorWorldTile.y, 1); break; } } @@ -106,23 +111,25 @@ void mouseInput(InputHandler *inputHandler, List *sprites, Texture2D *texture, C if(IsMouseButtonReleased(MOUSE_BUTTON_LEFT)){ inputHandler->pressed = 0; - // Cursorsprite is rechanged to normal + // Cursorsprite is changed back to normal inputHandler->cursorSprite->texture = (inputHandler->cursorTextures); float width = GetMousePosition().x - inputHandler->rectStart.x; float height = GetMousePosition().y - inputHandler->rectStart.y; // Add Sprite if(width + height <= 1){ - ListInsertBack(sprites, SpriteCreate(texture, inputHandler->cursorPos.x + (*camera).target.x - (texture->width)/2, inputHandler->cursorPos.y + (*camera).target.y - (texture->height)/2)); + ListInsertBack(sprites, SpriteCreate(texture, inputHandler->cursorWorldPos.x, inputHandler->cursorWorldPos.y)); } - // Berechnung, welche Sprites ausgewählt wurden + // Berechnung, welche Sprites ausgewählt wurden, scuffed Vector2 rect = GetRectangle(inputHandler->rectStart); width = abs(width); height = abs(height); printf("Auswahl: x: %f, y: %f, w: %f, h: %f\n", rect.x, rect.y, width, height); + + // TODO: update to World Coordinates float deltaX; float deltaY; Node *current = sprites->head; @@ -149,8 +156,8 @@ void mouseInput(InputHandler *inputHandler, List *sprites, Texture2D *texture, C while (current != 0){ if(current->data.selected){ current->data.hasDestination = 1; - current->data.destX = inputHandler->cursorPos.x + (*camera).target.x - (texture->width)/2; - current->data.destY = inputHandler->cursorPos.y + (*camera).target.y - (texture->height)/2; + current->data.destX = inputHandler->cursorWorldPos.x; + current->data.destY = inputHandler->cursorWorldPos.y; } current = current->next; @@ -159,16 +166,17 @@ void mouseInput(InputHandler *inputHandler, List *sprites, Texture2D *texture, C } void keyboardInput(InputHandler *inputHandler, Camera2D *camera){ + float camSpeed = 1000.0f; if(IsKeyDown(KEY_W)){ - (*camera).target.y -= 1000.0f * GetFrameTime(); + (*camera).target.y -= camSpeed * GetFrameTime(); } if(IsKeyDown(KEY_S)){ - (*camera).target.y += 1000.0f * GetFrameTime(); + (*camera).target.y += camSpeed * GetFrameTime(); } if(IsKeyDown(KEY_D)){ - (*camera).target.x += 1000.0f * GetFrameTime(); + (*camera).target.x += camSpeed * GetFrameTime(); } if(IsKeyDown(KEY_A)){ - (*camera).target.x -= 1000.0f * GetFrameTime(); + (*camera).target.x -= camSpeed * GetFrameTime(); } } \ No newline at end of file diff --git a/Input/inputHandler.h b/Input/inputHandler.h index 25ac277..68f7627 100644 --- a/Input/inputHandler.h +++ b/Input/inputHandler.h @@ -10,6 +10,7 @@ typedef struct InputHandler{ Vector2 rectStart; Vector2 cursorPos; Vector2 cursorWorldPos; + Vector2 cursorWorldTile; int selectedLayer; Texture2D *cursorTextures; Sprite *cursorSprite; diff --git a/IsometricMap/isometricMap.c b/IsometricMap/isometricMap.c index 486d968..5a5bf94 100644 --- a/IsometricMap/isometricMap.c +++ b/IsometricMap/isometricMap.c @@ -7,6 +7,7 @@ IsometricMap * IsometricMapInit(int layer){ IsometricMap* map = (IsometricMap *) malloc(sizeof(IsometricMap)); + map->tileTextures[0] = LoadTexture("assets/grass.png"); map->tileTextures[1] = LoadTexture("assets/tower.png"); @@ -37,21 +38,13 @@ IsometricMap * IsometricMapInit(int layer){ } map->tiles = tiles; - return map; } - Vector2 * IsometricMapCalcOffsetForTileAt(int x, int y, int textureSize){ - Vector2* offset = (Vector2 *)malloc(sizeof(Vector2)); - - offset->x = x * textureSize/2; - offset->y = x * textureSize/4; - - offset->x -= y * textureSize/2; - offset->y += y * textureSize/4; - + offset->x = x * textureSize/2 - y * textureSize/2; + offset->y = x * textureSize/4 + y * textureSize/4; return offset; } @@ -59,6 +52,7 @@ Tile * IsometricMapGetTileFromArrayPosition(IsometricMap *map, int x, int y){ return map->tiles[x][y]; } +// Project: Screen Coordinates -> World Coordinates void IsometricMapProject(IsometricMap *isometricMap, Camera2D *camera, float x, float y, Vector2 *tmp){ float tileWidthHalf = isometricMap->tileTextures[0].width / 2; @@ -78,8 +72,8 @@ void IsometricMapProject(IsometricMap *isometricMap, Camera2D *camera, float x, tmp->y = isoY * isometricMap->tileTextures[0].height; } +// Unproject: World Coordinates -> Screen Coordinates void IsometricMapUnproject(IsometricMap *isometricMap, Camera2D *camera, int x, int y, Vector2 *tmp){ - float xPos = (float) x; float yPos = (float) y; @@ -91,11 +85,8 @@ void IsometricMapUnproject(IsometricMap *isometricMap, Camera2D *camera, int x, tmp->x = worldX; tmp->y = worldY; - } - - Tile * IsometricMapGetTileFromWorldCoordinates(IsometricMap *isometricMap, float x, float y){ x = (int)(x / isometricMap->tileTextures->width); @@ -117,15 +108,12 @@ Tile * IsometricMapGetTileFromWorldCoordinates(IsometricMap *isometricMap, float return ptr; } - - +// IsometricMapAddTile and IsometricMapChangeTextureIdOfTile pretty much do the same by now... void IsometricMapAddTile(IsometricMap *isometricMap, int x, int y, int textureId){ isometricMap->tiles[x][y]->textureId = textureId; isometricMap->tiles[x][y]->x = x; - isometricMap->tiles[x][y]->y = y; - + isometricMap->tiles[x][y]->y = y; } - void IsometricMapChangeTextureIdOfTile(IsometricMap *map, int x, int y, int id){ if( x < map->widthBounds && y < map->heightBounds && x >= 0 && y >= 0 ){ @@ -133,10 +121,3 @@ void IsometricMapChangeTextureIdOfTile(IsometricMap *map, int x, int y, int id){ } } - - - - - - - diff --git a/IsometricMap/isometricMap.h b/IsometricMap/isometricMap.h index 172e98c..5a76f81 100644 --- a/IsometricMap/isometricMap.h +++ b/IsometricMap/isometricMap.h @@ -15,19 +15,20 @@ typedef struct IsometricMap{ int layer; } IsometricMap; -// TODO: -Tile * IsometricMapGetTileFromWorldCoordinates(IsometricMap *isometricMap, float x, float y); +// --- TODO functions: --- + -// Working +// --- Working ----------- IsometricMap * IsometricMapInit(int layer); Vector2 * IsometricMapCalcOffsetForTileAt(int x, int y, int textureSize); Tile * IsometricMapGetTileFromArrayPosition(IsometricMap *isometricMap, int x, int y); -// Screen Coordinates -> World Coordinates +// Project: Screen Coordinates -> World Coordinates void IsometricMapProject(IsometricMap *isometricMap, Camera2D *camera, float x, float y, Vector2 *tmp); -// World Coordinates -> Screen Coordinates +// Unproject: World Coordinates -> Screen Coordinates void IsometricMapUnproject(IsometricMap *isometricMap, Camera2D *camera, int x, int y, Vector2 *tmp); void IsometricMapAddTile(IsometricMap *isometricMap, int x, int y, int textureId); void IsometricMapChangeTextureIdOfTile(IsometricMap *map, int x, int y, int id); +Tile * IsometricMapGetTileFromWorldCoordinates(IsometricMap *isometricMap, float x, float y); #endif \ No newline at end of file diff --git a/IsometricMap/isometricRenderer.c b/IsometricMap/isometricRenderer.c index 46788c3..1482d61 100644 --- a/IsometricMap/isometricRenderer.c +++ b/IsometricMap/isometricRenderer.c @@ -4,10 +4,12 @@ #include "../Input/inputHandler.h" #include -//TODO: Isometric Tilemap Struct, which can be scanned for clicked Tile -// General coordinate translation function - +// @param deprecated void IsometricRendererDrawMap(IsometricRenderer *renderer, int height){ + + printf("WARNING: Using deprecated Function IsometricRendererDrawMap!\n"); + + float originX = 0.0f; float originY = 0.0f; @@ -36,7 +38,6 @@ void IsometricRendererDrawMap(IsometricRenderer *renderer, int height){ } void IsometricRendererRenderIsometricMap(IsometricMap **map, InputHandler *input){ - int n = 0; int i = 0; int j = 0; diff --git a/IsometricMap/isometricRenderer.h b/IsometricMap/isometricRenderer.h index 685ec6c..7de86d0 100644 --- a/IsometricMap/isometricRenderer.h +++ b/IsometricMap/isometricRenderer.h @@ -8,6 +8,7 @@ typedef struct IsometricRenderer{ Texture *texture; } IsometricRenderer; +// @param deprecated void IsometricRendererDrawMap(IsometricRenderer *renderer, int height); void IsometricRendererRenderIsometricMap(IsometricMap **map, InputHandler *input); diff --git a/List/list.c b/List/list.c index 515eaf5..39ba93a 100644 --- a/List/list.c +++ b/List/list.c @@ -67,11 +67,11 @@ List * ListInit(){ return newList; } -void ListDrawAllSprites(List *list){ +void ListDrawAllSprites(List *list, IsometricMap *map, Camera2D *camera){ Node *current = list->head; while(current != 0){ - DrawSprite(¤t->data); + DrawSpriteToWorld(¤t->data, map, camera); current = current->next; } } diff --git a/List/list.h b/List/list.h index e8de5a1..2fda7d9 100644 --- a/List/list.h +++ b/List/list.h @@ -1,6 +1,8 @@ #ifndef LIST_H_ #define LIST_H_ #include "../sprite.h" +#include "../IsometricMap/isometricMap.h" +#include "raylib.h" typedef struct Node Node; typedef struct List List; @@ -26,6 +28,6 @@ void ListPrintForward(List *list); void ListInsertFront(List *list, Sprite *data); void ListInsertBack(List *list, Sprite *data); List * ListInit(); -void ListDrawAllSprites(List *list); +void ListDrawAllSprites(List *list, IsometricMap *map, Camera2D *camera); #endif diff --git a/README.md b/README.md index ad3d6dc..b52de6e 100644 --- a/README.md +++ b/README.md @@ -16,5 +16,5 @@ Fantasy Welt oder Realistisch? ## TODO + LinkedList erweitern -+ Sprites in World Koordinaten einbinden + Sprites Animationen etc improven ++ Sprite Auswahlrechteck in inputHandler umschreiben auf World Koordinaten. Sprites an sich sind auf World Koordinaten geändert \ No newline at end of file diff --git a/main.c b/main.c index 2e6fbbe..1e793c9 100644 --- a/main.c +++ b/main.c @@ -48,6 +48,8 @@ int main(){ inputHandler.cursorPos.y = 0; inputHandler.cursorWorldPos.x = 0; inputHandler.cursorWorldPos.y = 0; + inputHandler.cursorWorldTile.x = 0; + inputHandler.cursorWorldTile.y = 0; inputHandler.selectedLayer = -1; inputHandler.cursorTextures = cursorTextures; inputHandler.cursorSprite = &cursorSprite; @@ -124,27 +126,26 @@ int main(){ BeginMode2D(camera); - //IsometricRendererRenderIsometricMap(map, &inputHandler); - //IsometricRendererRenderIsometricMap(Layer1, &inputHandler); - //IsometricRendererRenderIsometricMap(Layer2, &inputHandler); - //IsometricRendererRenderIsometricMap(Layer3, &inputHandler); - //IsometricRendererRenderIsometricMap(Layer4, &inputHandler); IsometricRendererRenderIsometricMap(layers, &inputHandler); - ListDrawAllSprites(sprites); + ListDrawAllSprites(sprites, layers[0], &camera); EndMode2D(); // Moving cursor Sprite to Mouse Pos and drawing it cursorSprite.x = inputHandler.cursorPos.x; cursorSprite.y = inputHandler.cursorPos.y; - DrawSprite(&cursorSprite); + DrawSpriteToScreen(&cursorSprite); // User Input Handling mouseInput(&inputHandler, sprites, worker+4, &camera, layers); keyboardInput(&inputHandler, &camera); + //cursor Positions test + //printf("Cursor Pos: %f %f\n", inputHandler.cursorPos.x, inputHandler.cursorPos.y); + //printf("Cursor World Pos: %f %f\n", inputHandler.cursorWorldPos.x, inputHandler.cursorWorldPos.y); + // Sprites move towards their destination float movementSpeed = 10.0f; Node *current = sprites->head; diff --git a/sprite.c b/sprite.c index 4b23b3c..fe059c6 100644 --- a/sprite.c +++ b/sprite.c @@ -20,7 +20,22 @@ void SpriteAdd(Sprite *sprites, int *spriteAmount, Texture2D *texture, int x, in } } -void DrawSprite(Sprite *sprite){ +void DrawSpriteToWorld(Sprite *sprite, IsometricMap *map, Camera2D *camera){ + + Vector2 pos = {sprite->x, sprite->y}; + IsometricMapUnproject(map, camera, pos.x, pos.y, &pos); + pos.x -= camera->target.x; + pos.y -= camera->target.y; + if(sprite->selected){ + DrawTexture(*sprite->texture, pos.x, pos.y, WHITE); + //DrawTexture(*sprite->texture, sprite->x, sprite->y, BLACK); + } + else{ + DrawTexture(*sprite->texture, pos.x, pos.y, WHITE); + } +} + +void DrawSpriteToScreen(Sprite *sprite){ if(sprite->selected){ DrawTexture(*sprite->texture, sprite->x, sprite->y, WHITE); @@ -35,8 +50,8 @@ Sprite * SpriteCreate(Texture2D *texture, int x, int y){ Sprite *newSprite = (Sprite *) malloc(sizeof(Sprite)); newSprite->texture = texture; - newSprite->x = x; - newSprite->y = y; + newSprite->x = x - texture->width / 2; + newSprite->y = y - texture->height / 2; newSprite->destX = x; newSprite->destY = y; newSprite->hasDestination = 0; diff --git a/sprite.h b/sprite.h index a0b0771..ddc0c65 100644 --- a/sprite.h +++ b/sprite.h @@ -1,6 +1,7 @@ #ifndef SPRITE_H_ #define SPRITE_H_ #include "raylib.h" +#include "IsometricMap/isometricMap.h" typedef struct Sprite { Texture2D *texture; @@ -14,7 +15,8 @@ typedef struct Sprite { void SpriteAdd(Sprite *sprites, int *spriteAmount, Texture2D *texture, int x, int y); -void DrawSprite(Sprite *sprite); +void DrawSpriteToWorld(Sprite *sprite, IsometricMap *map, Camera2D *camera); +void DrawSpriteToScreen(Sprite *sprite); Sprite * SpriteCreate(Texture2D *texture, int x, int y);