mirror of
https://github.com/Kapendev/parin.git
synced 2025-04-27 13:39:54 +03:00
Example changes and some structs have positions now.
This commit is contained in:
parent
66b07f3684
commit
3b5e98ae4b
7 changed files with 93 additions and 44 deletions
|
@ -4,7 +4,7 @@ import parin;
|
||||||
// The game variables.
|
// The game variables.
|
||||||
auto camera = Camera(0, -14);
|
auto camera = Camera(0, -14);
|
||||||
auto cameraTarget = Vec2(0, -14);
|
auto cameraTarget = Vec2(0, -14);
|
||||||
auto cameraSpeed = Vec2(120);
|
auto cameraSpeed = 120;
|
||||||
|
|
||||||
void ready() {
|
void ready() {
|
||||||
lockResolution(320, 180);
|
lockResolution(320, 180);
|
||||||
|
@ -12,7 +12,7 @@ void ready() {
|
||||||
|
|
||||||
bool update(float dt) {
|
bool update(float dt) {
|
||||||
// Move the camera.
|
// Move the camera.
|
||||||
cameraTarget += wasd * cameraSpeed * Vec2(dt);
|
cameraTarget += wasd * Vec2(cameraSpeed * dt);
|
||||||
camera.followPositionWithSlowdown(cameraTarget, 0.15);
|
camera.followPositionWithSlowdown(cameraTarget, 0.15);
|
||||||
|
|
||||||
// Draw the game world.
|
// Draw the game world.
|
||||||
|
|
|
@ -3,7 +3,7 @@ import parin;
|
||||||
|
|
||||||
// The game variables.
|
// The game variables.
|
||||||
auto player = Rect(16, 16);
|
auto player = Rect(16, 16);
|
||||||
auto playerSpeed = Vec2(120);
|
auto playerSpeed = 120;
|
||||||
|
|
||||||
auto coins = SparseList!Rect();
|
auto coins = SparseList!Rect();
|
||||||
auto coinSize = Vec2(8);
|
auto coinSize = Vec2(8);
|
||||||
|
@ -33,7 +33,7 @@ bool update(float dt) {
|
||||||
if (Keyboard.right.isDown || 'd'.isDown) playerDirection.x = 1;
|
if (Keyboard.right.isDown || 'd'.isDown) playerDirection.x = 1;
|
||||||
if (Keyboard.up.isDown || 'w'.isDown) playerDirection.y = -1;
|
if (Keyboard.up.isDown || 'w'.isDown) playerDirection.y = -1;
|
||||||
if (Keyboard.down.isDown || 's'.isDown) playerDirection.y = 1;
|
if (Keyboard.down.isDown || 's'.isDown) playerDirection.y = 1;
|
||||||
player.position += playerDirection * playerSpeed * Vec2(dt);
|
player.position += playerDirection * Vec2(playerSpeed * dt);
|
||||||
|
|
||||||
// Check if the player is touching some coins and remove those coins.
|
// Check if the player is touching some coins and remove those coins.
|
||||||
foreach (id; coins.ids) {
|
foreach (id; coins.ids) {
|
||||||
|
|
|
@ -3,11 +3,8 @@ import parin;
|
||||||
|
|
||||||
// The game variables.
|
// The game variables.
|
||||||
auto atlas = TextureId();
|
auto atlas = TextureId();
|
||||||
|
|
||||||
auto sprite = Sprite(16, 16, 0, 128);
|
auto sprite = Sprite(16, 16, 0, 128);
|
||||||
auto spritePosition = Vec2();
|
|
||||||
auto spriteFlip = Flip.none;
|
auto spriteFlip = Flip.none;
|
||||||
|
|
||||||
auto idleAnimation = SpriteAnimation(0, 1, 6);
|
auto idleAnimation = SpriteAnimation(0, 1, 6);
|
||||||
auto walkAnimation = SpriteAnimation(0, 2, 6);
|
auto walkAnimation = SpriteAnimation(0, 2, 6);
|
||||||
|
|
||||||
|
@ -25,10 +22,10 @@ bool update(float dt) {
|
||||||
sprite.update(dt);
|
sprite.update(dt);
|
||||||
|
|
||||||
// Get some basic info about the mouse.
|
// Get some basic info about the mouse.
|
||||||
auto mouseDistance = spritePosition.distanceTo(mouseScreenPosition);
|
auto mouseDistance = sprite.position.distanceTo(mouseScreenPosition);
|
||||||
auto mouseDirection = spritePosition.directionTo(mouseScreenPosition);
|
auto mouseDirection = sprite.position.directionTo(mouseScreenPosition);
|
||||||
// Move the sprite around in a smooth way.
|
// Move the sprite around in a smooth way.
|
||||||
spritePosition = spritePosition.moveToWithSlowdown(mouseScreenPosition, Vec2(dt), 0.2);
|
sprite.followPositionWithSlowdown(mouseScreenPosition, 0.2);
|
||||||
|
|
||||||
// Play the right animation.
|
// Play the right animation.
|
||||||
auto isWaiting = mouseDistance < 0.2;
|
auto isWaiting = mouseDistance < 0.2;
|
||||||
|
@ -59,7 +56,7 @@ bool update(float dt) {
|
||||||
options.scale = Vec2(2);
|
options.scale = Vec2(2);
|
||||||
|
|
||||||
// Draw the sprite, the mouse position and some info.
|
// Draw the sprite, the mouse position and some info.
|
||||||
drawSprite(atlas, sprite, spritePosition, options);
|
drawSprite(atlas, sprite, options);
|
||||||
drawVec2(mouseScreenPosition, 8, isWaiting ? blank : white.alpha(150));
|
drawVec2(mouseScreenPosition, 8, isWaiting ? blank : white.alpha(150));
|
||||||
drawDebugText("Press 1, 2 or 3 to change the character.", Vec2(8));
|
drawDebugText("Press 1, 2 or 3 to change the character.", Vec2(8));
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -4,9 +4,10 @@ import parin;
|
||||||
// The game variables.
|
// The game variables.
|
||||||
auto atlas = TextureId();
|
auto atlas = TextureId();
|
||||||
auto map = TileMap();
|
auto map = TileMap();
|
||||||
auto playerTile = Tile(145, 16, 16);
|
auto camera = Camera(0, 0, true);
|
||||||
auto playerPosition = Vec2();
|
auto tile = Tile(145, 16, 16);
|
||||||
auto playerSpeed = Vec2(120);
|
auto tileSpeed = 120;
|
||||||
|
auto tileLookDirection = -1;
|
||||||
|
|
||||||
void ready() {
|
void ready() {
|
||||||
lockResolution(320, 180);
|
lockResolution(320, 180);
|
||||||
|
@ -18,11 +19,21 @@ void ready() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update(float dt) {
|
bool update(float dt) {
|
||||||
playerPosition += wasd * playerSpeed * Vec2(dt);
|
tile.position += wasd * Vec2(tileSpeed * dt);
|
||||||
|
camera.followPosition(tile.position, tileSpeed);
|
||||||
|
if (wasd.x != 0) tileLookDirection = cast(int) wasd.normalize.round.x;
|
||||||
|
|
||||||
|
// Make some options.
|
||||||
|
auto mapOptions = DrawOptions(Hook.center);
|
||||||
|
mapOptions.scale = Vec2(2);
|
||||||
|
auto tileOptions = mapOptions;
|
||||||
|
tileOptions.flip = tileLookDirection > 0 ? Flip.x : Flip.none;
|
||||||
|
|
||||||
// Draw the tile map.
|
// Draw the tile map.
|
||||||
auto options = DrawOptions(Vec2(2));
|
camera.attach();
|
||||||
drawTileMap(atlas, map, Vec2(), Camera(), options);
|
drawTileMap(atlas, map, camera, mapOptions);
|
||||||
drawTile(atlas, playerTile, playerPosition, options);
|
drawTile(atlas, tile, tileOptions);
|
||||||
|
camera.detach();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,12 @@ import parin;
|
||||||
// The game variables.
|
// The game variables.
|
||||||
auto gameCounter = 0;
|
auto gameCounter = 0;
|
||||||
|
|
||||||
auto paddle1 = Rect(2, 30);
|
auto paddle1 = Rect(2, 25);
|
||||||
auto paddle2 = Rect(2, 30);
|
auto paddle2 = Rect(2, 25);
|
||||||
|
|
||||||
auto ball = Rect(5, 5);
|
auto ball = Rect(5, 5);
|
||||||
auto ballSpeed = Vec2(120);
|
|
||||||
auto ballDirection = Vec2(1, 1);
|
auto ballDirection = Vec2(1, 1);
|
||||||
|
auto ballSpeed = 120;
|
||||||
|
|
||||||
void ready() {
|
void ready() {
|
||||||
lockResolution(320, 180);
|
lockResolution(320, 180);
|
||||||
|
@ -28,7 +28,7 @@ bool update(float dt) {
|
||||||
// A centered rectangle is used for collision checking and drawing.
|
// A centered rectangle is used for collision checking and drawing.
|
||||||
|
|
||||||
// Move the ball.
|
// Move the ball.
|
||||||
ball.position += ballDirection * ballSpeed * Vec2(dt);
|
ball.position += ballDirection * Vec2(ballSpeed * dt);
|
||||||
// Check if the ball exited the screen from the left or right side.
|
// Check if the ball exited the screen from the left or right side.
|
||||||
if (ball.centerArea.leftPoint.x < 0) {
|
if (ball.centerArea.leftPoint.x < 0) {
|
||||||
ball.position = resolution * Vec2(0.5);
|
ball.position = resolution * Vec2(0.5);
|
||||||
|
@ -51,13 +51,13 @@ bool update(float dt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move paddle1.
|
// Move paddle1.
|
||||||
paddle1.position.y = clamp(paddle1.position.y + wasd.y * ballSpeed.y * dt, paddle1.size.y * 0.5f, resolutionHeight - paddle1.size.y * 0.5f);
|
paddle1.position.y = clamp(paddle1.position.y + wasd.y * ballSpeed * dt, paddle1.size.y * 0.5f, resolutionHeight - paddle1.size.y * 0.5f);
|
||||||
// Move paddle2.
|
// Move paddle2.
|
||||||
auto paddle2Target = ball.position.y;
|
auto paddle2Target = ball.position.y;
|
||||||
if (ballDirection.x < 1) {
|
if (ballDirection.x < 1) {
|
||||||
paddle2Target = paddle2.position.y;
|
paddle2Target = paddle2.position.y;
|
||||||
}
|
}
|
||||||
paddle2.position.y = paddle2.position.y.moveTo(clamp(paddle2Target, paddle2.size.y * 0.5f, resolutionHeight - paddle2.size.y * 0.5f), ballSpeed.y * dt);
|
paddle2.position.y = paddle2.position.y.moveTo(clamp(paddle2Target, paddle2.size.y * 0.5f, resolutionHeight - paddle2.size.y * 0.5f), ballSpeed * dt);
|
||||||
|
|
||||||
// Check for paddle and ball collisions.
|
// Check for paddle and ball collisions.
|
||||||
if (paddle1.centerArea.hasIntersection(ball.centerArea)) {
|
if (paddle1.centerArea.hasIntersection(ball.centerArea)) {
|
||||||
|
|
|
@ -90,6 +90,7 @@ struct Sprite {
|
||||||
ushort atlasTop;
|
ushort atlasTop;
|
||||||
float frameProgress = 0.0f;
|
float frameProgress = 0.0f;
|
||||||
SpriteAnimation animation;
|
SpriteAnimation animation;
|
||||||
|
Vec2 position;
|
||||||
|
|
||||||
@safe:
|
@safe:
|
||||||
|
|
||||||
|
@ -132,9 +133,19 @@ struct Sprite {
|
||||||
if (animation.frameCount <= 1) return;
|
if (animation.frameCount <= 1) return;
|
||||||
frameProgress = fmod(frameProgress + animation.frameSpeed * dt, cast(float) animation.frameCount);
|
frameProgress = fmod(frameProgress + animation.frameSpeed * dt, cast(float) animation.frameCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Moves the sprite to follow the target position at the specified speed.
|
||||||
|
void followPosition(Vec2 target, float speed) {
|
||||||
|
position = position.moveTo(target, Vec2(speed));
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawSprite(Texture texture, Sprite sprite, Vec2 position, DrawOptions options = DrawOptions()) {
|
/// Moves the sprite to follow the target position with gradual slowdown.
|
||||||
|
void followPositionWithSlowdown(Vec2 target, float slowdown) {
|
||||||
|
position = position.moveToWithSlowdown(target, Vec2(deltaTime), slowdown);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawSprite(Texture texture, Sprite sprite, DrawOptions options = DrawOptions()) {
|
||||||
if (sprite.width == 0 || sprite.height == 0) return;
|
if (sprite.width == 0 || sprite.height == 0) return;
|
||||||
|
|
||||||
auto top = sprite.atlasTop + sprite.animation.frameRow * sprite.height;
|
auto top = sprite.atlasTop + sprite.animation.frameRow * sprite.height;
|
||||||
|
@ -146,9 +157,9 @@ void drawSprite(Texture texture, Sprite sprite, Vec2 position, DrawOptions optio
|
||||||
auto row = sprite.frame / gridWidth;
|
auto row = sprite.frame / gridWidth;
|
||||||
auto col = sprite.frame % gridWidth;
|
auto col = sprite.frame % gridWidth;
|
||||||
auto area = Rect(sprite.atlasLeft + col * sprite.width, top + row * sprite.height, sprite.width, sprite.height);
|
auto area = Rect(sprite.atlasLeft + col * sprite.width, top + row * sprite.height, sprite.width, sprite.height);
|
||||||
drawTextureArea(texture, area, position, options);
|
drawTextureArea(texture, area, sprite.position, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawSprite(TextureId texture, Sprite sprite, Vec2 position, DrawOptions options = DrawOptions()) {
|
void drawSprite(TextureId texture, Sprite sprite, DrawOptions options = DrawOptions()) {
|
||||||
drawSprite(texture.getOr(), sprite, position, options);
|
drawSprite(texture.getOr(), sprite, options);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,9 @@ struct Tile {
|
||||||
Sz id;
|
Sz id;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
Vec2 position;
|
||||||
|
|
||||||
@safe @nogc nothrow:
|
@safe:
|
||||||
|
|
||||||
Sz row(Sz colCount) {
|
Sz row(Sz colCount) {
|
||||||
return id / colCount;
|
return id / colCount;
|
||||||
|
@ -38,9 +39,19 @@ struct Tile {
|
||||||
return id % colCount;
|
return id % colCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect area(Sz colCount) {
|
Rect textureArea(Sz colCount) {
|
||||||
return Rect(col(colCount) * width, row(colCount) * height, width, height);
|
return Rect(col(colCount) * width, row(colCount) * height, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Moves the tile to follow the target position at the specified speed.
|
||||||
|
void followPosition(Vec2 target, float speed) {
|
||||||
|
position = position.moveTo(target, Vec2(speed));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Moves the tile to follow the target position with gradual slowdown.
|
||||||
|
void followPositionWithSlowdown(Vec2 target, float slowdown) {
|
||||||
|
position = position.moveToWithSlowdown(target, Vec2(deltaTime), slowdown);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TileMap {
|
struct TileMap {
|
||||||
|
@ -49,9 +60,18 @@ struct TileMap {
|
||||||
Sz estimatedMaxColCount;
|
Sz estimatedMaxColCount;
|
||||||
int tileWidth;
|
int tileWidth;
|
||||||
int tileHeight;
|
int tileHeight;
|
||||||
|
Vec2 position;
|
||||||
alias data this;
|
alias data this;
|
||||||
|
|
||||||
@safe @nogc nothrow:
|
@safe:
|
||||||
|
|
||||||
|
this(short value, int tileWidth, int tileHeight) {
|
||||||
|
this.tileWidth = tileWidth;
|
||||||
|
this.tileHeight = tileHeight;
|
||||||
|
this.estimatedMaxRowCount = data.maxRowCount;
|
||||||
|
this.estimatedMaxColCount = data.maxColCount;
|
||||||
|
this.data.fill(value);
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if the tile map has not been loaded.
|
/// Returns true if the tile map has not been loaded.
|
||||||
bool isEmpty() {
|
bool isEmpty() {
|
||||||
|
@ -99,6 +119,16 @@ struct TileMap {
|
||||||
}
|
}
|
||||||
return Fault.none;
|
return Fault.none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Moves the tile map to follow the target position at the specified speed.
|
||||||
|
void followPosition(Vec2 target, float speed) {
|
||||||
|
position = position.moveTo(target, Vec2(speed));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Moves the tile map to follow the target position with gradual slowdown.
|
||||||
|
void followPositionWithSlowdown(Vec2 target, float slowdown) {
|
||||||
|
position = position.moveToWithSlowdown(target, Vec2(deltaTime), slowdown);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2 findTilePosition(TileMap map, Vec2 position, Sz row, Sz col, DrawOptions options = DrawOptions()) {
|
Vec2 findTilePosition(TileMap map, Vec2 position, Sz row, Sz col, DrawOptions options = DrawOptions()) {
|
||||||
|
@ -122,15 +152,15 @@ Result!TileMap loadRawTileMap(IStr path, int tileWidth, int tileHeight) {
|
||||||
return toTileMap(temp.get(), tileWidth, tileHeight);
|
return toTileMap(temp.get(), tileWidth, tileHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawTile(Texture texture, Tile tile, Vec2 position, DrawOptions options = DrawOptions()) {
|
void drawTile(Texture texture, Tile tile, DrawOptions options = DrawOptions()) {
|
||||||
drawTextureArea(texture, tile.area(texture.width / tile.width), position, options);
|
drawTextureArea(texture, tile.textureArea(texture.width / tile.width), tile.position, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawTile(TextureId texture, Tile tile, Vec2 position, DrawOptions options = DrawOptions()) {
|
void drawTile(TextureId texture, Tile tile, DrawOptions options = DrawOptions()) {
|
||||||
drawTile(texture.getOr(), tile, position, options);
|
drawTile(texture.getOr(), tile, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawTileMap(Texture texture, TileMap map, Vec2 position, Camera camera, DrawOptions options = DrawOptions()) {
|
void drawTileMap(Texture texture, TileMap map, Camera camera, DrawOptions options = DrawOptions()) {
|
||||||
auto area = camera.area;
|
auto area = camera.area;
|
||||||
auto topLeft = area.topLeftPoint;
|
auto topLeft = area.topLeftPoint;
|
||||||
auto bottomRight = area.bottomRightPoint;
|
auto bottomRight = area.bottomRightPoint;
|
||||||
|
@ -138,22 +168,22 @@ void drawTileMap(Texture texture, TileMap map, Vec2 position, Camera camera, Dra
|
||||||
auto targetTileWidth = cast(int) (map.tileWidth * options.scale.x);
|
auto targetTileWidth = cast(int) (map.tileWidth * options.scale.x);
|
||||||
auto targetTileHeight = cast(int) (map.tileHeight * options.scale.y);
|
auto targetTileHeight = cast(int) (map.tileHeight * options.scale.y);
|
||||||
|
|
||||||
auto row1 = cast(int) floor(clamp((topLeft.y - position.y) / targetTileHeight, 0, map.rowCount));
|
auto row1 = cast(int) floor(clamp((topLeft.y - map.position.y) / targetTileHeight, 0, map.rowCount));
|
||||||
auto col1 = cast(int) floor(clamp((topLeft.x - position.x) / targetTileWidth, 0, map.colCount));
|
auto col1 = cast(int) floor(clamp((topLeft.x - map.position.x) / targetTileWidth, 0, map.colCount));
|
||||||
auto row2 = cast(int) floor(clamp((bottomRight.y - position.y) / targetTileHeight + 1, 0, map.rowCount));
|
auto row2 = cast(int) floor(clamp((bottomRight.y - map.position.y) / targetTileHeight + 2, 0, map.rowCount));
|
||||||
auto col2 = cast(int) floor(clamp((bottomRight.x - position.x) / targetTileWidth + 1, 0, map.colCount));
|
auto col2 = cast(int) floor(clamp((bottomRight.x - map.position.x) / targetTileWidth + 2, 0, map.colCount));
|
||||||
if (row1 == row2 || col1 == col2) return;
|
if (row1 == row2 || col1 == col2) return;
|
||||||
|
|
||||||
foreach (row; row1 .. row2) {
|
foreach (row; row1 .. row2) {
|
||||||
foreach (col; col1 .. col2) {
|
foreach (col; col1 .. col2) {
|
||||||
if (map[row, col] == -1) continue;
|
if (map[row, col] == -1) continue;
|
||||||
auto tile = Tile(map[row, col], map.tileWidth, map.tileHeight);
|
auto tile = Tile(map[row, col], map.tileWidth, map.tileHeight);
|
||||||
auto tilePosition = position + Vec2(col * targetTileWidth, row * targetTileHeight);
|
tile.position = map.position + Vec2(col * targetTileWidth, row * targetTileHeight);
|
||||||
drawTile(texture, tile, tilePosition, options);
|
drawTile(texture, tile, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawTileMap(TextureId texture, TileMap map, Vec2 position, Camera camera, DrawOptions options = DrawOptions()) {
|
void drawTileMap(TextureId texture, TileMap map, Camera camera, DrawOptions options = DrawOptions()) {
|
||||||
drawTileMap(texture.getOr(), map, position, camera, options);
|
drawTileMap(texture.getOr(), map, camera, options);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue