mirror of
https://github.com/GayPizzaSpecifications/voxelotl-engine.git
synced 2025-08-03 05:10:57 +00:00
more complicated viewport resizing logic to make sure viewport offset works
This commit is contained in:
@ -133,7 +133,7 @@ public class Application {
|
|||||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
||||||
let backBufferSize = Size(Int(event.window.data1), Int(event.window.data2))
|
let backBufferSize = Size(Int(event.window.data1), Int(event.window.data2))
|
||||||
self.renderer!.resize(size: backBufferSize)
|
self.renderer!.resize(size: backBufferSize)
|
||||||
self.del.resize(backBufferSize)
|
self.del.resize(.init(origin: .zero, size: backBufferSize))
|
||||||
return .running
|
return .running
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -3,13 +3,13 @@ public protocol GameDelegate {
|
|||||||
func fixedUpdate(_ time: GameTime)
|
func fixedUpdate(_ time: GameTime)
|
||||||
func update(_ time: GameTime)
|
func update(_ time: GameTime)
|
||||||
func draw(_ renderer: Renderer, _ time: GameTime)
|
func draw(_ renderer: Renderer, _ time: GameTime)
|
||||||
func resize(_ size: Size<Int>)
|
func resize(_ frame: Rect<Int>)
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension GameDelegate {
|
public extension GameDelegate {
|
||||||
func fixedUpdate(_ time: GameTime) {}
|
func fixedUpdate(_ time: GameTime) {}
|
||||||
func update(_ time: GameTime) {}
|
func update(_ time: GameTime) {}
|
||||||
func resize(_ size: Size<Int>) {}
|
func resize(_ frame: Rect<Int>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct GameTime {
|
public struct GameTime {
|
||||||
|
@ -6,6 +6,7 @@ public class Keyboard {
|
|||||||
case leftBracket
|
case leftBracket
|
||||||
case right, left, up, down
|
case right, left, up, down
|
||||||
case space, tab
|
case space, tab
|
||||||
|
case enter
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func down(_ key: Keys) -> Bool {
|
public static func down(_ key: Keys) -> Bool {
|
||||||
@ -93,6 +94,7 @@ internal extension Keyboard.Keys {
|
|||||||
case .down: SDLK_DOWN
|
case .down: SDLK_DOWN
|
||||||
case .space: SDLK_SPACE
|
case .space: SDLK_SPACE
|
||||||
case .tab: SDLK_TAB
|
case .tab: SDLK_TAB
|
||||||
|
case .enter: SDLK_RETURN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +133,7 @@ internal extension Keyboard.Keys {
|
|||||||
case .down: SDL_SCANCODE_DOWN
|
case .down: SDL_SCANCODE_DOWN
|
||||||
case .space: SDL_SCANCODE_SPACE
|
case .space: SDL_SCANCODE_SPACE
|
||||||
case .tab: SDL_SCANCODE_TAB
|
case .tab: SDL_SCANCODE_TAB
|
||||||
|
case .enter: SDL_SCANCODE_RETURN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,25 @@ import simd
|
|||||||
|
|
||||||
internal class SpriteTestGame: GameDelegate {
|
internal class SpriteTestGame: GameDelegate {
|
||||||
private var spriteBatch: SpriteBatch!
|
private var spriteBatch: SpriteBatch!
|
||||||
private var player = TestPlayer(position: .one * 10)
|
private var player = TestPlayer(position: .one * 100)
|
||||||
private var texture: RendererTexture2D!
|
private var texture: RendererTexture2D!
|
||||||
private var wireShark: RendererTexture2D!
|
private var wireShark: RendererTexture2D!
|
||||||
private var level = TestLevel()
|
private var level = TestLevel()
|
||||||
|
private var frame: Size<Float>!
|
||||||
|
|
||||||
|
var worldMousePosition: SIMD2<Float> {
|
||||||
|
var mpos = Mouse.position
|
||||||
|
if self.spriteBatch.viewport != .init(origin: .zero, size: self.frame) {
|
||||||
|
mpos /= SIMD2(self.frame)
|
||||||
|
mpos *= SIMD2(self.spriteBatch.viewport.size)
|
||||||
|
mpos += SIMD2(self.spriteBatch.viewport.origin)
|
||||||
|
}
|
||||||
|
return mpos
|
||||||
|
}
|
||||||
|
|
||||||
func create(_ renderer: Renderer) {
|
func create(_ renderer: Renderer) {
|
||||||
self.spriteBatch = renderer.createSpriteBatch()
|
self.spriteBatch = renderer.createSpriteBatch()
|
||||||
|
self.resize(renderer.frame)
|
||||||
renderer.clearColor = .init(hue: 301.2, saturation: 0.357, value: 0.488).linear // .magenta.mix(.white, 0.4).mix(.black, 0.8)
|
renderer.clearColor = .init(hue: 301.2, saturation: 0.357, value: 0.488).linear // .magenta.mix(.white, 0.4).mix(.black, 0.8)
|
||||||
self.texture = renderer.loadTexture(resourcePath: "test.png")
|
self.texture = renderer.loadTexture(resourcePath: "test.png")
|
||||||
self.wireShark = renderer.loadTexture(resourcePath: "wireshark.png")
|
self.wireShark = renderer.loadTexture(resourcePath: "wireshark.png")
|
||||||
@ -22,7 +34,8 @@ internal class SpriteTestGame: GameDelegate {
|
|||||||
if let pad = GameController.current?.state {
|
if let pad = GameController.current?.state {
|
||||||
self.player.velocity.x = pad.leftStick.x.axisDeadzone(0.1, 0.8) * 660
|
self.player.velocity.x = pad.leftStick.x.axisDeadzone(0.1, 0.8) * 660
|
||||||
if pad.pressed(.start) {
|
if pad.pressed(.start) {
|
||||||
self.player.position = .one * 10
|
self.player.position = .one * 100
|
||||||
|
self.player.velocity = .zero
|
||||||
}
|
}
|
||||||
if pad.pressed(.east) && player.onGround {
|
if pad.pressed(.east) && player.onGround {
|
||||||
self.player.velocity.y = -1000
|
self.player.velocity.y = -1000
|
||||||
@ -30,6 +43,10 @@ internal class SpriteTestGame: GameDelegate {
|
|||||||
self.player.velocity.y = -550
|
self.player.velocity.y = -550
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if Keyboard.pressed(.enter) {
|
||||||
|
self.player.position = .one * 100
|
||||||
|
self.player.velocity = .zero
|
||||||
|
}
|
||||||
if Keyboard.down(.left) {
|
if Keyboard.down(.left) {
|
||||||
self.player.velocity.x = -660
|
self.player.velocity.x = -660
|
||||||
} else if Keyboard.down(.right) {
|
} else if Keyboard.down(.right) {
|
||||||
@ -41,10 +58,11 @@ internal class SpriteTestGame: GameDelegate {
|
|||||||
self.player.velocity.y = -550
|
self.player.velocity.y = -550
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mpos = self.worldMousePosition
|
||||||
if Mouse.down(.left) {
|
if Mouse.down(.left) {
|
||||||
self.level.set(SIMD2(Mouse.position / TestLevel.cellScale, rounding: .down), true)
|
self.level.set(SIMD2(mpos / TestLevel.cellScale, rounding: .down), true)
|
||||||
} else if Mouse.down(.right) {
|
} else if Mouse.down(.right) {
|
||||||
self.level.set(SIMD2(Mouse.position / TestLevel.cellScale, rounding: .down), false)
|
self.level.set(SIMD2(mpos / TestLevel.cellScale, rounding: .down), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.player.update(deltaTime: dt, level: self.level)
|
self.player.update(deltaTime: dt, level: self.level)
|
||||||
@ -93,11 +111,7 @@ internal class SpriteTestGame: GameDelegate {
|
|||||||
position: doorPosition, transform: doorAffine, color: .red.mix(.white, 0.3))
|
position: doorPosition, transform: doorAffine, color: .red.mix(.white, 0.3))
|
||||||
|
|
||||||
// Draw mouse cursor
|
// Draw mouse cursor
|
||||||
var mpos = Mouse.position
|
let mpos = self.worldMousePosition
|
||||||
if self.spriteBatch.viewport.size != Size<Float>(renderer.frame.size) {
|
|
||||||
mpos /= SIMD2(Size<Float>(renderer.frame.size))
|
|
||||||
mpos *= SIMD2(self.spriteBatch.viewport.size)
|
|
||||||
}
|
|
||||||
let inter = 0.5 + sin(Float(time.total) * 10) * 0.5
|
let inter = 0.5 + sin(Float(time.total) * 10) * 0.5
|
||||||
let color = Color<Float>.green.mix(.white, 0.3)
|
let color = Color<Float>.green.mix(.white, 0.3)
|
||||||
let mesh = Mesh<VertexPosition2DTexcoordColor, UInt16>.init(vertices: [
|
let mesh = Mesh<VertexPosition2DTexcoordColor, UInt16>.init(vertices: [
|
||||||
@ -115,8 +129,34 @@ internal class SpriteTestGame: GameDelegate {
|
|||||||
self.spriteBatch.end()
|
self.spriteBatch.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
func resize(_ size: Size<Int>) {
|
func resize(_ frame: Rect<Int>) {
|
||||||
self.spriteBatch.viewport.size = Size<Float>(size)
|
let viewport = Rect<Float>(frame)
|
||||||
|
self.frame = viewport.size
|
||||||
|
|
||||||
|
let rect = Rect<Float>(origin: .zero, size: .init(2560, 1440))
|
||||||
|
if viewport == rect {
|
||||||
|
self.spriteBatch.viewport = rect
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let viewportRatio = viewport.w / viewport.h
|
||||||
|
let rectRatio = rect.w / rect.h
|
||||||
|
if abs(viewportRatio - rectRatio) <= .ulpOfOne * 10 { self.spriteBatch.viewport = rect }
|
||||||
|
else if viewportRatio > rectRatio {
|
||||||
|
let width = rect.h * viewportRatio
|
||||||
|
self.spriteBatch.viewport = .init(
|
||||||
|
x: (rect.w - width) * 0.5,
|
||||||
|
y: 0,
|
||||||
|
width: width,
|
||||||
|
height: rect.h)
|
||||||
|
} else {
|
||||||
|
let height = rect.w / viewportRatio
|
||||||
|
self.spriteBatch.viewport = .init(
|
||||||
|
x: 0,
|
||||||
|
y: (rect.h - height) * 0.5,
|
||||||
|
width: rect.w,
|
||||||
|
height: height)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user