Skip to content

Commit

Permalink
Cleanup and fix unit/sprite centering
Browse files Browse the repository at this point in the history
  • Loading branch information
ultraq committed May 18, 2024
1 parent 47763cf commit 9f6f41b
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ class Unit extends Node<Unit> implements FactionColours, Rotatable, Temporal {
final ImagesFile imagesFile
final Palette palette
final UnitData unitData
final PalettedSprite body
final PalettedSprite turret

private PalettedSprite body
private PalettedSprite turret
private int stateIndex = 0
private long animationStartTime
private SpriteSheet spriteSheet
Expand All @@ -75,6 +75,9 @@ class Unit extends Node<Unit> implements FactionColours, Rotatable, Temporal {
})
addChild(turret)
}
else {
turret = null
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,11 @@ interface GraphicsElement {
* Render the element for display.
*/
void render(GraphicsRenderer renderer)

/**
* Called on every frame before the node is rendered, allowing it to perform
* any processing as a response to changes in the scene.
*/
default void update() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,4 @@ interface SceneEvents {

return CompletableFuture<Void>.completedFuture(null)
}

/**
* Called on every frame before the node is rendered, allowing it to perform
* any processing as a response to changes in the scene.
*/
default void update() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class Animation extends Node<Animation> implements GraphicsElement, Playable, Te

private final AnimationSource animationSource

private final int numFrames
private final float frameRate
private long startTimeMs
private int currentFrame = -1
private Mesh mesh
Expand All @@ -62,19 +64,23 @@ class Animation extends Node<Animation> implements GraphicsElement, Playable, Te
*/
Animation(AnimationFile animationFile) {

this(animationFile.width, animationFile.height, animationFile.forVgaMonitors,
new StreamingAnimationSource(((Streaming)animationFile).streamingDecoder, animationFile.frameRate, animationFile.numFrames, true))
this(animationFile.width, animationFile.height, animationFile.numFrames, animationFile.frameRate,
animationFile.forVgaMonitors, new StreamingAnimationSource(((Streaming)animationFile).streamingDecoder, true))
}

/**
* Constructor, create an animation using any implementation of the
* {@link AnimationSource} interface.
*/
Animation(int width, int height, boolean forVgaMonitors = false, AnimationSource animationSource) {
Animation(int width, int height, int numFrames, float frameRate, boolean forVgaMonitors = false,
AnimationSource animationSource) {

bounds.set(0, 0, width, forVgaMonitors ? height * 1.2f as float : height)
this.numFrames = numFrames
this.frameRate = frameRate

this.animationSource = animationSource
animationSource.relay(Event, this)
bounds.set(0, 0, width, forVgaMonitors ? height * 1.2f as float : height)
}

@Override
Expand Down Expand Up @@ -135,8 +141,8 @@ class Animation extends Node<Animation> implements GraphicsElement, Playable, Te
@Override
void update() {

var nextFrame = Math.floor((currentTimeMs - startTimeMs) / 1000 * animationSource.frameRate) as int
if (nextFrame < animationSource.numFrames) {
var nextFrame = Math.floor((currentTimeMs - startTimeMs) / 1000 * frameRate) as int
if (nextFrame < numFrames) {
currentFrame = nextFrame
}
else {
Expand All @@ -147,11 +153,7 @@ class Animation extends Node<Animation> implements GraphicsElement, Playable, Te
/**
* Interface for any source from which frames of animation can be obtained.
*/
interface AnimationSource extends EventTarget, SceneEvents {

float getFrameRate()

int getNumFrames()
static interface AnimationSource extends EventTarget, SceneEvents {

/**
* Called during {@code render}, return the texture to be used for rendering
Expand All @@ -167,8 +169,6 @@ class Animation extends Node<Animation> implements GraphicsElement, Playable, Te
static class StreamingAnimationSource implements AnimationSource {

final StreamingDecoder streamingDecoder
final float frameRate
final int numFrames
final boolean autoStream

private List<Texture> frames = []
Expand Down Expand Up @@ -197,7 +197,7 @@ class Animation extends Node<Animation> implements GraphicsElement, Playable, Te
.requestCreateOrGet(new TextureRequest(event.width, event.height, event.format, event.frameFlippedVertical))
.get()
buffersAdded++
if (buffersAdded == Math.ceil(frameRate) as int) {
if (buffersAdded == 10) {
trigger(new PlaybackReadyEvent())
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ class Video extends Node<Video> implements AudioElement, GraphicsElement, Playab

streamingDecoder = videoFile.streamingDecoder

animation = new Animation(videoFile.width, videoFile.height, videoFile.forVgaMonitors,
new StreamingAnimationSource(streamingDecoder, videoFile.frameRate, videoFile.numFrames, false))
animation = new Animation(videoFile.width, videoFile.height, videoFile.numFrames, videoFile.frameRate,
videoFile.forVgaMonitors, new StreamingAnimationSource(streamingDecoder, false))
bounds.set(animation.bounds)
addChild(animation)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,11 @@ abstract class Script<T extends Scriptable> implements SceneEvents {
this.scriptable = scriptable
return this
}

/**
* Called on every frame before the node is rendered, allowing it to perform
* any processing as a response to changes in the scene.
*/
void update() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -379,15 +379,17 @@ class Explorer {
.getDeclaredConstructor(ImagesFile, nz.net.ultraq.redhorizon.filetypes.Palette, UnitData)
.newInstance(shpFile, palette, unitData)
.attachScript(new UnitShowcaseScript())
unit.body.bounds.center()
unit.turret?.bounds?.center()
scene << unit
}
}

// No config found, fall back to viewing a SHP file as media
else {
var palettedSprite = new PalettedSprite(shpFile, palette)
.attachScript(new SpriteShowcaseScript())
scene << palettedSprite
var sprite = new PalettedSprite(shpFile, palette).attachScript(new SpriteShowcaseScript())
sprite.bounds.center()
scene << sprite
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ class UnitShowcaseScript extends Script<Unit> {
CompletableFuture<Void> onSceneAdded(Scene scene) {

return CompletableFuture.runAsync { ->

// TODO: Have it so that the render window is the desktop resolution and the
// camera scales things so that things are the size they were back
// when the game was 640x480
scene.camera.scale(4.0f)
logger.info("Showing ${state} state")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ import org.joml.primitives.Rectanglef
import spock.lang.Specification

import groovy.json.JsonSlurper
import java.util.concurrent.Future
import java.util.concurrent.CompletableFuture
import java.util.function.Consumer

/**
* Tests for the Unit class.
Expand All @@ -45,19 +46,29 @@ class UnitTests extends Specification {
graphicsRequestHandler = Mock(GraphicsRequests) {
requestCreateOrGet(_) >> { args ->
return args[0].class == SpriteSheetRequest ?
Mock(Future) {
get() >> Mock(SpriteSheet) {
getAt(0) >> new Rectanglef(0, 0, 1, 1)
Mock(CompletableFuture) {
thenAcceptAsync(_ as Consumer) >> { Consumer action ->
return CompletableFuture.runAsync { ->
action(Mock(SpriteSheet) {
getAt(0) >> new Rectanglef(0, 0, 1, 1)
})
}
}
} :
Mock(Future) {
get() >> null
Mock(CompletableFuture) {
thenAcceptAsync(_ as Consumer) >> { Consumer action ->
return CompletableFuture.runAsync { ->
action(null)
}
}
}
}
}
}
var spriteFile = loadResource("nz/net/ultraq/redhorizon/explorer/harv.shp", ShpFile)
var palette = loadResource("nz/net/ultraq/redhorizon/explorer/ra-temperate.pal", PalFile)
var spriteStream = new BufferedInputStream(getResourceAsStream('nz/net/ultraq/redhorizon/explorer/harv.shp'))
var paletteStream = new BufferedInputStream(getResourceAsStream('nz/net/ultraq/redhorizon/explorer/ra-temperate.pal'))
var spriteFile = new ShpFile(spriteStream)
var palette = new PalFile(paletteStream)
var unitData = getResourceAsStream('nz/net/ultraq/redhorizon/classic/units/data/harv.json').withBufferedReader { reader ->
return new JsonSlurper().parseText(reader.text) as UnitData
}
Expand All @@ -66,9 +77,8 @@ class UnitTests extends Specification {
scene << unit
then:
notThrown(Exception)
}

private <T> T loadResource(String path, Class<T> clazz) {
return getResourceAsStream(path).withBufferedStream { stream -> clazz.newInstance(stream) }
cleanup:
spriteStream?.close()
paletteStream?.close()
}
}

0 comments on commit 9f6f41b

Please sign in to comment.