cocos2dx-html5 实现网页版flappy bird游戏

1
|
< li >< a href = "projects/flappybird/index.html" >flappybird </ a > < span > - Game</ span ></ li > |


首先加载资源和添加游戏背景:
1
2
3
4
5
|
this .winSize = cc.Director.getInstance().getWinSize(); cc.SpriteFrameCache.getInstance().addSpriteFrames(res.flappy_packer); this .bgSprite = cc.Sprite.create(res.bg); this .bgSprite.setPosition( this .winSize.width / 2, this .winSize.height / 2); this .addChild( this .bgSprite, 0); |
游戏资源使用TexturePacker打包在flappy_packer.plist文件中,函数名跟cocos2d-x c++版本是一样的。 初始化地面:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Helloworld.prototype.initGround = function () { //cc.log("initGround"); this .groundSprite = cc.Sprite.create(res.ground); var halfGroundW = this .groundSprite.getContentSize().width; var halfGroundH = this .groundSprite.getContentSize().height; this .groundSprite.setAnchorPoint(0.5, 0.5); this .groundSprite.setPosition(halfGroundW / 2, halfGroundH / 2); this .addChild( this .groundSprite, GROUND_Z); var action1 = cc.MoveTo.create(0.5, cc.p(halfGroundW / 2 - 120, this .groundSprite.getPositionY())); var action2 = cc.MoveTo.create(0, cc.p(halfGroundW / 2, this .groundSprite.getPositionY())); var action = cc.Sequence.create(action1, action2); this .groundSprite.runAction(cc.RepeatForever.create(action)); }; |
js可以使用proptotype来为类型添加行为,不理解的可以google一下。当然也可以跟init函数一样写在里面,像这样:
1
2
3
4
5
6
7
|
var Helloworld = cc.Layer.extend({ init: function () { }, initGround:: function () { } ); |
这里为地面定义两个动作,因为地面图片宽度是840px,而游戏屏幕分辨率指定是720×1280,所以先让地面向左移动120px,再迅速回到原位置。
初始化小鸟动画:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
Helloworld.prototype.initBird = function () { //cc.log("initBird"); var animation = cc.AnimationCache.getInstance().getAnimation( "FlyBirdAnimation" ) if (!animation) { var animFrames = []; var str = "" ; var birdFrameCount = 4; for ( var i = 1; i < birdFrameCount; ++ i) { str = "bird" + i + ".png" ; var frame = cc.SpriteFrameCache.getInstance().getSpriteFrame(str); animFrames.push(frame); } var animation = cc.Animation.create(animFrames, 0.05); cc.AnimationCache.getInstance().addAnimation(animation, "FlyBirdAnimation" ); } this .flyBird = cc.Sprite.createWithSpriteFrameName(res.fly_bird); this .flyBird.setAnchorPoint(cc.p(0.5, 0.5)); this .flyBird.setPosition( this .winSize.width / 2, this .winSize.height / 2); this .addChild( this .flyBird, BIRD_Z); var actionFrame = cc.Animate.create(animation); var flyAction = cc.RepeatForever.create(actionFrame); this .flyBird.runAction(cc.RepeatForever.create(flyAction)); }; |
小鸟自身动画是一个帧动画,创建成功后添加到缓存中。
初始化ready界面,就是游戏开始的时候提示用户点击的画面:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
Helloworld.prototype.initReady = function () { this .readyLayer = cc.Layer.create(); var logo = cc.Sprite.createWithSpriteFrameName(res.logo); logo.setAnchorPoint(cc.p(0.5, 0.5)); logo.setPosition( this .winSize.width / 2, this .winSize.height - logo.getContentSize().height - 50); this .readyLayer.addChild(logo); var getReady = cc.Sprite.createWithSpriteFrameName(res.getReady); getReady.setAnchorPoint(cc.p(0.5, 0.5)); getReady.setPosition( this .winSize.width / 2, this .winSize.height / 2 + getReady.getContentSize().height); this .readyLayer.addChild(getReady); var click = cc.Sprite.createWithSpriteFrameName(res.click); click.setAnchorPoint(cc.p(0.5, 0.5)); click.setPosition( this .winSize.width / 2, getReady.getPositionY() - getReady.getContentSize().height / 2 - click.getContentSize().height / 2); this .readyLayer.addChild(click); this .addChild( this .readyLayer); }; |
效果如下:
添加点击屏幕时小鸟上升和下降自由落体的动画:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
Helloworld.prototype.runBirdAction = function () { var riseHeight = 50; var birdX = this .flyBird.getPositionX(); var birdY = this .flyBird.getPositionY(); var bottomY = this .groundSprite.getContentSize().height - this .flyBird.getContentSize().height / 2; var actionFrame = cc.Animate.create(cc.AnimationCache.getInstance().getAnimation( "FlyBirdAnimation" )); var flyAction = cc.RepeatForever.create(actionFrame); //上升动画 var riseMoveAction = cc.MoveTo.create(0.2, cc.p(birdX, birdY + riseHeight)); var riseRotateAction = cc.RotateTo.create(0, -30); var riseAction = cc.Spawn.create(riseMoveAction, riseRotateAction); //下落动画 //模拟自由落体运动 var fallMoveAction = FreeFall.create(birdY - bottomY); var fallRotateAction =cc.RotateTo.create(0, 30); var fallAction = cc.Spawn.create(fallMoveAction, fallRotateAction); this .flyBird.stopAllActions(); this .flyBird.runAction(flyAction); this .flyBird.runAction(cc.Spawn.create( cc.Sequence.create(riseAction, fallAction) ) ); }; |
这里自定义了一个自由落体的Action:FreeFall:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
var FreeFall = cc.ActionInterval.extend( { timeElasped:0, m_positionDeltaY: null , m_startPosition: null , m_targetPosition: null , ctor: function () { cc.ActionInterval.prototype.ctor.call( this ); this .yOffsetElasped = 0; this .timeElasped = 0; this .m_positionDeltaY = 0; this .m_startPosition = cc.p(0, 0); this .m_targetPosition = cc.p(0, 0); }, initWithDuration: function (duration) { if (cc.ActionInterval.prototype.initWithDuration.call( this , duration)) { return true ; } return false ; }, initWithOffset: function (deltaPosition) { var dropTime = Math.sqrt(2.0*Math.abs(deltaPosition)/k_Acceleration) * 0.1; //cc.log("dropTime=" + dropTime); if ( this .initWithDuration(dropTime)) { this .m_positionDeltaY = deltaPosition; return true ; } //cc.log("dropTime =" + dropTime + "; deltaPosition=" + deltaPosition); return false ; }, isDone: function () { if ( this .m_targetPosition.y >= this ._target.getPositionY()) { return true ; } return false ; }, //Node的runAction函数会调用ActionManager的addAction函数,在ActionManager的addAction函数中会调用Action的startWithTarget,然后在Action类的startWithTarget函数中设置_target的值。 startWithTarget: function (target) { //cc.log("startWithTarget target=" + target); cc.ActionInterval.prototype.startWithTarget.call( this , target); this .m_startPosition = target.getPosition(); this .m_targetPosition = cc.p( this .m_startPosition.x, this .m_startPosition.y - this .m_positionDeltaY); }, update: function (dt) { this .timeElasped += dt; //cc.log("isdone=" + this.timeElasped); if ( this ._target && !( this .m_targetPosition.y >= this ._target.getPositionY())) { var yMoveOffset = 0.5 * k_Acceleration * this .timeElasped * this .timeElasped * 0.3; if (cc.ENABLE_STACKABLE_ACTIONS) { var newPos = cc.p( this .m_startPosition.x, this .m_startPosition.y - yMoveOffset); if ( this .m_targetPosition.y > newPos.y) { newPos.y = this .m_targetPosition.y; this ._target.stopAction( this ); } this ._target.setPosition(newPos); } else { this ._target.setPosition(cc.p( this .m_startPosition.x, this .m_startPosition.y + this .m_positionDeltaY * dt)); } } } }); FreeFall.create = function (deltaPosition) { var ff = new FreeFall(); ff.initWithOffset(deltaPosition); return ff; }; |
模仿了CCActionInterval.js中的其他内置的Action,如MoveBy,主要重写了initWithDuration,startWithTarget,update,isDone函数。 initWithDuration是设置该action运行的时间,时间的长短决定下降的速度。 startWithTarget函数由ActionManager调用,设置_target的值。 update函数在ActionInterval的step函数中会调用,在这个函数中不断更新精灵的坐标,使用了自由落体计算位移的公式。 isDone函数设置了动作是否运行结束。 重力加速度和action运行的时间需要不断调试。
添加水管:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
function getRandom(maxSize) { return Math.floor(Math.random() * maxSize) % maxSize; } Helloworld.prototype.addPipe = function () { cc.log( "addPipe" ); var ccSpriteDown = cc.Sprite.createWithSpriteFrameName(res.holdback1); var pipeHeight = ccSpriteDown.getContentSize().height; var pipeWidth = ccSpriteDown.getContentSize().width; var groundHeight = this .groundSprite.getContentSize().height; //小鸟飞行区间高度 var acrossHeight = 300; var downPipeHeight = 100 + getRandom(400); // cc.log("downPipeHeight=" + downPipeHeight); var upPipeHeight = this .winSize.height - downPipeHeight - acrossHeight - groundHeight; var PipeX = this .winSize.width + pipeWidth / 2; ccSpriteDown.setZOrder(1); ccSpriteDown.setAnchorPoint(cc.p(0.5, 0.5)); ccSpriteDown.setPosition(cc.p(PipeX + pipeWidth / 2, groundHeight + pipeHeight / 2 - (pipeHeight - downPipeHeight))); var ccSpriteUp = cc.Sprite.createWithSpriteFrameName(res.holdback2); ccSpriteUp.setZOrder(1); ccSpriteUp.setAnchorPoint(cc.p(0.5, 0.5)); ccSpriteUp.setPosition(cc.p(PipeX + pipeWidth / 2, this .winSize.height + (pipeHeight- upPipeHeight) - pipeHeight / 2)); this .addChild(ccSpriteDown, PIPE_Z); this .addChild(ccSpriteUp, PIPE_Z); this .PipeSpriteList.push(ccSpriteDown); this .PipeSpriteList.push(ccSpriteUp); this .score += 1; }; |
分为上下两根水管,随机设置上下水管的高度,固定小鸟飞行区间的高度为300。然后把创建的水管放到数组中,同时每添加一排水管就增加一分。
添加碰撞检测函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
Helloworld.prototype.getRect = function (a) { var pos = a.getPosition(); var content = a.getContentSize(); return cc.rect(pos.x - content.width / 2, pos.y - content.height / 2, content.width, content.height); }; Helloworld.prototype.collide = function (a, b) { var aRect = this .getRect(a); var bRect = this .getRect(b); return cc.rectIntersectsRect(aRect, bRect); }; Helloworld.prototype.checkCollision = function () { if ( this .collide( this .flyBird, this .groundSprite)) { //cc.log("hit floor"); this .birdFallAction(); return ; } for ( var i = 0; i < this .PipeSpriteList.length; i++) { var pipe = this .PipeSpriteList[i]; if ( this .collide( this .flyBird, pipe)) { cc.log( "hit pipe i=" + i); this .birdFallAction(); break ; } } } |
采用最简单的方式:判断矩形是否相交。把小鸟分别跟地面和数组中的水管进行检测,如果发生碰撞,则执行小鸟死亡动画:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
Helloworld.prototype.birdFallAction = function () { this .gameMode = OVER; this .flyBird.stopAllActions(); this .groundSprite.stopAllActions(); var birdX = this .flyBird.getPositionX(); var birdY = this .flyBird.getPositionY(); var bottomY = this .groundSprite.getContentSize().height + this .flyBird.getContentSize().width / 2; var fallMoveAction = FreeFall.create(birdY - bottomY); var fallRotateAction =cc.RotateTo.create(0, 90); var fallAction = cc.Spawn.create(fallMoveAction, fallRotateAction); this .flyBird.runAction(cc.Sequence.create(cc.DelayTime.create(0.1), fallAction) ); this .runAction(cc.Sequence.create(cc.DelayTime.create(1.0), cc.CallFunc.create( this .showGameOver, this )) ); } |
让小鸟旋转90度,然后垂直下落,然后显示game over画面:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
Helloworld.prototype.showGameOver = function () { var userDefault = cc.UserDefault.getInstance(); var oldScore = userDefault.getIntegerForKey( "score" ); var maxScore = 0; if ( this .score > oldScore) { maxScore = this .score; userDefault.setIntegerForKey( "score" , maxScore); } else { maxScore = oldScore; } var gameOverLayer = cc.Layer.create(); cc.log( "gameover=" + res.gameover); var gameOver = cc.Sprite.createWithSpriteFrameName(res.gameover); gameOver.setAnchorPoint(cc.p(0.5, 0.5)); gameOver.setPosition( this .winSize.width / 2, this .winSize.height - gameOver.getContentSize().height / 2 - 150); gameOverLayer.addChild(gameOver); var scorePanel = cc.Sprite.createWithSpriteFrameName(res.scorePanel); scorePanel.setAnchorPoint(cc.p(0.5, 0.5)); scorePanel.setPosition(gameOver.getPositionX(), gameOver.getPositionY() - gameOver.getContentSize().height / 2 - scorePanel.getContentSize().height / 2 - 60); gameOverLayer.addChild(scorePanel); if ( this .score > oldScore) { var gold = cc.Sprite.createWithSpriteFrameName(res.gold); gold.setAnchorPoint(cc.p(0.5, 0.5)); gold.setPosition(68 + gold.getContentSize().width / 2, 72 + gold.getContentSize().height / 2); scorePanel.addChild(gold); } else { var gray = cc.Sprite.createWithSpriteFrameName(res.gray); gray.setAnchorPoint(cc.p(0.5, 0.5)); gray.setPosition(68 + gray.getContentSize().width / 2, 72 + gray.getContentSize().height / 2); scorePanel.addChild(gray); } var newScoreLabel = cc.LabelAtlas.create( this .score, res.number, 22, 28, '0' ); newScoreLabel.setAnchorPoint(cc.p(0.5, 0.5)); newScoreLabel.setScale(1.2); newScoreLabel.setPosition(scorePanel.getContentSize().width - newScoreLabel.getContentSize().width - 90, newScoreLabel.getContentSize().height / 2 + 180); scorePanel.addChild(newScoreLabel); var maxScoreLabel = cc.LabelAtlas.create(maxScore, res.number, 22, 28, '0' ); maxScoreLabel.setAnchorPoint(cc.p(0.5, 0.5)); maxScoreLabel.setScale(1.2); maxScoreLabel.setPosition(newScoreLabel.getPositionX(), maxScoreLabel.getContentSize().height / 2 + 75); scorePanel.addChild(maxScoreLabel); var start = cc.Sprite.createWithSpriteFrameName(res.start); var startMenuItem = cc.MenuItemSprite.create(start, null , null , this .restartGame, this ); var startMenu = cc.Menu.create(startMenuItem); startMenu.setAnchorPoint(cc.p(0.5, 0.5)); startMenu.setPosition( this .winSize.width / 2 , scorePanel.getPositionY() - scorePanel.getContentSize().height / 2 - start.getContentSize().height / 2 - 60); gameOverLayer.addChild(startMenu); this .addChild(gameOverLayer, GAMEOVER_Z); }; |
显示game over时保存游戏数据,显示这局游戏的分数和历史最高分。
点击开始游戏按钮,就可以重新开始游戏:
1
2
3
4
5
|
Helloworld.prototype.restartGame = function () { var scene = cc.Scene.create(); scene.addChild(Helloworld.create()); cc.Director.getInstance().replaceScene(cc.TransitionFade.create(1.2, scene)); }; |
记得在init函数中清空水管数组:
1
|
this .PipeSpriteList = []; |
下面是Helloworld类的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
var Helloworld = cc.Layer.extend({ gameMode: null , bgSprite: null , groundSprite: null , flyBird: null , PipeSpriteList:[], passTime: 0, winSize: 0, screenRect: null , readyLayer: null , score: 0, scoreLabel: null , init: function () { cc.log( "helloworld init" ); this ._super(); this .PipeSpriteList = []; this .winSize = cc.Director.getInstance().getWinSize(); cc.SpriteFrameCache.getInstance().addSpriteFrames(res.flappy_packer); this .bgSprite = cc.Sprite.create(res.bg); this .bgSprite.setPosition( this .winSize.width / 2, this .winSize.height / 2); this .addChild( this .bgSprite, 0); this .initGround(); this .initReady(); this .screenRect = cc.rect(0, 0, this .winSize.width, this .winSize.height); this .gameMode = READY; this .score = 0; this .scheduleUpdate(); this .setTouchEnabled( true ); return true ; }, onTouchesBegan: function (touches, event) { }, onTouchesMoved: function (touches, event) { }, onTouchesEnded: function (touches, event) { if ( this .gameMode == OVER) { return ; } if ( this .gameMode == READY) { this .gameMode = START; this .readyLayer.setVisible( false ); this .initBird();; } this .runBirdAction(); }, onTouchesCancelled: function (touches, event) { }, update: function (dt) { if ( this .gameMode != START) { return ; } for ( var i = 0; i < this .PipeSpriteList.length; ++ i) { var pipe = this .PipeSpriteList[i]; pipe.setPositionX(pipe.getPositionX() - 3); if (pipe.getPositionX() < -pipe.getContentSize().width / 2) { this .PipeSpriteList.splice(i, 1); //cc.log("delete pipe i=" + i); } } this .passTime += 1; if ( this .passTime >= this .winSize.width / 6) { this .addPipe(); this .passTime = 0; } this .checkCollision(); } }); |
在update函数中更新水管的位置,如果水管出了左边的屏幕就从数组中移除,每经过一定的时间就添加一排水管。 现在看看index.html的内容,在浏览器中访问的就是它:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<!DOCTYPE HTML> < html > < head > < meta charset = "utf-8" > < title >Flappy Bird-codingnow.cn</ title > < link rel = "icon" type = "image/png" href = "http://codingnow.cn/favicon.ico" > < meta name = "viewport" content = "user-scalable=no" /> < meta name = "screen-orientation" content = "portrait" /> < meta name = "apple-mobile-web-app-capable" content = "yes" /> < meta name = "full-screen" content = "yes" /> < meta name = "x5-fullscreen" content = "true" /> < style > body, canvas, div { -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; -khtml-user-select: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } </ style > </ head > < body style = "padding:0; margin: 0;text-align: center;background: #f2f6f8;" > < canvas id = "gameCanvas" width = "720" height = "1280" ></ canvas > < script src = "cocos2d.js" ></ script > < img style = "position:absolute;left:-9999px" src = "http://zhoujianghai.github.io/games/flappybird/res/icon_wechat.png" onerror = "this.parentNode.removeChild(this)" > </ body > </ html > |
在这个文件中指定了canvas的尺寸。html的内容从cocos2d-html5自带的例子中copy过来的,这里在底部添加了一个img,这个图片是分享到微信朋友圈时显示在左边的图片。 当浏览器窗口大小改变时,为了能自动调整显示游戏完整画面,需要在main.js的applicationDidFinishLaunching函数中添加:
1
2
3
|
cc.EGLView.getInstance().adjustViewPort( true ); cc.EGLView.getInstance().setDesignResolutionSize(720, 1280, cc.RESOLUTION_POLICY.SHOW_ALL); cc.EGLView.getInstance().resizeWithBrowserSize( true ); |
还记得那个build.xml文件么,可以使用ant打包工具,把src目录下的js代码跟引擎代码打包成一个myApp-HelloWorld.js文件,这样我们只需要把res资源、cocos2d.js、index.html、myApp-HelloWorld.js放到网站上就可以了,也就更安全了。切换到项目build.xml所在目录,在命令符窗口执行:ant。很快就会生成myApp-HelloWorld.js文件,然后还需要修改cocos2d.js的window.addEventListener函数,修改s.src的值为myApp-HelloWorld.js,cocos2d.js文件里有详细注释的。
ok,flappy bird游戏的主要代码就完成了,感觉cocos2d-html5还是非常强大的,开发效率很高。 现在还只能在本地运行游戏,为了能在外网访问,可以把项目传到github上,创建github pages,可以参考:http://pages.github.com/
cocos2dx-html5 实现网页版flappy bird游戏的更多相关文章
- flappy bird游戏源代码揭秘和下载
转:http://blog.csdn.net/touchsnow/article/details/19071961 背景: 最近火爆全球的游戏flappy bird让笔者叹为观止,于是花了一天的时间山 ...
- 65行 JavaScript 代码实现 Flappy Bird 游戏
飞扬的小鸟(Flappy Bird)无疑是2014年全世界最受关注的一款游戏.这款游戏是一位来自越南河内的独立游戏开发者阮哈东开发,形式简易但难度极高的休闲游戏,很容易让人上瘾. 这里给大家分享一篇这 ...
- 也来山寨一版Flappy Bird (js版)
随着Flappy Bird的火爆,各种实现的版也不断出现,于是也手痒简单实现了一版. 其实本来只是想实现一下这只笨鸟的飞翔运动的,后来没忍住,就直接实现一个完整游戏了…… 因为这个游戏本身实现起来就没 ...
- jQuery实践-网页版2048小游戏
▓▓▓▓▓▓ 大致介绍 看了一个实现网页版2048小游戏的视频,觉得能做出自己以前喜欢玩的小游戏很有意思便自己动手试了试,真正的验证了这句话-不要以为你以为的就是你以为的,看视频时觉得看懂了,会写了, ...
- html5 canvas简易版捕鱼达人游戏源码
插件描述:html5利用canvas写的一个js版本的捕鱼,有积分统计,鱼可以全方位移动,炮会跟着鼠标移动,第一次打开需要鼠标移出背景图,再移入的时候就可以控制炮的转动,因为是用的mouseover触 ...
- 飞翔的圆(Flappy Bird)游戏源码
这个源码是一个不错的休闲类的游戏源码,飞翔的圆(Flappy Bird)游戏源码V1.0,本项目是一个仿Flappy Bird的小游戏,只不过是把Flappy Bird里面的鸟替换成了简单的圆.感兴趣 ...
- 在code.org上自己写一个flappy bird游戏
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:在code.org上自己写一个flappy bird游戏.
- 利用python开发的flappy bird 游戏
python 中 pygame模块能让我们很方便的编写游戏,16年我用python 仿制了flappy bird 游戏,下面是游戏的完整代码以及素材,分享给大家. 第一个python文件,flappy ...
- Python3+pygame实现的flappy bird游戏,代码完整,还有音乐
之前一直在手机上玩flappy bird游戏,闲暇时间就编写了一个 是采用python3+pygame模块制作而成的,运行效果非常流畅,会让你大吃一惊哦哈哈 一.运行效果展示 下载游戏之后,注意在自己 ...
随机推荐
- 《算法问题实战策略》-chaper15-计算几何-线段相交
这篇文章着力来讨论线段相交这一个问题. 给出两条线段,如何判断这两条线段相交? 如果这两条线段相交,如何求其交点? 线段相交问题通常由于其繁杂的情况种类而让人避而远之,在这里希望通过笔者的简化讨论希望 ...
- JSP路径的问题
JSP因为是客户端使用的路径,所以完全可以使用全路径形式 那么在JSP里面使用路径的方式有两种,超链接或者form 当我们在MyEclipse中新建JSP时,可以发现有下面 <%@ page l ...
- Cocos2d-x CCActionInterval
第一部分:CCActionInterval家族(持续动作) 持续动作,顾名思义,就是该动作的执行将持续一段时间.因此持续动作的静态生成函数,往往附带一个时间值Duration.例如: CCAction ...
- Java 动态分页类
动态分页类: Cls_page.java package pagination; public class Cls_page { private int nums;// 总条目数 private i ...
- localstorage 初谈
废话 : localStorage作为本地存储,比cookie大,可以看做一个小的服务器,几个api也可以看做增,删,查,找..... 设置 window.localStorage.setItem() ...
- [AngularJS] Accessing The View-Model Inside The link() When Using controllerAs
If u using controller & controllerAs in directive, then the link()'s 4th param 'controller' will ...
- 执行游戏时出现0xc000007b错误的解决方法
如图,这个错误使无数玩家烦恼. 出现这个错误,可能是硬件的问题,也可能是软件的问题.可是,因为硬件引起该问题的概率非常小,而且除了更换硬件之外没有更好的解决方法,因此本文将具体介绍怎样通过软件解决此问 ...
- [CodeForce]356D Bags and Coins
已知有n个包,和总共s个钱币. n,s<=70000. 每个包可以装钱币,还可以套别的包.每个包中的钱数等于 所有套的包的钱数 加上 自己装的钱. 所有的钱都在包内. 问给定每个包中的钱数,输出 ...
- Java基础知识强化02:import static 和 import
1.import static静态导入是JDK1.5中的新特性.一般我们导入一个类都用 import com.....ClassName;而静态导入是这样:import static com..... ...
- 本地代码git到github上
本地代码git到github上 对于个程序员来说,不写自己的博客,没有自己的作品集没有Github就不算好的程序员!咳咳~ 开个玩笑.对于我个人来说,要做个程序员,就要有自己的作品集和技术博客(我说是 ...