snake demo
This commit is contained in:
parent
c6dc0fd476
commit
32c409c7b0
@ -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() {
|
||||||
|
@ -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 {
|
||||||
|
Reference in New Issue
Block a user