snake demo

This commit is contained in:
pengfei.zhou 2019-07-25 00:14:55 +08:00
parent 8cdff3a8e4
commit cd85a5a676
3 changed files with 58 additions and 7 deletions

View File

@ -100,9 +100,14 @@ enum State {
class SnakeModel { class SnakeModel {
state = State.idel state = State.idel
direction = Direction.left direction = Direction.left
width = 10
height = 10
width: number
height: number
constructor(w: number, h: number) {
this.width = w
this.height = h
}
food = { x: 0, y: 0 } food = { x: 0, y: 0 }
head: SnakeNode = { head: SnakeNode = {
@ -192,6 +197,7 @@ class SnakeModel {
} }
class SnakeView extends ViewHolder { class SnakeView extends ViewHolder {
panel: Stack = new Stack
build(root: Group): void { build(root: Group): void {
root.bgColor = Color.parse('#000000') root.bgColor = Color.parse('#000000')
@ -205,23 +211,66 @@ class SnakeView extends ViewHolder {
top: 20 top: 20
} }
} as StackConfig } as StackConfig
root.addChild(this.panel)
root.addChild(title) root.addChild(title)
} }
} }
class SnakeVM extends ViewModel<SnakeModel, SnakeView>{ class SnakeVM extends ViewModel<SnakeModel, SnakeView>{
binding(v: SnakeView, model: SnakeModel) { timerId?: any
start() {
if (this.timerId !== undefined) {
clearInterval(this.timerId)
}
this.timerId = setInterval(() => {
this.getModel().step()
}, 1000)
}
stop() {
if (this.timerId !== undefined) {
clearInterval(this.timerId)
this.timerId = undefined
}
}
binding(v: SnakeView, model: SnakeModel) {
v.panel.width = model.width * 10
v.panel.height = model.height * 10
let node: SnakeNode | undefined = model.head
let nodes: SnakeNode[] = []
while (node != undefined) {
nodes.push(node)
node = node.next
}
nodes.forEach((e, index) => {
let item = v.panel.children[index]
if (item) {
item.x = e.x * 10
item.height = e.y * 10
} else {
item = new Stack
item.bgColor = Color.parse('#0000ff')
item.width = item.height = 10
v.panel.addChild(item)
}
})
if (nodes.length < v.panel.children.length) {
v.panel.children.length = nodes.length
}
} }
} }
@Entry @Entry
class SnakePanel extends VMPanel<SnakeModel, SnakeView>{ class SnakePanel extends VMPanel<SnakeModel, SnakeView>{
getVMClass() { getVMClass() {
return SnakeVM return SnakeVM
} }
getModel() { getModel() {
return new SnakeModel return new SnakeModel(this.getRootView().width / 10, this.getRootView().width / 10)
} }
getViewHolder() { getViewHolder() {

View File

@ -69,7 +69,7 @@ export abstract class View implements Modeling {
set: (target, p, v, receiver) => { set: (target, p, v, receiver) => {
const oldV = Reflect.get(target, p, receiver) const oldV = Reflect.get(target, p, receiver)
const ret = Reflect.set(target, p, v, receiver) const ret = Reflect.set(target, p, v, receiver)
if (Reflect.getMetadata(p, target)) { if (Reflect.getMetadata(p, target) && oldV !== v) {
receiver.onPropertyChanged(p.toString(), oldV, v) receiver.onPropertyChanged(p.toString(), oldV, v)
} }
return ret return ret
@ -209,7 +209,7 @@ export interface LinearConfig extends Config {
export abstract class Group extends View { export abstract class Group extends View {
@Property @Property
children: View[] = new Proxy([], { readonly children: View[] = new Proxy([], {
set: (target, index, value) => { set: (target, index, value) => {
if (index === 'length') { if (index === 'length') {
this.getDirtyChildrenModel().length = value as number this.getDirtyChildrenModel().length = value as number
@ -231,6 +231,7 @@ export abstract class Group extends View {
addChild(view: View) { addChild(view: View) {
this.children.push(view) this.children.push(view)
} }
clean() { clean() {
this.children.forEach(e => { e.clean() }) this.children.forEach(e => { e.clean() })
super.clean() super.clean()

View File

@ -30,7 +30,7 @@ export abstract class ViewHolder {
export abstract class VMPanel<M extends Object, V extends ViewHolder> extends Panel { export abstract class VMPanel<M extends Object, V extends ViewHolder> extends Panel {
private vm: ViewModel<M, V> = new (this.getVMClass())(this.getModel(), this.getViewHolder()) private vm?: ViewModel<M, V>
abstract getVMClass(): new (m: M, v: V) => ViewModel<M, V> abstract getVMClass(): new (m: M, v: V) => ViewModel<M, V>
@ -44,6 +44,7 @@ export abstract class VMPanel<M extends Object, V extends ViewHolder> extends Pa
} }
build(root: Group): void { build(root: Group): void {
this.vm = new (this.getVMClass())(this.getModel(), this.getViewHolder())
this.vm.build(root) this.vm.build(root)
} }
} }