Learn CocosCreator some time now spent two days writing pixels bird game, before the game has seen, but they do not know how the shelves, before the fire is still pretty game, after going to think of it looked online to see the original because of a violation of super Mario game elements are pixel-level game, ah, foreign copyright awareness is still pricey. Well, digression on this, and he began to cut to the chase.
Write this game is not difficult, the most important is the idea, how to write, I have also seen online version of C ++, easy language, Cocos2d, have a lot of, are big God
![](https://img2018.cnblogs.com/blog/1536089/201909/1536089-20190905220344111-384053672.gif)
This is my version of the Creator, a little difference with Cocos2d, but the difference is not great
Well, on the code (screenshot wanted, but still think to be fair to yourself, or hand on it)
This game I used to write ts, plus CocosCreator
onLoad(){
// Get the bird, pipeline, background, terrestrial nodes, which this is the first statement in front of
// birds
this.bird = cc.find('layout_wrap/node_bird', this.node)
// background
this.bg = cc.find('layout_wrap/layout_bg', this.node)
// Pipeline
this.pipe = cc.find('layout_wrap/layout_cont', this.node)
// land
this.land = cc.find('layout_wrap/layout_land', this.node)
// Initialization data
this.initData()
}
// initialize here to look at some statements of game data
private initData(): void {
this.time = 0 // frame rate (frame per call, analog bird flapping its wings)
this.speed = 0 // Speed
this.distance = 150 // duct from
this.rateSpeed = 1 // 移速
this.upSpeed = 2 // acceleration
this.slowSpeed = 0.06 // deceleration
// Listen running events
let wrap = cc.find('layout_wrap', this.node)
wrap.on(cc.Node.EventType.TOUCH_START, this.runnIng.bind(this), this)
// start interface
this.layoutstar = cc.find('layout_wrap/layout_star', this.node)
// Start button
this.starbtn = cc.find('layout_content/button_play', this.layoutstar)
this.addClickEvent(this.starbtn, 'onClickStar')
// pause button
let pausebtn = cc.find('node_score/button_pause', wrap)
this.addClickEvent(pausebtn, 'onClickPause')
// Continue button
let resumebtn = cc.find('layout_pause/button_resume', wrap)
this.addClickEvent(resumebtn, 'onClickResume')
// the game is over, start again
let again = cc.find('layout_over/node_content/button_play', wrap)
this.addClickEvent(again, 'onClickAgain')
// Get Ready prompt node
this.ready = cc.find('node_score/node_ready', wrap)
// game over
this.gameover = cc.find('layout_over', wrap)
// loading tube
this.addPipe()
// collision system
let manager = cc.director.getCollisionManager()
manager.enabled = true
}
// The following function began to write
Click Start //
protected onClickStar(): void {
// zooming interface
let act = cc.callFunc(() => {
this.layoutstar.active = false
this.layoutstar.destroy()
})
// here to use the zoom operation of the system and fade, be it a little bit of animation
let seq = cc.sequence(cc.spawn(cc.scaleTo(0.3, 0), cc.fadeOut(0.3)), act)
if (this.layoutstar) {
this.layoutstar.runAction(seq)
}
// here is to avoid forget it end interface is not hidden away,
if (this.gameover) {
this.gameover.active = false
}
}
// click Run
private runnIng(): void {
if (this.ready.active && !this.layoutstar.active) {
// hide Get Ready prompt node
this.ready.active = false
// display update, ison update as a switch
this.ison = true
}
this.speed = 2.5 // upward acceleration to a bird
}
// loading tube, pipe here is to load up the preform by
private addPipe(): void {
this.LoadPrefabs('node_pipe', (n: cc.Node) => {
if (!n) {
return
}
for (let i = 0; i < 4; i++) {
// copy nodes
let copy = cc.instantiate(n)
// insert node
this.pipe.addChild(copy, i)
// adjust the position of the pipe
copy.x = this.node.width / 2 + (this.distance + copy.width) * i
// 480~720
copy.y = (Math.random() * 0.5 + 1) * 480
if (i > 0) {
// gap between adjacent pipe does not exceed 120
this.distanceY(i, i - 1)
}
}
})
}
// move the background
private moveBg(bgs: cc.Node): void {
bgs.x = bgs.x - 1
// when the background moves out of the screen, the background of the background plus two front
// pixel snapping, so an exact number for the bg.x
if (bgs.x < -614) {
bgs.x = 1228
// adjust node order
if (bgs == this.bg.children[0]) {
this.bg.children[1].zIndex = 0
this.bg.children[2].zIndex = 1
this.bg.children[0].zIndex = 2
} else if (bgs == this.bg.children[1]) {
this.bg.children[2].zIndex = 0
this.bg.children[0].zIndex = 1
this.bg.children[1].zIndex = 2
} else if (bgs == this.bg.children[2]) {
this.bg.children[0].zIndex = 0
this.bg.children[1].zIndex = 1
this.bg.children[2].zIndex = 2
}
}
}
// move the pipeline
private movePipe(pipes: cc.Node): void {
pipes.x = pipes.x - 2
// When moving a conduit wide screen, and then change the position of the pipe to the right side of the screen
if (pipes.x < -(pipes.width + this.node.width / 2)) {
pipes.x = 515
// 480~1000
pipes.y = (Math.random() + 1) * 520 - 40
// gap between adjacent pipe does not exceed 120
if (pipes == this.pipe.children[0]) {
this.distanceY(0, 3)
} else if (pipes == this.pipe.children[1]) {
this.distanceY(1, 0)
} else if (pipes == this.pipe.children[2]) {
this.distanceY(2, 1)
} else if (pipes == this.pipe.children[3]) {
this.distanceY(3, 2)
}
}
}
// move land
private moveLand(lands: cc.Node): void {
lands.x = lands.x - 2 * this.rateSpeed
// When a land mobile wide screen, and then change the position of the land to the right of the screen
if (lands.x < -(this.node.width)) {
lands.x = this.node.width - 2 * this.rateSpeed
}
}
// Y direction gap between adjacent pipeline
private distanceY(a: number, b: number): void {
if (Math.abs(this.pipe.children[a].y - this.pipe.children[b].y) > 140) {
this.pipe.children[a].y = this.pipe.children[b].y + ((Math.random() * 2 - 1) * 140)
if (this.pipe.children[a].y > 1000) {
this.pipe.children[a].y = this.pipe.children[b].y - (Math.random() * 140)
} else if (this.pipe.children[a].y < 480) {
this.pipe.children[a].y = this.pipe.children[b].y + (Math.random() * 140)
}
}
}
// The main thing is this idea, to form a smooth effect, it is necessary to call it every frame,
update(dt: number) {
// mobile termination
if (this.gameover.active) {
this.ison = false
}
// display frame rate of the switching node, the analog wings fan
if (this.ison) {
let timeTemp = this.time + dt
this.time = timeTemp
if (this.time > 0.5) {
if (this.bird.children[0].active) {
this.bird.children[0].active = false
this.bird.children[1].active = true
}
else if (this.bird.children[1].active) {
this.bird.children[1].active = false
this.bird.children[2].active = true
}
else if (this.bird.children[2].active) {
this.bird.children[2].active = false
this.bird.children[3].active = true
}
else if (this.bird.children[3].active) {
this.bird.children[3].active = false
this.bird.children[0].active = true
}
// Do not forget to reset to zero
this.time = 0
}
// to decline given the birds of deceleration
this.speed = this.speed - 0.06
// move birds in the y-axis
this.bird.y = this.bird.y + this.speed
// change the direction of flying bird, the bird is achieved by changing the orientation of the rotational direction
this.bird.angle = this.speed * 10
// move the background
this.moveBg(this.bg.children[0])
this.moveBg(this.bg.children[1])
this.moveBg(this.bg.children[2])
// move the pipeline
this.movePipe(this.pipe.children[0])
this.movePipe(this.pipe.children[1])
this.movePipe(this.pipe.children[2])
this.movePipe(this.pipe.children[3])
// move land
this.moveLand(this.land.children[0])
this.moveLand(this.land.children[1])
}
}
// This is mounted on the main scene of the script, screens and functions to do it, but if not end, then I believe this game will not be too funny
// how to end the game? That is when the bird mounted on the pipe, the game is over, if not, it would be a plus
// here is used to write the collision, of course, you can go other ways to achieve
// This script is mounted on the node of the birds
// load time will be the initial score
onLoad() {
// scores
this.gameMain.Score = 0
// node scores
this.topScore = cc.find('node_score/label_score', this.node.parent)
}
// collision used herein, the bird, pipes, and the middle of the gap will collide binding assembly
// When the birds hit the pipe, the end of the game,
// bird through the intermediary of the gap, plus one point
onCollisionEnter(other, self) {
if (other.tag == 2) {
this.gameMain.Score++
} else if (other.tag == 1) {
this.gameOver()
}
// display scores
this.topScore.getComponent(cc.Label).string = this.gameMain.Score.toString()
}
// End Game
private gameOver(): void {
// Display the end of the game interface
let gameover = cc.find('layout_over', this.node.parent)
gameover.active = true
// fade
gameover.runAction(cc.fadeTo(0.5, 255))
// scores
let scorelabel = cc.find('node_content/sprite_panel/label_score', gameover).getComponent(cc.Label)
scorelabel.string = this.gameMain.Score.toString()
// reset the scores
this.scheduleOnce(() => {
this.gameMain.Score = 0
}, 0.5)
}
Well, a simple single pixel on the bird well, we want a more detailed source of my little friends can whisper oh ~ ~
The following release renderings, alas, did not mount server can not be uploaded directly to the web platform, it can only be released gif