Skip to content

Instantly share code, notes, and snippets.

@RSDuck
Last active October 25, 2017 21:31
Show Gist options
  • Save RSDuck/eef0b300cbf0f5732fa39053b17b53d6 to your computer and use it in GitHub Desktop.
Save RSDuck/eef0b300cbf0f5732fa39053b17b53d6 to your computer and use it in GitHub Desktop.
Vlong
import
../../felis/core/[context, engine, entity, systems, assetmanager], ../../felis/scene/transform2d,
../../felis/gfx/[sprite, texture], ../../felis/input/input, ../../felis/helper/box,
glm
type
PaddleController {.pure.} = enum
Player0, Player1, Cpu
Paddle = object
ctrl: PaddleController
Ball = object
velocity: Vec2f
PongSystem = ref object of System
ctx: Context
paddles: array[2, Entity]
ball: Entity
display: array[2, Entity]
timeout: float32
proc init(self: ptr Ball, entity: Entity) = discard entity.ensureDependency(Transform2d)
proc init(self: ptr Paddle, entity: Entity) = discard entity.ensureDependency(Transform2d)
const BallSpeed = 800f
{.this: self.}
proc reset(self: PongSystem) =
paddles[0].assign(initTransform2d(position = vec2f(10f, (float32 ctx.windowInfo.height) / 2f),
pivot = vec2f(10f, 70f)))
paddles[1].assign(initTransform2d(position = vec2f((float32 ctx.windowInfo.width) - 10f,
(float32 ctx.windowInfo.height) / 2f), pivot = vec2f(10f, 70f)))
ball.assign(Ball(velocity: vec2f(BallSpeed, 0f)))
ball.assign(initTransform2d(position = vec2f(ctx.windowInfo.width / 2, ctx.windowInfo.height / 2), pivot = vec2f(15f, 15f)))
timeout = 0.7f
proc newPongSystem(ctx: Context): PongSystem =
result = PongSystem(ctx: ctx)
result.initSystem(SystemPriority.PreGameplay)
method start(self: PongSystem) =
let
paddleTexture = ctx.assetMgr.get(Texture, "asset://coredata/pong.png")
paddles[0] = ctx.entityMgr.create()
paddles[0].assign(Paddle(ctrl: PaddleController.Player0))
paddles[0].assign(Sprite(subX: 34, subY: 0, subW: 20, subH: 140, texture: paddleTexture))
paddles[1] = ctx.entityMgr.create()
paddles[1].assign(Paddle(ctrl: PaddleController.Cpu))
paddles[1].assign(Sprite(subX: 34, subY: 0, subW: 20, subH: 140, texture: paddleTexture))
for i in 0..1:
display[i] = ctx.entityMgr.create()
display[i].assign(Sprite(subX: 0, subY: 26, subW: 16, subH: 24,
texture: ctx.assetMgr.get(Texture, "asset://coredata/led16.png"))) # font by mold
display[i].assign(initTransform2d(position = vec2f(ctx.windowInfo.width / 4 - 3 * 16 / 2 + ctx.windowInfo.width / 2 * (float32 i), 20f), scale = vec2f(3f, 3f)))
ball = ctx.entityMgr.create()
ball.assign(Sprite(subX: 34, subY: 0, subW: 30, subH: 30, texture: ctx.assetMgr.get(Texture, "asset://coredata/pong.png")))
let net = ctx.entityMgr.create()
net.assign(Sprite(texture: ctx.assetMgr.get(Texture, "asset://coredata/pong.png"), subX: 0, subY: 0, subW: 10, subH: ctx.windowInfo.height))
net.assign(initTransform2d(position = vec2f(ctx.windowInfo.width / 2 - 7 / 2, 0f)))
reset()
method update(self: PongSystem, dt: float) =
if timeout < 0f:
let
ballComponent = ball.componentPtr(Ball)
ballTransform = ball.componentPtr(Transform2d)
var newBallPosition = ballTransform.position + ballComponent.velocity * dt
if newBallPosition.y - 15f < 0f or newBallPosition.y + 15f > float32 ctx.windowInfo.height:
ballComponent.velocity.y *= -1.1f
ballComponent.velocity.y = clamp(ballComponent.velocity.y, -1200f, 1200f)
newBallPosition = ballTransform.position + ballComponent.velocity * dt
let ballRect = initRect(newBallPosition + vec2f(-15f, -15f), vec2f(30f, 30f))
let
inputSys = ctx.systemMgr.get(InputSystem)
upDown = inputSys.isKeyDown(keyUp)
downDown = inputSys.isKeyDown(keyDown)
wDown = inputSys.isKeyDown(keyW)
sDown = inputSys.isKeyDown(keyS)
for paddle in paddles:
let
paddleComponent = paddle.componentPtr(Paddle)
paddleTransform = paddle.componentPtr(Transform2d)
rect = initRect(vec2f(-10f, -70f) + paddleTransform.position, vec2f(20f, 140f))
const PaddleSpeed = 300f
paddleTransform.mposition += (case paddleComponent.ctrl
of Player0:
vec2f(0f, -(float32 wDown) + (float32 sDown))
of Player1:
vec2f(0f, -(float32 upDown) + (float32 downDown))
of Cpu:
vec2f(0f, clamp(((ballTransform.position + ballComponent.velocity * 2f).y) - paddleTransform.position.y, -1, 1))) * PaddleSpeed * dt
paddleTransform.position = clamp(paddleTransform.position, vec2f(0f, 70f),
vec2(float32 ctx.windowInfo.width, (float32 ctx.windowInfo.height) - 70f))
if rect.intersects ballRect:
echo "collision"
ballComponent.velocity = (newBallPosition - paddleTransform.position).normalize * BallSpeed
newBallPosition = ballTransform.position
ballTransform.position = newBallPosition
if ballTransform.position.x + 15f < 0f:
self.display[1].componentPtr(Sprite).subX += 18
reset()
newBallPosition = ballTransform.position
ballComponent.velocity = vec2f(BallSpeed, 0f)
if ballTransform.position.x - 15f > float32 ctx.windowInfo.width:
self.display[0].componentPtr(Sprite).subX += 18
reset()
ballComponent.velocity = vec2f(-BallSpeed, 0f)
newBallPosition = ballTransform.position
else:
timeout -= dt
let myEngine = newEngine(title = "Vlong")
myEngine.addSystem(newPongSystem(myEngine.getContext()))
myEngine.start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment