snake demo

This commit is contained in:
pengfei.zhou 2019-07-25 11:59:20 +08:00
parent c6dc0fd476
commit 32c409c7b0
2 changed files with 67 additions and 67 deletions

View File

@ -1,4 +1,5 @@
import { StackConfig, ViewHolder, VMPanel, View, ViewModel, WRAP_CONTENT, Gravity, Mutable, NativeCall, Text, Color, VLayout, Panel, log, logw, loge, Group, Stack, } from "./index" import { HLayout, StackConfig, ViewHolder, VMPanel, View, ViewModel, WRAP_CONTENT, Gravity, Mutable, NativeCall, Text, Color, VLayout, Panel, log, logw, loge, Group, Stack, } from "./index"
interface CountModel { interface CountModel {
count: number count: number
@ -73,53 +74,21 @@ class MyPage extends VMPanel<CountModel, CounterView>{
loge("Hello.HEGO") loge("Hello.HEGO")
} }
} }
type SnakeNode = {
x: number
y: number
prev?: SnakeNode
next?: SnakeNode
}
type Postion = { x: number, y: number } enum Direction {
enum Location {
left = 0, left = 0,
right = 1, right = 1,
top = 2, up = 2,
bottom = 3, down = 3,
} }
class Snake {
direction: "left" | "right" | "top" | "bottom" = "right"
length: number = 1
width: number = 1
height: number = 1
head: Postion = { x: 1, y: 0 }
body: Location[] = []
crash() {
}
step() {
switch (this.direction) {
case "left":
const head = this.body[0]
if (head.x - 1 < 0) {
this.crash()
}
head.x -= 1
this.body.reduce((pre, cur) => {
return cur
})
break
case "right":
break
case "top":
break
case "bottom":
break
}
}
enum State { enum State {
idel, idel,
run, run,
@ -128,7 +97,7 @@ enum State {
class SnakeModel { class SnakeModel {
state = State.idel state = State.idel
direction = Direction.left direction = Direction.right
width: number width: number
height: number height: number
@ -137,7 +106,7 @@ class SnakeModel {
this.width = w this.width = w
this.height = h this.height = h
} }
food = { x: 0, y: 0 } food = { x: -1, y: -1 }
head: SnakeNode = { head: SnakeNode = {
x: 0, x: 0,
@ -167,20 +136,22 @@ class SnakeModel {
} }
forward(node: SnakeNode) { forward(node: SnakeNode) {
loge('forward', node)
switch (this.direction) { switch (this.direction) {
case Direction.left: case Direction.left:
node.x -= 10 node.x -= 1
break; break;
case Direction.right: case Direction.right:
node.x += 10 node.x += 1
break; break;
case Direction.up: case Direction.up:
node.y -= 10 node.y -= 1
break; break;
case Direction.down: case Direction.down:
node.y += 10 node.y += 1
break; break;
} }
loge('forward', node)
} }
@ -227,37 +198,57 @@ class SnakeModel {
class SnakeView extends ViewHolder { class SnakeView extends ViewHolder {
panel: Stack = new Stack panel: Stack = new Stack
start: Text = new Text
build(root: Group): void { build(root: Group): void {
root.bgColor = Color.parse('#000000') root.bgColor = Color.parse('#000000')
const vlayout = new VLayout
const title = new Text const title = new Text
title.text = "Snake" title.text = "Snake"
title.textSize = 20 title.textSize = 20
title.textColor = Color.parse("#ffffff") title.textColor = Color.parse("#ffffff")
title.layoutConfig = { title.layoutConfig = {
alignment: new Gravity().centerX().top(), alignment: new Gravity().centerX(),
margin: { margin: {
top: 20 top: 20
},
} }
} as StackConfig vlayout.layoutConfig = {
root.addChild(this.panel) alignment: new Gravity().centerX().top()
root.addChild(title) }
this.panel.bgColor = Color.parse('#00ff00')
vlayout.addChild(title)
vlayout.addChild(this.panel)
root.addChild(vlayout)
const hlayout = new HLayout
this.start.text = "Start"
this.start.textSize = 30
this.start.textColor = Color.parse("#ffffff")
hlayout.addChild(this.start)
vlayout.addChild(hlayout)
} }
} }
class SnakeVM extends ViewModel<SnakeModel, SnakeView>{ class SnakeVM extends ViewModel<SnakeModel, SnakeView>{
timerId?: any timerId?: any
start() { start = () => {
if (this.timerId !== undefined) { if (this.timerId !== undefined) {
clearInterval(this.timerId) clearInterval(this.timerId)
} }
this.getModel().state = State.run
this.getModel().head.x = 0
this.getModel().head.y = 0
this.getModel().head.next = undefined
this.getModel().refreshFood()
this.timerId = setInterval(() => { this.timerId = setInterval(() => {
this.getModel().step() this.getModel().step()
}, 1000) }, 1000)
} }
stop() { stop = () => {
if (this.timerId !== undefined) { if (this.timerId !== undefined) {
clearInterval(this.timerId) clearInterval(this.timerId)
this.timerId = undefined this.timerId = undefined
@ -265,6 +256,10 @@ class SnakeVM extends ViewModel<SnakeModel, SnakeView>{
} }
binding(v: SnakeView, model: SnakeModel) { binding(v: SnakeView, model: SnakeModel) {
if (model.state === State.fail) {
this.stop()
}
v.start.onClick = this.start
v.panel.width = model.width * 10 v.panel.width = model.width * 10
v.panel.height = model.height * 10 v.panel.height = model.height * 10
let node: SnakeNode | undefined = model.head let node: SnakeNode | undefined = model.head
@ -273,18 +268,25 @@ class SnakeVM extends ViewModel<SnakeModel, SnakeView>{
nodes.push(node) nodes.push(node)
node = node.next node = node.next
} }
nodes.push(model.food)
nodes.forEach((e, index) => { nodes.forEach((e, index) => {
let item = v.panel.children[index] let item = v.panel.children[index]
if (item) { if (item === undefined) {
item.x = e.x * 10
item.height = e.y * 10
} else {
item = new Stack item = new Stack
item.bgColor = Color.parse('#0000ff')
item.width = item.height = 10 item.width = item.height = 10
v.panel.addChild(item) v.panel.addChild(item)
} }
if (index === nodes.length - 1) {
item.bgColor = Color.parse('#ffff00')
} else {
item.bgColor = Color.parse('#ff0000')
}
item.x = e.x * 10
item.y = e.y * 10
loge('render', v.panel.toModel())
}) })
if (nodes.length < v.panel.children.length) { if (nodes.length < v.panel.children.length) {
v.panel.children.length = nodes.length v.panel.children.length = nodes.length
} }
@ -299,7 +301,7 @@ class SnakePanel extends VMPanel<SnakeModel, SnakeView>{
} }
getModel() { getModel() {
return new SnakeModel(this.getRootView().width / 10, this.getRootView().width / 10) return new SnakeModel(35, 35)
} }
getViewHolder() { getViewHolder() {

View File

@ -6,9 +6,7 @@ function listen<T extends Object>(obj: T, listener: Function): T {
get: (target, prop, receiver) => { get: (target, prop, receiver) => {
const ret = Reflect.get(target, prop, receiver) const ret = Reflect.get(target, prop, receiver)
if (ret instanceof Function) { if (ret instanceof Function) {
return () => { return Reflect.get(target, prop, receiver)
return Reflect.apply(ret, receiver, arguments)
}
} else if (ret instanceof Object) { } else if (ret instanceof Object) {
return listen(ret, listener) return listen(ret, listener)
} else { } else {