On 8 Apr 2016, at 11:05, Milos Rankovic via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
This is just a sketch. There may be issues down the line (I’ve indicated some with `TODO`s), but it works and you can try it in the playground:
// Swift 2.2
// utility:
extension Array {
func first <T> (_: T.Type) -> T? {
for e in self where e is T { return e as? T }
return nil
}
}
// Entity-Component System (sketch):
protocol Component { }
protocol Entity {
static func with(_: Component...) -> Self
// TODO: make get only
// also should be a set-by-type really, but that would
// force `Component` to be a class (which may be worth it)
var components: [Component] { get set }
init()
func component<T: Component>(_: T.Type) -> T?
}
extension Entity {
static func with(components: Component...) -> Self {
var entity = self.init()
// TODO: enforce uniquely typed elements
entity.components = components
return entity
}
func component<T: Component>(_: T.Type) -> T? {
return self.components.first(T)
}
}
// game:
struct Character: Entity {
// TODO: make private
var components: [Component] =
}
struct Health: Component {
var percent = 100.0
var dead = false
}
struct Attack: Component {
var range = 0, damage = 0
}
// use:
var health = Health()
var attack = Attack()
var character = Character.with(health, attack)
character.component(Health)?.percent // 100
Hope this helps,
milos
On 8 Apr 2016, at 00:47, Adriano Ferreira via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
Hi everyone!
I’m experimenting with Entity-Component Systems <https://en.wikipedia.org/wiki/Entity_component_system> and I’d appreciate if you could help me working on how to check/get custom objects from a collection.
The idea is to verify if an entity contains a particular component and, if so, retrieve it.
Here’s the API I’d like work on:
// Entity Library
class Character: Entity {}
// Component Library
class HealthComponent: Component {
var health = 100.0
var isDead = false
}
class AttackComponent: Component {
var range = 0
var damage = 0
}
// Usage
var healthComponent = HealthComponent()
var attackComponent = AttackComponent()
var components: [ComponentType] = [healthComponent, attackComponent]
var char = Character(components: components)
let hc = char.get(component: HealthComponent)
let ac = char.get(component: AttackComponent)
So, what are your thoughts on the TODOs below?
—
import Foundation
protocol ComponentType {
var entity: EntityType? { get }
}
protocol EntityType {
var components: [ComponentType] { get }
func get<T: ComponentType>(component c: T.Type) -> T?
func add(component c: ComponentType)
func remove(component c: ComponentType)
}
class Component: ComponentType {
var entity: EntityType?
}
class Entity: EntityType {
var components = [ComponentType]()
init(components: [ComponentType]) {
for component in components {
self.add(component: component)
}
}
func get<T: ComponentType>(component c: T.Type) -> T? {
// TODO: - not sure how to work the types here
// if `self` contains component of given type, return it
// otherwise, return nil
}
func add(component c: ComponentType) {
// TODO: - depends on the `get` function
// if `self` already contains component, just return
// otherwise, self.components += [component]
}
func remove(component c: ComponentType) {
// TODO: - also depends on the `get` function
// if `self` contains component, remove it
// otherwise, just return
}
}
Best,
—A
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users