mirror of
https://github.com/Kapendev/parin.git
synced 2025-04-25 20:49:57 +03:00
Almost done with spatial stuff.
This commit is contained in:
parent
dcb49d6cdd
commit
915b6f92a8
3 changed files with 79 additions and 47 deletions
|
@ -10,9 +10,9 @@
|
|||
module parin.engine;
|
||||
|
||||
import rl = parin.rl;
|
||||
import stdc = joka.stdc;
|
||||
import joka.ascii;
|
||||
import joka.io;
|
||||
import joka.memory;
|
||||
public import joka.containers;
|
||||
public import joka.math;
|
||||
public import joka.types;
|
||||
|
@ -1257,8 +1257,8 @@ void openUrl(IStr url = "https://github.com/Kapendev/parin") {
|
|||
@trusted
|
||||
void openWindow(int width, int height, const(IStr)[] args, IStr title = "Parin") {
|
||||
if (rl.IsWindowReady) return;
|
||||
engineState = cast(EngineState*) stdc.malloc(EngineState.sizeof);
|
||||
stdc.memset(engineState, 0, EngineState.sizeof);
|
||||
engineState = cast(EngineState*) jokaMalloc(EngineState.sizeof);
|
||||
jokaMemset(engineState, 0, EngineState.sizeof);
|
||||
// Raylib stuff.
|
||||
rl.SetConfigFlags(rl.FLAG_WINDOW_RESIZABLE | rl.FLAG_VSYNC_HINT);
|
||||
rl.SetTraceLogLevel(rl.LOG_ERROR);
|
||||
|
@ -1411,7 +1411,7 @@ void closeWindow() {
|
|||
engineState.loadTextBuffer.free();
|
||||
engineState.saveTextBuffer.free();
|
||||
engineState.assetsPath.free();
|
||||
stdc.free(engineState);
|
||||
jokaFree(engineState);
|
||||
engineState = null;
|
||||
rl.CloseAudioDevice();
|
||||
rl.CloseWindow();
|
||||
|
@ -1918,34 +1918,28 @@ dchar dequeuePressedRune() {
|
|||
/// Returns the directional input based on the WASD and arrow keys when they are down.
|
||||
/// The vector is not normalized.
|
||||
Vec2 wasd() {
|
||||
auto result = Vec2();
|
||||
if (Keyboard.w.isDown || Keyboard.up.isDown) result.y -= 1.0f;
|
||||
if (Keyboard.a.isDown || Keyboard.left.isDown) result.x -= 1.0f;
|
||||
if (Keyboard.s.isDown || Keyboard.down.isDown) result.y += 1.0f;
|
||||
if (Keyboard.d.isDown || Keyboard.right.isDown) result.x += 1.0f;
|
||||
return result;
|
||||
with (Keyboard) return Vec2(
|
||||
(d.isDown || right.isDown) - (a.isDown || left.isDown),
|
||||
(s.isDown || down.isDown) - (w.isDown || up.isDown),
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the directional input based on the WASD and arrow keys when they are pressed.
|
||||
/// The vector is not normalized.
|
||||
Vec2 wasdPressed() {
|
||||
auto result = Vec2();
|
||||
if (Keyboard.w.isPressed || Keyboard.up.isPressed) result.y -= 1.0f;
|
||||
if (Keyboard.a.isPressed || Keyboard.left.isPressed) result.x -= 1.0f;
|
||||
if (Keyboard.s.isPressed || Keyboard.down.isPressed) result.y += 1.0f;
|
||||
if (Keyboard.d.isPressed || Keyboard.right.isPressed) result.x += 1.0f;
|
||||
return result;
|
||||
with (Keyboard) return Vec2(
|
||||
(d.isPressed || right.isPressed) - (a.isPressed || left.isPressed),
|
||||
(s.isPressed || down.isPressed) - (w.isPressed || up.isPressed),
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the directional input based on the WASD and arrow keys when they are released.
|
||||
/// The vector is not normalized.
|
||||
Vec2 wasdReleased() {
|
||||
auto result = Vec2();
|
||||
if (Keyboard.w.isReleased || Keyboard.up.isReleased) result.y -= 1.0f;
|
||||
if (Keyboard.a.isReleased || Keyboard.left.isReleased) result.x -= 1.0f;
|
||||
if (Keyboard.s.isReleased || Keyboard.down.isReleased) result.y += 1.0f;
|
||||
if (Keyboard.d.isReleased || Keyboard.right.isReleased) result.x += 1.0f;
|
||||
return result;
|
||||
with (Keyboard) return Vec2(
|
||||
(d.isReleased || right.isReleased) - (a.isReleased || left.isReleased),
|
||||
(s.isReleased || down.isReleased) - (w.isReleased || up.isReleased),
|
||||
);
|
||||
}
|
||||
|
||||
/// Plays the specified sound.
|
||||
|
|
|
@ -155,12 +155,12 @@ struct BoxWorld {
|
|||
foreach (i, ref properties; wallsProperties) {
|
||||
auto id = cast(BaseBoxId) (i + 1);
|
||||
auto point = getWallGridPoint(id);
|
||||
grid[point.y, point.x].append(id & ~taggedBoxTagBit);
|
||||
if (hasGridPoint(point)) grid[point.y, point.x].append(id & ~taggedBoxTagBit);
|
||||
}
|
||||
foreach (i, ref properties; actorsProperties) {
|
||||
auto id = cast(BaseBoxId) (i + 1);
|
||||
auto point = getActorGridPoint(id);
|
||||
grid[point.y, point.x].append(id | taggedBoxTagBit);
|
||||
if (hasGridPoint(point)) grid[point.y, point.x].append(id | taggedBoxTagBit);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,6 +171,7 @@ struct BoxWorld {
|
|||
}
|
||||
|
||||
IVec2 getGridPoint(IRect box) {
|
||||
if (!grid.length) assert(0, "Can't get a grid point from a disabled grid.");
|
||||
return IVec2(
|
||||
box.position.x / gridTileWidth - (box.position.x < 0),
|
||||
box.position.y / gridTileHeight - (box.position.y < 0),
|
||||
|
@ -207,6 +208,10 @@ struct BoxWorld {
|
|||
return getGridPoint(actors[id - 1]);
|
||||
}
|
||||
|
||||
bool hasGridPoint(IVec2 point) {
|
||||
return point.x >= 0 && point.y >= 0 && grid.has(point.y, point.x);
|
||||
}
|
||||
|
||||
WallBoxId appendWall(IRect box, OneWaySide oneWaySide = OneWaySide.none) {
|
||||
walls.append(box);
|
||||
wallsProperties.append(WallBoxProperties());
|
||||
|
@ -214,8 +219,7 @@ struct BoxWorld {
|
|||
auto id = cast(BaseBoxId) walls.length;
|
||||
if (grid.length) {
|
||||
auto point = getGridPoint(box);
|
||||
if (box.position.x < 0 || box.position.y < 0 || !grid.has(point.y, point.x)) return id;
|
||||
grid[point.y, point.x].append(id & ~taggedBoxTagBit);
|
||||
if (hasGridPoint(point)) grid[point.y, point.x].append(id & ~taggedBoxTagBit);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
@ -227,65 +231,76 @@ struct BoxWorld {
|
|||
auto id = cast(BaseBoxId) actors.length;
|
||||
if (grid.length) {
|
||||
auto point = getGridPoint(box);
|
||||
if (box.position.x < 0 || box.position.y < 0 || !grid.has(point.y, point.x)) return id;
|
||||
grid[point.y, point.x].append(id | taggedBoxTagBit);
|
||||
if (hasGridPoint(point)) grid[point.y, point.x].append(id | taggedBoxTagBit);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
WallBoxId[] getWallCollisions(IRect box) {
|
||||
WallBoxId[] getWallCollisions(IRect box, bool canStopAtFirst = false) {
|
||||
collisionIdsBuffer.clear();
|
||||
// TODO: Try not going over every neighboring cell please...
|
||||
if (grid.length) {
|
||||
auto point = getGridPoint(box);
|
||||
foreach (y; -1 .. 2) { foreach (x; -1 .. 2) {
|
||||
auto otherPoint = IVec2(point.x + x, point.y + y);
|
||||
if (otherPoint.x < 0 || otherPoint.y < 0 || !grid.has(otherPoint.y, otherPoint.x)) continue;
|
||||
foreach (taggedId; grid[point.y + y, point.x + x]) {
|
||||
if (!hasGridPoint(otherPoint)) continue;
|
||||
foreach (taggedId; grid[otherPoint.y, otherPoint.x]) {
|
||||
auto i = (taggedId & ~taggedBoxTagBit) - 1;
|
||||
auto isActor = taggedId & taggedBoxTagBit;
|
||||
if (isActor) continue;
|
||||
if (walls[i].hasIntersection(box) && ~wallsProperties[i].flags & boxPassableFlag) collisionIdsBuffer.append(cast(BaseBoxId) (i + 1));
|
||||
if (walls[i].hasIntersection(box) && ~wallsProperties[i].flags & boxPassableFlag) {
|
||||
collisionIdsBuffer.append(cast(BaseBoxId) (i + 1));
|
||||
if (canStopAtFirst) return collisionIdsBuffer[];
|
||||
}
|
||||
}
|
||||
}}
|
||||
} else {
|
||||
foreach (i, wall; walls) {
|
||||
if (wall.hasIntersection(box) && ~wallsProperties[i].flags & boxPassableFlag) collisionIdsBuffer.append(cast(BaseBoxId) (i + 1));
|
||||
if (wall.hasIntersection(box) && ~wallsProperties[i].flags & boxPassableFlag) {
|
||||
collisionIdsBuffer.append(cast(BaseBoxId) (i + 1));
|
||||
if (canStopAtFirst) return collisionIdsBuffer[];
|
||||
}
|
||||
}
|
||||
}
|
||||
return collisionIdsBuffer[];
|
||||
}
|
||||
|
||||
ActorBoxId[] getActorCollisions(IRect box) {
|
||||
ActorBoxId[] getActorCollisions(IRect box, bool canStopAtFirst = false) {
|
||||
collisionIdsBuffer.clear();
|
||||
// TODO: Try not going over every neighboring cell please...
|
||||
if (grid.length) {
|
||||
auto point = getGridPoint(box);
|
||||
foreach (y; -1 .. 2) { foreach (x; -1 .. 2) {
|
||||
auto otherPoint = IVec2(point.x + x, point.y + y);
|
||||
if (otherPoint.x < 0 || otherPoint.y < 0 || !grid.has(otherPoint.y, otherPoint.x)) continue;
|
||||
foreach (taggedId; grid[point.y + y, point.x + x]) {
|
||||
if (!hasGridPoint(otherPoint)) continue;
|
||||
foreach (taggedId; grid[otherPoint.y, otherPoint.x]) {
|
||||
auto i = (taggedId & ~taggedBoxTagBit) - 1;
|
||||
auto isWall = !(taggedId & taggedBoxTagBit);
|
||||
if (isWall) continue;
|
||||
if (actors[i].hasIntersection(box) && ~actorsProperties[i].flags & boxPassableFlag) collisionIdsBuffer.append(cast(BaseBoxId) (i + 1));
|
||||
if (actors[i].hasIntersection(box) && ~actorsProperties[i].flags & boxPassableFlag) {
|
||||
collisionIdsBuffer.append(cast(BaseBoxId) (i + 1));
|
||||
if (canStopAtFirst) return collisionIdsBuffer[];
|
||||
}
|
||||
}
|
||||
}}
|
||||
} else {
|
||||
foreach (i, actor; actors) {
|
||||
if (actor.hasIntersection(box) && ~actorsProperties[i].flags & boxPassableFlag) collisionIdsBuffer.append(cast(BaseBoxId) (i + 1));
|
||||
if (actor.hasIntersection(box) && ~actorsProperties[i].flags & boxPassableFlag) {
|
||||
collisionIdsBuffer.append(cast(BaseBoxId) (i + 1));
|
||||
if (canStopAtFirst) return collisionIdsBuffer[];
|
||||
}
|
||||
}
|
||||
}
|
||||
return collisionIdsBuffer[];
|
||||
}
|
||||
|
||||
WallBoxId hasWallCollision(IRect box) {
|
||||
auto boxes = getWallCollisions(box);
|
||||
auto boxes = getWallCollisions(box, true);
|
||||
return boxes.length ? boxes[0] : 0;
|
||||
}
|
||||
|
||||
ActorBoxId hasActorCollision(IRect box) {
|
||||
auto boxes = getActorCollisions(box);
|
||||
auto boxes = getActorCollisions(box, true);
|
||||
return boxes.length ? boxes[0] : 0;
|
||||
}
|
||||
|
||||
|
@ -323,8 +338,31 @@ struct BoxWorld {
|
|||
if (~properties.flags & boxPassableFlag && wallId) {
|
||||
return wallId;
|
||||
} else {
|
||||
actor.position.x += moveSign;
|
||||
move -= moveSign;
|
||||
if (grid.length) {
|
||||
auto oldPoint = getGridPoint(*actor);
|
||||
actor.position.x += moveSign;
|
||||
move -= moveSign;
|
||||
auto newPoint = getGridPoint(*actor);
|
||||
// TODO: Maybe think of how not to write this again. ...
|
||||
if (oldPoint != newPoint) {
|
||||
if (hasGridPoint(oldPoint)) {
|
||||
foreach (j, taggedId; grid[oldPoint.y, oldPoint.x]) {
|
||||
auto i = (taggedId & ~taggedBoxTagBit) - 1;
|
||||
auto isActor = taggedId & taggedBoxTagBit;
|
||||
if (isActor && (i + 1 == id)) {
|
||||
grid[oldPoint.y, oldPoint.x].remove(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasGridPoint(newPoint)) {
|
||||
grid[newPoint.y, newPoint.x].append(id | taggedBoxTagBit);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
actor.position.x += moveSign;
|
||||
move -= moveSign;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
module parin.ui;
|
||||
|
||||
import rl = parin.rl;
|
||||
import stdc = joka.stdc;
|
||||
import joka.ascii;
|
||||
import joka.memory;
|
||||
import parin.engine;
|
||||
|
||||
@safe @nogc nothrow:
|
||||
|
@ -112,10 +112,10 @@ int findSpaceInTextField(IStr text) {
|
|||
void prepareUi() {
|
||||
if (uiState == null) {
|
||||
// NOTE: This leaks. THIS IS SO BAD WHERE IS `Box::leak` IN THIS CODEBASE???
|
||||
uiState = cast(UiState*) stdc.malloc(UiState.sizeof);
|
||||
uiPreviousState = cast(UiState*) stdc.malloc(UiState.sizeof);
|
||||
stdc.memset(uiState, 0, UiState.sizeof);
|
||||
stdc.memset(uiPreviousState, 0, UiState.sizeof);
|
||||
uiState = cast(UiState*) jokaMalloc(UiState.sizeof);
|
||||
uiPreviousState = cast(UiState*) jokaMalloc(UiState.sizeof);
|
||||
jokaMemset(uiState, 0, UiState.sizeof);
|
||||
jokaMemset(uiPreviousState, 0, UiState.sizeof);
|
||||
// TODO: Should be changed to something better looking.
|
||||
uiState.mouseClickAction = Mouse.left;
|
||||
uiState.keyboardClickAction = Keyboard.enter;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue