mirror of
https://github.com/Kapendev/parin.git
synced 2025-04-26 13:09:56 +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.
|
||||
auto camera = Camera(0, -14);
|
||||
auto cameraTarget = Vec2(0, -14);
|
||||
auto cameraSpeed = Vec2(120);
|
||||
auto cameraSpeed = 120;
|
||||
|
||||
void ready() {
|
||||
lockResolution(320, 180);
|
||||
|
@ -12,7 +12,7 @@ void ready() {
|
|||
|
||||
bool update(float dt) {
|
||||
// Move the camera.
|
||||
cameraTarget += wasd * cameraSpeed * Vec2(dt);
|
||||
cameraTarget += wasd * Vec2(cameraSpeed * dt);
|
||||
camera.followPositionWithSlowdown(cameraTarget, 0.15);
|
||||
|
||||
// Draw the game world.
|
||||
|
|
|
@ -3,7 +3,7 @@ import parin;
|
|||
|
||||
// The game variables.
|
||||
auto player = Rect(16, 16);
|
||||
auto playerSpeed = Vec2(120);
|
||||
auto playerSpeed = 120;
|
||||
|
||||
auto coins = SparseList!Rect();
|
||||
auto coinSize = Vec2(8);
|
||||
|
@ -33,7 +33,7 @@ bool update(float dt) {
|
|||
if (Keyboard.right.isDown || 'd'.isDown) playerDirection.x = 1;
|
||||
if (Keyboard.up.isDown || 'w'.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.
|
||||
foreach (id; coins.ids) {
|
||||
|
|
|
@ -3,11 +3,8 @@ import parin;
|
|||
|
||||
// The game variables.
|
||||
auto atlas = TextureId();
|
||||
|
||||
auto sprite = Sprite(16, 16, 0, 128);
|
||||
auto spritePosition = Vec2();
|
||||
auto spriteFlip = Flip.none;
|
||||
|
||||
auto idleAnimation = SpriteAnimation(0, 1, 6);
|
||||
auto walkAnimation = SpriteAnimation(0, 2, 6);
|
||||
|
||||
|
@ -25,10 +22,10 @@ bool update(float dt) {
|
|||
sprite.update(dt);
|
||||
|
||||
// Get some basic info about the mouse.
|
||||
auto mouseDistance = spritePosition.distanceTo(mouseScreenPosition);
|
||||
auto mouseDirection = spritePosition.directionTo(mouseScreenPosition);
|
||||
auto mouseDistance = sprite.position.distanceTo(mouseScreenPosition);
|
||||
auto mouseDirection = sprite.position.directionTo(mouseScreenPosition);
|
||||
// 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.
|
||||
auto isWaiting = mouseDistance < 0.2;
|
||||
|
@ -59,7 +56,7 @@ bool update(float dt) {
|
|||
options.scale = Vec2(2);
|
||||
|
||||
// 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));
|
||||
drawDebugText("Press 1, 2 or 3 to change the character.", Vec2(8));
|
||||
return false;
|
||||
|
|
|
@ -4,9 +4,10 @@ import parin;
|
|||
// The game variables.
|
||||
auto atlas = TextureId();
|
||||
auto map = TileMap();
|
||||
auto playerTile = Tile(145, 16, 16);
|
||||
auto playerPosition = Vec2();
|
||||
auto playerSpeed = Vec2(120);
|
||||
auto camera = Camera(0, 0, true);
|
||||
auto tile = Tile(145, 16, 16);
|
||||
auto tileSpeed = 120;
|
||||
auto tileLookDirection = -1;
|
||||
|
||||
void ready() {
|
||||
lockResolution(320, 180);
|
||||
|
@ -18,11 +19,21 @@ void ready() {
|
|||
}
|
||||
|
||||
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.
|
||||
auto options = DrawOptions(Vec2(2));
|
||||
drawTileMap(atlas, map, Vec2(), Camera(), options);
|
||||
drawTile(atlas, playerTile, playerPosition, options);
|
||||
camera.attach();
|
||||
drawTileMap(atlas, map, camera, mapOptions);
|
||||
drawTile(atlas, tile, tileOptions);
|
||||
camera.detach();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,12 @@ import parin;
|
|||
// The game variables.
|
||||
auto gameCounter = 0;
|
||||
|
||||
auto paddle1 = Rect(2, 30);
|
||||
auto paddle2 = Rect(2, 30);
|
||||
auto paddle1 = Rect(2, 25);
|
||||
auto paddle2 = Rect(2, 25);
|
||||
|
||||
auto ball = Rect(5, 5);
|
||||
auto ballSpeed = Vec2(120);
|
||||
auto ballDirection = Vec2(1, 1);
|
||||
auto ballSpeed = 120;
|
||||
|
||||
void ready() {
|
||||
lockResolution(320, 180);
|
||||
|
@ -28,7 +28,7 @@ bool update(float dt) {
|
|||
// A centered rectangle is used for collision checking and drawing.
|
||||
|
||||
// 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.
|
||||
if (ball.centerArea.leftPoint.x < 0) {
|
||||
ball.position = resolution * Vec2(0.5);
|
||||
|
@ -51,13 +51,13 @@ bool update(float dt) {
|
|||
}
|
||||
|
||||
// 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.
|
||||
auto paddle2Target = ball.position.y;
|
||||
if (ballDirection.x < 1) {
|
||||
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.
|
||||
if (paddle1.centerArea.hasIntersection(ball.centerArea)) {
|
||||
|
|
|
@ -90,6 +90,7 @@ struct Sprite {
|
|||
ushort atlasTop;
|
||||
float frameProgress = 0.0f;
|
||||
SpriteAnimation animation;
|
||||
Vec2 position;
|
||||
|
||||
@safe:
|
||||
|
||||
|
@ -132,9 +133,19 @@ struct Sprite {
|
|||
if (animation.frameCount <= 1) return;
|
||||
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));
|
||||
}
|
||||
|
||||
/// 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, Vec2 position, DrawOptions options = DrawOptions()) {
|
||||
void drawSprite(Texture texture, Sprite sprite, DrawOptions options = DrawOptions()) {
|
||||
if (sprite.width == 0 || sprite.height == 0) return;
|
||||
|
||||
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 col = sprite.frame % gridWidth;
|
||||
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()) {
|
||||
drawSprite(texture.getOr(), sprite, position, options);
|
||||
void drawSprite(TextureId texture, Sprite sprite, DrawOptions options = DrawOptions()) {
|
||||
drawSprite(texture.getOr(), sprite, options);
|
||||
}
|
||||
|
|
|
@ -27,8 +27,9 @@ struct Tile {
|
|||
Sz id;
|
||||
int width;
|
||||
int height;
|
||||
Vec2 position;
|
||||
|
||||
@safe @nogc nothrow:
|
||||
@safe:
|
||||
|
||||
Sz row(Sz colCount) {
|
||||
return id / colCount;
|
||||
|
@ -38,9 +39,19 @@ struct Tile {
|
|||
return id % colCount;
|
||||
}
|
||||
|
||||
Rect area(Sz colCount) {
|
||||
Rect textureArea(Sz colCount) {
|
||||
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 {
|
||||
|
@ -49,9 +60,18 @@ struct TileMap {
|
|||
Sz estimatedMaxColCount;
|
||||
int tileWidth;
|
||||
int tileHeight;
|
||||
Vec2 position;
|
||||
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.
|
||||
bool isEmpty() {
|
||||
|
@ -99,6 +119,16 @@ struct TileMap {
|
|||
}
|
||||
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()) {
|
||||
|
@ -122,15 +152,15 @@ Result!TileMap loadRawTileMap(IStr path, int tileWidth, int tileHeight) {
|
|||
return toTileMap(temp.get(), tileWidth, tileHeight);
|
||||
}
|
||||
|
||||
void drawTile(Texture texture, Tile tile, Vec2 position, DrawOptions options = DrawOptions()) {
|
||||
drawTextureArea(texture, tile.area(texture.width / tile.width), position, options);
|
||||
void drawTile(Texture texture, Tile tile, DrawOptions options = DrawOptions()) {
|
||||
drawTextureArea(texture, tile.textureArea(texture.width / tile.width), tile.position, options);
|
||||
}
|
||||
|
||||
void drawTile(TextureId texture, Tile tile, Vec2 position, DrawOptions options = DrawOptions()) {
|
||||
drawTile(texture.getOr(), tile, position, options);
|
||||
void drawTile(TextureId texture, Tile tile, DrawOptions options = DrawOptions()) {
|
||||
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 topLeft = area.topLeftPoint;
|
||||
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 targetTileHeight = cast(int) (map.tileHeight * options.scale.y);
|
||||
|
||||
auto row1 = cast(int) floor(clamp((topLeft.y - position.y) / targetTileHeight, 0, map.rowCount));
|
||||
auto col1 = cast(int) floor(clamp((topLeft.x - position.x) / targetTileWidth, 0, map.colCount));
|
||||
auto row2 = cast(int) floor(clamp((bottomRight.y - position.y) / targetTileHeight + 1, 0, map.rowCount));
|
||||
auto col2 = cast(int) floor(clamp((bottomRight.x - position.x) / targetTileWidth + 1, 0, map.colCount));
|
||||
auto row1 = cast(int) floor(clamp((topLeft.y - map.position.y) / targetTileHeight, 0, map.rowCount));
|
||||
auto col1 = cast(int) floor(clamp((topLeft.x - map.position.x) / targetTileWidth, 0, map.colCount));
|
||||
auto row2 = cast(int) floor(clamp((bottomRight.y - map.position.y) / targetTileHeight + 2, 0, map.rowCount));
|
||||
auto col2 = cast(int) floor(clamp((bottomRight.x - map.position.x) / targetTileWidth + 2, 0, map.colCount));
|
||||
if (row1 == row2 || col1 == col2) return;
|
||||
|
||||
foreach (row; row1 .. row2) {
|
||||
foreach (col; col1 .. col2) {
|
||||
if (map[row, col] == -1) continue;
|
||||
auto tile = Tile(map[row, col], map.tileWidth, map.tileHeight);
|
||||
auto tilePosition = position + Vec2(col * targetTileWidth, row * targetTileHeight);
|
||||
drawTile(texture, tile, tilePosition, options);
|
||||
tile.position = map.position + Vec2(col * targetTileWidth, row * targetTileHeight);
|
||||
drawTile(texture, tile, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawTileMap(TextureId texture, TileMap map, Vec2 position, Camera camera, DrawOptions options = DrawOptions()) {
|
||||
drawTileMap(texture.getOr(), map, position, camera, options);
|
||||
void drawTileMap(TextureId texture, TileMap map, Camera camera, DrawOptions options = DrawOptions()) {
|
||||
drawTileMap(texture.getOr(), map, camera, options);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue