Hallo zusammen,
ich versuche gerade ein wenig in JavaScript rein zu kommen und habe mir als einfaches Beispiel Snake implementiert.
Nun wollte ich die Spielelogik in eine Klasse "Logic" auslagern. Das Snake Objekt wird außen erzeugt und über den Konstruktor an das Logic Objekt übergeben. Ich sehe dass die this.snake danach gesetzt ist. Direkt nach dem Konstruktor wird logic.start() aufgerufen. Darin wird ein Interval für die Spielezüge gestaret. executePlayStep wird vom Interval getriggert. Im executePlayStep ist dann this.snake undefined. Das gleiche gilt übrigens für apples in spawnApple. Es scheint bei allen Methoden die aus einem Interval aufgerufen werden so zu sein. Ich hoffe jemand hat eine zündende Idee.
ich versuche gerade ein wenig in JavaScript rein zu kommen und habe mir als einfaches Beispiel Snake implementiert.
Nun wollte ich die Spielelogik in eine Klasse "Logic" auslagern. Das Snake Objekt wird außen erzeugt und über den Konstruktor an das Logic Objekt übergeben. Ich sehe dass die this.snake danach gesetzt ist. Direkt nach dem Konstruktor wird logic.start() aufgerufen. Darin wird ein Interval für die Spielezüge gestaret. executePlayStep wird vom Interval getriggert. Im executePlayStep ist dann this.snake undefined. Das gleiche gilt übrigens für apples in spawnApple. Es scheint bei allen Methoden die aus einem Interval aufgerufen werden so zu sein. Ich hoffe jemand hat eine zündende Idee.
Javascript:
class Logic {
score = 0
apples = []
paused = false
constructor(snake, gameAreaWidth, gameAreaHeight, window, gameOverFunction) {
this.snake = snake
this.gameAreaWidth = gameAreaWidth
this.gameAreaHeight = gameAreaHeight
this.window = window
this.gameOverFunction = gameOverFunction
this.score = 0
this.apples = []
this.paused = false
}
executePlayStep() {
console.debug( "executePlayStep " + this.snake )
this.snake.move()
this.detectWallCollisionAndSetToOtherSide()
this.eatAppleNearby()
if( this.snake.bitTail() ) {
this.stop()
this.gameOverFunction()
}
}
start() {
this.playing = true
this.playInterval = this.window.setInterval( this.executePlayStep, 20 )
this.spawnAppleInterval = this.window.setInterval( this.spawnApple, 500 )
}
stop() {
this.playing = false
this.window.clearInterval( this.playInterval )
this.window.clearInterval( this.spawnAppleInterval )
}
togglePaused() {
if(this.paused) {
this.paused = false
this.start()
}
else {
if(this.playing) {
this.paused = true
this.stop()
}
}
}
reset() {
//TODO
}
isActive() {
return this.playing
}
onDirectionChanged( newDirection ) {
if( newDirection == direction.left && this.snake.currentDirection == direction.right ||
newDirection == direction.right && this.snake.currentDirection == direction.left ||
newDirection == direction.up && this.snake.currentDirection == direction.down ||
newDirection == direction.down && this.snake.currentDirection == direction.up ) {
return
}
this.snake.currentDirection = newDirection
}
spawnApple() {
var randomX = Math.floor(Math.random() * this.gameAreaWidth)
var randomY = Math.floor(Math.random() * this.gameAreaHeight)
this.apples.push( new Apple(randomX, randomY))
}
eatAppleNearby() {
var nearByApples = this.apples.filter( apple => {
var eatDistance = apple.size / 2 + this.snake.headSize / 2
return Math.abs(apple.x - this.snake.x) < eatDistance && Math.abs(apple.y - this.snake.y) < eatDistance
})
nearByApples.forEach( nearByApple => {
const index = this.apples.indexOf(nearByApple)
if (index > -1) {
this.apples.splice(index, 1)
}
this.snake.grow()
this.score++
})
}
beamOnOtherSideWhenBorderCrossed() {
if( this.snake.x > this.gameAreaWidth ) {
this.snake.x = 0
}
else if( this.snake.x < 0 ) {
this.snake.x = this.gameAreaWidth
}
else if( this.snake.y > this.gameAreaHeight ) {
this.snake.y = 0
}
else if( this.snake.y < 0 ) {
this.snake.y = this.gameAreaHeight
}
}
}